| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- /*
- 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 "settings/business/settings_greeting.h"
- #include "base/event_filter.h"
- #include "core/application.h"
- #include "data/business/data_business_info.h"
- #include "data/business/data_shortcut_messages.h"
- #include "data/data_session.h"
- #include "lang/lang_keys.h"
- #include "main/main_session.h"
- #include "settings/business/settings_shortcut_messages.h"
- #include "settings/business/settings_recipients_helper.h"
- #include "ui/boxes/time_picker_box.h"
- #include "ui/layers/generic_box.h"
- #include "ui/text/text_utilities.h"
- #include "ui/toast/toast.h"
- #include "ui/widgets/box_content_divider.h"
- #include "ui/widgets/buttons.h"
- #include "ui/widgets/vertical_drum_picker.h"
- #include "ui/wrap/slide_wrap.h"
- #include "ui/wrap/vertical_layout.h"
- #include "ui/vertical_list.h"
- #include "window/window_session_controller.h"
- #include "styles/style_layers.h"
- #include "styles/style_settings.h"
- namespace Settings {
- namespace {
- constexpr auto kDefaultNoActivityDays = 7;
- class Greeting : public BusinessSection<Greeting> {
- public:
- Greeting(
- QWidget *parent,
- not_null<Window::SessionController*> controller);
- ~Greeting();
- [[nodiscard]] bool closeByOutsideClick() const override;
- [[nodiscard]] rpl::producer<QString> title() override;
- const Ui::RoundRect *bottomSkipRounding() const override {
- return &_bottomSkipRounding;
- }
- private:
- void setupContent(not_null<Window::SessionController*> controller);
- void save();
- Ui::RoundRect _bottomSkipRounding;
- rpl::variable<Data::BusinessRecipients> _recipients;
- rpl::variable<bool> _canHave;
- rpl::event_stream<> _deactivateOnAttempt;
- rpl::variable<int> _noActivityDays;
- rpl::variable<bool> _enabled;
- };
- Greeting::Greeting(
- QWidget *parent,
- not_null<Window::SessionController*> controller)
- : BusinessSection(parent, controller)
- , _bottomSkipRounding(st::boxRadius, st::boxDividerBg) {
- setupContent(controller);
- }
- void EditPeriodBox(
- not_null<Ui::GenericBox*> box,
- int days,
- Fn<void(int)> save) {
- auto values = std::vector{ 7, 14, 21, 28 };
- if (!ranges::contains(values, days)) {
- values.push_back(days);
- ranges::sort(values);
- }
- const auto phrases = ranges::views::all(
- values
- ) | ranges::views::transform([](int days) {
- return tr::lng_days(tr::now, lt_count, days);
- }) | ranges::to_vector;
- const auto take = TimePickerBox(box, values, phrases, days);
- box->addButton(tr::lng_settings_save(), [=] {
- const auto weak = Ui::MakeWeak(box);
- save(take());
- if (const auto strong = weak.data()) {
- strong->closeBox();
- }
- });
- box->addButton(tr::lng_cancel(), [=] {
- box->closeBox();
- });
- }
- Greeting::~Greeting() {
- if (!Core::Quitting()) {
- save();
- }
- }
- bool Greeting::closeByOutsideClick() const {
- return false;
- }
- rpl::producer<QString> Greeting::title() {
- return tr::lng_greeting_title();
- }
- void Greeting::setupContent(
- not_null<Window::SessionController*> controller) {
- using namespace rpl::mappers;
- const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
- const auto info = &controller->session().data().businessInfo();
- const auto current = info->greetingSettings();
- const auto disabled = !current.noActivityDays;
- _recipients = disabled
- ? Data::BusinessRecipients{ .allButExcluded = true }
- : Data::BusinessRecipients::MakeValid(current.recipients);
- _noActivityDays = disabled
- ? kDefaultNoActivityDays
- : current.noActivityDays;
- AddDividerTextWithLottie(content, {
- .lottie = u"greeting"_q,
- .lottieSize = st::settingsCloudPasswordIconSize,
- .lottieMargins = st::peerAppearanceIconPadding,
- .showFinished = showFinishes(),
- .about = tr::lng_greeting_about(Ui::Text::WithEntities),
- .aboutMargins = st::peerAppearanceCoverLabelMargin,
- });
- const auto session = &controller->session();
- _canHave = rpl::combine(
- ShortcutsCountValue(session),
- ShortcutsLimitValue(session),
- ShortcutExistsValue(session, u"hello"_q),
- (_1 < _2) || _3);
- Ui::AddSkip(content);
- const auto enabled = content->add(object_ptr<Ui::SettingsButton>(
- content,
- tr::lng_greeting_enable(),
- st::settingsButtonNoIcon
- ))->toggleOn(rpl::single(
- !disabled
- ) | rpl::then(rpl::merge(
- _canHave.value() | rpl::filter(!_1),
- _deactivateOnAttempt.events() | rpl::map_to(false)
- )));
- _enabled = enabled->toggledValue();
- _enabled.value() | rpl::filter(_1) | rpl::start_with_next([=] {
- if (!_canHave.current()) {
- controller->showToast({
- .text = { tr::lng_greeting_limit_reached(tr::now) },
- .adaptive = true,
- });
- _deactivateOnAttempt.fire({});
- }
- }, lifetime());
- Ui::AddSkip(content);
- content->add(
- object_ptr<Ui::SlideWrap<Ui::BoxContentDivider>>(
- content,
- object_ptr<Ui::BoxContentDivider>(
- content,
- st::boxDividerHeight,
- st::boxDividerBg,
- RectPart::Top))
- )->setDuration(0)->toggleOn(enabled->toggledValue() | rpl::map(!_1));
- content->add(
- object_ptr<Ui::SlideWrap<Ui::BoxContentDivider>>(
- content,
- object_ptr<Ui::BoxContentDivider>(
- content))
- )->setDuration(0)->toggleOn(enabled->toggledValue());
- const auto wrap = content->add(
- object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
- content,
- object_ptr<Ui::VerticalLayout>(content)));
- const auto inner = wrap->entity();
- const auto createWrap = inner->add(
- object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
- inner,
- object_ptr<Ui::VerticalLayout>(inner)));
- const auto createInner = createWrap->entity();
- Ui::AddSkip(createInner);
- const auto create = AddButtonWithLabel(
- createInner,
- rpl::conditional(
- ShortcutExistsValue(session, u"hello"_q),
- tr::lng_business_edit_messages(),
- tr::lng_greeting_create()),
- ShortcutMessagesCountValue(
- session,
- u"hello"_q
- ) | rpl::map([=](int count) {
- return count
- ? tr::lng_forum_messages(tr::now, lt_count, count)
- : QString();
- }),
- st::settingsButtonLightNoIcon);
- create->setClickedCallback([=] {
- const auto owner = &controller->session().data();
- const auto id = owner->shortcutMessages().emplaceShortcut("hello");
- showOther(ShortcutMessagesId(id));
- });
- Ui::AddSkip(createInner);
- Ui::AddDivider(createInner);
- createWrap->toggleOn(rpl::single(true));
- Ui::AddSkip(inner);
- AddBusinessRecipientsSelector(inner, {
- .controller = controller,
- .title = tr::lng_greeting_recipients(),
- .data = &_recipients,
- .type = Data::BusinessRecipientsType::Messages,
- });
- Ui::AddSkip(inner);
- Ui::AddDivider(inner);
- Ui::AddSkip(inner);
- AddButtonWithLabel(
- inner,
- tr::lng_greeting_period_title(),
- _noActivityDays.value(
- ) | rpl::map(
- [](int days) { return tr::lng_days(tr::now, lt_count, days); }
- ),
- st::settingsButtonNoIcon
- )->setClickedCallback([=] {
- controller->show(Box(
- EditPeriodBox,
- _noActivityDays.current(),
- [=](int days) { _noActivityDays = days; }));
- });
- Ui::AddSkip(inner);
- Ui::AddDividerText(
- inner,
- tr::lng_greeting_period_about(),
- st::settingsChatbotsBottomTextMargin,
- RectPart::Top);
- wrap->toggleOn(enabled->toggledValue());
- wrap->finishAnimating();
- Ui::ResizeFitChild(this, content);
- }
- void Greeting::save() {
- const auto show = controller()->uiShow();
- const auto session = &controller()->session();
- const auto fail = [=](QString error) {
- if (error == u"BUSINESS_RECIPIENTS_EMPTY"_q) {
- show->showToast(tr::lng_greeting_recipients_empty(tr::now));
- } else if (error != u"SHORTCUT_INVALID"_q) {
- show->showToast(error);
- }
- };
- session->data().businessInfo().saveGreetingSettings(
- _enabled.current() ? Data::GreetingSettings{
- .recipients = _recipients.current(),
- .noActivityDays = _noActivityDays.current(),
- .shortcutId = LookupShortcutId(session, u"hello"_q),
- } : Data::GreetingSettings(),
- fail);
- }
- } // namespace
- Type GreetingId() {
- return Greeting::Id();
- }
- } // namespace Settings
|