parent
175f3d7a38
commit
728b1efb9a
|
@ -715,23 +715,16 @@ void NotificationData::notificationReplied(
|
|||
|
||||
} // namespace
|
||||
|
||||
bool SkipAudio() {
|
||||
return Inhibited();
|
||||
}
|
||||
|
||||
bool SkipToast() {
|
||||
// Do not skip native notifications because of Do not disturb.
|
||||
// They respect this setting anyway.
|
||||
if ((Core::App().settings().nativeNotifications() && Supported())
|
||||
|| Enforced()) {
|
||||
bool SkipAudioForCustom() {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Inhibited();
|
||||
}
|
||||
|
||||
bool SkipFlashBounce() {
|
||||
return Inhibited();
|
||||
bool SkipToastForCustom() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkipFlashBounceForCustom() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Supported() {
|
||||
|
@ -1030,5 +1023,17 @@ void Manager::doClearFromSession(not_null<Main::Session*> session) {
|
|||
_private->clearFromSession(session);
|
||||
}
|
||||
|
||||
bool Manager::doSkipAudio() const {
|
||||
return Inhibited();
|
||||
}
|
||||
|
||||
bool Manager::doSkipToast() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Manager::doSkipFlashBounce() const {
|
||||
return Inhibited();
|
||||
}
|
||||
|
||||
} // namespace Notifications
|
||||
} // namespace Platform
|
||||
|
|
|
@ -34,6 +34,9 @@ protected:
|
|||
void doClearAllFast() override;
|
||||
void doClearFromHistory(not_null<History*> history) override;
|
||||
void doClearFromSession(not_null<Main::Session*> session) override;
|
||||
bool doSkipAudio() const override;
|
||||
bool doSkipToast() const override;
|
||||
bool doSkipFlashBounce() const override;
|
||||
|
||||
private:
|
||||
class Private;
|
||||
|
|
|
@ -32,6 +32,9 @@ protected:
|
|||
void doClearFromHistory(not_null<History*> history) override;
|
||||
void doClearFromSession(not_null<Main::Session*> session) override;
|
||||
QString accountNameSeparator() override;
|
||||
bool doSkipAudio() const override;
|
||||
bool doSkipToast() const override;
|
||||
bool doSkipFlashBounce() const override;
|
||||
|
||||
private:
|
||||
class Private;
|
||||
|
|
|
@ -140,23 +140,16 @@ using Manager = Platform::Notifications::Manager;
|
|||
namespace Platform {
|
||||
namespace Notifications {
|
||||
|
||||
bool SkipAudio() {
|
||||
queryDoNotDisturbState();
|
||||
return DoNotDisturbEnabled;
|
||||
}
|
||||
|
||||
bool SkipToast() {
|
||||
if (Supported()) {
|
||||
// Do not skip native notifications because of Do not disturb.
|
||||
// They respect this setting anyway.
|
||||
bool SkipAudioForCustom() {
|
||||
return false;
|
||||
}
|
||||
queryDoNotDisturbState();
|
||||
return DoNotDisturbEnabled;
|
||||
}
|
||||
|
||||
bool SkipFlashBounce() {
|
||||
return SkipAudio();
|
||||
bool SkipToastForCustom() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkipFlashBounceForCustom() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Supported() {
|
||||
|
@ -438,5 +431,18 @@ QString Manager::accountNameSeparator() {
|
|||
return QString::fromUtf8(" \xE2\x86\x92 ");
|
||||
}
|
||||
|
||||
bool Manager::doSkipAudio() const {
|
||||
queryDoNotDisturbState();
|
||||
return DoNotDisturbEnabled;
|
||||
}
|
||||
|
||||
bool Manager::doSkipToast() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Manager::doSkipFlashBounce() const {
|
||||
return doSkipAudio();
|
||||
}
|
||||
|
||||
} // namespace Notifications
|
||||
} // namespace Platform
|
||||
|
|
|
@ -12,9 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace Platform {
|
||||
namespace Notifications {
|
||||
|
||||
[[nodiscard]] bool SkipAudio();
|
||||
[[nodiscard]] bool SkipToast();
|
||||
[[nodiscard]] bool SkipFlashBounce();
|
||||
[[nodiscard]] bool SkipAudioForCustom();
|
||||
[[nodiscard]] bool SkipToastForCustom();
|
||||
[[nodiscard]] bool SkipFlashBounceForCustom();
|
||||
|
||||
[[nodiscard]] bool Supported();
|
||||
[[nodiscard]] bool Enforced();
|
||||
|
|
|
@ -257,9 +257,188 @@ void Check() {
|
|||
InitSucceeded = init();
|
||||
}
|
||||
|
||||
bool QuietHoursEnabled = false;
|
||||
DWORD QuietHoursValue = 0;
|
||||
|
||||
[[nodiscard]] bool UseQuietHoursRegistryEntry() {
|
||||
static const bool result = [] {
|
||||
// Taken from QSysInfo.
|
||||
OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0,{ '\0' } };
|
||||
if (const auto library = GetModuleHandle(L"ntdll.dll")) {
|
||||
using RtlGetVersionFunction = NTSTATUS(NTAPI*)(LPOSVERSIONINFO);
|
||||
const auto RtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(
|
||||
GetProcAddress(library, "RtlGetVersion"));
|
||||
if (RtlGetVersion) {
|
||||
RtlGetVersion(&result);
|
||||
}
|
||||
}
|
||||
// At build 17134 (Redstone 4) the "Quiet hours" was replaced
|
||||
// by "Focus assist" and it looks like it doesn't use registry.
|
||||
return (result.dwMajorVersion == 10
|
||||
&& result.dwMinorVersion == 0
|
||||
&& result.dwBuildNumber < 17134);
|
||||
}();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Thanks https://stackoverflow.com/questions/35600128/get-windows-quiet-hours-from-win32-or-c-sharp-api
|
||||
void QueryQuietHours() {
|
||||
if (!UseQuietHoursRegistryEntry()) {
|
||||
// There are quiet hours in Windows starting from Windows 8.1
|
||||
// But there were several reports about the notifications being shut
|
||||
// down according to the registry while no quiet hours were enabled.
|
||||
// So we try this method only starting with Windows 10.
|
||||
return;
|
||||
}
|
||||
|
||||
LPCWSTR lpKeyName = L"Software\\Microsoft\\Windows\\CurrentVersion\\Notifications\\Settings";
|
||||
LPCWSTR lpValueName = L"NOC_GLOBAL_SETTING_TOASTS_ENABLED";
|
||||
HKEY key;
|
||||
auto result = RegOpenKeyEx(HKEY_CURRENT_USER, lpKeyName, 0, KEY_READ, &key);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD value = 0, type = 0, size = sizeof(value);
|
||||
result = RegQueryValueEx(key, lpValueName, 0, &type, (LPBYTE)&value, &size);
|
||||
RegCloseKey(key);
|
||||
|
||||
auto quietHoursEnabled = (result == ERROR_SUCCESS) && (value == 0);
|
||||
if (QuietHoursEnabled != quietHoursEnabled) {
|
||||
QuietHoursEnabled = quietHoursEnabled;
|
||||
QuietHoursValue = value;
|
||||
LOG(("Quiet hours changed, entry value: %1").arg(value));
|
||||
} else if (QuietHoursValue != value) {
|
||||
QuietHoursValue = value;
|
||||
LOG(("Quiet hours value changed, was value: %1, entry value: %2").arg(QuietHoursValue).arg(value));
|
||||
}
|
||||
}
|
||||
|
||||
bool FocusAssistBlocks = false;
|
||||
|
||||
// Thanks https://www.withinrafael.com/2019/09/19/determine-if-your-app-is-in-a-focus-assist-profiles-priority-list/
|
||||
void QueryFocusAssist() {
|
||||
ComPtr<IQuietHoursSettings> quietHoursSettings;
|
||||
auto hr = CoCreateInstance(
|
||||
CLSID_QuietHoursSettings,
|
||||
nullptr,
|
||||
CLSCTX_LOCAL_SERVER,
|
||||
IID_PPV_ARGS(&quietHoursSettings));
|
||||
if (!SUCCEEDED(hr) || !quietHoursSettings) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto profileId = LPWSTR{};
|
||||
const auto guardProfileId = gsl::finally([&] {
|
||||
if (profileId) CoTaskMemFree(profileId);
|
||||
});
|
||||
hr = quietHoursSettings->get_UserSelectedProfile(&profileId);
|
||||
if (!SUCCEEDED(hr) || !profileId) {
|
||||
return;
|
||||
}
|
||||
const auto profileName = QString::fromWCharArray(profileId);
|
||||
if (profileName.endsWith(".alarmsonly", Qt::CaseInsensitive)) {
|
||||
if (!FocusAssistBlocks) {
|
||||
LOG(("Focus Assist: Alarms Only."));
|
||||
FocusAssistBlocks = true;
|
||||
}
|
||||
return;
|
||||
} else if (!profileName.endsWith(".priorityonly", Qt::CaseInsensitive)) {
|
||||
if (!profileName.endsWith(".unrestricted", Qt::CaseInsensitive)) {
|
||||
LOG(("Focus Assist Warning: Unknown profile '%1'"
|
||||
).arg(profileName));
|
||||
}
|
||||
if (FocusAssistBlocks) {
|
||||
LOG(("Focus Assist: Unrestricted."));
|
||||
FocusAssistBlocks = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const auto appUserModelId = std::wstring(AppUserModelId::getId());
|
||||
auto blocked = true;
|
||||
const auto guard = gsl::finally([&] {
|
||||
if (FocusAssistBlocks != blocked) {
|
||||
LOG(("Focus Assist: %1, AppUserModelId: %2, Blocks: %3"
|
||||
).arg(profileName
|
||||
).arg(QString::fromStdWString(appUserModelId)
|
||||
).arg(Logs::b(blocked)));
|
||||
FocusAssistBlocks = blocked;
|
||||
}
|
||||
});
|
||||
|
||||
ComPtr<IQuietHoursProfile> profile;
|
||||
hr = quietHoursSettings->GetProfile(profileId, &profile);
|
||||
if (!SUCCEEDED(hr) || !profile) {
|
||||
return;
|
||||
}
|
||||
|
||||
UINT32 count = 0;
|
||||
auto apps = (LPWSTR*)nullptr;
|
||||
const auto guardApps = gsl::finally([&] {
|
||||
if (apps) CoTaskMemFree(apps);
|
||||
});
|
||||
hr = profile->GetAllowedApps(&count, &apps);
|
||||
if (!SUCCEEDED(hr) || !apps) {
|
||||
return;
|
||||
}
|
||||
for (UINT32 i = 0; i < count; i++) {
|
||||
auto app = apps[i];
|
||||
const auto guardApp = gsl::finally([&] {
|
||||
if (app) CoTaskMemFree(app);
|
||||
});
|
||||
if (app == appUserModelId) {
|
||||
blocked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QUERY_USER_NOTIFICATION_STATE UserNotificationState = QUNS_ACCEPTS_NOTIFICATIONS;
|
||||
|
||||
void QueryUserNotificationState() {
|
||||
if (Dlls::SHQueryUserNotificationState != nullptr) {
|
||||
QUERY_USER_NOTIFICATION_STATE state;
|
||||
if (SUCCEEDED(Dlls::SHQueryUserNotificationState(&state))) {
|
||||
UserNotificationState = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr auto kQuerySettingsEachMs = 1000;
|
||||
crl::time LastSettingsQueryMs = 0;
|
||||
|
||||
void QuerySystemNotificationSettings() {
|
||||
auto ms = crl::now();
|
||||
if (LastSettingsQueryMs > 0 && ms <= LastSettingsQueryMs + kQuerySettingsEachMs) {
|
||||
return;
|
||||
}
|
||||
LastSettingsQueryMs = ms;
|
||||
QueryQuietHours();
|
||||
QueryFocusAssist();
|
||||
QueryUserNotificationState();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
#endif // !__MINGW32__
|
||||
|
||||
bool SkipAudioForCustom() {
|
||||
QuerySystemNotificationSettings();
|
||||
|
||||
return (UserNotificationState == QUNS_NOT_PRESENT)
|
||||
|| (UserNotificationState == QUNS_PRESENTATION_MODE)
|
||||
|| Global::ScreenIsLocked();
|
||||
}
|
||||
|
||||
bool SkipToastForCustom() {
|
||||
QuerySystemNotificationSettings();
|
||||
|
||||
return (UserNotificationState == QUNS_PRESENTATION_MODE)
|
||||
|| (UserNotificationState == QUNS_RUNNING_D3D_FULL_SCREEN);
|
||||
}
|
||||
|
||||
bool SkipFlashBounceForCustom() {
|
||||
return SkipToastForCustom();
|
||||
}
|
||||
|
||||
bool Supported() {
|
||||
#ifndef __MINGW32__
|
||||
if (!Checked) {
|
||||
|
@ -627,201 +806,23 @@ void Manager::onAfterNotificationActivated(
|
|||
not_null<Window::SessionController*> window) {
|
||||
_private->afterNotificationActivated(id, window);
|
||||
}
|
||||
|
||||
bool Manager::doSkipAudio() const {
|
||||
return SkipAudioForCustom()
|
||||
|| QuietHoursEnabled
|
||||
|| FocusAssistBlocks;
|
||||
}
|
||||
|
||||
bool Manager::doSkipToast() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Manager::doSkipFlashBounce() const {
|
||||
return SkipFlashBounceForCustom()
|
||||
|| QuietHoursEnabled
|
||||
|| FocusAssistBlocks;
|
||||
}
|
||||
#endif // !__MINGW32__
|
||||
|
||||
namespace {
|
||||
|
||||
bool QuietHoursEnabled = false;
|
||||
DWORD QuietHoursValue = 0;
|
||||
|
||||
[[nodiscard]] bool UseQuietHoursRegistryEntry() {
|
||||
static const bool result = [] {
|
||||
// Taken from QSysInfo.
|
||||
OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0,{ '\0' } };
|
||||
if (const auto library = GetModuleHandle(L"ntdll.dll")) {
|
||||
using RtlGetVersionFunction = NTSTATUS(NTAPI*)(LPOSVERSIONINFO);
|
||||
const auto RtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(
|
||||
GetProcAddress(library, "RtlGetVersion"));
|
||||
if (RtlGetVersion) {
|
||||
RtlGetVersion(&result);
|
||||
}
|
||||
}
|
||||
// At build 17134 (Redstone 4) the "Quiet hours" was replaced
|
||||
// by "Focus assist" and it looks like it doesn't use registry.
|
||||
return (result.dwMajorVersion == 10
|
||||
&& result.dwMinorVersion == 0
|
||||
&& result.dwBuildNumber < 17134);
|
||||
}();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Thanks https://stackoverflow.com/questions/35600128/get-windows-quiet-hours-from-win32-or-c-sharp-api
|
||||
void QueryQuietHours() {
|
||||
if (!UseQuietHoursRegistryEntry()) {
|
||||
// There are quiet hours in Windows starting from Windows 8.1
|
||||
// But there were several reports about the notifications being shut
|
||||
// down according to the registry while no quiet hours were enabled.
|
||||
// So we try this method only starting with Windows 10.
|
||||
return;
|
||||
}
|
||||
|
||||
LPCWSTR lpKeyName = L"Software\\Microsoft\\Windows\\CurrentVersion\\Notifications\\Settings";
|
||||
LPCWSTR lpValueName = L"NOC_GLOBAL_SETTING_TOASTS_ENABLED";
|
||||
HKEY key;
|
||||
auto result = RegOpenKeyEx(HKEY_CURRENT_USER, lpKeyName, 0, KEY_READ, &key);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD value = 0, type = 0, size = sizeof(value);
|
||||
result = RegQueryValueEx(key, lpValueName, 0, &type, (LPBYTE)&value, &size);
|
||||
RegCloseKey(key);
|
||||
|
||||
auto quietHoursEnabled = (result == ERROR_SUCCESS) && (value == 0);
|
||||
if (QuietHoursEnabled != quietHoursEnabled) {
|
||||
QuietHoursEnabled = quietHoursEnabled;
|
||||
QuietHoursValue = value;
|
||||
LOG(("Quiet hours changed, entry value: %1").arg(value));
|
||||
} else if (QuietHoursValue != value) {
|
||||
QuietHoursValue = value;
|
||||
LOG(("Quiet hours value changed, was value: %1, entry value: %2").arg(QuietHoursValue).arg(value));
|
||||
}
|
||||
}
|
||||
|
||||
bool FocusAssistBlocks = false;
|
||||
|
||||
// Thanks https://www.withinrafael.com/2019/09/19/determine-if-your-app-is-in-a-focus-assist-profiles-priority-list/
|
||||
void QueryFocusAssist() {
|
||||
ComPtr<IQuietHoursSettings> quietHoursSettings;
|
||||
auto hr = CoCreateInstance(
|
||||
CLSID_QuietHoursSettings,
|
||||
nullptr,
|
||||
CLSCTX_LOCAL_SERVER,
|
||||
IID_PPV_ARGS(&quietHoursSettings));
|
||||
if (!SUCCEEDED(hr) || !quietHoursSettings) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto profileId = LPWSTR{};
|
||||
const auto guardProfileId = gsl::finally([&] {
|
||||
if (profileId) CoTaskMemFree(profileId);
|
||||
});
|
||||
hr = quietHoursSettings->get_UserSelectedProfile(&profileId);
|
||||
if (!SUCCEEDED(hr) || !profileId) {
|
||||
return;
|
||||
}
|
||||
const auto profileName = QString::fromWCharArray(profileId);
|
||||
if (profileName.endsWith(".alarmsonly", Qt::CaseInsensitive)) {
|
||||
if (!FocusAssistBlocks) {
|
||||
LOG(("Focus Assist: Alarms Only."));
|
||||
FocusAssistBlocks = true;
|
||||
}
|
||||
return;
|
||||
} else if (!profileName.endsWith(".priorityonly", Qt::CaseInsensitive)) {
|
||||
if (!profileName.endsWith(".unrestricted", Qt::CaseInsensitive)) {
|
||||
LOG(("Focus Assist Warning: Unknown profile '%1'"
|
||||
).arg(profileName));
|
||||
}
|
||||
if (FocusAssistBlocks) {
|
||||
LOG(("Focus Assist: Unrestricted."));
|
||||
FocusAssistBlocks = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const auto appUserModelId = std::wstring(AppUserModelId::getId());
|
||||
auto blocked = true;
|
||||
const auto guard = gsl::finally([&] {
|
||||
if (FocusAssistBlocks != blocked) {
|
||||
LOG(("Focus Assist: %1, AppUserModelId: %2, Blocks: %3"
|
||||
).arg(profileName
|
||||
).arg(QString::fromStdWString(appUserModelId)
|
||||
).arg(Logs::b(blocked)));
|
||||
FocusAssistBlocks = blocked;
|
||||
}
|
||||
});
|
||||
|
||||
ComPtr<IQuietHoursProfile> profile;
|
||||
hr = quietHoursSettings->GetProfile(profileId, &profile);
|
||||
if (!SUCCEEDED(hr) || !profile) {
|
||||
return;
|
||||
}
|
||||
|
||||
UINT32 count = 0;
|
||||
auto apps = (LPWSTR*)nullptr;
|
||||
const auto guardApps = gsl::finally([&] {
|
||||
if (apps) CoTaskMemFree(apps);
|
||||
});
|
||||
hr = profile->GetAllowedApps(&count, &apps);
|
||||
if (!SUCCEEDED(hr) || !apps) {
|
||||
return;
|
||||
}
|
||||
for (UINT32 i = 0; i < count; i++) {
|
||||
auto app = apps[i];
|
||||
const auto guardApp = gsl::finally([&] {
|
||||
if (app) CoTaskMemFree(app);
|
||||
});
|
||||
if (app == appUserModelId) {
|
||||
blocked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QUERY_USER_NOTIFICATION_STATE UserNotificationState = QUNS_ACCEPTS_NOTIFICATIONS;
|
||||
|
||||
void QueryUserNotificationState() {
|
||||
if (Dlls::SHQueryUserNotificationState != nullptr) {
|
||||
QUERY_USER_NOTIFICATION_STATE state;
|
||||
if (SUCCEEDED(Dlls::SHQueryUserNotificationState(&state))) {
|
||||
UserNotificationState = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr auto kQuerySettingsEachMs = 1000;
|
||||
crl::time LastSettingsQueryMs = 0;
|
||||
|
||||
void QuerySystemNotificationSettings() {
|
||||
auto ms = crl::now();
|
||||
if (LastSettingsQueryMs > 0 && ms <= LastSettingsQueryMs + kQuerySettingsEachMs) {
|
||||
return;
|
||||
}
|
||||
LastSettingsQueryMs = ms;
|
||||
QueryQuietHours();
|
||||
QueryFocusAssist();
|
||||
QueryUserNotificationState();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool SkipAudio() {
|
||||
QuerySystemNotificationSettings();
|
||||
|
||||
if (UserNotificationState == QUNS_NOT_PRESENT
|
||||
|| UserNotificationState == QUNS_PRESENTATION_MODE
|
||||
|| QuietHoursEnabled
|
||||
|| FocusAssistBlocks
|
||||
|| Global::ScreenIsLocked()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkipToast() {
|
||||
QuerySystemNotificationSettings();
|
||||
|
||||
if (UserNotificationState == QUNS_PRESENTATION_MODE
|
||||
|| UserNotificationState == QUNS_RUNNING_D3D_FULL_SCREEN
|
||||
//|| UserNotificationState == QUNS_BUSY
|
||||
|| QuietHoursEnabled
|
||||
|| FocusAssistBlocks) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkipFlashBounce() {
|
||||
return SkipToast();
|
||||
}
|
||||
|
||||
} // namespace Notifications
|
||||
} // namespace Platform
|
||||
|
|
|
@ -39,6 +39,9 @@ protected:
|
|||
void onAfterNotificationActivated(
|
||||
NotificationId id,
|
||||
not_null<Window::SessionController*> window) override;
|
||||
bool doSkipAudio() const override;
|
||||
bool doSkipToast() const override;
|
||||
bool doSkipFlashBounce() const override;
|
||||
|
||||
private:
|
||||
class Private;
|
||||
|
|
|
@ -138,6 +138,8 @@ System::SkipState System::skipNotification(
|
|||
}
|
||||
|
||||
void System::schedule(not_null<HistoryItem*> item) {
|
||||
Expects(_manager != nullptr);
|
||||
|
||||
const auto history = item->history();
|
||||
const auto skip = skipNotification(item);
|
||||
if (skip.value == SkipState::Skip) {
|
||||
|
@ -167,7 +169,7 @@ void System::schedule(not_null<HistoryItem*> item) {
|
|||
_whenAlerts[history].emplace(when, notifyBy);
|
||||
}
|
||||
if (Core::App().settings().desktopNotify()
|
||||
&& !Platform::Notifications::SkipToast()) {
|
||||
&& !_manager->skipToast()) {
|
||||
auto &whenMap = _whenMaps[history];
|
||||
if (whenMap.find(item->id) == whenMap.end()) {
|
||||
whenMap.emplace(item->id, when);
|
||||
|
@ -391,7 +393,7 @@ void System::showNext() {
|
|||
}
|
||||
const auto &settings = Core::App().settings();
|
||||
if (alert) {
|
||||
if (settings.flashBounceNotify() && !Platform::Notifications::SkipFlashBounce()) {
|
||||
if (settings.flashBounceNotify() && !_manager->skipFlashBounce()) {
|
||||
if (const auto window = Core::App().activeWindow()) {
|
||||
if (const auto handle = window->widget()->windowHandle()) {
|
||||
handle->alert(kSystemAlertDuration);
|
||||
|
@ -399,7 +401,7 @@ void System::showNext() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (settings.soundNotify() && !Platform::Notifications::SkipAudio()) {
|
||||
if (settings.soundNotify() && !_manager->skipAudio()) {
|
||||
ensureSoundCreated();
|
||||
_soundTrack->playOnce();
|
||||
Media::Player::mixer()->suppressAll(_soundTrack->getLengthMs());
|
||||
|
@ -407,7 +409,7 @@ void System::showNext() {
|
|||
}
|
||||
}
|
||||
|
||||
if (_waiters.empty() || !settings.desktopNotify() || Platform::Notifications::SkipToast()) {
|
||||
if (_waiters.empty() || !settings.desktopNotify() || _manager->skipToast()) {
|
||||
if (nextAlert) {
|
||||
_waitTimer.callOnce(nextAlert - ms);
|
||||
}
|
||||
|
|
|
@ -202,6 +202,16 @@ public:
|
|||
|
||||
[[nodiscard]] virtual ManagerType type() const = 0;
|
||||
|
||||
[[nodiscard]] bool skipAudio() const {
|
||||
return doSkipAudio();
|
||||
}
|
||||
[[nodiscard]] bool skipToast() const {
|
||||
return doSkipToast();
|
||||
}
|
||||
[[nodiscard]] bool skipFlashBounce() const {
|
||||
return doSkipFlashBounce();
|
||||
}
|
||||
|
||||
virtual ~Manager() = default;
|
||||
|
||||
protected:
|
||||
|
@ -218,6 +228,9 @@ protected:
|
|||
virtual void doClearFromItem(not_null<HistoryItem*> item) = 0;
|
||||
virtual void doClearFromHistory(not_null<History*> history) = 0;
|
||||
virtual void doClearFromSession(not_null<Main::Session*> session) = 0;
|
||||
virtual bool doSkipAudio() const = 0;
|
||||
virtual bool doSkipToast() const = 0;
|
||||
virtual bool doSkipFlashBounce() const = 0;
|
||||
[[nodiscard]] virtual bool forceHideDetails() const {
|
||||
return false;
|
||||
}
|
||||
|
@ -298,6 +311,15 @@ protected:
|
|||
}
|
||||
void doClearFromSession(not_null<Main::Session*> session) override {
|
||||
}
|
||||
bool doSkipAudio() const {
|
||||
return false;
|
||||
}
|
||||
bool doSkipToast() const {
|
||||
return false;
|
||||
}
|
||||
bool doSkipFlashBounce() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -404,6 +404,18 @@ void Manager::doClearFromItem(not_null<HistoryItem*> item) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Manager::doSkipAudio() const {
|
||||
return Platform::Notifications::SkipAudioForCustom();
|
||||
}
|
||||
|
||||
bool Manager::doSkipToast() const {
|
||||
return Platform::Notifications::SkipToastForCustom();
|
||||
}
|
||||
|
||||
bool Manager::doSkipFlashBounce() const {
|
||||
return Platform::Notifications::SkipFlashBounceForCustom();
|
||||
}
|
||||
|
||||
void Manager::doUpdateAll() {
|
||||
for_const (auto ¬ification, _notifications) {
|
||||
notification->updateNotifyDisplay();
|
||||
|
|
|
@ -76,6 +76,9 @@ private:
|
|||
void doClearFromHistory(not_null<History*> history) override;
|
||||
void doClearFromSession(not_null<Main::Session*> session) override;
|
||||
void doClearFromItem(not_null<HistoryItem*> item) override;
|
||||
bool doSkipAudio() const;
|
||||
bool doSkipToast() const;
|
||||
bool doSkipFlashBounce() const;
|
||||
|
||||
void showNextFromQueue();
|
||||
void unlinkFromShown(Notification *remove);
|
||||
|
|
Loading…
Reference in New Issue