Add 'Use proxy for calls' option.

This commit is contained in:
John Preston 2018-05-07 00:29:53 +03:00
parent d2fa8ef0b0
commit 48c1576d7f
14 changed files with 201 additions and 66 deletions

View file

@ -423,6 +423,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_proxy_settings" = "Proxy settings";
"lng_proxy_use" = "Use proxy";
"lng_proxy_use_for_calls" = "Use proxy for calls";
"lng_proxy_about" = "Proxy servers may be helpful in accessing Telegram if there is no connection in a specific region.";
"lng_proxy_add" = "Add proxy";
"lng_proxy_share" = "Share";
"lng_proxy_online" = "online";

View file

@ -117,6 +117,11 @@ boxLabel: FlatLabel(defaultFlatLabel) {
align: align(topleft);
style: boxLabelStyle;
}
boxDividerLabel: FlatLabel(boxLabel) {
minWidth: 245px;
textFg: windowSubTextFg;
style: defaultTextStyle;
}
countryRowHeight: 36px;
countryRowNameFont: semiboldFont;
@ -712,8 +717,8 @@ sendMediaFileThumbSkip: 10px;
sendMediaFileNameTop: 7px;
sendMediaFileStatusTop: 37px;
proxyUsePadding: margins(22px, 8px, 22px, 12px);
proxyTryIPv6Padding: margins(22px, 12px, 22px, 8px);
proxyUsePadding: margins(22px, 6px, 22px, 5px);
proxyTryIPv6Padding: margins(22px, 8px, 22px, 5px);
proxyRowPadding: margins(22px, 8px, 8px, 8px);
proxyRowIconSkip: 32px;
proxyRowSkip: 2px;
@ -774,3 +779,5 @@ proxyCheckingAnimation: InfiniteRadialAnimation(defaultInfiniteRadialAnimation)
}
proxyDropdownDownPosition: point(-2px, 35px);
proxyDropdownUpPosition: point(-2px, 20px);
proxyAboutPadding: margins(22px, 7px, 22px, 14px);

View file

