Support file reference repair for notification sounds.

This commit is contained in:
levlam 2022-04-15 16:27:30 +03:00
parent ff50eec3ee
commit 77532d67f8
5 changed files with 107 additions and 21 deletions

View File

@ -13,6 +13,7 @@
#include "td/telegram/files/FileManager.h"
#include "td/telegram/Global.h"
#include "td/telegram/MessagesManager.h"
#include "td/telegram/NotificationSettingsManager.h"
#include "td/telegram/StickerSetId.h"
#include "td/telegram/StickersManager.h"
#include "td/telegram/Td.h"
@ -60,6 +61,7 @@ fileSourceBackground background_id:int64 access_hash:int64 = FileSource; // repa
fileSourceBasicGroupFull basic_group_id:int32 = FileSource; // repaired with messages.getFullChat
fileSourceSupergroupFull supergroup_id:int32 = FileSource; // repaired with messages.getFullChannel
fileSourceAppConfig = FileSource; // repaired with help.getAppConfig, not reliable
fileSourceSavedRingtones = FileSource; // repaired with account.getSavedRingtones
*/
FileSourceId FileReferenceManager::get_current_file_source_id() const {
@ -131,6 +133,11 @@ bool FileReferenceManager::add_file_source(NodeId node_id, FileSourceId file_sou
return is_added;
}
FileSourceId FileReferenceManager::create_saved_ringtones_file_source() {
FileSourceSavedRingtones source;
return add_file_source_id(source, "saved notification sounds");
}
bool FileReferenceManager::remove_file_source(NodeId node_id, FileSourceId file_source_id) {
CHECK(node_id.is_valid());
bool is_removed = nodes_[node_id].file_source_ids.remove(file_source_id);
@ -305,6 +312,10 @@ void FileReferenceManager::send_query(Destination dest, FileSourceId file_source
},
[&](const FileSourceAppConfig &source) {
send_closure_later(G()->config_manager(), &ConfigManager::reget_app_config, std::move(promise));
},
[&](const FileSourceSavedRingtones &source) {
send_closure_later(G()->notification_settings_manager(), &NotificationSettingsManager::repair_saved_ringtones,
std::move(promise));
}));
}

View File

@ -52,6 +52,7 @@ class FileReferenceManager final : public Actor {
FileSourceId create_chat_full_file_source(ChatId chat_id);
FileSourceId create_channel_full_file_source(ChannelId channel_id);
FileSourceId create_app_config_file_source();
FileSourceId create_saved_ringtones_file_source();
using NodeId = FileId;
void repair_file_reference(NodeId node_id, Promise<> promise);
@ -144,12 +145,15 @@ class FileReferenceManager final : public Actor {
struct FileSourceAppConfig {
// empty
};
struct FileSourceSavedRingtones {
// empty
};
// append only
using FileSource =
Variant<FileSourceMessage, FileSourceUserPhoto, FileSourceChatPhoto, FileSourceChannelPhoto, FileSourceWallpapers,
FileSourceWebPage, FileSourceSavedAnimations, FileSourceRecentStickers, FileSourceFavoriteStickers,
FileSourceBackground, FileSourceChatFull, FileSourceChannelFull, FileSourceAppConfig>;
using FileSource = Variant<FileSourceMessage, FileSourceUserPhoto, FileSourceChatPhoto, FileSourceChannelPhoto,
FileSourceWallpapers, FileSourceWebPage, FileSourceSavedAnimations,
FileSourceRecentStickers, FileSourceFavoriteStickers, FileSourceBackground,
FileSourceChatFull, FileSourceChannelFull, FileSourceAppConfig, FileSourceSavedRingtones>;
vector<FileSource> file_sources_;
int64 query_generation_{0};

View File

@ -15,6 +15,7 @@
#include "td/telegram/files/FileSourceId.h"
#include "td/telegram/FullMessageId.h"
#include "td/telegram/MessagesManager.h"
#include "td/telegram/NotificationSettingsManager.h"
#include "td/telegram/StickersManager.h"
#include "td/telegram/Td.h"
#include "td/telegram/UserId.h"
@ -50,7 +51,7 @@ void FileReferenceManager::store_file_source(FileSourceId file_source_id, Storer
},
[&](const FileSourceChatFull &source) { td::store(source.chat_id, storer); },
[&](const FileSourceChannelFull &source) { td::store(source.channel_id, storer); },
[&](const FileSourceAppConfig &source) {}));
[&](const FileSourceAppConfig &source) {}, [&](const FileSourceSavedRingtones &source) {}));
}
template <class ParserT>
@ -114,6 +115,8 @@ FileSourceId FileReferenceManager::parse_file_source(Td *td, ParserT &parser) {
}
case 12:
return td->stickers_manager_->get_app_config_file_source_id();
case 13:
return td->notification_settings_manager_->get_saved_ringtones_file_source_id();
default:
parser.set_error("Invalid type in FileSource");
return FileSourceId();

