mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added ability to add proxy from clipboard.
This commit is contained in:
parent
48e3802565
commit
f6b849e4f7
3 changed files with 123 additions and 28 deletions
|
@ -1053,6 +1053,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_proxy_sponsor" = "Proxy sponsor";
|
"lng_proxy_sponsor" = "Proxy sponsor";
|
||||||
"lng_proxy_sponsor_about" = "This channel is shown by your proxy server.\nTo remove this channel from your chats list,\ndisable the proxy in Telegram Settings.";
|
"lng_proxy_sponsor_about" = "This channel is shown by your proxy server.\nTo remove this channel from your chats list,\ndisable the proxy in Telegram Settings.";
|
||||||
"lng_proxy_sponsor_warning" = "This proxy may display a sponsored channel in your chat list. This doesn't reveal any of your Telegram traffic.";
|
"lng_proxy_sponsor_warning" = "This proxy may display a sponsored channel in your chat list. This doesn't reveal any of your Telegram traffic.";
|
||||||
|
"lng_proxy_add_from_clipboard" = "Add proxy from clipboard";
|
||||||
|
"lng_proxy_add_from_clipboard_good_toast" = "Proxy was added from clipboard.";
|
||||||
|
"lng_proxy_add_from_clipboard_failed_toast" = "This is not a proxy link.";
|
||||||
|
"lng_proxy_add_from_clipboard_existing_toast" = "This proxy is already in the list.";
|
||||||
"lng_badge_psa_default" = "PSA";
|
"lng_badge_psa_default" = "PSA";
|
||||||
"lng_about_psa_default" = "This message provides you with a public service announcement. To remove it from your chats list, right click it and select **Hide**.";
|
"lng_about_psa_default" = "This message provides you with a public service announcement. To remove it from your chats list, right click it and select **Hide**.";
|
||||||
"lng_tooltip_psa_default" = "This message provides you with a public service announcement.";
|
"lng_tooltip_psa_default" = "This message provides you with a public service announcement.";
|
||||||
|
|
|
@ -7,31 +7,35 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "boxes/connection_box.h"
|
#include "boxes/connection_box.h"
|
||||||
|
|
||||||
#include "ui/boxes/confirm_box.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "storage/localstorage.h"
|
|
||||||
#include "base/qthelp_url.h"
|
|
||||||
#include "base/call_delayed.h"
|
#include "base/call_delayed.h"
|
||||||
|
#include "base/qthelp_regex.h"
|
||||||
|
#include "base/qthelp_url.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
|
#include "core/click_handler_types.h"
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
|
#include "core/local_url_handlers.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
#include "mtproto/facade.h"
|
#include "mtproto/facade.h"
|
||||||
#include "ui/widgets/checkbox.h"
|
#include "storage/localstorage.h"
|
||||||
|
#include "ui/basic_click_handlers.h"
|
||||||
|
#include "ui/boxes/confirm_box.h"
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
|
#include "ui/effects/radial_animation.h"
|
||||||
|
#include "ui/painter.h"
|
||||||
|
#include "ui/text/text_options.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/widgets/checkbox.h"
|
||||||
|
#include "ui/widgets/dropdown_menu.h"
|
||||||
#include "ui/widgets/fields/input_field.h"
|
#include "ui/widgets/fields/input_field.h"
|
||||||
#include "ui/widgets/fields/number_input.h"
|
#include "ui/widgets/fields/number_input.h"
|
||||||
#include "ui/widgets/fields/password_input.h"
|
#include "ui/widgets/fields/password_input.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/widgets/dropdown_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/wrap/slide_wrap.h"
|
#include "ui/wrap/slide_wrap.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "ui/toast/toast.h"
|
|
||||||
#include "ui/effects/animations.h"
|
|
||||||
#include "ui/effects/radial_animation.h"
|
|
||||||
#include "ui/text/text_options.h"
|
|
||||||
#include "ui/text/text_utilities.h"
|
|
||||||
#include "ui/basic_click_handlers.h"
|
|
||||||
#include "ui/painter.h"
|
|
||||||
#include "boxes/abstract_box.h" // Ui::show().
|
#include "boxes/abstract_box.h" // Ui::show().
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
@ -48,6 +52,22 @@ constexpr auto kSaveSettingsDelayedTimeout = crl::time(1000);
|
||||||
|
|
||||||
using ProxyData = MTP::ProxyData;
|
using ProxyData = MTP::ProxyData;
|
||||||
|
|
||||||
|
[[nodiscard]] ProxyData ProxyDataFromFields(
|
||||||
|
ProxyData::Type type,
|
||||||
|
const QMap<QString, QString> &fields) {
|
||||||
|
auto proxy = ProxyData();
|
||||||
|
proxy.type = type;
|
||||||
|
proxy.host = fields.value(u"server"_q);
|
||||||
|
proxy.port = fields.value(u"port"_q).toUInt();
|
||||||
|
if (type == ProxyData::Type::Socks5) {
|
||||||
|
proxy.user = fields.value(u"user"_q);
|
||||||
|
proxy.password = fields.value(u"pass"_q);
|
||||||
|
} else if (type == ProxyData::Type::Mtproto) {
|
||||||
|
proxy.password = fields.value(u"secret"_q);
|
||||||
|
}
|
||||||
|
return proxy;
|
||||||
|
};
|
||||||
|
|
||||||
class HostInput : public Ui::MaskedInputField {
|
class HostInput : public Ui::MaskedInputField {
|
||||||
public:
|
public:
|
||||||
HostInput(
|
HostInput(
|
||||||
|
@ -203,6 +223,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupContent();
|
void setupContent();
|
||||||
|
void setupTopButton();
|
||||||
void createNoRowsLabel();
|
void createNoRowsLabel();
|
||||||
void addNewProxy();
|
void addNewProxy();
|
||||||
void applyView(View &&view);
|
void applyView(View &&view);
|
||||||
|
@ -600,9 +621,80 @@ void ProxiesBox::prepare() {
|
||||||
addButton(tr::lng_proxy_add(), [=] { addNewProxy(); });
|
addButton(tr::lng_proxy_add(), [=] { addNewProxy(); });
|
||||||
addButton(tr::lng_close(), [=] { closeBox(); });
|
addButton(tr::lng_close(), [=] { closeBox(); });
|
||||||
|
|
||||||
|
setupTopButton();
|
||||||
setupContent();
|
setupContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProxiesBox::setupTopButton() {
|
||||||
|
const auto top = addTopButton(st::infoTopBarMenu);
|
||||||
|
const auto menu
|
||||||
|
= top->lifetime().make_state<base::unique_qptr<Ui::PopupMenu>>();
|
||||||
|
const auto callback = [=] {
|
||||||
|
const auto maybeUrl = QGuiApplication::clipboard()->text();
|
||||||
|
const auto local = Core::TryConvertUrlToLocal(maybeUrl);
|
||||||
|
|
||||||
|
const auto proxyString = u"proxy"_q;
|
||||||
|
const auto socksString = u"socks"_q;
|
||||||
|
const auto protocol = u"tg://"_q;
|
||||||
|
const auto command = base::StringViewMid(
|
||||||
|
local,
|
||||||
|
protocol.size(),
|
||||||
|
8192);
|
||||||
|
|
||||||
|
if (local.startsWith(protocol + proxyString)
|
||||||
|
|| local.startsWith(protocol + socksString)) {
|
||||||
|
|
||||||
|
using namespace qthelp;
|
||||||
|
const auto options = RegExOption::CaseInsensitive;
|
||||||
|
for (const auto &[expression, _] : Core::LocalUrlHandlers()) {
|
||||||
|
const auto midExpression = base::StringViewMid(
|
||||||
|
expression,
|
||||||
|
1);
|
||||||
|
const auto isSocks = midExpression.startsWith(
|
||||||
|
socksString);
|
||||||
|
if (!midExpression.startsWith(proxyString)
|
||||||
|
&& !isSocks) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto match = regex_match(
|
||||||
|
expression,
|
||||||
|
command,
|
||||||
|
options);
|
||||||
|
if (!match) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto type = isSocks
|
||||||
|
? ProxyData::Type::Socks5
|
||||||
|
: ProxyData::Type::Mtproto;
|
||||||
|
const auto fields = url_parse_params(
|
||||||
|
match->captured(1),
|
||||||
|
qthelp::UrlParamNameTransform::ToLower);
|
||||||
|
const auto proxy = ProxyDataFromFields(type, fields);
|
||||||
|
const auto contains = _controller->contains(proxy);
|
||||||
|
const auto toast = (contains
|
||||||
|
? tr::lng_proxy_add_from_clipboard_existing_toast
|
||||||
|
: tr::lng_proxy_add_from_clipboard_good_toast)(tr::now);
|
||||||
|
uiShow()->showToast(toast);
|
||||||
|
if (!contains) {
|
||||||
|
_controller->addNewItem(proxy);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uiShow()->showToast(
|
||||||
|
tr::lng_proxy_add_from_clipboard_failed_toast(tr::now));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
top->setClickedCallback([=] {
|
||||||
|
*menu = base::make_unique_q<Ui::PopupMenu>(top, st::defaultPopupMenu);
|
||||||
|
(*menu)->addAction(
|
||||||
|
tr::lng_proxy_add_from_clipboard(tr::now),
|
||||||
|
callback);
|
||||||
|
(*menu)->popup(QCursor::pos());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ProxiesBox::setupContent() {
|
void ProxiesBox::setupContent() {
|
||||||
const auto inner = setInnerWidget(object_ptr<Ui::VerticalLayout>(this));
|
const auto inner = setInnerWidget(object_ptr<Ui::VerticalLayout>(this));
|
||||||
|
|
||||||
|
@ -1096,24 +1188,13 @@ ProxiesBoxController::ProxiesBoxController(not_null<Main::Account*> account)
|
||||||
void ProxiesBoxController::ShowApplyConfirmation(
|
void ProxiesBoxController::ShowApplyConfirmation(
|
||||||
Type type,
|
Type type,
|
||||||
const QMap<QString, QString> &fields) {
|
const QMap<QString, QString> &fields) {
|
||||||
const auto server = fields.value(u"server"_q);
|
const auto proxy = ProxyDataFromFields(type, fields);
|
||||||
const auto port = fields.value(u"port"_q).toUInt();
|
|
||||||
auto proxy = ProxyData();
|
|
||||||
proxy.type = type;
|
|
||||||
proxy.host = server;
|
|
||||||
proxy.port = port;
|
|
||||||
if (type == Type::Socks5) {
|
|
||||||
proxy.user = fields.value(u"user"_q);
|
|
||||||
proxy.password = fields.value(u"pass"_q);
|
|
||||||
} else if (type == Type::Mtproto) {
|
|
||||||
proxy.password = fields.value(u"secret"_q);
|
|
||||||
}
|
|
||||||
if (proxy) {
|
if (proxy) {
|
||||||
static const auto UrlStartRegExp = QRegularExpression(
|
static const auto UrlStartRegExp = QRegularExpression(
|
||||||
"^https://",
|
"^https://",
|
||||||
QRegularExpression::CaseInsensitiveOption);
|
QRegularExpression::CaseInsensitiveOption);
|
||||||
static const auto UrlEndRegExp = QRegularExpression("/$");
|
static const auto UrlEndRegExp = QRegularExpression("/$");
|
||||||
const auto displayed = "https://" + server + "/";
|
const auto displayed = "https://" + proxy.host + "/";
|
||||||
const auto parsed = QUrl::fromUserInput(displayed);
|
const auto parsed = QUrl::fromUserInput(displayed);
|
||||||
const auto displayUrl = !UrlClickHandler::IsSuspicious(displayed)
|
const auto displayUrl = !UrlClickHandler::IsSuspicious(displayed)
|
||||||
? displayed
|
? displayed
|
||||||
|
@ -1131,7 +1212,7 @@ void ProxiesBoxController::ShowApplyConfirmation(
|
||||||
lt_server,
|
lt_server,
|
||||||
displayServer,
|
displayServer,
|
||||||
lt_port,
|
lt_port,
|
||||||
QString::number(port))
|
QString::number(proxy.port))
|
||||||
+ (proxy.type == Type::Mtproto
|
+ (proxy.type == Type::Mtproto
|
||||||
? "\n\n" + tr::lng_proxy_sponsor_warning(tr::now)
|
? "\n\n" + tr::lng_proxy_sponsor_warning(tr::now)
|
||||||
: QString());
|
: QString());
|
||||||
|
@ -1448,6 +1529,14 @@ object_ptr<Ui::BoxContent> ProxiesBoxController::addNewItemBox() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProxiesBoxController::contains(const ProxyData &proxy) const {
|
||||||
|
const auto j = ranges::find(
|
||||||
|
_list,
|
||||||
|
proxy,
|
||||||
|
[](const Item &item) { return item.data; });
|
||||||
|
return (j != end(_list));
|
||||||
|
}
|
||||||
|
|
||||||
void ProxiesBoxController::addNewItem(const ProxyData &proxy) {
|
void ProxiesBoxController::addNewItem(const ProxyData &proxy) {
|
||||||
auto &proxies = _settings.list();
|
auto &proxies = _settings.list();
|
||||||
proxies.push_back(proxy);
|
proxies.push_back(proxy);
|
||||||
|
|
|
@ -77,6 +77,9 @@ public:
|
||||||
void setTryIPv6(bool enabled);
|
void setTryIPv6(bool enabled);
|
||||||
rpl::producer<ProxyData::Settings> proxySettingsValue() const;
|
rpl::producer<ProxyData::Settings> proxySettingsValue() const;
|
||||||
|
|
||||||
|
[[nodiscard]] bool contains(const ProxyData &proxy) const;
|
||||||
|
void addNewItem(const ProxyData &proxy);
|
||||||
|
|
||||||
rpl::producer<ItemView> views() const;
|
rpl::producer<ItemView> views() const;
|
||||||
|
|
||||||
~ProxiesBoxController();
|
~ProxiesBoxController();
|
||||||
|
@ -109,7 +112,6 @@ private:
|
||||||
void replaceItemValue(
|
void replaceItemValue(
|
||||||
std::vector<Item>::iterator which,
|
std::vector<Item>::iterator which,
|
||||||
const ProxyData &proxy);
|
const ProxyData &proxy);
|
||||||
void addNewItem(const ProxyData &proxy);
|
|
||||||
|
|
||||||
const not_null<Main::Account*> _account;
|
const not_null<Main::Account*> _account;
|
||||||
Core::SettingsProxy &_settings;
|
Core::SettingsProxy &_settings;
|
||||||
|
|
Loading…
Add table
Reference in a new issue