Default disable_notification support.

GitOrigin-RevId: 014a8b141dc1cff5126748c7785ea22d12aef7b3
This commit is contained in:
levlam 2018-04-28 21:05:04 +03:00
parent 19ba540336
commit e9ba26c4f0
10 changed files with 181 additions and 8 deletions

View File

@ -530,6 +530,7 @@ chatTypeSecret secret_chat_id:int32 user_id:int32 = ChatType;
//@order Descending parameter by which chats are sorted in the main chat list. If the order number of two chats is the same, they must be sorted in descending order by ID. If 0, the position of the chat in the list is undetermined
//@is_pinned True, if the chat is pinned
//@can_be_reported True, if the chat can be reported to Telegram moderators through reportChat
//@default_disable_notification Default value of disable_notification parameter, used when a message is sent to the chat
//@unread_count Number of unread messages in the chat
//@last_read_inbox_message_id Identifier of the last read incoming message
//@last_read_outbox_message_id Identifier of the last read outgoing message
@ -538,7 +539,7 @@ chatTypeSecret secret_chat_id:int32 user_id:int32 = ChatType;
//@reply_markup_message_id Identifier of the message from which reply markup needs to be used; 0 if there is no default custom reply markup in the chat
//@draft_message A draft of a message in the chat; may be null
//@client_data Contains client-specific data associated with the chat. (For example, the chat position or local chat notification settings can be stored here.) Persistent if a message database is used
chat id:int53 type:ChatType title:string photo:chatPhoto last_message:message order:int64 is_pinned:Bool can_be_reported:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 notification_settings:chatNotificationSettings reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat;
chat id:int53 type:ChatType title:string photo:chatPhoto last_message:message order:int64 is_pinned:Bool can_be_reported:Bool default_disable_notification:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 notification_settings:chatNotificationSettings reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat;
//@description Represents a list of chats @chat_ids List of chat identifiers
chats chat_ids:vector<int53> = Chats;
@ -2057,6 +2058,9 @@ updateChatOrder chat_id:int53 order:int64 = Update;
//@description A chat was pinned or unpinned @chat_id Chat identifier @is_pinned New value of is_pinned @order New value of the chat order
updateChatIsPinned chat_id:int53 is_pinned:Bool order:int64 = Update;
//@description A value of default disable_notification parameter, used when a message is sent to the chat, was changed @chat_id Chat identifier @default_disable_notification The new default_disable_notification value
updateChatDefaultDisableNotification chat_id:int53 default_disable_notification:Bool = Update;
//@description Incoming messages were read or number of unread messages has been changed @chat_id Chat identifier @last_read_inbox_message_id Identifier of the last read incoming message @unread_count The number of unread messages left in the chat
updateChatReadInbox chat_id:int53 last_read_inbox_message_id:int53 unread_count:int32 = Update;
@ -2621,6 +2625,9 @@ setChatNotificationSettings chat_id:int53 notification_settings:chatNotification
//@description Changes the pinned state of a chat. You can pin up to GetOption("pinned_chat_count_max") non-secret chats and the same number of secret chats @chat_id Chat identifier @is_pinned New value of is_pinned
toggleChatIsPinned chat_id:int53 is_pinned:Bool = Ok;
//@description Changes the value of default disable_notification parameter, used when a message is sent to a chat @chat_id Chat identifier @default_disable_notification New value of default_disable_notification
toggleChatDefaultDisableNotification chat_id:int53 default_disable_notification:Bool = Ok;
//@description Changes client data associated with a chat @chat_id Chat identifier @client_data New value of client_data
setChatClientData chat_id:int53 client_data:string = Ok;

Binary file not shown.

View File

