From fe9f02e485e3122bc9df31bca4daede114843cc3 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 17 Sep 2018 20:31:01 +0300 Subject: [PATCH] Improve self-destruct setting edit. --- Telegram/Resources/langs/lang.strings | 2 +- Telegram/SourceFiles/apiwrap.cpp | 39 +++++ Telegram/SourceFiles/apiwrap.h | 10 ++ .../boxes/self_destruction_box.cpp | 134 ++++++++++++------ .../SourceFiles/boxes/self_destruction_box.h | 13 +- .../settings/settings_privacy_security.cpp | 15 +- 6 files changed, 162 insertions(+), 51 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index ab45758ff..b918dfb80 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -519,7 +519,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_groups_invite_privacy" = "Group invite settings"; "lng_settings_show_sessions" = "Show all sessions"; "lng_settings_export_data" = "Export Telegram data"; -"lng_settings_self_destruct" = "Account self-destruct settings"; +"lng_settings_destroy_if" = "If away for..."; "lng_settings_change_phone" = "Change phone number"; "lng_settings_reset" = "Terminate all other sessions"; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index b47fad100..abd5783fc 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -5039,6 +5039,7 @@ void ApiWrap::reloadPrivacy(Privacy::Key key) { }).fail([=](const RPCError &error) { _privacyRequestIds.erase(key); }).send(); + _privacyRequestIds.emplace(key, requestId); } auto ApiWrap::parsePrivacy(const QVector &rules) @@ -5113,6 +5114,44 @@ auto ApiWrap::privacyValue(Privacy::Key key) -> rpl::producer { } } +void ApiWrap::reloadSelfDestruct() { + if (_selfDestructRequestId) { + return; + } + _selfDestructRequestId = request(MTPaccount_GetAccountTTL( + )).done([=](const MTPAccountDaysTTL &result) { + _selfDestructRequestId = 0; + result.match([&](const MTPDaccountDaysTTL &data) { + setSelfDestructDays(data.vdays.v); + }); + }).fail([=](const RPCError &error) { + _selfDestructRequestId = 0; + }).send(); +} + +rpl::producer ApiWrap::selfDestructValue() const { + return _selfDestructDays + ? _selfDestructChanges.events_starting_with_copy(*_selfDestructDays) + : (_selfDestructChanges.events() | rpl::type_erased()); +} + +void ApiWrap::saveSelfDestruct(int days) { + request(_selfDestructRequestId).cancel(); + _selfDestructRequestId = request(MTPaccount_SetAccountTTL( + MTP_accountDaysTTL(MTP_int(days)) + )).done([=](const MTPBool &result) { + _selfDestructRequestId = 0; + }).fail([=](const RPCError &result) { + _selfDestructRequestId = 0; + }).send(); + setSelfDestructDays(days); +} + +void ApiWrap::setSelfDestructDays(int days) { + _selfDestructDays = days; + _selfDestructChanges.fire_copy(days); +} + void ApiWrap::readServerHistory(not_null history) { if (history->unreadCount()) { readServerHistoryForce(history); diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index ecee3efac..8fcc195ed 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -360,6 +360,10 @@ public: void reloadPrivacy(Privacy::Key key); rpl::producer privacyValue(Privacy::Key key); + void reloadSelfDestruct(); + rpl::producer selfDestructValue() const; + void saveSelfDestruct(int days); + ~ApiWrap(); private: @@ -549,6 +553,8 @@ private: const QVector &rules); void updatePrivacyLastSeens(const QVector &rules); + void setSelfDestructDays(int days); + not_null _session; MessageDataRequests _messageDataRequests; @@ -710,4 +716,8 @@ private: base::flat_map _privacyValues; std::map> _privacyChanges; + mtpRequestId _selfDestructRequestId = 0; + base::optional _selfDestructDays; + rpl::event_stream _selfDestructChanges; + }; diff --git a/Telegram/SourceFiles/boxes/self_destruction_box.cpp b/Telegram/SourceFiles/boxes/self_destruction_box.cpp index 9a03306fa..128fe05e2 100644 --- a/Telegram/SourceFiles/boxes/self_destruction_box.cpp +++ b/Telegram/SourceFiles/boxes/self_destruction_box.cpp @@ -10,59 +10,109 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/labels.h" +#include "apiwrap.h" +#include "auth_session.h" #include "styles/style_boxes.h" +SelfDestructionBox::SelfDestructionBox( + QWidget*, + rpl::producer preloaded) +: _ttlValues{ 30, 90, 180, 365 } +, _loading( + this, + lang(lng_contacts_loading), + Ui::FlatLabel::InitType::Simple, + st::membersAbout) { + std::move( + preloaded + ) | rpl::take( + 1 + ) | rpl::start_with_next([=](int days) { + gotCurrent(days); + }, lifetime()); +} + +void SelfDestructionBox::gotCurrent(int days) { + Expects(!_ttlValues.empty()); + + _loading.destroy(); + + auto daysAdjusted = _ttlValues[0]; + for (const auto value : _ttlValues) { + if (qAbs(days - value) < qAbs(days - daysAdjusted)) { + daysAdjusted = value; + } + } + _ttlGroup = std::make_shared(daysAdjusted); + + if (_prepared) { + showContent(); + } +} + +void SelfDestructionBox::showContent() { + auto y = st::boxOptionListPadding.top(); + _description.create( + this, + lang(lng_self_destruct_description), + Ui::FlatLabel::InitType::Simple, + st::boxLabel); + _description->moveToLeft(st::boxPadding.left(), y); + y += _description->height() + st::boxMediumSkip; + + const auto count = int(_ttlValues.size()); + for (const auto value : _ttlValues) { + const auto button = Ui::CreateChild( + this, + _ttlGroup, + value, + DaysLabel(value), + st::langsButton); + button->moveToLeft(st::boxPadding.left(), y); + y += button->heightNoMargins() + st::boxOptionListSkip; + } + showChildren(); + + clearButtons(); + addButton(langFactory(lng_settings_save), [=] { + Auth().api().saveSelfDestruct(_ttlGroup->value()); + closeBox(); + }); + addButton(langFactory(lng_cancel), [=] { closeBox(); }); +} + +QString SelfDestructionBox::DaysLabel(int days) { + return (days > 364) + ? lng_self_destruct_years(lt_count, days / 365) + : lng_self_destruct_months(lt_count, qMax(days / 30, 1)); +} + void SelfDestructionBox::prepare() { setTitle(langFactory(lng_self_destruct_title)); - _ttlValues = { 30, 90, 180, 365 }; - - auto fake = object_ptr(this, lang(lng_self_destruct_description), Ui::FlatLabel::InitType::Simple, st::boxLabel); - auto boxHeight = st::boxOptionListPadding.top() + auto fake = object_ptr( + this, + lang(lng_self_destruct_description), + Ui::FlatLabel::InitType::Simple, + st::boxLabel); + const auto boxHeight = st::boxOptionListPadding.top() + fake->height() + st::boxMediumSkip - + _ttlValues.size() * (st::defaultRadio.diameter + st::boxOptionListSkip) - st::boxOptionListSkip + + (_ttlValues.size() + * (st::defaultRadio.diameter + st::boxOptionListSkip)) + - st::boxOptionListSkip + st::boxOptionListPadding.bottom() + st::boxPadding.bottom(); fake.destroy(); setDimensions(st::boxWidth, boxHeight); - auto loading = object_ptr(this, lang(lng_contacts_loading), Ui::FlatLabel::InitType::Simple, st::membersAbout); - loading->moveToLeft((st::boxWidth - loading->width()) / 2, boxHeight / 3); - addButton(langFactory(lng_cancel), [this] { closeBox(); }); - request(MTPaccount_GetAccountTTL()).done([this, loading = std::move(loading)](const MTPAccountDaysTTL &result) mutable { - Expects(result.type() == mtpc_accountDaysTTL); - Expects(!_ttlValues.empty()); - - loading.destroy(); - auto y = st::boxOptionListPadding.top(); - _description.create(this, lang(lng_self_destruct_description), Ui::FlatLabel::InitType::Simple, st::boxLabel); - _description->moveToLeft(st::boxPadding.left(), y); - y += _description->height() + st::boxMediumSkip; - - auto current = result.c_accountDaysTTL().vdays.v; - auto currentAdjusted = _ttlValues[0]; - for (auto days : _ttlValues) { - if (qAbs(current - days) < qAbs(current - currentAdjusted)) { - currentAdjusted = days; - } - } - auto group = std::make_shared(currentAdjusted); - auto count = int(_ttlValues.size()); - _options.reserve(count); - for (auto days : _ttlValues) { - _options.emplace_back(this, group, days, (days > 364) ? lng_self_destruct_years(lt_count, days / 365) : lng_self_destruct_months(lt_count, qMax(days / 30, 1)), st::langsButton); - _options.back()->moveToLeft(st::boxPadding.left(), y); - y += _options.back()->heightNoMargins() + st::boxOptionListSkip; - } - showChildren(); - - clearButtons(); - addButton(langFactory(lng_settings_save), [this, group] { - MTP::send(MTPaccount_SetAccountTTL(MTP_accountDaysTTL(MTP_int(group->value())))); - closeBox(); - }); - addButton(langFactory(lng_cancel), [this] { closeBox(); }); - }).send(); + if (_loading) { + _loading->moveToLeft( + (st::boxWidth - _loading->width()) / 2, + boxHeight / 3); + _prepared = true; + } else { + showContent(); + } } diff --git a/Telegram/SourceFiles/boxes/self_destruction_box.h b/Telegram/SourceFiles/boxes/self_destruction_box.h index 6371dd68a..d4f995a74 100644 --- a/Telegram/SourceFiles/boxes/self_destruction_box.h +++ b/Telegram/SourceFiles/boxes/self_destruction_box.h @@ -17,19 +17,22 @@ class FlatLabel; } // namespace Ui class SelfDestructionBox : public BoxContent, private MTP::Sender { - Q_OBJECT - public: - SelfDestructionBox(QWidget*) { - } + SelfDestructionBox(QWidget*, rpl::producer preloaded); + + static QString DaysLabel(int days); protected: void prepare() override; private: + void gotCurrent(int days); + void showContent(); + + bool _prepared = false; std::vector _ttlValues; object_ptr _description = { nullptr }; + object_ptr _loading; std::shared_ptr _ttlGroup; - std::vector> _options; }; diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/settings_privacy_security.cpp index c504a06b0..d3d65a87d 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_security.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_security.cpp @@ -380,12 +380,21 @@ void SetupSelfDestruction(not_null container) { AddSkip(container); AddSubsectionTitle(container, lng_settings_destroy_title); - AddButton( + Auth().api().reloadSelfDestruct(); + const auto label = [] { + return Auth().api().selfDestructValue( + ) | rpl::map( + SelfDestructionBox::DaysLabel + ); + }; + + AddButtonWithLabel( container, - lng_settings_self_destruct, + lng_settings_destroy_if, + label(), st::settingsButton )->addClickHandler([] { - Ui::show(Box()); + Ui::show(Box(Auth().api().selfDestructValue())); }); AddSkip(container);