2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-27 21:07:09 +00:00
2021-09-17 17:28:15 +03:00

220 lines
6.6 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
This code is in Public Domain, see license terms in .github/CONTRIBUTING.md
Copyright (C) 2017, Nicholas Guriev <guriev-ns@ya.ru>
*/
#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"
#include "styles/style_boxes.h"
namespace {
constexpr auto kForeverHours = 24 * 365;
constexpr auto kForeverSeconds = kForeverHours * 3600;
constexpr auto kCustomFor = kForeverHours - 1;
} // namespace
MuteSettingsBox::MuteSettingsBox(QWidget *parent, not_null<PeerData*> peer)
: _peer(peer)
, _forNumberInput(this, st::scheduleDateField)
, _forPeriodInput(this, st::scheduleDateField) {
}
void MuteSettingsBox::prepare() {
setTitle(tr::lng_disable_notifications_from_tray());
auto y = 0;
object_ptr<Ui::FlatLabel> info(this, st::boxLabel);
info->setText(tr::lng_mute_box_tip(tr::now));
info->moveToLeft(st::boxPadding.left(), y);
y += info->height() + st::boxLittleSkip;
const auto icon = object_ptr<Ui::UserpicButton>(
this,
_peer,
Ui::UserpicButton::Role::Custom,
st::mutePhotoButton);
icon->setPointerCursor(false);
icon->moveToLeft(st::boxPadding.left(), y);
object_ptr<Ui::FlatLabel> title(this, st::muteChatTitle);
title->setText(_peer->name);
title->moveToLeft(
st::boxPadding.left() + st::muteChatTitleLeft,
y + (icon->height() / 2) - (title->height() / 2));
// the icon is always higher than this chat title
y += icon->height() + st::boxMediumSkip;
// in fact, this is mute only for 1 year
const auto group = std::make_shared<Ui::RadiobuttonGroup>(kForeverHours);
y += st::boxOptionListPadding.top();
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 == kCustomFor) {
return ktr("ktg_mute_for_selected_time");
} else {
return tr::lng_mute_duration_forever(tr::now);
}
}();
object_ptr<Ui::Radiobutton> 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<QEvent*> 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<Ui::DropdownMenu>(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({ 0, 0 });
const auto inputTopLeft = _forPeriodInput->mapToGlobal({ 0, 0 });
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() == 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(); });
setDimensions(st::boxWidth, y);
}
void MuteSettingsBox::keyPressEvent(QKeyEvent *e) {
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
if (_save) {
_save();
}
}
}
// vi: ts=4 tw=80