Skip to content

Commit eef401c

Browse files
committed
Save and load saved notification sounds.
1 parent 6b23333 commit eef401c

File tree

2 files changed

+100
-7
lines changed

2 files changed

+100
-7
lines changed

td/telegram/NotificationSettingsManager.cpp

Lines changed: 90 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "td/telegram/AccessRights.h"
1010
#include "td/telegram/AudiosManager.h"
11+
#include "td/telegram/AudiosManager.hpp"
1112
#include "td/telegram/AuthManager.h"
1213
#include "td/telegram/ConfigShared.h"
1314
#include "td/telegram/ContactsManager.h"
@@ -460,6 +461,39 @@ class NotificationSettingsManager::UploadRingtoneCallback final : public FileMan
460461
}
461462
};
462463

464+
class NotificationSettingsManager::RingtoneListLogEvent {
465+
public:
466+
int64 hash_;
467+
vector<FileId> ringtone_file_ids_;
468+
469+
RingtoneListLogEvent() = default;
470+
471+
RingtoneListLogEvent(int64 hash, vector<FileId> ringtone_file_ids)
472+
: hash_(hash), ringtone_file_ids_(std::move(ringtone_file_ids)) {
473+
}
474+
475+
template <class StorerT>
476+
void store(StorerT &storer) const {
477+
td::store(hash_, storer);
478+
AudiosManager *audios_manager = storer.context()->td().get_actor_unsafe()->audios_manager_.get();
479+
td::store(narrow_cast<int32>(ringtone_file_ids_.size()), storer);
480+
for (auto ringtone_file_id : ringtone_file_ids_) {
481+
audios_manager->store_audio(ringtone_file_id, storer);
482+
}
483+
}
484+
485+
template <class ParserT>
486+
void parse(ParserT &parser) {
487+
td::parse(hash_, parser);
488+
AudiosManager *audios_manager = parser.context()->td().get_actor_unsafe()->audios_manager_.get();
489+
int32 size = parser.fetch_int();
490+
ringtone_file_ids_.resize(size);
491+
for (auto &ringtone_file_id : ringtone_file_ids_) {
492+
ringtone_file_id = audios_manager->parse_audio(parser);
493+
}
494+
}
495+
};
496+
463497
NotificationSettingsManager::NotificationSettingsManager(Td *td, ActorShared<> parent)
464498
: td_(td), parent_(std::move(parent)) {
465499
upload_ringtone_callback_ = std::make_shared<UploadRingtoneCallback>();
@@ -761,7 +795,7 @@ bool NotificationSettingsManager::is_active() const {
761795

762796
FileId NotificationSettingsManager::get_saved_ringtone(int64 ringtone_id, Promise<Unit> &&promise) {
763797
if (!are_saved_ringtones_loaded_) {
764-
reload_saved_ringtones(std::move(promise));
798+
load_saved_ringtones(std::move(promise));
765799
return {};
766800
}
767801

@@ -780,7 +814,7 @@ FileId NotificationSettingsManager::get_saved_ringtone(int64 ringtone_id, Promis
780814

781815
vector<FileId> NotificationSettingsManager::get_saved_ringtones(Promise<Unit> &&promise) {
782816
if (!are_saved_ringtones_loaded_) {
783-
reload_saved_ringtones(std::move(promise));
817+
load_saved_ringtones(std::move(promise));
784818
return {};
785819
}
786820

@@ -808,8 +842,8 @@ void NotificationSettingsManager::add_saved_ringtone(td_api::object_ptr<td_api::
808842
TRY_STATUS_PROMISE(promise, G()->close_status());
809843

810844
if (!are_saved_ringtones_loaded_) {
811-
reload_saved_ringtones(PromiseCreator::lambda([actor_id = actor_id(this), input_file = std::move(input_file),
812-
promise = std::move(promise)](Result<Unit> &&result) mutable {
845+
load_saved_ringtones(PromiseCreator::lambda([actor_id = actor_id(this), input_file = std::move(input_file),
846+
promise = std::move(promise)](Result<Unit> &&result) mutable {
813847
if (result.is_error()) {
814848
return promise.set_error(result.move_as_error());
815849
}
@@ -1017,7 +1051,7 @@ void NotificationSettingsManager::on_add_saved_ringtone(
10171051

10181052
void NotificationSettingsManager::remove_saved_ringtone(int64 ringtone_id, Promise<Unit> &&promise) {
10191053
if (!are_saved_ringtones_loaded_) {
1020-
reload_saved_ringtones(std::move(promise));
1054+
load_saved_ringtones(std::move(promise));
10211055
return;
10221056
}
10231057

@@ -1093,12 +1127,51 @@ Result<FileId> NotificationSettingsManager::get_ringtone(
10931127
return parsed_document.file_id;
10941128
}
10951129

1130+
void NotificationSettingsManager::load_saved_ringtones(Promise<Unit> &&promise) {
1131+
CHECK(!are_saved_ringtones_loaded_);
1132+
auto saved_ringtones_string = G()->td_db()->get_binlog_pmc()->get(get_saved_ringtones_database_key());
1133+
if (saved_ringtones_string.empty()) {
1134+
return reload_saved_ringtones(std::move(promise));
1135+
}
1136+
1137+
RingtoneListLogEvent saved_ringtones_log_event;
1138+
bool is_valid = log_event_parse(saved_ringtones_log_event, saved_ringtones_string).is_ok();
1139+
1140+
for (auto &ringtone_file_id : saved_ringtones_log_event.ringtone_file_ids_) {
1141+
if (!ringtone_file_id.is_valid()) {
1142+
is_valid = false;
1143+
break;
1144+
}
1145+
}
1146+
if (is_valid) {
1147+
saved_ringtone_hash_ = saved_ringtones_log_event.hash_;
1148+
saved_ringtone_file_ids_ = std::move(saved_ringtones_log_event.ringtone_file_ids_);
1149+
are_saved_ringtones_loaded_ = true;
1150+
1151+
if (!saved_ringtone_file_ids_.empty()) {
1152+
on_saved_ringtones_updated(true);
1153+
}
1154+
1155+
// the promis must not be set synchronously
1156+
send_closure_later(actor_id(this), &NotificationSettingsManager::on_load_saved_ringtones, std::move(promise));
1157+
reload_saved_ringtones(Auto());
1158+
} else {
1159+
LOG(ERROR) << "Ignore invalid saved notification sounds log event";
1160+
reload_saved_ringtones(std::move(promise));
1161+
}
1162+
}
1163+
1164+
void NotificationSettingsManager::on_load_saved_ringtones(Promise<Unit> &&promise) {
1165+
promise.set_value(Unit());
1166+
}
1167+
10961168
void NotificationSettingsManager::reload_saved_ringtones(Promise<Unit> &&promise) {
10971169
if (!is_active()) {
10981170
return promise.set_error(Status::Error(400, "Don't need to reload saved notification sounds"));
10991171
}
11001172
reload_saved_ringtones_queries_.push_back(std::move(promise));
11011173
if (reload_saved_ringtones_queries_.size() == 1) {
1174+
are_saved_ringtones_reloaded_ = true;
11021175
auto query_promise = PromiseCreator::lambda(
11031176
[actor_id = actor_id(this)](Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result) {
11041177
send_closure(actor_id, &NotificationSettingsManager::on_reload_saved_ringtones, false, std::move(result));
@@ -1114,6 +1187,7 @@ void NotificationSettingsManager::repair_saved_ringtones(Promise<Unit> &&promise
11141187

11151188
repair_saved_ringtones_queries_.push_back(std::move(promise));
11161189
if (repair_saved_ringtones_queries_.size() == 1u) {
1190+
are_saved_ringtones_reloaded_ = true;
11171191
auto query_promise = PromiseCreator::lambda(
11181192
[actor_id = actor_id(this)](Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result) {
11191193
send_closure(actor_id, &NotificationSettingsManager::on_reload_saved_ringtones, true, std::move(result));
@@ -1201,6 +1275,16 @@ NotificationSettingsManager::get_update_saved_notification_sounds_object() const
12011275
return td_api::make_object<td_api::updateSavedNotificationSounds>(std::move(ringtone_ids));
12021276
}
12031277

1278+
string NotificationSettingsManager::get_saved_ringtones_database_key() {
1279+
return "ringtones";
1280+
}
1281+
1282+
void NotificationSettingsManager::save_saved_ringtones_to_database() const {
1283+
RingtoneListLogEvent ringtone_list_log_event{saved_ringtone_hash_, saved_ringtone_file_ids_};
1284+
G()->td_db()->get_binlog_pmc()->set(get_saved_ringtones_database_key(),
1285+
log_event_store(ringtone_list_log_event).as_slice().str());
1286+
}
1287+
12041288
void NotificationSettingsManager::on_saved_ringtones_updated(bool from_database) {
12051289
CHECK(are_saved_ringtones_loaded_);
12061290
vector<FileId> new_sorted_saved_ringtone_file_ids = saved_ringtone_file_ids_;
@@ -1212,7 +1296,7 @@ void NotificationSettingsManager::on_saved_ringtones_updated(bool from_database)
12121296
}
12131297

12141298
if (!from_database) {
1215-
// save_saved_ringtones_to_database();
1299+
save_saved_ringtones_to_database();
12161300
}
12171301

12181302
send_closure(G()->td(), &Td::send_update, get_update_saved_notification_sounds_object());
@@ -1365,7 +1449,6 @@ void NotificationSettingsManager::after_get_difference() {
13651449
}
13661450

13671451
if (td_->is_online() && !are_saved_ringtones_reloaded_) {
1368-
are_saved_ringtones_reloaded_ = true;
13691452
reload_saved_ringtones(Auto());
13701453
}
13711454
}

td/telegram/NotificationSettingsManager.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class NotificationSettingsManager final : public Actor {
102102
private:
103103
class UpdateScopeNotificationSettingsOnServerLogEvent;
104104

105+
class RingtoneListLogEvent;
106+
105107
class UploadRingtoneCallback;
106108

107109
void start_up() final;
@@ -135,6 +137,14 @@ class NotificationSettingsManager final : public Actor {
135137
void on_reload_saved_ringtones(bool is_repair,
136138
Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result);
137139

140+
static string get_saved_ringtones_database_key();
141+
142+
void load_saved_ringtones(Promise<Unit> &&promise);
143+
144+
void on_load_saved_ringtones(Promise<Unit> &&promise);
145+
146+
void save_saved_ringtones_to_database() const;
147+
138148
void on_saved_ringtones_updated(bool from_database);
139149

140150
ScopeNotificationSettings *get_scope_notification_settings(NotificationSettingsScope scope);

0 commit comments

Comments
 (0)