Send to NotificationManager notifications about new/edited messages.
GitOrigin-RevId: 79647054a22e1376c8a69da180ba293300468ed6
This commit is contained in:
parent
4240b785a0
commit
0ca9b6493d
@ -3447,7 +3447,7 @@ setLogVerbosityLevel new_verbosity_level:int32 = Ok;
|
||||
//@description Returns current verbosity level of the internal logging of TDLib. This is an offline method. Can be called before authorization. Can be called synchronously
|
||||
getLogVerbosityLevel = LogVerbosityLevel;
|
||||
|
||||
//@description Returns list of available TDLib internal log tags. Currently returns ["td_init", "update_file", "connections", "binlog", "proxy", "net_query", "td_requests", "dc", "files", "mtproto", "raw_mtproto", "fd", "actor", "buffer", "sqlite"]
|
||||
//@description Returns list of available TDLib internal log tags. Currently returns ["td_init", "update_file", "connections", "binlog", "proxy", "net_query", "td_requests", "dc", "files", "mtproto", "raw_mtproto", "fd", "actor", "buffer", "sqlite", "notifications"]
|
||||
getLogTags = LogTags;
|
||||
|
||||
//@description Sets the verbosity level for a specified TDLib internal log tag. This is an offline method. Can be called before authorization. Can be called synchronously
|
||||
|
@ -42,6 +42,7 @@ class LanguagePackManager;
|
||||
class MessagesManager;
|
||||
class MtprotoHeader;
|
||||
class NetQueryDispatcher;
|
||||
class NotificationManager;
|
||||
class PasswordManager;
|
||||
class SecretChatsManager;
|
||||
class StateManager;
|
||||
@ -189,6 +190,13 @@ class Global : public ActorContext {
|
||||
messages_manager_ = messages_manager;
|
||||
}
|
||||
|
||||
ActorId<NotificationManager> notification_manager() const {
|
||||
return notification_manager_;
|
||||
}
|
||||
void set_notification_manager(ActorId<NotificationManager> notification_manager) {
|
||||
notification_manager_ = notification_manager;
|
||||
}
|
||||
|
||||
ActorId<PasswordManager> password_manager() const {
|
||||
return password_manager_;
|
||||
}
|
||||
@ -333,6 +341,7 @@ class Global : public ActorContext {
|
||||
ActorId<FileManager> file_manager_;
|
||||
ActorId<LanguagePackManager> language_pack_manager_;
|
||||
ActorId<MessagesManager> messages_manager_;
|
||||
ActorId<NotificationManager> notification_manager_;
|
||||
ActorId<PasswordManager> password_manager_;
|
||||
ActorId<SecretChatsManager> secret_chats_manager_;
|
||||
ActorId<StickersManager> stickers_manager_;
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "td/telegram/files/FileManager.h"
|
||||
#include "td/telegram/net/ConnectionCreator.h"
|
||||
#include "td/telegram/NotificationManager.h"
|
||||
#include "td/telegram/Td.h"
|
||||
|
||||
#include "tddb/td/db/binlog/BinlogEvent.h"
|
||||
@ -31,9 +32,10 @@ static NullLog null_log;
|
||||
#define ADD_TAG(tag) \
|
||||
{ #tag, &VERBOSITY_NAME(tag) }
|
||||
static const std::unordered_map<Slice, int *, SliceHash> log_tags{
|
||||
ADD_TAG(td_init), ADD_TAG(update_file), ADD_TAG(connections), ADD_TAG(binlog), ADD_TAG(proxy),
|
||||
ADD_TAG(net_query), ADD_TAG(td_requests), ADD_TAG(dc), ADD_TAG(files), ADD_TAG(mtproto),
|
||||
ADD_TAG(raw_mtproto), ADD_TAG(fd), ADD_TAG(actor), ADD_TAG(buffer), ADD_TAG(sqlite)};
|
||||
ADD_TAG(td_init), ADD_TAG(update_file), ADD_TAG(connections), ADD_TAG(binlog),
|
||||
ADD_TAG(proxy), ADD_TAG(net_query), ADD_TAG(td_requests), ADD_TAG(dc),
|
||||
ADD_TAG(files), ADD_TAG(mtproto), ADD_TAG(raw_mtproto), ADD_TAG(fd),
|
||||
ADD_TAG(actor), ADD_TAG(buffer), ADD_TAG(sqlite), ADD_TAG(notifications)};
|
||||
#undef ADD_TAG
|
||||
|
||||
Status Logging::set_current_stream(td_api::object_ptr<td_api::LogStream> stream) {
|
||||
|
@ -29,7 +29,9 @@
|
||||
#include "td/telegram/net/DcId.h"
|
||||
#include "td/telegram/net/NetActor.h"
|
||||
#include "td/telegram/net/NetQuery.h"
|
||||
#include "td/telegram/NotificationManager.h"
|
||||
#include "td/telegram/NotificationSettings.hpp"
|
||||
#include "td/telegram/NotificationType.h"
|
||||
#include "td/telegram/Payments.h"
|
||||
#include "td/telegram/ReplyMarkup.h"
|
||||
#include "td/telegram/ReplyMarkup.hpp"
|
||||
@ -3538,6 +3540,7 @@ void MessagesManager::Message::store(StorerT &storer) const {
|
||||
is_forwarded && (forward_info->from_dialog_id.is_valid() || forward_info->from_message_id.is_valid());
|
||||
bool has_send_date = message_id.is_yet_unsent() && send_date != 0;
|
||||
bool has_flags2 = true;
|
||||
bool has_notification_id = notification_id.is_valid();
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(is_channel_post);
|
||||
STORE_FLAG(is_outgoing);
|
||||
@ -3572,6 +3575,7 @@ void MessagesManager::Message::store(StorerT &storer) const {
|
||||
END_STORE_FLAGS();
|
||||
if (has_flags2) {
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(has_notification_id);
|
||||
END_STORE_FLAGS();
|
||||
}
|
||||
|
||||
@ -3631,6 +3635,9 @@ void MessagesManager::Message::store(StorerT &storer) const {
|
||||
if (has_media_album_id) {
|
||||
store(media_album_id, storer);
|
||||
}
|
||||
if (has_notification_id) {
|
||||
store(notification_id, storer);
|
||||
}
|
||||
store_message_content(content.get(), storer);
|
||||
if (has_reply_markup) {
|
||||
store(*reply_markup, storer);
|
||||
@ -3657,6 +3664,7 @@ void MessagesManager::Message::parse(ParserT &parser) {
|
||||
bool has_forward_from;
|
||||
bool has_send_date;
|
||||
bool has_flags2;
|
||||
bool has_notification_id = false;
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(is_channel_post);
|
||||
PARSE_FLAG(is_outgoing);
|
||||
@ -3691,6 +3699,7 @@ void MessagesManager::Message::parse(ParserT &parser) {
|
||||
END_PARSE_FLAGS();
|
||||
if (has_flags2) {
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(has_notification_id);
|
||||
END_PARSE_FLAGS();
|
||||
}
|
||||
|
||||
@ -3758,6 +3767,9 @@ void MessagesManager::Message::parse(ParserT &parser) {
|
||||
if (has_media_album_id) {
|
||||
parse(media_album_id, parser);
|
||||
}
|
||||
if (has_notification_id) {
|
||||
parse(notification_id, parser);
|
||||
}
|
||||
parse_message_content(content, parser);
|
||||
if (has_reply_markup) {
|
||||
reply_markup = make_unique<ReplyMarkup>();
|
||||
@ -3788,6 +3800,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const {
|
||||
bool has_deleted_last_message = delete_last_message_date > 0;
|
||||
bool has_last_clear_history_message_id = last_clear_history_message_id.is_valid();
|
||||
bool has_last_database_message_id = !has_last_database_message && last_database_message_id.is_valid();
|
||||
bool has_message_notification_group_id = message_notification_group_id.is_valid();
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(has_draft_message);
|
||||
STORE_FLAG(has_last_database_message);
|
||||
@ -3812,6 +3825,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const {
|
||||
STORE_FLAG(has_last_database_message_id);
|
||||
STORE_FLAG(need_repair_server_unread_count);
|
||||
STORE_FLAG(is_marked_as_unread);
|
||||
STORE_FLAG(has_message_notification_group_id); // 23
|
||||
END_STORE_FLAGS();
|
||||
|
||||
store(dialog_id, storer); // must be stored at offset 4
|
||||
@ -3870,6 +3884,9 @@ void MessagesManager::Dialog::store(StorerT &storer) const {
|
||||
if (has_last_database_message_id) {
|
||||
store(last_database_message_id, storer);
|
||||
}
|
||||
if (has_message_notification_group_id) {
|
||||
store(message_notification_group_id, storer);
|
||||
}
|
||||
}
|
||||
|
||||
// do not forget to resolve dialog dependencies including dependencies of last_message
|
||||
@ -3889,6 +3906,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) {
|
||||
bool has_deleted_last_message;
|
||||
bool has_last_clear_history_message_id;
|
||||
bool has_last_database_message_id;
|
||||
bool has_message_notification_group_id;
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(has_draft_message);
|
||||
PARSE_FLAG(has_last_database_message);
|
||||
@ -3912,7 +3930,8 @@ void MessagesManager::Dialog::parse(ParserT &parser) {
|
||||
PARSE_FLAG(has_contact_registered_message);
|
||||
PARSE_FLAG(has_last_database_message_id);
|
||||
PARSE_FLAG(need_repair_server_unread_count);
|
||||
PARSE_FLAG(is_marked_as_unread); // 22
|
||||
PARSE_FLAG(is_marked_as_unread);
|
||||
PARSE_FLAG(has_message_notification_group_id);
|
||||
END_PARSE_FLAGS();
|
||||
|
||||
parse(dialog_id, parser); // must be stored at offset 4
|
||||
@ -3995,6 +4014,9 @@ void MessagesManager::Dialog::parse(ParserT &parser) {
|
||||
if (has_last_database_message_id) {
|
||||
parse(last_database_message_id, parser);
|
||||
}
|
||||
if (has_message_notification_group_id) {
|
||||
parse(message_notification_group_id, parser);
|
||||
}
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
@ -4783,8 +4805,8 @@ void MessagesManager::on_update_service_notification(tl_object_ptr<telegram_api:
|
||||
bool need_update = true;
|
||||
bool need_update_dialog_pos = false;
|
||||
|
||||
Message *m = add_message_to_dialog(d, std::move(new_message), true, &need_update, &need_update_dialog_pos,
|
||||
"on_update_service_notification");
|
||||
const Message *m = add_message_to_dialog(d, std::move(new_message), true, &need_update, &need_update_dialog_pos,
|
||||
"on_update_service_notification");
|
||||
if (m != nullptr && need_update) {
|
||||
send_update_new_message(d, m);
|
||||
}
|
||||
@ -4838,8 +4860,8 @@ void MessagesManager::on_update_contact_registered(tl_object_ptr<telegram_api::u
|
||||
bool need_update = true;
|
||||
bool need_update_dialog_pos = false;
|
||||
|
||||
Message *m = add_message_to_dialog(d, std::move(new_message), true, &need_update, &need_update_dialog_pos,
|
||||
"on_update_contact_registered");
|
||||
const Message *m = add_message_to_dialog(d, std::move(new_message), true, &need_update, &need_update_dialog_pos,
|
||||
"on_update_contact_registered");
|
||||
if (m != nullptr && need_update) {
|
||||
send_update_new_message(d, m);
|
||||
}
|
||||
@ -5553,6 +5575,11 @@ void MessagesManager::on_message_edited(FullMessageId full_message_id) {
|
||||
if (m->forward_info == nullptr && (m->is_outgoing || dialog_id == get_my_dialog_id())) {
|
||||
update_used_hashtags(dialog_id, m);
|
||||
}
|
||||
|
||||
if (m->notification_id.is_valid()) {
|
||||
send_closure_later(G()->notification_manager(), &NotificationManager::edit_notification, m->notification_id,
|
||||
create_new_message_notification(m->message_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9512,8 +9539,8 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, bool f
|
||||
new_message->have_next = true;
|
||||
}
|
||||
|
||||
Message *m = add_message_to_dialog(dialog_id, std::move(new_message), from_update, &need_update,
|
||||
&need_update_dialog_pos, source);
|
||||
const Message *m = add_message_to_dialog(dialog_id, std::move(new_message), from_update, &need_update,
|
||||
&need_update_dialog_pos, source);
|
||||
Dialog *d = get_dialog(dialog_id);
|
||||
if (m == nullptr) {
|
||||
if (need_update_dialog_pos && d != nullptr) {
|
||||
@ -17323,35 +17350,47 @@ void MessagesManager::on_dialog_updated(DialogId dialog_id, const char *source)
|
||||
}
|
||||
}
|
||||
|
||||
void MessagesManager::send_update_new_message(Dialog *d, const Message *m) {
|
||||
void MessagesManager::send_update_new_message(const Dialog *d, const Message *m) {
|
||||
CHECK(d != nullptr);
|
||||
CHECK(m != nullptr);
|
||||
|
||||
LOG(INFO) << "Send updateNewMessage for " << m->message_id << " in " << d->dialog_id;
|
||||
send_closure(G()->td(), &Td::send_update,
|
||||
make_tl_object<td_api::updateNewMessage>(get_message_object(d->dialog_id, m)));
|
||||
|
||||
add_new_message_notification(d, m, false);
|
||||
}
|
||||
|
||||
void MessagesManager::add_new_message_notification(Dialog *d, const Message *m, bool force) {
|
||||
NotificationGroupId MessagesManager::get_dialog_message_notification_group_id(Dialog *d) {
|
||||
if (!d->message_notification_group_id.is_valid()) {
|
||||
d->message_notification_group_id = td_->notification_manager_->get_next_notification_group_id();
|
||||
VLOG(notifications) << "Assign " << d->message_notification_group_id << " to " << d->dialog_id;
|
||||
on_dialog_updated(d->dialog_id, "get_dialog_message_notification_group_id");
|
||||
}
|
||||
|
||||
CHECK(d->message_notification_group_id.is_valid());
|
||||
return d->message_notification_group_id;
|
||||
}
|
||||
|
||||
void MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool force) {
|
||||
CHECK(d != nullptr);
|
||||
CHECK(m != nullptr);
|
||||
|
||||
if (m->disable_notification || m->is_outgoing || d->dialog_id == get_my_dialog_id() || td_->auth_manager_->is_bot()) {
|
||||
CHECK(!m->notification_id.is_valid());
|
||||
if (m->is_outgoing || d->dialog_id == get_my_dialog_id() || td_->auth_manager_->is_bot()) {
|
||||
return;
|
||||
}
|
||||
if (m->message_id.get() <= d->last_read_inbox_message_id.get()) {
|
||||
LOG(INFO) << "Disable notification for read " << m->message_id << " in " << d->dialog_id;
|
||||
VLOG(notifications) << "Disable notification for read " << m->message_id << " in " << d->dialog_id;
|
||||
return;
|
||||
}
|
||||
if (d->dialog_id.get_type() == DialogType::Channel &&
|
||||
!td_->contacts_manager_->get_channel_status(d->dialog_id.get_channel_id()).is_member()) {
|
||||
return;
|
||||
if (d->dialog_id.get_type() == DialogType::Channel) {
|
||||
if (!td_->contacts_manager_->get_channel_status(d->dialog_id.get_channel_id()).is_member() ||
|
||||
m->date < td_->contacts_manager_->get_channel_date(d->dialog_id.get_channel_id())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LOG(INFO) << "Trying to " << (force ? "forcely " : "") << "add new message notification for " << m->message_id
|
||||
<< " in " << d->dialog_id;
|
||||
VLOG(notifications) << "Trying to " << (force ? "forcely " : "") << "add new message notification for "
|
||||
<< m->message_id << " in " << d->dialog_id;
|
||||
|
||||
DialogId settings_dialog_id = d->dialog_id;
|
||||
Dialog *settings_dialog = d;
|
||||
@ -17365,6 +17404,7 @@ void MessagesManager::add_new_message_notification(Dialog *d, const Message *m,
|
||||
int32 mute_until;
|
||||
std::tie(have_settings, mute_until) = get_dialog_mute_until(settings_dialog_id, settings_dialog);
|
||||
if (mute_until > G()->unix_time()) {
|
||||
VLOG(notifications) << "Disable notification, because " << settings_dialog_id << " is muted";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -17375,14 +17415,15 @@ void MessagesManager::add_new_message_notification(Dialog *d, const Message *m,
|
||||
create_actor<SleepActor>(
|
||||
"FlushPendingNewMessageNotificationsSleepActor", 5.0,
|
||||
PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = d->dialog_id](Result<Unit> result) {
|
||||
LOG(INFO) << "Flush pending notifications in " << dialog_id << " by timeout";
|
||||
VLOG(notifications) << "Flush pending notifications in " << dialog_id << " by timeout";
|
||||
send_closure(actor_id, &MessagesManager::flush_pending_new_message_notifications, dialog_id);
|
||||
}))
|
||||
.release();
|
||||
}
|
||||
d->pending_new_message_notifications.push_back(m->message_id);
|
||||
auto promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = d->dialog_id](Result<Unit> result) {
|
||||
LOG(INFO) << "Flush pending notifications in " << dialog_id << " because of received notification settings";
|
||||
VLOG(notifications) << "Flush pending notifications in " << dialog_id
|
||||
<< " because of received notification settings";
|
||||
send_closure(actor_id, &MessagesManager::flush_pending_new_message_notifications, dialog_id);
|
||||
});
|
||||
if (settings_dialog == nullptr && have_input_peer(settings_dialog_id, AccessRights::Read)) {
|
||||
@ -17400,7 +17441,11 @@ void MessagesManager::add_new_message_notification(Dialog *d, const Message *m,
|
||||
LOG_IF(WARNING, !have_settings) << "Have no notification settings for " << settings_dialog_id
|
||||
<< ", but forced to send notification about " << m->message_id << " in "
|
||||
<< d->dialog_id;
|
||||
// TODO
|
||||
m->notification_id = td_->notification_manager_->get_next_notification_id();
|
||||
VLOG(notifications) << "Assign " << m->notification_id << " to " << m->message_id << " in " << d->dialog_id;
|
||||
send_closure_later(G()->notification_manager(), &NotificationManager::add_notification,
|
||||
get_dialog_message_notification_group_id(d), d->dialog_id, settings_dialog_id,
|
||||
m->disable_notification, m->notification_id, create_new_message_notification(m->message_id));
|
||||
}
|
||||
|
||||
void MessagesManager::flush_pending_new_message_notifications(DialogId dialog_id) {
|
||||
@ -19892,46 +19937,49 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
|
||||
cancel_user_dialog_action(dialog_id, message.get());
|
||||
}
|
||||
|
||||
unique_ptr<Message> *v = &d->messages;
|
||||
while (*v != nullptr && (*v)->random_y >= message->random_y) {
|
||||
if ((*v)->message_id.get() < message_id.get()) {
|
||||
v = &(*v)->right;
|
||||
} else if ((*v)->message_id == message_id) {
|
||||
LOG(INFO) << "Adding already existing " << message_id << " in " << dialog_id << " from " << source;
|
||||
if (*need_update) {
|
||||
*need_update = false;
|
||||
if (!G()->parameters().use_message_db) {
|
||||
LOG(ERROR) << "Receive again " << (message->is_outgoing ? "outgoing" : "incoming")
|
||||
<< (message->forward_info == nullptr ? " not" : "") << " forwarded " << message_id
|
||||
<< " with content of type " << message_content_type << " in " << dialog_id << " from " << source
|
||||
<< ", current last new is " << d->last_new_message_id << ", last is " << d->last_message_id << ". "
|
||||
<< td_->updates_manager_->get_state();
|
||||
dump_debug_message_op(d, 1);
|
||||
{
|
||||
// TODO function
|
||||
unique_ptr<Message> *v = &d->messages;
|
||||
while (*v != nullptr && (*v)->random_y >= message->random_y) {
|
||||
if ((*v)->message_id.get() < message_id.get()) {
|
||||
v = &(*v)->right;
|
||||
} else if ((*v)->message_id == message_id) {
|
||||
LOG(INFO) << "Adding already existing " << message_id << " in " << dialog_id << " from " << source;
|
||||
if (*need_update) {
|
||||
*need_update = false;
|
||||
if (!G()->parameters().use_message_db) {
|
||||
LOG(ERROR) << "Receive again " << (message->is_outgoing ? "outgoing" : "incoming")
|
||||
<< (message->forward_info == nullptr ? " not" : "") << " forwarded " << message_id
|
||||
<< " with content of type " << message_content_type << " in " << dialog_id << " from " << source
|
||||
<< ", current last new is " << d->last_new_message_id << ", last is " << d->last_message_id
|
||||
<< ". " << td_->updates_manager_->get_state();
|
||||
dump_debug_message_op(d, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (auto_attach) {
|
||||
CHECK(message->have_previous);
|
||||
CHECK(message->have_next);
|
||||
message->have_previous = false;
|
||||
message->have_next = false;
|
||||
}
|
||||
if (!message->from_database) {
|
||||
const int32 INDEX_MASK_MASK = ~search_messages_filter_index_mask(SearchMessagesFilter::UnreadMention);
|
||||
auto old_index_mask = get_message_index_mask(dialog_id, v->get()) & INDEX_MASK_MASK;
|
||||
bool was_deleted = delete_active_live_location(dialog_id, v->get());
|
||||
update_message(d, *v, std::move(message), true, need_update_dialog_pos);
|
||||
auto new_index_mask = get_message_index_mask(dialog_id, v->get()) & INDEX_MASK_MASK;
|
||||
if (was_deleted) {
|
||||
try_add_active_live_location(dialog_id, v->get());
|
||||
if (auto_attach) {
|
||||
CHECK(message->have_previous);
|
||||
CHECK(message->have_next);
|
||||
message->have_previous = false;
|
||||
message->have_next = false;
|
||||
}
|
||||
if (old_index_mask != new_index_mask) {
|
||||
update_message_count_by_index(d, -1, old_index_mask & ~new_index_mask);
|
||||
update_message_count_by_index(d, +1, new_index_mask & ~old_index_mask);
|
||||
if (!message->from_database) {
|
||||
const int32 INDEX_MASK_MASK = ~search_messages_filter_index_mask(SearchMessagesFilter::UnreadMention);
|
||||
auto old_index_mask = get_message_index_mask(dialog_id, v->get()) & INDEX_MASK_MASK;
|
||||
bool was_deleted = delete_active_live_location(dialog_id, v->get());
|
||||
update_message(d, *v, std::move(message), true, need_update_dialog_pos);
|
||||
auto new_index_mask = get_message_index_mask(dialog_id, v->get()) & INDEX_MASK_MASK;
|
||||
if (was_deleted) {
|
||||
try_add_active_live_location(dialog_id, v->get());
|
||||
}
|
||||
if (old_index_mask != new_index_mask) {
|
||||
update_message_count_by_index(d, -1, old_index_mask & ~new_index_mask);
|
||||
update_message_count_by_index(d, +1, new_index_mask & ~old_index_mask);
|
||||
}
|
||||
}
|
||||
return v->get();
|
||||
} else {
|
||||
v = &(*v)->left;
|
||||
}
|
||||
return v->get();
|
||||
} else {
|
||||
v = &(*v)->left;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20151,11 +20199,17 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!message->from_database && !message_id.is_yet_unsent()) {
|
||||
add_message_to_database(d, message.get(), "add_message_to_dialog");
|
||||
|
||||
if (*need_update) {
|
||||
add_new_message_notification(d, message.get(), false);
|
||||
}
|
||||
|
||||
if (!is_attached && !message->have_next && !message->have_previous) {
|
||||
const Message *m = message.get();
|
||||
if (!m->from_database && !message_id.is_yet_unsent()) {
|
||||
add_message_to_database(d, m, "add_message_to_dialog");
|
||||
}
|
||||
|
||||
if (!is_attached && !m->have_next && !m->have_previous) {
|
||||
MessagesIterator it(d, message_id);
|
||||
if (*it != nullptr && (*it)->have_next) {
|
||||
// need to drop a connection between messages
|
||||
@ -20181,7 +20235,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
|
||||
}
|
||||
|
||||
if (!td_->auth_manager_->is_bot() && from_update && d->reply_markup_message_id != MessageId()) {
|
||||
auto deleted_user_id = get_message_content_deleted_user_id(message->content.get());
|
||||
auto deleted_user_id = get_message_content_deleted_user_id(m->content.get());
|
||||
if (deleted_user_id.is_valid() && td_->contacts_manager_->is_user_bot(deleted_user_id)) {
|
||||
const Message *old_message = get_message_force(d, d->reply_markup_message_id);
|
||||
if (old_message == nullptr || old_message->sender_user_id == deleted_user_id) {
|
||||
@ -20196,40 +20250,40 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
|
||||
}
|
||||
|
||||
if (from_update && message_id.is_server() && dialog_id.get_type() == DialogType::Channel) {
|
||||
int32 new_participant_count = get_message_content_new_participant_count(message->content.get());
|
||||
int32 new_participant_count = get_message_content_new_participant_count(m->content.get());
|
||||
if (new_participant_count != 0) {
|
||||
td_->contacts_manager_->speculative_add_channel_participants(dialog_id.get_channel_id(), new_participant_count,
|
||||
message->sender_user_id == my_user_id);
|
||||
m->sender_user_id == my_user_id);
|
||||
}
|
||||
auto pinned_message_id = get_message_content_pinned_message_id(message->content.get());
|
||||
auto pinned_message_id = get_message_content_pinned_message_id(m->content.get());
|
||||
if (pinned_message_id.is_valid()) {
|
||||
td_->contacts_manager_->on_update_channel_pinned_message(dialog_id.get_channel_id(), pinned_message_id);
|
||||
}
|
||||
}
|
||||
if (!td_->auth_manager_->is_bot() && from_update && message->forward_info == nullptr &&
|
||||
(message->is_outgoing || dialog_id == my_dialog_id)) {
|
||||
if (!td_->auth_manager_->is_bot() && from_update && m->forward_info == nullptr &&
|
||||
(m->is_outgoing || dialog_id == my_dialog_id)) {
|
||||
switch (message_content_type) {
|
||||
case MessageContentType::Animation:
|
||||
if (dialog_id.get_type() != DialogType::SecretChat) {
|
||||
td_->animations_manager_->add_saved_animation_by_id(get_message_content_file_id(message->content.get()));
|
||||
td_->animations_manager_->add_saved_animation_by_id(get_message_content_file_id(m->content.get()));
|
||||
}
|
||||
break;
|
||||
case MessageContentType::Sticker:
|
||||
if (dialog_id.get_type() != DialogType::SecretChat) {
|
||||
td_->stickers_manager_->add_recent_sticker_by_id(false, get_message_content_file_id(message->content.get()));
|
||||
td_->stickers_manager_->add_recent_sticker_by_id(false, get_message_content_file_id(m->content.get()));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
update_used_hashtags(dialog_id, message.get());
|
||||
update_used_hashtags(dialog_id, m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!td_->auth_manager_->is_bot() && from_update && message_id.is_server() &&
|
||||
(message->is_outgoing || dialog_id == my_dialog_id) && dialog_id.get_type() != DialogType::SecretChat) {
|
||||
if (message->via_bot_user_id.is_valid() && message->forward_info == nullptr) {
|
||||
(m->is_outgoing || dialog_id == my_dialog_id) && dialog_id.get_type() != DialogType::SecretChat) {
|
||||
if (m->via_bot_user_id.is_valid() && m->forward_info == nullptr) {
|
||||
// forwarded game messages can't be distinguished from sent via bot game messages, so increase rating anyway
|
||||
send_closure(G()->top_dialog_manager(), &TopDialogManager::on_dialog_used, TopDialogCategory::BotInline,
|
||||
DialogId(message->via_bot_user_id), message->date);
|
||||
DialogId(m->via_bot_user_id), m->date);
|
||||
}
|
||||
|
||||
TopDialogCategory category = TopDialogCategory::Size;
|
||||
@ -20266,48 +20320,52 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (category != TopDialogCategory::Size) {
|
||||
send_closure(G()->top_dialog_manager(), &TopDialogManager::on_dialog_used, category, dialog_id, message->date);
|
||||
send_closure(G()->top_dialog_manager(), &TopDialogManager::on_dialog_used, category, dialog_id, m->date);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO function
|
||||
v = &d->messages;
|
||||
while (*v != nullptr && (*v)->random_y >= message->random_y) {
|
||||
if ((*v)->message_id.get() < message_id.get()) {
|
||||
v = &(*v)->right;
|
||||
} else if ((*v)->message_id == message_id) {
|
||||
UNREACHABLE();
|
||||
} else {
|
||||
v = &(*v)->left;
|
||||
Message *result_message = nullptr;
|
||||
{
|
||||
// TODO function
|
||||
auto v = &d->messages;
|
||||
while (*v != nullptr && (*v)->random_y >= m->random_y) {
|
||||
if ((*v)->message_id.get() < message_id.get()) {
|
||||
v = &(*v)->right;
|
||||
} else if ((*v)->message_id == message_id) {
|
||||
UNREACHABLE();
|
||||
} else {
|
||||
v = &(*v)->left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unique_ptr<Message> *left = &message->left;
|
||||
unique_ptr<Message> *right = &message->right;
|
||||
unique_ptr<Message> *left = &message->left;
|
||||
unique_ptr<Message> *right = &message->right;
|
||||
|
||||
unique_ptr<Message> cur = std::move(*v);
|
||||
while (cur != nullptr) {
|
||||
if (cur->message_id.get() < message_id.get()) {
|
||||
*left = std::move(cur);
|
||||
left = &((*left)->right);
|
||||
cur = std::move(*left);
|
||||
} else {
|
||||
*right = std::move(cur);
|
||||
right = &((*right)->left);
|
||||
cur = std::move(*right);
|
||||
unique_ptr<Message> cur = std::move(*v);
|
||||
while (cur != nullptr) {
|
||||
if (cur->message_id.get() < message_id.get()) {
|
||||
*left = std::move(cur);
|
||||
left = &((*left)->right);
|
||||
cur = std::move(*left);
|
||||
} else {
|
||||
*right = std::move(cur);
|
||||
right = &((*right)->left);
|
||||
cur = std::move(*right);
|
||||
}
|
||||
}
|
||||
CHECK(*left == nullptr);
|
||||
CHECK(*right == nullptr);
|
||||
*v = std::move(message);
|
||||
result_message = v->get();
|
||||
}
|
||||
CHECK(*left == nullptr);
|
||||
CHECK(*right == nullptr);
|
||||
*v = std::move(message);
|
||||
|
||||
CHECK(result_message != nullptr);
|
||||
CHECK(d->messages != nullptr);
|
||||
|
||||
if (!is_attached) {
|
||||
if ((*v)->have_next) {
|
||||
CHECK(!(*v)->have_previous);
|
||||
if (m->have_next) {
|
||||
CHECK(!m->have_previous);
|
||||
attach_message_to_next(d, message_id, source);
|
||||
} else if ((*v)->have_previous) {
|
||||
} else if (m->have_previous) {
|
||||
attach_message_to_previous(d, message_id, source);
|
||||
}
|
||||
}
|
||||
@ -20321,14 +20379,14 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
|
||||
// nothing to do
|
||||
break;
|
||||
case DialogType::SecretChat:
|
||||
add_random_id_to_message_id_correspondence(d, (*v)->random_id, message_id);
|
||||
add_random_id_to_message_id_correspondence(d, m->random_id, message_id);
|
||||
break;
|
||||
case DialogType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return v->get();
|
||||
return result_message;
|
||||
}
|
||||
|
||||
void MessagesManager::on_message_changed(const Dialog *d, const Message *m, const char *source) {
|
||||
|
@ -10,14 +10,6 @@
|
||||
#include "td/telegram/td_api.h"
|
||||
#include "td/telegram/telegram_api.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/MultiPromise.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
#include "td/actor/SignalSlot.h"
|
||||
#include "td/actor/Timeout.h"
|
||||
|
||||
#include "td/db/binlog/BinlogEvent.h"
|
||||
|
||||
#include "td/telegram/AccessRights.h"
|
||||
#include "td/telegram/ChannelId.h"
|
||||
#include "td/telegram/Dependencies.h"
|
||||
@ -31,12 +23,22 @@
|
||||
#include "td/telegram/MessageId.h"
|
||||
#include "td/telegram/MessagesDb.h"
|
||||
#include "td/telegram/net/NetQuery.h"
|
||||
#include "td/telegram/NotificationGroupId.h"
|
||||
#include "td/telegram/NotificationId.h"
|
||||
#include "td/telegram/NotificationSettings.h"
|
||||
#include "td/telegram/ReplyMarkup.h"
|
||||
#include "td/telegram/SecretChatId.h"
|
||||
#include "td/telegram/SecretInputMedia.h"
|
||||
#include "td/telegram/UserId.h"
|
||||
|
||||
#include "td/db/binlog/BinlogEvent.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/MultiPromise.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
#include "td/actor/SignalSlot.h"
|
||||
#include "td/actor/Timeout.h"
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/ChangesProcessor.h"
|
||||
#include "td/utils/common.h"
|
||||
@ -782,6 +784,8 @@ class MessagesManager : public Actor {
|
||||
bool have_next = false;
|
||||
bool from_database = false;
|
||||
|
||||
NotificationId notification_id;
|
||||
|
||||
int32 views = 0;
|
||||
|
||||
int32 ttl = 0;
|
||||
@ -862,6 +866,8 @@ class MessagesManager : public Actor {
|
||||
|
||||
MessageId max_added_message_id;
|
||||
|
||||
NotificationGroupId message_notification_group_id;
|
||||
|
||||
bool has_contact_registered_message = false;
|
||||
|
||||
bool is_last_message_deleted_locally = false;
|
||||
@ -1444,9 +1450,11 @@ class MessagesManager : public Actor {
|
||||
bool update_message_content(DialogId dialog_id, Message *old_message, unique_ptr<MessageContent> new_content,
|
||||
bool need_send_update_message_content, bool need_merge_files);
|
||||
|
||||
void send_update_new_message(Dialog *d, const Message *m);
|
||||
void send_update_new_message(const Dialog *d, const Message *m);
|
||||
|
||||
void add_new_message_notification(Dialog *d, const Message *m, bool force);
|
||||
NotificationGroupId get_dialog_message_notification_group_id(Dialog *d);
|
||||
|
||||
void add_new_message_notification(Dialog *d, Message *m, bool force);
|
||||
|
||||
void flush_pending_new_message_notifications(DialogId dialog_id);
|
||||
|
||||
|
@ -36,6 +36,16 @@ class NotificationGroupId {
|
||||
return id == other.id;
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const {
|
||||
storer.store_int(id);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(ParserT &parser) {
|
||||
id = parser.fetch_int();
|
||||
}
|
||||
|
||||
private:
|
||||
int32 id{0};
|
||||
};
|
||||
@ -47,7 +57,7 @@ struct NotificationGroupIdHash {
|
||||
};
|
||||
|
||||
inline StringBuilder &operator<<(StringBuilder &sb, const NotificationGroupId group_id) {
|
||||
return sb << "NotificationGroup(" << group_id.get() << ")";
|
||||
return sb << "notification group " << group_id.get();
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -36,6 +36,16 @@ class NotificationId {
|
||||
return id == other.id;
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const {
|
||||
storer.store_int(id);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(ParserT &parser) {
|
||||
id = parser.fetch_int();
|
||||
}
|
||||
|
||||
private:
|
||||
int32 id{0};
|
||||
};
|
||||
@ -47,7 +57,7 @@ struct NotificationIdHash {
|
||||
};
|
||||
|
||||
inline StringBuilder &operator<<(StringBuilder &sb, const NotificationId notification_id) {
|
||||
return sb << "Notification(" << notification_id.get() << ")";
|
||||
return sb << "notification " << notification_id.get();
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -6,23 +6,52 @@
|
||||
//
|
||||
#include "td/telegram/NotificationManager.h"
|
||||
|
||||
#include "td/telegram/Global.h"
|
||||
#include "td/telegram/Td.h"
|
||||
#include "td/telegram/TdDb.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
NotificationManager::NotificationManager(Td *td) : td_(td) {
|
||||
int VERBOSITY_NAME(notifications) = VERBOSITY_NAME(WARNING);
|
||||
|
||||
NotificationManager::NotificationManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
|
||||
}
|
||||
|
||||
void NotificationManager::start_up() {
|
||||
current_notification_id_ =
|
||||
NotificationId(to_integer<int32>(G()->td_db()->get_binlog_pmc()->get("notification_id_current")));
|
||||
current_notification_group_id_ =
|
||||
NotificationGroupId(to_integer<int32>(G()->td_db()->get_binlog_pmc()->get("notification_group_id_current")));
|
||||
}
|
||||
|
||||
void NotificationManager::tear_down() {
|
||||
parent_.reset();
|
||||
}
|
||||
|
||||
NotificationId NotificationManager::get_next_notification_id() {
|
||||
return NotificationId();
|
||||
current_notification_id_ = NotificationId(current_notification_id_.get() % 0x7FFFFFFF + 1);
|
||||
G()->td_db()->get_binlog_pmc()->set("notification_id_current", to_string(current_notification_id_.get()));
|
||||
return current_notification_id_;
|
||||
}
|
||||
|
||||
void NotificationManager::add_notification(NotificationGroupId group_id, int32 total_count, DialogId dialog_id,
|
||||
NotificationGroupId NotificationManager::get_next_notification_group_id() {
|
||||
current_notification_group_id_ = NotificationGroupId(current_notification_group_id_.get() % 0x7FFFFFFF + 1);
|
||||
G()->td_db()->get_binlog_pmc()->set("notification_group_id_current", to_string(current_notification_group_id_.get()));
|
||||
return current_notification_group_id_;
|
||||
}
|
||||
|
||||
void NotificationManager::add_notification(NotificationGroupId group_id, DialogId dialog_id,
|
||||
DialogId notification_settings_dialog_id, bool silent,
|
||||
NotificationId notification_id, unique_ptr<NotificationType> type) {
|
||||
CHECK(type != nullptr);
|
||||
VLOG(notifications) << "Add " << notification_id << " to " << group_id << " in " << dialog_id
|
||||
<< " with settings from " << notification_settings_dialog_id
|
||||
<< (silent ? " silent" : " with sound") << ": " << *type;
|
||||
// TODO total_count++;
|
||||
}
|
||||
|
||||
void NotificationManager::edit_notification(NotificationId notification_id, unique_ptr<NotificationType> type) {
|
||||
VLOG(notifications) << "Edit " << notification_id << ": " << *type;
|
||||
}
|
||||
|
||||
void NotificationManager::delete_notification(NotificationId notification_id) {
|
||||
@ -32,6 +61,8 @@ void NotificationManager::remove_notification(NotificationId notification_id, Pr
|
||||
if (!notification_id.is_valid()) {
|
||||
return promise.set_error(Status::Error(400, "Notification identifier is invalid"));
|
||||
}
|
||||
|
||||
// TODO update total_count
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
|
||||
@ -43,6 +74,8 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id
|
||||
if (!max_notification_id.is_valid()) {
|
||||
return promise.set_error(Status::Error(400, "Notification identifier is invalid"));
|
||||
}
|
||||
|
||||
// TODO update total_count
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
|
||||
|
@ -11,23 +11,27 @@
|
||||
#include "td/telegram/NotificationId.h"
|
||||
#include "td/telegram/NotificationType.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
extern int VERBOSITY_NAME(notifications);
|
||||
|
||||
class Td;
|
||||
|
||||
class NotificationManager {
|
||||
class NotificationManager : public Actor {
|
||||
public:
|
||||
explicit NotificationManager(Td *td);
|
||||
NotificationManager(Td *td, ActorShared<> parent);
|
||||
|
||||
NotificationId get_next_notification_id();
|
||||
|
||||
void add_notification(NotificationGroupId group_id, int32 total_count, DialogId dialog_id,
|
||||
DialogId notification_settings_dialog_id, bool silent, NotificationId notification_id,
|
||||
unique_ptr<NotificationType> type);
|
||||
NotificationGroupId get_next_notification_group_id();
|
||||
|
||||
void add_notification(NotificationGroupId group_id, DialogId dialog_id, DialogId notification_settings_dialog_id,
|
||||
bool silent, NotificationId notification_id, unique_ptr<NotificationType> type);
|
||||
|
||||
void edit_notification(NotificationId notification_id, unique_ptr<NotificationType> type);
|
||||
|
||||
@ -39,7 +43,14 @@ class NotificationManager {
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
private:
|
||||
void start_up() override;
|
||||
void tear_down() override;
|
||||
|
||||
NotificationId current_notification_id_;
|
||||
NotificationGroupId current_notification_group_id_;
|
||||
|
||||
Td *td_;
|
||||
ActorShared<> parent_;
|
||||
};
|
||||
|
||||
} // namespace td
|
||||
|
@ -3769,6 +3769,8 @@ void Td::clear() {
|
||||
LOG(DEBUG) << "InlineQueriesManager actor was cleared " << timer;
|
||||
messages_manager_actor_.reset(); // TODO: Stop silent
|
||||
LOG(DEBUG) << "MessagesManager actor was cleared " << timer;
|
||||
notification_manager_actor_.reset();
|
||||
LOG(DEBUG) << "NotificationManager actor was cleared " << timer;
|
||||
stickers_manager_actor_.reset();
|
||||
LOG(DEBUG) << "StickersManager actor was cleared " << timer;
|
||||
updates_manager_actor_.reset();
|
||||
@ -4028,7 +4030,6 @@ Status Td::init(DbKey key) {
|
||||
audios_manager_ = make_unique<AudiosManager>(this);
|
||||
callback_queries_manager_ = make_unique<CallbackQueriesManager>(this);
|
||||
documents_manager_ = make_unique<DocumentsManager>(this);
|
||||
notification_manager_ = make_unique<NotificationManager>(this);
|
||||
video_notes_manager_ = make_unique<VideoNotesManager>(this);
|
||||
videos_manager_ = make_unique<VideosManager>(this);
|
||||
voice_notes_manager_ = make_unique<VoiceNotesManager>(this);
|
||||
@ -4044,6 +4045,9 @@ Status Td::init(DbKey key) {
|
||||
messages_manager_ = make_unique<MessagesManager>(this, create_reference());
|
||||
messages_manager_actor_ = register_actor("MessagesManager", messages_manager_.get());
|
||||
G()->set_messages_manager(messages_manager_actor_.get());
|
||||
notification_manager_ = make_unique<NotificationManager>(this, create_reference());
|
||||
notification_manager_actor_ = register_actor("NotificationManager", notification_manager_.get());
|
||||
G()->set_notification_manager(notification_manager_actor_.get());
|
||||
stickers_manager_ = make_unique<StickersManager>(this, create_reference());
|
||||
stickers_manager_actor_ = register_actor("StickersManager", stickers_manager_.get());
|
||||
G()->set_stickers_manager(stickers_manager_actor_.get());
|
||||
|
@ -126,7 +126,6 @@ class Td final : public NetQueryCallback {
|
||||
unique_ptr<AudiosManager> audios_manager_;
|
||||
unique_ptr<CallbackQueriesManager> callback_queries_manager_;
|
||||
unique_ptr<DocumentsManager> documents_manager_;
|
||||
unique_ptr<NotificationManager> notification_manager_;
|
||||
unique_ptr<VideoNotesManager> video_notes_manager_;
|
||||
unique_ptr<VideosManager> videos_manager_;
|
||||
unique_ptr<VoiceNotesManager> voice_notes_manager_;
|
||||
@ -143,6 +142,8 @@ class Td final : public NetQueryCallback {
|
||||
ActorOwn<InlineQueriesManager> inline_queries_manager_actor_;
|
||||
unique_ptr<MessagesManager> messages_manager_;
|
||||
ActorOwn<MessagesManager> messages_manager_actor_;
|
||||
unique_ptr<NotificationManager> notification_manager_;
|
||||
ActorOwn<NotificationManager> notification_manager_actor_;
|
||||
unique_ptr<StickersManager> stickers_manager_;
|
||||
ActorOwn<StickersManager> stickers_manager_actor_;
|
||||
unique_ptr<UpdatesManager> updates_manager_;
|
||||
|
@ -6,7 +6,7 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
#include "td/telegram/TdParameters.h"
|
||||
|
||||
#include "td/db/binlog/Binlog.h"
|
||||
#include "td/db/binlog/BinlogEvent.h"
|
||||
@ -15,7 +15,7 @@
|
||||
#include "td/db/DbKey.h"
|
||||
#include "td/db/Pmc.h"
|
||||
|
||||
#include "td/telegram/TdParameters.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
Reference in New Issue
Block a user