@ -104,13 +104,17 @@ private:
void applyView(View &&view);
void setupButtons(int id, not_null<ProxyRow*> button);
int rowHeight() const;
void refreshProxyForCalls();
not_null<ProxiesBoxController*> _controller;
object_ptr<Ui::PaddingWrap<Ui::Checkbox>> _useProxy;
object_ptr<Ui::PaddingWrap<Ui::Checkbox>> _tryIPv6;
QPointer<Ui::Checkbox> _tryIPv6;
QPointer<Ui::Checkbox> _useProxy;
QPointer<Ui::SlideWrap<Ui::Checkbox>> _proxyForCalls;
QPointer<Ui::DividerLabel> _about;
base::unique_qptr<Ui::RpWidget> _noRows;
object_ptr<Ui::VerticalLayout> _initialWrap;
QPointer<Ui::VerticalLayout> _wrap;
int _currentProxySupportsCallsId = 0;
base::flat_map<int, base::unique_qptr<ProxyRow>> _rows;
@ -416,7 +420,7 @@ void ProxyRow::showMenu() {
addAction(lang(lng_proxy_menu_edit), [=] {
_editClicks.fire({});
});
if (_view.canShare) {
if (_view.supportsShare) {
addAction(lang(lng_proxy_edit_share), [=] {
_shareClicks.fire({});
});
@ -465,19 +469,6 @@ ProxiesBox::ProxiesBox(
QWidget*,
not_null<ProxiesBoxController*> controller)
: _controller(controller)
, _useProxy(
this,
object_ptr<Ui::Checkbox>(
this,
lang(lng_proxy_use)),
st::proxyUsePadding)
, _tryIPv6(
this,
object_ptr<Ui::Checkbox>(
this,
lang(lng_connection_try_ipv6),
Global::TryIPv6()),
st::proxyTryIPv6Padding)
, _initialWrap(this) {
_controller->views(
) | rpl::start_with_next([=](View &&view) {
@ -495,59 +486,100 @@ void ProxiesBox::prepare() {
}
void ProxiesBox::setupContent() {
_useProxy->resizeToWidth(st::boxWideWidth);
_useProxy->moveToLeft(0, 0);
subscribe(_useProxy->entity()->checkedChanged, [=](bool checked) {
if (!_controller->setProxyEnabled(checked)) {
_useProxy->entity()->setChecked(false);
addNewProxy();
}
});
subscribe(_tryIPv6->entity()->checkedChanged, [=](bool checked) {
_controller->setTryIPv6(checked);
});
_controller->proxyEnabledValue(
) | rpl::start_with_next([=](bool enabled) {
_useProxy->entity()->setChecked(enabled);
}, _useProxy->entity()->lifetime());
_useProxy->entity()->finishAnimating();
const auto inner = setInnerWidget(object_ptr<Ui::VerticalLayout>(this));
_tryIPv6->resizeToWidth(st::boxWideWidth);
_tryIPv6 = inner->add(
object_ptr<Ui::Checkbox>(
inner,
lang(lng_connection_try_ipv6),
Global::TryIPv6()),
st::proxyTryIPv6Padding);
_useProxy = inner->add(
object_ptr<Ui::Checkbox>(
inner,
lang(lng_proxy_use)),
st::proxyUsePadding);
_proxyForCalls = inner->add(
object_ptr<Ui::SlideWrap<Ui::Checkbox>>(
inner,
object_ptr<Ui::Checkbox>(
inner,
lang(lng_proxy_use_for_calls),
Global::UseProxyForCalls()),
style::margins(
0,
st::proxyUsePadding.top(),
0,
st::proxyUsePadding.bottom())),
style::margins(
st::proxyTryIPv6Padding.left(),
0,
st::proxyTryIPv6Padding.right(),
st::proxyTryIPv6Padding.top()));
_about = inner->add(
object_ptr<Ui::DividerLabel>(
inner,
object_ptr<Ui::FlatLabel>(
inner,
lang(lng_proxy_about),
Ui::FlatLabel::InitType::Simple,
st::boxDividerLabel),
st::proxyAboutPadding),
style::margins(0, 0, 0, st::proxyRowPadding.top()));
const auto topSkip = _useProxy->heightNoMargins();
const auto bottomSkip = _tryIPv6->heightNoMargins();
const auto inner = setInnerWidget(
object_ptr<Ui::VerticalLayout>(this),
topSkip,
bottomSkip);
inner->add(object_ptr<Ui::FixedHeightWidget>(
inner,
st::proxyRowPadding.top()));
_wrap = inner->add(std::move(_initialWrap));
inner->add(object_ptr<Ui::FixedHeightWidget>(
inner,
st::proxyRowPadding.bottom()));
subscribe(_useProxy->checkedChanged, [=](bool checked) {
if (!_controller->setProxyEnabled(checked)) {
_useProxy->setChecked(false);
addNewProxy();
}
refreshProxyForCalls();
});
subscribe(_tryIPv6->checkedChanged, [=](bool checked) {
_controller->setTryIPv6(checked);
});
_controller->proxyEnabledValue(
) | rpl::start_with_next([=](bool enabled) {
_useProxy->setChecked(enabled);
}, _useProxy->lifetime());
_useProxy->finishAnimating();
subscribe(_proxyForCalls->entity()->checkedChanged, [=](bool checked) {
_controller->setProxyForCalls(checked);
});
if (_rows.empty()) {
createNoRowsLabel();
}
refreshProxyForCalls();
_proxyForCalls->finishAnimating();
inner->resizeToWidth(st::boxWideWidth);
inner->heightValue(
) | rpl::map([=](int height) {
return std::min(
topSkip + std::max(height, 3 * rowHeight()) + bottomSkip,
std::max(height, _about->y()
+ _about->height()
+ 3 * rowHeight()),
st::boxMaxListHeight);
}) | rpl::distinct_until_changed(
) | rpl::start_with_next([=](int height) {
setDimensions(st::boxWideWidth, height);
}, inner->lifetime());
}
heightValue(
) | rpl::start_with_next([=](int height) {
_tryIPv6->moveToLeft(0, height - _tryIPv6->heightNoMargins());
}, _tryIPv6->lifetime());
void ProxiesBox::refreshProxyForCalls() {
if (!_proxyForCalls) {
return;
}
_proxyForCalls->toggle(
_useProxy->checked() && _currentProxySupportsCallsId != 0,
anim::type::normal);
}
int ProxiesBox::rowHeight() const {
@ -563,6 +595,13 @@ void ProxiesBox::addNewProxy() {
}
void ProxiesBox::applyView(View &&view) {
if (view.selected) {
_currentProxySupportsCallsId = view.supportsCalls ? view.id : 0;
} else if (view.id == _currentProxySupportsCallsId) {
_currentProxySupportsCallsId = 0;
}
refreshProxyForCalls();
const auto id = view.id;
const auto i = _rows.find(id);
if (i == _rows.end()) {
@ -652,7 +691,7 @@ void ProxyBox::prepare() {
_content->heightValue(
) | rpl::start_with_next([=](int height) {
setDimensions(st::boxWidth, height);
setDimensions(st::boxWideWidth, height);
}, _content->lifetime());
}
@ -819,7 +858,7 @@ void ProxyBox::setupControls(const ProxyData &data) {
? Type::Socks5
: data.type));
_content.create(this);
_content->resizeToWidth(st::boxWidth);
_content->resizeToWidth(st::boxWideWidth);
_content->moveToLeft(0, 0);
setupTypes();
@ -827,7 +866,7 @@ void ProxyBox::setupControls(const ProxyData &data) {
setupCredentials(data);
setupMtprotoCredentials(data);
_content->resizeToWidth(st::boxWidth);
_content->resizeToWidth(st::boxWideWidth);
const auto handleType = [=](Type type) {
_credentials->toggle(
@ -1525,6 +1564,17 @@ bool ProxiesBoxController::setProxyEnabled(bool enabled) {
return true;
}
void ProxiesBoxController::setProxyForCalls(bool enabled) {
if (Global::UseProxyForCalls() == enabled) {
return;
}
Global::SetUseProxyForCalls(enabled);
if (Global::UseProxy() && Global::SelectedProxy().supportsCalls()) {
Global::RefConnectionTypeChanged().notify();
}
saveDelayed();
}
void ProxiesBoxController::setTryIPv6(bool enabled) {
if (Global::TryIPv6() == enabled) {
return;
@ -1571,8 +1621,9 @@ void ProxiesBoxController::updateView(const Item &item) {
}
return ItemState::Connecting;
}();
const auto canShare = (item.data.type == Type::Socks5)
const auto supportsShare = (item.data.type == Type::Socks5)
|| (item.data.type == Type::Mtproto);
const auto supportsCalls = item.data.supportsCalls();
_views.fire({
item.id,
type,
@ -1581,7 +1632,8 @@ void ProxiesBoxController::updateView(const Item &item) {
item.ping,
!deleted && selected,
deleted,
!deleted && canShare,
!deleted && supportsShare,
supportsCalls,
state });
}

View file

@ -116,7 +116,8 @@ public:
int ping = 0;
bool selected = false;
bool deleted = false;
bool canShare = false;
bool supportsShare = false;
bool supportsCalls = false;
ItemState state = ItemState::Checking;
};
@ -128,6 +129,7 @@ public:
object_ptr<BoxContent> editItemBox(int id);
object_ptr<BoxContent> addNewItemBox();
bool setProxyEnabled(bool enabled);
void setProxyForCalls(bool enabled);
void setTryIPv6(bool enabled);
rpl::producer<bool> proxyEnabledValue() const;

View file

@ -40,17 +40,30 @@ constexpr auto kHangupTimeoutMs = 5000;
using tgvoip::Endpoint;
void ConvertEndpoint(std::vector<tgvoip::Endpoint> &ep, const MTPDphoneConnection &mtc) {
void ConvertEndpoint(
std::vector<tgvoip::Endpoint> &ep,
const MTPDphoneConnection &mtc) {
if (mtc.vpeer_tag.v.length() != 16) {
return;
}
auto ipv4 = tgvoip::IPv4Address(std::string(mtc.vip.v.constData(), mtc.vip.v.size()));
auto ipv6 = tgvoip::IPv6Address(std::string(mtc.vipv6.v.constData(), mtc.vipv6.v.size()));
ep.push_back(Endpoint((int64_t)mtc.vid.v, (uint16_t)mtc.vport.v, ipv4, ipv6, EP_TYPE_UDP_RELAY, (unsigned char*)mtc.vpeer_tag.v.data()));
auto ipv4 = tgvoip::IPv4Address(std::string(
mtc.vip.v.constData(),
mtc.vip.v.size()));
auto ipv6 = tgvoip::IPv6Address(std::string(
mtc.vipv6.v.constData(),
mtc.vipv6.v.size()));
ep.push_back(Endpoint(
(int64_t)mtc.vid.v,
(uint16_t)mtc.vport.v,
ipv4,
ipv6,
EP_TYPE_UDP_RELAY,
(unsigned char*)mtc.vpeer_tag.v.data()));
}
constexpr auto kFingerprintDataSize = 256;
uint64 ComputeFingerprint(const std::array<gsl::byte, kFingerprintDataSize> &authKey) {
uint64 ComputeFingerprint(
const std::array<gsl::byte, kFingerprintDataSize> &authKey) {
auto hash = openssl::Sha1(authKey);
return (gsl::to_integer<uint64>(hash[19]) << 56)
| (gsl::to_integer<uint64>(hash[18]) << 48)
@ -64,7 +77,10 @@ uint64 ComputeFingerprint(const std::array<gsl::byte, kFingerprintDataSize> &aut
} // namespace
Call::Call(not_null<Delegate*> delegate, not_null<UserData*> user, Type type)
Call::Call(
not_null<Delegate*> delegate,
not_null<UserData*> user,
Type type)
: _delegate(delegate)
, _user(user)
, _type(type) {
@ -505,6 +521,18 @@ void Call::createAndStartController(const MTPDphoneCall &call) {
_controller->SetStateCallback([](tgvoip::VoIPController *controller, int state) {
static_cast<Call*>(controller->implData)->handleControllerStateChange(controller, state);
});
if (Global::UseProxy() && Global::UseProxyForCalls()) {
const auto proxy = Global::SelectedProxy();
if (proxy.supportsCalls()) {
Assert(proxy.type == ProxyData::Type::Socks5);
_controller->SetProxy(
tgvoip::PROXY_SOCKS5,
proxy.host.toStdString(),
proxy.port,
proxy.user.toStdString(),
proxy.password.toStdString());
}
}
_controller->Start();
_controller->Connect();
}

View file

@ -871,7 +871,8 @@ void LastCrashedWindow::onUpdateSkip() {
if (_sendingState == SendingNoReport) {
onContinue();
} else {
if (_updatingState == UpdatingCheck || _updatingState == UpdatingDownload) {
if (_updatingState == UpdatingCheck
|| _updatingState == UpdatingDownload) {
Core::UpdateChecker checker;
checker.stop();
setUpdatingState(UpdatingFail);

View file

@ -245,6 +245,10 @@ bool ProxyData::valid() const {
return true;
}
bool ProxyData::supportsCalls() const {
return (type == Type::Socks5);
}
ProxyData::operator bool() const {
return valid();
}

View file

@ -434,6 +434,7 @@ struct ProxyData {
QString user, password;
bool valid() const;
bool supportsCalls() const;
explicit operator bool() const;
bool operator==(const ProxyData &other) const;
bool operator!=(const ProxyData &other) const;

View file

@ -568,6 +568,7 @@ struct Data {
std::vector<ProxyData> ProxiesList;
ProxyData SelectedProxy;
bool UseProxy = false;
bool UseProxyForCalls = false;
base::Observable<void> ConnectionTypeChanged;
int AutoLock = 3600;
@ -692,6 +693,7 @@ DefineVar(Global, bool, TryIPv6);
DefineVar(Global, std::vector<ProxyData>, ProxiesList);
DefineVar(Global, ProxyData, SelectedProxy);
DefineVar(Global, bool, UseProxy);
DefineVar(Global, bool, UseProxyForCalls);
DefineRefVar(Global, base::Observable<void>, ConnectionTypeChanged);
DefineVar(Global, int, AutoLock);

View file

@ -372,10 +372,11 @@ DeclareVar(int, NotificationsCount);
DeclareVar(Notify::ScreenCorner, NotificationsCorner);
DeclareVar(bool, NotificationsDemoIsShown);
DeclareVar(bool, TryIPv6);
DeclareVar(std::vector<ProxyData>, ProxiesList);
DeclareVar(ProxyData, SelectedProxy);
DeclareVar(bool, UseProxy);
DeclareVar(bool, TryIPv6);
DeclareVar(bool, UseProxyForCalls);
DeclareRefVar(base::Observable<void>, ConnectionTypeChanged);
DeclareVar(int, AutoLock);

View file

@ -1218,6 +1218,13 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
if (connectionType == dbictProxiesList) {
qint32 count = 0, index = 0;
stream >> count >> index;
if (std::abs(index) > count) {
Global::SetUseProxyForCalls(true);
index -= (index > 0 ? count : -count);
} else {
Global::SetUseProxyForCalls(false);
}
auto list = std::vector<ProxyData>();
for (auto i = 0; i < count; ++i) {
const auto proxy = readProxy();
@ -2485,7 +2492,9 @@ void writeSettings() {
data.stream << quint32(dbiConnectionType) << qint32(dbictProxiesList);
data.stream << qint32(proxies.size());
const auto index = qint32(proxyIt - begin(proxies)) + 1;
const auto index = qint32(proxyIt - begin(proxies))
+ qint32(Global::UseProxyForCalls() ? proxies.size() : 0)
+ 1;
data.stream << (Global::UseProxy() ? index : -index);
for (const auto &proxy : proxies) {
data.stream << qint32(kProxyTypeShift + int(proxy.type));

View file

@ -818,4 +818,14 @@ void FlatLabel::paintEvent(QPaintEvent *e) {
}
}
int DividerLabel::naturalWidth() const {
return -1;
}
void DividerLabel::resizeEvent(QResizeEvent *e) {
_background->lower();
_background->setGeometry(rect());
return PaddingWrap::resizeEvent(e);
}
} // namespace Ui

View file

@ -7,8 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <rpl/producer.h>
#include "ui/rp_widget.h"
#include "ui/wrap/padding_wrap.h"
#include "boxes/abstract_box.h"
#include "styles/style_widgets.h"
namespace Ui {
@ -213,4 +214,19 @@ private:
};
class DividerLabel : public Ui::PaddingWrap<Ui::FlatLabel> {
public:
using PaddingWrap::PaddingWrap;
int naturalWidth() const override;
protected:
void resizeEvent(QResizeEvent *e) override;
private:
object_ptr<BoxContentDivider> _background
= object_ptr<BoxContentDivider>(this);
};
} // namespace Ui

@ -1 +1 @@
Subproject commit 6e0e1026147364cfb1234489980a2625ab50b598
Subproject commit 3d82d03bbb03c0cdb11bcaa399c01a57671044d8