Handle chat link clicks.

This commit is contained in:
John Preston 2024-03-26 19:13:26 +04:00
parent 3d54f8ec49
commit f240cbbda6
6 changed files with 96 additions and 2 deletions

View file

@ -977,6 +977,24 @@ bool ResolveBoost(
return true;
}
bool ResolveChatLink(
Window::SessionController *controller,
const Match &match,
const QVariant &context) {
if (!controller) {
return false;
}
const auto myContext = context.value<ClickHandlerContext>();
const auto slug = match->captured(1);
controller->window().activate();
controller->showPeerByLink(Window::PeerByLinkInfo{
.chatLinkSlug = match->captured(1),
.clickFromMessageId = myContext.itemId,
.clickFromAttachBotWebviewUrl = myContext.attachBotWebviewUrl,
});
return true;
}
} // namespace
const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
@ -1046,11 +1064,11 @@ const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
ResolveTestChatTheme,
},
{
u"invoice/?\\?(.+)(#|$)"_q,
u"^invoice/?\\?(.+)(#|$)"_q,
ResolveInvoice,
},
{
u"premium_offer/?(\\?.+)?(#|$)"_q,
u"^premium_offer/?(\\?.+)?(#|$)"_q,
ResolvePremiumOffer,
},
{
@ -1065,6 +1083,10 @@ const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
u"^boost/?\\?(.+)(#|$)"_q,
ResolveBoost,
},
{
u"^message/?\\?slug=([a-zA-Z0-9\\.\\_]+)(&|$)"_q,
ResolveChatLink
},
{
u"^([^\\?]+)(\\?|#|$)"_q,
HandleUnknown
@ -1176,6 +1198,9 @@ QString TryConvertUrlToLocal(QString url) {
? "gradient"
: "slug";
return u"tg://bg?"_q + type + '=' + bg + (params.isEmpty() ? QString() : '&' + params);
} else if (const auto chatlinkMatch = regex_match(u"^m/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"_q, query, matchOptions)) {
const auto slug = chatlinkMatch->captured(1);
return u"tg://message?slug="_q + slug;
} else if (const auto privateMatch = regex_match(u"^"
"c/(\\-?\\d+)"
"("

View file

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_widget.h"
#include "history/history_item_components.h"
#include "main/main_session.h"
#include "data/data_changes.h"
#include "data/data_session.h"
#include "data/data_web_page.h"
#include "mainwidget.h"
@ -128,4 +129,29 @@ void ClearPeerCloudDraft(
history->applyCloudDraft(topicRootId);
}
void SetChatLinkDraft(
not_null<PeerData*> peer,
const TextWithEntities &draft) {
const auto textWithTags = TextWithTags{
draft.text,
TextUtilities::ConvertEntitiesToTextTags(draft.entities)
};
const auto cursor = MessageCursor{
int(textWithTags.text.size()),
int(textWithTags.text.size()),
Ui::kQFixedMax
};
const auto history = peer->owner().history(peer->id);
const auto topicRootId = MsgId();
history->setLocalDraft(std::make_unique<Data::Draft>(
textWithTags,
FullReplyTo{ .topicRootId = topicRootId },
cursor,
Data::WebPageDraft()));
history->clearLocalEditDraft(topicRootId);
history->session().changes().entryUpdated(
history,
Data::EntryUpdate::Flag::LocalDraftSet);
}
} // namespace Data

View file

@ -205,4 +205,8 @@ using HistoryDrafts = base::flat_map<DraftKey, std::unique_ptr<Draft>>;
&& (a->webpage == b->webpage);
}
void SetChatLinkDraft(
not_null<PeerData*> peer,
const TextWithEntities &draft);
} // namespace Data

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "window/window_session_controller.h"
#include "api/api_text_entities.h"
#include "boxes/add_contact_box.h"
#include "boxes/peers/add_bot_to_chat_box.h"
#include "boxes/peers/edit_peer_info_box.h"
@ -307,6 +308,13 @@ void SessionNavigation::showPeerByLink(const PeerByLinkInfo &info) {
resolvePhone(info.phone, [=](not_null<PeerData*> peer) {
showPeerByLinkResolved(peer, info);
});
} else if (!info.chatLinkSlug.isEmpty()) {
resolveChatLink(info.chatLinkSlug, [=](
not_null<PeerData*> peer,
TextWithEntities draft) {
Data::SetChatLinkDraft(peer, draft);
showPeerByLinkResolved(peer, info);
});
} else if (const auto name = std::get_if<QString>(&info.usernameOrId)) {
resolveUsername(*name, [=](not_null<PeerData*> peer) {
if (info.startAutoSubmit) {
@ -352,6 +360,33 @@ void SessionNavigation::resolvePhone(
}).send();
}
void SessionNavigation::resolveChatLink(
const QString &slug,
Fn<void(not_null<PeerData*> peer, TextWithEntities draft)> done) {
_api.request(base::take(_resolveRequestId)).cancel();
_resolveRequestId = _api.request(MTPaccount_ResolveBusinessChatLink(
MTP_string(slug)
)).done([=](const MTPaccount_ResolvedBusinessChatLinks &result) {
_resolveRequestId = 0;
parentController()->hideLayer();
const auto &data = result.data();
_session->data().processUsers(data.vusers());
_session->data().processChats(data.vchats());
using namespace Api;
const auto peerId = peerFromMTP(data.vpeer());
done(_session->data().peer(peerId), {
qs(data.vmessage()),
EntitiesFromMTP(_session, data.ventities().value_or_empty())
});
}).fail([=](const MTP::Error &error) {
_resolveRequestId = 0;
if (error.code() == 400) {
showToast(tr::lng_confirm_phone_link_invalid(tr::now));
}
}).send();
}
void SessionNavigation::resolveUsername(
const QString &username,
Fn<void(not_null<PeerData*>)> done) {

View file

@ -260,6 +260,9 @@ private:
void resolvePhone(
const QString &phone,
Fn<void(not_null<PeerData*>)> done);
void resolveChatLink(
const QString &slug,
Fn<void(not_null<PeerData*> peer, TextWithEntities draft)> done);
void resolveUsername(
const QString &username,
Fn<void(not_null<PeerData*>)> done);

View file

@ -31,6 +31,7 @@ using RepliesByLinkInfo = std::variant<v::null_t, CommentId, ThreadId>;
struct PeerByLinkInfo {
std::variant<QString, ChannelId> usernameOrId;
QString phone;
QString chatLinkSlug;
MsgId messageId = ShowAtUnreadMsgId;
StoryId storyId = 0;
RepliesByLinkInfo repliesInfo;