Support chat folder color.

This commit is contained in:
levlam 2024-03-01 15:57:30 +03:00
parent 60ee05aef7
commit b9c66aaea6
6 changed files with 59 additions and 17 deletions

View File

@ -1616,6 +1616,7 @@ chatFolderIcon name:string = ChatFolderIcon;
//@description Represents a folder for user chats
//@title The title of the folder; 1-12 characters without line feeds
//@icon The chosen icon for the chat folder; may be null. If null, use getChatFolderDefaultIconName to get default icon name for the folder
//@color_id The identifier of the chosen color for the chat folder icon; from -1 to 6. If -1, then color is didabled
//@is_shareable True, if at least one link has been created for the folder
//@pinned_chat_ids The chat identifiers of pinned chats in the folder. There can be up to getOption("chat_folder_chosen_chat_count_max") pinned and always included non-secret chats and the same number of secret chats, but the limit can be increased with Telegram Premium
//@included_chat_ids The chat identifiers of always included chats in the folder. There can be up to getOption("chat_folder_chosen_chat_count_max") pinned and always included non-secret chats and the same number of secret chats, but the limit can be increased with Telegram Premium
@ -1628,15 +1629,16 @@ chatFolderIcon name:string = ChatFolderIcon;
//@include_bots True, if bots need to be included
//@include_groups True, if basic groups and supergroups need to be included
//@include_channels True, if channels need to be included
chatFolder title:string icon:chatFolderIcon is_shareable:Bool pinned_chat_ids:vector<int53> included_chat_ids:vector<int53> excluded_chat_ids:vector<int53> exclude_muted:Bool exclude_read:Bool exclude_archived:Bool include_contacts:Bool include_non_contacts:Bool include_bots:Bool include_groups:Bool include_channels:Bool = ChatFolder;
chatFolder title:string icon:chatFolderIcon color_id:int32 is_shareable:Bool pinned_chat_ids:vector<int53> included_chat_ids:vector<int53> excluded_chat_ids:vector<int53> exclude_muted:Bool exclude_read:Bool exclude_archived:Bool include_contacts:Bool include_non_contacts:Bool include_bots:Bool include_groups:Bool include_channels:Bool = ChatFolder;
//@description Contains basic information about a chat folder
//@id Unique chat folder identifier
//@title The title of the folder; 1-12 characters without line feeds
//@icon The chosen or default icon for the chat folder
//@color_id The identifier of the chosen color for the chat folder icon; from -1 to 6. If -1, then color is didabled
//@is_shareable True, if at least one link has been created for the folder
//@has_my_invite_links True, if the chat folder has invite links created by the current user
chatFolderInfo id:int32 title:string icon:chatFolderIcon is_shareable:Bool has_my_invite_links:Bool = ChatFolderInfo;
chatFolderInfo id:int32 title:string icon:chatFolderIcon color_id:int32 is_shareable:Bool has_my_invite_links:Bool = ChatFolderInfo;
//@description Contains a chat folder invite link
//@invite_link The chat folder invite link

View File

