mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-19 07:37:11 +02:00
Support t.me/+phonenumber links.
This commit is contained in:
parent
f7957a8903
commit
bea2cfd363
6 changed files with 81 additions and 21 deletions
|
@ -304,6 +304,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_username_bad_symbols" = "Only a-z, 0-9, and underscores allowed.";
|
||||
"lng_username_available" = "This username is available.";
|
||||
"lng_username_not_found" = "User @{user} not found.";
|
||||
"lng_username_by_phone_not_found" = "User {phone} not found.";
|
||||
"lng_username_link_willbe" = "This link will open a chat with you:";
|
||||
"lng_username_link" = "This link opens a chat with you:";
|
||||
"lng_username_copied" = "Link copied to clipboard.";
|
||||
|
|
|
@ -251,7 +251,7 @@ bool ShowWallPaper(
|
|||
params);
|
||||
}
|
||||
|
||||
bool ResolveUsername(
|
||||
bool ResolveUsernameOrPhone(
|
||||
Window::SessionController *controller,
|
||||
const Match &match,
|
||||
const QVariant &context) {
|
||||
|
@ -262,16 +262,20 @@ bool ResolveUsername(
|
|||
match->captured(1),
|
||||
qthelp::UrlParamNameTransform::ToLower);
|
||||
const auto domain = params.value(qsl("domain"));
|
||||
const auto valid = [](const QString &domain) {
|
||||
const auto phone = params.value(qsl("phone"));
|
||||
const auto validDomain = [](const QString &domain) {
|
||||
return qthelp::regex_match(
|
||||
qsl("^[a-zA-Z0-9\\.\\_]+$"),
|
||||
domain,
|
||||
{}
|
||||
).valid();
|
||||
};
|
||||
const auto validPhone = [](const QString &phone) {
|
||||
return qthelp::regex_match(qsl("^[0-9]+$"), phone, {}).valid();
|
||||
};
|
||||
if (domain == qsl("telegrampassport")) {
|
||||
return ShowPassportForm(controller, params);
|
||||
} else if (!valid(domain)) {
|
||||
} else if (!validDomain(domain) && !validPhone(phone)) {
|
||||
return false;
|
||||
}
|
||||
auto start = qsl("start");
|
||||
|
@ -295,7 +299,7 @@ bool ResolveUsername(
|
|||
const auto threadParam = params.value(qsl("thread"));
|
||||
const auto threadId = threadParam.toInt();
|
||||
const auto gameParam = params.value(qsl("game"));
|
||||
if (!gameParam.isEmpty() && valid(gameParam)) {
|
||||
if (!gameParam.isEmpty() && validDomain(gameParam)) {
|
||||
startToken = gameParam;
|
||||
post = ShowAtGameShareMsgId;
|
||||
}
|
||||
|
@ -303,6 +307,7 @@ bool ResolveUsername(
|
|||
using Navigation = Window::SessionNavigation;
|
||||
controller->showPeerByLink(Navigation::PeerByLinkInfo{
|
||||
.usernameOrId = domain,
|
||||
.phone = phone,
|
||||
.messageId = post,
|
||||
.repliesInfo = commentId
|
||||
? Navigation::RepliesByLinkInfo{
|
||||
|
@ -682,7 +687,7 @@ const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
|
|||
},
|
||||
{
|
||||
qsl("^resolve/?\\?(.+)(#|$)"),
|
||||
ResolveUsername
|
||||
ResolveUsernameOrPhone
|
||||
},
|
||||
{
|
||||
qsl("^privatepost/?\\?(.+)(#|$)"),
|
||||
|
@ -732,7 +737,9 @@ QString TryConvertUrlToLocal(QString url) {
|
|||
auto telegramMeMatch = regex_match(qsl("^(https?://)?(www\\.)?(telegram\\.(me|dog)|t\\.me)/(.+)$"), url, matchOptions);
|
||||
if (telegramMeMatch) {
|
||||
auto query = telegramMeMatch->capturedView(5);
|
||||
if (auto joinChatMatch = regex_match(qsl("^(joinchat/|\\+|\\%20)([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"), query, matchOptions)) {
|
||||
if (auto phoneMatch = regex_match(qsl("^\\+([0-9]+)(\\?|$)"), query, matchOptions)) {
|
||||
return qsl("tg://resolve?phone=") + phoneMatch->captured(1);
|
||||
} else if (auto joinChatMatch = regex_match(qsl("^(joinchat/|\\+|\\%20)([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"), query, matchOptions)) {
|
||||
return qsl("tg://join?invite=") + url_encode(joinChatMatch->captured(2));
|
||||
} else if (auto stickerSetMatch = regex_match(qsl("^addstickers/([a-zA-Z0-9\\.\\_]+)(\\?|$)"), query, matchOptions)) {
|
||||
return qsl("tg://addstickers?set=") + url_encode(stickerSetMatch->captured(1));
|
||||
|
@ -778,7 +785,7 @@ QString TryConvertUrlToLocal(QString url) {
|
|||
if (auto postMatch = regex_match(qsl("^/\\d+/?(?:\\?|$)"), usernameMatch->captured(2))) {
|
||||
postParam = qsl("&post=") + usernameMatch->captured(3);
|
||||
}
|
||||
return qsl("tg://resolve/?domain=") + url_encode(usernameMatch->captured(1)) + postParam + (params.isEmpty() ? QString() : '&' + params);
|
||||
return qsl("tg://resolve?domain=") + url_encode(usernameMatch->captured(1)) + postParam + (params.isEmpty() ? QString() : '&' + params);
|
||||
}
|
||||
}
|
||||
return url;
|
||||
|
|
|
@ -914,6 +914,18 @@ void Session::unregisterInvitedToCallUser(
|
|||
}
|
||||
}
|
||||
|
||||
UserData *Session::userByPhone(const QString &phone) const {
|
||||
const auto pname = phone.trimmed();
|
||||
for (const auto &[peerId, peer] : _peers) {
|
||||
if (const auto user = peer->asUser()) {
|
||||
if (user->phone() == pname) {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PeerData *Session::peerByUsername(const QString &username) const {
|
||||
const auto uname = username.trimmed();
|
||||
for (const auto &[peerId, peer] : _peers) {
|
||||
|
|
|
@ -190,6 +190,7 @@ public:
|
|||
void enumerateUsers(Fn<void(not_null<UserData*>)> action) const;
|
||||
void enumerateGroups(Fn<void(not_null<PeerData*>)> action) const;
|
||||
void enumerateChannels(Fn<void(not_null<ChannelData*>)> action) const;
|
||||
[[nodiscard]] UserData *userByPhone(const QString &phone) const;
|
||||
[[nodiscard]] PeerData *peerByUsername(const QString &username) const;
|
||||
|
||||
[[nodiscard]] not_null<History*> history(PeerId peerId);
|
||||
|
|
|
@ -48,6 +48,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/unixtime.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/text/format_values.h" // Ui::FormatPhone.
|
||||
#include "ui/delayed_activation.h"
|
||||
#include "ui/chat/message_bubble.h"
|
||||
#include "ui/chat/chat_style.h"
|
||||
|
@ -175,8 +176,12 @@ Main::Session &SessionNavigation::session() const {
|
|||
|
||||
void SessionNavigation::showPeerByLink(const PeerByLinkInfo &info) {
|
||||
Core::App().hideMediaView();
|
||||
if (const auto username = std::get_if<QString>(&info.usernameOrId)) {
|
||||
resolveUsername(*username, [=](not_null<PeerData*> peer) {
|
||||
if (!info.phone.isEmpty()) {
|
||||
resolvePhone(info.phone, [=](not_null<PeerData*> peer) {
|
||||
showPeerByLinkResolved(peer, info);
|
||||
});
|
||||
} else if (const auto name = std::get_if<QString>(&info.usernameOrId)) {
|
||||
resolveUsername(*name, [=](not_null<PeerData*> peer) {
|
||||
showPeerByLinkResolved(peer, info);
|
||||
});
|
||||
} else if (const auto id = std::get_if<ChannelId>(&info.usernameOrId)) {
|
||||
|
@ -186,6 +191,29 @@ void SessionNavigation::showPeerByLink(const PeerByLinkInfo &info) {
|
|||
}
|
||||
}
|
||||
|
||||
void SessionNavigation::resolvePhone(
|
||||
const QString &phone,
|
||||
Fn<void(not_null<PeerData*>)> done) {
|
||||
if (const auto peer = _session->data().userByPhone(phone)) {
|
||||
done(peer);
|
||||
return;
|
||||
}
|
||||
_session->api().request(base::take(_resolveRequestId)).cancel();
|
||||
_resolveRequestId = _session->api().request(MTPcontacts_ResolvePhone(
|
||||
MTP_string(phone)
|
||||
)).done([=](const MTPcontacts_ResolvedPeer &result) {
|
||||
resolveDone(result, done);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_resolveRequestId = 0;
|
||||
if (error.code() == 400) {
|
||||
show(Ui::MakeInformBox(tr::lng_username_by_phone_not_found(
|
||||
tr::now,
|
||||
lt_phone,
|
||||
Ui::FormatPhone(phone))));
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
void SessionNavigation::resolveUsername(
|
||||
const QString &username,
|
||||
Fn<void(not_null<PeerData*>)> done) {
|
||||
|
@ -197,18 +225,7 @@ void SessionNavigation::resolveUsername(
|
|||
_resolveRequestId = _session->api().request(MTPcontacts_ResolveUsername(
|
||||
MTP_string(username)
|
||||
)).done([=](const MTPcontacts_ResolvedPeer &result) {
|
||||
_resolveRequestId = 0;
|
||||
Ui::hideLayer();
|
||||
if (result.type() != mtpc_contacts_resolvedPeer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &d(result.c_contacts_resolvedPeer());
|
||||
_session->data().processUsers(d.vusers());
|
||||
_session->data().processChats(d.vchats());
|
||||
if (const auto peerId = peerFromMTP(d.vpeer())) {
|
||||
done(_session->data().peer(peerId));
|
||||
}
|
||||
resolveDone(result, done);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_resolveRequestId = 0;
|
||||
if (error.code() == 400) {
|
||||
|
@ -218,6 +235,20 @@ void SessionNavigation::resolveUsername(
|
|||
}).send();
|
||||
}
|
||||
|
||||
void SessionNavigation::resolveDone(
|
||||
const MTPcontacts_ResolvedPeer &result,
|
||||
Fn<void(not_null<PeerData*>)> done) {
|
||||
_resolveRequestId = 0;
|
||||
Ui::hideLayer();
|
||||
result.match([&](const MTPDcontacts_resolvedPeer &data) {
|
||||
_session->data().processUsers(data.vusers());
|
||||
_session->data().processChats(data.vchats());
|
||||
if (const auto peerId = peerFromMTP(data.vpeer())) {
|
||||
done(_session->data().peer(peerId));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SessionNavigation::resolveChannelById(
|
||||
ChannelId channelId,
|
||||
Fn<void(not_null<ChannelData*>)> done) {
|
||||
|
|
|
@ -173,6 +173,7 @@ public:
|
|||
using RepliesByLinkInfo = std::variant<v::null_t, CommentId, ThreadId>;
|
||||
struct PeerByLinkInfo {
|
||||
std::variant<QString, ChannelId> usernameOrId;
|
||||
QString phone;
|
||||
MsgId messageId = ShowAtUnreadMsgId;
|
||||
RepliesByLinkInfo repliesInfo;
|
||||
QString startToken;
|
||||
|
@ -230,6 +231,9 @@ public:
|
|||
|
||||
|
||||
private:
|
||||
void resolvePhone(
|
||||
const QString &phone,
|
||||
Fn<void(not_null<PeerData*>)> done);
|
||||
void resolveUsername(
|
||||
const QString &username,
|
||||
Fn<void(not_null<PeerData*>)> done);
|
||||
|
@ -237,6 +241,10 @@ private:
|
|||
ChannelId channelId,
|
||||
Fn<void(not_null<ChannelData*>)> done);
|
||||
|
||||
void resolveDone(
|
||||
const MTPcontacts_ResolvedPeer &result,
|
||||
Fn<void(not_null<PeerData*>)> done);
|
||||
|
||||
void showPeerByLinkResolved(
|
||||
not_null<PeerData*> peer,
|
||||
const PeerByLinkInfo &info);
|
||||
|
|
Loading…
Add table
Reference in a new issue