mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
784 lines
25 KiB
C++
784 lines
25 KiB
C++
/*
|
|
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/builder/settings_notifications_builder.h"
|
|
|
|
#include "api/api_authorizations.h"
|
|
#include "api/api_ringtones.h"
|
|
#include "apiwrap.h"
|
|
#include "base/platform/base_platform_info.h"
|
|
#include "boxes/ringtones_box.h"
|
|
#include "core/application.h"
|
|
#include "data/data_chat_filters.h"
|
|
#include "data/data_session.h"
|
|
#include "data/notify/data_notify_settings.h"
|
|
#include "data/notify/data_peer_notify_volume.h"
|
|
#include "lang/lang_keys.h"
|
|
#include "main/main_account.h"
|
|
#include "main/main_domain.h"
|
|
#include "main/main_session.h"
|
|
#include "mainwindow.h"
|
|
#include "platform/platform_notifications_manager.h"
|
|
#include "platform/platform_specific.h"
|
|
#include "settings/builder/settings_builder.h"
|
|
#include "settings/settings_notifications_common.h"
|
|
#include "settings/settings_notifications_type.h"
|
|
#include "ui/vertical_list.h"
|
|
#include "ui/widgets/buttons.h"
|
|
#include "ui/widgets/checkbox.h"
|
|
#include "ui/widgets/continuous_sliders.h"
|
|
#include "ui/widgets/discrete_sliders.h"
|
|
#include "ui/wrap/slide_wrap.h"
|
|
#include "ui/wrap/vertical_layout.h"
|
|
#include "window/notifications_manager.h"
|
|
#include "window/window_session_controller.h"
|
|
#include "styles/style_settings.h"
|
|
#include "styles/style_menu_icons.h"
|
|
|
|
#include <QtGui/QGuiApplication>
|
|
#include <QtGui/QScreen>
|
|
|
|
namespace Settings::Builder {
|
|
namespace {
|
|
|
|
constexpr auto kDefaultDisplayIndex = -1;
|
|
|
|
using NotifyView = Core::Settings::NotifyView;
|
|
using ChangeType = Window::Notifications::ChangeType;
|
|
|
|
void BuildMultiAccountSection(
|
|
SectionBuilder &builder,
|
|
Window::SessionController *controller) {
|
|
if (Core::App().domain().accounts().size() < 2) {
|
|
return;
|
|
}
|
|
|
|
builder.addSubsectionTitle(tr::lng_settings_show_from());
|
|
|
|
const auto container = builder.container();
|
|
if (!container) {
|
|
builder.addToggle({
|
|
.id = u"notifications/multi_account"_q,
|
|
.title = tr::lng_settings_notify_all(),
|
|
.toggled = rpl::single(Core::App().settings().notifyFromAll()),
|
|
.keywords = { u"all accounts"_q, u"multiple"_q },
|
|
});
|
|
builder.addSkip();
|
|
builder.addDividerText(tr::lng_settings_notify_all_about());
|
|
builder.addSkip();
|
|
return;
|
|
}
|
|
|
|
const auto fromAll = builder.addToggle({
|
|
.id = u"notifications/accounts"_q,
|
|
.title = tr::lng_settings_notify_all(),
|
|
.st = &st::settingsButtonNoIcon,
|
|
.toggled = rpl::single(Core::App().settings().notifyFromAll()),
|
|
.keywords = { u"all accounts"_q, u"multiple"_q },
|
|
});
|
|
|
|
if (fromAll) {
|
|
fromAll->toggledChanges(
|
|
) | rpl::filter([](bool checked) {
|
|
return (checked != Core::App().settings().notifyFromAll());
|
|
}) | rpl::on_next([=](bool checked) {
|
|
Core::App().settings().setNotifyFromAll(checked);
|
|
Core::App().saveSettingsDelayed();
|
|
if (!checked) {
|
|
auto ¬ifications = Core::App().notifications();
|
|
const auto &list = Core::App().domain().accounts();
|
|
for (const auto &[index, account] : list) {
|
|
if (account.get() == &Core::App().domain().active()) {
|
|
continue;
|
|
} else if (const auto session = account->maybeSession()) {
|
|
notifications.clearFromSession(session);
|
|
}
|
|
}
|
|
}
|
|
}, fromAll->lifetime());
|
|
}
|
|
|
|
builder.addSkip();
|
|
builder.addDividerText(tr::lng_settings_notify_all_about());
|
|
builder.addSkip();
|
|
}
|
|
|
|
void BuildGlobalNotificationsSection(
|
|
SectionBuilder &builder,
|
|
Window::SessionController *controller) {
|
|
builder.addSubsectionTitle(tr::lng_settings_notify_global());
|
|
|
|
const auto container = builder.container();
|
|
const auto &settings = Core::App().settings();
|
|
|
|
const auto desktopToggles = container
|
|
? container->lifetime().make_state<rpl::event_stream<bool>>()
|
|
: nullptr;
|
|
const auto desktop = builder.addToggle({
|
|
.id = u"notifications/desktop"_q,
|
|
.title = tr::lng_settings_desktop_notify(),
|
|
.icon = { &st::menuIconNotifications },
|
|
.toggled = desktopToggles
|
|
? desktopToggles->events_starting_with(settings.desktopNotify())
|
|
: rpl::single(settings.desktopNotify()),
|
|
.keywords = { u"desktop"_q, u"popup"_q, u"show"_q },
|
|
});
|
|
|
|
const auto flashbounceToggles = container
|
|
? container->lifetime().make_state<rpl::event_stream<bool>>()
|
|
: nullptr;
|
|
const auto flashbounce = builder.addToggle({
|
|
.id = u"notifications/flash"_q,
|
|
.title = (Platform::IsWindows()
|
|
? tr::lng_settings_alert_windows
|
|
: Platform::IsMac()
|
|
? tr::lng_settings_alert_mac
|
|
: tr::lng_settings_alert_linux)(),
|
|
.icon = { &st::menuIconDockBounce },
|
|
.toggled = flashbounceToggles
|
|
? flashbounceToggles->events_starting_with(settings.flashBounceNotify())
|
|
: rpl::single(settings.flashBounceNotify()),
|
|
.keywords = { u"flash"_q, u"bounce"_q, u"taskbar"_q },
|
|
});
|
|
|
|
const auto soundAllowed = container
|
|
? container->lifetime().make_state<rpl::event_stream<bool>>()
|
|
: nullptr;
|
|
const auto allowed = [=] {
|
|
return Core::App().settings().soundNotify();
|
|
};
|
|
const auto sound = builder.addToggle({
|
|
.id = u"notifications/sound"_q,
|
|
.title = tr::lng_settings_sound_allowed(),
|
|
.icon = { &st::menuIconUnmute },
|
|
.toggled = soundAllowed
|
|
? soundAllowed->events_starting_with(allowed())
|
|
: rpl::single(allowed()),
|
|
.keywords = { u"sound"_q, u"audio"_q, u"mute"_q },
|
|
});
|
|
|
|
if (container && controller) {
|
|
const auto session = &controller->session();
|
|
Ui::AddRingtonesVolumeSlider(
|
|
container,
|
|
rpl::single(true),
|
|
tr::lng_settings_master_volume_notifications(),
|
|
Data::VolumeController{
|
|
.volume = []() -> ushort {
|
|
const auto volume
|
|
= Core::App().settings().notificationsVolume();
|
|
return volume ? volume : 100;
|
|
},
|
|
.saveVolume = [=](ushort volume) {
|
|
Core::App().notifications().playSound(
|
|
session,
|
|
0,
|
|
volume / 100.);
|
|
Core::App().settings().setNotificationsVolume(volume);
|
|
Core::App().saveSettingsDelayed();
|
|
}});
|
|
}
|
|
|
|
builder.addSkip();
|
|
|
|
if (desktop) {
|
|
const auto changed = [=](ChangeType change) {
|
|
Core::App().saveSettingsDelayed();
|
|
Core::App().notifications().notifySettingsChanged(change);
|
|
};
|
|
|
|
desktop->toggledChanges(
|
|
) | rpl::filter([](bool checked) {
|
|
return (checked != Core::App().settings().desktopNotify());
|
|
}) | rpl::on_next([=](bool checked) {
|
|
Core::App().settings().setDesktopNotify(checked);
|
|
changed(ChangeType::DesktopEnabled);
|
|
}, desktop->lifetime());
|
|
|
|
if (sound) {
|
|
sound->toggledChanges(
|
|
) | rpl::filter([](bool checked) {
|
|
return (checked != Core::App().settings().soundNotify());
|
|
}) | rpl::on_next([=](bool checked) {
|
|
Core::App().settings().setSoundNotify(checked);
|
|
changed(ChangeType::SoundEnabled);
|
|
}, sound->lifetime());
|
|
}
|
|
|
|
if (flashbounce) {
|
|
flashbounce->toggledChanges(
|
|
) | rpl::filter([](bool checked) {
|
|
return (checked != Core::App().settings().flashBounceNotify());
|
|
}) | rpl::on_next([=](bool checked) {
|
|
Core::App().settings().setFlashBounceNotify(checked);
|
|
changed(ChangeType::FlashBounceEnabled);
|
|
}, flashbounce->lifetime());
|
|
}
|
|
|
|
Core::App().notifications().settingsChanged(
|
|
) | rpl::on_next([=](ChangeType change) {
|
|
if (change == ChangeType::DesktopEnabled) {
|
|
desktopToggles->fire(Core::App().settings().desktopNotify());
|
|
} else if (change == ChangeType::SoundEnabled) {
|
|
soundAllowed->fire(allowed());
|
|
} else if (change == ChangeType::FlashBounceEnabled) {
|
|
flashbounceToggles->fire(
|
|
Core::App().settings().flashBounceNotify());
|
|
}
|
|
}, desktop->lifetime());
|
|
}
|
|
}
|
|
|
|
void BuildNotifyViewSection(
|
|
SectionBuilder &builder,
|
|
Window::SessionController *controller,
|
|
rpl::lifetime &lifetime) {
|
|
const auto container = builder.container();
|
|
if (!container || !controller) {
|
|
return;
|
|
}
|
|
|
|
const auto &settings = Core::App().settings();
|
|
const auto checkboxes = SetupNotifyViewOptions(
|
|
controller,
|
|
container,
|
|
(settings.notifyView() <= NotifyView::ShowName),
|
|
(settings.notifyView() <= NotifyView::ShowPreview));
|
|
const auto name = checkboxes.name;
|
|
const auto preview = checkboxes.preview;
|
|
const auto previewWrap = checkboxes.wrap;
|
|
|
|
const auto previewDivider = container->add(
|
|
object_ptr<Ui::SlideWrap<Ui::BoxContentDivider>>(
|
|
container,
|
|
object_ptr<Ui::BoxContentDivider>(container)));
|
|
previewWrap->toggle(settings.desktopNotify(), anim::type::instant);
|
|
previewDivider->toggle(!settings.desktopNotify(), anim::type::instant);
|
|
|
|
const auto changed = [=](ChangeType change) {
|
|
Core::App().saveSettingsDelayed();
|
|
Core::App().notifications().notifySettingsChanged(change);
|
|
};
|
|
|
|
name->checkedChanges(
|
|
) | rpl::map([=](bool checked) {
|
|
if (!checked) {
|
|
preview->setChecked(false);
|
|
return NotifyView::ShowNothing;
|
|
} else if (!preview->checked()) {
|
|
return NotifyView::ShowName;
|
|
}
|
|
return NotifyView::ShowPreview;
|
|
}) | rpl::filter([=](NotifyView value) {
|
|
return (value != Core::App().settings().notifyView());
|
|
}) | rpl::on_next([=](NotifyView value) {
|
|
Core::App().settings().setNotifyView(value);
|
|
changed(ChangeType::ViewParams);
|
|
}, name->lifetime());
|
|
|
|
preview->checkedChanges(
|
|
) | rpl::map([=](bool checked) {
|
|
if (checked) {
|
|
name->setChecked(true);
|
|
return NotifyView::ShowPreview;
|
|
} else if (name->checked()) {
|
|
return NotifyView::ShowName;
|
|
}
|
|
return NotifyView::ShowNothing;
|
|
}) | rpl::filter([=](NotifyView value) {
|
|
return (value != Core::App().settings().notifyView());
|
|
}) | rpl::on_next([=](NotifyView value) {
|
|
Core::App().settings().setNotifyView(value);
|
|
changed(ChangeType::ViewParams);
|
|
}, preview->lifetime());
|
|
|
|
Core::App().notifications().settingsChanged(
|
|
) | rpl::on_next([=](ChangeType change) {
|
|
if (change == ChangeType::DesktopEnabled) {
|
|
previewWrap->toggle(
|
|
Core::App().settings().desktopNotify(),
|
|
anim::type::normal);
|
|
previewDivider->toggle(
|
|
!Core::App().settings().desktopNotify(),
|
|
anim::type::normal);
|
|
}
|
|
}, lifetime);
|
|
}
|
|
|
|
void BuildNotifyTypeSection(
|
|
SectionBuilder &builder,
|
|
Window::SessionController *controller) {
|
|
const auto container = builder.container();
|
|
const auto showOther = builder.showOther();
|
|
|
|
builder.addSkip(st::notifyPreviewBottomSkip);
|
|
builder.addSubsectionTitle(tr::lng_settings_notify_title());
|
|
|
|
if (container && controller && showOther) {
|
|
controller->session().data().notifySettings().loadExceptions();
|
|
AddTypeButton(container, controller, Data::DefaultNotify::User, showOther);
|
|
AddTypeButton(container, controller, Data::DefaultNotify::Group, showOther);
|
|
AddTypeButton(container, controller, Data::DefaultNotify::Broadcast, showOther);
|
|
} else {
|
|
builder.addSettingsButton({
|
|
.id = u"notifications/private"_q,
|
|
.title = tr::lng_notification_private_chats(),
|
|
.icon = { &st::menuIconProfile },
|
|
.keywords = { u"private"_q, u"chats"_q, u"direct"_q },
|
|
});
|
|
builder.addSettingsButton({
|
|
.id = u"notifications/groups"_q,
|
|
.title = tr::lng_notification_groups(),
|
|
.icon = { &st::menuIconGroups },
|
|
.keywords = { u"groups"_q, u"chats"_q },
|
|
});
|
|
builder.addSettingsButton({
|
|
.id = u"notifications/channels"_q,
|
|
.title = tr::lng_notification_channels(),
|
|
.icon = { &st::menuIconChannel },
|
|
.keywords = { u"channels"_q, u"broadcast"_q },
|
|
});
|
|
}
|
|
}
|
|
|
|
void BuildEventNotificationsSection(
|
|
SectionBuilder &builder,
|
|
Window::SessionController *controller) {
|
|
builder.addSkip(st::settingsCheckboxesSkip);
|
|
builder.addDivider();
|
|
builder.addSkip(st::settingsCheckboxesSkip);
|
|
builder.addSubsectionTitle(tr::lng_settings_events_title());
|
|
|
|
if (!controller) {
|
|
builder.addToggle({
|
|
.id = u"notifications/events/joined"_q,
|
|
.title = tr::lng_settings_events_joined(),
|
|
.icon = { &st::menuIconInvite },
|
|
.toggled = rpl::single(false),
|
|
.keywords = { u"joined"_q, u"contacts"_q, u"signup"_q },
|
|
});
|
|
builder.addToggle({
|
|
.id = u"notifications/events/pinned"_q,
|
|
.title = tr::lng_settings_events_pinned(),
|
|
.icon = { &st::menuIconPin },
|
|
.toggled = rpl::single(Core::App().settings().notifyAboutPinned()),
|
|
.keywords = { u"pinned"_q, u"message"_q },
|
|
});
|
|
return;
|
|
}
|
|
|
|
const auto session = &controller->session();
|
|
const auto &settings = Core::App().settings();
|
|
|
|
auto joinSilent = rpl::single(
|
|
session->api().contactSignupSilentCurrent().value_or(false)
|
|
) | rpl::then(session->api().contactSignupSilent());
|
|
|
|
const auto joined = builder.addToggle({
|
|
.id = u"notifications/events/joined"_q,
|
|
.title = tr::lng_settings_events_joined(),
|
|
.icon = { &st::menuIconInvite },
|
|
.toggled = std::move(joinSilent) | rpl::map([](bool s) { return !s; }),
|
|
.keywords = { u"joined"_q, u"contacts"_q, u"signup"_q },
|
|
});
|
|
if (joined) {
|
|
joined->toggledChanges(
|
|
) | rpl::filter([=](bool enabled) {
|
|
const auto silent = session->api().contactSignupSilentCurrent();
|
|
return (enabled == silent.value_or(false));
|
|
}) | rpl::on_next([=](bool enabled) {
|
|
session->api().saveContactSignupSilent(!enabled);
|
|
}, joined->lifetime());
|
|
}
|
|
|
|
const auto pinned = builder.addToggle({
|
|
.id = u"notifications/events/pinned"_q,
|
|
.title = tr::lng_settings_events_pinned(),
|
|
.icon = { &st::menuIconPin },
|
|
.toggled = rpl::single(
|
|
settings.notifyAboutPinned()
|
|
) | rpl::then(settings.notifyAboutPinnedChanges()),
|
|
.keywords = { u"pinned"_q, u"message"_q },
|
|
});
|
|
if (pinned) {
|
|
pinned->toggledChanges(
|
|
) | rpl::filter([=](bool notify) {
|
|
return (notify != Core::App().settings().notifyAboutPinned());
|
|
}) | rpl::on_next([=](bool notify) {
|
|
Core::App().settings().setNotifyAboutPinned(notify);
|
|
Core::App().saveSettingsDelayed();
|
|
}, pinned->lifetime());
|
|
}
|
|
}
|
|
|
|
void BuildCallNotificationsSection(
|
|
SectionBuilder &builder,
|
|
Window::SessionController *controller) {
|
|
builder.addSkip(st::settingsCheckboxesSkip);
|
|
builder.addDivider();
|
|
builder.addSkip(st::settingsCheckboxesSkip);
|
|
builder.addSubsectionTitle(tr::lng_settings_notifications_calls_title());
|
|
|
|
if (!controller) {
|
|
builder.addToggle({
|
|
.id = u"notifications/calls/accept"_q,
|
|
.title = tr::lng_settings_call_accept_calls(),
|
|
.icon = { &st::menuIconCallsReceive },
|
|
.toggled = rpl::single(true),
|
|
.keywords = { u"calls"_q, u"receive"_q, u"incoming"_q },
|
|
});
|
|
return;
|
|
}
|
|
|
|
const auto session = &controller->session();
|
|
const auto authorizations = &session->api().authorizations();
|
|
authorizations->reload();
|
|
|
|
const auto acceptCalls = builder.addToggle({
|
|
.id = u"notifications/calls/accept"_q,
|
|
.title = tr::lng_settings_call_accept_calls(),
|
|
.icon = { &st::menuIconCallsReceive },
|
|
.toggled = authorizations->callsDisabledHereValue()
|
|
| rpl::map([](bool disabled) { return !disabled; }),
|
|
.keywords = { u"calls"_q, u"receive"_q, u"incoming"_q },
|
|
});
|
|
if (acceptCalls) {
|
|
const auto container = builder.container();
|
|
acceptCalls->toggledChanges(
|
|
) | rpl::filter([=](bool toggled) {
|
|
return (toggled == authorizations->callsDisabledHere());
|
|
}) | rpl::on_next([=](bool toggled) {
|
|
authorizations->toggleCallsDisabledHere(!toggled);
|
|
}, container->lifetime());
|
|
}
|
|
}
|
|
|
|
void BuildBadgeCounterSection(
|
|
SectionBuilder &builder,
|
|
Window::SessionController *controller) {
|
|
builder.addSkip(st::settingsCheckboxesSkip);
|
|
builder.addDivider();
|
|
builder.addSkip(st::settingsCheckboxesSkip);
|
|
builder.addSubsectionTitle(tr::lng_settings_badge_title());
|
|
|
|
const auto &settings = Core::App().settings();
|
|
|
|
const auto muted = builder.addToggle({
|
|
.id = u"notifications/include-muted-chats"_q,
|
|
.title = tr::lng_settings_include_muted(),
|
|
.st = &st::settingsButtonNoIcon,
|
|
.toggled = rpl::single(settings.includeMutedCounter()),
|
|
.keywords = { u"muted"_q, u"badge"_q, u"counter"_q },
|
|
});
|
|
|
|
const auto hasFolders = controller
|
|
&& controller->session().data().chatsFilters().has();
|
|
const auto mutedFolders = hasFolders ? builder.addToggle({
|
|
.id = u"notifications/badge/muted_folders"_q,
|
|
.title = tr::lng_settings_include_muted_folders(),
|
|
.st = &st::settingsButtonNoIcon,
|
|
.toggled = rpl::single(settings.includeMutedCounterFolders()),
|
|
.keywords = { u"muted"_q, u"folders"_q },
|
|
}) : nullptr;
|
|
|
|
const auto count = builder.addToggle({
|
|
.id = u"notifications/count-unread-messages"_q,
|
|
.title = tr::lng_settings_count_unread(),
|
|
.st = &st::settingsButtonNoIcon,
|
|
.toggled = rpl::single(settings.countUnreadMessages()),
|
|
.keywords = { u"unread"_q, u"messages"_q, u"count"_q },
|
|
});
|
|
|
|
const auto changed = [=](ChangeType change) {
|
|
Core::App().saveSettingsDelayed();
|
|
Core::App().notifications().notifySettingsChanged(change);
|
|
};
|
|
|
|
if (muted) {
|
|
muted->toggledChanges(
|
|
) | rpl::filter([=](bool checked) {
|
|
return (checked != Core::App().settings().includeMutedCounter());
|
|
}) | rpl::on_next([=](bool checked) {
|
|
Core::App().settings().setIncludeMutedCounter(checked);
|
|
changed(ChangeType::IncludeMuted);
|
|
}, muted->lifetime());
|
|
}
|
|
|
|
if (mutedFolders) {
|
|
mutedFolders->toggledChanges(
|
|
) | rpl::filter([=](bool checked) {
|
|
return (checked
|
|
!= Core::App().settings().includeMutedCounterFolders());
|
|
}) | rpl::on_next([=](bool checked) {
|
|
Core::App().settings().setIncludeMutedCounterFolders(checked);
|
|
changed(ChangeType::IncludeMuted);
|
|
}, mutedFolders->lifetime());
|
|
}
|
|
|
|
if (count) {
|
|
count->toggledChanges(
|
|
) | rpl::filter([=](bool checked) {
|
|
return (checked != Core::App().settings().countUnreadMessages());
|
|
}) | rpl::on_next([=](bool checked) {
|
|
Core::App().settings().setCountUnreadMessages(checked);
|
|
changed(ChangeType::CountMessages);
|
|
}, count->lifetime());
|
|
}
|
|
}
|
|
|
|
void BuildSystemIntegrationAndAdvancedSection(
|
|
SectionBuilder &builder,
|
|
Window::SessionController *controller) {
|
|
const auto container = builder.container();
|
|
|
|
auto nativeText = [&]() -> rpl::producer<QString> {
|
|
if (!Platform::Notifications::Supported()
|
|
|| Core::App().notifications().nativeEnforced()) {
|
|
return rpl::producer<QString>();
|
|
} else if (Platform::IsWindows()) {
|
|
return tr::lng_settings_use_windows();
|
|
}
|
|
return tr::lng_settings_use_native_notifications();
|
|
}();
|
|
|
|
if (nativeText) {
|
|
builder.addSkip(st::settingsCheckboxesSkip);
|
|
builder.addDivider();
|
|
builder.addSkip(st::settingsCheckboxesSkip);
|
|
builder.addSubsectionTitle(tr::lng_settings_native_title());
|
|
}
|
|
|
|
const auto &settings = Core::App().settings();
|
|
const auto native = nativeText ? builder.addToggle({
|
|
.id = u"notifications/native"_q,
|
|
.title = std::move(nativeText),
|
|
.st = &st::settingsButtonNoIcon,
|
|
.toggled = rpl::single(settings.nativeNotifications()),
|
|
.keywords = { u"native"_q, u"system"_q, u"windows"_q },
|
|
}) : nullptr;
|
|
|
|
if (Core::App().notifications().nativeEnforced()) {
|
|
return;
|
|
}
|
|
if (!container || !controller) {
|
|
return;
|
|
}
|
|
|
|
const auto advancedSlide = container->add(
|
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
|
container,
|
|
object_ptr<Ui::VerticalLayout>(container)));
|
|
const auto advancedWrap = advancedSlide->entity();
|
|
|
|
if (native) {
|
|
native->toggledChanges(
|
|
) | rpl::filter([](bool checked) {
|
|
return (checked != Core::App().settings().nativeNotifications());
|
|
}) | rpl::on_next([=](bool checked) {
|
|
Core::App().settings().setNativeNotifications(checked);
|
|
Core::App().saveSettingsDelayed();
|
|
Core::App().notifications().createManager();
|
|
advancedSlide->toggle(!checked, anim::type::normal);
|
|
}, native->lifetime());
|
|
}
|
|
|
|
if (Platform::IsWindows()) {
|
|
const auto skipInFocus = advancedWrap->add(object_ptr<Ui::SettingsButton>(
|
|
advancedWrap,
|
|
tr::lng_settings_skip_in_focus(),
|
|
st::settingsButtonNoIcon
|
|
))->toggleOn(rpl::single(Core::App().settings().skipToastsInFocus()));
|
|
|
|
skipInFocus->toggledChanges(
|
|
) | rpl::filter([](bool checked) {
|
|
return (checked != Core::App().settings().skipToastsInFocus());
|
|
}) | rpl::on_next([=](bool checked) {
|
|
Core::App().settings().setSkipToastsInFocus(checked);
|
|
Core::App().saveSettingsDelayed();
|
|
if (checked && Platform::Notifications::SkipToastForCustom()) {
|
|
Core::App().notifications().notifySettingsChanged(
|
|
ChangeType::DesktopEnabled);
|
|
}
|
|
}, skipInFocus->lifetime());
|
|
}
|
|
|
|
const auto screens = QGuiApplication::screens();
|
|
if (screens.size() > 1) {
|
|
Ui::AddSkip(advancedWrap, st::settingsCheckboxesSkip);
|
|
Ui::AddDivider(advancedWrap);
|
|
Ui::AddSkip(advancedWrap, st::settingsCheckboxesSkip);
|
|
Ui::AddSubsectionTitle(
|
|
advancedWrap,
|
|
tr::lng_settings_notifications_display());
|
|
|
|
const auto currentChecksum
|
|
= Core::App().settings().notificationsDisplayChecksum();
|
|
auto currentIndex = (currentChecksum == 0)
|
|
? kDefaultDisplayIndex
|
|
: 0;
|
|
for (auto i = 0; i < screens.size(); ++i) {
|
|
if (Platform::ScreenNameChecksum(screens[i]) == currentChecksum) {
|
|
currentIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
const auto group = std::make_shared<Ui::RadiobuttonGroup>(
|
|
currentIndex);
|
|
|
|
advancedWrap->add(
|
|
object_ptr<Ui::Radiobutton>(
|
|
advancedWrap,
|
|
group,
|
|
kDefaultDisplayIndex,
|
|
tr::lng_settings_notifications_display_default(tr::now),
|
|
st::settingsSendType),
|
|
st::settingsSendTypePadding);
|
|
|
|
for (auto i = 0; i < screens.size(); ++i) {
|
|
const auto &screen = screens[i];
|
|
const auto name = Platform::ScreenDisplayLabel(screen);
|
|
const auto geometry = screen->geometry();
|
|
const auto resolution = QString::number(geometry.width())
|
|
+ QChar(0x00D7)
|
|
+ QString::number(geometry.height());
|
|
const auto label = name.isEmpty()
|
|
? QString("Display (%1)").arg(resolution)
|
|
: QString("%1 (%2)").arg(name).arg(resolution);
|
|
advancedWrap->add(
|
|
object_ptr<Ui::Radiobutton>(
|
|
advancedWrap,
|
|
group,
|
|
i,
|
|
label,
|
|
st::settingsSendType),
|
|
st::settingsSendTypePadding);
|
|
}
|
|
group->setChangedCallback([=](int selectedIndex) {
|
|
if (selectedIndex == kDefaultDisplayIndex) {
|
|
Core::App().settings().setNotificationsDisplayChecksum(0);
|
|
Core::App().saveSettings();
|
|
Core::App().notifications().notifySettingsChanged(
|
|
ChangeType::Corner);
|
|
} else {
|
|
const auto screens = QGuiApplication::screens();
|
|
if (selectedIndex >= 0 && selectedIndex < screens.size()) {
|
|
const auto checksum = Platform::ScreenNameChecksum(
|
|
screens[selectedIndex]);
|
|
Core::App().settings().setNotificationsDisplayChecksum(
|
|
checksum);
|
|
Core::App().saveSettings();
|
|
Core::App().notifications().notifySettingsChanged(
|
|
ChangeType::Corner);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
Ui::AddSkip(advancedWrap, st::settingsCheckboxesSkip);
|
|
Ui::AddDivider(advancedWrap);
|
|
Ui::AddSkip(advancedWrap, st::settingsCheckboxesSkip);
|
|
Ui::AddSubsectionTitle(
|
|
advancedWrap,
|
|
tr::lng_settings_notifications_position());
|
|
Ui::AddSkip(advancedWrap, st::settingsCheckboxesSkip);
|
|
|
|
const auto position = advancedWrap->add(
|
|
object_ptr<NotificationsCount>(advancedWrap, controller));
|
|
|
|
Ui::AddSkip(advancedWrap, st::settingsCheckboxesSkip);
|
|
Ui::AddSubsectionTitle(advancedWrap, tr::lng_settings_notifications_count());
|
|
|
|
const auto countSlider = advancedWrap->add(
|
|
object_ptr<Ui::SettingsSlider>(advancedWrap, st::settingsSlider),
|
|
st::settingsBigScalePadding);
|
|
for (int i = 0; i != kMaxNotificationsCount; ++i) {
|
|
countSlider->addSection(QString::number(i + 1));
|
|
}
|
|
countSlider->setActiveSectionFast(CurrentNotificationsCount() - 1);
|
|
countSlider->sectionActivated(
|
|
) | rpl::on_next([=](int section) {
|
|
position->setCount(section + 1);
|
|
}, countSlider->lifetime());
|
|
Ui::AddSkip(advancedWrap, st::settingsCheckboxesSkip);
|
|
|
|
if (Core::App().settings().nativeNotifications()) {
|
|
advancedSlide->hide(anim::type::instant);
|
|
}
|
|
|
|
Core::App().notifications().settingsChanged(
|
|
) | rpl::on_next([=](ChangeType change) {
|
|
if (change == ChangeType::DesktopEnabled) {
|
|
const auto native = Core::App().settings().nativeNotifications();
|
|
advancedSlide->toggle(!native, anim::type::normal);
|
|
}
|
|
}, advancedSlide->lifetime());
|
|
}
|
|
|
|
void BuildNotificationsSectionContent(
|
|
SectionBuilder &builder,
|
|
Window::SessionController *controller) {
|
|
const auto container = builder.container();
|
|
|
|
builder.addSkip(st::settingsPrivacySkip);
|
|
|
|
BuildMultiAccountSection(builder, controller);
|
|
BuildGlobalNotificationsSection(builder, controller);
|
|
|
|
if (container && controller) {
|
|
BuildNotifyViewSection(builder, controller, container->lifetime());
|
|
}
|
|
|
|
BuildNotifyTypeSection(builder, controller);
|
|
BuildEventNotificationsSection(builder, controller);
|
|
BuildCallNotificationsSection(builder, controller);
|
|
BuildBadgeCounterSection(builder, controller);
|
|
BuildSystemIntegrationAndAdvancedSection(builder, controller);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void NotificationsSection(
|
|
not_null<Ui::VerticalLayout*> container,
|
|
not_null<Window::SessionController*> controller,
|
|
Fn<void(Type)> showOther,
|
|
rpl::producer<> showFinished) {
|
|
auto &lifetime = container->lifetime();
|
|
const auto highlights = lifetime.make_state<HighlightRegistry>();
|
|
const auto isPaused = Window::PausedIn(
|
|
controller,
|
|
Window::GifPauseReason::Layer);
|
|
auto builder = SectionBuilder(WidgetContext{
|
|
.container = container,
|
|
.controller = controller,
|
|
.showOther = std::move(showOther),
|
|
.isPaused = isPaused,
|
|
.highlights = highlights,
|
|
});
|
|
BuildNotificationsSectionContent(builder, controller);
|
|
|
|
std::move(showFinished) | rpl::on_next([=] {
|
|
for (const auto &[id, entry] : *highlights) {
|
|
if (entry.widget) {
|
|
auto args = entry.args;
|
|
controller->checkHighlightControl(id, entry.widget, std::move(args));
|
|
}
|
|
}
|
|
}, lifetime);
|
|
}
|
|
|
|
std::vector<SearchEntry> NotificationsSectionForSearch() {
|
|
auto entries = std::vector<SearchEntry>();
|
|
auto builder = SectionBuilder(SearchContext{
|
|
.entries = &entries,
|
|
});
|
|
BuildNotificationsSectionContent(builder, nullptr);
|
|
return entries;
|
|
}
|
|
|
|
} // namespace Settings::Builder
|