Handle socks internal links.

This commit is contained in:
John Preston 2017-06-27 23:11:38 +03:00
parent 1968ca07de
commit 82912f4a0b
15 changed files with 147 additions and 96 deletions

View File

@ -151,6 +151,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
"lng_sure_add_admin_unban" = "This user is currently restricted or banned in this group. Are you sure you want to unban and promote them?"; "lng_sure_add_admin_unban" = "This user is currently restricted or banned in this group. Are you sure you want to unban and promote them?";
"lng_sure_ban_admin" = "This user is an admin in this group. Are you sure you want to go ahead and restrict them?"; "lng_sure_ban_admin" = "This user is an admin in this group. Are you sure you want to go ahead and restrict them?";
"lng_sure_ban_user_group" = "Ban {user} in the group?"; "lng_sure_ban_user_group" = "Ban {user} in the group?";
"lng_sure_enable_socks" = "Are you sure you want to enable this proxy?\n\nServer: {server}\nPort: {port}\n\nYou can change your proxy server later in the Settings (Connection Type).";
"lng_sure_enable" = "Enable";
"lng_edit_deleted" = "This message was deleted"; "lng_edit_deleted" = "This message was deleted";
"lng_edit_too_long" = "Your message text is too long"; "lng_edit_too_long" = "Your message text is too long";

View File

