From a479459d766def0034460f128bfa23e11632e480 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 29 Mar 2026 13:33:43 +0300 Subject: [PATCH] Added support of link to specific option in poll. --- Telegram/Resources/langs/lang.strings | 1 + Telegram/SourceFiles/core/local_url_handlers.cpp | 7 +++++++ Telegram/SourceFiles/data/data_poll.cpp | 9 +++++++++ Telegram/SourceFiles/data/data_poll.h | 3 +++ .../history/view/history_view_context_menu.cpp | 15 +++++++++++++++ .../window/window_session_controller.cpp | 2 ++ .../window/window_session_controller_link_info.h | 1 + 7 files changed, 38 insertions(+) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index bb81b6db33..16c589bc6f 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -4988,6 +4988,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_context_reply_to_task" = "Reply to Task"; "lng_context_reply_to_poll_option" = "Reply to Option"; "lng_context_copy_poll_option" = "Copy Option"; +"lng_context_copy_poll_option_link" = "Copy Option Link"; "lng_context_delete_poll_option" = "Delete Item"; "lng_context_poll_message_tab" = "Poll"; "lng_context_poll_option_tab" = "Option"; diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index d1567d8929..6626de2f3e 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -43,6 +43,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_birthday.h" #include "data/data_channel.h" #include "data/data_document.h" +#include "data/data_poll.h" #include "data/data_session.h" #include "data/data_user.h" #include "media/player/media_player_instance.h" @@ -615,6 +616,8 @@ bool ResolveUsernameOrPhone( const auto threadId = topicId ? topicId : threadParam.toInt(); const auto gameParam = params.value(u"game"_q); const auto videot = params.value(u"t"_q); + const auto pollOption = PollOptionFromLink( + params.value(u"option"_q)); if (params.contains(u"direct"_q)) { resolveType = ResolveType::ChannelDirect; } @@ -633,6 +636,7 @@ bool ResolveUsernameOrPhone( .usernameOrId = domain, .phone = phone, .messageId = post, + .pollOption = pollOption, .storyParam = storyParam, .storyAlbumId = storyAlbumId, .giftCollectionId = giftCollectionId, @@ -704,6 +708,8 @@ bool ResolvePrivatePost( const auto topicId = topicParam.toInt(); const auto threadParam = params.value(u"thread"_q); const auto threadId = topicId ? topicId : threadParam.toInt(); + const auto pollOption = PollOptionFromLink( + params.value(u"option"_q)); if (!channelId || (msgId && !IsServerMsgId(msgId))) { return false; } @@ -711,6 +717,7 @@ bool ResolvePrivatePost( controller->showPeerByLink(Window::PeerByLinkInfo{ .usernameOrId = channelId, .messageId = msgId, + .pollOption = pollOption, .repliesInfo = commentId ? Window::RepliesByLinkInfo{ Window::CommentId{ commentId } diff --git a/Telegram/SourceFiles/data/data_poll.cpp b/Telegram/SourceFiles/data/data_poll.cpp index 9cf2197195..e3124bb59a 100644 --- a/Telegram/SourceFiles/data/data_poll.cpp +++ b/Telegram/SourceFiles/data/data_poll.cpp @@ -491,6 +491,15 @@ PollMedia PollMediaFromInputMTP( return result; } +QByteArray PollOptionFromLink(const QString &value) { + return QByteArray::fromBase64(value.toLatin1()); +} + +QString PollOptionToLink(const QByteArray &option) { + return QString::fromLatin1( + option.toBase64(QByteArray::OmitTrailingEquals)); +} + MTPPoll PollDataToMTP(not_null poll, bool close) { const auto convert = [&](const PollAnswer &answer) { const auto flags = answer.media diff --git a/Telegram/SourceFiles/data/data_poll.h b/Telegram/SourceFiles/data/data_poll.h index c257cb91d8..8dc87b4797 100644 --- a/Telegram/SourceFiles/data/data_poll.h +++ b/Telegram/SourceFiles/data/data_poll.h @@ -131,6 +131,9 @@ private: }; +[[nodiscard]] QByteArray PollOptionFromLink(const QString &value); +[[nodiscard]] QString PollOptionToLink(const QByteArray &option); + [[nodiscard]] MTPPoll PollDataToMTP( not_null poll, bool close = false); diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index 4c37b01f43..04ca626c27 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -1602,6 +1602,21 @@ void FillPollOptionPage( TextUtilities::SetClipboardText(text); }, &st::menuIconCopy); + if (item->hasDirectLink()) { + const auto link = item->history()->session().api() + .exportDirectMessageLink(item, false); + const auto separator = (link.indexOf('?') >= 0) ? u'&' : u'?'; + const auto optionLink = link + + separator + + u"option="_q + + PollOptionToLink(pollOption); + menu->addAction( + tr::lng_context_copy_poll_option_link(tr::now), + [optionLink] { + QGuiApplication::clipboard()->setText(optionLink); + }, + &st::menuIconLink); + } const auto canDelete = [&] { if (!a->addedDate) { return false; diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index bbaaaa95bb..d9c24641e9 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -596,6 +596,7 @@ void SessionNavigation::showMessageByLinkResolved( params.origin = SectionShow::OriginMessage{ info.clickFromMessageId }; + params.highlight.pollOption = info.pollOption; const auto peer = item->history()->peer; const auto topicId = peer->isForum() ? item->topicRootId() : 0; if (topicId) { @@ -615,6 +616,7 @@ void SessionNavigation::showPeerByLinkResolved( params.origin = SectionShow::OriginMessage{ info.clickFromMessageId }; + params.highlight.pollOption = info.pollOption; if (info.voicechatHash && peer->isChannel()) { // First show the channel itself. crl::on_main(this, [=] { diff --git a/Telegram/SourceFiles/window/window_session_controller_link_info.h b/Telegram/SourceFiles/window/window_session_controller_link_info.h index a8ecd9ac5d..a07a28508f 100644 --- a/Telegram/SourceFiles/window/window_session_controller_link_info.h +++ b/Telegram/SourceFiles/window/window_session_controller_link_info.h @@ -40,6 +40,7 @@ struct PeerByLinkInfo { QString phone; QString chatLinkSlug; MsgId messageId = ShowAtUnreadMsgId; + QByteArray pollOption; QString storyParam; int storyAlbumId = 0; int giftCollectionId = 0;