From 52953626a7169642bfe7b9129e2df723b7970a5b Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 4 Nov 2024 15:22:13 +0400 Subject: [PATCH] Allow ctrl/cmd+click copy private post link. --- Telegram/Resources/langs/lang.strings | 2 ++ Telegram/SourceFiles/apiwrap.cpp | 11 +++++--- Telegram/SourceFiles/apiwrap.h | 3 ++- .../view/history_view_context_menu.cpp | 26 +++++++++++++++---- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 330f90d70..ce54557e1 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2101,6 +2101,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_channel_public_link_copied" = "Link copied to clipboard."; "lng_context_about_private_link" = "This link will only work for members of this chat."; +"lng_public_post_private_hint_ctrl" = "Use Ctrl+Click to copy a non-public link."; +"lng_public_post_private_hint_cmd" = "Use Cmd+Click to copy a non-public link."; "lng_forwarded" = "Forwarded from {user}"; "lng_forwarded_story" = "Story from {user}"; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index f69e9c18c..b8d51732b 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -708,7 +708,8 @@ void ApiWrap::finalizeMessageDataRequest( QString ApiWrap::exportDirectMessageLink( not_null item, - bool inRepliesContext) { + bool inRepliesContext, + bool forceNonPublicLink) { Expects(item->history()->peer->isChannel()); const auto itemId = item->fullId(); @@ -731,7 +732,7 @@ QString ApiWrap::exportDirectMessageLink( const auto sender = root ? root->discussionPostOriginalSender() : nullptr; - if (sender && sender->hasUsername()) { + if (sender && sender->hasUsername() && !forceNonPublicLink) { // Comment to a public channel. const auto forwarded = root->Get(); linkItemId = forwarded->savedFromMsgId; @@ -747,7 +748,7 @@ QString ApiWrap::exportDirectMessageLink( } } } - const auto base = linkChannel->hasUsername() + const auto base = (linkChannel->hasUsername() && !forceNonPublicLink) ? linkChannel->username() : "c/" + QString::number(peerToChannel(linkChannel->id).bare); const auto post = QString::number(linkItemId.bare); @@ -761,6 +762,7 @@ QString ApiWrap::exportDirectMessageLink( ? (QString::number(linkThreadId.bare) + '/' + post) : post); if (linkChannel->hasUsername() + && !forceNonPublicLink && !linkChannel->isMegagroup() && !linkCommentId && !linkThreadId) { @@ -774,6 +776,9 @@ QString ApiWrap::exportDirectMessageLink( } return session().createInternalLinkFull(query); }; + if (forceNonPublicLink) { + return fallback(); + } const auto i = _unlikelyMessageLinks.find(itemId); const auto current = (i != end(_unlikelyMessageLinks)) ? i->second diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 18a505de9..7cff89c71 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -164,7 +164,8 @@ public: void requestMessageData(PeerData *peer, MsgId msgId, Fn done); QString exportDirectMessageLink( not_null item, - bool inRepliesContext); + bool inRepliesContext, + bool forceNonPublicLink = false); QString exportDirectStoryLink(not_null item); void requestContacts(); diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index 180e44cc6..ba765b3c7 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -98,6 +98,7 @@ namespace { constexpr auto kRescheduleLimit = 20; constexpr auto kTagNameLimit = 12; +constexpr auto kPublicPostLinkToastDuration = 4 * crl::time(1000); bool HasEditMessageAction( const ContextMenuRequest &request, @@ -1307,12 +1308,17 @@ void CopyPostLink( return; } const auto inRepliesContext = (context == Context::Replies); + const auto forceNonPublicLink = base::IsCtrlPressed(); QGuiApplication::clipboard()->setText( item->history()->session().api().exportDirectMessageLink( item, - inRepliesContext)); + inRepliesContext, + forceNonPublicLink)); const auto isPublicLink = [&] { + if (forceNonPublicLink) { + return false; + } const auto channel = item->history()->peer->asChannel(); Assert(channel != nullptr); if (const auto rootId = item->replyToTop()) { @@ -1328,10 +1334,20 @@ void CopyPostLink( } return channel->hasUsername(); }(); - - show->showToast(isPublicLink - ? tr::lng_channel_public_link_copied(tr::now) - : tr::lng_context_about_private_link(tr::now)); + if (isPublicLink) { + show->showToast({ + .text = tr::lng_channel_public_link_copied( + tr::now, Ui::Text::Bold + ).append('\n').append(Platform::IsMac() + ? tr::lng_public_post_private_hint_cmd(tr::now) + : tr::lng_public_post_private_hint_ctrl(tr::now)), + .duration = kPublicPostLinkToastDuration, + }); + } else { + show->showToast(isPublicLink + ? tr::lng_channel_public_link_copied(tr::now) + : tr::lng_context_about_private_link(tr::now)); + } } void CopyStoryLink(