mirror of https://github.com/procxx/kepka.git
Request, show and require accept for updated ToS.
This commit is contained in:
parent
c85fd368fe
commit
9ebeddbed8
|
@ -1524,6 +1524,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_terms_agree" = "Agree & Continue";
|
"lng_terms_agree" = "Agree & Continue";
|
||||||
"lng_terms_decline" = "Decline";
|
"lng_terms_decline" = "Decline";
|
||||||
"lng_terms_signup_sorry" = "We're very sorry, but this means you can't sign up for Telegram.\n\nUnlike others, we don't use your data for ad targeting or other commercial purposes. Telegram only stores the information it needs to function as a feature-rich cloud service. You can adjust how we use your data in Privacy & Security settings.\n\nBut if you're generally not OK with Telegram's modest needs, it won't be possible for us to provide this service.";
|
"lng_terms_signup_sorry" = "We're very sorry, but this means you can't sign up for Telegram.\n\nUnlike others, we don't use your data for ad targeting or other commercial purposes. Telegram only stores the information it needs to function as a feature-rich cloud service. You can adjust how we use your data in Privacy & Security settings.\n\nBut if you're generally not OK with Telegram's modest needs, it won't be possible for us to provide this service.";
|
||||||
|
"lng_terms_update_sorry" = "We're very sorry, but this means we must part ways here. Unlike others, we don't use your data for ad targeting or other commercial purposes. Telegram only stores the information it needs to function as a feature-rich cloud service. You can adjust how we use your data in Privacy & Security settings.\n\nBut if you're generally not OK with Telegram's modest needs, it won't be possible for us to provide this service. You can deactivate your account now — or look around some more and deactivate it later if you feel you're not happy with the way we use your data. How does that sound?";
|
||||||
|
"lng_terms_decline_and_delete" = "Decline & Delete";
|
||||||
|
"lng_terms_back" = "Back";
|
||||||
|
"lng_terms_delete_warning" = "Warning, this will irreversibly delete your Telegram account along with all the data you store in the Telegram cloud.\n\nWe will provide a tool to download your data before June, 23 – so you may want to wait a little before deleting.";
|
||||||
|
"lng_terms_delete_now" = "Delete now";
|
||||||
|
"lng_terms_agree_to_proceed" = "Please agree and proceed to {bot}.";
|
||||||
|
|
||||||
"lng_date_input_day" = "Day";
|
"lng_date_input_day" = "Day";
|
||||||
"lng_date_input_month" = "Month";
|
"lng_date_input_month" = "Month";
|
||||||
|
|
|
@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "window/notifications_manager.h"
|
#include "window/notifications_manager.h"
|
||||||
|
#include "window/window_lock_widgets.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "chat_helpers/message_field.h"
|
#include "chat_helpers/message_field.h"
|
||||||
#include "chat_helpers/stickers.h"
|
#include "chat_helpers/stickers.h"
|
||||||
|
@ -249,6 +250,62 @@ void ApiWrap::requestDeepLinkInfo(
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiWrap::requestTermsUpdate() {
|
||||||
|
if (_termsUpdateRequestId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto now = getms(true);
|
||||||
|
if (_termsUpdateSendAt && now < _termsUpdateSendAt) {
|
||||||
|
App::CallDelayed(_termsUpdateSendAt - now, _session, [=] {
|
||||||
|
requestTermsUpdate();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto kTermsUpdateTimeoutMin = 10 * TimeMs(1000);
|
||||||
|
constexpr auto kTermsUpdateTimeoutMax = 86400 * TimeMs(1000);
|
||||||
|
|
||||||
|
_termsUpdateRequestId = request(MTPhelp_GetTermsOfServiceUpdate(
|
||||||
|
)).done([=](const MTPhelp_TermsOfServiceUpdate &result) {
|
||||||
|
_termsUpdateRequestId = 0;
|
||||||
|
|
||||||
|
const auto requestNext = [&](auto &&data) {
|
||||||
|
_termsUpdateSendAt = getms(true) + snap(
|
||||||
|
TimeMs(data.vexpires.v - unixtime()),
|
||||||
|
kTermsUpdateTimeoutMin,
|
||||||
|
kTermsUpdateTimeoutMax);
|
||||||
|
requestTermsUpdate();
|
||||||
|
};
|
||||||
|
switch (result.type()) {
|
||||||
|
case mtpc_help_termsOfServiceUpdateEmpty: {
|
||||||
|
const auto &data = result.c_help_termsOfServiceUpdateEmpty();
|
||||||
|
requestNext(data);
|
||||||
|
} break;
|
||||||
|
case mtpc_help_termsOfServiceUpdate: {
|
||||||
|
const auto &data = result.c_help_termsOfServiceUpdate();
|
||||||
|
const auto &terms = data.vterms_of_service;
|
||||||
|
const auto &fields = terms.c_help_termsOfService();
|
||||||
|
Messenger::Instance().lockByTerms(
|
||||||
|
Window::TermsLock::FromMTP(fields));
|
||||||
|
requestNext(data);
|
||||||
|
} break;
|
||||||
|
default: Unexpected("Type in requestTermsUpdate().");
|
||||||
|
}
|
||||||
|
}).fail([=](const RPCError &error) {
|
||||||
|
_termsUpdateRequestId = 0;
|
||||||
|
_termsUpdateSendAt = getms(true) + kTermsUpdateTimeoutMin;
|
||||||
|
requestTermsUpdate();
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::acceptTerms(bytes::const_span id) {
|
||||||
|
request(MTPhelp_AcceptTermsOfService(
|
||||||
|
MTP_dataJSON(MTP_bytes(id))
|
||||||
|
)).done([=](const MTPBool &result) {
|
||||||
|
requestTermsUpdate();
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
void ApiWrap::applyUpdates(
|
void ApiWrap::applyUpdates(
|
||||||
const MTPUpdates &updates,
|
const MTPUpdates &updates,
|
||||||
uint64 sentMessageRandomId) {
|
uint64 sentMessageRandomId) {
|
||||||
|
|
|
@ -97,6 +97,8 @@ public:
|
||||||
void requestDeepLinkInfo(
|
void requestDeepLinkInfo(
|
||||||
const QString &path,
|
const QString &path,
|
||||||
Fn<void(const MTPDhelp_deepLinkInfo &result)> callback);
|
Fn<void(const MTPDhelp_deepLinkInfo &result)> callback);
|
||||||
|
void requestTermsUpdate();
|
||||||
|
void acceptTerms(bytes::const_span termsId);
|
||||||
|
|
||||||
void requestChannelMembersForAdd(
|
void requestChannelMembersForAdd(
|
||||||
not_null<ChannelData*> channel,
|
not_null<ChannelData*> channel,
|
||||||
|
@ -583,4 +585,7 @@ private:
|
||||||
|
|
||||||
mtpRequestId _deepLinkInfoRequestId = 0;
|
mtpRequestId _deepLinkInfoRequestId = 0;
|
||||||
|
|
||||||
|
TimeMs _termsUpdateSendAt = 0;
|
||||||
|
mtpRequestId _termsUpdateRequestId = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -140,13 +140,6 @@ namespace App {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool passcoded() {
|
|
||||||
if (auto window = wnd()) {
|
|
||||||
return window->passcodeWidget();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// we should get a full restriction in "{fulltype}: {reason}" format and we
|
// we should get a full restriction in "{fulltype}: {reason}" format and we
|
||||||
// need to find a "-all" tag in {fulltype}, otherwise ignore this restriction
|
// need to find a "-all" tag in {fulltype}, otherwise ignore this restriction
|
||||||
|
|
|
@ -66,7 +66,6 @@ enum RoundCorners {
|
||||||
namespace App {
|
namespace App {
|
||||||
MainWindow *wnd();
|
MainWindow *wnd();
|
||||||
MainWidget *main();
|
MainWidget *main();
|
||||||
bool passcoded();
|
|
||||||
|
|
||||||
QString formatPhone(QString phone);
|
QString formatPhone(QString phone);
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,8 @@ QString _escapeFrom7bit(const QString &str) {
|
||||||
|
|
||||||
bool StartUrlRequiresActivate(const QString &url) {
|
bool StartUrlRequiresActivate(const QString &url) {
|
||||||
const auto urlTrimmed = url.trimmed();
|
const auto urlTrimmed = url.trimmed();
|
||||||
if (!urlTrimmed.startsWith(qstr("tg://"), Qt::CaseInsensitive) || App::passcoded()) {
|
if (!urlTrimmed.startsWith(qstr("tg://"), Qt::CaseInsensitive)
|
||||||
|
|| Messenger::Instance().locked()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const auto command = urlTrimmed.midRef(qstr("tg://").size());
|
const auto command = urlTrimmed.midRef(qstr("tg://").size());
|
||||||
|
|
|
@ -281,14 +281,19 @@ AuthSession::AuthSession(UserId userId)
|
||||||
_saveDataTimer.setCallback([=] {
|
_saveDataTimer.setCallback([=] {
|
||||||
Local::writeUserSettings();
|
Local::writeUserSettings();
|
||||||
});
|
});
|
||||||
subscribe(Messenger::Instance().passcodedChanged(), [=] {
|
Messenger::Instance().passcodeLockChanges(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
_shouldLockAt = 0;
|
_shouldLockAt = 0;
|
||||||
|
}, _lifetime);
|
||||||
|
Messenger::Instance().lockChanges(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
notifications().updateAll();
|
notifications().updateAll();
|
||||||
});
|
}, _lifetime);
|
||||||
subscribe(Global::RefConnectionTypeChanged(), [=] {
|
subscribe(Global::RefConnectionTypeChanged(), [=] {
|
||||||
_api->refreshProxyPromotion();
|
_api->refreshProxyPromotion();
|
||||||
});
|
});
|
||||||
_api->refreshProxyPromotion();
|
_api->refreshProxyPromotion();
|
||||||
|
_api->requestTermsUpdate();
|
||||||
|
|
||||||
Window::Theme::Background()->start();
|
Window::Theme::Background()->start();
|
||||||
}
|
}
|
||||||
|
@ -327,7 +332,10 @@ void AuthSession::saveSettingsDelayed(TimeMs delay) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthSession::checkAutoLock() {
|
void AuthSession::checkAutoLock() {
|
||||||
if (!Global::LocalPasscode() || App::passcoded()) return;
|
if (!Global::LocalPasscode()
|
||||||
|
|| Messenger::Instance().passcodeLocked()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Messenger::Instance().checkLocalTime();
|
Messenger::Instance().checkLocalTime();
|
||||||
auto now = getms(true);
|
auto now = getms(true);
|
||||||
|
@ -336,7 +344,7 @@ void AuthSession::checkAutoLock() {
|
||||||
auto notPlayingVideoForMs = now - settings().lastTimeVideoPlayedAt();
|
auto notPlayingVideoForMs = now - settings().lastTimeVideoPlayedAt();
|
||||||
auto checkTimeMs = qMin(idleForMs, notPlayingVideoForMs);
|
auto checkTimeMs = qMin(idleForMs, notPlayingVideoForMs);
|
||||||
if (checkTimeMs >= shouldLockInMs || (_shouldLockAt > 0 && now > _shouldLockAt + kAutoLockTimeoutLateMs)) {
|
if (checkTimeMs >= shouldLockInMs || (_shouldLockAt > 0 && now > _shouldLockAt + kAutoLockTimeoutLateMs)) {
|
||||||
Messenger::Instance().setupPasscode();
|
Messenger::Instance().lockByPasscode();
|
||||||
} else {
|
} else {
|
||||||
_shouldLockAt = now + (shouldLockInMs - checkTimeMs);
|
_shouldLockAt = now + (shouldLockInMs - checkTimeMs);
|
||||||
_autoLockTimer.callOnce(shouldLockInMs - checkTimeMs);
|
_autoLockTimer.callOnce(shouldLockInMs - checkTimeMs);
|
||||||
|
|
|
@ -785,3 +785,9 @@ proxyAboutPadding: margins(22px, 7px, 22px, 14px);
|
||||||
proxyAboutSponsorPadding: margins(22px, 7px, 22px, 0px);
|
proxyAboutSponsorPadding: margins(22px, 7px, 22px, 0px);
|
||||||
|
|
||||||
markdownLinkFieldPadding: margins(22px, 0px, 22px, 10px);
|
markdownLinkFieldPadding: margins(22px, 0px, 22px, 10px);
|
||||||
|
|
||||||
|
termsContent: FlatLabel(defaultFlatLabel) {
|
||||||
|
minWidth: 285px;
|
||||||
|
}
|
||||||
|
termsPadding: margins(23px, 4px, 16px, 16px);
|
||||||
|
termsAgePadding: margins(23px, 16px, 16px, 0px);
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
}
|
}
|
||||||
void addItem(not_null<HistoryItem*> item) {
|
void addItem(not_null<HistoryItem*> item) {
|
||||||
Expects(canAddItem(item));
|
Expects(canAddItem(item));
|
||||||
|
|
||||||
_items.push_back(item);
|
_items.push_back(item);
|
||||||
ranges::sort(_items, [](not_null<HistoryItem*> a, auto b) {
|
ranges::sort(_items, [](not_null<HistoryItem*> a, auto b) {
|
||||||
return (a->id > b->id);
|
return (a->id > b->id);
|
||||||
|
|
|
@ -140,7 +140,7 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
|
||||||
subscribe(Global::RefLocalPasscodeChanged(), [this] { updateLockUnlockVisibility(); });
|
subscribe(Global::RefLocalPasscodeChanged(), [this] { updateLockUnlockVisibility(); });
|
||||||
_lockUnlock->setClickedCallback([this] {
|
_lockUnlock->setClickedCallback([this] {
|
||||||
_lockUnlock->setIconOverride(&st::dialogsUnlockIcon, &st::dialogsUnlockIconOver);
|
_lockUnlock->setIconOverride(&st::dialogsUnlockIcon, &st::dialogsUnlockIconOver);
|
||||||
Messenger::Instance().setupPasscode();
|
Messenger::Instance().lockByPasscode();
|
||||||
_lockUnlock->setIconOverride(nullptr);
|
_lockUnlock->setIconOverride(nullptr);
|
||||||
});
|
});
|
||||||
_mainMenuToggle->setClickedCallback([this] { showMainMenu(); });
|
_mainMenuToggle->setClickedCallback([this] { showMainMenu(); });
|
||||||
|
|
|
@ -46,8 +46,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "passcodewidget.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "storage/localimageloader.h"
|
#include "storage/localimageloader.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "storage/file_upload.h"
|
#include "storage/file_upload.h"
|
||||||
|
@ -55,6 +53,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "media/media_audio.h"
|
#include "media/media_audio.h"
|
||||||
#include "media/media_audio_capture.h"
|
#include "media/media_audio_capture.h"
|
||||||
#include "media/player/media_player_instance.h"
|
#include "media/player/media_player_instance.h"
|
||||||
|
#include "messenger.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "history/view/history_view_top_bar_widget.h"
|
#include "history/view/history_view_top_bar_widget.h"
|
||||||
#include "observer_peer.h"
|
#include "observer_peer.h"
|
||||||
|
@ -6472,8 +6471,13 @@ void HistoryWidget::updateTopBarSelection() {
|
||||||
_topBar->showSelected(selectedState);
|
_topBar->showSelected(selectedState);
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
updateHistoryGeometry();
|
updateHistoryGeometry();
|
||||||
if (!Ui::isLayerShown() && !App::passcoded()) {
|
if (!Ui::isLayerShown() && !Messenger::Instance().locked()) {
|
||||||
if (_nonEmptySelection || (_list && _list->wasSelectedText()) || _recording || isBotStart() || isBlocked() || !_canSendMessages) {
|
if (_nonEmptySelection
|
||||||
|
|| (_list && _list->wasSelectedText())
|
||||||
|
|| _recording
|
||||||
|
|| isBotStart()
|
||||||
|
|| isBlocked()
|
||||||
|
|| !_canSendMessages) {
|
||||||
_list->setFocus();
|
_list->setFocus();
|
||||||
} else {
|
} else {
|
||||||
_field->setFocus();
|
_field->setFocus();
|
||||||
|
|
|
@ -129,11 +129,6 @@ introTermsLabel: FlatLabel(defaultFlatLabel) {
|
||||||
align: align(top);
|
align: align(top);
|
||||||
}
|
}
|
||||||
introTermsBottom: 20px;
|
introTermsBottom: 20px;
|
||||||
introTermsContent: FlatLabel(defaultFlatLabel) {
|
|
||||||
minWidth: 285px;
|
|
||||||
}
|
|
||||||
introTermsPadding: margins(23px, 0px, 16px, 0px);
|
|
||||||
introTermsAgePadding: margins(23px, 8px, 16px, 8px);
|
|
||||||
|
|
||||||
introCountryIcon: icon {{ "intro_country_dropdown", menuIconFg }};
|
introCountryIcon: icon {{ "intro_country_dropdown", menuIconFg }};
|
||||||
introCountryIconPosition: point(8px, 37px);
|
introCountryIconPosition: point(8px, 37px);
|
||||||
|
|
|
@ -217,8 +217,8 @@ void SignupWidget::submit() {
|
||||||
rpcFail(&SignupWidget::nameSubmitFail));
|
rpcFail(&SignupWidget::nameSubmitFail));
|
||||||
};
|
};
|
||||||
if (_termsAccepted
|
if (_termsAccepted
|
||||||
|| getData()->termsText.text.isEmpty()
|
|| getData()->termsLock.text.text.isEmpty()
|
||||||
|| !getData()->termsPopup) {
|
|| !getData()->termsLock.popup) {
|
||||||
send();
|
send();
|
||||||
} else {
|
} else {
|
||||||
acceptTerms(crl::guard(this, [=] {
|
acceptTerms(crl::guard(this, [=] {
|
||||||
|
|
|
@ -24,13 +24,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/text/text.h"
|
#include "ui/text/text.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/widgets/checkbox.h"
|
|
||||||
#include "ui/wrap/fade_wrap.h"
|
#include "ui/wrap/fade_wrap.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
|
||||||
#include "ui/effects/slide_animation.h"
|
#include "ui/effects/slide_animation.h"
|
||||||
#include "core/update_checker.h"
|
#include "core/update_checker.h"
|
||||||
#include "window/window_slide_animation.h"
|
#include "window/window_slide_animation.h"
|
||||||
#include "window/window_connecting_widget.h"
|
#include "window/window_connecting_widget.h"
|
||||||
|
#include "window/window_lock_widgets.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "styles/style_intro.h"
|
#include "styles/style_intro.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
|
@ -43,114 +42,6 @@ namespace {
|
||||||
|
|
||||||
constexpr str_const kDefaultCountry = "US";
|
constexpr str_const kDefaultCountry = "US";
|
||||||
|
|
||||||
class TermsBox : public BoxContent {
|
|
||||||
public:
|
|
||||||
TermsBox(
|
|
||||||
QWidget*,
|
|
||||||
const TextWithEntities &text,
|
|
||||||
Fn<QString()> agree,
|
|
||||||
Fn<QString()> cancel,
|
|
||||||
int age = 0);
|
|
||||||
|
|
||||||
rpl::producer<> agreeClicks() const;
|
|
||||||
rpl::producer<> cancelClicks() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void prepare() override;
|
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent *e) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
TextWithEntities _text;
|
|
||||||
Fn<QString()> _agree;
|
|
||||||
Fn<QString()> _cancel;
|
|
||||||
int _age = 0;
|
|
||||||
rpl::event_stream<> _agreeClicks;
|
|
||||||
rpl::event_stream<> _cancelClicks;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
TermsBox::TermsBox(
|
|
||||||
QWidget*,
|
|
||||||
const TextWithEntities &text,
|
|
||||||
Fn<QString()> agree,
|
|
||||||
Fn<QString()> cancel,
|
|
||||||
int age)
|
|
||||||
: _text(text)
|
|
||||||
, _agree(agree)
|
|
||||||
, _cancel(cancel)
|
|
||||||
, _age(age) {
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<> TermsBox::agreeClicks() const {
|
|
||||||
return _agreeClicks.events();
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<> TermsBox::cancelClicks() const {
|
|
||||||
return _cancelClicks.events();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TermsBox::prepare() {
|
|
||||||
setTitle(langFactory(lng_terms_header));
|
|
||||||
|
|
||||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
|
||||||
content->add(
|
|
||||||
object_ptr<Ui::FlatLabel> (
|
|
||||||
this,
|
|
||||||
rpl::single(_text),
|
|
||||||
st::introTermsContent),
|
|
||||||
st::introTermsPadding);
|
|
||||||
const auto age = (_age > 0)
|
|
||||||
? content->add(
|
|
||||||
object_ptr<Ui::Checkbox>(
|
|
||||||
this,
|
|
||||||
lng_terms_age(lt_count, _age)),
|
|
||||||
st::introTermsAgePadding)
|
|
||||||
: nullptr;
|
|
||||||
|
|
||||||
const auto refreshButtons = [=] {
|
|
||||||
clearButtons();
|
|
||||||
if (age && !age->checked()) {
|
|
||||||
addButton(langFactory(lng_cancel), [=] { closeBox(); });
|
|
||||||
} else {
|
|
||||||
addButton(_agree, [=] {})->clicks(
|
|
||||||
) | rpl::filter([=] {
|
|
||||||
if (age && !age->checked()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}) | rpl::start_to_stream(_agreeClicks, lifetime());
|
|
||||||
|
|
||||||
if (_cancel) {
|
|
||||||
addButton(_cancel, [=] {})->clicks(
|
|
||||||
) | rpl::start_to_stream(_cancelClicks, lifetime());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (age) {
|
|
||||||
base::ObservableViewer(
|
|
||||||
age->checkedChanged
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
refreshButtons();
|
|
||||||
}, lifetime());
|
|
||||||
}
|
|
||||||
refreshButtons();
|
|
||||||
|
|
||||||
content->resizeToWidth(st::boxWideWidth);
|
|
||||||
content->heightValue(
|
|
||||||
) | rpl::start_with_next([=](int height) {
|
|
||||||
setDimensions(st::boxWideWidth, height);
|
|
||||||
}, content->lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TermsBox::keyPressEvent(QKeyEvent *e) {
|
|
||||||
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
|
||||||
_agreeClicks.fire({});
|
|
||||||
} else {
|
|
||||||
BoxContent::keyPressEvent(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Widget::Widget(QWidget *parent) : RpWidget(parent)
|
Widget::Widget(QWidget *parent) : RpWidget(parent)
|
||||||
|
@ -412,7 +303,7 @@ void Widget::showResetButton() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::showTerms() {
|
void Widget::showTerms() {
|
||||||
if (getData()->termsText.text.isEmpty()) {
|
if (getData()->termsLock.text.text.isEmpty()) {
|
||||||
_terms.destroy();
|
_terms.destroy();
|
||||||
} else if (!_terms) {
|
} else if (!_terms) {
|
||||||
auto entity = object_ptr<Ui::FlatLabel>(
|
auto entity = object_ptr<Ui::FlatLabel>(
|
||||||
|
@ -498,15 +389,22 @@ void Widget::getNearestDC() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::showTerms(Fn<void()> callback) {
|
void Widget::showTerms(Fn<void()> callback) {
|
||||||
if (getData()->termsText.text.isEmpty()) {
|
if (getData()->termsLock.text.text.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto weak = make_weak(this);
|
const auto weak = make_weak(this);
|
||||||
const auto box = Ui::show(Box<TermsBox>(
|
const auto box = Ui::show(callback
|
||||||
getData()->termsText,
|
? Box<Window::TermsBox>(
|
||||||
langFactory(callback ? lng_terms_agree : lng_box_ok),
|
getData()->termsLock,
|
||||||
callback ? langFactory(lng_terms_decline) : nullptr,
|
langFactory(lng_terms_agree),
|
||||||
getData()->termsAge));
|
langFactory(lng_terms_decline))
|
||||||
|
: Box<Window::TermsBox>(
|
||||||
|
getData()->termsLock.text,
|
||||||
|
langFactory(lng_box_ok),
|
||||||
|
nullptr));
|
||||||
|
|
||||||
|
box->setCloseByEscape(false);
|
||||||
|
box->setCloseByOutsideClick(false);
|
||||||
|
|
||||||
box->agreeClicks(
|
box->agreeClicks(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
|
@ -520,7 +418,7 @@ void Widget::showTerms(Fn<void()> callback) {
|
||||||
|
|
||||||
box->cancelClicks(
|
box->cancelClicks(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
const auto box = Ui::show(Box<TermsBox>(
|
const auto box = Ui::show(Box<Window::TermsBox>(
|
||||||
TextWithEntities{ lang(lng_terms_signup_sorry) },
|
TextWithEntities{ lang(lng_terms_signup_sorry) },
|
||||||
langFactory(lng_intro_finish),
|
langFactory(lng_intro_finish),
|
||||||
langFactory(lng_terms_decline)));
|
langFactory(lng_terms_decline)));
|
||||||
|
@ -836,16 +734,9 @@ bool Widget::Step::paintAnimated(Painter &p, QRect clip) {
|
||||||
void Widget::Step::fillSentCodeData(const MTPDauth_sentCode &data) {
|
void Widget::Step::fillSentCodeData(const MTPDauth_sentCode &data) {
|
||||||
if (data.has_terms_of_service()) {
|
if (data.has_terms_of_service()) {
|
||||||
const auto &terms = data.vterms_of_service.c_help_termsOfService();
|
const auto &terms = data.vterms_of_service.c_help_termsOfService();
|
||||||
getData()->termsText = TextWithEntities{
|
getData()->termsLock = Window::TermsLock::FromMTP(terms);
|
||||||
TextUtilities::Clean(qs(terms.vtext)),
|
|
||||||
TextUtilities::EntitiesFromMTP(terms.ventities.v) };
|
|
||||||
getData()->termsPopup = terms.is_popup();
|
|
||||||
getData()->termsAge = terms.has_min_age_confirm()
|
|
||||||
? terms.vmin_age_confirm.v
|
|
||||||
: 0;
|
|
||||||
} else {
|
} else {
|
||||||
getData()->termsText = TextWithEntities();
|
getData()->termsLock = Window::TermsLock();
|
||||||
getData()->termsAge = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &type = data.vtype;
|
const auto &type = data.vtype;
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
|
#include "window/window_lock_widgets.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class IconButton;
|
class IconButton;
|
||||||
|
@ -78,9 +79,7 @@ public:
|
||||||
QString pwdHint;
|
QString pwdHint;
|
||||||
bool pwdNotEmptyPassport = false;
|
bool pwdNotEmptyPassport = false;
|
||||||
|
|
||||||
TextWithEntities termsText;
|
Window::TermsLock termsLock;
|
||||||
bool termsPopup = false;
|
|
||||||
int termsAge = 0;
|
|
||||||
|
|
||||||
base::Observable<void> updated;
|
base::Observable<void> updated;
|
||||||
|
|
||||||
|
|
|
@ -872,7 +872,7 @@ void MainWidget::noHider(HistoryHider *destroyed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::hiderLayer(object_ptr<HistoryHider> h) {
|
void MainWidget::hiderLayer(object_ptr<HistoryHider> h) {
|
||||||
if (App::passcoded()) {
|
if (Messenger::Instance().locked()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2082,7 +2082,7 @@ void MainWidget::ui_showPeerHistory(
|
||||||
|
|
||||||
auto animatedShow = [&] {
|
auto animatedShow = [&] {
|
||||||
if (_a_show.animating()
|
if (_a_show.animating()
|
||||||
|| App::passcoded()
|
|| Messenger::Instance().locked()
|
||||||
|| (params.animated == anim::type::instant)) {
|
|| (params.animated == anim::type::instant)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2411,7 +2411,7 @@ void MainWidget::showNewSection(
|
||||||
|
|
||||||
auto animatedShow = [&] {
|
auto animatedShow = [&] {
|
||||||
if (_a_show.animating()
|
if (_a_show.animating()
|
||||||
|| App::passcoded()
|
|| Messenger::Instance().locked()
|
||||||
|| (params.animated == anim::type::instant)
|
|| (params.animated == anim::type::instant)
|
||||||
|| memento.instant()) {
|
|| memento.instant()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -21,8 +21,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "shortcuts.h"
|
#include "shortcuts.h"
|
||||||
#include "messenger.h"
|
#include "messenger.h"
|
||||||
|
#include "auth_session.h"
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "passcodewidget.h"
|
|
||||||
#include "intro/introwidget.h"
|
#include "intro/introwidget.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
|
@ -38,8 +38,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/notifications_manager.h"
|
#include "window/notifications_manager.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "window/themes/window_theme_warning.h"
|
#include "window/themes/window_theme_warning.h"
|
||||||
|
#include "window/window_lock_widgets.h"
|
||||||
#include "window/window_main_menu.h"
|
#include "window/window_main_menu.h"
|
||||||
#include "auth_session.h"
|
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -82,7 +82,10 @@ MainWindow::MainWindow() {
|
||||||
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &data) {
|
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &data) {
|
||||||
themeUpdated(data);
|
themeUpdated(data);
|
||||||
});
|
});
|
||||||
subscribe(Messenger::Instance().passcodedChanged(), [this] { updateGlobalMenu(); });
|
Messenger::Instance().lockChanges(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
updateGlobalMenu();
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
setAttribute(Qt::WA_NoSystemBackground);
|
setAttribute(Qt::WA_NoSystemBackground);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
@ -126,7 +129,7 @@ void MainWindow::firstShow() {
|
||||||
|
|
||||||
void MainWindow::clearWidgetsHook() {
|
void MainWindow::clearWidgetsHook() {
|
||||||
auto wasMain = (_main != nullptr);
|
auto wasMain = (_main != nullptr);
|
||||||
_passcode.destroyDelayed();
|
_passcodeLock.destroy();
|
||||||
_main.destroy();
|
_main.destroy();
|
||||||
_intro.destroy();
|
_intro.destroy();
|
||||||
if (wasMain) {
|
if (wasMain) {
|
||||||
|
@ -135,23 +138,43 @@ void MainWindow::clearWidgetsHook() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap MainWindow::grabInner() {
|
QPixmap MainWindow::grabInner() {
|
||||||
QPixmap result;
|
|
||||||
if (_intro) {
|
if (_intro) {
|
||||||
result = Ui::GrabWidget(_intro);
|
return Ui::GrabWidget(_intro);
|
||||||
} else if (_passcode) {
|
} else if (_passcodeLock) {
|
||||||
result = Ui::GrabWidget(_passcode);
|
return Ui::GrabWidget(_passcodeLock);
|
||||||
} else if (_main) {
|
} else if (_main) {
|
||||||
result = Ui::GrabWidget(_main);
|
return Ui::GrabWidget(_main);
|
||||||
}
|
}
|
||||||
return result;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::clearPasscode() {
|
void MainWindow::setupPasscodeLock() {
|
||||||
if (!_passcode) return;
|
auto animated = (_main || _intro);
|
||||||
|
auto bg = animated ? grabInner() : QPixmap();
|
||||||
|
_passcodeLock.create(bodyWidget());
|
||||||
|
updateControlsGeometry();
|
||||||
|
|
||||||
|
Messenger::Instance().hideMediaView();
|
||||||
|
Ui::hideSettingsAndLayer(anim::type::instant);
|
||||||
|
if (_main) {
|
||||||
|
_main->hide();
|
||||||
|
}
|
||||||
|
if (_intro) {
|
||||||
|
_intro->hide();
|
||||||
|
}
|
||||||
|
if (animated) {
|
||||||
|
_passcodeLock->showAnimated(bg);
|
||||||
|
} else {
|
||||||
|
setInnerFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::clearPasscodeLock() {
|
||||||
|
if (!_passcodeLock) return;
|
||||||
|
|
||||||
auto bg = grabInner();
|
auto bg = grabInner();
|
||||||
|
|
||||||
_passcode.destroy();
|
_passcodeLock.destroy();
|
||||||
if (_intro) {
|
if (_intro) {
|
||||||
_intro->showAnimated(bg, true);
|
_intro->showAnimated(bg, true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -161,23 +184,6 @@ void MainWindow::clearPasscode() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupPasscode() {
|
|
||||||
auto animated = (_main || _intro);
|
|
||||||
auto bg = animated ? grabInner() : QPixmap();
|
|
||||||
_passcode.create(bodyWidget());
|
|
||||||
updateControlsGeometry();
|
|
||||||
|
|
||||||
if (_main) _main->hide();
|
|
||||||
Messenger::Instance().hideMediaView();
|
|
||||||
Ui::hideSettingsAndLayer(anim::type::instant);
|
|
||||||
if (_intro) _intro->hide();
|
|
||||||
if (animated) {
|
|
||||||
_passcode->showAnimated(bg);
|
|
||||||
} else {
|
|
||||||
setInnerFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::setupIntro() {
|
void MainWindow::setupIntro() {
|
||||||
if (_intro && !_intro->isHidden() && !_main) {
|
if (_intro && !_intro->isHidden() && !_main) {
|
||||||
return;
|
return;
|
||||||
|
@ -185,7 +191,7 @@ void MainWindow::setupIntro() {
|
||||||
|
|
||||||
Ui::hideSettingsAndLayer(anim::type::instant);
|
Ui::hideSettingsAndLayer(anim::type::instant);
|
||||||
|
|
||||||
auto animated = (_main || _passcode);
|
auto animated = (_main || _passcodeLock);
|
||||||
auto bg = animated ? grabInner() : QPixmap();
|
auto bg = animated ? grabInner() : QPixmap();
|
||||||
|
|
||||||
clearWidgets();
|
clearWidgets();
|
||||||
|
@ -267,7 +273,7 @@ void MainWindow::sendServiceHistoryRequest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupMain(const MTPUser *self) {
|
void MainWindow::setupMain(const MTPUser *self) {
|
||||||
auto animated = (_intro || _passcode);
|
auto animated = (_intro || _passcodeLock);
|
||||||
auto bg = animated ? grabInner() : QPixmap();
|
auto bg = animated ? grabInner() : QPixmap();
|
||||||
|
|
||||||
clearWidgets();
|
clearWidgets();
|
||||||
|
@ -297,7 +303,7 @@ void MainWindow::showSettings() {
|
||||||
void MainWindow::showSpecialLayer(
|
void MainWindow::showSpecialLayer(
|
||||||
object_ptr<Window::LayerWidget> layer,
|
object_ptr<Window::LayerWidget> layer,
|
||||||
anim::type animated) {
|
anim::type animated) {
|
||||||
if (_passcode) return;
|
if (_passcodeLock) return;
|
||||||
|
|
||||||
if (layer) {
|
if (layer) {
|
||||||
ensureLayerCreated();
|
ensureLayerCreated();
|
||||||
|
@ -317,7 +323,7 @@ bool MainWindow::showSectionInExistingLayer(
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::showMainMenu() {
|
void MainWindow::showMainMenu() {
|
||||||
if (_passcode) return;
|
if (_passcodeLock) return;
|
||||||
|
|
||||||
if (isHidden()) showFromTray();
|
if (isHidden()) showFromTray();
|
||||||
|
|
||||||
|
@ -360,10 +366,6 @@ MainWidget *MainWindow::mainWidget() {
|
||||||
return _main;
|
return _main;
|
||||||
}
|
}
|
||||||
|
|
||||||
PasscodeWidget *MainWindow::passcodeWidget() {
|
|
||||||
return _passcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::ui_showBox(
|
void MainWindow::ui_showBox(
|
||||||
object_ptr<BoxContent> box,
|
object_ptr<BoxContent> box,
|
||||||
LayerOptions options,
|
LayerOptions options,
|
||||||
|
@ -481,8 +483,8 @@ void MainWindow::setInnerFocus() {
|
||||||
_testingThemeWarning->setFocus();
|
_testingThemeWarning->setFocus();
|
||||||
} else if (_layer && _layer->canSetFocus()) {
|
} else if (_layer && _layer->canSetFocus()) {
|
||||||
_layer->setInnerFocus();
|
_layer->setInnerFocus();
|
||||||
} else if (_passcode) {
|
} else if (_passcodeLock) {
|
||||||
_passcode->setInnerFocus();
|
_passcodeLock->setInnerFocus();
|
||||||
} else if (_main) {
|
} else if (_main) {
|
||||||
_main->setInnerFocus();
|
_main->setInnerFocus();
|
||||||
} else if (_intro) {
|
} else if (_intro) {
|
||||||
|
@ -700,7 +702,7 @@ bool MainWindow::skipTrayClick() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::toggleDisplayNotifyFromTray() {
|
void MainWindow::toggleDisplayNotifyFromTray() {
|
||||||
if (App::passcoded()) {
|
if (Messenger::Instance().locked()) {
|
||||||
if (!isActive()) showFromTray();
|
if (!isActive()) showFromTray();
|
||||||
Ui::show(Box<InformBox>(lang(lng_passcode_need_unblock)));
|
Ui::show(Box<InformBox>(lang(lng_passcode_need_unblock)));
|
||||||
return;
|
return;
|
||||||
|
@ -749,7 +751,7 @@ void MainWindow::updateControlsGeometry() {
|
||||||
Platform::MainWindow::updateControlsGeometry();
|
Platform::MainWindow::updateControlsGeometry();
|
||||||
|
|
||||||
auto body = bodyWidget()->rect();
|
auto body = bodyWidget()->rect();
|
||||||
if (_passcode) _passcode->setGeometry(body);
|
if (_passcodeLock) _passcodeLock->setGeometry(body);
|
||||||
if (_main) _main->setGeometry(body);
|
if (_main) _main->setGeometry(body);
|
||||||
if (_intro) _intro->setGeometry(body);
|
if (_intro) _intro->setGeometry(body);
|
||||||
if (_layer) _layer->setGeometry(body);
|
if (_layer) _layer->setGeometry(body);
|
||||||
|
@ -911,7 +913,9 @@ QImage MainWindow::iconWithCounter(int size, int count, style::color bg, style::
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::sendPaths() {
|
void MainWindow::sendPaths() {
|
||||||
if (App::passcoded()) return;
|
if (Messenger::Instance().locked()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Messenger::Instance().hideMediaView();
|
Messenger::Instance().hideMediaView();
|
||||||
Ui::hideSettingsAndLayer(anim::type::instant);
|
Ui::hideSettingsAndLayer(anim::type::instant);
|
||||||
if (_main) {
|
if (_main) {
|
||||||
|
|
|
@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "platform/platform_main_window.h"
|
#include "platform/platform_main_window.h"
|
||||||
#include "core/single_timer.h"
|
#include "core/single_timer.h"
|
||||||
|
|
||||||
class PasscodeWidget;
|
|
||||||
class MainWidget;
|
class MainWidget;
|
||||||
class BoxContent;
|
class BoxContent;
|
||||||
|
|
||||||
|
@ -28,6 +27,7 @@ class LayerWidget;
|
||||||
class LayerStackWidget;
|
class LayerStackWidget;
|
||||||
class SectionMemento;
|
class SectionMemento;
|
||||||
struct SectionShow;
|
struct SectionShow;
|
||||||
|
class PasscodeLockWidget;
|
||||||
namespace Theme {
|
namespace Theme {
|
||||||
struct BackgroundUpdate;
|
struct BackgroundUpdate;
|
||||||
class WarningWidget;
|
class WarningWidget;
|
||||||
|
@ -49,8 +49,8 @@ public:
|
||||||
|
|
||||||
void firstShow();
|
void firstShow();
|
||||||
|
|
||||||
void setupPasscode();
|
void setupPasscodeLock();
|
||||||
void clearPasscode();
|
void clearPasscodeLock();
|
||||||
void setupIntro();
|
void setupIntro();
|
||||||
void setupMain(const MTPUser *user = nullptr);
|
void setupMain(const MTPUser *user = nullptr);
|
||||||
void serviceNotification(const TextWithEntities &message, const MTPMessageMedia &media = MTP_messageMediaEmpty(), int32 date = 0, bool force = false);
|
void serviceNotification(const TextWithEntities &message, const MTPMessageMedia &media = MTP_messageMediaEmpty(), int32 date = 0, bool force = false);
|
||||||
|
@ -62,7 +62,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWidget *mainWidget();
|
MainWidget *mainWidget();
|
||||||
PasscodeWidget *passcodeWidget();
|
|
||||||
|
|
||||||
bool doWeReadServerHistory();
|
bool doWeReadServerHistory();
|
||||||
bool doWeReadMentions();
|
bool doWeReadMentions();
|
||||||
|
@ -173,7 +172,7 @@ private:
|
||||||
mtpRequestId _serviceHistoryRequest = 0;
|
mtpRequestId _serviceHistoryRequest = 0;
|
||||||
TimeMs _lastTrayClickTime = 0;
|
TimeMs _lastTrayClickTime = 0;
|
||||||
|
|
||||||
object_ptr<PasscodeWidget> _passcode = { nullptr };
|
object_ptr<Window::PasscodeLockWidget> _passcodeLock = { nullptr };
|
||||||
object_ptr<Intro::Widget> _intro = { nullptr };
|
object_ptr<Intro::Widget> _intro = { nullptr };
|
||||||
object_ptr<MainWidget> _main = { nullptr };
|
object_ptr<MainWidget> _main = { nullptr };
|
||||||
object_ptr<Window::LayerStackWidget> _layer = { nullptr };
|
object_ptr<Window::LayerStackWidget> _layer = { nullptr };
|
||||||
|
|
|
@ -39,6 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "media/media_audio_track.h"
|
#include "media/media_audio_track.h"
|
||||||
#include "window/notifications_manager.h"
|
#include "window/notifications_manager.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
|
#include "window/window_lock_widgets.h"
|
||||||
#include "history/history_location_manager.h"
|
#include "history/history_location_manager.h"
|
||||||
#include "ui/widgets/tooltip.h"
|
#include "ui/widgets/tooltip.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
|
@ -160,7 +161,7 @@ Messenger::Messenger(not_null<Core::Launcher*> launcher)
|
||||||
|
|
||||||
DEBUG_LOG(("Application Info: showing."));
|
DEBUG_LOG(("Application Info: showing."));
|
||||||
if (state == Local::ReadMapPassNeeded) {
|
if (state == Local::ReadMapPassNeeded) {
|
||||||
setupPasscode();
|
lockByPasscode();
|
||||||
} else {
|
} else {
|
||||||
if (AuthSession::Exists()) {
|
if (AuthSession::Exists()) {
|
||||||
_window->setupMain();
|
_window->setupMain();
|
||||||
|
@ -788,11 +789,14 @@ void Messenger::onSwitchTestMode() {
|
||||||
|
|
||||||
void Messenger::authSessionCreate(UserId userId) {
|
void Messenger::authSessionCreate(UserId userId) {
|
||||||
Expects(_mtproto != nullptr);
|
Expects(_mtproto != nullptr);
|
||||||
|
|
||||||
_authSession = std::make_unique<AuthSession>(userId);
|
_authSession = std::make_unique<AuthSession>(userId);
|
||||||
authSessionChanged().notify(true);
|
authSessionChanged().notify(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Messenger::authSessionDestroy() {
|
void Messenger::authSessionDestroy() {
|
||||||
|
unlockTerms();
|
||||||
|
|
||||||
_uploaderSubscription = rpl::lifetime();
|
_uploaderSubscription = rpl::lifetime();
|
||||||
_authSession.reset();
|
_authSession.reset();
|
||||||
_private->storedAuthSession.reset();
|
_private->storedAuthSession.reset();
|
||||||
|
@ -839,7 +843,7 @@ QString Messenger::createInternalLinkFull(const QString &query) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Messenger::checkStartUrl() {
|
void Messenger::checkStartUrl() {
|
||||||
if (!cStartUrl().isEmpty() && !App::passcoded()) {
|
if (!cStartUrl().isEmpty() && !locked()) {
|
||||||
auto url = cStartUrl();
|
auto url = cStartUrl();
|
||||||
cSetStartUrl(QString());
|
cSetStartUrl(QString());
|
||||||
if (!openLocalUrl(url)) {
|
if (!openLocalUrl(url)) {
|
||||||
|
@ -852,10 +856,11 @@ bool Messenger::openLocalUrl(const QString &url) {
|
||||||
auto urlTrimmed = url.trimmed();
|
auto urlTrimmed = url.trimmed();
|
||||||
if (urlTrimmed.size() > 8192) urlTrimmed = urlTrimmed.mid(0, 8192);
|
if (urlTrimmed.size() > 8192) urlTrimmed = urlTrimmed.mid(0, 8192);
|
||||||
|
|
||||||
if (!urlTrimmed.startsWith(qstr("tg://"), Qt::CaseInsensitive) || App::passcoded()) {
|
const auto protocol = qstr("tg://");
|
||||||
|
if (!urlTrimmed.startsWith(protocol, Qt::CaseInsensitive) || locked()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto command = urlTrimmed.midRef(qstr("tg://").size());
|
auto command = urlTrimmed.midRef(protocol.size());
|
||||||
|
|
||||||
const auto showPassportForm = [](const QMap<QString, QString> ¶ms) {
|
const auto showPassportForm = [](const QMap<QString, QString> ¶ms) {
|
||||||
const auto botId = params.value("bot_id", QString()).toInt();
|
const auto botId = params.value("bot_id", QString()).toInt();
|
||||||
|
@ -1026,15 +1031,75 @@ void Messenger::uploadProfilePhoto(QImage &&tosend, const PeerId &peerId) {
|
||||||
Auth().uploader().uploadMedia(newId, ready);
|
Auth().uploader().uploadMedia(newId, ready);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Messenger::setupPasscode() {
|
void Messenger::lockByPasscode() {
|
||||||
_window->setupPasscode();
|
_passcodeLock = true;
|
||||||
_passcodedChanged.notify();
|
_window->setupPasscodeLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Messenger::clearPasscode() {
|
void Messenger::unlockPasscode() {
|
||||||
cSetPasscodeBadTries(0);
|
cSetPasscodeBadTries(0);
|
||||||
_window->clearPasscode();
|
_window->clearPasscodeLock();
|
||||||
_passcodedChanged.notify();
|
_passcodeLock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Messenger::passcodeLocked() const {
|
||||||
|
return _passcodeLock.current();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> Messenger::passcodeLockChanges() const {
|
||||||
|
return _passcodeLock.changes();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> Messenger::passcodeLockValue() const {
|
||||||
|
return _passcodeLock.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Messenger::lockByTerms(const Window::TermsLock &data) {
|
||||||
|
if (!_termsLock || *_termsLock != data) {
|
||||||
|
_termsLock = std::make_unique<Window::TermsLock>(data);
|
||||||
|
_termsLockChanges.fire(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Messenger::unlockTerms() {
|
||||||
|
if (_termsLock) {
|
||||||
|
_termsLock = nullptr;
|
||||||
|
_termsLockChanges.fire(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base::optional<Window::TermsLock> Messenger::termsLocked() const {
|
||||||
|
return _termsLock ? base::make_optional(*_termsLock) : base::none;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> Messenger::termsLockChanges() const {
|
||||||
|
return _termsLockChanges.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> Messenger::termsLockValue() const {
|
||||||
|
return rpl::single(
|
||||||
|
_termsLock != nullptr
|
||||||
|
) | rpl::then(termsLockChanges());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Messenger::termsDeleteNow() {
|
||||||
|
MTP::send(MTPaccount_DeleteAccount(MTP_string("Decline ToS update")));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Messenger::locked() const {
|
||||||
|
return passcodeLocked() || termsLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> Messenger::lockChanges() const {
|
||||||
|
return lockValue() | rpl::skip(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> Messenger::lockValue() const {
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
return rpl::combine(
|
||||||
|
passcodeLockValue(),
|
||||||
|
termsLockValue(),
|
||||||
|
_1 || _2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Messenger::~Messenger() {
|
Messenger::~Messenger() {
|
||||||
|
|
|
@ -23,6 +23,10 @@ namespace Core {
|
||||||
class Launcher;
|
class Launcher;
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
struct TermsLock;
|
||||||
|
} // namespace Window
|
||||||
|
|
||||||
namespace App {
|
namespace App {
|
||||||
void quit();
|
void quit();
|
||||||
} // namespace App
|
} // namespace App
|
||||||
|
@ -168,11 +172,22 @@ public:
|
||||||
|
|
||||||
void forceLogOut(const TextWithEntities &explanation);
|
void forceLogOut(const TextWithEntities &explanation);
|
||||||
void checkLocalTime();
|
void checkLocalTime();
|
||||||
void setupPasscode();
|
void lockByPasscode();
|
||||||
void clearPasscode();
|
void unlockPasscode();
|
||||||
base::Observable<void> &passcodedChanged() {
|
[[nodiscard]] bool passcodeLocked() const;
|
||||||
return _passcodedChanged;
|
rpl::producer<bool> passcodeLockChanges() const;
|
||||||
}
|
rpl::producer<bool> passcodeLockValue() const;
|
||||||
|
|
||||||
|
void lockByTerms(const Window::TermsLock &data);
|
||||||
|
void unlockTerms();
|
||||||
|
[[nodiscard]] base::optional<Window::TermsLock> termsLocked() const;
|
||||||
|
rpl::producer<bool> termsLockChanges() const;
|
||||||
|
rpl::producer<bool> termsLockValue() const;
|
||||||
|
void termsDeleteNow();
|
||||||
|
|
||||||
|
[[nodiscard]] bool locked() const;
|
||||||
|
rpl::producer<bool> lockChanges() const;
|
||||||
|
rpl::producer<bool> lockValue() const;
|
||||||
|
|
||||||
void registerLeaveSubscription(QWidget *widget);
|
void registerLeaveSubscription(QWidget *widget);
|
||||||
void unregisterLeaveSubscription(QWidget *widget);
|
void unregisterLeaveSubscription(QWidget *widget);
|
||||||
|
@ -253,6 +268,10 @@ private:
|
||||||
QImage _logo;
|
QImage _logo;
|
||||||
QImage _logoNoMargin;
|
QImage _logoNoMargin;
|
||||||
|
|
||||||
|
rpl::variable<bool> _passcodeLock;
|
||||||
|
rpl::event_stream<bool> _termsLockChanges;
|
||||||
|
std::unique_ptr<Window::TermsLock> _termsLock;
|
||||||
|
|
||||||
base::DelayedCallTimer _callDelayedTimer;
|
base::DelayedCallTimer _callDelayedTimer;
|
||||||
|
|
||||||
struct LeaveSubscription {
|
struct LeaveSubscription {
|
||||||
|
|
|
@ -161,7 +161,9 @@ void ServiceWebRequest::destroy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWebRequest::~ServiceWebRequest() {
|
ServiceWebRequest::~ServiceWebRequest() {
|
||||||
destroy();
|
if (reply) {
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecialConfigRequest::SpecialConfigRequest(
|
SpecialConfigRequest::SpecialConfigRequest(
|
||||||
|
|
|
@ -1,184 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "passcodewidget.h"
|
|
||||||
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "storage/localstorage.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "messenger.h"
|
|
||||||
#include "ui/text/text.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "ui/widgets/input_fields.h"
|
|
||||||
#include "styles/style_boxes.h"
|
|
||||||
#include "window/window_slide_animation.h"
|
|
||||||
#include "window/window_controller.h"
|
|
||||||
#include "auth_session.h"
|
|
||||||
|
|
||||||
PasscodeWidget::PasscodeWidget(QWidget *parent) : TWidget(parent)
|
|
||||||
, _passcode(this, st::passcodeInput, langFactory(lng_passcode_ph))
|
|
||||||
, _submit(this, langFactory(lng_passcode_submit), st::passcodeSubmit)
|
|
||||||
, _logout(this, lang(lng_passcode_logout)) {
|
|
||||||
connect(_passcode, &Ui::MaskedInputField::changed, [=] { changed(); });
|
|
||||||
connect(_passcode, &Ui::MaskedInputField::submitted, [=] { submit(); });
|
|
||||||
|
|
||||||
_submit->setClickedCallback([=] { submit(); });
|
|
||||||
_logout->setClickedCallback([] { App::wnd()->onLogout(); });
|
|
||||||
|
|
||||||
show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PasscodeWidget::submit() {
|
|
||||||
if (_passcode->text().isEmpty()) {
|
|
||||||
_passcode->showError();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!passcodeCanTry()) {
|
|
||||||
_error = lang(lng_flood_error);
|
|
||||||
_passcode->showError();
|
|
||||||
update();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (App::main()) {
|
|
||||||
if (Local::checkPasscode(_passcode->text().toUtf8())) {
|
|
||||||
Messenger::Instance().clearPasscode(); // Destroys this widget.
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
cSetPasscodeBadTries(cPasscodeBadTries() + 1);
|
|
||||||
cSetPasscodeLastTry(getms(true));
|
|
||||||
error();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (Local::readMap(_passcode->text().toUtf8()) != Local::ReadMapPassNeeded) {
|
|
||||||
cSetPasscodeBadTries(0);
|
|
||||||
|
|
||||||
Messenger::Instance().startMtp();
|
|
||||||
if (AuthSession::Exists()) {
|
|
||||||
App::wnd()->setupMain();
|
|
||||||
} else {
|
|
||||||
App::wnd()->setupIntro();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cSetPasscodeBadTries(cPasscodeBadTries() + 1);
|
|
||||||
cSetPasscodeLastTry(getms(true));
|
|
||||||
error();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PasscodeWidget::error() {
|
|
||||||
_error = lang(lng_passcode_wrong);
|
|
||||||
_passcode->selectAll();
|
|
||||||
_passcode->showError();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PasscodeWidget::changed() {
|
|
||||||
if (!_error.isEmpty()) {
|
|
||||||
_error = QString();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PasscodeWidget::showAnimated(const QPixmap &bgAnimCache, bool back) {
|
|
||||||
_showBack = back;
|
|
||||||
(_showBack ? _cacheOver : _cacheUnder) = bgAnimCache;
|
|
||||||
|
|
||||||
_a_show.finish();
|
|
||||||
|
|
||||||
showAll();
|
|
||||||
setInnerFocus();
|
|
||||||
_passcode->finishAnimating();
|
|
||||||
(_showBack ? _cacheUnder : _cacheOver) = Ui::GrabWidget(this);
|
|
||||||
hideAll();
|
|
||||||
|
|
||||||
_a_show.start(
|
|
||||||
[this] { animationCallback(); },
|
|
||||||
0.,
|
|
||||||
1.,
|
|
||||||
st::slideDuration,
|
|
||||||
Window::SlideAnimation::transition());
|
|
||||||
show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PasscodeWidget::animationCallback() {
|
|
||||||
update();
|
|
||||||
if (!_a_show.animating()) {
|
|
||||||
showAll();
|
|
||||||
if (App::wnd()) App::wnd()->setInnerFocus();
|
|
||||||
|
|
||||||
Ui::showChatsList();
|
|
||||||
|
|
||||||
_cacheUnder = _cacheOver = QPixmap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PasscodeWidget::showAll() {
|
|
||||||
_passcode->show();
|
|
||||||
_submit->show();
|
|
||||||
_logout->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PasscodeWidget::hideAll() {
|
|
||||||
_passcode->hide();
|
|
||||||
_submit->hide();
|
|
||||||
_logout->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PasscodeWidget::paintEvent(QPaintEvent *e) {
|
|
||||||
bool trivial = (rect() == e->rect());
|
|
||||||
setMouseTracking(true);
|
|
||||||
|
|
||||||
Painter p(this);
|
|
||||||
if (!trivial) {
|
|
||||||
p.setClipRect(e->rect());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto progress = _a_show.current(getms(), 1.);
|
|
||||||
if (_a_show.animating()) {
|
|
||||||
auto coordUnder = _showBack ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
|
|
||||||
auto coordOver = _showBack ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
|
|
||||||
auto shadow = _showBack ? (1. - progress) : progress;
|
|
||||||
if (coordOver > 0) {
|
|
||||||
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * cRetinaFactor(), 0, coordOver * cRetinaFactor(), height() * cRetinaFactor()));
|
|
||||||
p.setOpacity(shadow);
|
|
||||||
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
|
|
||||||
p.setOpacity(1);
|
|
||||||
}
|
|
||||||
p.drawPixmap(coordOver, 0, _cacheOver);
|
|
||||||
p.setOpacity(shadow);
|
|
||||||
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
|
||||||
} else {
|
|
||||||
p.fillRect(rect(), st::windowBg);
|
|
||||||
|
|
||||||
p.setFont(st::passcodeHeaderFont);
|
|
||||||
p.setPen(st::windowFg);
|
|
||||||
p.drawText(QRect(0, _passcode->y() - st::passcodeHeaderHeight, width(), st::passcodeHeaderHeight), lang(lng_passcode_enter), style::al_center);
|
|
||||||
|
|
||||||
if (!_error.isEmpty()) {
|
|
||||||
p.setFont(st::boxTextFont);
|
|
||||||
p.setPen(st::boxTextFgError);
|
|
||||||
p.drawText(QRect(0, _passcode->y() + _passcode->height(), width(), st::passcodeSubmitSkip), _error, style::al_center);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PasscodeWidget::resizeEvent(QResizeEvent *e) {
|
|
||||||
_passcode->move((width() - _passcode->width()) / 2, (height() / 3));
|
|
||||||
_submit->move(_passcode->x(), _passcode->y() + _passcode->height() + st::passcodeSubmitSkip);
|
|
||||||
_logout->move(_passcode->x() + (_passcode->width() - _logout->width()) / 2, _submit->y() + _submit->height() + st::linkFont->ascent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PasscodeWidget::setInnerFocus() {
|
|
||||||
if (auto controller = App::wnd()->controller()) {
|
|
||||||
controller->dialogsListFocused().set(false, true);
|
|
||||||
}
|
|
||||||
_passcode->setFocusFast();
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class PasswordInput;
|
|
||||||
class LinkButton;
|
|
||||||
class RoundButton;
|
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
class PasscodeWidget : public TWidget {
|
|
||||||
public:
|
|
||||||
PasscodeWidget(QWidget *parent);
|
|
||||||
|
|
||||||
void setInnerFocus();
|
|
||||||
|
|
||||||
void showAnimated(const QPixmap &bgAnimCache, bool back = false);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void animationCallback();
|
|
||||||
void changed();
|
|
||||||
void submit();
|
|
||||||
void error();
|
|
||||||
|
|
||||||
void showAll();
|
|
||||||
void hideAll();
|
|
||||||
|
|
||||||
Animation _a_show;
|
|
||||||
bool _showBack = false;
|
|
||||||
QPixmap _cacheUnder, _cacheOver;
|
|
||||||
|
|
||||||
object_ptr<Ui::PasswordInput> _passcode;
|
|
||||||
object_ptr<Ui::RoundButton> _submit;
|
|
||||||
object_ptr<Ui::LinkButton> _logout;
|
|
||||||
QString _error;
|
|
||||||
|
|
||||||
};
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
#include "messenger.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_widget.h"
|
#include "history/history_widget.h"
|
||||||
#include "history/history_inner_widget.h"
|
#include "history/history_inner_widget.h"
|
||||||
|
@ -675,7 +676,7 @@ void MainWindow::updateGlobalMenuHook() {
|
||||||
if (!App::wnd() || !positionInited()) return;
|
if (!App::wnd() || !positionInited()) return;
|
||||||
|
|
||||||
auto focused = QApplication::focusWidget();
|
auto focused = QApplication::focusWidget();
|
||||||
bool isLogged = !!App::self(), canUndo = false, canRedo = false, canCut = false, canCopy = false, canPaste = false, canDelete = false, canSelectAll = false;
|
bool canUndo = false, canRedo = false, canCut = false, canCopy = false, canPaste = false, canDelete = false, canSelectAll = false;
|
||||||
auto clipboardHasText = _private->clipboardHasText();
|
auto clipboardHasText = _private->clipboardHasText();
|
||||||
if (auto edit = qobject_cast<QLineEdit*>(focused)) {
|
if (auto edit = qobject_cast<QLineEdit*>(focused)) {
|
||||||
canCut = canCopy = canDelete = edit->hasSelectedText();
|
canCut = canCopy = canDelete = edit->hasSelectedText();
|
||||||
|
@ -694,7 +695,10 @@ void MainWindow::updateGlobalMenuHook() {
|
||||||
canDelete = list->canDeleteSelected();
|
canDelete = list->canDeleteSelected();
|
||||||
}
|
}
|
||||||
App::wnd()->updateIsActive(0);
|
App::wnd()->updateIsActive(0);
|
||||||
_forceDisabled(psLogout, !isLogged && !App::passcoded());
|
const auto logged = !!App::self();
|
||||||
|
const auto locked = !Messenger::Instance().locked();
|
||||||
|
const auto inactive = !logged || locked;
|
||||||
|
_forceDisabled(psLogout, !logged && !locked);
|
||||||
_forceDisabled(psUndo, !canUndo);
|
_forceDisabled(psUndo, !canUndo);
|
||||||
_forceDisabled(psRedo, !canRedo);
|
_forceDisabled(psRedo, !canRedo);
|
||||||
_forceDisabled(psCut, !canCut);
|
_forceDisabled(psCut, !canCut);
|
||||||
|
@ -702,10 +706,10 @@ void MainWindow::updateGlobalMenuHook() {
|
||||||
_forceDisabled(psPaste, !canPaste);
|
_forceDisabled(psPaste, !canPaste);
|
||||||
_forceDisabled(psDelete, !canDelete);
|
_forceDisabled(psDelete, !canDelete);
|
||||||
_forceDisabled(psSelectAll, !canSelectAll);
|
_forceDisabled(psSelectAll, !canSelectAll);
|
||||||
_forceDisabled(psContacts, !isLogged || App::passcoded());
|
_forceDisabled(psContacts, inactive);
|
||||||
_forceDisabled(psAddContact, !isLogged || App::passcoded());
|
_forceDisabled(psAddContact, inactive);
|
||||||
_forceDisabled(psNewGroup, !isLogged || App::passcoded());
|
_forceDisabled(psNewGroup, inactive);
|
||||||
_forceDisabled(psNewChannel, !isLogged || App::passcoded());
|
_forceDisabled(psNewChannel, inactive);
|
||||||
_forceDisabled(psShowTelegram, App::wnd()->isActive());
|
_forceDisabled(psShowTelegram, App::wnd()->isActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_widget.h"
|
#include "history/history_widget.h"
|
||||||
#include "core/crash_reports.h"
|
#include "core/crash_reports.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "passcodewidget.h"
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "history/history_location_manager.h"
|
#include "history/history_location_manager.h"
|
||||||
#include "platform/mac/mac_utilities.h"
|
#include "platform/mac/mac_utilities.h"
|
||||||
|
|
|
@ -800,10 +800,14 @@ void MainWindow::psFirstShow() {
|
||||||
setWindowState(Qt::WindowMaximized);
|
setWindowState(Qt::WindowMaximized);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cLaunchMode() == LaunchModeAutoStart && cStartMinimized() && !App::passcoded()) || cStartInTray()) {
|
if (cStartInTray()
|
||||||
|
|| (cLaunchMode() == LaunchModeAutoStart
|
||||||
|
&& cStartMinimized()
|
||||||
|
&& !Messenger::Instance().passcodeLocked())) {
|
||||||
DEBUG_LOG(("Window Pos: First show, setting minimized after."));
|
DEBUG_LOG(("Window Pos: First show, setting minimized after."));
|
||||||
setWindowState(Qt::WindowMinimized);
|
setWindowState(Qt::WindowMinimized);
|
||||||
if (Global::WorkMode().value() == dbiwmTrayOnly || Global::WorkMode().value() == dbiwmWindowAndTray) {
|
if (Global::WorkMode().value() == dbiwmTrayOnly
|
||||||
|
|| Global::WorkMode().value() == dbiwmWindowAndTray) {
|
||||||
hide();
|
hide();
|
||||||
} else {
|
} else {
|
||||||
show();
|
show();
|
||||||
|
|
|
@ -17,7 +17,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "history/history_location_manager.h"
|
#include "history/history_location_manager.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "passcodewidget.h"
|
|
||||||
#include "core/crash_reports.h"
|
#include "core/crash_reports.h"
|
||||||
|
|
||||||
#include <Shobjidl.h>
|
#include <Shobjidl.h>
|
||||||
|
|
|
@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "shortcuts.h"
|
#include "shortcuts.h"
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "passcodewidget.h"
|
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "messenger.h"
|
#include "messenger.h"
|
||||||
#include "media/player/media_player_instance.h"
|
#include "media/player/media_player_instance.h"
|
||||||
|
@ -20,8 +19,9 @@ namespace ShortcutCommands {
|
||||||
using Handler = bool(*)();
|
using Handler = bool(*)();
|
||||||
|
|
||||||
bool lock_telegram() {
|
bool lock_telegram() {
|
||||||
if (!App::passcoded() && Global::LocalPasscode()) {
|
if (!Messenger::Instance().passcodeLocked()
|
||||||
Messenger::Instance().setupPasscode();
|
&& Global::LocalPasscode()) {
|
||||||
|
Messenger::Instance().lockByPasscode();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -16,14 +16,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
PopupMenu::PopupMenu(QWidget*, const style::PopupMenu &st) : TWidget(nullptr)
|
PopupMenu::PopupMenu(QWidget*, const style::PopupMenu &st)
|
||||||
, _st(st)
|
: _st(st)
|
||||||
, _menu(this, _st.menu) {
|
, _menu(this, _st.menu) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupMenu::PopupMenu(QWidget*, QMenu *menu, const style::PopupMenu &st) : TWidget(nullptr)
|
PopupMenu::PopupMenu(QWidget*, QMenu *menu, const style::PopupMenu &st)
|
||||||
, _st(st)
|
: _st(st)
|
||||||
, _menu(this, menu, _st.menu) {
|
, _menu(this, menu, _st.menu) {
|
||||||
init();
|
init();
|
||||||
|
|
||||||
|
@ -36,11 +36,14 @@ PopupMenu::PopupMenu(QWidget*, QMenu *menu, const style::PopupMenu &st) : TWidge
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupMenu::init() {
|
void PopupMenu::init() {
|
||||||
subscribe(Messenger::Instance().passcodedChanged(), [this] {
|
using namespace rpl::mappers;
|
||||||
if (App::passcoded()) {
|
|
||||||
|
rpl::merge(
|
||||||
|
Messenger::Instance().passcodeLockChanges(),
|
||||||
|
Messenger::Instance().termsLockChanges()
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
hideMenu(true);
|
hideMenu(true);
|
||||||
}
|
}, lifetime());
|
||||||
});
|
|
||||||
|
|
||||||
_menu->setResizedCallback([this] { handleMenuResize(); });
|
_menu->setResizedCallback([this] { handleMenuResize(); });
|
||||||
_menu->setActivatedCallback([this](QAction *action, int actionTop, TriggeredSource source) {
|
_menu->setActivatedCallback([this](QAction *action, int actionTop, TriggeredSource source) {
|
||||||
|
|
|
@ -8,12 +8,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
|
#include "ui/rp_widget.h"
|
||||||
#include "ui/widgets/menu.h"
|
#include "ui/widgets/menu.h"
|
||||||
#include "ui/effects/panel_animation.h"
|
#include "ui/effects/panel_animation.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
class PopupMenu : public TWidget, private base::Subscriber {
|
class PopupMenu : public Ui::RpWidget, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
PopupMenu(QWidget*, const style::PopupMenu &st = st::defaultPopupMenu);
|
PopupMenu(QWidget*, const style::PopupMenu &st = st::defaultPopupMenu);
|
||||||
PopupMenu(QWidget*, QMenu *menu, const style::PopupMenu &st = st::defaultPopupMenu);
|
PopupMenu(QWidget*, QMenu *menu, const style::PopupMenu &st = st::defaultPopupMenu);
|
||||||
|
|
|
@ -8,14 +8,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/main_window.h"
|
#include "window/main_window.h"
|
||||||
|
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "styles/style_window.h"
|
|
||||||
#include "platform/platform_window_title.h"
|
#include "platform/platform_window_title.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
|
#include "window/window_lock_widgets.h"
|
||||||
|
#include "boxes/confirm_box.h"
|
||||||
|
#include "core/click_handler_types.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
#include "mediaview.h"
|
#include "mediaview.h"
|
||||||
|
#include "auth_session.h"
|
||||||
|
#include "apiwrap.h"
|
||||||
#include "messenger.h"
|
#include "messenger.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "styles/style_window.h"
|
||||||
|
#include "styles/style_boxes.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
|
||||||
|
@ -64,10 +71,94 @@ MainWindow::MainWindow()
|
||||||
subscribe(Messenger::Instance().authSessionChanged(), [this] { checkAuthSession(); });
|
subscribe(Messenger::Instance().authSessionChanged(), [this] { checkAuthSession(); });
|
||||||
checkAuthSession();
|
checkAuthSession();
|
||||||
|
|
||||||
|
Messenger::Instance().termsLockValue(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
checkLockByTerms();
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
_isActiveTimer.setCallback([this] { updateIsActive(0); });
|
_isActiveTimer.setCallback([this] { updateIsActive(0); });
|
||||||
_inactivePressTimer.setCallback([this] { setInactivePress(false); });
|
_inactivePressTimer.setCallback([this] { setInactivePress(false); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::checkLockByTerms() {
|
||||||
|
const auto data = Messenger::Instance().termsLocked();
|
||||||
|
if (!data || !AuthSession::Exists()) {
|
||||||
|
if (_termsBox) {
|
||||||
|
_termsBox->closeBox();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ui::hideSettingsAndLayer(anim::type::instant);
|
||||||
|
const auto box = Ui::show(Box<TermsBox>(
|
||||||
|
*data,
|
||||||
|
langFactory(lng_terms_agree),
|
||||||
|
langFactory(lng_terms_decline)));
|
||||||
|
|
||||||
|
box->setCloseByEscape(false);
|
||||||
|
box->setCloseByOutsideClick(false);
|
||||||
|
|
||||||
|
const auto id = data->id;
|
||||||
|
box->agreeClicks(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
const auto mention = box ? box->lastClickedMention() : QString();
|
||||||
|
if (AuthSession::Exists()) {
|
||||||
|
Auth().api().acceptTerms(id);
|
||||||
|
if (!mention.isEmpty()) {
|
||||||
|
MentionClickHandler(mention).onClick(Qt::LeftButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Messenger::Instance().unlockTerms();
|
||||||
|
}, box->lifetime());
|
||||||
|
|
||||||
|
box->cancelClicks(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
showTermsDecline();
|
||||||
|
}, box->lifetime());
|
||||||
|
|
||||||
|
connect(box, &QObject::destroyed, [=] {
|
||||||
|
crl::on_main(this, [=] { checkLockByTerms(); });
|
||||||
|
});
|
||||||
|
|
||||||
|
_termsBox = box;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showTermsDecline() {
|
||||||
|
const auto box = Ui::show(
|
||||||
|
Box<Window::TermsBox>(
|
||||||
|
TextWithEntities{ lang(lng_terms_update_sorry) },
|
||||||
|
langFactory(lng_terms_decline_and_delete),
|
||||||
|
langFactory(lng_terms_back),
|
||||||
|
true),
|
||||||
|
LayerOption::KeepOther);
|
||||||
|
|
||||||
|
box->agreeClicks(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
if (box) {
|
||||||
|
box->closeBox();
|
||||||
|
}
|
||||||
|
showTermsDelete();
|
||||||
|
}, box->lifetime());
|
||||||
|
|
||||||
|
box->cancelClicks(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
if (box) {
|
||||||
|
box->closeBox();
|
||||||
|
}
|
||||||
|
}, box->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showTermsDelete() {
|
||||||
|
const auto box = std::make_shared<QPointer<BoxContent>>();
|
||||||
|
*box = Ui::show(
|
||||||
|
Box<ConfirmBox>(
|
||||||
|
lang(lng_terms_delete_warning),
|
||||||
|
lang(lng_terms_delete_now),
|
||||||
|
st::attentionBoxButton,
|
||||||
|
[=] { Messenger::Instance().termsDeleteNow(); },
|
||||||
|
[=] { if (*box) (*box)->closeBox(); }),
|
||||||
|
LayerOption::KeepOther);
|
||||||
|
}
|
||||||
|
|
||||||
bool MainWindow::hideNoQuit() {
|
bool MainWindow::hideNoQuit() {
|
||||||
if (App::quitting()) {
|
if (App::quitting()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -238,7 +329,7 @@ rpl::producer<> MainWindow::leaveEvents() const {
|
||||||
return _leaveEvents.events();
|
return _leaveEvents.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::leaveEvent(QEvent *e) {
|
void MainWindow::leaveEventHook(QEvent *e) {
|
||||||
_leaveEvents.fire({});
|
_leaveEvents.fire({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,22 +7,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <rpl/event_stream.h>
|
|
||||||
#include "window/window_title.h"
|
#include "window/window_title.h"
|
||||||
|
#include "ui/rp_widget.h"
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
|
|
||||||
|
class BoxContent;
|
||||||
class MediaView;
|
class MediaView;
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
|
||||||
class Controller;
|
class Controller;
|
||||||
class TitleWidget;
|
class TitleWidget;
|
||||||
|
struct TermsLock;
|
||||||
|
|
||||||
QImage LoadLogo();
|
QImage LoadLogo();
|
||||||
QImage LoadLogoNoMargin();
|
QImage LoadLogoNoMargin();
|
||||||
QIcon CreateIcon();
|
QIcon CreateIcon();
|
||||||
|
|
||||||
class MainWindow : public QWidget, protected base::Subscriber {
|
class MainWindow : public Ui::RpWidget, protected base::Subscriber {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -89,7 +91,7 @@ public slots:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
void leaveEvent(QEvent *e) override;
|
void leaveEventHook(QEvent *e) override;
|
||||||
|
|
||||||
void savePosition(Qt::WindowState state = Qt::WindowActive);
|
void savePosition(Qt::WindowState state = Qt::WindowActive);
|
||||||
void handleStateChanged(Qt::WindowState state);
|
void handleStateChanged(Qt::WindowState state);
|
||||||
|
@ -149,6 +151,9 @@ private:
|
||||||
void initSize();
|
void initSize();
|
||||||
|
|
||||||
bool computeIsActive() const;
|
bool computeIsActive() const;
|
||||||
|
void checkLockByTerms();
|
||||||
|
void showTermsDecline();
|
||||||
|
void showTermsDelete();
|
||||||
|
|
||||||
base::Timer _positionUpdatedTimer;
|
base::Timer _positionUpdatedTimer;
|
||||||
bool _positionInited = false;
|
bool _positionInited = false;
|
||||||
|
@ -157,6 +162,7 @@ private:
|
||||||
object_ptr<TitleWidget> _title = { nullptr };
|
object_ptr<TitleWidget> _title = { nullptr };
|
||||||
object_ptr<TWidget> _body;
|
object_ptr<TWidget> _body;
|
||||||
object_ptr<TWidget> _rightColumn = { nullptr };
|
object_ptr<TWidget> _rightColumn = { nullptr };
|
||||||
|
QPointer<BoxContent> _termsBox;
|
||||||
|
|
||||||
QIcon _icon;
|
QIcon _icon;
|
||||||
QString _titleText;
|
QString _titleText;
|
||||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
#include "messenger.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
|
|
||||||
|
@ -380,7 +381,8 @@ void System::updateAll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::DisplayOptions Manager::getNotificationOptions(HistoryItem *item) {
|
Manager::DisplayOptions Manager::getNotificationOptions(HistoryItem *item) {
|
||||||
auto hideEverything = (App::passcoded() || Global::ScreenIsLocked());
|
const auto hideEverything = Messenger::Instance().locked()
|
||||||
|
|| Global::ScreenIsLocked();
|
||||||
|
|
||||||
DisplayOptions result;
|
DisplayOptions result;
|
||||||
result.hideNameAndPhoto = hideEverything || (Global::NotifyView() > dbinvShowName);
|
result.hideNameAndPhoto = hideEverything || (Global::NotifyView() > dbinvShowName);
|
||||||
|
@ -395,7 +397,7 @@ void Manager::notificationActivated(PeerId peerId, MsgId msgId) {
|
||||||
auto history = App::history(peerId);
|
auto history = App::history(peerId);
|
||||||
window->showFromTray();
|
window->showFromTray();
|
||||||
window->reActivateWindow();
|
window->reActivateWindow();
|
||||||
if (App::passcoded()) {
|
if (Messenger::Instance().locked()) {
|
||||||
window->setInnerFocus();
|
window->setInnerFocus();
|
||||||
system()->clearAll();
|
system()->clearAll();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -727,7 +727,10 @@ bool Notification::unlinkItem(HistoryItem *deleted) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Notification::canReply() const {
|
bool Notification::canReply() const {
|
||||||
return !_hideReplyButton && (_item != nullptr) && !App::passcoded() && (Global::NotifyView() <= dbinvShowPreview);
|
return !_hideReplyButton
|
||||||
|
&& (_item != nullptr)
|
||||||
|
&& !Messenger::Instance().locked()
|
||||||
|
&& (Global::NotifyView() <= dbinvShowPreview);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notification::unlinkHistoryInManager() {
|
void Notification::unlinkHistoryInManager() {
|
||||||
|
|
|
@ -0,0 +1,357 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "window/window_lock_widgets.h"
|
||||||
|
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "storage/localstorage.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "messenger.h"
|
||||||
|
#include "ui/text/text.h"
|
||||||
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/widgets/checkbox.h"
|
||||||
|
#include "ui/widgets/input_fields.h"
|
||||||
|
#include "ui/widgets/labels.h"
|
||||||
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
#include "ui/toast/toast.h"
|
||||||
|
#include "styles/style_boxes.h"
|
||||||
|
#include "window/window_slide_animation.h"
|
||||||
|
#include "window/window_controller.h"
|
||||||
|
#include "auth_session.h"
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
|
||||||
|
LockWidget::LockWidget(QWidget *parent) : RpWidget(parent) {
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LockWidget::setInnerFocus() {
|
||||||
|
if (const auto controller = App::wnd()->controller()) {
|
||||||
|
controller->dialogsListFocused().set(false, true);
|
||||||
|
}
|
||||||
|
setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LockWidget::showAnimated(const QPixmap &bgAnimCache, bool back) {
|
||||||
|
_showBack = back;
|
||||||
|
(_showBack ? _cacheOver : _cacheUnder) = bgAnimCache;
|
||||||
|
|
||||||
|
_a_show.finish();
|
||||||
|
|
||||||
|
showChildren();
|
||||||
|
setInnerFocus();
|
||||||
|
(_showBack ? _cacheUnder : _cacheOver) = Ui::GrabWidget(this);
|
||||||
|
hideChildren();
|
||||||
|
|
||||||
|
_a_show.start(
|
||||||
|
[this] { animationCallback(); },
|
||||||
|
0.,
|
||||||
|
1.,
|
||||||
|
st::slideDuration,
|
||||||
|
Window::SlideAnimation::transition());
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LockWidget::animationCallback() {
|
||||||
|
update();
|
||||||
|
if (!_a_show.animating()) {
|
||||||
|
showChildren();
|
||||||
|
if (App::wnd()) App::wnd()->setInnerFocus();
|
||||||
|
|
||||||
|
Ui::showChatsList();
|
||||||
|
|
||||||
|
_cacheUnder = _cacheOver = QPixmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LockWidget::paintEvent(QPaintEvent *e) {
|
||||||
|
Painter p(this);
|
||||||
|
|
||||||
|
auto progress = _a_show.current(getms(), 1.);
|
||||||
|
if (_a_show.animating()) {
|
||||||
|
auto coordUnder = _showBack ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
|
||||||
|
auto coordOver = _showBack ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
|
||||||
|
auto shadow = _showBack ? (1. - progress) : progress;
|
||||||
|
if (coordOver > 0) {
|
||||||
|
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * cRetinaFactor(), 0, coordOver * cRetinaFactor(), height() * cRetinaFactor()));
|
||||||
|
p.setOpacity(shadow);
|
||||||
|
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
|
||||||
|
p.setOpacity(1);
|
||||||
|
}
|
||||||
|
p.drawPixmap(coordOver, 0, _cacheOver);
|
||||||
|
p.setOpacity(shadow);
|
||||||
|
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
||||||
|
} else {
|
||||||
|
paintContent(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LockWidget::paintContent(Painter &p) {
|
||||||
|
p.fillRect(rect(), st::windowBg);
|
||||||
|
}
|
||||||
|
|
||||||
|
PasscodeLockWidget::PasscodeLockWidget(QWidget *parent)
|
||||||
|
: LockWidget(parent)
|
||||||
|
, _passcode(this, st::passcodeInput, langFactory(lng_passcode_ph))
|
||||||
|
, _submit(this, langFactory(lng_passcode_submit), st::passcodeSubmit)
|
||||||
|
, _logout(this, lang(lng_passcode_logout)) {
|
||||||
|
connect(_passcode, &Ui::MaskedInputField::changed, [=] { changed(); });
|
||||||
|
connect(_passcode, &Ui::MaskedInputField::submitted, [=] { submit(); });
|
||||||
|
|
||||||
|
_submit->setClickedCallback([=] { submit(); });
|
||||||
|
_logout->setClickedCallback([] { App::wnd()->onLogout(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasscodeLockWidget::paintContent(Painter &p) {
|
||||||
|
LockWidget::paintContent(p);
|
||||||
|
|
||||||
|
p.setFont(st::passcodeHeaderFont);
|
||||||
|
p.setPen(st::windowFg);
|
||||||
|
p.drawText(QRect(0, _passcode->y() - st::passcodeHeaderHeight, width(), st::passcodeHeaderHeight), lang(lng_passcode_enter), style::al_center);
|
||||||
|
|
||||||
|
if (!_error.isEmpty()) {
|
||||||
|
p.setFont(st::boxTextFont);
|
||||||
|
p.setPen(st::boxTextFgError);
|
||||||
|
p.drawText(QRect(0, _passcode->y() + _passcode->height(), width(), st::passcodeSubmitSkip), _error, style::al_center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasscodeLockWidget::submit() {
|
||||||
|
if (_passcode->text().isEmpty()) {
|
||||||
|
_passcode->showError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!passcodeCanTry()) {
|
||||||
|
_error = lang(lng_flood_error);
|
||||||
|
_passcode->showError();
|
||||||
|
update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (App::main()) {
|
||||||
|
if (Local::checkPasscode(_passcode->text().toUtf8())) {
|
||||||
|
Messenger::Instance().unlockPasscode(); // Destroys this widget.
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cSetPasscodeBadTries(cPasscodeBadTries() + 1);
|
||||||
|
cSetPasscodeLastTry(getms(true));
|
||||||
|
error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Local::readMap(_passcode->text().toUtf8()) != Local::ReadMapPassNeeded) {
|
||||||
|
cSetPasscodeBadTries(0);
|
||||||
|
|
||||||
|
Messenger::Instance().startMtp();
|
||||||
|
|
||||||
|
// Destroys this widget.
|
||||||
|
if (AuthSession::Exists()) {
|
||||||
|
App::wnd()->setupMain();
|
||||||
|
} else {
|
||||||
|
App::wnd()->setupIntro();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cSetPasscodeBadTries(cPasscodeBadTries() + 1);
|
||||||
|
cSetPasscodeLastTry(getms(true));
|
||||||
|
error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasscodeLockWidget::error() {
|
||||||
|
_error = lang(lng_passcode_wrong);
|
||||||
|
_passcode->selectAll();
|
||||||
|
_passcode->showError();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasscodeLockWidget::changed() {
|
||||||
|
if (!_error.isEmpty()) {
|
||||||
|
_error = QString();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasscodeLockWidget::resizeEvent(QResizeEvent *e) {
|
||||||
|
_passcode->move((width() - _passcode->width()) / 2, (height() / 3));
|
||||||
|
_submit->move(_passcode->x(), _passcode->y() + _passcode->height() + st::passcodeSubmitSkip);
|
||||||
|
_logout->move(_passcode->x() + (_passcode->width() - _logout->width()) / 2, _submit->y() + _submit->height() + st::linkFont->ascent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasscodeLockWidget::setInnerFocus() {
|
||||||
|
LockWidget::setInnerFocus();
|
||||||
|
_passcode->setFocusFast();
|
||||||
|
}
|
||||||
|
|
||||||
|
TermsLock TermsLock::FromMTP(const MTPDhelp_termsOfService &data) {
|
||||||
|
return {
|
||||||
|
bytes::make_vector(data.vid.c_dataJSON().vdata.v),
|
||||||
|
TextWithEntities {
|
||||||
|
TextUtilities::Clean(qs(data.vtext)),
|
||||||
|
TextUtilities::EntitiesFromMTP(data.ventities.v) },
|
||||||
|
(data.has_min_age_confirm()
|
||||||
|
? base::make_optional(data.vmin_age_confirm.v)
|
||||||
|
: base::none),
|
||||||
|
data.is_popup()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
TermsBox::TermsBox(
|
||||||
|
QWidget*,
|
||||||
|
const TermsLock &data,
|
||||||
|
Fn<QString()> agree,
|
||||||
|
Fn<QString()> cancel)
|
||||||
|
: _data(data)
|
||||||
|
, _agree(agree)
|
||||||
|
, _cancel(cancel) {
|
||||||
|
}
|
||||||
|
|
||||||
|
TermsBox::TermsBox(
|
||||||
|
QWidget*,
|
||||||
|
const TextWithEntities &text,
|
||||||
|
Fn<QString()> agree,
|
||||||
|
Fn<QString()> cancel,
|
||||||
|
bool attentionAgree)
|
||||||
|
: _data{ {}, text, base::none, false }
|
||||||
|
, _agree(agree)
|
||||||
|
, _cancel(cancel)
|
||||||
|
, _attentionAgree(attentionAgree) {
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> TermsBox::agreeClicks() const {
|
||||||
|
return _agreeClicks.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> TermsBox::cancelClicks() const {
|
||||||
|
return _cancelClicks.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TermsBox::prepare() {
|
||||||
|
setTitle(langFactory(lng_terms_header));
|
||||||
|
|
||||||
|
auto check = std::make_unique<Ui::CheckView>(st::defaultCheck, false);
|
||||||
|
const auto ageCheck = check.get();
|
||||||
|
const auto age = _data.minAge
|
||||||
|
? Ui::CreateChild<Ui::PaddingWrap<Ui::Checkbox>>(
|
||||||
|
this,
|
||||||
|
object_ptr<Ui::Checkbox>(
|
||||||
|
this,
|
||||||
|
lng_terms_age(lt_count, *_data.minAge),
|
||||||
|
st::defaultCheckbox,
|
||||||
|
std::move(check)),
|
||||||
|
st::termsAgePadding)
|
||||||
|
: nullptr;
|
||||||
|
if (age) {
|
||||||
|
age->resizeToNaturalWidth(st::boxWideWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto content = setInnerWidget(
|
||||||
|
object_ptr<Ui::PaddingWrap<Ui::FlatLabel>>(
|
||||||
|
this,
|
||||||
|
object_ptr<Ui::FlatLabel> (
|
||||||
|
this,
|
||||||
|
rpl::single(_data.text),
|
||||||
|
st::termsContent),
|
||||||
|
st::termsPadding),
|
||||||
|
0,
|
||||||
|
age ? age->height() : 0);
|
||||||
|
content->entity()->setClickHandlerHook([=](
|
||||||
|
const ClickHandlerPtr &handler,
|
||||||
|
Qt::MouseButton button) {
|
||||||
|
const auto link = handler
|
||||||
|
? handler->copyToClipboardText()
|
||||||
|
: QString();
|
||||||
|
if (TextUtilities::RegExpMention().match(link).hasMatch()) {
|
||||||
|
_lastClickedMention = link;
|
||||||
|
Ui::Toast::Show(lng_terms_agree_to_proceed(lt_bot, link));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto errorAnimationCallback = [=] {
|
||||||
|
// lambda 'this' gets deleted in _ageErrorAnimation.current() call.
|
||||||
|
const auto check = ageCheck;
|
||||||
|
const auto error = _ageErrorAnimation.current(
|
||||||
|
_ageErrorShown ? 1. : 0.);
|
||||||
|
if (error == 0.) {
|
||||||
|
check->setUntoggledOverride(base::none);
|
||||||
|
} else {
|
||||||
|
const auto color = anim::color(
|
||||||
|
st::defaultCheck.untoggledFg,
|
||||||
|
st::boxTextFgError,
|
||||||
|
error);
|
||||||
|
check->setUntoggledOverride(color);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const auto toggleAgeError = [=](bool shown) {
|
||||||
|
if (_ageErrorShown != shown) {
|
||||||
|
_ageErrorShown = shown;
|
||||||
|
_ageErrorAnimation.start(
|
||||||
|
[=] { errorAnimationCallback(); },
|
||||||
|
_ageErrorShown ? 0. : 1.,
|
||||||
|
_ageErrorShown ? 1. : 0.,
|
||||||
|
st::defaultCheck.duration);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto &agreeStyle = _attentionAgree
|
||||||
|
? st::attentionBoxButton
|
||||||
|
: st::defaultBoxButton;
|
||||||
|
addButton(_agree, [=] {}, agreeStyle)->clicks(
|
||||||
|
) | rpl::filter([=] {
|
||||||
|
if (age && !age->entity()->checked()) {
|
||||||
|
toggleAgeError(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}) | rpl::start_to_stream(_agreeClicks, lifetime());
|
||||||
|
|
||||||
|
if (_cancel) {
|
||||||
|
addButton(_cancel, [=] {})->clicks(
|
||||||
|
) | rpl::start_to_stream(_cancelClicks, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (age) {
|
||||||
|
base::ObservableViewer(
|
||||||
|
age->entity()->checkedChanged
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
toggleAgeError(false);
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
|
heightValue(
|
||||||
|
) | rpl::start_with_next([=](int height) {
|
||||||
|
age->moveToLeft(0, height - age->height());
|
||||||
|
}, age->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
content->resizeToWidth(st::boxWideWidth);
|
||||||
|
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
rpl::combine(
|
||||||
|
content->heightValue(),
|
||||||
|
age ? age->heightValue() : rpl::single(0),
|
||||||
|
_1 + _2
|
||||||
|
) | rpl::start_with_next([=](int height) {
|
||||||
|
setDimensions(st::boxWideWidth, height);
|
||||||
|
}, content->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TermsBox::keyPressEvent(QKeyEvent *e) {
|
||||||
|
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
||||||
|
_agreeClicks.fire({});
|
||||||
|
} else {
|
||||||
|
BoxContent::keyPressEvent(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TermsBox::lastClickedMention() const {
|
||||||
|
return _lastClickedMention;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Window
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/rp_widget.h"
|
||||||
|
#include "boxes/abstract_box.h"
|
||||||
|
#include "base/bytes.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class PasswordInput;
|
||||||
|
class LinkButton;
|
||||||
|
class RoundButton;
|
||||||
|
class CheckView;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
|
||||||
|
class LockWidget : public Ui::RpWidget {
|
||||||
|
public:
|
||||||
|
LockWidget(QWidget *parent);
|
||||||
|
|
||||||
|
virtual void setInnerFocus();
|
||||||
|
|
||||||
|
void showAnimated(const QPixmap &bgAnimCache, bool back = false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
virtual void paintContent(Painter &p);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void animationCallback();
|
||||||
|
|
||||||
|
Animation _a_show;
|
||||||
|
bool _showBack = false;
|
||||||
|
QPixmap _cacheUnder, _cacheOver;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class PasscodeLockWidget : public LockWidget {
|
||||||
|
public:
|
||||||
|
PasscodeLockWidget(QWidget *parent);
|
||||||
|
|
||||||
|
void setInnerFocus() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void paintContent(Painter &p) override;
|
||||||
|
void changed();
|
||||||
|
void submit();
|
||||||
|
void error();
|
||||||
|
|
||||||
|
object_ptr<Ui::PasswordInput> _passcode;
|
||||||
|
object_ptr<Ui::RoundButton> _submit;
|
||||||
|
object_ptr<Ui::LinkButton> _logout;
|
||||||
|
QString _error;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TermsLock {
|
||||||
|
bytes::vector id;
|
||||||
|
TextWithEntities text;
|
||||||
|
base::optional<int> minAge;
|
||||||
|
bool popup = false;
|
||||||
|
|
||||||
|
inline bool operator==(const TermsLock &other) const {
|
||||||
|
return (id == other.id);
|
||||||
|
}
|
||||||
|
inline bool operator!=(const TermsLock &other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TermsLock FromMTP(const MTPDhelp_termsOfService &data);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class TermsBox : public BoxContent {
|
||||||
|
public:
|
||||||
|
TermsBox(
|
||||||
|
QWidget*,
|
||||||
|
const TermsLock &data,
|
||||||
|
Fn<QString()> agree,
|
||||||
|
Fn<QString()> cancel);
|
||||||
|
TermsBox(
|
||||||
|
QWidget*,
|
||||||
|
const TextWithEntities &text,
|
||||||
|
Fn<QString()> agree,
|
||||||
|
Fn<QString()> cancel,
|
||||||
|
bool attentionAgree = false);
|
||||||
|
|
||||||
|
rpl::producer<> agreeClicks() const;
|
||||||
|
rpl::producer<> cancelClicks() const;
|
||||||
|
QString lastClickedMention() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void prepare() override;
|
||||||
|
|
||||||
|
void keyPressEvent(QKeyEvent *e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TermsLock _data;
|
||||||
|
Fn<QString()> _agree;
|
||||||
|
Fn<QString()> _cancel;
|
||||||
|
rpl::event_stream<> _agreeClicks;
|
||||||
|
rpl::event_stream<> _cancelClicks;
|
||||||
|
QString _lastClickedMention;
|
||||||
|
bool _attentionAgree = false;
|
||||||
|
|
||||||
|
bool _ageErrorShown = false;
|
||||||
|
Animation _ageErrorAnimation;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Window
|
|
@ -729,6 +729,8 @@
|
||||||
<(src_loc)/window/window_connecting_widget.h
|
<(src_loc)/window/window_connecting_widget.h
|
||||||
<(src_loc)/window/window_controller.cpp
|
<(src_loc)/window/window_controller.cpp
|
||||||
<(src_loc)/window/window_controller.h
|
<(src_loc)/window/window_controller.h
|
||||||
|
<(src_loc)/window/window_lock_widgets.cpp
|
||||||
|
<(src_loc)/window/window_lock_widgets.h
|
||||||
<(src_loc)/window/window_main_menu.cpp
|
<(src_loc)/window/window_main_menu.cpp
|
||||||
<(src_loc)/window/window_main_menu.h
|
<(src_loc)/window/window_main_menu.h
|
||||||
<(src_loc)/window/window_peer_menu.cpp
|
<(src_loc)/window/window_peer_menu.cpp
|
||||||
|
@ -773,8 +775,6 @@
|
||||||
<(src_loc)/messenger.h
|
<(src_loc)/messenger.h
|
||||||
<(src_loc)/observer_peer.cpp
|
<(src_loc)/observer_peer.cpp
|
||||||
<(src_loc)/observer_peer.h
|
<(src_loc)/observer_peer.h
|
||||||
<(src_loc)/passcodewidget.cpp
|
|
||||||
<(src_loc)/passcodewidget.h
|
|
||||||
<(src_loc)/qt_static_plugins.cpp
|
<(src_loc)/qt_static_plugins.cpp
|
||||||
<(src_loc)/settings.cpp
|
<(src_loc)/settings.cpp
|
||||||
<(src_loc)/settings.h
|
<(src_loc)/settings.h
|
||||||
|
|
Loading…
Reference in New Issue