Skip to content

Commit

Permalink
Buffer receipts for messages not in chats
Browse files Browse the repository at this point in the history
Store receipts for messages that do not yet have message widgets (for delayed processing when the widget exists).
This can happen if:
  - a receipt arrives before a sync message (for a message sent from another device), or
  - a receipt arrives before signal-cli `send` process returns (can happen for messages with attachments)
  • Loading branch information
exquo committed Oct 20, 2020
1 parent 08662e7 commit a6544cf
Showing 1 changed file with 29 additions and 2 deletions.
31 changes: 29 additions & 2 deletions scli
Original file line number Diff line number Diff line change
Expand Up @@ -1942,7 +1942,8 @@ class State:
try:
msg_widget = self.get_message_widget(receipt_contact, timestamp)
except ValueError:
pass
# Receipt is received before the msg_widget exists (e.g. before receiving a `sync` message for a message sent from another device)
self.delivery_status.buffer_receipt(timestamp, status, receipt_contact)
else:
self.delivery_status.set(msg_widget, status, when, receipt_contact)

Expand All @@ -1966,6 +1967,8 @@ class State:
self.delivery_status.adjust_timestamp(get_envelope_time(envelope), timestamp_adj)
msg_widget.envelope['timestamp'] = msg_widget.envelope['dataMessage']['timestamp'] = timestamp_adj

self.delivery_status.process_buffered_receipts(msg_widget)

def format_msg(self, message):
message = '\n'.join(textwrap.wrap(message, width=self.cfg.wrap_at))

Expand Down Expand Up @@ -2128,7 +2131,13 @@ class DeliveryStatus:
grp_memb_remaining.remove(grp_member)
except (KeyError, AttributeError):
# This happens when 'read' receipt arrives before 'delivered', or after getting multiple copies of the same receipt message.
return None
grp_memb_remaining = grp_memb_remain_un.delivered
try:
grp_memb_remaining.remove(grp_member)
except (KeyError, AttributeError):
return None
if not grp_memb_remain_un.delivered and grp_memb_remain_un.read:
return 'delivered'

if status == 'delivered':
remaining_unread = grp_memb_remain_un.read
Expand Down Expand Up @@ -2163,6 +2172,7 @@ class DeliveryStatus:
def __init__(self, one_sided):
self._one_sided = one_sided
self._status_map = {}
self._buffered = {}
self._init_markup_text()
self.MAX_GROUP_SIZE = 15

Expand Down Expand Up @@ -2238,6 +2248,23 @@ class DeliveryStatus:

status_detailed.grp_memb_remain_un = self.DelivReadConts(set(group_members), set())

def buffer_receipt(self, timestamp, status, contact):
buffered = self._buffered.setdefault(timestamp, self.DelivReadConts(set(), set()))
buffered_contacts = getattr(buffered, status)
buffered_contacts.add(contact)

def process_buffered_receipts(self, msg_widget):
timestamp = get_envelope_time(msg_widget.envelope)
buffered = self._buffered.get(timestamp)
if buffered is None:
return
status_detailed = self._status_map[timestamp]
for status in buffered._fields:
buffered_contacts = getattr(buffered, status) or []
for contact in buffered_contacts:
self.set(msg_widget, status, receipt_contact=contact)
del self._buffered[timestamp]

def delete(self, envelope):
try:
del self._status_map[get_envelope_time(envelope)]
Expand Down

0 comments on commit a6544cf

Please sign in to comment.