data_channel.cpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "data/data_channel.h"
  8. #include "api/api_global_privacy.h"
  9. #include "data/components/credits.h"
  10. #include "data/data_changes.h"
  11. #include "data/data_channel_admins.h"
  12. #include "data/data_user.h"
  13. #include "data/data_chat.h"
  14. #include "data/data_session.h"
  15. #include "data/data_stories.h"
  16. #include "data/data_folder.h"
  17. #include "data/data_forum.h"
  18. #include "data/data_forum_icons.h"
  19. #include "data/data_histories.h"
  20. #include "data/data_group_call.h"
  21. #include "data/data_message_reactions.h"
  22. #include "data/data_wall_paper.h"
  23. #include "data/notify/data_notify_settings.h"
  24. #include "main/main_session.h"
  25. #include "main/session/send_as_peers.h"
  26. #include "base/unixtime.h"
  27. #include "core/application.h"
  28. #include "history/history.h"
  29. #include "api/api_chat_invite.h"
  30. #include "api/api_invite_links.h"
  31. #include "apiwrap.h"
  32. #include "storage/storage_account.h"
  33. #include "ui/unread_badge.h"
  34. #include "window/notifications_manager.h"
  35. namespace {
  36. using UpdateFlag = Data::PeerUpdate::Flag;
  37. } // namespace
  38. MegagroupInfo::MegagroupInfo() = default;
  39. MegagroupInfo::~MegagroupInfo() = default;
  40. ChatData *MegagroupInfo::getMigrateFromChat() const {
  41. return _migratedFrom;
  42. }
  43. void MegagroupInfo::setMigrateFromChat(ChatData *chat) {
  44. _migratedFrom = chat;
  45. }
  46. const ChannelLocation *MegagroupInfo::getLocation() const {
  47. return _location.address.isEmpty() ? nullptr : &_location;
  48. }
  49. void MegagroupInfo::setLocation(const ChannelLocation &location) {
  50. _location = location;
  51. }
  52. Data::ChatBotCommands::Changed MegagroupInfo::setBotCommands(
  53. const std::vector<Data::BotCommands> &list) {
  54. return _botCommands.update(list);
  55. }
  56. void MegagroupInfo::ensureForum(not_null<ChannelData*> that) {
  57. if (!_forum) {
  58. const auto history = that->owner().history(that);
  59. _forum = std::make_unique<Data::Forum>(history);
  60. history->forumChanged(nullptr);
  61. }
  62. }
  63. Data::Forum *MegagroupInfo::forum() const {
  64. return _forum.get();
  65. }
  66. std::unique_ptr<Data::Forum> MegagroupInfo::takeForumData() {
  67. if (auto result = base::take(_forum)) {
  68. result->history()->forumChanged(result.get());
  69. return result;
  70. }
  71. return nullptr;
  72. }
  73. ChannelData::ChannelData(not_null<Data::Session*> owner, PeerId id)
  74. : PeerData(owner, id)
  75. , inputChannel(
  76. MTP_inputChannel(MTP_long(peerToChannel(id).bare), MTP_long(0)))
  77. , _ptsWaiter(&owner->session().updates()) {
  78. }
  79. void ChannelData::setPhoto(const MTPChatPhoto &photo) {
  80. photo.match([&](const MTPDchatPhoto & data) {
  81. updateUserpic(
  82. data.vphoto_id().v,
  83. data.vdc_id().v,
  84. data.is_has_video());
  85. }, [&](const MTPDchatPhotoEmpty &) {
  86. clearUserpic();
  87. });
  88. }
  89. void ChannelData::setName(
  90. const QString &newName,
  91. const QString &newUsername) {
  92. updateNameDelayed(newName.isEmpty() ? name() : newName, {}, newUsername);
  93. }
  94. void ChannelData::setUsername(const QString &username) {
  95. _username.setUsername(username);
  96. }
  97. void ChannelData::setUsernames(const Data::Usernames &newUsernames) {
  98. const auto wasUsername = username();
  99. const auto wasUsernames = usernames();
  100. _username.setUsernames(newUsernames);
  101. const auto nowUsername = username();
  102. const auto nowUsernames = usernames();
  103. session().changes().peerUpdated(
  104. this,
  105. UpdateFlag()
  106. | ((wasUsername != nowUsername)
  107. ? UpdateFlag::Username
  108. : UpdateFlag())
  109. | (!ranges::equal(wasUsernames, nowUsernames)
  110. ? UpdateFlag::Usernames
  111. : UpdateFlag()));
  112. }
  113. QString ChannelData::username() const {
  114. return _username.username();
  115. }
  116. QString ChannelData::editableUsername() const {
  117. return _username.editableUsername();
  118. }
  119. const std::vector<QString> &ChannelData::usernames() const {
  120. return _username.usernames();
  121. }
  122. bool ChannelData::isUsernameEditable(QString username) const {
  123. return _username.isEditable(username);
  124. }
  125. void ChannelData::setAccessHash(uint64 accessHash) {
  126. access = accessHash;
  127. input = MTP_inputPeerChannel(
  128. MTP_long(peerToChannel(id).bare),
  129. MTP_long(accessHash));
  130. inputChannel = MTP_inputChannel(
  131. MTP_long(peerToChannel(id).bare),
  132. MTP_long(accessHash));
  133. }
  134. void ChannelData::setFlags(ChannelDataFlags which) {
  135. const auto diff = flags() ^ which;
  136. if ((which & Flag::Megagroup) && !mgInfo) {
  137. mgInfo = std::make_unique<MegagroupInfo>();
  138. }
  139. // Let Data::Forum live till the end of _flags.set.
  140. // That way the data can be used in changes handler.
  141. // Example: render frame for forum auto-closing animation.
  142. const auto taken = ((diff & Flag::Forum) && !(which & Flag::Forum))
  143. ? mgInfo->takeForumData()
  144. : nullptr;
  145. const auto wasIn = amIn();
  146. if ((diff & Flag::Forum) && (which & Flag::Forum)) {
  147. mgInfo->ensureForum(this);
  148. }
  149. _flags.set(which);
  150. if (diff & (Flag::Left | Flag::Forbidden)) {
  151. if (const auto chat = getMigrateFromChat()) {
  152. session().changes().peerUpdated(chat, UpdateFlag::Migration);
  153. session().changes().peerUpdated(this, UpdateFlag::Migration);
  154. }
  155. if (wasIn && !amIn()) {
  156. crl::on_main(&session(), [=] {
  157. if (!amIn()) {
  158. Core::App().closeChatFromWindows(this);
  159. }
  160. });
  161. }
  162. }
  163. if (diff & (Flag::Forum
  164. | Flag::CallNotEmpty
  165. | Flag::SimilarExpanded
  166. | Flag::Signatures
  167. | Flag::SignatureProfiles)) {
  168. if (const auto history = this->owner().historyLoaded(this)) {
  169. if (diff & Flag::CallNotEmpty) {
  170. history->updateChatListEntry();
  171. }
  172. if (diff & Flag::Forum) {
  173. Core::App().notifications().clearFromHistory(history);
  174. history->updateChatListEntryHeight();
  175. if (history->inChatList()) {
  176. if (const auto forum = this->forum()) {
  177. forum->preloadTopics();
  178. }
  179. }
  180. }
  181. if (diff & Flag::SimilarExpanded) {
  182. if (const auto item = history->joinedMessageInstance()) {
  183. history->owner().requestItemResize(item);
  184. }
  185. }
  186. if (diff & Flag::SignatureProfiles) {
  187. history->forceFullResize();
  188. }
  189. if (diff & (Flag::Signatures | Flag::SignatureProfiles)) {
  190. session().changes().peerUpdated(this, UpdateFlag::Rights);
  191. }
  192. }
  193. }
  194. if (const auto raw = taken.get()) {
  195. owner().forumIcons().clearUserpicsReset(raw);
  196. }
  197. }
  198. void ChannelData::addFlags(ChannelDataFlags which) {
  199. setFlags(flags() | which);
  200. }
  201. void ChannelData::removeFlags(ChannelDataFlags which) {
  202. setFlags(flags() & ~which);
  203. }
  204. void ChannelData::setInviteLink(const QString &newInviteLink) {
  205. _inviteLink = newInviteLink;
  206. }
  207. bool ChannelData::canHaveInviteLink() const {
  208. return amCreator()
  209. || (adminRights() & AdminRight::InviteByLinkOrAdd);
  210. }
  211. void ChannelData::setLocation(const MTPChannelLocation &data) {
  212. if (!mgInfo) {
  213. return;
  214. }
  215. const auto was = mgInfo->getLocation();
  216. const auto wasValue = was ? *was : ChannelLocation();
  217. data.match([&](const MTPDchannelLocation &data) {
  218. data.vgeo_point().match([&](const MTPDgeoPoint &point) {
  219. mgInfo->setLocation({
  220. qs(data.vaddress()),
  221. Data::LocationPoint(point)
  222. });
  223. }, [&](const MTPDgeoPointEmpty &) {
  224. mgInfo->setLocation(ChannelLocation());
  225. });
  226. }, [&](const MTPDchannelLocationEmpty &) {
  227. mgInfo->setLocation(ChannelLocation());
  228. });
  229. const auto now = mgInfo->getLocation();
  230. const auto nowValue = now ? *now : ChannelLocation();
  231. if (was != now || (was && wasValue != nowValue)) {
  232. session().changes().peerUpdated(
  233. this,
  234. UpdateFlag::ChannelLocation);
  235. }
  236. }
  237. const ChannelLocation *ChannelData::getLocation() const {
  238. return mgInfo ? mgInfo->getLocation() : nullptr;
  239. }
  240. void ChannelData::setLinkedChat(ChannelData *linked) {
  241. if (_linkedChat != linked) {
  242. _linkedChat = linked;
  243. if (const auto history = owner().historyLoaded(this)) {
  244. history->forceFullResize();
  245. }
  246. session().changes().peerUpdated(this, UpdateFlag::ChannelLinkedChat);
  247. }
  248. }
  249. ChannelData *ChannelData::linkedChat() const {
  250. return _linkedChat.value_or(nullptr);
  251. }
  252. bool ChannelData::linkedChatKnown() const {
  253. return _linkedChat.has_value();
  254. }
  255. void ChannelData::setMembersCount(int newMembersCount) {
  256. if (_membersCount != newMembersCount) {
  257. if (isMegagroup()
  258. && canViewMembers()
  259. && !mgInfo->lastParticipants.empty()) {
  260. mgInfo->lastParticipantsStatus
  261. |= MegagroupInfo::LastParticipantsCountOutdated;
  262. mgInfo->lastParticipantsCount = membersCount();
  263. }
  264. _membersCount = newMembersCount;
  265. session().changes().peerUpdated(this, UpdateFlag::Members);
  266. }
  267. }
  268. void ChannelData::setAdminsCount(int newAdminsCount) {
  269. if (_adminsCount != newAdminsCount) {
  270. _adminsCount = newAdminsCount;
  271. session().changes().peerUpdated(this, UpdateFlag::Admins);
  272. }
  273. }
  274. void ChannelData::setRestrictedCount(int newRestrictedCount) {
  275. if (_restrictedCount != newRestrictedCount) {
  276. _restrictedCount = newRestrictedCount;
  277. session().changes().peerUpdated(this, UpdateFlag::BannedUsers);
  278. }
  279. }
  280. void ChannelData::setKickedCount(int newKickedCount) {
  281. if (_kickedCount != newKickedCount) {
  282. _kickedCount = newKickedCount;
  283. session().changes().peerUpdated(this, UpdateFlag::BannedUsers);
  284. }
  285. }
  286. void ChannelData::setPendingRequestsCount(
  287. int count,
  288. const QVector<MTPlong> &recentRequesters) {
  289. setPendingRequestsCount(count, ranges::views::all(
  290. recentRequesters
  291. ) | ranges::views::transform([&](const MTPlong &value) {
  292. return UserId(value);
  293. }) | ranges::to_vector);
  294. }
  295. void ChannelData::setPendingRequestsCount(
  296. int count,
  297. std::vector<UserId> recentRequesters) {
  298. if (_pendingRequestsCount != count
  299. || _recentRequesters != recentRequesters) {
  300. _pendingRequestsCount = count;
  301. _recentRequesters = std::move(recentRequesters);
  302. session().changes().peerUpdated(this, UpdateFlag::PendingRequests);
  303. }
  304. }
  305. ChatRestrictionsInfo ChannelData::KickedRestrictedRights(
  306. not_null<PeerData*> participant) {
  307. using Flag = ChatRestriction;
  308. const auto flags = Flag::ViewMessages
  309. | Flag::SendStickers
  310. | Flag::SendGifs
  311. | Flag::SendGames
  312. | Flag::SendInline
  313. | Flag::SendPhotos
  314. | Flag::SendVideos
  315. | Flag::SendVideoMessages
  316. | Flag::SendMusic
  317. | Flag::SendVoiceMessages
  318. | Flag::SendFiles
  319. | Flag::SendOther
  320. | Flag::EmbedLinks;
  321. return ChatRestrictionsInfo(
  322. (participant->isUser() ? flags : Flag::ViewMessages),
  323. std::numeric_limits<int32>::max());
  324. }
  325. void ChannelData::applyEditAdmin(
  326. not_null<UserData*> user,
  327. ChatAdminRightsInfo oldRights,
  328. ChatAdminRightsInfo newRights,
  329. const QString &rank) {
  330. if (mgInfo) {
  331. // If rights are empty - still add participant? TODO check
  332. if (!base::contains(mgInfo->lastParticipants, user)) {
  333. mgInfo->lastParticipants.push_front(user);
  334. setMembersCount(membersCount() + 1);
  335. if (user->isBot() && !mgInfo->bots.contains(user)) {
  336. mgInfo->bots.insert(user);
  337. if (mgInfo->botStatus != 0 && mgInfo->botStatus < 2) {
  338. mgInfo->botStatus = 2;
  339. }
  340. }
  341. }
  342. // If rights are empty - still remove restrictions? TODO check
  343. if (mgInfo->lastRestricted.contains(user)) {
  344. mgInfo->lastRestricted.remove(user);
  345. if (restrictedCount() > 0) {
  346. setRestrictedCount(restrictedCount() - 1);
  347. }
  348. }
  349. auto userId = peerToUser(user->id);
  350. auto it = mgInfo->lastAdmins.find(user);
  351. if (newRights.flags) {
  352. auto lastAdmin = MegagroupInfo::Admin { newRights };
  353. lastAdmin.canEdit = true;
  354. if (it == mgInfo->lastAdmins.cend()) {
  355. mgInfo->lastAdmins.emplace(user, lastAdmin);
  356. setAdminsCount(adminsCount() + 1);
  357. } else {
  358. it->second = lastAdmin;
  359. }
  360. Data::ChannelAdminChanges(this).add(userId, rank);
  361. } else {
  362. if (it != mgInfo->lastAdmins.cend()) {
  363. mgInfo->lastAdmins.erase(it);
  364. if (adminsCount() > 0) {
  365. setAdminsCount(adminsCount() - 1);
  366. }
  367. }
  368. Data::ChannelAdminChanges(this).remove(userId);
  369. }
  370. }
  371. if (oldRights.flags && !newRights.flags) {
  372. // We removed an admin.
  373. if (adminsCount() > 1) {
  374. setAdminsCount(adminsCount() - 1);
  375. }
  376. if (!isMegagroup() && user->isBot() && membersCount() > 1) {
  377. // Removing bot admin removes it from channel.
  378. setMembersCount(membersCount() - 1);
  379. }
  380. } else if (!oldRights.flags && newRights.flags) {
  381. // We added an admin.
  382. setAdminsCount(adminsCount() + 1);
  383. updateFullForced();
  384. }
  385. session().changes().peerUpdated(this, UpdateFlag::Admins);
  386. }
  387. void ChannelData::applyEditBanned(
  388. not_null<PeerData*> participant,
  389. ChatRestrictionsInfo oldRights,
  390. ChatRestrictionsInfo newRights) {
  391. auto flags = UpdateFlag::BannedUsers | UpdateFlag::None;
  392. auto isKicked = newRights.flags & ChatRestriction::ViewMessages;
  393. auto isRestricted = !isKicked && newRights.flags;
  394. const auto user = participant->asUser();
  395. if (mgInfo && user) {
  396. // If rights are empty - still remove admin? TODO check
  397. if (mgInfo->lastAdmins.contains(user)) {
  398. mgInfo->lastAdmins.remove(user);
  399. if (adminsCount() > 1) {
  400. setAdminsCount(adminsCount() - 1);
  401. } else {
  402. flags |= UpdateFlag::Admins;
  403. }
  404. }
  405. auto it = mgInfo->lastRestricted.find(user);
  406. if (isRestricted) {
  407. if (it == mgInfo->lastRestricted.cend()) {
  408. mgInfo->lastRestricted.emplace(
  409. user,
  410. MegagroupInfo::Restricted { newRights });
  411. setRestrictedCount(restrictedCount() + 1);
  412. } else {
  413. it->second.rights = newRights;
  414. }
  415. } else {
  416. if (it != mgInfo->lastRestricted.cend()) {
  417. mgInfo->lastRestricted.erase(it);
  418. if (restrictedCount() > 0) {
  419. setRestrictedCount(restrictedCount() - 1);
  420. }
  421. }
  422. if (isKicked) {
  423. auto i = ranges::find(
  424. mgInfo->lastParticipants,
  425. not_null{ user });
  426. if (i != mgInfo->lastParticipants.end()) {
  427. mgInfo->lastParticipants.erase(i);
  428. }
  429. if (membersCount() > 1) {
  430. setMembersCount(membersCount() - 1);
  431. } else {
  432. mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
  433. mgInfo->lastParticipantsCount = 0;
  434. }
  435. setKickedCount(kickedCount() + 1);
  436. if (mgInfo->bots.contains(user)) {
  437. mgInfo->bots.remove(user);
  438. if (mgInfo->bots.empty() && mgInfo->botStatus > 0) {
  439. mgInfo->botStatus = -1;
  440. }
  441. }
  442. flags |= UpdateFlag::Members;
  443. owner().removeMegagroupParticipant(this, user);
  444. }
  445. }
  446. Data::ChannelAdminChanges(this).remove(peerToUser(user->id));
  447. } else if (!mgInfo) {
  448. if (isKicked) {
  449. if (user && membersCount() > 1) {
  450. setMembersCount(membersCount() - 1);
  451. flags |= UpdateFlag::Members;
  452. }
  453. setKickedCount(kickedCount() + 1);
  454. }
  455. }
  456. session().changes().peerUpdated(this, flags);
  457. }
  458. void ChannelData::setViewAsMessagesFlag(bool enabled) {
  459. if (viewForumAsMessages() == enabled) {
  460. return;
  461. }
  462. setFlags((flags() & ~Flag::ViewAsMessages)
  463. | (enabled ? Flag::ViewAsMessages : Flag()));
  464. }
  465. void ChannelData::markForbidden() {
  466. owner().processChat(MTP_channelForbidden(
  467. MTP_flags(isMegagroup()
  468. ? MTPDchannelForbidden::Flag::f_megagroup
  469. : MTPDchannelForbidden::Flag::f_broadcast),
  470. MTP_long(peerToChannel(id).bare),
  471. MTP_long(access),
  472. MTP_string(name()),
  473. MTPint()));
  474. }
  475. bool ChannelData::isGroupAdmin(not_null<UserData*> user) const {
  476. if (auto info = mgInfo.get()) {
  477. return info->admins.contains(peerToUser(user->id));
  478. }
  479. return false;
  480. }
  481. bool ChannelData::lastParticipantsRequestNeeded() const {
  482. if (!mgInfo || !canViewMembers()) {
  483. return false;
  484. } else if (mgInfo->lastParticipantsCount == membersCount()) {
  485. mgInfo->lastParticipantsStatus
  486. &= ~MegagroupInfo::LastParticipantsCountOutdated;
  487. }
  488. return mgInfo->lastParticipants.empty()
  489. || !(mgInfo->lastParticipantsStatus
  490. & MegagroupInfo::LastParticipantsOnceReceived)
  491. || (mgInfo->lastParticipantsStatus
  492. & MegagroupInfo::LastParticipantsCountOutdated);
  493. }
  494. auto ChannelData::unavailableReasons() const
  495. -> const std::vector<Data::UnavailableReason> & {
  496. return _unavailableReasons;
  497. }
  498. void ChannelData::setUnavailableReasonsList(
  499. std::vector<Data::UnavailableReason> &&reasons) {
  500. _unavailableReasons = std::move(reasons);
  501. }
  502. void ChannelData::setAvailableMinId(MsgId availableMinId) {
  503. if (_availableMinId != availableMinId) {
  504. _availableMinId = availableMinId;
  505. }
  506. }
  507. bool ChannelData::canBanMembers() const {
  508. return amCreator()
  509. || (adminRights() & AdminRight::BanUsers);
  510. }
  511. bool ChannelData::canPostMessages() const {
  512. return amCreator()
  513. || (adminRights() & AdminRight::PostMessages);
  514. }
  515. bool ChannelData::canEditMessages() const {
  516. return amCreator()
  517. || (adminRights() & AdminRight::EditMessages);
  518. }
  519. bool ChannelData::canDeleteMessages() const {
  520. return amCreator()
  521. || (adminRights() & AdminRight::DeleteMessages);
  522. }
  523. bool ChannelData::canPostStories() const {
  524. return amCreator()
  525. || (adminRights() & AdminRight::PostStories);
  526. }
  527. bool ChannelData::canEditStories() const {
  528. return amCreator()
  529. || (adminRights() & AdminRight::EditStories);
  530. }
  531. bool ChannelData::canDeleteStories() const {
  532. return amCreator()
  533. || (adminRights() & AdminRight::DeleteStories);
  534. }
  535. bool ChannelData::canPostPaidMedia() const {
  536. return canPostMessages() && (flags() & Flag::PaidMediaAllowed);
  537. }
  538. bool ChannelData::anyoneCanAddMembers() const {
  539. return !(defaultRestrictions() & Restriction::AddParticipants);
  540. }
  541. bool ChannelData::hiddenPreHistory() const {
  542. return (flags() & Flag::PreHistoryHidden);
  543. }
  544. bool ChannelData::canAddMembers() const {
  545. return isMegagroup()
  546. ? !amRestricted(ChatRestriction::AddParticipants)
  547. : ((adminRights() & AdminRight::InviteByLinkOrAdd) || amCreator());
  548. }
  549. bool ChannelData::canAddAdmins() const {
  550. return amCreator()
  551. || (adminRights() & AdminRight::AddAdmins);
  552. }
  553. bool ChannelData::allowsForwarding() const {
  554. return !(flags() & Flag::NoForwards);
  555. }
  556. bool ChannelData::canViewMembers() const {
  557. return (flags() & Flag::CanViewParticipants)
  558. && (!(flags() & Flag::ParticipantsHidden)
  559. || amCreator()
  560. || hasAdminRights());
  561. }
  562. bool ChannelData::canViewAdmins() const {
  563. return (isMegagroup() || hasAdminRights() || amCreator());
  564. }
  565. bool ChannelData::canViewBanned() const {
  566. return (hasAdminRights() || amCreator());
  567. }
  568. bool ChannelData::canEditInformation() const {
  569. return isMegagroup()
  570. ? !amRestricted(Restriction::ChangeInfo)
  571. : ((adminRights() & AdminRight::ChangeInfo) || amCreator());
  572. }
  573. bool ChannelData::canEditPermissions() const {
  574. return isMegagroup()
  575. && !isGigagroup()
  576. && ((adminRights() & AdminRight::BanUsers) || amCreator());
  577. }
  578. bool ChannelData::canEditSignatures() const {
  579. return isChannel() && canEditInformation();
  580. }
  581. bool ChannelData::canEditPreHistoryHidden() const {
  582. return isMegagroup()
  583. && ((adminRights() & AdminRight::BanUsers) || amCreator())
  584. && (!isPublic() || canEditUsername());
  585. }
  586. bool ChannelData::canEditUsername() const {
  587. return amCreator()
  588. && (flags() & Flag::CanSetUsername);
  589. }
  590. bool ChannelData::canEditStickers() const {
  591. return (flags() & Flag::CanSetStickers);
  592. }
  593. bool ChannelData::canEditEmoji() const {
  594. return amCreator() || (adminRights() & ChatAdminRight::ChangeInfo);
  595. }
  596. bool ChannelData::canDelete() const {
  597. constexpr auto kDeleteChannelMembersLimit = 1000;
  598. return amCreator()
  599. && (membersCount() <= kDeleteChannelMembersLimit);
  600. }
  601. bool ChannelData::canEditLastAdmin(not_null<UserData*> user) const {
  602. // Duplicated in ParticipantsAdditionalData::canEditAdmin :(
  603. if (mgInfo) {
  604. auto i = mgInfo->lastAdmins.find(user);
  605. if (i != mgInfo->lastAdmins.cend()) {
  606. return i->second.canEdit;
  607. }
  608. return (user != mgInfo->creator);
  609. }
  610. return false;
  611. }
  612. bool ChannelData::canEditAdmin(not_null<UserData*> user) const {
  613. // Duplicated in ParticipantsAdditionalData::canEditAdmin :(
  614. if (user->isSelf()) {
  615. return false;
  616. } else if (amCreator()) {
  617. return true;
  618. } else if (!canEditLastAdmin(user)) {
  619. return false;
  620. }
  621. return adminRights() & AdminRight::AddAdmins;
  622. }
  623. bool ChannelData::canRestrictParticipant(
  624. not_null<PeerData*> participant) const {
  625. // Duplicated in ParticipantsAdditionalData::canRestrictParticipant :(
  626. if (participant->isSelf()) {
  627. return false;
  628. } else if (amCreator()) {
  629. return true;
  630. } else if (const auto user = participant->asUser()) {
  631. if (!canEditLastAdmin(user)) {
  632. return false;
  633. }
  634. }
  635. return adminRights() & AdminRight::BanUsers;
  636. }
  637. void ChannelData::setBotVerifyDetails(Ui::BotVerifyDetails details) {
  638. if (!details) {
  639. if (_botVerifyDetails) {
  640. _botVerifyDetails = nullptr;
  641. session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
  642. }
  643. } else if (!_botVerifyDetails) {
  644. _botVerifyDetails = std::make_unique<Ui::BotVerifyDetails>(details);
  645. session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
  646. } else if (*_botVerifyDetails != details) {
  647. *_botVerifyDetails = details;
  648. session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
  649. }
  650. }
  651. void ChannelData::setBotVerifyDetailsIcon(DocumentId iconId) {
  652. if (!iconId) {
  653. setBotVerifyDetails({});
  654. } else {
  655. auto info = _botVerifyDetails
  656. ? *_botVerifyDetails
  657. : Ui::BotVerifyDetails();
  658. info.iconId = iconId;
  659. setBotVerifyDetails(info);
  660. }
  661. }
  662. void ChannelData::setAdminRights(ChatAdminRights rights) {
  663. if (rights == adminRights()) {
  664. return;
  665. }
  666. _adminRights.set(rights);
  667. if (!canHaveInviteLink()) {
  668. setPendingRequestsCount(0, std::vector<UserId>{});
  669. }
  670. if (isMegagroup()) {
  671. const auto self = session().user();
  672. if (hasAdminRights()) {
  673. if (!amCreator()) {
  674. auto me = MegagroupInfo::Admin{
  675. ChatAdminRightsInfo{ rights } };
  676. me.canEdit = false;
  677. mgInfo->lastAdmins.emplace(self, me);
  678. }
  679. mgInfo->lastRestricted.remove(self);
  680. } else {
  681. mgInfo->lastAdmins.remove(self);
  682. }
  683. }
  684. session().changes().peerUpdated(
  685. this,
  686. UpdateFlag::Rights | UpdateFlag::Admins | UpdateFlag::BannedUsers);
  687. }
  688. void ChannelData::setRestrictions(ChatRestrictionsInfo rights) {
  689. if (rights.flags == restrictions() && rights.until == _restrictedUntil) {
  690. return;
  691. }
  692. _restrictedUntil = rights.until;
  693. _restrictions.set(rights.flags);
  694. if (isMegagroup()) {
  695. const auto self = session().user();
  696. if (hasRestrictions()) {
  697. if (!amCreator()) {
  698. auto me = MegagroupInfo::Restricted { rights };
  699. mgInfo->lastRestricted.emplace(self, me);
  700. }
  701. mgInfo->lastAdmins.remove(self);
  702. Data::ChannelAdminChanges(this).remove(session().userId());
  703. } else {
  704. mgInfo->lastRestricted.remove(self);
  705. }
  706. }
  707. session().changes().peerUpdated(
  708. this,
  709. UpdateFlag::Rights | UpdateFlag::Admins | UpdateFlag::BannedUsers);
  710. }
  711. void ChannelData::setDefaultRestrictions(ChatRestrictions rights) {
  712. if (rights == defaultRestrictions()) {
  713. return;
  714. }
  715. _defaultRestrictions.set(rights);
  716. session().changes().peerUpdated(this, UpdateFlag::Rights);
  717. }
  718. ChatData *ChannelData::getMigrateFromChat() const {
  719. if (const auto info = mgInfo.get()) {
  720. return info->getMigrateFromChat();
  721. }
  722. return nullptr;
  723. }
  724. void ChannelData::setMigrateFromChat(ChatData *chat) {
  725. Expects(mgInfo != nullptr);
  726. const auto info = mgInfo.get();
  727. if (chat != info->getMigrateFromChat()) {
  728. info->setMigrateFromChat(chat);
  729. if (amIn()) {
  730. session().changes().peerUpdated(this, UpdateFlag::Migration);
  731. }
  732. }
  733. }
  734. int ChannelData::slowmodeSeconds() const {
  735. if (const auto info = mgInfo.get()) {
  736. return info->slowmodeSeconds;
  737. }
  738. return 0;
  739. }
  740. void ChannelData::setSlowmodeSeconds(int seconds) {
  741. if (!mgInfo || slowmodeSeconds() == seconds) {
  742. return;
  743. }
  744. mgInfo->slowmodeSeconds = seconds;
  745. session().changes().peerUpdated(this, UpdateFlag::Slowmode);
  746. }
  747. TimeId ChannelData::slowmodeLastMessage() const {
  748. return (hasAdminRights()
  749. || amCreator()
  750. || unrestrictedByBoosts()
  751. || !mgInfo)
  752. ? 0
  753. : mgInfo->slowmodeLastMessage;
  754. }
  755. void ChannelData::growSlowmodeLastMessage(TimeId when) {
  756. const auto info = mgInfo.get();
  757. const auto now = base::unixtime::now();
  758. accumulate_min(when, now);
  759. if (!info) {
  760. return;
  761. } else if (info->slowmodeLastMessage > now) {
  762. info->slowmodeLastMessage = when;
  763. } else if (info->slowmodeLastMessage >= when) {
  764. return;
  765. } else {
  766. info->slowmodeLastMessage = when;
  767. }
  768. session().changes().peerUpdated(this, UpdateFlag::Slowmode);
  769. }
  770. int ChannelData::starsPerMessage() const {
  771. if (const auto info = mgInfo.get()) {
  772. return info->_starsPerMessage;
  773. }
  774. return 0;
  775. }
  776. void ChannelData::setStarsPerMessage(int stars) {
  777. if (mgInfo && starsPerMessage() != stars) {
  778. mgInfo->_starsPerMessage = stars;
  779. session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
  780. }
  781. checkTrustedPayForMessage();
  782. }
  783. int ChannelData::peerGiftsCount() const {
  784. return _peerGiftsCount;
  785. }
  786. void ChannelData::setPeerGiftsCount(int count) {
  787. if (_peerGiftsCount != count) {
  788. _peerGiftsCount = count;
  789. session().changes().peerUpdated(this, UpdateFlag::PeerGifts);
  790. }
  791. }
  792. int ChannelData::boostsApplied() const {
  793. if (const auto info = mgInfo.get()) {
  794. return info->boostsApplied;
  795. }
  796. return 0;
  797. }
  798. int ChannelData::boostsUnrestrict() const {
  799. if (const auto info = mgInfo.get()) {
  800. return info->boostsUnrestrict;
  801. }
  802. return 0;
  803. }
  804. bool ChannelData::unrestrictedByBoosts() const {
  805. if (const auto info = mgInfo.get()) {
  806. return (info->boostsUnrestrict > 0)
  807. && (info->boostsApplied >= info->boostsUnrestrict);
  808. }
  809. return 0;
  810. }
  811. rpl::producer<bool> ChannelData::unrestrictedByBoostsValue() const {
  812. return mgInfo
  813. ? mgInfo->unrestrictedByBoostsChanges.events_starting_with(
  814. unrestrictedByBoosts())
  815. : (rpl::single(false) | rpl::type_erased());
  816. }
  817. void ChannelData::setBoostsUnrestrict(int applied, int unrestrict) {
  818. if (const auto info = mgInfo.get()) {
  819. if (info->boostsApplied == applied
  820. && info->boostsUnrestrict == unrestrict) {
  821. return;
  822. }
  823. const auto wasUnrestricted = unrestrictedByBoosts();
  824. info->boostsApplied = applied;
  825. info->boostsUnrestrict = unrestrict;
  826. const auto nowUnrestricted = unrestrictedByBoosts();
  827. if (wasUnrestricted != nowUnrestricted) {
  828. info->unrestrictedByBoostsChanges.fire_copy(nowUnrestricted);
  829. session().changes().peerUpdated(
  830. this,
  831. UpdateFlag::Rights | UpdateFlag::Slowmode);
  832. }
  833. }
  834. }
  835. void ChannelData::setInvitePeek(const QString &hash, TimeId expires) {
  836. if (!_invitePeek) {
  837. _invitePeek = std::make_unique<InvitePeek>();
  838. }
  839. _invitePeek->hash = hash;
  840. _invitePeek->expires = expires;
  841. }
  842. void ChannelData::clearInvitePeek() {
  843. _invitePeek = nullptr;
  844. }
  845. TimeId ChannelData::invitePeekExpires() const {
  846. return _invitePeek ? _invitePeek->expires : 0;
  847. }
  848. QString ChannelData::invitePeekHash() const {
  849. return _invitePeek ? _invitePeek->hash : QString();
  850. }
  851. void ChannelData::privateErrorReceived() {
  852. if (const auto expires = invitePeekExpires()) {
  853. const auto hash = invitePeekHash();
  854. for (const auto &window : session().windows()) {
  855. clearInvitePeek();
  856. Api::CheckChatInvite(window, hash, this);
  857. return;
  858. }
  859. _invitePeek->expires = base::unixtime::now();
  860. } else {
  861. markForbidden();
  862. }
  863. }
  864. void ChannelData::migrateCall(std::unique_ptr<Data::GroupCall> call) {
  865. Expects(_call == nullptr);
  866. Expects(call != nullptr);
  867. _call = std::move(call);
  868. _call->setPeer(this);
  869. session().changes().peerUpdated(this, UpdateFlag::GroupCall);
  870. addFlags(Flag::CallActive);
  871. }
  872. void ChannelData::setGroupCall(
  873. const MTPInputGroupCall &call,
  874. TimeId scheduleDate,
  875. bool rtmp) {
  876. call.match([&](const MTPDinputGroupCall &data) {
  877. if (_call && _call->id() == data.vid().v) {
  878. return;
  879. } else if (!_call && !data.vid().v) {
  880. return;
  881. } else if (!data.vid().v) {
  882. clearGroupCall();
  883. return;
  884. }
  885. const auto hasCall = (_call != nullptr);
  886. if (hasCall) {
  887. owner().unregisterGroupCall(_call.get());
  888. }
  889. _call = std::make_unique<Data::GroupCall>(
  890. this,
  891. data.vid().v,
  892. data.vaccess_hash().v,
  893. scheduleDate,
  894. rtmp);
  895. owner().registerGroupCall(_call.get());
  896. session().changes().peerUpdated(this, UpdateFlag::GroupCall);
  897. addFlags(Flag::CallActive);
  898. });
  899. }
  900. void ChannelData::clearGroupCall() {
  901. if (!_call) {
  902. return;
  903. }
  904. owner().unregisterGroupCall(_call.get());
  905. _call = nullptr;
  906. session().changes().peerUpdated(this, UpdateFlag::GroupCall);
  907. removeFlags(Flag::CallActive | Flag::CallNotEmpty);
  908. }
  909. void ChannelData::setGroupCallDefaultJoinAs(PeerId peerId) {
  910. _callDefaultJoinAs = peerId;
  911. }
  912. PeerId ChannelData::groupCallDefaultJoinAs() const {
  913. return _callDefaultJoinAs;
  914. }
  915. void ChannelData::setAllowedReactions(Data::AllowedReactions value) {
  916. if (_allowedReactions != value) {
  917. if (value.paidEnabled) {
  918. session().api().globalPrivacy().loadPaidReactionShownPeer();
  919. }
  920. const auto enabled = [](const Data::AllowedReactions &allowed) {
  921. return (allowed.type != Data::AllowedReactionsType::Some)
  922. || !allowed.some.empty()
  923. || allowed.paidEnabled;
  924. };
  925. const auto was = enabled(_allowedReactions);
  926. _allowedReactions = std::move(value);
  927. const auto now = enabled(_allowedReactions);
  928. if (was != now) {
  929. owner().reactions().updateAllInHistory(this, now);
  930. }
  931. session().changes().peerUpdated(this, UpdateFlag::Reactions);
  932. }
  933. }
  934. const Data::AllowedReactions &ChannelData::allowedReactions() const {
  935. return _allowedReactions;
  936. }
  937. bool ChannelData::hasActiveStories() const {
  938. return flags() & Flag::HasActiveStories;
  939. }
  940. bool ChannelData::hasUnreadStories() const {
  941. return flags() & Flag::HasUnreadStories;
  942. }
  943. void ChannelData::setStoriesState(StoriesState state) {
  944. Expects(state != StoriesState::Unknown);
  945. const auto was = flags();
  946. switch (state) {
  947. case StoriesState::None:
  948. _flags.remove(Flag::HasActiveStories | Flag::HasUnreadStories);
  949. break;
  950. case StoriesState::HasRead:
  951. _flags.set(
  952. (flags() & ~Flag::HasUnreadStories) | Flag::HasActiveStories);
  953. break;
  954. case StoriesState::HasUnread:
  955. _flags.add(Flag::HasActiveStories | Flag::HasUnreadStories);
  956. break;
  957. }
  958. if (flags() != was) {
  959. if (const auto history = owner().historyLoaded(this)) {
  960. history->updateChatListEntryPostponed();
  961. }
  962. session().changes().peerUpdated(this, UpdateFlag::StoriesState);
  963. }
  964. }
  965. void ChannelData::processTopics(const MTPVector<MTPForumTopic> &topics) {
  966. if (const auto forum = this->forum()) {
  967. forum->applyReceivedTopics(topics);
  968. }
  969. }
  970. int ChannelData::levelHint() const {
  971. return _levelHint;
  972. }
  973. void ChannelData::updateLevelHint(int levelHint) {
  974. _levelHint = levelHint;
  975. }
  976. TimeId ChannelData::subscriptionUntilDate() const {
  977. return _subscriptionUntilDate;
  978. }
  979. void ChannelData::updateSubscriptionUntilDate(TimeId subscriptionUntilDate) {
  980. _subscriptionUntilDate = subscriptionUntilDate;
  981. }
  982. namespace Data {
  983. void ApplyMigration(
  984. not_null<ChatData*> chat,
  985. not_null<ChannelData*> channel) {
  986. Expects(channel->isMegagroup());
  987. chat->setMigrateToChannel(channel);
  988. channel->setMigrateFromChat(chat);
  989. }
  990. void ApplyChannelUpdate(
  991. not_null<ChannelData*> channel,
  992. const MTPDupdateChatDefaultBannedRights &update) {
  993. channel->setDefaultRestrictions(ChatRestrictionsInfo(
  994. update.vdefault_banned_rights()).flags);
  995. }
  996. void ApplyChannelUpdate(
  997. not_null<ChannelData*> channel,
  998. const MTPDchannelFull &update) {
  999. const auto session = &channel->session();
  1000. if (channel->isMegagroup()) {
  1001. const auto suggestions = update.vpending_suggestions().value_or_empty();
  1002. channel->owner().setSuggestToGigagroup(
  1003. channel,
  1004. ranges::contains(
  1005. suggestions,
  1006. "convert_to_gigagroup"_q,
  1007. &MTPstring::v));
  1008. }
  1009. channel->setAvailableMinId(update.vavailable_min_id().value_or_empty());
  1010. auto canViewAdmins = channel->canViewAdmins();
  1011. auto canViewMembers = channel->canViewMembers();
  1012. auto canEditStickers = channel->canEditStickers();
  1013. if (const auto call = update.vcall()) {
  1014. channel->setGroupCall(*call);
  1015. } else {
  1016. channel->clearGroupCall();
  1017. }
  1018. if (const auto as = update.vgroupcall_default_join_as()) {
  1019. channel->setGroupCallDefaultJoinAs(peerFromMTP(*as));
  1020. } else {
  1021. channel->setGroupCallDefaultJoinAs(0);
  1022. }
  1023. channel->setMessagesTTL(update.vttl_period().value_or_empty());
  1024. using Flag = ChannelDataFlag;
  1025. const auto mask = Flag::CanSetUsername
  1026. | Flag::CanViewParticipants
  1027. | Flag::CanSetStickers
  1028. | Flag::PreHistoryHidden
  1029. | Flag::AntiSpam
  1030. | Flag::Location
  1031. | Flag::ParticipantsHidden
  1032. | Flag::CanGetStatistics
  1033. | Flag::ViewAsMessages
  1034. | Flag::CanViewRevenue
  1035. | Flag::PaidMediaAllowed
  1036. | Flag::CanViewCreditsRevenue
  1037. | Flag::StargiftsAvailable
  1038. | Flag::PaidMessagesAvailable;
  1039. channel->setFlags((channel->flags() & ~mask)
  1040. | (update.is_can_set_username() ? Flag::CanSetUsername : Flag())
  1041. | (update.is_can_view_participants()
  1042. ? Flag::CanViewParticipants
  1043. : Flag())
  1044. | (update.is_can_set_stickers() ? Flag::CanSetStickers : Flag())
  1045. | (update.is_hidden_prehistory() ? Flag::PreHistoryHidden : Flag())
  1046. | (update.is_antispam() ? Flag::AntiSpam : Flag())
  1047. | (update.vlocation() ? Flag::Location : Flag())
  1048. | (update.is_participants_hidden()
  1049. ? Flag::ParticipantsHidden
  1050. : Flag())
  1051. | (update.is_can_view_stats() ? Flag::CanGetStatistics : Flag())
  1052. | (update.is_view_forum_as_messages()
  1053. ? Flag::ViewAsMessages
  1054. : Flag())
  1055. | (update.is_paid_media_allowed() ? Flag::PaidMediaAllowed : Flag())
  1056. | (update.is_can_view_revenue() ? Flag::CanViewRevenue : Flag())
  1057. | (update.is_can_view_stars_revenue()
  1058. ? Flag::CanViewCreditsRevenue
  1059. : Flag())
  1060. | (update.is_stargifts_available()
  1061. ? Flag::StargiftsAvailable
  1062. : Flag())
  1063. | (update.is_paid_messages_available()
  1064. ? Flag::PaidMessagesAvailable
  1065. : Flag()));
  1066. channel->setUserpicPhoto(update.vchat_photo());
  1067. if (const auto migratedFrom = update.vmigrated_from_chat_id()) {
  1068. channel->addFlags(Flag::Megagroup);
  1069. const auto chat = channel->owner().chat(migratedFrom->v);
  1070. Data::ApplyMigration(chat, channel);
  1071. }
  1072. channel->setAbout(qs(update.vabout()));
  1073. channel->setMembersCount(update.vparticipants_count().value_or_empty());
  1074. channel->setAdminsCount(update.vadmins_count().value_or_empty());
  1075. channel->setRestrictedCount(update.vbanned_count().value_or_empty());
  1076. channel->setKickedCount(update.vkicked_count().value_or_empty());
  1077. channel->setSlowmodeSeconds(update.vslowmode_seconds().value_or_empty());
  1078. channel->setPeerGiftsCount(update.vstargifts_count().value_or_empty());
  1079. if (const auto next = update.vslowmode_next_send_date()) {
  1080. channel->growSlowmodeLastMessage(
  1081. next->v - channel->slowmodeSeconds());
  1082. }
  1083. if (const auto invite = update.vexported_invite()) {
  1084. channel->session().api().inviteLinks().setMyPermanent(
  1085. channel,
  1086. *invite);
  1087. } else {
  1088. channel->session().api().inviteLinks().clearMyPermanent(channel);
  1089. }
  1090. if (const auto location = update.vlocation()) {
  1091. channel->setLocation(*location);
  1092. } else {
  1093. channel->setLocation(MTP_channelLocationEmpty());
  1094. }
  1095. if (const auto chat = update.vlinked_chat_id()) {
  1096. channel->setLinkedChat(channel->owner().channelLoaded(chat->v));
  1097. } else {
  1098. channel->setLinkedChat(nullptr);
  1099. }
  1100. if (const auto history = channel->owner().historyLoaded(channel)) {
  1101. if (const auto available = update.vavailable_min_id()) {
  1102. history->clearUpTill(available->v);
  1103. }
  1104. const auto folderId = update.vfolder_id().value_or_empty();
  1105. const auto folder = folderId
  1106. ? channel->owner().folderLoaded(folderId)
  1107. : nullptr;
  1108. auto &histories = channel->owner().histories();
  1109. if (folder && history->folder() != folder) {
  1110. // If history folder is unknown or not synced, request both.
  1111. histories.requestDialogEntry(history);
  1112. histories.requestDialogEntry(folder);
  1113. } else if (!history->folderKnown()
  1114. || channel->pts() != update.vpts().v) {
  1115. histories.requestDialogEntry(history);
  1116. } else {
  1117. history->applyDialogFields(
  1118. history->folder(),
  1119. update.vunread_count().v,
  1120. update.vread_inbox_max_id().v,
  1121. update.vread_outbox_max_id().v);
  1122. }
  1123. }
  1124. if (const auto pinned = update.vpinned_msg_id()) {
  1125. SetTopPinnedMessageId(channel, pinned->v);
  1126. }
  1127. if (channel->isMegagroup()) {
  1128. auto commands = ranges::views::all(
  1129. update.vbot_info().v
  1130. ) | ranges::views::transform(
  1131. Data::BotCommandsFromTL
  1132. ) | ranges::to_vector;
  1133. if (channel->mgInfo->setBotCommands(std::move(commands))) {
  1134. channel->owner().botCommandsChanged(channel);
  1135. }
  1136. const auto stickerSet = update.vstickerset();
  1137. const auto sset = stickerSet ? &stickerSet->c_stickerSet() : nullptr;
  1138. const auto newStickerSetId = (sset ? sset->vid().v : 0);
  1139. const auto oldStickerSetId = channel->mgInfo->stickerSet.id;
  1140. const auto stickersChanged = (canEditStickers != channel->canEditStickers())
  1141. || (oldStickerSetId != newStickerSetId);
  1142. if (oldStickerSetId != newStickerSetId) {
  1143. channel->mgInfo->stickerSet = StickerSetIdentifier{
  1144. .id = sset ? sset->vid().v : 0,
  1145. .accessHash = sset ? sset->vaccess_hash().v : 0,
  1146. };
  1147. }
  1148. if (stickersChanged) {
  1149. session->changes().peerUpdated(channel, UpdateFlag::StickersSet);
  1150. }
  1151. const auto emojiSet = update.vemojiset();
  1152. const auto eset = emojiSet ? &emojiSet->c_stickerSet() : nullptr;
  1153. const auto newEmojiSetId = (eset ? eset->vid().v : 0);
  1154. const auto oldEmojiSetId = channel->mgInfo->emojiSet.id;
  1155. const auto emojiChanged = (oldEmojiSetId != newEmojiSetId);
  1156. if (oldEmojiSetId != newEmojiSetId) {
  1157. channel->mgInfo->emojiSet = StickerSetIdentifier{
  1158. .id = eset ? eset->vid().v : 0,
  1159. .accessHash = eset ? eset->vaccess_hash().v : 0,
  1160. };
  1161. }
  1162. if (emojiChanged) {
  1163. session->changes().peerUpdated(channel, UpdateFlag::EmojiSet);
  1164. }
  1165. channel->setBoostsUnrestrict(
  1166. update.vboosts_applied().value_or_empty(),
  1167. update.vboosts_unrestrict().value_or_empty());
  1168. }
  1169. channel->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty()));
  1170. channel->setTranslationDisabled(update.is_translations_disabled());
  1171. const auto reactionsLimit = update.vreactions_limit().value_or_empty();
  1172. if (const auto allowed = update.vavailable_reactions()) {
  1173. auto parsed = Data::Parse(
  1174. *allowed,
  1175. reactionsLimit,
  1176. update.is_paid_reactions_available());
  1177. channel->setAllowedReactions(std::move(parsed));
  1178. } else {
  1179. channel->setAllowedReactions({
  1180. .maxCount = reactionsLimit,
  1181. .paidEnabled = update.is_paid_reactions_available(),
  1182. });
  1183. }
  1184. channel->setBotVerifyDetails(
  1185. ParseBotVerifyDetails(update.vbot_verification()));
  1186. channel->owner().stories().apply(channel, update.vstories());
  1187. channel->fullUpdated();
  1188. channel->setPendingRequestsCount(
  1189. update.vrequests_pending().value_or_empty(),
  1190. update.vrecent_requesters().value_or_empty());
  1191. if (canViewAdmins != channel->canViewAdmins()
  1192. || canViewMembers != channel->canViewMembers()) {
  1193. session->changes().peerUpdated(channel, UpdateFlag::Rights);
  1194. }
  1195. channel->owner().notifySettings().apply(
  1196. channel,
  1197. update.vnotify_settings());
  1198. if (update.vstats_dc()) {
  1199. channel->owner().applyStatsDcId(channel, update.vstats_dc()->v);
  1200. }
  1201. if (const auto sendAs = update.vdefault_send_as()) {
  1202. session->sendAsPeers().setChosen(channel, peerFromMTP(*sendAs));
  1203. } else {
  1204. session->sendAsPeers().setChosen(channel, PeerId());
  1205. }
  1206. if (const auto paper = update.vwallpaper()) {
  1207. channel->setWallPaper(
  1208. Data::WallPaper::Create(&channel->session(), *paper));
  1209. } else {
  1210. channel->setWallPaper({});
  1211. }
  1212. // For clearUpTill() call.
  1213. channel->owner().sendHistoryChangeNotifications();
  1214. }
  1215. } // namespace Data