From c4b1bad4810e5dcf7abc1059b0ae7c995639a898 Mon Sep 17 00:00:00 2001 From: zubiden <19638254+zubiden@users.noreply.github.com> Date: Mon, 1 Jun 2026 01:15:32 +0200 Subject: [PATCH] Poll: Handle unread votes update (#6951) --- src/api/gramjs/updates/mtpUpdateHandler.ts | 14 ++++++++++++- src/api/types/updates.ts | 11 +++++++++- src/global/actions/apiUpdaters/messages.ts | 24 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/api/gramjs/updates/mtpUpdateHandler.ts b/src/api/gramjs/updates/mtpUpdateHandler.ts index d42c4b9be..7610010d7 100644 --- a/src/api/gramjs/updates/mtpUpdateHandler.ts +++ b/src/api/gramjs/updates/mtpUpdateHandler.ts @@ -474,7 +474,9 @@ export function updater(update: Update) { }, }); } else if (update instanceof GramJs.UpdateMessagePoll) { - const { pollId, poll, results } = update; + const { + pollId, poll, results, peer, msgId, topMsgId, + } = update; const apiPoll = poll && buildPoll(poll); const pollResults = buildPollResults(results); @@ -483,6 +485,16 @@ export function updater(update: Update) { pollId: pollId.toString(), pollUpdate: omitUndefined({ summary: apiPoll, results: pollResults }), }); + + if (peer && msgId && results.hasUnreadVotes && !results.min) { + sendApiUpdate({ + '@type': 'updateMessagePollUnread', + chatId: getApiChatIdFromMtpPeer(peer), + messageId: msgId, + threadId: topMsgId || MAIN_THREAD_ID, + pollId: pollId.toString(), + }); + } } else if (update instanceof GramJs.UpdateMessagePollVote) { sendApiUpdate({ '@type': 'updateMessagePollVote', diff --git a/src/api/types/updates.ts b/src/api/types/updates.ts index 57cf84532..bec3737f9 100644 --- a/src/api/types/updates.ts +++ b/src/api/types/updates.ts @@ -389,6 +389,14 @@ export type ApiUpdateMessagePoll = { pollUpdate: Partial; }; +export type ApiUpdateMessagePollUnread = { + '@type': 'updateMessagePollUnread'; + chatId: string; + messageId: number; + threadId: ThreadId; + pollId: string; +}; + export type ApiUpdateMessagePollVote = { '@type': 'updateMessagePollVote'; pollId: string; @@ -937,7 +945,8 @@ export type ApiUpdate = ( | ApiUpdateChatPinned | ApiUpdatePinnedMessageIds | ApiUpdateChatListType | ApiUpdateChatFolder | ApiUpdateChatFoldersOrder | ApiUpdateRecommendedChatFolders | ApiUpdateNewMessage | ApiUpdateMessage | ApiUpdateThreadInfo | ApiUpdateCommonBoxMessages | ApiUpdatePasskeyOption | - ApiUpdateDeleteMessages | ApiUpdateMessagePoll | ApiUpdateMessagePollVote | ApiUpdateDeleteHistory | + ApiUpdateDeleteMessages | ApiUpdateMessagePoll | ApiUpdateMessagePollUnread | ApiUpdateMessagePollVote | + ApiUpdateDeleteHistory | ApiDeleteParticipantHistory | ApiUpdateMessageSendSucceeded | ApiUpdateMessageSendFailed | ApiUpdateServiceNotification | ApiDeleteContact | ApiUpdateUser | ApiUpdateUserStatus | ApiUpdateUserFullInfo | ApiUpdateVideoProcessingPending | ApiUpdatePeerSettings | ApiUpdateUserAlreadyAuthorized | diff --git a/src/global/actions/apiUpdaters/messages.ts b/src/global/actions/apiUpdaters/messages.ts index f46c1a4ef..986253291 100644 --- a/src/global/actions/apiUpdaters/messages.ts +++ b/src/global/actions/apiUpdaters/messages.ts @@ -64,6 +64,7 @@ import { updateQuickReplyMessage, updateScheduledMessage, } from '../../reducers'; +import { addUnreadPollVotes } from '../../reducers/polls'; import { addUnreadReactions, removeUnreadReactions } from '../../reducers/reactions'; import { updateTabState } from '../../reducers/tabs'; import { @@ -923,6 +924,29 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => { break; } + case 'updateMessagePollUnread': { + const { chatId, messageId, threadId } = update; + const readState = selectThreadReadState(global, chatId, threadId); + + if (!readState?.unreadPollVotes) { + actions.loadUnreadPollVotes({ chatId, threadId }); + break; + } + + if (readState.unreadPollVotes.includes(messageId)) break; + + // We can't calculate threads without local messages, so reload instead. + if (!selectChatMessage(global, chatId, messageId)) { + actions.loadUnreadPollVotes({ chatId, threadId }); + break; + } + + global = addUnreadPollVotes({ global, chatId, ids: [messageId] }); + setGlobal(global); + + break; + } + case 'updateServiceNotification': { const { message } = update;