diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index 6fedca26e..37a8e21db 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -20,3 +20,8 @@ settingsSlider: SettingsSlider(defaultSettingsSlider) { labelFg: windowSubTextFg; labelFgActive: windowActiveTextFg; } + +settingsNotificationsCheckbox: defaultBoxCheckbox; +settingsNotificationsCheckboxPadding: margins(22px, 10px, 10px, 10px); +settingsLink: boxLinkButton; +settingsAdvancedNotificationsPadding: margins(22px, 20px, 10px, 10px); diff --git a/Telegram/SourceFiles/settings/settings_common.cpp b/Telegram/SourceFiles/settings/settings_common.cpp index a683d9096..901fbc91e 100644 --- a/Telegram/SourceFiles/settings/settings_common.cpp +++ b/Telegram/SourceFiles/settings/settings_common.cpp @@ -13,11 +13,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/settings_main.h" #include "settings/settings_notifications.h" #include "settings/settings_privacy_security.h" +#include "ui/wrap/padding_wrap.h" +#include "ui/wrap/vertical_layout.h" +#include "boxes/abstract_box.h" #include "lang/lang_keys.h" #include "mainwindow.h" +#include "styles/style_settings.h" namespace Settings { +void AddSkip(not_null container) { + container->add(object_ptr( + container, + st::settingsSectionSkip)); +} + +void AddDivider(not_null container) { + container->add(object_ptr(container)); +} + object_ptr
CreateSection( Type type, not_null parent, diff --git a/Telegram/SourceFiles/settings/settings_common.h b/Telegram/SourceFiles/settings/settings_common.h index 284c32009..f76d335a9 100644 --- a/Telegram/SourceFiles/settings/settings_common.h +++ b/Telegram/SourceFiles/settings/settings_common.h @@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/rp_widget.h" +namespace Ui { +class VerticalLayout; +} // namespace Ui + namespace Window { class Controller; } // namespace Window @@ -48,6 +52,9 @@ object_ptr
CreateSection( not_null controller, UserData *self = nullptr); +void AddSkip(not_null container); +void AddDivider(not_null container); + using MenuCallback = Fn handler)>; diff --git a/Telegram/SourceFiles/settings/settings_main.cpp b/Telegram/SourceFiles/settings/settings_main.cpp index a9207a799..7213d79fb 100644 --- a/Telegram/SourceFiles/settings/settings_main.cpp +++ b/Telegram/SourceFiles/settings/settings_main.cpp @@ -15,7 +15,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/about_box.h" #include "boxes/photo_crop_box.h" #include "ui/wrap/vertical_layout.h" -#include "ui/wrap/padding_wrap.h" #include "ui/widgets/labels.h" #include "ui/widgets/discrete_sliders.h" #include "info/profile/info_profile_button.h" @@ -30,16 +29,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Settings { namespace { -void AddSkip(not_null container) { - container->add(object_ptr( - container, - st::settingsSectionSkip)); -} - -void AddDivider(not_null container) { - container->add(object_ptr(container)); -} - void SetupUploadPhotoButton( not_null container, not_null self) { diff --git a/Telegram/SourceFiles/settings/settings_notifications.cpp b/Telegram/SourceFiles/settings/settings_notifications.cpp index 7a6e31ac1..c6eeb6fa6 100644 --- a/Telegram/SourceFiles/settings/settings_notifications.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications.cpp @@ -8,12 +8,216 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/settings_notifications.h" #include "settings/settings_common.h" -#include "boxes/abstract_box.h" #include "ui/wrap/vertical_layout.h" +#include "ui/wrap/slide_wrap.h" +#include "ui/widgets/checkbox.h" +#include "ui/widgets/buttons.h" #include "lang/lang_keys.h" +#include "storage/localstorage.h" +#include "window/notifications_manager.h" +#include "boxes/notifications_box.h" +#include "platform/platform_notifications_manager.h" +#include "mainwindow.h" +#include "auth_session.h" #include "styles/style_settings.h" namespace Settings { +namespace { + +void SetupNotificationsContent(not_null container) { + const auto checkbox = [&](LangKey label, bool checked) { + return object_ptr( + container, + lang(label), + checked, + st::settingsNotificationsCheckbox); + }; + const auto addCheckbox = [&](LangKey label, bool checked) { + return container->add( + checkbox(label, checked), + st::settingsNotificationsCheckboxPadding); + }; + const auto addSlidingCheckbox = [&](LangKey label, bool checked) { + return container->add( + object_ptr>( + container, + checkbox(label, checked), + st::settingsNotificationsCheckboxPadding)); + }; + const auto desktop = addCheckbox( + lng_settings_desktop_notify, + Global::DesktopNotify()); + const auto name = addSlidingCheckbox( + lng_settings_show_name, + (Global::NotifyView() <= dbinvShowName)); + const auto preview = addSlidingCheckbox( + lng_settings_show_preview, + (Global::NotifyView() <= dbinvShowPreview)); + const auto sound = addCheckbox( + lng_settings_sound_notify, + Global::SoundNotify()); + const auto muted = addCheckbox( + lng_settings_include_muted, + Global::IncludeMuted()); + + const auto nativeNotificationsKey = [&] { + if (!Platform::Notifications::Supported()) { + return LangKey(); + } else if (cPlatform() == dbipWindows) { + return lng_settings_use_windows; + } else if (cPlatform() == dbipLinux32 + || cPlatform() == dbipLinux64) { + return lng_settings_use_native_notifications; + } + return LangKey(); + }(); + const auto native = nativeNotificationsKey + ? addCheckbox(nativeNotificationsKey, Global::NativeNotifications()) + : nullptr; + const auto advanced = (cPlatform() != dbipMac) + ? container->add( + object_ptr>( + container, + object_ptr( + container, + lang(lng_settings_advanced_notifications), + st::settingsLink), + st::settingsAdvancedNotificationsPadding)) + : nullptr; + + if (!name->entity()->checked()) { + preview->hide(anim::type::instant); + } + if (!desktop->checked()) { + name->hide(anim::type::instant); + preview->hide(anim::type::instant); + } + if (native && advanced && Global::NativeNotifications()) { + advanced->hide(anim::type::instant); + } + + const auto lifetime = Ui::AttachAsChild(container, rpl::lifetime()); + + using Change = Window::Notifications::ChangeType; + const auto changed = [](Change change) { + Local::writeUserSettings(); + Auth().notifications().settingsChanged().notify(change); + }; + base::ObservableViewer( + desktop->checkedChanged + ) | rpl::filter([](bool checked) { + return (checked != Global::DesktopNotify()); + }) | rpl::start_with_next([=](bool checked) { + Global::SetDesktopNotify(checked); + changed(Change::DesktopEnabled); + }, *lifetime); + + base::ObservableViewer( + name->entity()->checkedChanged + ) | rpl::map([=](bool checked) { + if (!checked) { + return dbinvShowNothing; + } else if (!preview->entity()->checked()) { + return dbinvShowName; + } + return dbinvShowPreview; + }) | rpl::filter([=](DBINotifyView value) { + return (value != Global::NotifyView()); + }) | rpl::start_with_next([=](DBINotifyView value) { + Global::SetNotifyView(value); + changed(Change::ViewParams); + }, *lifetime); + + base::ObservableViewer( + preview->entity()->checkedChanged + ) | rpl::map([=](bool checked) { + if (checked) { + return dbinvShowPreview; + } else if (name->entity()->checked()) { + return dbinvShowName; + } + return dbinvShowNothing; + }) | rpl::filter([=](DBINotifyView value) { + return (value != Global::NotifyView()); + }) | rpl::start_with_next([=](DBINotifyView value) { + Global::SetNotifyView(value); + changed(Change::ViewParams); + }, *lifetime); + + base::ObservableViewer( + sound->checkedChanged + ) | rpl::filter([](bool checked) { + return (checked != Global::SoundNotify()); + }) | rpl::start_with_next([=](bool checked) { + Global::SetSoundNotify(checked); + changed(Change::SoundEnabled); + }, *lifetime); + + base::ObservableViewer( + muted->checkedChanged + ) | rpl::filter([](bool checked) { + return (checked != Global::IncludeMuted()); + }) | rpl::start_with_next([=](bool checked) { + Global::SetIncludeMuted(checked); + changed(Change::IncludeMuted); + }, *lifetime); + + base::ObservableViewer( + Auth().notifications().settingsChanged() + ) | rpl::start_with_next([=](Change change) { + if (change == Change::DesktopEnabled) { + desktop->setChecked(Global::DesktopNotify()); + name->toggle(Global::DesktopNotify(), anim::type::normal); + preview->toggle( + Global::DesktopNotify() && name->entity()->checked(), + anim::type::normal); + } else if (change == Change::ViewParams) { + preview->toggle(name->entity()->checked(), anim::type::normal); + } else if (change == Change::SoundEnabled) { + sound->setChecked(Global::SoundNotify()); + } + }, *lifetime); + + if (native) { + base::ObservableViewer( + native->checkedChanged + ) | rpl::filter([](bool checked) { + return (checked != Global::NativeNotifications()); + }) | rpl::start_with_next([=](bool checked) { + Global::SetNativeNotifications(checked); + Local::writeUserSettings(); + + Auth().notifications().createManager(); + + if (advanced) { + advanced->toggle( + !Global::NativeNotifications(), + anim::type::normal); + } + }, *lifetime); + } + if (advanced) { + advanced->entity()->addClickHandler([=] { + Ui::show(Box()); + }); + } +} + +void SetupNotifications(not_null container) { + AddDivider(container); + AddSkip(container); + + auto wrap = object_ptr(container); + SetupNotificationsContent(wrap.data()); + + container->add(object_ptr( + container, + std::move(wrap))); + + AddSkip(container); +} + +} // namespace Notifications::Notifications(QWidget *parent, not_null self) : Section(parent) @@ -24,7 +228,7 @@ Notifications::Notifications(QWidget *parent, not_null self) void Notifications::setupContent() { const auto content = Ui::CreateChild(this); - content->add(object_ptr(content)); + SetupNotifications(content); Ui::ResizeFitChild(this, content); }