[iOS · Disappearing Messages · #19] Disappearing message remains visible in an open chat after expiry and disappears only after reopening #27

Open
opened 2026-11-06 13:36:19 +00:00 by asemeniv · 1 comment
Member

[iOS · Disappearing Messages · #19] Disappearing message remains visible in an open chat after expiry and disappears only after reopening
Build: TestFlight 1.1.0 (96)
Date: November 6, 2026
Result: Reproduced. Acceptance item #19 remains open.

Related: #19

Summary
A disappearing message remains visible in an open conversation after its expiry timer has elapsed, even though the backend reports a message Expired event.

The message disappears after leaving and reopening the chat. This suggests that the active transcript is not updated when the expiry event is received.

Environment
Sender (A): iPhone 13 Pro Max, iOS 26.7.1, build 96, testman421@another.im

Recipient (B): iPhone 17 Pro Max, iOS 27.0.1, build 96, testman435@another.im

1:1 chat with OMEMO enabled

Steps to reproduce
With Disappearing Messages disabled, send a control message.

Enable Disappearing Messages → 5 minutes.

Send a message and edit it.

Open/read the message on the other device.

Keep the chat open on both devices for more than five minutes.

Check whether the message disappears without navigating away.

Leave the chat and open it again.

Expected result
Once the message expires, it should automatically disappear from the currently open transcript without requiring navigation, a new incoming message, or an application restart.

Messages sent before the disappearing-message timer was enabled should remain.

Actual result
The edited disappearing message remained visible in the open chat after expiry.

On device A:

message Expired was logged at 13:12:53 UTC.

At 13:20 UTC, more than seven minutes later, the expired message was still visible on screen.

According to the tester, the message disappeared after leaving and reopening the chat.

The control message remained, and searches for both the original and edited versions of the expired text returned no results.

Expiry events were present in diagnostics from both devices.

Diagnostics
Device UTC Event
A 13:06:37 ephemeral set_timer, seconds=300
A 13:07:53 Message sent
A 13:08:26 Message edited
A 13:12:53 message Expired
B 13:07:54 message mark_displayed
B 13:14:26 message Expired
The difference in expiry timestamps between the two devices was not investigated as part of this issue.

Suspected cause
Source review of build 96 (529d77d) found that the Swift event mapping handles message Removed, but does not handle message Expired; unknown events are mapped to other.

The existing Removed path removes the message from the active transcript:

XMPPEventKind.from maps message Removed to messageRemoved.

ConversationClient converts it to ConversationEvent.removed.

TranscriptWindow removes the message from the current rows.

Generated TackyWire documentation describes Expired as removing the message and its edits when preserve_history=0, and indicates that it should be handled as Removed by timestamp.

The missing Expired handling is consistent with the observed behavior, but the exact causal chain should be confirmed by development.

Retest criteria
Repeat the scenario with a new control message and a new disappearing message while keeping the chat open.

After Expired, the message must disappear on both devices without navigation or restart.

The message sent before enabling the timer must remain.

The expired message must not reappear after reopening the chat or restarting the app.

Search should return no results for either the original or edited version.

Repeat the same test with an unedited disappearing message.

[iOS · Disappearing Messages · #19] Disappearing message remains visible in an open chat after expiry and disappears only after reopening Build: TestFlight 1.1.0 (96) Date: November 6, 2026 Result: Reproduced. Acceptance item #19 remains open. Related: #19 Summary A disappearing message remains visible in an open conversation after its expiry timer has elapsed, even though the backend reports a message Expired event. The message disappears after leaving and reopening the chat. This suggests that the active transcript is not updated when the expiry event is received. Environment Sender (A): iPhone 13 Pro Max, iOS 26.7.1, build 96, testman421@another.im Recipient (B): iPhone 17 Pro Max, iOS 27.0.1, build 96, testman435@another.im 1:1 chat with OMEMO enabled Steps to reproduce With Disappearing Messages disabled, send a control message. Enable Disappearing Messages → 5 minutes. Send a message and edit it. Open/read the message on the other device. Keep the chat open on both devices for more than five minutes. Check whether the message disappears without navigating away. Leave the chat and open it again. Expected result Once the message expires, it should automatically disappear from the currently open transcript without requiring navigation, a new incoming message, or an application restart. Messages sent before the disappearing-message timer was enabled should remain. Actual result The edited disappearing message remained visible in the open chat after expiry. On device A: message Expired was logged at 13:12:53 UTC. At 13:20 UTC, more than seven minutes later, the expired message was still visible on screen. According to the tester, the message disappeared after leaving and reopening the chat. The control message remained, and searches for both the original and edited versions of the expired text returned no results. Expiry events were present in diagnostics from both devices. Diagnostics Device UTC Event A 13:06:37 ephemeral set_timer, seconds=300 A 13:07:53 Message sent A 13:08:26 Message edited A 13:12:53 message Expired B 13:07:54 message mark_displayed B 13:14:26 message Expired The difference in expiry timestamps between the two devices was not investigated as part of this issue. Suspected cause Source review of build 96 (529d77d) found that the Swift event mapping handles message Removed, but does not handle message Expired; unknown events are mapped to other. The existing Removed path removes the message from the active transcript: XMPPEventKind.from maps message Removed to messageRemoved. ConversationClient converts it to ConversationEvent.removed. TranscriptWindow removes the message from the current rows. Generated TackyWire documentation describes Expired as removing the message and its edits when preserve_history=0, and indicates that it should be handled as Removed by timestamp. The missing Expired handling is consistent with the observed behavior, but the exact causal chain should be confirmed by development. Retest criteria Repeat the scenario with a new control message and a new disappearing message while keeping the chat open. After Expired, the message must disappear on both devices without navigation or restart. The message sent before enabling the timer must remain. The expired message must not reappear after reopening the chat or restarting the app. Search should return no results for either the original or edited version. Repeat the same test with an unedited disappearing message.
Contributor

Fixed in branch fix/app-issues-25-28 (https://dev.another.im/another-im/anotherim-swift/compare/master...fix/app-issues-25-28), commit 0a6073fd: libtacky's message <Expired> (what the app gets, since it keeps no history: preserve_history 0) was not mapped and became .other, so the open transcript kept the row until the chat was reopened. It is now handled as Removed of its timestamp, as TackyWire says; edits go with the row in libtacky's store. Test: ConversationLiveEventsTests plays Expired. Left: the chat list's preview keeps the expired text until the list's next update, since libtacky's chatlist does not follow <Expired>: another-im/libtacky#23.

Fixed in branch `fix/app-issues-25-28` (https://dev.another.im/another-im/anotherim-swift/compare/master...fix/app-issues-25-28), commit 0a6073fd: libtacky's `message <Expired>` (what the app gets, since it keeps no history: `preserve_history` 0) was not mapped and became `.other`, so the open transcript kept the row until the chat was reopened. It is now handled as `Removed` of its timestamp, as TackyWire says; edits go with the row in libtacky's store. Test: ConversationLiveEventsTests plays `Expired`. Left: the chat list's preview keeps the expired text until the list's next update, since libtacky's chatlist does not follow `<Expired>`: another-im/libtacky#23.
Sign in to join this conversation.
No labels
done
fixed
returned
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
another-im/anotherim-swift#27
No description provided.