feat: disappearing messages support - #522
Conversation
|
Thank you for taking the time to implement this feature! The timer is sent on outgoing messages, so it's not reset every time a message is written in gurk. That's great! But the messages are not yet deleted in gurk itself. I set the timer to 30s in the "Note to self" chat. While the desktop client deleted the message just fine, gurk still has it saved even after a restart. Edit: The general "delete message from view" logic seems to be fine. If I delete a message manually in the desktop client, it is deleted in gurk as well. |
|
I tested the feature with "Note to Self" chat where it currently doesn't expire anything. I can confirm this works with regular chats though. Thank you! |
Both should work now. There are multiple parallel paths we could refactor to avoid some of this. I made a note to consider this later once we see what if anything can be merged here. |
|
Works like a charm. Lgtm! |
Implements Signal's disappearing messages (expiring message timers). ## Outgoing messages - Read expire_timer from Channel, set on outgoing DataMessage - Fixes messages sent from gurk not carrying the timer (boxdot#79) ## Incoming messages - Extract expire_timer from DataMessage (both direct and sync-sent) - Update per-channel timer (stored in DB, persists across restarts) - Handle timer disable (expire_timer: None clears channel timer) - Per-message expire_timer persisted for correct activation ## Timer activation (start-on-view) - Messages show [pending] until channel is viewed for 10+ seconds - After dwell, expires_at is set and countdown begins - New messages arriving in an already-viewed channel activate eagerly - Activation runs once per channel selection (no repeated scanning) - Outgoing messages activate immediately (sender starts on send) ## Expiration - Sweep every 5 seconds removes messages past expires_at - Only scans channels with expire_timer enabled - Partial index on expires_at for efficient queries ## UI - Channel title shows timer setting (e.g. [1m], [1w]) - Per-message countdown ([pending], [45s], [expired]) - format_duration_short() helper for consistent formatting ## Schema - channels: add expire_timer column - messages: add expire_timer and expires_at columns - Partial index on messages.expires_at Closes boxdot#79
The Private note message match arm did not extract expire_timer from the DataMessage (swallowed by ..). Messages sent to Note to Self never had their timer set, so they never expired. Extract expire_timer, update the channel timer, and set it on the Message struct — same pattern as the sync-sent and incoming DataMessage arms.
The countdown label was only rendered in the else branch (non-deleted messages). Move add_expire_countdown() outside the if/else so tombstones show [message deleted] [30s] or [message deleted] [expired].
fa27670 to
679a8da
Compare
|
@boxdot rebased |
Implements Signal's disappearing messages (expiring message timers).
Depends on #519 (message deletion) — uses
remove_message()from that PR.Closes #79
Outgoing messages
expire_timerfrom Channel, set on outgoingDataMessageIncoming messages
expire_timerfromDataMessage(both direct and sync-sent)expire_timer: Noneclears channel timer)expire_timerpersisted for correct activationTimer activation (start-on-view)
[pending]until channel is viewed for 10+ secondsexpires_atis set and countdown beginsExpiration
expires_atexpire_timerenabledexpires_atfor efficient queriesUI
[1m],[1w])[pending],[45s],[expired])format_duration_short()helper for consistent formattingSchema (migration 005)
channels: addexpire_timercolumnmessages: addexpire_timerandexpires_atcolumnsmessages.expires_atKnown limitations
each individual message (matches Signal Desktop behavior)
(tracked separately)
upsert) by storing the timer independently on the channel
Tested: incoming/outgoing timers, timer disable, persistence across
restarts, start-on-view with 10s dwell, countdown UI, expiration sweep.