Sincronización del estado de entrega

Cuando enviamos un mensaje a una conversación, el estado de entrega debe ser explícito y comprensible para el usuario final. Por lo tanto, Jami debe ofrecer la posibilidad de saber si el mensaje fue entregado a los demás miembros de una conversación y sincronizar este estado (enviado y mostrado) en todos los dispositivos.

Cómo funciona (backend)

El estado de los mensajes se almacena en la capa de conversación a través de la variable messagesStatus (map<string, map<string, string>) con la siguiente estructura:

{uri, {
         {"fetch", "commitId"},
         {"fetched_ts", "timestamp"},
         {"read", "commitId"},
         {"read_ts", "timestamp"}
      }
}

El estado de fetch es el commitId del último mensaje obtenido por el miembro. El fetched_ts es la marca de tiempo del último mensaje obtenido por el miembro. El estado de read es el commitId del último mensaje leído por el miembro. El read_ts es la marca de tiempo del último mensaje leído por el miembro.

Cuando un miembro recupera un mensaje, el estado fetch se actualiza con el commitId del mensaje y el fetched_ts se actualiza con la marca de tiempo del mensaje. Cuando un miembro lee un mensaje, el estado read se actualiza con el commitId del mensaje y el read_ts se actualiza con la marca de tiempo del mensaje. Esta información se sincroniza a través de dispositivos y otros dispositivos actualizarán su estructura interna si la marca de tiempo es más reciente.

Esta información se almacena en conversation_data/xxxxxxxxx/status.

API del cliente

El cliente debe obtener el estado de la estructura SwarmMessage actual al cargar la conversación y actualizar el estado a través de AccountMessageStatusChanged. En AccountMessageStatusChanged, el cliente tendrá el commitId, el uri del peer y el nuevo estado. Por lo tanto, esto corresponderá a message.status[uri].

La estructura de estado de SwarmMessage es:

{
    {uri, status},
    {uri2, status2}
}

Donde uri es el uri del par y status es el estado del mensaje para este par (de la enumeración MessageStates).

Cuando se envía un mensaje nuevo, el mapa de status puede estar vacío (porque nadie lo ha buscado). Por defecto, si no hay información de búsqueda/lectura para un mensaje, el mensaje DEBE considerarse como enviado. El estado global de un mensaje es el máximo del estado de todos los miembros excepto nosotros mismos. Por ejemplo, si Alice envía un mensaje y tenemos:

status = {alice: displayed, bob: sending, carl: sent}

El estado global es sent.

Notas para el cliente

  • Si el cliente quiere mostrar qué mensaje es el último mensaje leído para un miembro, debe verificar el índice al responder a AccountMessageStatusChanged. Porque esta señal puede emitir que un mensaje anterior se muestra más tarde.

  • El estado de un mensaje puede utilizarse para crear una vista detallada de quién recibió/mostró un mensaje específico. Sin embargo, las marcas de tiempo de esos eventos no se almacenan, porque esto representaría demasiados datos.