Skip to content

fix: do not mark call message as seen when accepting or declining a call - #8633

Open
link2xt wants to merge 1 commit into
mainfrom
link2xt/decline-call-not-mark-messages-as-noticed
Open

fix: do not mark call message as seen when accepting or declining a call#8633
link2xt wants to merge 1 commit into
mainfrom
link2xt/decline-call-not-mark-messages-as-noticed

Conversation

@link2xt

@link2xt link2xt commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

When the message is marked as seen, an MDN (read receipt) is sent to self
and receiving such MDN marks all messages in the chat above the call message as noticed.
Calls may be accepted or declined from the notification,
so user may accept or decline a call without ever seeing a call message in the chat.

Closes #8631

@link2xt
link2xt force-pushed the link2xt/decline-call-not-mark-messages-as-noticed branch from 49467e9 to 3784b3e Compare August 27, 2026 16:37
@link2xt link2xt changed the title test: test that declining a call does not mark the messages as noticed fix: do not mark call message as seen when declining a call Aug 27, 2026
@link2xt
link2xt marked this pull request as ready for review August 27, 2026 16:38

@hpk42 hpk42 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am afraid I don't quite get the overall scheme of how caller/callee and their multi-device setups are meant to land in consistent states including UI notifications/interactions. I filed an issue #8635 and is it not strictly related to this particular PR.

For this PR my main concern is that the second device of the Callee might be left with a "Missed call" notifcation if there is no self-MDN anymore. As far as i see, at receiving time, a stale-on-arrival call notifies via

core/src/calls.rs

Lines 368 to 372 in 3784b3e

if call.is_incoming() {
if call.is_stale() {
let missed_call_str = stock_str::missed_call(self);
call.update_text(self, &missed_call_str).await?;
self.emit_incoming_msg(call.msg.chat_id, call_id); // notify missed call
and i don't see what removes that notification afterwards.

The accepted-call path should probably be handled before #8631 can be closed but it doesn't necessarily block this PR i guess.

Comment thread src/calls.rs Outdated
Comment thread src/calls.rs
(MessageState::InNoticed, call_id, MessageState::InFresh),
)
.await
.context("Failed to mark incoming call as noticed")?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This by itself does not send out anything, right?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just marks the message as noticed, as if you opened a chat with the message off the screen. Nothing is sent as a result and the message may still be marked as seen once the user opens the chat and the message appears on the screen, then MDN will be sent.

@link2xt
link2xt marked this pull request as draft August 28, 2026 19:07
@link2xt
link2xt force-pushed the link2xt/decline-call-not-mark-messages-as-noticed branch 2 times, most recently from 0e63c4f to 981ec3d Compare August 28, 2026 19:30
@link2xt

link2xt commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author

For this PR my main concern is that the second device of the Callee might be left with a "Missed call" notifcation if there is no self-MDN anymore.

As far as I understand, this does not depend on MDNs. Declining a call (ending unaccepted call) sends SystemMessage::CallEnded, also as a copy to self if bcc_self (multi-device mode) is enabled. When second device receives it, it will turn the call into declined call:

core/src/calls.rs

Lines 463 to 468 in 322dd11

if call.is_incoming() {
if from_id == ContactId::SELF {
call.mark_as_ended(self).await?;
let declined_call_str = stock_str::declined_call(self);
call.update_text(self, &declined_call_str).await?;
} else {

If second device comes online much later, it should first receive "missed call", but then a copy of "call ended" message should turn it into declined call. UI may show "missed call" notification for a moment and should probably wait for IncomingMsgBunch event before showing any notifications to avoid notifying about missed call just before "call ended" arrives and it would be nice if the core postponed emitting "missed call" event until fetching is finished, but that's a separate problem.

The accepted-call path should probably be handled before #8631 can be closed but it doesn't necessarily block this PR i guess.

I fixed accepted calls as well, now only need to cleanup all SQL calls.

@link2xt
link2xt force-pushed the link2xt/decline-call-not-mark-messages-as-noticed branch from 981ec3d to a31d221 Compare August 28, 2026 20:40
When the message is marked as seen, an MDN (read receipt) is sent to self
and receiving such MDN marks all messages in the chat above the call message as noticed.
Calls may be accepted or declined from the notification,
so user may accept or decline a call without ever seeing a call message in the chat.
@link2xt
link2xt force-pushed the link2xt/decline-call-not-mark-messages-as-noticed branch from a31d221 to 58d5ab9 Compare August 28, 2026 20:46
@link2xt link2xt changed the title fix: do not mark call message as seen when declining a call fix: do not mark call message as seen when accepting or declining a call Aug 28, 2026
@link2xt
link2xt marked this pull request as ready for review August 28, 2026 20:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Declining a call desyncs read states between devices

2 participants