@ -2969,9 +2969,13 @@ class GetScopeNotifySettingsQuery : public Td::ResultHandler {
};
class UpdateDialogNotifySettingsQuery : public Td::ResultHandler {
Promise<Unit> promise_;
DialogId dialog_id_;
public:
explicit UpdateDialogNotifySettingsQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
}
void send(DialogId dialog_id, const DialogNotificationSettings &new_settings) {
auto input_notify_peer = td->messages_manager_->get_input_notify_peer(dialog_id);
if (input_notify_peer == nullptr) {
@ -3007,18 +3011,21 @@ class UpdateDialogNotifySettingsQuery : public Td::ResultHandler {
if (!result) {
return on_error(id, Status::Error(400, "Receive false as result"));
}
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
if (!td->messages_manager_->on_get_dialog_error(dialog_id_, status, "UpdateDialogNotifySettingsQuery")) {
LOG(INFO) << "Receive error for set chat notification settings: " << status;
status.ignore();
}
if (!td->auth_manager_->is_bot() && td->messages_manager_->get_input_notify_peer(dialog_id_) != nullptr) {
// trying to repair notification settings for this dialog
td->create_handler<GetDialogNotifySettingsQuery>(Promise<>())->send(dialog_id_);
}
promise_.set_error(std::move(status));
}
};
@ -6267,8 +6274,10 @@ bool MessagesManager::update_dialog_notification_settings(DialogId dialog_id,
current_settings->use_default_mute_until != new_settings.use_default_mute_until ||
current_settings->use_default_sound != new_settings.use_default_sound ||
current_settings->use_default_show_preview != new_settings.use_default_show_preview;
bool is_changed = need_update || current_settings->is_synchronized != new_settings.is_synchronized ||
current_settings->silent_send_message != new_settings.silent_send_message ||
bool need_update_default_disable_notification =
current_settings->silent_send_message != new_settings.silent_send_message;
bool is_changed = need_update || need_update_default_disable_notification ||
current_settings->is_synchronized != new_settings.is_synchronized ||
current_settings->is_use_default_fixed != new_settings.is_use_default_fixed;
if (is_changed) {
@ -6287,6 +6296,11 @@ bool MessagesManager::update_dialog_notification_settings(DialogId dialog_id,
make_tl_object<td_api::updateChatNotificationSettings>(
dialog_id.get(), get_chat_notification_settings_object(current_settings)));
}
if (need_update_default_disable_notification) {
send_closure(G()->td(), &Td::send_update,
make_tl_object<td_api::updateChatDefaultDisableNotification>(dialog_id.get(),
current_settings->silent_send_message));
}
}
return is_changed;
}
@ -6476,6 +6490,24 @@ void MessagesManager::on_update_scope_notify_settings(
update_scope_notification_settings(scope, get_scope_notification_settings(scope), notification_settings);
}
bool MessagesManager::update_dialog_silent_send_message(Dialog *d, bool silent_send_message) {
CHECK(d != nullptr);
LOG_IF(WARNING, !d->notification_settings.is_synchronized)
<< "Have unknown notification settings in " << d->dialog_id;
if (d->notification_settings.silent_send_message == silent_send_message) {
return false;
}
LOG(INFO) << "Update silent send message in " << d->dialog_id << " to " << silent_send_message;
d->notification_settings.silent_send_message = silent_send_message;
on_dialog_updated(d->dialog_id, "update_dialog_silent_send_message");
send_closure(G()->td(), &Td::send_update,
make_tl_object<td_api::updateChatDefaultDisableNotification>(d->dialog_id.get(), silent_send_message));
return true;
}
bool MessagesManager::get_dialog_report_spam_state(DialogId dialog_id, Promise<Unit> &&promise) {
Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr) {
@ -12464,6 +12496,90 @@ void MessagesManager::reorder_pinned_dialogs_on_server(const vector<DialogId> &d
td_->create_handler<ReorderPinnedDialogsQuery>(std::move(promise))->send(dialog_ids);
}
Status MessagesManager::toggle_dialog_silent_send_message(DialogId dialog_id, bool silent_send_message) {
CHECK(!td_->auth_manager_->is_bot());
Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr) {
return Status::Error(6, "Chat not found");
}
if (!have_input_peer(dialog_id, AccessRights::Read)) {
return Status::Error(6, "Can't access the chat");
}
if (update_dialog_silent_send_message(d, silent_send_message)) {
save_dialog_notification_settings_on_server(dialog_id, false);
}
return Status::OK();
}
class MessagesManager::SaveDialogNotificationSettingsOnServerLogEvent {
public:
DialogId dialog_id_;
template <class StorerT>
void store(StorerT &storer) const {
td::store(dialog_id_, storer);
}
template <class ParserT>
void parse(ParserT &parser) {
td::parse(dialog_id_, parser);
}
};
void MessagesManager::save_dialog_notification_settings_on_server(DialogId dialog_id, bool from_binlog) {
auto d = get_dialog(dialog_id);
CHECK(d != nullptr);
if (!from_binlog && G()->parameters().use_message_db) {
LOG(INFO) << "Save notification settings of " << dialog_id << " to binlog";
SaveDialogNotificationSettingsOnServerLogEvent logevent;
logevent.dialog_id_ = dialog_id;
auto storer = LogEventStorerImpl<SaveDialogNotificationSettingsOnServerLogEvent>(logevent);
if (d->save_notification_settings_logevent_id == 0) {
d->save_notification_settings_logevent_id = BinlogHelper::add(
G()->td_db()->get_binlog(), LogEvent::HandlerType::SaveDialogNotificationSettingsOnServer, storer);
LOG(INFO) << "Add notification settings logevent " << d->save_notification_settings_logevent_id;
} else {
auto new_logevent_id =
BinlogHelper::rewrite(G()->td_db()->get_binlog(), d->save_notification_settings_logevent_id,
LogEvent::HandlerType::SaveDialogNotificationSettingsOnServer, storer);
LOG(INFO) << "Rewrite notification settings logevent " << d->save_notification_settings_logevent_id << " with "
<< new_logevent_id;
}
d->save_notification_settings_logevent_id_generation++;
}
Promise<> promise;
if (d->save_notification_settings_logevent_id != 0) {
promise = PromiseCreator::lambda(
[actor_id = actor_id(this), dialog_id,
generation = d->save_notification_settings_logevent_id_generation](Result<Unit> result) mutable {
if (!G()->close_flag()) {
send_closure(actor_id, &MessagesManager::on_saved_dialog_notification_settings, dialog_id, generation);
}
});
}
// TODO do not send two queries simultaneously or use SequenceDispatcher
td_->create_handler<UpdateDialogNotifySettingsQuery>(std::move(promise))->send(dialog_id, d->notification_settings);
}
void MessagesManager::on_saved_dialog_notification_settings(DialogId dialog_id, uint64 generation) {
auto d = get_dialog(dialog_id);
CHECK(d != nullptr);
LOG(INFO) << "Saved notification settings in " << dialog_id << " with logevent "
<< d->save_notification_settings_logevent_id;
if (d->save_notification_settings_logevent_id_generation == generation) {
CHECK(d->save_notification_settings_logevent_id != 0);
LOG(INFO) << "Delete notification settings logevent " << d->save_notification_settings_logevent_id;
BinlogHelper::erase(G()->td_db()->get_binlog(), d->save_notification_settings_logevent_id);
d->save_notification_settings_logevent_id = 0;
}
}
Status MessagesManager::set_dialog_client_data(DialogId dialog_id, string &&client_data) {
Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr) {
@ -12994,8 +13110,9 @@ tl_object_ptr<td_api::chat> MessagesManager::get_chat_object(const Dialog *d) {
get_chat_photo_object(td_->file_manager_.get(), get_dialog_photo(d->dialog_id)),
get_message_object(d->dialog_id, get_message(d, d->last_message_id)),
DialogDate(d->order, d->dialog_id) <= last_dialog_date_ ? d->order : 0, d->pinned_order != DEFAULT_ORDER,
can_report_dialog(d->dialog_id), d->server_unread_count + d->local_unread_count,
d->last_read_inbox_message_id.get(), d->last_read_outbox_message_id.get(), d->unread_mention_count,
can_report_dialog(d->dialog_id), d->notification_settings.silent_send_message,
d->server_unread_count + d->local_unread_count, d->last_read_inbox_message_id.get(),
d->last_read_outbox_message_id.get(), d->unread_mention_count,
get_chat_notification_settings_object(&d->notification_settings), d->reply_markup_message_id.get(),
get_draft_message_object(d->draft_message), d->client_data);
}
@ -13166,7 +13283,7 @@ Status MessagesManager::set_dialog_notification_settings(
std::move(notification_settings->sound_), notification_settings->use_default_show_preview_,
notification_settings->show_preview_, current_settings->silent_send_message);
if (update_dialog_notification_settings(dialog_id, current_settings, new_settings)) {
td_->create_handler<UpdateDialogNotifySettingsQuery>()->send(dialog_id, new_settings);
save_dialog_notification_settings_on_server(dialog_id, false);
}
return Status::OK();
}
@ -15122,7 +15239,7 @@ MessagesManager::Message *MessagesManager::get_message_to_send(Dialog *d, Messag
m->content = std::move(content);
m->forward_info = std::move(forward_info);
if (td_->auth_manager_->is_bot()) {
if (td_->auth_manager_->is_bot() || disable_notification) {
m->disable_notification = disable_notification;
} else {
auto notification_settings = get_dialog_notification_settings(dialog_id, true);
@ -25106,6 +25223,26 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
save_dialog_draft_message_on_server(dialog_id);
break;
}
case LogEvent::HandlerType::SaveDialogNotificationSettingsOnServer: {
if (!G()->parameters().use_message_db) {
BinlogHelper::erase(G()->td_db()->get_binlog(), event.id_);
break;
}
SaveDialogNotificationSettingsOnServerLogEvent log_event;
log_event_parse(log_event, event.data_).ensure();
auto dialog_id = log_event.dialog_id_;
Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) {
BinlogHelper::erase(G()->td_db()->get_binlog(), event.id_);
break;
}
d->save_notification_settings_logevent_id = event.id_;
save_dialog_notification_settings_on_server(dialog_id, true);
break;
}
case LogEvent::HandlerType::GetChannelDifference: {
GetChannelDifferenceLogEvent log_event;
log_event_parse(log_event, event.data_).ensure();

View File

@ -1223,6 +1223,8 @@ class MessagesManager : public Actor {
Status toggle_dialog_is_pinned(DialogId dialog_id, bool is_pinned) TD_WARN_UNUSED_RESULT;
Status toggle_dialog_silent_send_message(DialogId dialog_id, bool silent_send_message) TD_WARN_UNUSED_RESULT;
Status set_pinned_dialogs(vector<DialogId> dialog_ids) TD_WARN_UNUSED_RESULT;
Status set_dialog_client_data(DialogId dialog_id, string &&client_data) TD_WARN_UNUSED_RESULT;
@ -1577,6 +1579,8 @@ class MessagesManager : public Actor {
unique_ptr<DraftMessage> draft_message;
uint64 save_draft_message_logevent_id = 0;
uint64 save_draft_message_logevent_id_generation = 0;
uint64 save_notification_settings_logevent_id = 0;
uint64 save_notification_settings_logevent_id_generation = 0;
MessageId
last_read_all_mentions_message_id; // all mentions with a message id not greater than it are implicitly read
@ -1835,6 +1839,7 @@ class MessagesManager : public Actor {
class ReadMessageContentsOnServerLogEvent;
class ReorderPinnedDialogsOnServerLogEvent;
class SaveDialogDraftMessageOnServerLogEvent;
class SaveDialogNotificationSettingsOnServerLogEvent;
class SendBotStartMessageLogEvent;
class SendInlineQueryResultMessageLogEvent;
class SendMessageLogEvent;
@ -2251,6 +2256,8 @@ class MessagesManager : public Actor {
void on_scope_unmute(NotificationSettingsScope scope);
bool update_dialog_silent_send_message(Dialog *d, bool silent_send_message);
void on_send_dialog_action_timeout(DialogId dialog_id);
void on_active_dialog_action_timeout(DialogId dialog_id);
@ -2475,6 +2482,10 @@ class MessagesManager : public Actor {
void on_saved_dialog_draft_message(DialogId dialog_id, uint64 generation);
void save_dialog_notification_settings_on_server(DialogId dialog_id, bool from_binlog);
void on_saved_dialog_notification_settings(DialogId dialog_id, uint64 generation);
int64 get_next_pinned_dialog_order();
void update_dialog_pos(Dialog *d, bool remove_from_dialog_list, const char *source,

View File

@ -8,6 +8,7 @@
#include "td/telegram/ContactsManager.h"
#include "td/telegram/DialogId.h"
#include "td/telegram/files/FileId.h"
#include "td/telegram/files/FileManager.h"
#include "td/telegram/Global.h"
#include "td/telegram/misc.h"

View File

@ -6013,6 +6013,13 @@ void Td::on_request(uint64 id, const td_api::toggleChatIsPinned &request) {
answer_ok_query(id, messages_manager_->toggle_dialog_is_pinned(DialogId(request.chat_id_), request.is_pinned_));
}
void Td::on_request(uint64 id, const td_api::toggleChatDefaultDisableNotification &request) {
CHECK_AUTH();
CHECK_IS_USER();
answer_ok_query(id, messages_manager_->toggle_dialog_silent_send_message(DialogId(request.chat_id_),
request.default_disable_notification_));
}
void Td::on_request(uint64 id, const td_api::setPinnedChats &request) {
CHECK_AUTH();
CHECK_IS_USER();

View File

@ -547,6 +547,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, const td_api::toggleChatIsPinned &request);
void on_request(uint64 id, const td_api::toggleChatDefaultDisableNotification &request);
void on_request(uint64 id, const td_api::setPinnedChats &request);
void on_request(uint64 id, td_api::setChatClientData &request);

View File

@ -82,6 +82,7 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue<Binlog> &binlog_p
case LogEvent::HandlerType::ToggleDialogIsPinnedOnServer:
case LogEvent::HandlerType::ReorderPinnedDialogsOnServer:
case LogEvent::HandlerType::SaveDialogDraftMessageOnServer:
case LogEvent::HandlerType::SaveDialogNotificationSettingsOnServer:
case LogEvent::HandlerType::GetChannelDifference:
events.to_messages_manager.push_back(event.clone());
break;

View File

@ -2194,6 +2194,12 @@ class CliClient final : public Actor {
string is_pinned;
std::tie(chat_id, is_pinned) = split(args);
send_request(make_tl_object<td_api::toggleChatIsPinned>(as_chat_id(chat_id), as_bool(is_pinned)));
} else if (op == "tcddn") {
string chat_id;
string default_disable_notification;
std::tie(chat_id, default_disable_notification) = split(args);
send_request(make_tl_object<td_api::toggleChatDefaultDisableNotification>(as_chat_id(chat_id),
as_bool(default_disable_notification)));
} else if (op == "spchats") {
vector<string> chat_ids_str = full_split(args, ' ');
vector<int64> chat_ids;

View File

@ -83,6 +83,7 @@ class LogEvent {
ToggleDialogIsPinnedOnServer = 0x10c,
ReorderPinnedDialogsOnServer = 0x10d,
SaveDialogDraftMessageOnServer = 0x10e,
SaveDialogNotificationSettingsOnServer = 0x10f,
GetChannelDifference = 0x140,
ConfigPmcMagic = 0x1f18,
BinlogPmcMagic = 0x4327