diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 5a96cf55a..227794612 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1313,7 +1313,7 @@ notificationSettingsScopeChannelChats = NotificationSettingsScope; //@use_default_show_preview If true, show_preview is ignored and the value for the relevant type of chat or the forum chat is used instead //@show_preview True, if message content must be displayed in notifications //@use_default_mute_stories If true, mute_stories is ignored and the value for the relevant type of chat is used instead -//@mute_stories True, if story notifications are received without sound +//@mute_stories True, if story notifications are disabled for the chat //@use_default_story_sound If true, the value for the relevant type of chat is used instead of story_sound_id //@story_sound_id Identifier of the notification sound to be played for stories; 0 if sound is disabled //@use_default_show_story_sender If true, show_story_sender is ignored and the value for the relevant type of chat is used instead @@ -1328,8 +1328,8 @@ chatNotificationSettings use_default_mute_for:Bool mute_for:int32 use_default_so //@mute_for Time left before notifications will be unmuted, in seconds //@sound_id Identifier of the notification sound to be played; 0 if sound is disabled //@show_preview True, if message content must be displayed in notifications -//@use_default_mute_stories If true, mute_stories is ignored and stories are unmuted only for the first 5 chats from topChatCategoryUsers -//@mute_stories True, if story notifications are received without sound +//@use_default_mute_stories If true, mute_stories is ignored and story notifications are received only for the first 5 chats from topChatCategoryUsers +//@mute_stories True, if story notifications are disabled for the chat //@story_sound_id Identifier of the notification sound to be played for stories; 0 if sound is disabled //@show_story_sender True, if the sender of stories must be displayed in notifications //@disable_pinned_message_notifications True, if notifications for incoming pinned messages will be created as for an ordinary unread message diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 664e7d88a..82d04e6da 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -72,6 +72,7 @@ #include "td/telegram/TdDb.h" #include "td/telegram/telegram_api.h" #include "td/telegram/TopDialogCategory.h" +#include "td/telegram/TopDialogManager.h" #include "td/telegram/TranslationManager.h" #include "td/telegram/UpdatesManager.h" #include "td/telegram/Version.h" @@ -20836,7 +20837,8 @@ std::pair MessagesManager::get_dialog_mute_until(DialogId dialog_id int64 MessagesManager::get_dialog_notification_ringtone_id(DialogId dialog_id, const Dialog *d) const { CHECK(!td_->auth_manager_->is_bot()); - if (d == nullptr || !d->notification_settings.is_synchronized || d->notification_settings.use_default_mute_until) { + if (d == nullptr || !d->notification_settings.is_synchronized || + is_notification_sound_default(d->notification_settings.sound)) { auto scope = get_dialog_notification_setting_scope(dialog_id); return get_notification_sound_ringtone_id(td_->notification_settings_manager_->get_scope_notification_sound(scope)); } @@ -20860,6 +20862,47 @@ NotificationSettingsScope MessagesManager::get_dialog_notification_setting_scope } } +StoryNotificationSettings MessagesManager::get_story_notification_settings(DialogId dialog_id) { + bool need_dialog_settings = false; + bool need_top_dialogs = false; + bool are_muted = false; + bool hide_sender = false; + int64 ringtone_id = 0; + + const Dialog *d = get_dialog_force(dialog_id, "get_story_notification_settings"); + if (d == nullptr || !d->notification_settings.is_synchronized) { + need_dialog_settings = true; + } + auto scope = get_dialog_notification_setting_scope(dialog_id); + if (need_dialog_settings || d->notification_settings.use_default_mute_stories) { + bool use_default; + std::tie(use_default, are_muted) = td_->notification_settings_manager_->get_scope_mute_stories(scope); + if (use_default) { + auto is_top_dialog = td_->top_dialog_manager_->is_top_dialog(TopDialogCategory::Correspondent, 5, dialog_id); + if (is_top_dialog == -1) { + need_top_dialogs = true; + } else { + are_muted = is_top_dialog != 0; + } + } + } else { + are_muted = d->notification_settings.mute_stories; + } + if (need_dialog_settings || d->notification_settings.use_default_hide_story_sender) { + hide_sender = td_->notification_settings_manager_->get_scope_hide_story_sender(scope); + } else { + hide_sender = d->notification_settings.hide_story_sender; + } + if (need_dialog_settings || is_notification_sound_default(d->notification_settings.story_sound)) { + ringtone_id = get_notification_sound_ringtone_id( + td_->notification_settings_manager_->get_scope_story_notification_sound(scope)); + } else { + ringtone_id = get_notification_sound_ringtone_id(d->notification_settings.story_sound); + } + + return {need_dialog_settings, need_top_dialogs, are_muted, hide_sender, ringtone_id}; +} + vector MessagesManager::get_dialog_notification_settings_exceptions(NotificationSettingsScope scope, bool filter_scope, bool compare_sound, bool force, Promise &&promise) { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 4b08167ba..49e2a9677 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -65,6 +65,7 @@ #include "td/telegram/SecretInputMedia.h" #include "td/telegram/ServerMessageId.h" #include "td/telegram/StoryFullId.h" +#include "td/telegram/StoryNotificationSettings.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" @@ -753,6 +754,8 @@ class MessagesManager final : public Actor { void click_animated_emoji_message(FullMessageId full_message_id, Promise> &&promise); + StoryNotificationSettings get_story_notification_settings(DialogId dialog_id); + vector get_dialog_notification_settings_exceptions(NotificationSettingsScope scope, bool filter_scope, bool compare_sound, bool force, Promise &&promise); diff --git a/td/telegram/NotificationSettingsManager.cpp b/td/telegram/NotificationSettingsManager.cpp index 8416d1003..3801c1eda 100644 --- a/td/telegram/NotificationSettingsManager.cpp +++ b/td/telegram/NotificationSettingsManager.cpp @@ -628,15 +628,29 @@ int32 NotificationSettingsManager::get_scope_mute_until(NotificationSettingsScop return get_scope_notification_settings(scope)->mute_until; } +std::pair NotificationSettingsManager::get_scope_mute_stories(NotificationSettingsScope scope) const { + auto *settings = get_scope_notification_settings(scope); + return {settings->use_default_mute_stories, settings->mute_stories}; +} + const unique_ptr &NotificationSettingsManager::get_scope_notification_sound( NotificationSettingsScope scope) const { return get_scope_notification_settings(scope)->sound; } +const unique_ptr &NotificationSettingsManager::get_scope_story_notification_sound( + NotificationSettingsScope scope) const { + return get_scope_notification_settings(scope)->story_sound; +} + bool NotificationSettingsManager::get_scope_show_preview(NotificationSettingsScope scope) const { return get_scope_notification_settings(scope)->show_preview; } +bool NotificationSettingsManager::get_scope_hide_story_sender(NotificationSettingsScope scope) const { + return get_scope_notification_settings(scope)->hide_story_sender; +} + bool NotificationSettingsManager::get_scope_disable_pinned_message_notifications( NotificationSettingsScope scope) const { return get_scope_notification_settings(scope)->disable_pinned_message_notifications; diff --git a/td/telegram/NotificationSettingsManager.h b/td/telegram/NotificationSettingsManager.h index 0cfeaa6c7..137c370e8 100644 --- a/td/telegram/NotificationSettingsManager.h +++ b/td/telegram/NotificationSettingsManager.h @@ -26,6 +26,7 @@ #include "td/utils/Status.h" #include +#include namespace td { @@ -46,10 +47,16 @@ class NotificationSettingsManager final : public Actor { int32 get_scope_mute_until(NotificationSettingsScope scope) const; + std::pair get_scope_mute_stories(NotificationSettingsScope scope) const; + const unique_ptr &get_scope_notification_sound(NotificationSettingsScope scope) const; + const unique_ptr &get_scope_story_notification_sound(NotificationSettingsScope scope) const; + bool get_scope_show_preview(NotificationSettingsScope scope) const; + bool get_scope_hide_story_sender(NotificationSettingsScope scope) const; + bool get_scope_disable_pinned_message_notifications(NotificationSettingsScope scope) const; bool get_scope_disable_mention_notifications(NotificationSettingsScope scope) const; diff --git a/td/telegram/StoryNotificationSettings.h b/td/telegram/StoryNotificationSettings.h new file mode 100644 index 000000000..65f8d9bb4 --- /dev/null +++ b/td/telegram/StoryNotificationSettings.h @@ -0,0 +1,31 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/utils/common.h" + +namespace td { + +class StoryNotificationSettings { + public: + const bool need_dialog_settings_ = false; + const bool need_top_dialogs_ = false; + const bool are_muted_ = false; + const bool hide_sender_ = false; + const int64 ringtone_id_ = 0; + + StoryNotificationSettings(bool need_dialog_settings, bool need_top_dialogs, bool are_muted, bool hide_sender, + int64 ringtone_id) + : need_dialog_settings_(need_dialog_settings) + , need_top_dialogs_(need_top_dialogs) + , are_muted_(are_muted) + , hide_sender_(hide_sender) + , ringtone_id_(ringtone_id) { + } +}; + +} // namespace td diff --git a/td/telegram/TopDialogManager.cpp b/td/telegram/TopDialogManager.cpp index 99b29de15..8dad3d92f 100644 --- a/td/telegram/TopDialogManager.cpp +++ b/td/telegram/TopDialogManager.cpp @@ -292,6 +292,29 @@ void TopDialogManager::get_top_dialogs(TopDialogCategory category, int32 limit, loop(); } +int TopDialogManager::is_top_dialog(TopDialogCategory category, size_t limit, DialogId dialog_id) const { + CHECK(category != TopDialogCategory::Size); + CHECK(category != TopDialogCategory::ForwardUsers); + CHECK(limit > 0); + if (!is_active_) { + return -1; + } + if (!is_enabled_) { + return 0; + } + + vector dialog_ids; + auto pos = static_cast(category); + CHECK(pos < by_category_.size()); + const auto &dialogs = by_category_[pos].dialogs; + for (size_t i = 0; i < limit && i < dialogs.size(); i++) { + if (dialogs[i].dialog_id == dialog_id) { + return 1; + } + } + return is_synchronized_ ? 0 : -1; +} + void TopDialogManager::update_rating_e_decay() { if (!is_active_) { return; @@ -456,6 +479,7 @@ void TopDialogManager::on_get_top_peers(Result> &&promise); + int is_top_dialog(TopDialogCategory category, size_t limit, DialogId dialog_id) const; + void update_rating_e_decay(); void update_is_enabled(bool is_enabled); @@ -52,6 +54,7 @@ class TopDialogManager final : public Actor { bool is_active_ = false; bool is_enabled_ = true; + bool is_synchronized_ = false; int32 rating_e_decay_ = 241920; bool have_toggle_top_peers_query_ = false;