View File

@ -53,7 +53,7 @@ class UploadRingtoneQuery final : public Td::ResultHandler {
file_id_ = file_id;
send_query(G()->net_query_creator().create(
telegram_api::account_uploadRingtone(std::move(input_file), file_name, mime_type)));
telegram_api::account_uploadRingtone(std::move(input_file), file_name, mime_type), {{"ringtone"}}));
}
void on_result(BufferSlice packet) final {
@ -1052,6 +1052,7 @@ void NotificationSettingsManager::on_remove_saved_ringtone(int64 ringtone_id, Pr
CHECK(file_view.has_remote_location());
if (file_view.remote_location().get_id() == ringtone_id) {
saved_ringtone_file_ids_.erase(it);
on_saved_ringtones_updated(false);
break;
}
}
@ -1078,38 +1079,64 @@ Result<FileId> NotificationSettingsManager::get_ringtone(
void NotificationSettingsManager::reload_saved_ringtones(Promise<Unit> &&promise) {
if (!is_active()) {
return;
return promise.set_error(Status::Error(400, "Don't need to reload saved notification sounds"));
}
reload_saved_ringtone_queries_.push_back(std::move(promise));
if (reload_saved_ringtone_queries_.size() == 1) {
reload_saved_ringtones_queries_.push_back(std::move(promise));
if (reload_saved_ringtones_queries_.size() == 1) {
auto query_promise = PromiseCreator::lambda(
[actor_id = actor_id(this)](Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result) {
send_closure(actor_id, &NotificationSettingsManager::on_reload_saved_ringtones, std::move(result));
send_closure(actor_id, &NotificationSettingsManager::on_reload_saved_ringtones, false, std::move(result));
});
td_->create_handler<GetSavedRingtonesQuery>(std::move(query_promise))->send(saved_ringtone_hash_);
}
}
void NotificationSettingsManager::repair_saved_ringtones(Promise<Unit> &&promise) {
if (!is_active()) {
return promise.set_error(Status::Error(400, "Don't need to repair saved notification sounds"));
}
repair_saved_ringtones_queries_.push_back(std::move(promise));
if (repair_saved_ringtones_queries_.size() == 1u) {
auto query_promise = PromiseCreator::lambda(
[actor_id = actor_id(this)](Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result) {
send_closure(actor_id, &NotificationSettingsManager::on_reload_saved_ringtones, true, std::move(result));
});
td_->create_handler<GetSavedRingtonesQuery>(std::move(query_promise))->send(0);
}
}
void NotificationSettingsManager::on_reload_saved_ringtones(
Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result) {
bool is_repair, Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result) {
if (!is_active()) {
are_saved_ringtones_loaded_ = true;
set_promises(reload_saved_ringtone_queries_);
set_promises(reload_saved_ringtones_queries_);
set_promises(repair_saved_ringtones_queries_);
return;
}
if (result.is_error()) {
fail_promises(reload_saved_ringtone_queries_, result.move_as_error());
set_timeout_in(Random::fast(60, 120));
if (is_repair) {
fail_promises(repair_saved_ringtones_queries_, result.move_as_error());
} else {
fail_promises(reload_saved_ringtones_queries_, result.move_as_error());
set_timeout_in(Random::fast(60, 120));
}
return;
}
set_timeout_in(Random::fast(3600, 4800));
if (!is_repair) {
set_timeout_in(Random::fast(3600, 4800));
}
auto saved_ringtones_ptr = result.move_as_ok();
auto constructor_id = saved_ringtones_ptr->get_id();
if (constructor_id == telegram_api::account_savedRingtonesNotModified::ID) {
are_saved_ringtones_loaded_ = true;
set_promises(reload_saved_ringtone_queries_);
if (is_repair) {
fail_promises(repair_saved_ringtones_queries_, Status::Error(500, "Failed to repair saved animations"));
} else {
are_saved_ringtones_loaded_ = true;
set_promises(reload_saved_ringtones_queries_);
}
return;
}
CHECK(constructor_id == telegram_api::account_savedRingtones::ID);
@ -1130,12 +1157,42 @@ void NotificationSettingsManager::on_reload_saved_ringtones(
}
bool need_update = new_saved_ringtone_file_ids != saved_ringtone_file_ids_;
are_saved_ringtones_loaded_ = true;
if (need_update || saved_ringtone_hash_ != new_hash) {
saved_ringtone_hash_ = new_hash;
saved_ringtone_file_ids_ = std::move(new_saved_ringtone_file_ids);
if (need_update) {
on_saved_ringtones_updated(false);
}
}
are_saved_ringtones_loaded_ = true;
set_promises(reload_saved_ringtone_queries_);
if (is_repair) {
set_promises(repair_saved_ringtones_queries_);
} else {
set_promises(reload_saved_ringtones_queries_);
}
}
void NotificationSettingsManager::on_saved_ringtones_updated(bool from_database) {
CHECK(are_saved_ringtones_loaded_);
vector<FileId> new_sorted_saved_ringtone_file_ids = saved_ringtone_file_ids_;
std::sort(new_sorted_saved_ringtone_file_ids.begin(), new_sorted_saved_ringtone_file_ids.end());
if (new_sorted_saved_ringtone_file_ids != sorted_saved_ringtone_file_ids_) {
td_->file_manager_->change_files_source(get_saved_ringtones_file_source_id(), sorted_saved_ringtone_file_ids_,
new_sorted_saved_ringtone_file_ids);
sorted_saved_ringtone_file_ids_ = std::move(new_sorted_saved_ringtone_file_ids);
}
if (!from_database) {
// save_saved_ringtones_to_database();
}
}
FileSourceId NotificationSettingsManager::get_saved_ringtones_file_source_id() {
if (!saved_ringtones_file_source_id_.is_valid()) {
saved_ringtones_file_source_id_ = td_->file_reference_manager_->create_saved_ringtones_file_source();
}
return saved_ringtones_file_source_id_;
}
void NotificationSettingsManager::send_get_dialog_notification_settings_query(DialogId dialog_id,

View File

@ -8,6 +8,7 @@
#include "td/telegram/DialogId.h"
#include "td/telegram/files/FileId.h"
#include "td/telegram/files/FileSourceId.h"
#include "td/telegram/NotificationSettings.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
@ -59,6 +60,10 @@ class NotificationSettingsManager final : public Actor {
void reload_saved_ringtones(Promise<Unit> &&promise);
void repair_saved_ringtones(Promise<Unit> &&promise);
FileSourceId get_saved_ringtones_file_source_id();
void send_save_ringtone_query(FileId ringtone_file_id, bool unsave,
Promise<telegram_api::object_ptr<telegram_api::account_SavedRingtone>> &&promise);
@ -125,7 +130,10 @@ class NotificationSettingsManager final : public Actor {
void on_remove_saved_ringtone(int64 ringtone_id, Promise<Unit> &&promise);
void on_reload_saved_ringtones(Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result);
void on_reload_saved_ringtones(bool is_repair,
Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result);
void on_saved_ringtones_updated(bool from_database);
ScopeNotificationSettings *get_scope_notification_settings(NotificationSettingsScope scope);
@ -167,6 +175,8 @@ class NotificationSettingsManager final : public Actor {
int64 saved_ringtone_hash_ = 0;
vector<FileId> saved_ringtone_file_ids_;
vector<FileId> sorted_saved_ringtone_file_ids_;
FileSourceId saved_ringtones_file_source_id_;
std::shared_ptr<UploadRingtoneCallback> upload_ringtone_callback_;
@ -180,7 +190,8 @@ class NotificationSettingsManager final : public Actor {
};
FlatHashMap<FileId, UploadedRingtone, FileIdHash> being_uploaded_ringtones_;
vector<Promise<Unit>> reload_saved_ringtone_queries_;
vector<Promise<Unit>> reload_saved_ringtones_queries_;
vector<Promise<Unit>> repair_saved_ringtones_queries_;
FlatHashMap<DialogId, vector<Promise<Unit>>, DialogIdHash> get_dialog_notification_settings_queries_;
};