diff --git a/Telegram/Resources/langs/rewrites/en.json b/Telegram/Resources/langs/rewrites/en.json index 436083227..74be075f5 100644 --- a/Telegram/Resources/langs/rewrites/en.json +++ b/Telegram/Resources/langs/rewrites/en.json @@ -202,6 +202,39 @@ "ktg_filters_hide_all_chats_toast": "\"All Chats\" folder is hidden.\nYou can enable it back in Kotatogram Settings.", "ktg_filters_hide_edit_toast": "Edit button is hidden.\nYou can enable it back in Kotatogram Settings.", "ktg_settings_telegram_sites_autologin": "Auto-login on Telegram sites", + "ktg_mute_for_selected_time": "For selected time", + "ktg_notifications_mute_seconds": { + "zero": "seconds", + "one": "second", + "two": "seconds", + "few": "seconds", + "many": "seconds", + "other": "seconds" + }, + "ktg_notifications_mute_minutes": { + "zero": "minutes", + "one": "minute", + "two": "minutes", + "few": "minutes", + "many": "minutes", + "other": "minutes" + }, + "ktg_notifications_mute_hours": { + "zero": "hours", + "one": "hour", + "two": "hours", + "few": "hours", + "many": "hours", + "other": "hours" + }, + "ktg_notifications_mute_days": { + "zero": "days", + "one": "day", + "two": "days", + "few": "days", + "many": "days", + "other": "days" + }, "ktg_forward_sender_names_and_captions_removed": "Sender names and captions removed", "ktg_forward_remember_mode": "Remember forward mode", "ktg_forward_mode": "Forward mode", diff --git a/Telegram/SourceFiles/boxes/mute_settings_box.cpp b/Telegram/SourceFiles/boxes/mute_settings_box.cpp index be5137f9a..df8e56b5e 100644 --- a/Telegram/SourceFiles/boxes/mute_settings_box.cpp +++ b/Telegram/SourceFiles/boxes/mute_settings_box.cpp @@ -7,11 +7,15 @@ Copyright (C) 2017, Nicholas Guriev */ #include "boxes/mute_settings_box.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" +#include "base/event_filter.h" #include "main/main_session.h" #include "data/data_session.h" #include "data/data_peer.h" #include "ui/special_buttons.h" +#include "ui/widgets/dropdown_menu.h" +#include "ui/widgets/input_fields.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/labels.h" #include "styles/style_layers.h" @@ -20,11 +24,15 @@ Copyright (C) 2017, Nicholas Guriev namespace { constexpr auto kForeverHours = 24 * 365; +constexpr auto kForeverSeconds = kForeverHours * 3600; +constexpr auto kCustomFor = kForeverHours - 1; } // namespace MuteSettingsBox::MuteSettingsBox(QWidget *parent, not_null peer) -: _peer(peer) { +: _peer(peer) +, _forNumberInput(this, st::scheduleDateField) +, _forPeriodInput(this, st::scheduleDateField) { } void MuteSettingsBox::prepare() { @@ -55,12 +63,28 @@ void MuteSettingsBox::prepare() { // in fact, this is mute only for 1 year const auto group = std::make_shared(kForeverHours); y += st::boxOptionListPadding.top(); - for (const auto hours : { 1, 4, 18, 72, kForeverHours }) { + + const auto makePeriodText = [=, this] (Period period) { + const auto currentValue = _forNumberInput->getLastText().toInt(); + switch (period) { + case Period::Second: return ktr("ktg_notifications_mute_seconds", currentValue); + case Period::Minute: return ktr("ktg_notifications_mute_minutes", currentValue); + case Period::Hour: return ktr("ktg_notifications_mute_hours", currentValue); + case Period::Day: return ktr("ktg_notifications_mute_days", currentValue); + + default: + return QString(); + } + }; + + // Prefill input values, default is 1 hour + _forNumberInput->setText("1"); + _forPeriodInput->setText(makePeriodText(_period)); + + for (const auto hours : { kCustomFor, kForeverHours }) { const auto text = [&] { - if (hours < 24) { - return tr::lng_mute_duration_hours(tr::now, lt_count, hours); - } else if (hours < kForeverHours) { - return tr::lng_mute_duration_days(tr::now, lt_count, hours / 24); + if (hours == kCustomFor) { + return ktr("ktg_mute_for_selected_time"); } else { return tr::lng_mute_duration_forever(tr::now); } @@ -68,17 +92,115 @@ void MuteSettingsBox::prepare() { object_ptr option(this, group, hours, text); option->moveToLeft(st::boxPadding.left(), y); y += option->heightNoMargins() + st::boxOptionListSkip; + + if (hours == kCustomFor) { + const auto fieldLeft = st::boxPadding.left() + + st::autolockButton.margin.left() + + st::autolockButton.margin.right() + + st::defaultToggle.width + + st::defaultToggle.border * 2; + + _forNumberInput->resizeToWidth(st::scheduleTimeWidth); + _forNumberInput->moveToLeft(fieldLeft, y); + + _forPeriodInput->resizeToWidth(st::scheduleDateWidth); + _forPeriodInput->moveToLeft(fieldLeft + st::scheduleTimeWidth + st::scheduleAtSkip, y); + + y += _forNumberInput->heightNoMargins() + st::boxOptionListSkip; + } } + group->setChangedCallback([this] (int hours) { + if (hours == kCustomFor) { + _forNumberInput->setFocus(); + } else { + _forNumberInput->clearFocus(); + } + }); y += st::boxOptionListPadding.bottom() - st::boxOptionListSkip + st::defaultCheckbox.margin.bottom(); + _forNumberInput->customTab(true); + + _forNumberInput->documentContentsChanges( + ) | rpl::start_with_next([=](const auto &value) { + _forNumberInput->hideError(); + _forPeriodInput->setText(makePeriodText(_period)); + }, _lifetime); + + QObject::connect(_forNumberInput, &Ui::InputField::focused, [=] { + if (group->value() != kCustomFor) { + group->setValue(kCustomFor); + } + }); + + _forPeriodInput->rawTextEdit()->setTextInteractionFlags(Qt::NoTextInteraction); + + const auto &forPeriodViewport = _forPeriodInput->rawTextEdit()->viewport(); + base::install_event_filter(forPeriodViewport, [=](not_null event) { + switch (event->type()) { + case QEvent::Leave: + if (_menu) { + _menu->hideAnimated(); + } + return base::EventFilterResult::Cancel; + + case QEvent::ContextMenu: + case QEvent::MouseButtonDblClick: + return base::EventFilterResult::Cancel; + + case QEvent::MouseButtonPress: + if (group->value() != kCustomFor) { + group->setValue(kCustomFor); + } + + _forNumberInput->setFocus(); + + if (_menu) { + _menu->hideAnimated(Ui::InnerDropdown::HideOption::IgnoreShow); + return base::EventFilterResult::Cancel; + } + + _menu = base::make_unique_q(window()); + const auto weak = _menu.get(); + _menu->setHiddenCallback([=] { + weak->deleteLater(); + }); + + for (const auto period : { Period::Second, Period::Minute, Period::Hour, Period::Day }) { + const auto periodStr = makePeriodText(period); + _menu->addAction(periodStr, [=] { + _period = period; + _forPeriodInput->setText(periodStr); + }); + } + + const auto parentTopLeft = window()->mapToGlobal(QPoint()); + const auto inputTopLeft = _forPeriodInput->mapToGlobal(QPoint()); + const auto parentRect = QRect(parentTopLeft, window()->size()); + const auto inputRect = QRect(inputTopLeft, _forPeriodInput->size()); + _menu->move( + inputRect.x() + inputRect.width() + st::boxPadding.left() - _menu->width() - parentRect.x(), + inputRect.y() + inputRect.height() - parentRect.y()); + _menu->showAnimated(Ui::PanelAnimation::Origin::TopRight); + return base::EventFilterResult::Cancel; + } + + return base::EventFilterResult::Continue; + }); + _save = [=] { - const auto muteForSeconds = group->value() * 3600; - _peer->owner().updateNotifySettings( - _peer, - muteForSeconds); - closeBox(); + const auto muteForSeconds = (group->value() == kCustomFor) + ? _forNumberInput->getLastText().toInt() * int(_period) + : group->value() * 3600; + if (muteForSeconds <= 0 || muteForSeconds > kForeverSeconds) { + _forNumberInput->showError(); + } else { + _peer->owner().updateNotifySettings( + _peer, + muteForSeconds); + closeBox(); + } }; addButton(tr::lng_box_ok(), _save); addButton(tr::lng_cancel(), [this] { closeBox(); }); diff --git a/Telegram/SourceFiles/boxes/mute_settings_box.h b/Telegram/SourceFiles/boxes/mute_settings_box.h index d91692410..dfca331e5 100644 --- a/Telegram/SourceFiles/boxes/mute_settings_box.h +++ b/Telegram/SourceFiles/boxes/mute_settings_box.h @@ -9,6 +9,11 @@ Copyright (C) 2017, Nicholas Guriev #include "boxes/abstract_box.h" +namespace Ui { +class InputField; +class DropdownMenu; +} + /* This class implements a dialog-box with radio-buttons for pick duration of * turning off notifications from a chat. The widget is opened by a context menu * in the left list of dialogues. */ @@ -22,8 +27,22 @@ protected: void keyPressEvent(QKeyEvent *e) override; private: + enum Period { + Second = 1, + Minute = 60, + Hour = 3600, + Day = 86400, + }; + not_null _peer; Fn _save; + object_ptr _forNumberInput; + object_ptr _forPeriodInput; + + Period _period = Period::Hour; + base::unique_qptr _menu; + + rpl::lifetime _lifetime; }; // vi: ts=4 tw=80