diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 0653486a2..3072e1235 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -898,6 +898,8 @@ PRIVATE menu/menu_mute.h menu/menu_send.cpp menu/menu_send.h + menu/menu_ttl_validator.cpp + menu/menu_ttl_validator.h mtproto/config_loader.cpp mtproto/config_loader.h mtproto/connection_abstract.cpp diff --git a/Telegram/Resources/icons/chat/input_autodelete.png b/Telegram/Resources/icons/chat/input_autodelete.png new file mode 100644 index 000000000..68f8f7b74 Binary files /dev/null and b/Telegram/Resources/icons/chat/input_autodelete.png differ diff --git a/Telegram/Resources/icons/chat/input_autodelete@2x.png b/Telegram/Resources/icons/chat/input_autodelete@2x.png new file mode 100644 index 000000000..37c858111 Binary files /dev/null and b/Telegram/Resources/icons/chat/input_autodelete@2x.png differ diff --git a/Telegram/Resources/icons/chat/input_autodelete@3x.png b/Telegram/Resources/icons/chat/input_autodelete@3x.png new file mode 100644 index 000000000..2ad4551d1 Binary files /dev/null and b/Telegram/Resources/icons/chat/input_autodelete@3x.png differ diff --git a/Telegram/Resources/icons/chat/input_autodelete_1d.png b/Telegram/Resources/icons/chat/input_autodelete_1d.png deleted file mode 100644 index 22aa744ba..000000000 Binary files a/Telegram/Resources/icons/chat/input_autodelete_1d.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_autodelete_1d@2x.png b/Telegram/Resources/icons/chat/input_autodelete_1d@2x.png deleted file mode 100644 index 765078a9b..000000000 Binary files a/Telegram/Resources/icons/chat/input_autodelete_1d@2x.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_autodelete_1d@3x.png b/Telegram/Resources/icons/chat/input_autodelete_1d@3x.png deleted file mode 100644 index 97fb566d0..000000000 Binary files a/Telegram/Resources/icons/chat/input_autodelete_1d@3x.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_autodelete_30d.png b/Telegram/Resources/icons/chat/input_autodelete_30d.png deleted file mode 100644 index 85ba465a6..000000000 Binary files a/Telegram/Resources/icons/chat/input_autodelete_30d.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_autodelete_30d@2x.png b/Telegram/Resources/icons/chat/input_autodelete_30d@2x.png deleted file mode 100644 index 052d067f8..000000000 Binary files a/Telegram/Resources/icons/chat/input_autodelete_30d@2x.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_autodelete_30d@3x.png b/Telegram/Resources/icons/chat/input_autodelete_30d@3x.png deleted file mode 100644 index c71ea6fcb..000000000 Binary files a/Telegram/Resources/icons/chat/input_autodelete_30d@3x.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_autodelete_7d.png b/Telegram/Resources/icons/chat/input_autodelete_7d.png deleted file mode 100644 index c5dae024f..000000000 Binary files a/Telegram/Resources/icons/chat/input_autodelete_7d.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_autodelete_7d@2x.png b/Telegram/Resources/icons/chat/input_autodelete_7d@2x.png deleted file mode 100644 index ba42b0ab6..000000000 Binary files a/Telegram/Resources/icons/chat/input_autodelete_7d@2x.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_autodelete_7d@3x.png b/Telegram/Resources/icons/chat/input_autodelete_7d@3x.png deleted file mode 100644 index 341182dfa..000000000 Binary files a/Telegram/Resources/icons/chat/input_autodelete_7d@3x.png and /dev/null differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index f88ef925b..921b35184 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1123,7 +1123,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_manage_history_visibility_hidden_legacy" = "New members won't see more than 100 previous messages."; "lng_manage_messages_ttl_title" = "Auto-delete after..."; -"lng_manage_messages_ttl_never" = "Disable"; +"lng_manage_messages_ttl_disable" = "Disable"; "lng_manage_messages_ttl_after1" = "1 hour"; "lng_manage_messages_ttl_after2" = "1 day"; "lng_manage_messages_ttl_after3" = "1 week"; diff --git a/Telegram/SourceFiles/history/view/controls/history_view_ttl_button.cpp b/Telegram/SourceFiles/history/view/controls/history_view_ttl_button.cpp index af3ae4947..7e293f8e4 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_ttl_button.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_ttl_button.cpp @@ -7,102 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/controls/history_view_ttl_button.h" -#include "data/data_peer.h" -#include "data/data_chat.h" -#include "data/data_channel.h" #include "data/data_changes.h" +#include "data/data_peer.h" #include "main/main_session.h" -#include "menu/menu_ttl.h" -#include "lang/lang_keys.h" -#include "boxes/peers/edit_peer_info_box.h" -#include "ui/boxes/auto_delete_settings.h" -#include "ui/toast/toast.h" -#include "ui/toasts/common_toasts.h" +#include "menu/menu_ttl_validator.h" +#include "ui/text/format_values.h" #include "ui/text/text_utilities.h" -#include "apiwrap.h" #include "styles/style_chat.h" namespace HistoryView::Controls { -namespace { - -constexpr auto kToastDuration = crl::time(3500); - -void ShowAutoDeleteToast( - not_null parent, - not_null peer) { - const auto period = peer->messagesTTL(); - if (!period) { - Ui::Toast::Show(parent, tr::lng_ttl_about_tooltip_off(tr::now)); - return; - } - - const auto duration = (period == 5) - ? u"5 seconds"_q - : (period < 2 * 86400) - ? tr::lng_ttl_about_duration1(tr::now) - : (period < 8 * 86400) - ? tr::lng_ttl_about_duration2(tr::now) - : tr::lng_ttl_about_duration3(tr::now); - const auto text = peer->isBroadcast() - ? tr::lng_ttl_about_tooltip_channel(tr::now, lt_duration, duration) - : tr::lng_ttl_about_tooltip(tr::now, lt_duration, duration); - Ui::ShowMultilineToast({ - .parentOverride = parent, - .text = { text }, - .duration = kToastDuration, - }); -} - -} // namespace - -void AutoDeleteSettingsMenu( - not_null parent, - std::shared_ptr show, - not_null peer, - rpl::producer<> triggers) { - struct State { - TimeId savingPeriod = 0; - mtpRequestId savingRequestId = 0; - QPointer weak; - }; - const auto state = std::make_shared(State{ - .weak = Ui::MakeWeak(parent.get()), - }); - auto callback = [=](TimeId period) { - auto &api = peer->session().api(); - if (state->savingRequestId) { - if (period == state->savingPeriod) { - return; - } - api.request(state->savingRequestId).cancel(); - } - state->savingPeriod = period; - state->savingRequestId = api.request(MTPmessages_SetHistoryTTL( - peer->input, - MTP_int(period) - )).done([=](const MTPUpdates &result) { - peer->session().api().applyUpdates(result); - ShowAutoDeleteToast(show->toastParent(), peer); -#if 0 - if (const auto strong = state->weak.data()) { - strong->closeBox(); - } -#endif - }).fail([=] { - state->savingRequestId = 0; - }).send(); - }; - auto about = peer->isUser() - ? tr::lng_ttl_edit_about(lt_user, rpl::single(peer->shortName())) - : peer->isBroadcast() - ? tr::lng_ttl_edit_about_channel() - : tr::lng_ttl_edit_about_group(); - const auto ttl = peer->messagesTTL(); - TTLMenu::SetupTTLMenu( - parent, - std::move(triggers), - { std::move(show), ttl, std::move(about), std::move(callback) }); -} TTLButton::TTLButton( not_null parent, @@ -110,37 +23,23 @@ TTLButton::TTLButton( not_null peer) : _peer(peer) , _button(parent, st::historyMessagesTTL) { - auto triggers = _button.clicks( + + const auto validator = TTLMenu::TTLValidator(std::move(show), peer); + auto clicks = _button.clicks( ) | rpl::to_empty | rpl::filter([=] { - const auto canEdit = peer->isUser() - || (peer->isChat() - && peer->asChat()->canDeleteMessages()) - || (peer->isChannel() - && peer->asChannel()->canDeleteMessages()); - if (!canEdit) { - ShowAutoDeleteToast(show->toastParent(), peer); + if (!validator.can()) { + validator.showToast(); return false; } return true; }); - AutoDeleteSettingsMenu(parent, show, peer, std::move(triggers)); + TTLMenu::SetupTTLMenu(parent, std::move(clicks), validator.createArgs()); peer->session().changes().peerFlagsValue( peer, Data::PeerUpdate::Flag::MessagesTTL ) | rpl::start_with_next([=] { - const auto ttl = peer->messagesTTL(); - if (ttl < 2 * 86400) { - _button.setIconOverride(nullptr, nullptr); - } else if (ttl < 8 * 86400) { - _button.setIconOverride( - &st::historyMessagesTTL2Icon, - &st::historyMessagesTTL2IconOver); - } else { - _button.setIconOverride( - &st::historyMessagesTTL3Icon, - &st::historyMessagesTTL3IconOver); - } + _button.setText(Ui::FormatTTLTiny(peer->messagesTTL())); }, _button.lifetime()); } diff --git a/Telegram/SourceFiles/history/view/controls/history_view_ttl_button.h b/Telegram/SourceFiles/history/view/controls/history_view_ttl_button.h index bfc431765..dbdc50a9f 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_ttl_button.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_ttl_button.h @@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "ui/widgets/buttons.h" +#include "ui/widgets/icon_button_with_text.h" namespace Ui { class Show; @@ -15,12 +15,6 @@ class Show; namespace HistoryView::Controls { -void AutoDeleteSettingsMenu( - not_null parent, - std::shared_ptr show, - not_null peer, - rpl::producer<> triggers); - class TTLButton final { public: TTLButton( @@ -40,7 +34,7 @@ public: private: const not_null _peer; - Ui::IconButton _button; + Ui::IconButtonWithText _button; }; diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp index f30696161..f38ff4f00 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.cpp +++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp @@ -38,6 +38,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "mainwidget.h" #include "lang/lang_keys.h" +#include "styles/style_chat.h" // popupMenuExpandedSeparator #include "styles/style_info.h" #include "styles/style_profile.h" #include "styles/style_menu_icons.h" @@ -494,7 +495,7 @@ void WrapWidget::showTopBarMenu() { } _topBarMenu = base::make_unique_q( this, - st::popupMenuWithIcons); + st::popupMenuExpandedSeparator); _topBarMenu->setDestroyedCallback([this] { InvokeQueued(this, [this] { _topBarMenu = nullptr; }); @@ -506,6 +507,19 @@ void WrapWidget::showTopBarMenu() { const auto addAction = Window::PeerMenuCallback([=]( Window::PeerMenuCallback::Args a) { + if (a.isSeparator) { + return _topBarMenu->addSeparator(); + } else if (a.fillSubmenu) { + const auto action = _topBarMenu->addAction( + a.text, + std::move(a.handler), + a.icon); + // Dummy menu. + action->setMenu( + Ui::CreateChild(_topBarMenu->menu().get())); + a.fillSubmenu(_topBarMenu->ensureSubmenu(action)); + return action; + } return _topBarMenu->addAction(a.text, std::move(a.handler), a.icon); }); if (key().isDownloads()) { diff --git a/Telegram/SourceFiles/menu/menu_ttl.cpp b/Telegram/SourceFiles/menu/menu_ttl.cpp index 31ec538e4..f36337923 100644 --- a/Telegram/SourceFiles/menu/menu_ttl.cpp +++ b/Telegram/SourceFiles/menu/menu_ttl.cpp @@ -137,7 +137,7 @@ void TTLBox( ) | rpl::map([=](int seconds) { state->lastSeconds = seconds; return !seconds - ? tr::lng_manage_messages_ttl_never() + ? tr::lng_manage_messages_ttl_disable() : tr::lng_enable_auto_delete(); }) | rpl::flatten_latest(); const auto confirm = box->addButton(std::move(confirmText), [=] { @@ -178,7 +178,7 @@ void FillTTLMenu(not_null menu, Args args) { if (args.startTtl) { const auto disable = menu->addAction( - tr::lng_manage_messages_ttl_never(tr::now), + tr::lng_manage_messages_ttl_disable(tr::now), [=] { args.callback(0); }, &st::menuIconDisableAttention); disable->setData(st::menuIconAttentionColor->c); diff --git a/Telegram/SourceFiles/menu/menu_ttl_validator.cpp b/Telegram/SourceFiles/menu/menu_ttl_validator.cpp new file mode 100644 index 000000000..93779cdb7 --- /dev/null +++ b/Telegram/SourceFiles/menu/menu_ttl_validator.cpp @@ -0,0 +1,122 @@ +/* +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 "menu/menu_ttl_validator.h" + +#include "apiwrap.h" +#include "data/data_channel.h" +#include "data/data_chat.h" +#include "data/data_peer.h" +#include "lang/lang_keys.h" +#include "main/main_session.h" +#include "menu/menu_ttl.h" +#include "ui/layers/show.h" +#include "ui/text/text_utilities.h" +#include "ui/toast/toast.h" +#include "ui/toasts/common_toasts.h" +#include "styles/style_chat.h" +#include "styles/style_menu_icons.h" + +namespace TTLMenu { +namespace { + +constexpr auto kToastDuration = crl::time(3500); + +void ShowAutoDeleteToast( + not_null parent, + not_null peer) { + const auto period = peer->messagesTTL(); + if (!period) { + Ui::Toast::Show(parent, tr::lng_ttl_about_tooltip_off(tr::now)); + return; + } + + const auto duration = (period == 5) + ? u"5 seconds"_q + : (period < 2 * 86400) + ? tr::lng_ttl_about_duration1(tr::now) + : (period < 8 * 86400) + ? tr::lng_ttl_about_duration2(tr::now) + : tr::lng_ttl_about_duration3(tr::now); + const auto text = peer->isBroadcast() + ? tr::lng_ttl_about_tooltip_channel(tr::now, lt_duration, duration) + : tr::lng_ttl_about_tooltip(tr::now, lt_duration, duration); + Ui::ShowMultilineToast({ + .parentOverride = parent, + .text = { text }, + .duration = kToastDuration, + }); +} + +} // namespace + +TTLValidator::TTLValidator( + std::shared_ptr show, + not_null peer) +: _peer(peer) +, _show(std::move(show)) { +} + +Args TTLValidator::createArgs() const { + const auto peer = _peer; + const auto show = _show; + struct State { + TimeId savingPeriod = 0; + mtpRequestId savingRequestId = 0; + }; + const auto state = std::make_shared(); + auto callback = [=, toastParent = show->toastParent()](TimeId period) { + auto &api = peer->session().api(); + if (state->savingRequestId) { + if (period == state->savingPeriod) { + return; + } + api.request(state->savingRequestId).cancel(); + } + state->savingPeriod = period; + state->savingRequestId = api.request(MTPmessages_SetHistoryTTL( + peer->input, + MTP_int(period) + )).done([=](const MTPUpdates &result) { + peer->session().api().applyUpdates(result); + ShowAutoDeleteToast(toastParent, peer); + state->savingRequestId = 0; +#if 0 + if (const auto strong = state->weak.data()) { + strong->closeBox(); + } +#endif + }).fail([=] { + state->savingRequestId = 0; + }).send(); + }; + auto about = peer->isUser() + ? tr::lng_ttl_edit_about(lt_user, rpl::single(peer->shortName())) + : peer->isBroadcast() + ? tr::lng_ttl_edit_about_channel() + : tr::lng_ttl_edit_about_group(); + const auto ttl = peer->messagesTTL(); + return { std::move(show), ttl, std::move(about), std::move(callback) }; +} + +bool TTLValidator::can() const { + return _peer->isUser() + || (_peer->isChat() + && _peer->asChat()->canDeleteMessages()) + || (_peer->isChannel() + && _peer->asChannel()->canDeleteMessages()); +} + +void TTLValidator::showToast() const { + ShowAutoDeleteToast(_show->toastParent(), _peer); +} + +const style::icon *TTLValidator::icon() const { + return &st::menuIconTTL; +} + +} // namespace TTLMenu diff --git a/Telegram/SourceFiles/menu/menu_ttl_validator.h b/Telegram/SourceFiles/menu/menu_ttl_validator.h new file mode 100644 index 000000000..eb737baf3 --- /dev/null +++ b/Telegram/SourceFiles/menu/menu_ttl_validator.h @@ -0,0 +1,38 @@ +/* +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 "menu/menu_ttl.h" + +class PeerData; + +namespace Ui { +class Show; +class RpWidget; +} // namespace Ui + +namespace TTLMenu { + +class TTLValidator final { +public: + TTLValidator( + std::shared_ptr show, + not_null peer); + + [[nodiscard]] bool can() const; + [[nodiscard]] Args createArgs() const; + void showToast() const; + const style::icon *icon() const; + +private: + const not_null _peer; + const std::shared_ptr _show; + +}; + +} // namespace TTLMenu diff --git a/Telegram/SourceFiles/ui/boxes/auto_delete_settings.cpp b/Telegram/SourceFiles/ui/boxes/auto_delete_settings.cpp index 0818a1dee..d65417979 100644 --- a/Telegram/SourceFiles/ui/boxes/auto_delete_settings.cpp +++ b/Telegram/SourceFiles/ui/boxes/auto_delete_settings.cpp @@ -200,7 +200,7 @@ void AutoDeleteSettingsBox( }); const auto options = std::vector{ - tr::lng_manage_messages_ttl_never(tr::now), + tr::lng_manage_messages_ttl_disable(tr::now), //u"5 seconds"_q, AssertIsDebug() tr::lng_manage_messages_ttl_after1(tr::now), tr::lng_manage_messages_ttl_after2(tr::now), diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style index 6987ada8c..cec0536c8 100644 --- a/Telegram/SourceFiles/ui/chat/chat.style +++ b/Telegram/SourceFiles/ui/chat/chat.style @@ -311,14 +311,17 @@ historyAttachEmoji: IconButton(historyAttach) { icon: icon {{ "chat/input_smile_face", historyComposeIconFg }}; iconOver: icon {{ "chat/input_smile_face", historyComposeIconFgOver }}; } -historyMessagesTTL: IconButton(historyAttach) { - icon: icon {{ "chat/input_autodelete_1d", historyComposeIconFg }}; - iconOver: icon {{ "chat/input_autodelete_1d", historyComposeIconFgOver }}; +historyMessagesTTL: IconButtonWithText { + iconButton: IconButton(historyAttach) { + icon: icon {{ "chat/input_autodelete", historyComposeIconFg }}; + iconOver: icon {{ "chat/input_autodelete", historyComposeIconFgOver }}; + } + textFg: historyComposeIconFg; + textFgOver: historyComposeIconFgOver; + textPadding: margins(16px, 20px, 6px, 7px); + + font: font(10px semibold); } -historyMessagesTTL2Icon: icon {{ "chat/input_autodelete_7d", historyComposeIconFg }}; -historyMessagesTTL2IconOver: icon {{ "chat/input_autodelete_7d", historyComposeIconFgOver }}; -historyMessagesTTL3Icon: icon {{ "chat/input_autodelete_30d", historyComposeIconFg }}; -historyMessagesTTL3IconOver: icon {{ "chat/input_autodelete_30d", historyComposeIconFgOver }}; historyMessagesTTLLabel: FlatLabel(defaultFlatLabel) { minWidth: 200px; align: align(topleft); diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 72c046dab..7dccca6f4 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "main/main_session_settings.h" #include "menu/menu_mute.h" +#include "menu/menu_ttl_validator.h" #include "apiwrap.h" #include "mainwidget.h" #include "mainwindow.h" @@ -191,6 +192,7 @@ private: void addBotToGroup(); void addNewMembers(); void addDeleteContact(); + void addTTLSubmenu(bool addSeparator); not_null _controller; Dialogs::EntryState _request; @@ -764,6 +766,26 @@ void Filler::addThemeEdit() { &st::menuIconChangeColors); } +void Filler::addTTLSubmenu(bool addSeparator) { + const auto validator = TTLMenu::TTLValidator( + std::make_shared(_controller), + _peer); + if (!validator.can()) { + return; + } + _addAction(PeerMenuCallback::Args{ + .text = tr::lng_manage_messages_ttl_menu(tr::now), + .handler = nullptr, + .icon = validator.icon(), + .fillSubmenu = [=](not_null menu) { + TTLMenu::FillTTLMenu(menu, validator.createArgs()); + }, + }); + if (addSeparator) { + _addAction(PeerMenuCallback::Args{ .isSeparator = true }); + } +} + void Filler::fill() { if (_folder) { fillArchiveActions(); @@ -808,6 +830,7 @@ void Filler::fillHistoryActions() { addThemeEdit(); addViewDiscussion(); addExportChat(); + addTTLSubmenu(false); addReport(); addClearHistory(); addDeleteChat(); @@ -816,6 +839,7 @@ void Filler::fillHistoryActions() { void Filler::fillProfileActions() { addSupportInfo(); + addTTLSubmenu(true); addNewContact(); addShareContact(); addEditContact();