1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #include "td/telegram/DialogActionBar.h"
8
9 #include "td/telegram/ContactsManager.h"
10 #include "td/telegram/Td.h"
11
12 namespace td {
13
create(bool can_report_spam,bool can_add_contact,bool can_block_user,bool can_share_phone_number,bool can_report_location,bool can_unarchive,int32 distance,bool can_invite_members,string join_request_dialog_title,bool is_join_request_broadcast,int32 join_request_date)14 unique_ptr<DialogActionBar> DialogActionBar::create(bool can_report_spam, bool can_add_contact, bool can_block_user,
15 bool can_share_phone_number, bool can_report_location,
16 bool can_unarchive, int32 distance, bool can_invite_members,
17 string join_request_dialog_title, bool is_join_request_broadcast,
18 int32 join_request_date) {
19 if (!can_report_spam && !can_add_contact && !can_block_user && !can_share_phone_number && !can_report_location &&
20 !can_invite_members && join_request_dialog_title.empty()) {
21 return nullptr;
22 }
23
24 auto action_bar = make_unique<DialogActionBar>();
25 action_bar->can_report_spam_ = can_report_spam;
26 action_bar->can_add_contact_ = can_add_contact;
27 action_bar->can_block_user_ = can_block_user;
28 action_bar->can_share_phone_number_ = can_share_phone_number;
29 action_bar->can_report_location_ = can_report_location;
30 action_bar->can_unarchive_ = can_unarchive;
31 action_bar->distance_ = distance >= 0 ? distance : -1;
32 action_bar->can_invite_members_ = can_invite_members;
33 action_bar->join_request_dialog_title_ = std::move(join_request_dialog_title);
34 action_bar->is_join_request_broadcast_ = is_join_request_broadcast;
35 action_bar->join_request_date_ = join_request_date;
36 return action_bar;
37 }
38
is_empty() const39 bool DialogActionBar::is_empty() const {
40 return !can_report_spam_ && !can_add_contact_ && !can_block_user_ && !can_share_phone_number_ &&
41 !can_report_location_ && !can_invite_members_ && join_request_dialog_title_.empty();
42 }
43
fix(Td * td,DialogId dialog_id,bool is_dialog_blocked,FolderId folder_id)44 void DialogActionBar::fix(Td *td, DialogId dialog_id, bool is_dialog_blocked, FolderId folder_id) {
45 auto dialog_type = dialog_id.get_type();
46 if (distance_ >= 0 && dialog_type != DialogType::User) {
47 LOG(ERROR) << "Receive distance " << distance_ << " to " << dialog_id;
48 distance_ = -1;
49 }
50
51 if (!join_request_dialog_title_.empty()) {
52 if (dialog_type != DialogType::User || join_request_date_ <= 0) {
53 LOG(ERROR) << "Receive join_request_date = " << join_request_date_ << " in " << dialog_id;
54 join_request_dialog_title_.clear();
55 is_join_request_broadcast_ = false;
56 join_request_date_ = 0;
57 } else if (can_report_location_ || can_report_spam_ || can_add_contact_ || can_block_user_ ||
58 can_share_phone_number_ || can_unarchive_ || can_invite_members_) {
59 LOG(ERROR) << "Receive action bar " << can_report_location_ << '/' << can_report_spam_ << '/' << can_add_contact_
60 << '/' << can_block_user_ << '/' << can_share_phone_number_ << '/' << can_report_location_ << '/'
61 << can_unarchive_ << '/' << can_invite_members_;
62 can_report_location_ = false;
63 can_report_spam_ = false;
64 can_add_contact_ = false;
65 can_block_user_ = false;
66 can_share_phone_number_ = false;
67 can_unarchive_ = false;
68 can_invite_members_ = false;
69 distance_ = -1;
70 }
71 }
72 if (join_request_dialog_title_.empty() && (is_join_request_broadcast_ || join_request_date_ != 0)) {
73 LOG(ERROR) << "Receive join request date = " << join_request_date_ << " and " << is_join_request_broadcast_
74 << " in " << dialog_id;
75 is_join_request_broadcast_ = false;
76 join_request_date_ = 0;
77 }
78 if (can_report_location_) {
79 if (dialog_type != DialogType::Channel) {
80 LOG(ERROR) << "Receive can_report_location in " << dialog_id;
81 can_report_location_ = false;
82 } else if (can_report_spam_ || can_add_contact_ || can_block_user_ || can_share_phone_number_ || can_unarchive_ ||
83 can_invite_members_) {
84 LOG(ERROR) << "Receive action bar " << can_report_spam_ << '/' << can_add_contact_ << '/' << can_block_user_
85 << '/' << can_share_phone_number_ << '/' << can_report_location_ << '/' << can_unarchive_ << '/'
86 << can_invite_members_;
87 can_report_spam_ = false;
88 can_add_contact_ = false;
89 can_block_user_ = false;
90 can_share_phone_number_ = false;
91 can_unarchive_ = false;
92 can_invite_members_ = false;
93 CHECK(distance_ == -1);
94 }
95 }
96 if (can_invite_members_) {
97 if (dialog_type != DialogType::Chat &&
98 (dialog_type != DialogType::Channel || td->contacts_manager_->get_channel_type(dialog_id.get_channel_id()) ==
99 ContactsManager::ChannelType::Broadcast)) {
100 LOG(ERROR) << "Receive can_invite_members in " << dialog_id;
101 can_invite_members_ = false;
102 } else if (can_report_spam_ || can_add_contact_ || can_block_user_ || can_share_phone_number_ || can_unarchive_) {
103 LOG(ERROR) << "Receive action bar " << can_report_spam_ << '/' << can_add_contact_ << '/' << can_block_user_
104 << '/' << can_share_phone_number_ << '/' << can_unarchive_ << '/' << can_invite_members_;
105 can_report_spam_ = false;
106 can_add_contact_ = false;
107 can_block_user_ = false;
108 can_share_phone_number_ = false;
109 can_unarchive_ = false;
110 CHECK(distance_ == -1);
111 }
112 }
113 if (dialog_type == DialogType::User) {
114 auto user_id = dialog_id.get_user_id();
115 bool is_me = user_id == td->contacts_manager_->get_my_id();
116 bool is_deleted = td->contacts_manager_->is_user_deleted(user_id);
117 bool is_contact = td->contacts_manager_->is_user_contact(user_id);
118 if (is_me || is_dialog_blocked) {
119 can_report_spam_ = false;
120 can_unarchive_ = false;
121 }
122 if (is_me || is_dialog_blocked || is_deleted) {
123 can_share_phone_number_ = false;
124 }
125 if (is_me || is_dialog_blocked || is_deleted || is_contact) {
126 can_block_user_ = false;
127 can_add_contact_ = false;
128 }
129 }
130 if (folder_id != FolderId::archive()) {
131 can_unarchive_ = false;
132 }
133 if (can_share_phone_number_) {
134 CHECK(!can_report_location_);
135 CHECK(!can_invite_members_);
136 if (dialog_type != DialogType::User) {
137 LOG(ERROR) << "Receive can_share_phone_number in " << dialog_id;
138 can_share_phone_number_ = false;
139 } else if (can_report_spam_ || can_add_contact_ || can_block_user_ || can_unarchive_ || distance_ >= 0) {
140 LOG(ERROR) << "Receive action bar " << can_report_spam_ << '/' << can_add_contact_ << '/' << can_block_user_
141 << '/' << can_share_phone_number_ << '/' << can_unarchive_ << '/' << distance_;
142 can_report_spam_ = false;
143 can_add_contact_ = false;
144 can_block_user_ = false;
145 can_unarchive_ = false;
146 }
147 }
148 if (can_block_user_) {
149 CHECK(!can_report_location_);
150 CHECK(!can_invite_members_);
151 CHECK(!can_share_phone_number_);
152 if (dialog_type != DialogType::User) {
153 LOG(ERROR) << "Receive can_block_user in " << dialog_id;
154 can_block_user_ = false;
155 } else if (!can_report_spam_ || !can_add_contact_) {
156 LOG(ERROR) << "Receive action bar " << can_report_spam_ << '/' << can_add_contact_ << '/' << can_block_user_;
157 can_report_spam_ = true;
158 can_add_contact_ = true;
159 }
160 }
161 if (can_add_contact_) {
162 CHECK(!can_report_location_);
163 CHECK(!can_invite_members_);
164 CHECK(!can_share_phone_number_);
165 if (dialog_type != DialogType::User) {
166 LOG(ERROR) << "Receive can_add_contact in " << dialog_id;
167 can_add_contact_ = false;
168 } else if (can_report_spam_ != can_block_user_) {
169 LOG(ERROR) << "Receive action bar " << can_report_spam_ << '/' << can_add_contact_ << '/' << can_block_user_;
170 can_report_spam_ = false;
171 can_block_user_ = false;
172 can_unarchive_ = false;
173 }
174 }
175 if (!can_block_user_) {
176 distance_ = -1;
177 }
178 if (!can_report_spam_) {
179 can_unarchive_ = false;
180 }
181 }
182
get_chat_action_bar_object(DialogType dialog_type,bool hide_unarchive) const183 td_api::object_ptr<td_api::ChatActionBar> DialogActionBar::get_chat_action_bar_object(DialogType dialog_type,
184 bool hide_unarchive) const {
185 if (!join_request_dialog_title_.empty()) {
186 CHECK(dialog_type == DialogType::User);
187 CHECK(!can_report_location_ && !can_share_phone_number_ && !can_block_user_ && !can_add_contact_ &&
188 !can_report_spam_ && !can_invite_members_);
189 return td_api::make_object<td_api::chatActionBarJoinRequest>(join_request_dialog_title_, is_join_request_broadcast_,
190 join_request_date_);
191 }
192 if (can_report_location_) {
193 CHECK(dialog_type == DialogType::Channel);
194 CHECK(!can_share_phone_number_ && !can_block_user_ && !can_add_contact_ && !can_report_spam_ &&
195 !can_invite_members_);
196 return td_api::make_object<td_api::chatActionBarReportUnrelatedLocation>();
197 }
198 if (can_invite_members_) {
199 CHECK(!can_share_phone_number_ && !can_block_user_ && !can_add_contact_ && !can_report_spam_);
200 return td_api::make_object<td_api::chatActionBarInviteMembers>();
201 }
202 if (can_share_phone_number_) {
203 CHECK(dialog_type == DialogType::User);
204 CHECK(!can_block_user_ && !can_add_contact_ && !can_report_spam_);
205 return td_api::make_object<td_api::chatActionBarSharePhoneNumber>();
206 }
207 if (hide_unarchive) {
208 if (can_add_contact_) {
209 return td_api::make_object<td_api::chatActionBarAddContact>();
210 } else {
211 return nullptr;
212 }
213 }
214 if (can_block_user_) {
215 CHECK(dialog_type == DialogType::User);
216 CHECK(can_report_spam_ && can_add_contact_);
217 return td_api::make_object<td_api::chatActionBarReportAddBlock>(can_unarchive_, distance_);
218 }
219 if (can_add_contact_) {
220 CHECK(dialog_type == DialogType::User);
221 CHECK(!can_report_spam_);
222 return td_api::make_object<td_api::chatActionBarAddContact>();
223 }
224 if (can_report_spam_) {
225 return td_api::make_object<td_api::chatActionBarReportSpam>(can_unarchive_);
226 }
227 return nullptr;
228 }
229
on_dialog_unarchived()230 bool DialogActionBar::on_dialog_unarchived() {
231 if (!can_unarchive_) {
232 return false;
233 }
234
235 can_unarchive_ = false;
236 can_report_spam_ = false;
237 can_block_user_ = false;
238 // keep can_add_contact_
239 return true;
240 }
241
on_user_contact_added()242 bool DialogActionBar::on_user_contact_added() {
243 if (!can_block_user_ && !can_add_contact_) {
244 return false;
245 }
246
247 can_block_user_ = false;
248 can_add_contact_ = false;
249 // keep can_unarchive_
250 distance_ = -1;
251 return true;
252 }
253
on_user_deleted()254 bool DialogActionBar::on_user_deleted() {
255 if (join_request_dialog_title_.empty() && !can_share_phone_number_ && !can_block_user_ && !can_add_contact_ &&
256 distance_ < 0) {
257 return false;
258 }
259
260 join_request_dialog_title_.clear();
261 is_join_request_broadcast_ = false;
262 join_request_date_ = 0;
263 can_share_phone_number_ = false;
264 can_block_user_ = false;
265 can_add_contact_ = false;
266 distance_ = -1;
267 return true;
268 }
269
on_outgoing_message()270 bool DialogActionBar::on_outgoing_message() {
271 if (distance_ < 0) {
272 return false;
273 }
274
275 distance_ = -1;
276 return true;
277 }
278
operator ==(const unique_ptr<DialogActionBar> & lhs,const unique_ptr<DialogActionBar> & rhs)279 bool operator==(const unique_ptr<DialogActionBar> &lhs, const unique_ptr<DialogActionBar> &rhs) {
280 if (lhs == nullptr) {
281 return rhs == nullptr;
282 }
283 if (rhs == nullptr) {
284 return false;
285 }
286 return lhs->can_report_spam_ == rhs->can_report_spam_ && lhs->can_add_contact_ == rhs->can_add_contact_ &&
287 lhs->can_block_user_ == rhs->can_block_user_ && lhs->can_share_phone_number_ == rhs->can_share_phone_number_ &&
288 lhs->can_report_location_ == rhs->can_report_location_ && lhs->can_unarchive_ == rhs->can_unarchive_ &&
289 lhs->distance_ == rhs->distance_ && lhs->can_invite_members_ == rhs->can_invite_members_ &&
290 lhs->join_request_dialog_title_ == rhs->join_request_dialog_title_ &&
291 lhs->is_join_request_broadcast_ == lhs->is_join_request_broadcast_ &&
292 lhs->join_request_date_ == rhs->join_request_date_;
293 ;
294 }
295
296 } // namespace td
297