Sincronização do estado de entrega (status)

Quando enviamos uma mensagem para uma conversa, o estado da entrega deve ser explícito e compreensível para o utilizador final. Assim, o Jami tem de oferecer a possibilidade de saber se a mensagem foi entregue aos outros membros de uma conversa e sincronizar este estado (enviado e apresentado) entre dispositivos.

Como funciona (backend)

O status das mensagens é armazenado na camada de conversação através da variável messagesStatus (map<string, map<string, string>) com a seguinte estrutura:

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

O status fetch é o commitId da última mensagem obtida pelo membro. O fetched_ts é o carimbo de tempo da última mensagem obtida pelo membro. O status read é o commitId da última mensagem lida pelo membro. O read_ts é a data e hora da última mensagem lida pelo membro.

Quando um membro vai buscar uma mensagem, o status fetch é atualizado com o commitId da mensagem e o fetched_ts é atualizado com o carimbo de data/hora da mensagem. Quando um membro lê uma mensagem, o status read é atualizado com o commitId da mensagem e o read_ts é atualizado com o carimbo de data/hora da mensagem. Esta informação é sincronizada entre dispositivos e outros dispositivos irão atualizar a sua estrutura interna se o carimbo de data/hora for mais recente.

Esta informação é armazenada em conversation_data/xxxxxxxxx/status.

API de cliente

O cliente deve obter o status da estrutura SwarmMessage atual ao carregar a conversa e atualizar o status através de AccountMessageStatusChanged. Em AccountMessageStatusChanged o cliente terá o commitId, o peer uri e o novo status. Portanto, isso corresponderá a message.status[uri].

A estrutura do status de SwarmMessage é:

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

Onde uri é o uri do par e status é o estado da mensagem para este par (do enum MessageStates).

Ao enviar uma nova mensagem, o mapa status pode estar vazio (porque ninguém foi buscado). Por padrão, se não houver nenhuma informação de busca/leitura para uma mensagem, a mensagem DEVE ser considerada como enviada. O status global de uma mensagem é o máximo do status de todos os membros, exceto nós mesmos. Por exemplo, se a Alice enviar uma mensagem e tivermos:

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

O estado global é sent.

Notas para o cliente

  • Se o cliente quiser mostrar qual é a última mensagem lida para um membro, ele deve verificar o índice ao responder a AccountMessageStatusChanged. Porque este sinal pode emitir que uma mensagem anterior seja mostrada mais tarde.

  • O estado de uma mensagem pode ser utilizado para criar uma visão detalhada de quem recebeu/mostrou uma mensagem específica. No entanto, os carimbos de data/hora desses eventos não são armazenados, porque isso representaria demasiados dados.