@ -286,9 +286,7 @@ void Application::readClients() {
if (!startUrl.isEmpty()) { if (!startUrl.isEmpty()) {
cSetStartUrl(startUrl); cSetStartUrl(startUrl);
} }
if (auto main = App::main()) { Messenger::Instance().checkStartUrl();
main->checkStartUrl();
}
} }
void Application::removeClients() { void Application::removeClients() {

View File

@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/ */
#include "boxes/connection_box.h" #include "boxes/connection_box.h"
#include "boxes/confirm_box.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "mainwidget.h" #include "mainwidget.h"
@ -30,6 +31,30 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "history/history_location_manager.h" #include "history/history_location_manager.h"
#include "styles/style_boxes.h" #include "styles/style_boxes.h"
void ConnectionBox::ShowApplyProxyConfirmation(const QMap<QString, QString> &fields) {
auto server = fields.value(qsl("server"));
auto port = fields.value(qsl("port")).toInt();
if (!server.isEmpty() && port != 0) {
auto weakBox = std::make_shared<QPointer<ConfirmBox>>(nullptr);
auto box = Ui::show(Box<ConfirmBox>(lng_sure_enable_socks(lt_server, server, lt_port, QString::number(port)), lang(lng_sure_enable), [fields, weakBox] {
auto p = ProxyData();
p.host = fields.value(qsl("server"));
p.user = fields.value(qsl("user"));
p.password = fields.value(qsl("pass"));
p.port = fields.value(qsl("port")).toInt();
Global::SetConnectionType(dbictTcpProxy);
Global::SetConnectionProxy(p);
Local::writeSettings();
Global::RefConnectionTypeChanged().notify();
MTP::restart();
reinitLocationManager();
reinitWebLoadManager();
if (*weakBox) (*weakBox)->closeBox();
}), KeepOtherLayers);
*weakBox = box;
}
}
ConnectionBox::ConnectionBox(QWidget *parent) ConnectionBox::ConnectionBox(QWidget *parent)
: _hostInput(this, st::connectionHostInputField, langFactory(lng_connection_host_ph), Global::ConnectionProxy().host) : _hostInput(this, st::connectionHostInputField, langFactory(lng_connection_host_ph), Global::ConnectionProxy().host)
, _portInput(this, st::connectionPortInputField, langFactory(lng_connection_port_ph), QString::number(Global::ConnectionProxy().port)) , _portInput(this, st::connectionPortInputField, langFactory(lng_connection_port_ph), QString::number(Global::ConnectionProxy().port))

View File

@ -39,6 +39,8 @@ class ConnectionBox : public BoxContent {
public: public:
ConnectionBox(QWidget *parent); ConnectionBox(QWidget *parent);
static void ShowApplyProxyConfirmation(const QMap<QString, QString> &fields);
protected: protected:
void prepare() override; void prepare() override;
void setInnerFocus() override; void setInnerFocus() override;

View File

@ -809,7 +809,7 @@ QVector<PeerData*> ShareBox::Inner::selected() const {
return result; return result;
} }
QString appendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) { QString AppendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) {
auto shareHashData = QByteArray(0x10, Qt::Uninitialized); auto shareHashData = QByteArray(0x10, Qt::Uninitialized);
auto shareHashDataInts = reinterpret_cast<int32*>(shareHashData.data()); auto shareHashDataInts = reinterpret_cast<int32*>(shareHashData.data());
auto channel = fullId.channel ? App::channelLoaded(fullId.channel) : static_cast<ChannelData*>(nullptr); auto channel = fullId.channel ? App::channelLoaded(fullId.channel) : static_cast<ChannelData*>(nullptr);
@ -854,7 +854,7 @@ QString appendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) {
namespace { namespace {
void shareGameScoreFromItem(HistoryItem *item) { void ShareGameScoreFromItem(HistoryItem *item) {
struct ShareGameScoreData { struct ShareGameScoreData {
ShareGameScoreData(const FullMsgId &msgId) : msgId(msgId) { ShareGameScoreData(const FullMsgId &msgId) : msgId(msgId) {
} }
@ -949,7 +949,7 @@ void shareGameScoreFromItem(HistoryItem *item) {
} // namespace } // namespace
void shareGameScoreByHash(const QString &hash) { void ShareGameScoreByHash(const QString &hash) {
auto key128Size = 0x10; auto key128Size = 0x10;
auto hashEncrypted = QByteArray::fromBase64(hash.toLatin1(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); auto hashEncrypted = QByteArray::fromBase64(hash.toLatin1(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
@ -1000,12 +1000,12 @@ void shareGameScoreByHash(const QString &hash) {
} }
if (auto item = App::histItemById(channelId, msgId)) { if (auto item = App::histItemById(channelId, msgId)) {
shareGameScoreFromItem(item); ShareGameScoreFromItem(item);
} else if (App::api()) { } else if (App::api()) {
auto resolveMessageAndShareScore = [msgId](ChannelData *channel) { auto resolveMessageAndShareScore = [msgId](ChannelData *channel) {
App::api()->requestMessageData(channel, msgId, [](ChannelData *channel, MsgId msgId) { App::api()->requestMessageData(channel, msgId, [](ChannelData *channel, MsgId msgId) {
if (auto item = App::histItemById(channel, msgId)) { if (auto item = App::histItemById(channel, msgId)) {
shareGameScoreFromItem(item); ShareGameScoreFromItem(item);
} else { } else {
Ui::show(Box<InformBox>(lang(lng_edit_deleted))); Ui::show(Box<InformBox>(lang(lng_edit_deleted)));
} }

View File

@ -37,8 +37,8 @@ namespace Ui {
class MultiSelect; class MultiSelect;
} // namespace Ui } // namespace Ui
QString appendShareGameScoreUrl(const QString &url, const FullMsgId &fullId); QString AppendShareGameScoreUrl(const QString &url, const FullMsgId &fullId);
void shareGameScoreByHash(const QString &hash); void ShareGameScoreByHash(const QString &hash);
class ShareBox : public BoxContent, public RPCSender { class ShareBox : public BoxContent, public RPCSender {
Q_OBJECT Q_OBJECT

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "messenger.h"
#include "platform/platform_specific.h" #include "platform/platform_specific.h"
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
#include "base/qthelp_regex.h" #include "base/qthelp_regex.h"
@ -58,6 +59,8 @@ QString tryConvertUrlToLocal(QString url) {
|| previewedUrl.startsWith(qstr("https://"), Qt::CaseInsensitive)) { || previewedUrl.startsWith(qstr("https://"), Qt::CaseInsensitive)) {
return previewedUrl; return previewedUrl;
} }
} else if (auto socksMatch = regex_match(qsl("socks/?\\?(.+)(#|$)"), query, matchOptions)) {
return qsl("tg://socks?") + socksMatch->captured(1);
} else if (auto usernameMatch = regex_match(qsl("^([a-zA-Z0-9\\.\\_]+)(/?\\?|/?$|/(\\d+)/?(?:\\?|$))"), query, matchOptions)) { } else if (auto usernameMatch = regex_match(qsl("^([a-zA-Z0-9\\.\\_]+)(/?\\?|/?$|/(\\d+)/?(?:\\?|$))"), query, matchOptions)) {
auto params = query.mid(usernameMatch->captured(0).size()).toString(); auto params = query.mid(usernameMatch->captured(0).size()).toString();
auto postParam = QString(); auto postParam = QString();
@ -83,7 +86,7 @@ void UrlClickHandler::doOpen(QString url) {
url = tryConvertUrlToLocal(url); url = tryConvertUrlToLocal(url);
if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)) { if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
App::openLocalUrl(url); Messenger::Instance().openLocalUrl(url);
} else { } else {
QDesktopServices::openUrl(url); QDesktopServices::openUrl(url);
} }
@ -113,7 +116,7 @@ void HiddenUrlClickHandler::doOpen(QString url) {
auto urlText = tryConvertUrlToLocal(url); auto urlText = tryConvertUrlToLocal(url);
if (urlText.startsWith(qstr("tg://"), Qt::CaseInsensitive)) { if (urlText.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
App::openLocalUrl(urlText); Messenger::Instance().openLocalUrl(urlText);
} else { } else {
auto parsedUrl = QUrl::fromUserInput(urlText); auto parsedUrl = QUrl::fromUserInput(urlText);
auto displayUrl = parsedUrl.isValid() ? parsedUrl.toDisplayString() : urlText; auto displayUrl = parsedUrl.isValid() ? parsedUrl.toDisplayString() : urlText;
@ -128,7 +131,7 @@ void BotGameUrlClickHandler::onClick(Qt::MouseButton button) const {
auto urlText = tryConvertUrlToLocal(url()); auto urlText = tryConvertUrlToLocal(url());
if (urlText.startsWith(qstr("tg://"), Qt::CaseInsensitive)) { if (urlText.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
App::openLocalUrl(urlText); Messenger::Instance().openLocalUrl(urlText);
} else if (!_bot || _bot->isVerified() || Local::isBotTrusted(_bot)) { } else if (!_bot || _bot->isVerified() || Local::isBotTrusted(_bot)) {
doOpen(urlText); doOpen(urlText);
} else { } else {

View File

@ -167,10 +167,6 @@ void stickersBox(const QString &name) {
if (MainWidget *m = main()) m->stickersBox(MTP_inputStickerSetShortName(MTP_string(name))); if (MainWidget *m = main()) m->stickersBox(MTP_inputStickerSetShortName(MTP_string(name)));
} }
void openLocalUrl(const QString &url) {
if (MainWidget *m = main()) m->openLocalUrl(url);
}
bool forward(const PeerId &peer, ForwardWhatMessages what) { bool forward(const PeerId &peer, ForwardWhatMessages what) {
if (MainWidget *m = main()) return m->onForward(peer, what); if (MainWidget *m = main()) return m->onForward(peer, what);
return false; return false;

View File

@ -73,7 +73,6 @@ void searchByHashtag(const QString &tag, PeerData *inPeer);
void openPeerByName(const QString &username, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString()); void openPeerByName(const QString &username, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString());
void joinGroupByHash(const QString &hash); void joinGroupByHash(const QString &hash);
void stickersBox(const QString &name); void stickersBox(const QString &name);
void openLocalUrl(const QString &url);
bool forward(const PeerId &peer, ForwardWhatMessages what); bool forward(const PeerId &peer, ForwardWhatMessages what);
void removeDialog(History *history); void removeDialog(History *history);
void showSettings(); void showSettings();

View File

@ -3510,7 +3510,7 @@ void HistoryWidget::botCallbackDone(BotCallbackInfo info, const MTPmessages_BotC
} else if (answerData.has_url()) { } else if (answerData.has_url()) {
auto url = qs(answerData.vurl); auto url = qs(answerData.vurl);
if (info.game) { if (info.game) {
url = appendShareGameScoreUrl(url, info.msgId); url = AppendShareGameScoreUrl(url, info.msgId);
BotGameUrlClickHandler(info.bot, url).onClick(Qt::LeftButton); BotGameUrlClickHandler(info.bot, url).onClick(Qt::LeftButton);
if (item && (!item->history()->peer->isChannel() || item->history()->peer->isMegagroup())) { if (item && (!item->history()->peer->isChannel() || item->history()->peer->isMegagroup())) {
updateSendAction(item->history(), SendAction::Type::PlayGame); updateSendAction(item->history(), SendAction::Type::PlayGame);

View File

@ -51,8 +51,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "boxes/sticker_set_box.h" #include "boxes/sticker_set_box.h"
#include "boxes/contacts_box.h" #include "boxes/contacts_box.h"
#include "boxes/download_path_box.h" #include "boxes/download_path_box.h"
#include "boxes/confirm_phone_box.h"
#include "boxes/share_box.h"
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "shortcuts.h" #include "shortcuts.h"
#include "media/media_audio.h" #include "media/media_audio.h"
@ -4088,81 +4086,13 @@ void MainWidget::start(const MTPUser *self) {
Local::readSavedGifs(); Local::readSavedGifs();
_history->start(); _history->start();
checkStartUrl(); Messenger::Instance().checkStartUrl();
} }
bool MainWidget::started() { bool MainWidget::started() {
return _started; return _started;
} }
void MainWidget::checkStartUrl() {
if (!cStartUrl().isEmpty() && App::self() && !App::passcoded()) {
auto url = cStartUrl();
cSetStartUrl(QString());
openLocalUrl(url);
}
}
void MainWidget::openLocalUrl(const QString &url) {
auto urlTrimmed = url.trimmed();
if (urlTrimmed.size() > 8192) urlTrimmed = urlTrimmed.mid(0, 8192);
if (!urlTrimmed.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
return;
}
auto command = urlTrimmed.midRef(qstr("tg://").size());
using namespace qthelp;
auto matchOptions = RegExOption::CaseInsensitive;
if (auto joinChatMatch = regex_match(qsl("^join/?\\?invite=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"), command, matchOptions)) {
joinGroupByHash(joinChatMatch->captured(1));
} else if (auto stickerSetMatch = regex_match(qsl("^addstickers/?\\?set=([a-zA-Z0-9\\.\\_]+)(&|$)"), command, matchOptions)) {
stickersBox(MTP_inputStickerSetShortName(MTP_string(stickerSetMatch->captured(1))));
} else if (auto shareUrlMatch = regex_match(qsl("^msg_url/?\\?(.+)(#|$)"), command, matchOptions)) {
auto params = url_parse_params(shareUrlMatch->captured(1), UrlParamNameTransform::ToLower);
auto url = params.value(qsl("url"));
if (!url.isEmpty()) {
shareUrlLayer(url, params.value("text"));
}
} else if (auto confirmPhoneMatch = regex_match(qsl("^confirmphone/?\\?(.+)(#|$)"), command, matchOptions)) {
auto params = url_parse_params(confirmPhoneMatch->captured(1), UrlParamNameTransform::ToLower);
auto phone = params.value(qsl("phone"));
auto hash = params.value(qsl("hash"));
if (!phone.isEmpty() && !hash.isEmpty()) {
ConfirmPhoneBox::start(phone, hash);
}
} else if (auto usernameMatch = regex_match(qsl("^resolve/?\\?(.+)(#|$)"), command, matchOptions)) {
auto params = url_parse_params(usernameMatch->captured(1), UrlParamNameTransform::ToLower);
auto domain = params.value(qsl("domain"));
if (regex_match(qsl("^[a-zA-Z0-9\\.\\_]+$"), domain, matchOptions)) {
auto start = qsl("start");
auto startToken = params.value(start);
if (startToken.isEmpty()) {
start = qsl("startgroup");
startToken = params.value(start);
if (startToken.isEmpty()) {
start = QString();
}
}
auto post = (start == qsl("startgroup")) ? ShowAtProfileMsgId : ShowAtUnreadMsgId;
auto postParam = params.value(qsl("post"));
if (auto postId = postParam.toInt()) {
post = postId;
}
auto gameParam = params.value(qsl("game"));
if (!gameParam.isEmpty() && regex_match(qsl("^[a-zA-Z0-9\\.\\_]+$"), gameParam, matchOptions)) {
startToken = gameParam;
post = ShowAtGameShareMsgId;
}
openPeerByName(domain, post, startToken);
}
} else if (auto shareGameScoreMatch = regex_match(qsl("^share_game_score/?\\?(.+)(#|$)"), command, matchOptions)) {
auto params = url_parse_params(shareGameScoreMatch->captured(1), UrlParamNameTransform::ToLower);
shareGameScoreByHash(params.value(qsl("hash")));
}
}
void MainWidget::openPeerByName(const QString &username, MsgId msgId, const QString &startToken) { void MainWidget::openPeerByName(const QString &username, MsgId msgId, const QString &startToken) {
App::wnd()->hideMediaview(); App::wnd()->hideMediaview();

View File

@ -168,8 +168,6 @@ public:
void start(const MTPUser *self = nullptr); void start(const MTPUser *self = nullptr);
void checkStartUrl();
void openLocalUrl(const QString &str);
void openPeerByName(const QString &name, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString()); void openPeerByName(const QString &name, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString());
void joinGroupByHash(const QString &hash); void joinGroupByHash(const QString &hash);
void stickersBox(const MTPInputStickerSet &set); void stickersBox(const MTPInputStickerSet &set);

View File

@ -218,7 +218,7 @@ void MainWindow::clearPasscode() {
} else { } else {
t_assert(_main != nullptr); t_assert(_main != nullptr);
_main->showAnimated(bg, true); _main->showAnimated(bg, true);
_main->checkStartUrl(); Messenger::Instance().checkStartUrl();
} }
} }
@ -609,9 +609,7 @@ bool MainWindow::eventFilter(QObject *object, QEvent *e) {
QString url = static_cast<QFileOpenEvent*>(e)->url().toEncoded().trimmed(); QString url = static_cast<QFileOpenEvent*>(e)->url().toEncoded().trimmed();
if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)) { if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
cSetStartUrl(url.mid(0, 8192)); cSetStartUrl(url.mid(0, 8192));
if (_main) { Messenger::Instance().checkStartUrl();
_main->checkStartUrl();
}
} }
activate(); activate();
} }

View File

@ -45,6 +45,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "ui/widgets/tooltip.h" #include "ui/widgets/tooltip.h"
#include "storage/serialize_common.h" #include "storage/serialize_common.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "base/qthelp_regex.h"
#include "base/qthelp_url.h"
#include "boxes/connection_box.h"
#include "boxes/confirm_phone_box.h"
#include "boxes/share_box.h"
namespace { namespace {
@ -651,6 +656,98 @@ QString Messenger::createInternalLinkFull(const QString &query) const {
return Global::InternalLinksDomain() + query; return Global::InternalLinksDomain() + query;
} }
void Messenger::checkStartUrl() {
if (!cStartUrl().isEmpty() && !App::passcoded()) {
auto url = cStartUrl();
cSetStartUrl(QString());
if (!openLocalUrl(url)) {
cSetStartUrl(url);
}
}
}
bool Messenger::openLocalUrl(const QString &url) {
auto urlTrimmed = url.trimmed();
if (urlTrimmed.size() > 8192) urlTrimmed = urlTrimmed.mid(0, 8192);
if (!urlTrimmed.startsWith(qstr("tg://"), Qt::CaseInsensitive) || App::passcoded()) {
return false;
}
auto command = urlTrimmed.midRef(qstr("tg://").size());
using namespace qthelp;
auto matchOptions = RegExOption::CaseInsensitive;
if (auto joinChatMatch = regex_match(qsl("^join/?\\?invite=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"), command, matchOptions)) {
if (auto main = App::main()) {
main->joinGroupByHash(joinChatMatch->captured(1));
return true;
}
} else if (auto stickerSetMatch = regex_match(qsl("^addstickers/?\\?set=([a-zA-Z0-9\\.\\_]+)(&|$)"), command, matchOptions)) {
if (auto main = App::main()) {
main->stickersBox(MTP_inputStickerSetShortName(MTP_string(stickerSetMatch->captured(1))));
return true;
}
} else if (auto shareUrlMatch = regex_match(qsl("^msg_url/?\\?(.+)(#|$)"), command, matchOptions)) {
if (auto main = App::main()) {
auto params = url_parse_params(shareUrlMatch->captured(1), UrlParamNameTransform::ToLower);
auto url = params.value(qsl("url"));
if (!url.isEmpty()) {
main->shareUrlLayer(url, params.value("text"));
return true;
}
}
} else if (auto confirmPhoneMatch = regex_match(qsl("^confirmphone/?\\?(.+)(#|$)"), command, matchOptions)) {
if (auto main = App::main()) {
auto params = url_parse_params(confirmPhoneMatch->captured(1), UrlParamNameTransform::ToLower);
auto phone = params.value(qsl("phone"));
auto hash = params.value(qsl("hash"));
if (!phone.isEmpty() && !hash.isEmpty()) {
ConfirmPhoneBox::start(phone, hash);
return true;
}
}
} else if (auto usernameMatch = regex_match(qsl("^resolve/?\\?(.+)(#|$)"), command, matchOptions)) {
if (auto main = App::main()) {
auto params = url_parse_params(usernameMatch->captured(1), UrlParamNameTransform::ToLower);
auto domain = params.value(qsl("domain"));
if (regex_match(qsl("^[a-zA-Z0-9\\.\\_]+$"), domain, matchOptions)) {
auto start = qsl("start");
auto startToken = params.value(start);
if (startToken.isEmpty()) {
start = qsl("startgroup");
startToken = params.value(start);
if (startToken.isEmpty()) {
start = QString();
}
}
auto post = (start == qsl("startgroup")) ? ShowAtProfileMsgId : ShowAtUnreadMsgId;
auto postParam = params.value(qsl("post"));
if (auto postId = postParam.toInt()) {
post = postId;
}
auto gameParam = params.value(qsl("game"));
if (!gameParam.isEmpty() && regex_match(qsl("^[a-zA-Z0-9\\.\\_]+$"), gameParam, matchOptions)) {
startToken = gameParam;
post = ShowAtGameShareMsgId;
}
main->openPeerByName(domain, post, startToken);
return true;
}
}
} else if (auto shareGameScoreMatch = regex_match(qsl("^share_game_score/?\\?(.+)(#|$)"), command, matchOptions)) {
if (auto main = App::main()) {
auto params = url_parse_params(shareGameScoreMatch->captured(1), UrlParamNameTransform::ToLower);
ShareGameScoreByHash(params.value(qsl("hash")));
return true;
}
} else if (auto socksMatch = regex_match(qsl("^socks/?\\?(.+)(#|$)"), command, matchOptions)) {
auto params = url_parse_params(socksMatch->captured(1), UrlParamNameTransform::ToLower);
ConnectionBox::ShowApplyProxyConfirmation(params);
return true;
}
return false;
}
FileUploader *Messenger::uploader() { FileUploader *Messenger::uploader() {
if (!_uploader && !App::quitting()) _uploader = new FileUploader(); if (!_uploader && !App::quitting()) _uploader = new FileUploader();
return _uploader; return _uploader;

View File

@ -128,9 +128,12 @@ public:
return *_audio; return *_audio;
} }
// Internal links.
void setInternalLinkDomain(const QString &domain) const; void setInternalLinkDomain(const QString &domain) const;
QString createInternalLink(const QString &query) const; QString createInternalLink(const QString &query) const;
QString createInternalLinkFull(const QString &query) const; QString createInternalLinkFull(const QString &query) const;
void checkStartUrl();
bool openLocalUrl(const QString &url);
FileUploader *uploader(); FileUploader *uploader();
void uploadProfilePhoto(const QImage &tosend, const PeerId &peerId); void uploadProfilePhoto(const QImage &tosend, const PeerId &peerId);