Synchronizacja statusu dostawy

Kiedy wysyłamy wiadomość do konwersacji, status jej dostarczenia musi być jawny i zrozumiały dla użytkownika końcowego. Jami musi więc oferować możliwość sprawdzenia, czy wiadomość została dostarczona do innych członków konwersacji i zsynchronizować ten status (wysłany i wyświetlony) na różnych urządzeniach.

Jak to działa (zaplecze)

Status wiadomości jest przechowywany w warstwie konwersacji poprzez zmienną messagesStatus (map<string, map<string, string>) o następującej strukturze:

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

Status fetch to commitId ostatniej wiadomości pobranej przez członka. fetched_ts to znacznik czasu ostatniej wiadomości pobranej przez członka. Status read to commitId ostatniej wiadomości odczytanej przez członka. read_ts to znacznik czasu ostatniej wiadomości odczytanej przez członka.

Gdy członek pobiera wiadomość, status fetch jest aktualizowany o commitId wiadomości, a fetched_ts jest aktualizowany o znacznik czasu wiadomości. Gdy członek czyta wiadomość, status read jest aktualizowany o commitId wiadomości, a read_ts jest aktualizowany o znacznik czasu wiadomości. Informacje te są synchronizowane między urządzeniami, a inne urządzenia zaktualizują swoją wewnętrzną strukturę, jeśli znacznik czasu jest nowszy.

Informacje te są przechowywane w conversation_data/xxxxxxxxx/status.

API klienta

Klient powinien pobrać status z bieżącej struktury SwarmMessage podczas ładowania konwersacji i zaktualizować status poprzez AccountMessageStatusChanged. W AccountMessageStatusChanged klient będzie miał commitId, peer uri i nowy status. Będzie to więc odpowiadać message.status[uri].

Struktura statusu SwarmMessage to:

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

Gdzie uri jest uri peera, a status jest statusem wiadomości dla tego peera (z wyliczenia MessageStates).

Podczas wysyłania nowej wiadomości, mapa status może być pusta (ponieważ nikt jej nie pobrał). Domyślnie, jeśli nie ma informacji o pobraniu/odczycie wiadomości, wiadomość MUSI być uznana za wysłaną. Globalny status wiadomości jest maksymalnym statusem wszystkich członków z wyjątkiem nas samych. Na przykład, jeśli Alicja wysyła wiadomość i mamy:

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

Globalny status to wysłane.

Uwagi dla klienta

  • Jeśli klient chce pokazać, która wiadomość jest ostatnią odczytaną wiadomością dla członka, musi sprawdzić indeks podczas odpowiadania na AccountMessageStatusChanged. Ponieważ ten sygnał może emitować, że poprzednia wiadomość jest wyświetlana później.

  • Status wiadomości może być wykorzystany do stworzenia szczegółowego widoku tego, kto otrzymał/wyświetlił daną wiadomość. Jednak znaczniki czasu tych zdarzeń nie są przechowywane, ponieważ stanowiłoby to zbyt dużą ilość danych.