mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Open some telegram.org and Telegram links in IV.
This commit is contained in:
parent
09f07a7a9d
commit
ea178862d8
6 changed files with 146 additions and 60 deletions
|
@ -46,6 +46,7 @@ struct ClickHandlerContext {
|
||||||
bool mayShowConfirmation = false;
|
bool mayShowConfirmation = false;
|
||||||
bool skipBotAutoLogin = false;
|
bool skipBotAutoLogin = false;
|
||||||
bool botStartAutoSubmit = false;
|
bool botStartAutoSubmit = false;
|
||||||
|
bool ignoreIv = false;
|
||||||
// Is filled from peer info.
|
// Is filled from peer info.
|
||||||
PeerData *peer = nullptr;
|
PeerData *peer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/stickers/data_custom_emoji.h"
|
#include "data/stickers/data_custom_emoji.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_sponsored_messages.h"
|
#include "data/data_sponsored_messages.h"
|
||||||
|
#include "iv/iv_instance.h"
|
||||||
#include "ui/text/text_custom_emoji.h"
|
#include "ui/text/text_custom_emoji.h"
|
||||||
#include "ui/basic_click_handlers.h"
|
#include "ui/basic_click_handlers.h"
|
||||||
#include "ui/emoji_config.h"
|
#include "ui/emoji_config.h"
|
||||||
|
@ -237,6 +238,13 @@ bool UiIntegration::handleUrlClick(
|
||||||
} else if (local.startsWith(u"internal:"_q, Qt::CaseInsensitive)) {
|
} else if (local.startsWith(u"internal:"_q, Qt::CaseInsensitive)) {
|
||||||
Core::App().openInternalUrl(local, context);
|
Core::App().openInternalUrl(local, context);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (Iv::PreferForUri(url)
|
||||||
|
&& !context.value<ClickHandlerContext>().ignoreIv) {
|
||||||
|
const auto my = context.value<ClickHandlerContext>();
|
||||||
|
if (const auto controller = my.sessionWindow.get()) {
|
||||||
|
Core::App().iv().openWithIvPreferred(controller, url, context);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parsed = UrlForAutoLogin(url);
|
auto parsed = UrlForAutoLogin(url);
|
||||||
|
|
|
@ -656,50 +656,12 @@ void AttachWebView::botHandleMenuButton(Ui::BotWebView::MenuButton button) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachWebView::botOpenIvLink(QString uri) {
|
void AttachWebView::botOpenIvLink(QString uri) {
|
||||||
const auto parts = uri.split('#');
|
const auto window = _context ? _context->controller.get() : nullptr;
|
||||||
if (parts.isEmpty()) {
|
if (window) {
|
||||||
return;
|
Core::App().iv().openWithIvPreferred(window, uri);
|
||||||
|
} else {
|
||||||
|
Core::App().iv().openWithIvPreferred(_session, uri);
|
||||||
}
|
}
|
||||||
const auto hash = (parts.size() > 1) ? parts[1] : u""_q;
|
|
||||||
const auto url = parts[0];
|
|
||||||
if (const auto i = _ivCache.find(url); i != end(_ivCache)) {
|
|
||||||
const auto page = i->second;
|
|
||||||
if (page && page->iv) {
|
|
||||||
const auto window = _context
|
|
||||||
? _context->controller.get()
|
|
||||||
: nullptr;
|
|
||||||
if (window) {
|
|
||||||
Core::App().iv().show(window, page->iv.get(), hash);
|
|
||||||
} else {
|
|
||||||
Core::App().iv().show(_session, page->iv.get(), hash);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
UrlClickHandler::Open(uri);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (_ivRequestUri == uri) {
|
|
||||||
return;
|
|
||||||
} else if (_ivRequestId) {
|
|
||||||
_session->api().request(_ivRequestId).cancel();
|
|
||||||
}
|
|
||||||
const auto finish = [=](WebPageData *page) {
|
|
||||||
_ivRequestId = 0;
|
|
||||||
_ivRequestUri = QString();
|
|
||||||
_ivCache[url] = page;
|
|
||||||
botOpenIvLink(uri);
|
|
||||||
};
|
|
||||||
_ivRequestUri = uri;
|
|
||||||
_ivRequestId = _session->api().request(MTPmessages_GetWebPage(
|
|
||||||
MTP_string(url),
|
|
||||||
MTP_int(0)
|
|
||||||
)).done([=](const MTPmessages_WebPage &result) {
|
|
||||||
const auto &data = result.data();
|
|
||||||
_session->data().processUsers(data.vusers());
|
|
||||||
_session->data().processChats(data.vchats());
|
|
||||||
finish(_session->data().processWebpage(data.vwebpage()));
|
|
||||||
}).fail([=] {
|
|
||||||
finish(nullptr);
|
|
||||||
}).send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachWebView::botSendData(QByteArray data) {
|
void AttachWebView::botSendData(QByteArray data) {
|
||||||
|
|
|
@ -267,10 +267,6 @@ private:
|
||||||
rpl::event_stream<> _attachBotsUpdates;
|
rpl::event_stream<> _attachBotsUpdates;
|
||||||
base::flat_set<not_null<UserData*>> _disclaimerAccepted;
|
base::flat_set<not_null<UserData*>> _disclaimerAccepted;
|
||||||
|
|
||||||
base::flat_map<QString, WebPageData*> _ivCache;
|
|
||||||
QString _ivRequestUri;
|
|
||||||
mtpRequestId _ivRequestId = 0;
|
|
||||||
|
|
||||||
std::unique_ptr<Ui::BotWebView::Panel> _panel;
|
std::unique_ptr<Ui::BotWebView::Panel> _panel;
|
||||||
bool _catchingCancelInShowCall = false;
|
bool _catchingCancelInShowCall = false;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/file_utilities.h"
|
#include "core/file_utilities.h"
|
||||||
#include "core/shortcuts.h"
|
#include "core/shortcuts.h"
|
||||||
|
#include "core/click_handler_types.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_cloud_file.h"
|
#include "data/data_cloud_file.h"
|
||||||
|
@ -926,20 +927,104 @@ void Instance::show(
|
||||||
}
|
}
|
||||||
}, _shown->lifetime());
|
}, _shown->lifetime());
|
||||||
|
|
||||||
if (!_tracking.contains(session)) {
|
trackSession(session);
|
||||||
_tracking.emplace(session);
|
}
|
||||||
session->lifetime().add([=] {
|
|
||||||
_tracking.remove(session);
|
void Instance::trackSession(not_null<Main::Session*> session) {
|
||||||
_joining.remove(session);
|
if (!_tracking.emplace(session).second) {
|
||||||
_fullRequested.remove(session);
|
return;
|
||||||
if (_shownSession == session) {
|
|
||||||
_shownSession = nullptr;
|
|
||||||
}
|
|
||||||
if (_shown && _shown->showingFrom(session)) {
|
|
||||||
_shown = nullptr;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
session->lifetime().add([=] {
|
||||||
|
_tracking.remove(session);
|
||||||
|
_joining.remove(session);
|
||||||
|
_fullRequested.remove(session);
|
||||||
|
_ivCache.remove(session);
|
||||||
|
if (_ivRequestSession == session) {
|
||||||
|
session->api().request(_ivRequestId).cancel();
|
||||||
|
_ivRequestSession = nullptr;
|
||||||
|
_ivRequestUri = QString();
|
||||||
|
_ivRequestId = 0;
|
||||||
|
}
|
||||||
|
if (_shownSession == session) {
|
||||||
|
_shownSession = nullptr;
|
||||||
|
}
|
||||||
|
if (_shown && _shown->showingFrom(session)) {
|
||||||
|
_shown = nullptr;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instance::openWithIvPreferred(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
QString uri,
|
||||||
|
QVariant context) {
|
||||||
|
auto my = context.value<ClickHandlerContext>();
|
||||||
|
my.sessionWindow = controller;
|
||||||
|
openWithIvPreferred(
|
||||||
|
&controller->session(),
|
||||||
|
uri,
|
||||||
|
QVariant::fromValue(my));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instance::openWithIvPreferred(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
QString uri,
|
||||||
|
QVariant context) {
|
||||||
|
const auto openExternal = [=] {
|
||||||
|
auto my = context.value<ClickHandlerContext>();
|
||||||
|
my.ignoreIv = true;
|
||||||
|
UrlClickHandler::Open(uri, QVariant::fromValue(my));
|
||||||
|
};
|
||||||
|
const auto parts = uri.split('#');
|
||||||
|
if (parts.isEmpty() || parts[0].isEmpty()) {
|
||||||
|
return;
|
||||||
|
} else if (!ShowButton()) {
|
||||||
|
return openExternal();
|
||||||
|
}
|
||||||
|
trackSession(session);
|
||||||
|
const auto hash = (parts.size() > 1) ? parts[1] : u""_q;
|
||||||
|
const auto url = parts[0];
|
||||||
|
auto &cache = _ivCache[session];
|
||||||
|
if (const auto i = cache.find(url); i != end(cache)) {
|
||||||
|
const auto page = i->second;
|
||||||
|
if (page && page->iv) {
|
||||||
|
auto my = context.value<ClickHandlerContext>();
|
||||||
|
if (const auto window = my.sessionWindow.get()) {
|
||||||
|
show(window, page->iv.get(), hash);
|
||||||
|
} else {
|
||||||
|
show(session, page->iv.get(), hash);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
openExternal();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (_ivRequestSession == session.get() && _ivRequestUri == uri) {
|
||||||
|
return;
|
||||||
|
} else if (_ivRequestId) {
|
||||||
|
_ivRequestSession->api().request(_ivRequestId).cancel();
|
||||||
|
}
|
||||||
|
const auto finish = [=](WebPageData *page) {
|
||||||
|
Expects(_ivRequestSession == session);
|
||||||
|
|
||||||
|
_ivRequestId = 0;
|
||||||
|
_ivRequestUri = QString();
|
||||||
|
_ivRequestSession = nullptr;
|
||||||
|
_ivCache[session][url] = page;
|
||||||
|
openWithIvPreferred(session, uri, context);
|
||||||
|
};
|
||||||
|
_ivRequestSession = session;
|
||||||
|
_ivRequestUri = uri;
|
||||||
|
_ivRequestId = session->api().request(MTPmessages_GetWebPage(
|
||||||
|
MTP_string(url),
|
||||||
|
MTP_int(0)
|
||||||
|
)).done([=](const MTPmessages_WebPage &result) {
|
||||||
|
const auto &data = result.data();
|
||||||
|
session->data().processUsers(data.vusers());
|
||||||
|
session->data().processChats(data.vchats());
|
||||||
|
finish(session->data().processWebpage(data.vwebpage()));
|
||||||
|
}).fail([=] {
|
||||||
|
finish(nullptr);
|
||||||
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::requestFull(
|
void Instance::requestFull(
|
||||||
|
@ -1033,4 +1118,17 @@ void Instance::closeAll() {
|
||||||
_shown = nullptr;
|
_shown = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PreferForUri(const QString &uri) {
|
||||||
|
const auto url = QUrl(uri);
|
||||||
|
const auto host = url.host().toLower();
|
||||||
|
const auto path = url.path().toLower();
|
||||||
|
return (host == u"telegra.ph"_q)
|
||||||
|
|| (host == u"te.legra.ph"_q)
|
||||||
|
|| (host == u"graph.org"_q)
|
||||||
|
|| (host == u"telegram.org"_q
|
||||||
|
&& (path.startsWith(u"/faq"_q)
|
||||||
|
|| path.startsWith(u"/privacy"_q)
|
||||||
|
|| path.startsWith(u"/blog"_q)));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Iv
|
} // namespace Iv
|
||||||
|
|
|
@ -41,6 +41,15 @@ public:
|
||||||
not_null<Data*> data,
|
not_null<Data*> data,
|
||||||
QString hash);
|
QString hash);
|
||||||
|
|
||||||
|
void openWithIvPreferred(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
QString uri,
|
||||||
|
QVariant context = {});
|
||||||
|
void openWithIvPreferred(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
QString uri,
|
||||||
|
QVariant context = {});
|
||||||
|
|
||||||
[[nodiscard]] bool hasActiveWindow(
|
[[nodiscard]] bool hasActiveWindow(
|
||||||
not_null<Main::Session*> session) const;
|
not_null<Main::Session*> session) const;
|
||||||
|
|
||||||
|
@ -56,6 +65,8 @@ private:
|
||||||
void processJoinChannel(const QString &context);
|
void processJoinChannel(const QString &context);
|
||||||
void requestFull(not_null<Main::Session*> session, const QString &id);
|
void requestFull(not_null<Main::Session*> session, const QString &id);
|
||||||
|
|
||||||
|
void trackSession(not_null<Main::Session*> session);
|
||||||
|
|
||||||
const not_null<Delegate*> _delegate;
|
const not_null<Delegate*> _delegate;
|
||||||
|
|
||||||
std::unique_ptr<Shown> _shown;
|
std::unique_ptr<Shown> _shown;
|
||||||
|
@ -68,8 +79,18 @@ private:
|
||||||
not_null<Main::Session*>,
|
not_null<Main::Session*>,
|
||||||
base::flat_set<QString>> _fullRequested;
|
base::flat_set<QString>> _fullRequested;
|
||||||
|
|
||||||
|
base::flat_map<
|
||||||
|
not_null<Main::Session*>,
|
||||||
|
base::flat_map<QString, WebPageData*>> _ivCache;
|
||||||
|
Main::Session *_ivRequestSession = nullptr;
|
||||||
|
QString _ivRequestUri;
|
||||||
|
mtpRequestId _ivRequestId = 0;
|
||||||
|
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] bool PreferForUri(const QString &uri);
|
||||||
|
|
||||||
} // namespace Iv
|
} // namespace Iv
|
||||||
|
|
Loading…
Add table
Reference in a new issue