@ -48,6 +48,7 @@ unique_ptr<DialogFilter> DialogFilter::get_dialog_filter(
dialog_filter->dialog_filter_id_ = dialog_filter_id;
dialog_filter->title_ = std::move(filter->title_);
dialog_filter->emoji_ = std::move(filter->emoticon_);
dialog_filter->color_id_ = (filter->flags_ & telegram_api::dialogFilter::COLOR_MASK) != 0 ? filter->color_ : -1;
dialog_filter->pinned_dialog_ids_ = InputDialogId::get_input_dialog_ids(filter->pinned_peers_, &added_dialog_ids);
dialog_filter->included_dialog_ids_ =
InputDialogId::get_input_dialog_ids(filter->include_peers_, &added_dialog_ids);
@ -62,6 +63,10 @@ unique_ptr<DialogFilter> DialogFilter::get_dialog_filter(
dialog_filter->include_bots_ = (flags & telegram_api::dialogFilter::BOTS_MASK) != 0;
dialog_filter->include_groups_ = (flags & telegram_api::dialogFilter::GROUPS_MASK) != 0;
dialog_filter->include_channels_ = (flags & telegram_api::dialogFilter::BROADCASTS_MASK) != 0;
if (!is_valid_color_id(dialog_filter->color_id_)) {
LOG(ERROR) << "Receive color " << dialog_filter->color_id_;
dialog_filter->color_id_ = -1;
}
return dialog_filter;
}
case telegram_api::dialogFilterChatlist::ID: {
@ -79,11 +84,17 @@ unique_ptr<DialogFilter> DialogFilter::get_dialog_filter(
dialog_filter->dialog_filter_id_ = dialog_filter_id;
dialog_filter->title_ = std::move(filter->title_);
dialog_filter->emoji_ = std::move(filter->emoticon_);
dialog_filter->color_id_ =
(filter->flags_ & telegram_api::dialogFilterChatlist::COLOR_MASK) != 0 ? filter->color_ : -1;
dialog_filter->pinned_dialog_ids_ = InputDialogId::get_input_dialog_ids(filter->pinned_peers_, &added_dialog_ids);
dialog_filter->included_dialog_ids_ =
InputDialogId::get_input_dialog_ids(filter->include_peers_, &added_dialog_ids);
dialog_filter->is_shareable_ = true;
dialog_filter->has_my_invites_ = filter->has_my_invites_;
if (!is_valid_color_id(dialog_filter->color_id_)) {
LOG(ERROR) << "Receive color " << dialog_filter->color_id_;
dialog_filter->color_id_ = -1;
}
return dialog_filter;
}
default:
@ -132,6 +143,10 @@ Result<unique_ptr<DialogFilter>> DialogFilter::create_dialog_filter(Td *td, Dial
if (dialog_filter->emoji_.empty() && !icon_name.empty()) {
return Status::Error(400, "Invalid icon name specified");
}
dialog_filter->color_id_ = filter->color_id_;
if (!is_valid_color_id(dialog_filter->color_id_)) {
return Status::Error(400, "Invalid color identifier specified");
}
dialog_filter->exclude_muted_ = filter->exclude_muted_;
dialog_filter->exclude_read_ = filter->exclude_read_;
dialog_filter->exclude_archived_ = filter->exclude_archived_;
@ -414,17 +429,23 @@ telegram_api::object_ptr<telegram_api::DialogFilter> DialogFilter::get_input_dia
if (!emoji_.empty()) {
flags |= telegram_api::dialogFilterChatlist::EMOTICON_MASK;
}
if (color_id_ != -1) {
flags |= telegram_api::dialogFilterChatlist::COLOR_MASK;
}
if (has_my_invites_) {
flags |= telegram_api::dialogFilterChatlist::HAS_MY_INVITES_MASK;
}
return telegram_api::make_object<telegram_api::dialogFilterChatlist>(
flags, false /*ignored*/, dialog_filter_id_.get(), title_, emoji_, 0,
flags, false /*ignored*/, dialog_filter_id_.get(), title_, emoji_, color_id_,
InputDialogId::get_input_peers(pinned_dialog_ids_), InputDialogId::get_input_peers(included_dialog_ids_));
}
int32 flags = 0;
if (!emoji_.empty()) {
flags |= telegram_api::dialogFilter::EMOTICON_MASK;
}
if (color_id_ != -1) {
flags |= telegram_api::dialogFilter::COLOR_MASK;
}
if (exclude_muted_) {
flags |= telegram_api::dialogFilter::EXCLUDE_MUTED_MASK;
}
@ -452,7 +473,7 @@ telegram_api::object_ptr<telegram_api::DialogFilter> DialogFilter::get_input_dia
return telegram_api::make_object<telegram_api::dialogFilter>(
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
false /*ignored*/, false /*ignored*/, false /*ignored*/, dialog_filter_id_.get(), title_, emoji_, 0,
false /*ignored*/, false /*ignored*/, false /*ignored*/, dialog_filter_id_.get(), title_, emoji_, color_id_,
InputDialogId::get_input_peers(pinned_dialog_ids_), InputDialogId::get_input_peers(included_dialog_ids_),
InputDialogId::get_input_peers(excluded_dialog_ids_));
}
@ -477,15 +498,15 @@ td_api::object_ptr<td_api::chatFolder> DialogFilter::get_chat_folder_object(
icon = td_api::make_object<td_api::chatFolderIcon>(icon_name);
}
return td_api::make_object<td_api::chatFolder>(
title_, std::move(icon), is_shareable_, get_chat_ids(pinned_dialog_ids_), get_chat_ids(included_dialog_ids_),
get_chat_ids(excluded_dialog_ids_), exclude_muted_, exclude_read_, exclude_archived_, include_contacts_,
include_non_contacts_, include_bots_, include_groups_, include_channels_);
title_, std::move(icon), color_id_, is_shareable_, get_chat_ids(pinned_dialog_ids_),
get_chat_ids(included_dialog_ids_), get_chat_ids(excluded_dialog_ids_), exclude_muted_, exclude_read_,
exclude_archived_, include_contacts_, include_non_contacts_, include_bots_, include_groups_, include_channels_);
}
td_api::object_ptr<td_api::chatFolderInfo> DialogFilter::get_chat_folder_info_object() const {
return td_api::make_object<td_api::chatFolderInfo>(
dialog_filter_id_.get(), title_, td_api::make_object<td_api::chatFolderIcon>(get_chosen_or_default_icon_name()),
is_shareable_, has_my_invites_);
color_id_, is_shareable_, has_my_invites_);
}
void DialogFilter::for_each_dialog(std::function<void(const InputDialogId &)> callback) const {
@ -656,6 +677,7 @@ unique_ptr<DialogFilter> DialogFilter::merge_dialog_filter_changes(const DialogF
update_value(new_filter->title_, old_server_filter->title_, new_server_filter->title_);
update_value(new_filter->emoji_, old_server_filter->emoji_, new_server_filter->emoji_);
update_value(new_filter->color_id_, old_server_filter->color_id_, new_server_filter->color_id_);
LOG(INFO) << "Old local filter: " << *old_filter;
LOG(INFO) << "Old server filter: " << *old_server_filter;
@ -873,8 +895,8 @@ bool DialogFilter::are_similar(const DialogFilter &lhs, const DialogFilter &rhs)
}
bool DialogFilter::are_equivalent(const DialogFilter &lhs, const DialogFilter &rhs) {
return lhs.title_ == rhs.title_ && lhs.emoji_ == rhs.emoji_ && lhs.is_shareable_ == rhs.is_shareable_ &&
lhs.has_my_invites_ == rhs.has_my_invites_ &&
return lhs.title_ == rhs.title_ && lhs.emoji_ == rhs.emoji_ && lhs.color_id_ == rhs.color_id_ &&
lhs.is_shareable_ == rhs.is_shareable_ && lhs.has_my_invites_ == rhs.has_my_invites_ &&
InputDialogId::are_equivalent(lhs.pinned_dialog_ids_, rhs.pinned_dialog_ids_) &&
InputDialogId::are_equivalent(lhs.included_dialog_ids_, rhs.included_dialog_ids_) &&
InputDialogId::are_equivalent(lhs.excluded_dialog_ids_, rhs.excluded_dialog_ids_) && are_flags_equal(lhs, rhs);
@ -918,6 +940,10 @@ void DialogFilter::init_icon_names() {
CHECK(is_inited);
}
bool DialogFilter::is_valid_color_id(int32 color_id) {
return -1 <= color_id && color_id <= 6;
}
bool DialogFilter::are_flags_equal(const DialogFilter &lhs, const DialogFilter &rhs) {
return lhs.exclude_muted_ == rhs.exclude_muted_ && lhs.exclude_read_ == rhs.exclude_read_ &&
lhs.exclude_archived_ == rhs.exclude_archived_ && lhs.include_contacts_ == rhs.include_contacts_ &&

View File

@ -125,6 +125,7 @@ class DialogFilter {
vector<InputDialogId> pinned_dialog_ids_;
vector<InputDialogId> included_dialog_ids_;
vector<InputDialogId> excluded_dialog_ids_;
int32 color_id_ = -1;
bool exclude_muted_ = false;
bool exclude_read_ = false;
bool exclude_archived_ = false;
@ -139,6 +140,8 @@ class DialogFilter {
static FlatHashMap<string, string> emoji_to_icon_name_;
static FlatHashMap<string, string> icon_name_to_emoji_;
static bool is_valid_color_id(int32 color_id);
static bool are_flags_equal(const DialogFilter &lhs, const DialogFilter &rhs);
static void init_icon_names();
@ -152,9 +155,10 @@ class DialogFilter {
inline bool operator==(const DialogFilter &lhs, const DialogFilter &rhs) {
return lhs.dialog_filter_id_ == rhs.dialog_filter_id_ && lhs.title_ == rhs.title_ && lhs.emoji_ == rhs.emoji_ &&
lhs.is_shareable_ == rhs.is_shareable_ && lhs.has_my_invites_ == rhs.has_my_invites_ &&
lhs.pinned_dialog_ids_ == rhs.pinned_dialog_ids_ && lhs.included_dialog_ids_ == rhs.included_dialog_ids_ &&
lhs.excluded_dialog_ids_ == rhs.excluded_dialog_ids_ && DialogFilter::are_flags_equal(lhs, rhs);
lhs.color_id_ == rhs.color_id_ && lhs.is_shareable_ == rhs.is_shareable_ &&
lhs.has_my_invites_ == rhs.has_my_invites_ && lhs.pinned_dialog_ids_ == rhs.pinned_dialog_ids_ &&
lhs.included_dialog_ids_ == rhs.included_dialog_ids_ && lhs.excluded_dialog_ids_ == rhs.excluded_dialog_ids_ &&
DialogFilter::are_flags_equal(lhs, rhs);
}
inline bool operator!=(const DialogFilter &lhs, const DialogFilter &rhs) {

View File

@ -19,6 +19,7 @@ void DialogFilter::store(StorerT &storer) const {
bool has_pinned_dialog_ids = !pinned_dialog_ids_.empty();
bool has_included_dialog_ids = !included_dialog_ids_.empty();
bool has_excluded_dialog_ids = !excluded_dialog_ids_.empty();
bool has_color_id = color_id_ != -1;
BEGIN_STORE_FLAGS();
STORE_FLAG(exclude_muted_);
STORE_FLAG(exclude_read_);
@ -33,8 +34,8 @@ void DialogFilter::store(StorerT &storer) const {
STORE_FLAG(has_excluded_dialog_ids);
STORE_FLAG(is_shareable_);
STORE_FLAG(has_my_invites_);
STORE_FLAG(has_color_id);
END_STORE_FLAGS();
store(dialog_filter_id_, storer);
store(title_, storer);
store(emoji_, storer);
@ -47,6 +48,9 @@ void DialogFilter::store(StorerT &storer) const {
if (has_excluded_dialog_ids) {
store(excluded_dialog_ids_, storer);
}
if (has_color_id) {
store(color_id_, storer);
}
}
template <class ParserT>
@ -55,6 +59,7 @@ void DialogFilter::parse(ParserT &parser) {
bool has_pinned_dialog_ids;
bool has_included_dialog_ids;
bool has_excluded_dialog_ids;
bool has_color_id;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(exclude_muted_);
PARSE_FLAG(exclude_read_);
@ -69,8 +74,8 @@ void DialogFilter::parse(ParserT &parser) {
PARSE_FLAG(has_excluded_dialog_ids);
PARSE_FLAG(is_shareable_);
PARSE_FLAG(has_my_invites_);
PARSE_FLAG(has_color_id);
END_PARSE_FLAGS();
parse(dialog_filter_id_, parser);
parse(title_, parser);
parse(emoji_, parser);
@ -83,6 +88,11 @@ void DialogFilter::parse(ParserT &parser) {
if (has_excluded_dialog_ids) {
parse(excluded_dialog_ids_, parser);
}
if (has_color_id) {
parse(color_id_, parser);
} else {
color_id_ = -1;
}
}
} // namespace td

View File

@ -2010,7 +2010,7 @@ void DialogFilterManager::on_get_chatlist_invite(
icon_name = "Custom";
}
info = td_api::make_object<td_api::chatFolderInfo>(
0, invite->title_, td_api::make_object<td_api::chatFolderIcon>(icon_name), true, false);
0, invite->title_, td_api::make_object<td_api::chatFolderIcon>(icon_name), -1, true, false);
missing_peers = std::move(invite->peers_);
chats = std::move(invite->chats_);
users = std::move(invite->users_);

View File

@ -1928,7 +1928,7 @@ class CliClient final : public Actor {
string excluded_chat_ids;
get_args(filter, title, icon_name, pinned_chat_ids, included_chat_ids, excluded_chat_ids);
return td_api::make_object<td_api::chatFolder>(
title, td_api::make_object<td_api::chatFolderIcon>(icon_name), is_shareable, as_chat_ids(pinned_chat_ids),
title, td_api::make_object<td_api::chatFolderIcon>(icon_name), -1, is_shareable, as_chat_ids(pinned_chat_ids),
as_chat_ids(included_chat_ids), as_chat_ids(excluded_chat_ids), rand_bool(), rand_bool(), rand_bool(),
rand_bool(), rand_bool(), rand_bool(), rand_bool(), rand_bool());
}