From 69f6a1ee79bbd4582c58e5d288d5b5e65da7c11b Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 29 Oct 2015 15:10:49 -0400 Subject: [PATCH] chat admins state is read and updated --- Telegram/Resources/lang.strings | 4 +- Telegram/SourceFiles/app.cpp | 149 ++++++++++++++--- Telegram/SourceFiles/app.h | 2 + Telegram/SourceFiles/boxes/contactsbox.cpp | 8 +- Telegram/SourceFiles/historywidget.cpp | 4 +- Telegram/SourceFiles/localstorage.cpp | 16 +- Telegram/SourceFiles/mainwidget.cpp | 47 +++--- Telegram/SourceFiles/mainwidget.h | 2 +- Telegram/SourceFiles/mtproto/mtpCoreTypes.cpp | 14 -- Telegram/SourceFiles/mtproto/mtpScheme.cpp | 125 ++++++++------ Telegram/SourceFiles/mtproto/mtpScheme.h | 155 +++++++++++++++--- Telegram/SourceFiles/mtproto/scheme.tl | 22 +-- Telegram/SourceFiles/profilewidget.cpp | 44 +++-- Telegram/SourceFiles/structs.h | 38 ++++- 14 files changed, 446 insertions(+), 184 deletions(-) diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index 9f23087302..f826ffd2dc 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -103,7 +103,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org "lng_channel_status" = "channel"; "lng_channel_members_link" = "{count:_not_used_|# member|# members} »"; -"lng_channel_admins_link" = "{count:_not_used_|# administrator|# administrators} »"; +"lng_channel_admins_link" = "{count:Manage administrators|# administrator|# administrators} »"; "lng_server_error" = "Internal server error."; "lng_flood_error" = "Too many tries. Please try again later."; @@ -430,7 +430,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org "lng_channel_admins" = "Administrators"; "lng_channel_add_admin" = "Add Administrator"; "lng_channel_admin_sure" = "Add {user} to administrators?"; -"lng_channel_admins_too_much" = "Sorry, you have reached the limit of channel administrators. Please remove some administrator first."; +"lng_channel_admins_too_much" = "Sorry, you have reached the limit of channel administrators. Please remove one administrator first."; "lng_participant_filter" = "Search"; "lng_participant_invite" = "Invite"; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 802e1ecc2f..af51a095e4 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -502,9 +502,14 @@ namespace App { ChatData *cdata = data->asChat(); cdata->setPhoto(d.vphoto); cdata->date = d.vdate.v; + + if (!(cdata->flags & MTPDchat::flag_admins_enabled) && (d.vflags.v & MTPDchat::flag_admins_enabled)) { + cdata->invalidateParticipants(false); + } + cdata->flags = d.vflags.v; + cdata->count = d.vparticipants_count.v; - cdata->isForbidden = d.is_kicked(); - cdata->haveLeft = d.is_left(); + cdata->isForbidden = false; if (cdata->version < d.vversion.v) { cdata->version = d.vversion.v; cdata->participants = ChatData::Participants(); @@ -523,8 +528,8 @@ namespace App { cdata->setPhoto(MTP_chatPhotoEmpty()); cdata->date = 0; cdata->count = -1; + cdata->flags = 0; cdata->isForbidden = true; - cdata->haveLeft = false; } break; case mtpc_channel: { const MTPDchannel &d(chat.c_channel()); @@ -589,34 +594,55 @@ namespace App { const MTPDchatParticipantsForbidden &d(p.c_chatParticipantsForbidden()); chat = App::chat(d.vchat_id.v); chat->count = -1; + chat->participants = ChatData::Participants(); + chat->invitedByMe = ChatData::InvitedByMe(); + chat->admins = ChatData::Admins(); } break; case mtpc_chatParticipants: { const MTPDchatParticipants &d(p.c_chatParticipants()); chat = App::chat(d.vchat_id.v); - chat->creator = d.vadmin_id.v; if (!requestBotInfos || chat->version <= d.vversion.v) { // !requestBotInfos is true on getFullChat result chat->version = d.vversion.v; const QVector &v(d.vparticipants.c_vector().v); chat->count = v.size(); int32 pversion = chat->participants.isEmpty() ? 1 : (chat->participants.begin().value() + 1); - chat->cankick = ChatData::CanKick(); + chat->invitedByMe = ChatData::InvitedByMe(); + chat->admins = ChatData::Admins(); for (QVector::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { - if (i->type() != mtpc_chatParticipant) continue; + int32 uid = 0, inviter = 0; + switch (i->type()) { + case mtpc_chatParticipantCreator: { + const MTPDchatParticipantCreator &p(i->c_chatParticipantCreator()); + uid = p.vuser_id.v; + chat->creator = uid; + } break; + case mtpc_chatParticipantAdmin: { + const MTPDchatParticipantAdmin &p(i->c_chatParticipantAdmin()); + uid = p.vuser_id.v; + inviter = p.vinviter_id.v; + } break; + case mtpc_chatParticipant: { + const MTPDchatParticipant &p(i->c_chatParticipant()); + uid = p.vuser_id.v; + inviter = p.vinviter_id.v; + } break; + } + if (!uid) continue; - const MTPDchatParticipant &p(i->c_chatParticipant()); - //if (p.vuser_id.v == MTP::authedId()) { - // chat->inviter = p.vinviter_id.v; // we use inviter only from service msgs - // chat->inviteDate = p.vdate.v; - //} - UserData *user = App::userLoaded(p.vuser_id.v); + UserData *user = App::userLoaded(uid); if (user) { chat->participants[user] = pversion; - if (p.vinviter_id.v == MTP::authedId()) { - chat->cankick[user] = true; + if (inviter == MTP::authedId()) { + chat->invitedByMe[user] = true; + } + if (i->type() == mtpc_chatParticipantAdmin) { + chat->admins[user] = true; } } else { chat->participants = ChatData::Participants(); + chat->invitedByMe = ChatData::InvitedByMe(); + chat->admins = ChatData::Admins(); chat->botStatus = 0; break; } @@ -660,12 +686,17 @@ namespace App { void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d, bool emitPeerUpdated) { ChatData *chat = App::chat(d.vchat_id.v); - if (chat->version <= d.vversion.v && chat->count >= 0) { + if (chat->version + 1 < d.vversion.v) { + chat->invalidateParticipants(); + if (App::main()) { + if (emitPeerUpdated) { + App::main()->peerUpdated(chat); + } else { + markPeerUpdated(chat); + } + } + } else if (chat->version <= d.vversion.v && chat->count >= 0) { chat->version = d.vversion.v; - //if (d.vuser_id.v == MTP::authedId()) { - // chat->inviter = d.vinviter_id.v; // we use inviter only from service msgs - // chat->inviteDate = unixtime(); // no event date here :( - //} UserData *user = App::userLoaded(d.vuser_id.v); if (user) { if (chat->participants.isEmpty() && chat->count) { @@ -674,9 +705,9 @@ namespace App { } else if (chat->participants.find(user) == chat->participants.end()) { chat->participants[user] = (chat->participants.isEmpty() ? 1 : chat->participants.begin().value()); if (d.vinviter_id.v == MTP::authedId()) { - chat->cankick[user] = true; + chat->invitedByMe[user] = true; } else { - chat->cankick.remove(user); + chat->invitedByMe.remove(user); } chat->count++; if (user->botInfo) { @@ -685,8 +716,7 @@ namespace App { } } } else { - chat->participants = ChatData::Participants(); - chat->botStatus = 0; + chat->invalidateParticipants(false); chat->count++; } if (App::main()) { @@ -701,7 +731,16 @@ namespace App { void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d, bool emitPeerUpdated) { ChatData *chat = App::chat(d.vchat_id.v); - if (chat->version <= d.vversion.v && chat->count > 0) { + if (chat->version + 1 < d.vversion.v) { + chat->invalidateParticipants(); + if (App::main()) { + if (emitPeerUpdated) { + App::main()->peerUpdated(chat); + } else { + markPeerUpdated(chat); + } + } + } else if (chat->version <= d.vversion.v && chat->count > 0) { chat->version = d.vversion.v; UserData *user = App::userLoaded(d.vuser_id.v); if (user) { @@ -712,6 +751,8 @@ namespace App { if (i != chat->participants.end()) { chat->participants.erase(i); chat->count--; + chat->invitedByMe.remove(user); + chat->admins.remove(user); History *h = App::historyLoaded(chat->id); if (h && h->lastKeyboardFrom == user->id) { @@ -735,8 +776,7 @@ namespace App { } } } else { - chat->participants = ChatData::Participants(); - chat->botStatus = 0; + chat->invalidateParticipants(false); chat->count--; } if (App::main()) { @@ -749,6 +789,63 @@ namespace App { } } + void feedChatAdmins(const MTPDupdateChatAdmins &d, bool emitPeerUpdated) { + ChatData *chat = App::chat(d.vchat_id.v); + if (chat->version <= d.vversion.v) { + bool badVersion = (chat->version + 1 < d.vversion.v); + if (badVersion) { + chat->invalidateParticipants(); + } + chat->version = d.vversion.v; + if (mtpIsTrue(d.venabled)) { + chat->flags |= MTPDchat::flag_admins_enabled; + if (!badVersion) { + chat->invalidateParticipants(false); + } + } else { + chat->flags &= ~MTPDchat::flag_admins_enabled; + } + if (emitPeerUpdated) { + App::main()->peerUpdated(chat); + } else { + markPeerUpdated(chat); + } + } + } + + void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d, bool emitPeerUpdated) { + ChatData *chat = App::chat(d.vchat_id.v); + if (chat->version + 1 < d.vversion.v) { + chat->invalidateParticipants(); + if (App::main()) { + if (emitPeerUpdated) { + App::main()->peerUpdated(chat); + } else { + markPeerUpdated(chat); + } + } + } else if (chat->version <= d.vversion.v && chat->count > 0) { + chat->version = d.vversion.v; + UserData *user = App::userLoaded(d.vuser_id.v); + if (user) { + if (mtpIsTrue(d.vis_admin)) { + chat->admins.insert(user, true); + } else { + chat->admins.remove(user); + } + } else { + chat->invalidateParticipants(false); + } + if (App::main()) { + if (emitPeerUpdated) { + App::main()->peerUpdated(chat); + } else { + markPeerUpdated(chat); + } + } + } + } + bool checkEntitiesAndViewsUpdate(const MTPDmessage &m) { PeerId peerId = peerFromMTP(m.vto_id); if (m.has_from_id() && peerToUser(peerId) == MTP::authedId()) { diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index ab9f49140d..615be17a36 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -105,6 +105,8 @@ namespace App { void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos, bool emitPeerUpdated = true); void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d, bool emitPeerUpdated = true); void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d, bool emitPeerUpdated = true); + void feedChatAdmins(const MTPDupdateChatAdmins &d, bool emitPeerUpdated = true); + void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d, bool emitPeerUpdated = true); bool checkEntitiesAndViewsUpdate(const MTPDmessage &m); // returns true if item found and it is not detached void feedMsgs(const MTPVector &msgs, NewMessageType type); void feedInboxRead(const PeerId &peer, MsgId upTo); diff --git a/Telegram/SourceFiles/boxes/contactsbox.cpp b/Telegram/SourceFiles/boxes/contactsbox.cpp index 32bafe8907..8a3a7904b9 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.cpp +++ b/Telegram/SourceFiles/boxes/contactsbox.cpp @@ -129,7 +129,7 @@ ContactsInner::ContactsInner(UserData *bot) : TWidget() , _addContactLnk(this, lang(lng_add_contact_button)) { DialogsIndexed &v(App::main()->dialogsList()); for (DialogRow *r = v.list.begin; r != v.list.end; r = r->next) { - if (r->history->peer->isChat() && !r->history->peer->asChat()->isForbidden && !r->history->peer->asChat()->haveLeft) { + if (r->history->peer->isChat() && r->history->peer->asChat()->amIn()) { _contacts->addToEnd(r->history); } } @@ -197,12 +197,12 @@ bool ContactsInner::addAdminFail(const RPCError &error, mtpRequestId req) { if (req != _addAdminRequestId) return true; _addAdminRequestId = 0; + if (_addAdminBox) _addAdminBox->onClose(); if (error.type() == "USERS_TOO_MUCH") { App::wnd()->replaceLayer(new MaxInviteBox(_channel->invitationUrl)); } else if (error.type() == "ADMINS_TOO_MUCH") { App::wnd()->replaceLayer(new InformBox(lang(lng_channel_admins_too_much))); } else { - if (_addAdminBox) _addAdminBox->onClose(); emit adminAdded(); } return true; @@ -210,7 +210,7 @@ bool ContactsInner::addAdminFail(const RPCError &error, mtpRequestId req) { void ContactsInner::peerUpdated(PeerData *peer) { if (_chat && (!peer || peer == _chat)) { - if (_chat->isForbidden || _chat->haveLeft) { + if (!_chat->amIn()) { App::wnd()->hideLayer(); } else if (!_chat->participants.isEmpty() || _chat->count <= 0) { for (ContactsData::iterator i = _contactsData.begin(), e = _contactsData.end(); i != e; ++i) { @@ -308,7 +308,7 @@ ContactsInner::ContactData *ContactsInner::contactData(DialogRow *row) { data->online = App::onlineText(peer->asUser(), _time); } else if (peer->isChat()) { ChatData *chat = peer->asChat(); - if (chat->isForbidden || chat->haveLeft) { + if (!chat->amIn()) { data->online = lang(lng_chat_status_unaccessible); } else { data->online = lng_chat_status_members(lt_count, chat->count); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index fb0b520680..26539587a0 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -4435,7 +4435,7 @@ bool HistoryWidget::canSendMessages(PeerData *peer) const { if (peer->isUser()) { return peer->asUser()->access != UserNoAccess; } else if (peer->isChat()) { - return !peer->asChat()->isForbidden && !peer->asChat()->haveLeft; + return peer->asChat()->amIn(); } else if (peer->isChannel()) { return peer->asChannel()->amIn() && (peer->asChannel()->canPublish() || !peer->asChannel()->isBroadcast()); } @@ -4683,7 +4683,7 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) { text = App::onlineText(_peer->asUser(), t); } else if (_peer->isChat()) { ChatData *chat = _peer->asChat(); - if (chat->isForbidden || chat->haveLeft) { + if (!chat->amIn()) { text = lang(lng_chat_status_unaccessible); } else if (chat->participants.isEmpty()) { text = _titlePeerText.isEmpty() ? lng_chat_status_members(lt_count, chat->count < 0 ? 0 : chat->count) : _titlePeerText; diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index ebbad9f3d9..fc1fa6764e 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -2973,8 +2973,10 @@ namespace Local { } else if (peer->isChat()) { ChatData *chat = peer->asChat(); + qint32 flagsData = (AppVersion >= 9009) ? chat->flags : (chat->haveLeft() ? 1 : 0); + stream << chat->name << qint32(chat->count) << qint32(chat->date) << qint32(chat->version) << qint32(chat->creator); - stream << qint32(chat->isForbidden ? 1 : 0) << qint32(chat->haveLeft ? 1 : 0) << chat->invitationUrl; + stream << qint32(chat->isForbidden ? 1 : 0) << qint32(flagsData) << chat->invitationUrl; } else if (peer->isChannel()) { ChannelData *channel = peer->asChannel(); @@ -3028,16 +3030,22 @@ namespace Local { ChatData *chat = result->asChat(); QString name, invitationUrl; - qint32 count, date, version, creator, forbidden, left; - from.stream >> name >> count >> date >> version >> creator >> forbidden >> left >> invitationUrl; + qint32 count, date, version, creator, forbidden, flagsData, flags; + from.stream >> name >> count >> date >> version >> creator >> forbidden >> flagsData >> invitationUrl; + if (from.version >= 9009) { + flags = flagsData; + } else { + // flagsData was haveLeft + flags = (flagsData == 1 ? MTPDchat::flag_left : 0); + } chat->updateName(name, QString(), QString()); chat->count = count; chat->date = date; chat->version = version; chat->creator = creator; chat->isForbidden = (forbidden == 1); - chat->haveLeft = (left == 1); + chat->flags = flags; chat->invitationUrl = invitationUrl; chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id))); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 0573393431..912c4dee2a 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -293,10 +293,10 @@ void TopBarWidget::showAll() { PeerData *p = App::main() ? App::main()->profilePeer() : 0, *h = App::main() ? App::main()->historyPeer() : 0, *o = App::main() ? App::main()->overviewPeer() : 0; if (p && (p->isChat() || (p->isUser() && (p->asUser()->contact >= 0 || !App::phoneFromSharedContact(peerToUser(p->id)).isEmpty())))) { if (p->isChat()) { - if (p->asChat()->isForbidden) { - _edit.hide(); - } else { + if (p->asChat()->amIn()) { _edit.show(); + } else { + _edit.hide(); } _leaveGroup.show(); _addContact.hide(); @@ -477,7 +477,7 @@ MainWidget::MainWidget(Window *window) : TWidget(window) bool MainWidget::onForward(const PeerId &peer, ForwardWhatMessages what) { PeerData *p = App::peer(peer); - if (!peer || (p->isChannel() && !p->asChannel()->canPublish() && p->asChannel()->isBroadcast()) || (p->isChat() && (p->asChat()->haveLeft || p->asChat()->isForbidden)) || (p->isUser() && p->asUser()->access == UserNoAccess)) { + if (!peer || (p->isChannel() && !p->asChannel()->canPublish() && p->asChannel()->isBroadcast()) || (p->isChat() && !p->asChat()->amIn()) || (p->isUser() && p->asUser()->access == UserNoAccess)) { App::wnd()->showLayer(new InformBox(lang(lng_forward_cant))); return false; } @@ -511,7 +511,7 @@ bool MainWidget::onForward(const PeerId &peer, ForwardWhatMessages what) { bool MainWidget::onShareUrl(const PeerId &peer, const QString &url, const QString &text) { PeerData *p = App::peer(peer); - if (!peer || (p->isChannel() && !p->asChannel()->canPublish() && p->asChannel()->isBroadcast()) || (p->isChat() && (p->asChat()->haveLeft || p->asChat()->isForbidden)) || (p->isUser() && p->asUser()->access == UserNoAccess)) { + if (!peer || (p->isChannel() && !p->asChannel()->canPublish() && p->asChannel()->isBroadcast()) || (p->isChat() && !p->asChat()->amIn()) || (p->isUser() && p->asUser()->access == UserNoAccess)) { App::wnd()->showLayer(new InformBox(lang(lng_share_cant))); return false; } @@ -1032,7 +1032,7 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu if (!v) return; if (v->isEmpty()) { - if (peer->isChat() && peer->asChat()->haveLeft) { + if (peer->isChat() && peer->asChat()->haveLeft()) { deleteConversation(peer, false); } else if (peer->isChannel()) { if (peer->asChannel()->inviter > 0 && peer->asChannel()->amIn()) { @@ -1591,7 +1591,7 @@ void MainWidget::sendReadRequest(PeerData *peer, MsgId upTo) { if (peer->isChannel()) { _readRequests.insert(peer, qMakePair(MTP::send(MTPchannels_ReadHistory(peer->asChannel()->inputChannel, MTP_int(upTo)), rpcDone(&MainWidget::channelWasRead, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo)); } else { - _readRequests.insert(peer, qMakePair(MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(upTo), MTP_int(0)), rpcDone(&MainWidget::partWasRead, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo)); + _readRequests.insert(peer, qMakePair(MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(upTo)), rpcDone(&MainWidget::historyWasRead, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo)); } } @@ -1599,19 +1599,9 @@ void MainWidget::channelWasRead(PeerData *peer, const MTPBool &result) { readRequestDone(peer); } -void MainWidget::partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result) { - const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory()); - if (ptsUpdated(d.vpts.v, d.vpts_count.v)) { - ptsApplySkippedUpdates(); - App::emitPeerUpdated(); - } - - int32 offset = d.voffset.v; - if (!MTP::authedId() || offset <= 0) { - readRequestDone(peer); - } else { - _readRequests[peer].first = MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(_readRequests[peer].second), MTP_int(offset)), rpcDone(&MainWidget::partWasRead, peer)); - } +void MainWidget::historyWasRead(PeerData *peer, const MTPmessages_AffectedMessages &result) { + messagesAffected(peer, result); + readRequestDone(peer); } bool MainWidget::readRequestFail(PeerData *peer, const RPCError &error) { @@ -4372,18 +4362,23 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { } break; case mtpc_updateChatParticipants: { - const MTPDupdateChatParticipants &d(update.c_updateChatParticipants()); - App::feedParticipants(d.vparticipants, true, false); + App::feedParticipants(update.c_updateChatParticipants().vparticipants, true, false); } break; case mtpc_updateChatParticipantAdd: { - const MTPDupdateChatParticipantAdd &d(update.c_updateChatParticipantAdd()); - App::feedParticipantAdd(d, false); + App::feedParticipantAdd(update.c_updateChatParticipantAdd(), false); } break; case mtpc_updateChatParticipantDelete: { - const MTPDupdateChatParticipantDelete &d(update.c_updateChatParticipantDelete()); - App::feedParticipantDelete(d, false); + App::feedParticipantDelete(update.c_updateChatParticipantDelete(), false); + } break; + + case mtpc_updateChatAdmins: { + App::feedChatAdmins(update.c_updateChatAdmins(), false); + } break; + + case mtpc_updateChatParticipantAdmin: { + App::feedParticipantAdmin(update.c_updateChatParticipantAdmin(), false); } break; case mtpc_updateUserStatus: { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 599f6ab97b..66b4533cde 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -490,7 +490,7 @@ private: void sendReadRequest(PeerData *peer, MsgId upTo); void channelWasRead(PeerData *peer, const MTPBool &result); - void partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result); + void historyWasRead(PeerData *peer, const MTPmessages_AffectedMessages &result); bool readRequestFail(PeerData *peer, const RPCError &error); void readRequestDone(PeerData *peer); diff --git a/Telegram/SourceFiles/mtproto/mtpCoreTypes.cpp b/Telegram/SourceFiles/mtproto/mtpCoreTypes.cpp index 761fe57e4b..57904985c5 100644 --- a/Telegram/SourceFiles/mtproto/mtpCoreTypes.cpp +++ b/Telegram/SourceFiles/mtproto/mtpCoreTypes.cpp @@ -86,20 +86,6 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP to.add("]"); } break; - case mtpc_error: { - to.add("{ error"); - to.add("\n").addSpaces(level); - to.add(" code: "); mtpTextSerializeType(to, from, end, mtpc_int, level + 1); to.add(",\n").addSpaces(level); - to.add(" text: "); mtpTextSerializeType(to, from, end, mtpc_string, level + 1); to.add(",\n").addSpaces(level); - to.add("}"); - } break; - - case mtpc_null: { - to.add("{ null"); - to.add(" "); - to.add("}"); - } break; - case mtpc_gzip_packed: { MTPstring packed(from, end); // read packed string as serialized mtp string type uint32 packedLen = packed.c_string().v.size(), unpackedChunk = packedLen; diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.cpp b/Telegram/SourceFiles/mtproto/mtpScheme.cpp index e13d27d62b..9f5f551db1 100644 --- a/Telegram/SourceFiles/mtproto/mtpScheme.cpp +++ b/Telegram/SourceFiles/mtproto/mtpScheme.cpp @@ -1215,7 +1215,7 @@ void _serialize_chat(MTPStringLogger &to, int32 stage, int32 lev, Types &types, case 1: to.add(" creator: "); ++stages.back(); if (flag & MTPDchat::flag_creator) { to.add("NO [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break; case 2: to.add(" kicked: "); ++stages.back(); if (flag & MTPDchat::flag_kicked) { to.add("NO [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break; case 3: to.add(" left: "); ++stages.back(); if (flag & MTPDchat::flag_left) { to.add("NO [ BY BIT 2 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; - case 4: to.add(" has_admins: "); ++stages.back(); if (flag & MTPDchat::flag_has_admins) { to.add("NO [ BY BIT 3 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break; + case 4: to.add(" admins_enabled: "); ++stages.back(); if (flag & MTPDchat::flag_admins_enabled) { to.add("NO [ BY BIT 3 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break; case 5: to.add(" admin: "); ++stages.back(); if (flag & MTPDchat::flag_admin) { to.add("NO [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break; case 6: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 7: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; @@ -1393,9 +1393,8 @@ void _serialize_chatParticipants(MTPStringLogger &to, int32 stage, int32 lev, Ty } switch (stage) { case 0: to.add(" chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 1: to.add(" admin_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 2: to.add(" participants: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 3: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" participants: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } @@ -2903,6 +2902,37 @@ void _serialize_updateChannelMessageViews(MTPStringLogger &to, int32 stage, int3 } } +void _serialize_updateChatAdmins(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ updateChatAdmins"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" enabled: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; + } +} + +void _serialize_updateChatParticipantAdmin(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ updateChatParticipantAdmin"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" is_admin: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 3: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; + } +} + void _serialize_updates_state(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { if (stage) { to.add(",\n").addSpaces(lev); @@ -6129,35 +6159,6 @@ void _serialize_messages_readHistory(MTPStringLogger &to, int32 stage, int32 lev switch (stage) { case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 1: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 2: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; - } -} - -void _serialize_messages_deleteHistory(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { - if (stage) { - to.add(",\n").addSpaces(lev); - } else { - to.add("{ messages_deleteHistory"); - to.add("\n").addSpaces(lev); - } - switch (stage) { - case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 1: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; - } -} - -void _serialize_channels_deleteUserHistory(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { - if (stage) { - to.add(",\n").addSpaces(lev); - } else { - to.add("{ channels_deleteUserHistory"); - to.add("\n").addSpaces(lev); - } - switch (stage) { - case 0: to.add(" channel: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 1: to.add(" user_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } @@ -6202,6 +6203,34 @@ void _serialize_channels_deleteMessages(MTPStringLogger &to, int32 stage, int32 } } +void _serialize_messages_deleteHistory(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ messages_deleteHistory"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; + } +} + +void _serialize_channels_deleteUserHistory(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ channels_deleteUserHistory"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" channel: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" user_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; + } +} + void _serialize_messages_receivedMessages(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) { if (stage) { to.add(",\n").addSpaces(lev); @@ -6225,12 +6254,13 @@ void _serialize_messages_sendMessage(MTPStringLogger &to, int32 stage, int32 lev switch (stage) { case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 1: to.add(" no_webpage: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_no_webpage) { to.add("NO [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break; - case 2: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 3: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break; - case 4: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 5: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 6: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; - case 7: to.add(" entities: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break; + case 2: to.add(" broadcast: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_broadcast) { to.add("NO [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break; + case 3: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 4: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break; + case 5: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 6: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 7: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; + case 8: to.add(" entities: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } @@ -6244,11 +6274,12 @@ void _serialize_messages_sendMedia(MTPStringLogger &to, int32 stage, int32 lev, } switch (stage) { case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 1: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 2: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMedia::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break; - case 3: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 4: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 5: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMedia::flag_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; + case 1: to.add(" broadcast: "); ++stages.back(); if (flag & MTPmessages_sendMedia::flag_broadcast) { to.add("NO [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break; + case 2: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 3: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMedia::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break; + case 4: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 5: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 6: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMedia::flag_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } @@ -7266,6 +7297,8 @@ namespace { _serializers.insert(mtpc_updateReadChannelInbox, _serialize_updateReadChannelInbox); _serializers.insert(mtpc_updateDeleteChannelMessages, _serialize_updateDeleteChannelMessages); _serializers.insert(mtpc_updateChannelMessageViews, _serialize_updateChannelMessageViews); + _serializers.insert(mtpc_updateChatAdmins, _serialize_updateChatAdmins); + _serializers.insert(mtpc_updateChatParticipantAdmin, _serialize_updateChatParticipantAdmin); _serializers.insert(mtpc_updates_state, _serialize_updates_state); _serializers.insert(mtpc_updates_differenceEmpty, _serialize_updates_differenceEmpty); _serializers.insert(mtpc_updates_difference, _serialize_updates_difference); @@ -7524,11 +7557,11 @@ namespace { _serializers.insert(mtpc_messages_getDialogs, _serialize_messages_getDialogs); _serializers.insert(mtpc_channels_getDialogs, _serialize_channels_getDialogs); _serializers.insert(mtpc_messages_readHistory, _serialize_messages_readHistory); - _serializers.insert(mtpc_messages_deleteHistory, _serialize_messages_deleteHistory); - _serializers.insert(mtpc_channels_deleteUserHistory, _serialize_channels_deleteUserHistory); _serializers.insert(mtpc_messages_deleteMessages, _serialize_messages_deleteMessages); _serializers.insert(mtpc_messages_readMessageContents, _serialize_messages_readMessageContents); _serializers.insert(mtpc_channels_deleteMessages, _serialize_channels_deleteMessages); + _serializers.insert(mtpc_messages_deleteHistory, _serialize_messages_deleteHistory); + _serializers.insert(mtpc_channels_deleteUserHistory, _serialize_channels_deleteUserHistory); _serializers.insert(mtpc_messages_receivedMessages, _serialize_messages_receivedMessages); _serializers.insert(mtpc_messages_sendMessage, _serialize_messages_sendMessage); _serializers.insert(mtpc_messages_sendMedia, _serialize_messages_sendMedia); diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.h b/Telegram/SourceFiles/mtproto/mtpScheme.h index a2c7c71ab8..dd04ba37f8 100644 --- a/Telegram/SourceFiles/mtproto/mtpScheme.h +++ b/Telegram/SourceFiles/mtproto/mtpScheme.h @@ -149,7 +149,7 @@ enum { mtpc_chatParticipantCreator = 0xda13538a, mtpc_chatParticipantAdmin = 0xe2d6e436, mtpc_chatParticipantsForbidden = 0xfc900c2b, - mtpc_chatParticipants = 0x7841b415, + mtpc_chatParticipants = 0x3f460fed, mtpc_chatPhotoEmpty = 0x37c1011c, mtpc_chatPhoto = 0x6153276a, mtpc_messageEmpty = 0x83e5de54, @@ -268,6 +268,8 @@ enum { mtpc_updateReadChannelInbox = 0x4214f37f, mtpc_updateDeleteChannelMessages = 0xc37521c9, mtpc_updateChannelMessageViews = 0x98a12b4b, + mtpc_updateChatAdmins = 0x6e947941, + mtpc_updateChatParticipantAdmin = 0xb6901959, mtpc_updates_state = 0xa56c2a3e, mtpc_updates_differenceEmpty = 0x5d75a138, mtpc_updates_difference = 0xf49ca0, @@ -494,8 +496,8 @@ enum { mtpc_messages_getDialogs = 0x859b3d3c, mtpc_messages_getHistory = 0x8a8ec2da, mtpc_messages_search = 0xd4569248, - mtpc_messages_readHistory = 0xb04f2510, - mtpc_messages_deleteHistory = 0xf4f8fb61, + mtpc_messages_readHistory = 0xe306d3a, + mtpc_messages_deleteHistory = 0xb7c13bd9, mtpc_messages_deleteMessages = 0xa5f18925, mtpc_messages_receivedMessages = 0x5a954c0, mtpc_messages_setTyping = 0xa3825e50, @@ -924,6 +926,8 @@ class MTPDupdateNewChannelMessage; class MTPDupdateReadChannelInbox; class MTPDupdateDeleteChannelMessages; class MTPDupdateChannelMessageViews; +class MTPDupdateChatAdmins; +class MTPDupdateChatParticipantAdmin; class MTPupdates_state; class MTPDupdates_state; @@ -3485,7 +3489,7 @@ private: explicit MTPchatParticipants(MTPDchatParticipants *_data); friend MTPchatParticipants MTP_chatParticipantsForbidden(MTPint _flags, MTPint _chat_id, const MTPChatParticipant &_self_participant); - friend MTPchatParticipants MTP_chatParticipants(MTPint _chat_id, MTPint _admin_id, const MTPVector &_participants, MTPint _version); + friend MTPchatParticipants MTP_chatParticipants(MTPint _chat_id, const MTPVector &_participants, MTPint _version); mtpTypeId _type; }; @@ -5501,6 +5505,30 @@ public: return *(const MTPDupdateChannelMessageViews*)data; } + MTPDupdateChatAdmins &_updateChatAdmins() { + if (!data) throw mtpErrorUninitialized(); + if (_type != mtpc_updateChatAdmins) throw mtpErrorWrongTypeId(_type, mtpc_updateChatAdmins); + split(); + return *(MTPDupdateChatAdmins*)data; + } + const MTPDupdateChatAdmins &c_updateChatAdmins() const { + if (!data) throw mtpErrorUninitialized(); + if (_type != mtpc_updateChatAdmins) throw mtpErrorWrongTypeId(_type, mtpc_updateChatAdmins); + return *(const MTPDupdateChatAdmins*)data; + } + + MTPDupdateChatParticipantAdmin &_updateChatParticipantAdmin() { + if (!data) throw mtpErrorUninitialized(); + if (_type != mtpc_updateChatParticipantAdmin) throw mtpErrorWrongTypeId(_type, mtpc_updateChatParticipantAdmin); + split(); + return *(MTPDupdateChatParticipantAdmin*)data; + } + const MTPDupdateChatParticipantAdmin &c_updateChatParticipantAdmin() const { + if (!data) throw mtpErrorUninitialized(); + if (_type != mtpc_updateChatParticipantAdmin) throw mtpErrorWrongTypeId(_type, mtpc_updateChatParticipantAdmin); + return *(const MTPDupdateChatParticipantAdmin*)data; + } + uint32 innerLength() const; mtpTypeId type() const; void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons); @@ -5545,6 +5573,8 @@ private: explicit MTPupdate(MTPDupdateReadChannelInbox *_data); explicit MTPupdate(MTPDupdateDeleteChannelMessages *_data); explicit MTPupdate(MTPDupdateChannelMessageViews *_data); + explicit MTPupdate(MTPDupdateChatAdmins *_data); + explicit MTPupdate(MTPDupdateChatParticipantAdmin *_data); friend MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count); friend MTPupdate MTP_updateMessageID(MTPint _id, const MTPlong &_random_id); @@ -5581,6 +5611,8 @@ private: friend MTPupdate MTP_updateReadChannelInbox(MTPint _channel_id, MTPint _max_id); friend MTPupdate MTP_updateDeleteChannelMessages(MTPint _channel_id, const MTPVector &_messages, MTPint _pts, MTPint _pts_count); friend MTPupdate MTP_updateChannelMessageViews(MTPint _channel_id, MTPint _id, MTPint _views); + friend MTPupdate MTP_updateChatAdmins(MTPint _chat_id, MTPBool _enabled, MTPint _version); + friend MTPupdate MTP_updateChatParticipantAdmin(MTPint _chat_id, MTPint _user_id, MTPBool _is_admin, MTPint _version); mtpTypeId _type; }; @@ -9606,14 +9638,14 @@ public: flag_creator = (1 << 0), flag_kicked = (1 << 1), flag_left = (1 << 2), - flag_has_admins = (1 << 3), + flag_admins_enabled = (1 << 3), flag_admin = (1 << 4), }; bool is_creator() const { return vflags.v & flag_creator; } bool is_kicked() const { return vflags.v & flag_kicked; } bool is_left() const { return vflags.v & flag_left; } - bool is_has_admins() const { return vflags.v & flag_has_admins; } + bool is_admins_enabled() const { return vflags.v & flag_admins_enabled; } bool is_admin() const { return vflags.v & flag_admin; } }; @@ -9781,11 +9813,10 @@ class MTPDchatParticipants : public mtpDataImpl { public: MTPDchatParticipants() { } - MTPDchatParticipants(MTPint _chat_id, MTPint _admin_id, const MTPVector &_participants, MTPint _version) : vchat_id(_chat_id), vadmin_id(_admin_id), vparticipants(_participants), vversion(_version) { + MTPDchatParticipants(MTPint _chat_id, const MTPVector &_participants, MTPint _version) : vchat_id(_chat_id), vparticipants(_participants), vversion(_version) { } MTPint vchat_id; - MTPint vadmin_id; MTPVector vparticipants; MTPint vversion; }; @@ -10955,6 +10986,31 @@ public: MTPint vviews; }; +class MTPDupdateChatAdmins : public mtpDataImpl { +public: + MTPDupdateChatAdmins() { + } + MTPDupdateChatAdmins(MTPint _chat_id, MTPBool _enabled, MTPint _version) : vchat_id(_chat_id), venabled(_enabled), vversion(_version) { + } + + MTPint vchat_id; + MTPBool venabled; + MTPint vversion; +}; + +class MTPDupdateChatParticipantAdmin : public mtpDataImpl { +public: + MTPDupdateChatParticipantAdmin() { + } + MTPDupdateChatParticipantAdmin(MTPint _chat_id, MTPint _user_id, MTPBool _is_admin, MTPint _version) : vchat_id(_chat_id), vuser_id(_user_id), vis_admin(_is_admin), vversion(_version) { + } + + MTPint vchat_id; + MTPint vuser_id; + MTPBool vis_admin; + MTPint vversion; +}; + class MTPDupdates_state : public mtpDataImpl { public: MTPDupdates_state() { @@ -15515,18 +15571,17 @@ class MTPmessages_readHistory { // RPC method 'messages.readHistory' public: MTPInputPeer vpeer; MTPint vmax_id; - MTPint voffset; MTPmessages_readHistory() { } MTPmessages_readHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_readHistory) { read(from, end, cons); } - MTPmessages_readHistory(const MTPInputPeer &_peer, MTPint _max_id, MTPint _offset) : vpeer(_peer), vmax_id(_max_id), voffset(_offset) { + MTPmessages_readHistory(const MTPInputPeer &_peer, MTPint _max_id) : vpeer(_peer), vmax_id(_max_id) { } uint32 innerLength() const { - return vpeer.innerLength() + vmax_id.innerLength() + voffset.innerLength(); + return vpeer.innerLength() + vmax_id.innerLength(); } mtpTypeId type() const { return mtpc_messages_readHistory; @@ -15534,15 +15589,13 @@ public: void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_readHistory) { vpeer.read(from, end); vmax_id.read(from, end); - voffset.read(from, end); } void write(mtpBuffer &to) const { vpeer.write(to); vmax_id.write(to); - voffset.write(to); } - typedef MTPmessages_AffectedHistory ResponseType; + typedef MTPmessages_AffectedMessages ResponseType; }; class MTPmessages_ReadHistory : public MTPBoxed { public: @@ -15552,36 +15605,36 @@ public: } MTPmessages_ReadHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { } - MTPmessages_ReadHistory(const MTPInputPeer &_peer, MTPint _max_id, MTPint _offset) : MTPBoxed(MTPmessages_readHistory(_peer, _max_id, _offset)) { + MTPmessages_ReadHistory(const MTPInputPeer &_peer, MTPint _max_id) : MTPBoxed(MTPmessages_readHistory(_peer, _max_id)) { } }; class MTPmessages_deleteHistory { // RPC method 'messages.deleteHistory' public: MTPInputPeer vpeer; - MTPint voffset; + MTPint vmax_id; MTPmessages_deleteHistory() { } MTPmessages_deleteHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_deleteHistory) { read(from, end, cons); } - MTPmessages_deleteHistory(const MTPInputPeer &_peer, MTPint _offset) : vpeer(_peer), voffset(_offset) { + MTPmessages_deleteHistory(const MTPInputPeer &_peer, MTPint _max_id) : vpeer(_peer), vmax_id(_max_id) { } uint32 innerLength() const { - return vpeer.innerLength() + voffset.innerLength(); + return vpeer.innerLength() + vmax_id.innerLength(); } mtpTypeId type() const { return mtpc_messages_deleteHistory; } void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_deleteHistory) { vpeer.read(from, end); - voffset.read(from, end); + vmax_id.read(from, end); } void write(mtpBuffer &to) const { vpeer.write(to); - voffset.write(to); + vmax_id.write(to); } typedef MTPmessages_AffectedHistory ResponseType; @@ -15594,7 +15647,7 @@ public: } MTPmessages_DeleteHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { } - MTPmessages_DeleteHistory(const MTPInputPeer &_peer, MTPint _offset) : MTPBoxed(MTPmessages_deleteHistory(_peer, _offset)) { + MTPmessages_DeleteHistory(const MTPInputPeer &_peer, MTPint _max_id) : MTPBoxed(MTPmessages_deleteHistory(_peer, _max_id)) { } }; @@ -15738,12 +15791,14 @@ public: enum { flag_no_webpage = (1 << 1), + flag_broadcast = (1 << 4), flag_reply_to_msg_id = (1 << 0), flag_reply_markup = (1 << 2), flag_entities = (1 << 3), }; bool is_no_webpage() const { return vflags.v & flag_no_webpage; } + bool is_broadcast() const { return vflags.v & flag_broadcast; } bool has_reply_to_msg_id() const { return vflags.v & flag_reply_to_msg_id; } bool has_reply_markup() const { return vflags.v & flag_reply_markup; } bool has_entities() const { return vflags.v & flag_entities; } @@ -15805,10 +15860,12 @@ public: } enum { + flag_broadcast = (1 << 4), flag_reply_to_msg_id = (1 << 0), flag_reply_markup = (1 << 2), }; + bool is_broadcast() const { return vflags.v & flag_broadcast; } bool has_reply_to_msg_id() const { return vflags.v & flag_reply_to_msg_id; } bool has_reply_markup() const { return vflags.v & flag_reply_markup; } @@ -21919,7 +21976,7 @@ inline uint32 MTPchatParticipants::innerLength() const { } case mtpc_chatParticipants: { const MTPDchatParticipants &v(c_chatParticipants()); - return v.vchat_id.innerLength() + v.vadmin_id.innerLength() + v.vparticipants.innerLength() + v.vversion.innerLength(); + return v.vchat_id.innerLength() + v.vparticipants.innerLength() + v.vversion.innerLength(); } } return 0; @@ -21942,7 +21999,6 @@ inline void MTPchatParticipants::read(const mtpPrime *&from, const mtpPrime *end if (!data) setData(new MTPDchatParticipants()); MTPDchatParticipants &v(_chatParticipants()); v.vchat_id.read(from, end); - v.vadmin_id.read(from, end); v.vparticipants.read(from, end); v.vversion.read(from, end); } break; @@ -21960,7 +22016,6 @@ inline void MTPchatParticipants::write(mtpBuffer &to) const { case mtpc_chatParticipants: { const MTPDchatParticipants &v(c_chatParticipants()); v.vchat_id.write(to); - v.vadmin_id.write(to); v.vparticipants.write(to); v.vversion.write(to); } break; @@ -21980,8 +22035,8 @@ inline MTPchatParticipants::MTPchatParticipants(MTPDchatParticipants *_data) : m inline MTPchatParticipants MTP_chatParticipantsForbidden(MTPint _flags, MTPint _chat_id, const MTPChatParticipant &_self_participant) { return MTPchatParticipants(new MTPDchatParticipantsForbidden(_flags, _chat_id, _self_participant)); } -inline MTPchatParticipants MTP_chatParticipants(MTPint _chat_id, MTPint _admin_id, const MTPVector &_participants, MTPint _version) { - return MTPchatParticipants(new MTPDchatParticipants(_chat_id, _admin_id, _participants, _version)); +inline MTPchatParticipants MTP_chatParticipants(MTPint _chat_id, const MTPVector &_participants, MTPint _version) { + return MTPchatParticipants(new MTPDchatParticipants(_chat_id, _participants, _version)); } inline uint32 MTPchatPhoto::innerLength() const { @@ -24226,6 +24281,14 @@ inline uint32 MTPupdate::innerLength() const { const MTPDupdateChannelMessageViews &v(c_updateChannelMessageViews()); return v.vchannel_id.innerLength() + v.vid.innerLength() + v.vviews.innerLength(); } + case mtpc_updateChatAdmins: { + const MTPDupdateChatAdmins &v(c_updateChatAdmins()); + return v.vchat_id.innerLength() + v.venabled.innerLength() + v.vversion.innerLength(); + } + case mtpc_updateChatParticipantAdmin: { + const MTPDupdateChatParticipantAdmin &v(c_updateChatParticipantAdmin()); + return v.vchat_id.innerLength() + v.vuser_id.innerLength() + v.vis_admin.innerLength() + v.vversion.innerLength(); + } } return 0; } @@ -24468,6 +24531,21 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI v.vid.read(from, end); v.vviews.read(from, end); } break; + case mtpc_updateChatAdmins: _type = cons; { + if (!data) setData(new MTPDupdateChatAdmins()); + MTPDupdateChatAdmins &v(_updateChatAdmins()); + v.vchat_id.read(from, end); + v.venabled.read(from, end); + v.vversion.read(from, end); + } break; + case mtpc_updateChatParticipantAdmin: _type = cons; { + if (!data) setData(new MTPDupdateChatParticipantAdmin()); + MTPDupdateChatParticipantAdmin &v(_updateChatParticipantAdmin()); + v.vchat_id.read(from, end); + v.vuser_id.read(from, end); + v.vis_admin.read(from, end); + v.vversion.read(from, end); + } break; default: throw mtpErrorUnexpected(cons, "MTPupdate"); } } @@ -24670,6 +24748,19 @@ inline void MTPupdate::write(mtpBuffer &to) const { v.vid.write(to); v.vviews.write(to); } break; + case mtpc_updateChatAdmins: { + const MTPDupdateChatAdmins &v(c_updateChatAdmins()); + v.vchat_id.write(to); + v.venabled.write(to); + v.vversion.write(to); + } break; + case mtpc_updateChatParticipantAdmin: { + const MTPDupdateChatParticipantAdmin &v(c_updateChatParticipantAdmin()); + v.vchat_id.write(to); + v.vuser_id.write(to); + v.vis_admin.write(to); + v.vversion.write(to); + } break; } } inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) { @@ -24709,6 +24800,8 @@ inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) { case mtpc_updateReadChannelInbox: setData(new MTPDupdateReadChannelInbox()); break; case mtpc_updateDeleteChannelMessages: setData(new MTPDupdateDeleteChannelMessages()); break; case mtpc_updateChannelMessageViews: setData(new MTPDupdateChannelMessageViews()); break; + case mtpc_updateChatAdmins: setData(new MTPDupdateChatAdmins()); break; + case mtpc_updateChatParticipantAdmin: setData(new MTPDupdateChatParticipantAdmin()); break; default: throw mtpErrorBadTypeId(type, "MTPupdate"); } } @@ -24782,6 +24875,10 @@ inline MTPupdate::MTPupdate(MTPDupdateDeleteChannelMessages *_data) : mtpDataOwn } inline MTPupdate::MTPupdate(MTPDupdateChannelMessageViews *_data) : mtpDataOwner(_data), _type(mtpc_updateChannelMessageViews) { } +inline MTPupdate::MTPupdate(MTPDupdateChatAdmins *_data) : mtpDataOwner(_data), _type(mtpc_updateChatAdmins) { +} +inline MTPupdate::MTPupdate(MTPDupdateChatParticipantAdmin *_data) : mtpDataOwner(_data), _type(mtpc_updateChatParticipantAdmin) { +} inline MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count) { return MTPupdate(new MTPDupdateNewMessage(_message, _pts, _pts_count)); } @@ -24887,6 +24984,12 @@ inline MTPupdate MTP_updateDeleteChannelMessages(MTPint _channel_id, const MTPVe inline MTPupdate MTP_updateChannelMessageViews(MTPint _channel_id, MTPint _id, MTPint _views) { return MTPupdate(new MTPDupdateChannelMessageViews(_channel_id, _id, _views)); } +inline MTPupdate MTP_updateChatAdmins(MTPint _chat_id, MTPBool _enabled, MTPint _version) { + return MTPupdate(new MTPDupdateChatAdmins(_chat_id, _enabled, _version)); +} +inline MTPupdate MTP_updateChatParticipantAdmin(MTPint _chat_id, MTPint _user_id, MTPBool _is_admin, MTPint _version) { + return MTPupdate(new MTPDupdateChatParticipantAdmin(_chat_id, _user_id, _is_admin, _version)); +} inline MTPupdates_state::MTPupdates_state() : mtpDataOwner(new MTPDupdates_state()) { } diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl index d7cbf6b19d..063c82340d 100644 --- a/Telegram/SourceFiles/mtproto/scheme.tl +++ b/Telegram/SourceFiles/mtproto/scheme.tl @@ -1,14 +1,7 @@ // Core types (no need to gen) -//boolFalse#bc799737 = Bool; -//boolTrue#997275b5 = Bool; - //vector#1cb5c415 {t:Type} # [ t ] = Vector t; -//error#c4b9f9bb code:int text:string = Error; - -//null#56730bcc = Null; - /////////////////////////////// /////////////////// Layer cons /////////////////////////////// @@ -125,6 +118,7 @@ register.saveDeveloperInfo#9a5f6e95 name:string email:string phone_number:string /////////////////////////////// ---types--- + boolFalse#bc799737 = Bool; boolTrue#997275b5 = Bool; @@ -222,7 +216,7 @@ userStatusLastWeek#7bf09fc = UserStatus; userStatusLastMonth#77ebc742 = UserStatus; chatEmpty#9ba2d800 id:int = Chat; -chat#7312bc48 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true has_admins:flags.3?true admin:flags.4?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int = Chat; +chat#7312bc48 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int = Chat; chatForbidden#7328bdb id:int title:string = Chat; channel#678e9587 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true editor:flags.3?true moderator:flags.4?true broadcast:flags.5?true verified:flags.7?true id:int access_hash:long title:string username:flags.6?string photo:ChatPhoto date:int version:int = Chat; channelForbidden#2d85832c id:int access_hash:long title:string = Chat; @@ -235,7 +229,7 @@ chatParticipantCreator#da13538a user_id:int = ChatParticipant; chatParticipantAdmin#e2d6e436 user_id:int inviter_id:int date:int = ChatParticipant; chatParticipantsForbidden#fc900c2b flags:# chat_id:int self_participant:flags.0?ChatParticipant = ChatParticipants; -chatParticipants#7841b415 chat_id:int admin_id:int participants:Vector version:int = ChatParticipants; +chatParticipants#3f460fed chat_id:int participants:Vector version:int = ChatParticipants; chatPhotoEmpty#37c1011c = ChatPhoto; chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto; @@ -391,6 +385,8 @@ updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update; updateReadChannelInbox#4214f37f channel_id:int max_id:int = Update; updateDeleteChannelMessages#c37521c9 channel_id:int messages:Vector pts:int pts_count:int = Update; updateChannelMessageViews#98a12b4b channel_id:int id:int views:int = Update; +updateChatAdmins#6e947941 chat_id:int enabled:Bool version:int = Update; +updateChatParticipantAdmin#b6901959 chat_id:int user_id:int is_admin:Bool version:int = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -696,13 +692,13 @@ messages.getMessages#4222fa74 id:Vector = messages.Messages; messages.getDialogs#859b3d3c offset:int limit:int = messages.Dialogs; messages.getHistory#8a8ec2da peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages; messages.search#d4569248 flags:# important_only:flags.0?true peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages; -messages.readHistory#b04f2510 peer:InputPeer max_id:int offset:int = messages.AffectedHistory; -messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory; +messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages; +messages.deleteHistory#b7c13bd9 peer:InputPeer max_id:int = messages.AffectedHistory; messages.deleteMessages#a5f18925 id:Vector = messages.AffectedMessages; messages.receivedMessages#5a954c0 max_id:int = Vector; messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool; -messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector = Updates; -messages.sendMedia#c8f16791 flags:# peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates; +messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true broadcast:flags.4?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector = Updates; +messages.sendMedia#c8f16791 flags:# broadcast:flags.4?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates; messages.forwardMessages#708e0195 flags:# broadcast:flags.4?true from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer = Updates; messages.reportSpam#cf1592db peer:InputPeer = Bool; messages.getChats#3c6aa187 id:Vector = messages.Chats; diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index 8bdbc14edf..e12e201d0a 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -34,7 +34,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const PeerData *peer) : TWidget(0), _profile(profile), _scroll(scroll), _peer(App::peer(peer->id)), _peerUser(_peer->asUser()), _peerChat(_peer->asChat()), _peerChannel(_peer->asChannel()), _hist(App::history(peer->id)), - _amCreator(_peerChat ? (_peerChat->creator == MTP::authedId()) : (_peerChannel ? _peerChannel->amCreator() : false)), + _amCreator(_peerChat ? _peerChat->amCreator() : (_peerChannel ? _peerChannel->amCreator() : false)), _width(0), _left(0), _addToHeight(0), @@ -52,7 +52,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee _botHelp(this, lang(lng_profile_bot_help)), _username(this, (_peerChannel && _peerChannel->isPublic()) ? (qsl("telegram.me/") + _peerChannel->username) : lang(lng_profile_create_public_link)), _members(this, lng_channel_members_link(lt_count, (_peerChannel && _peerChannel->count > 0) ? _peerChannel->count : 1)), - _admins(this, lng_channel_admins_link(lt_count, (_peerChannel && _peerChannel->adminsCount > 0) ? _peerChannel->adminsCount : 1)), + _admins(this, lng_channel_admins_link(lt_count, (_peerChannel ? (_peerChannel->adminsCount > 0 ? _peerChannel->adminsCount : 1) : ((_peerChat && _peerChat->adminsEnabled() && !_peerChat->admins.isEmpty()) ? _peerChat->admins.size() : 0)))), // about _about(st::wndMinWidth - st::profilePadding.left() - st::profilePadding.right()), @@ -427,8 +427,10 @@ void ProfileInner::onMembers() { } void ProfileInner::onAdmins() { - if (!_peerChannel) return; - App::wnd()->showLayer(new MembersBox(_peerChannel, MembersFilterAdmins)); + if (_peerChannel) { + App::wnd()->showLayer(new MembersBox(_peerChannel, MembersFilterAdmins)); + } else if (_peerChat) { + } } void ProfileInner::onCreateInvitationLink() { @@ -487,7 +489,7 @@ void ProfileInner::onFullPeerUpdated(PeerData *peer) { } else if (_peerChannel) { updateInvitationLink(); _members.setText(lng_channel_members_link(lt_count, (_peerChannel->count > 0) ? _peerChannel->count : 1)); - _admins.setText(lng_channel_admins_link(lt_count, (_peerChannel->adminsCount > 0) ? _peerChannel->adminsCount : 1)); + _admins.setText(lng_channel_admins_link(lt_count, (_peerChannel ? (_peerChannel->adminsCount > 0 ? _peerChannel->adminsCount : 1) : ((_peerChat && _peerChat->adminsEnabled() && !_peerChat->admins.isEmpty()) ? _peerChat->admins.size() : 0)))); _onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(lng_channel_status); if (_peerChannel->about.isEmpty()) { _about = Text(st::wndMinWidth - st::profilePadding.left() - st::profilePadding.right()); @@ -545,7 +547,7 @@ void ProfileInner::peerUpdated(PeerData *data) { peerUsernameChanged(); } _members.setText(lng_channel_members_link(lt_count, (_peerChannel->count > 0) ? _peerChannel->count : 1)); - _admins.setText(lng_channel_admins_link(lt_count, (_peerChannel->adminsCount > 0) ? _peerChannel->adminsCount : 1)); + _admins.setText(lng_channel_admins_link(lt_count, (_peerChannel ? (_peerChannel->adminsCount > 0 ? _peerChannel->adminsCount : 1) : ((_peerChat && _peerChat->adminsEnabled() && !_peerChat->admins.isEmpty()) ? _peerChat->admins.size() : 0)))); _onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(lng_channel_status); } _photoLink = (photo && photo->date) ? TextLinkPtr(new PhotoLink(photo, _peer)) : TextLinkPtr(); @@ -583,7 +585,7 @@ void ProfileInner::updateOnlineDisplayTimer() { void ProfileInner::reorderParticipants() { int32 was = _participants.size(), t = unixtime(), onlineCount = 0; - if (_peerChat && !_peerChat->isForbidden) { + if (_peerChat && _peerChat->amIn()) { if (_peerChat->count <= 0 || !_peerChat->participants.isEmpty()) { _participants.clear(); for (ParticipantsData::iterator i = _participantsData.begin(), e = _participantsData.end(); i != e; ++i) { @@ -671,7 +673,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) { // profile top += st::profilePadding.top(); - if (_photoLink || _peerUser || (_peerChat && _peerChat->isForbidden) || (_peerChannel && !_amCreator)) { + if (_photoLink || _peerUser || (_peerChat && !_peerChat->canEdit()) || (_peerChannel && !_amCreator)) { p.drawPixmap(_left, top, _peer->photo->pix(st::profilePhotoSize)); } else { if (a_photo.current() < 1) { @@ -724,7 +726,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) { top += st::profilePhotoSize; top += st::profileButtonTop; - if (_peerChat && _peerChat->isForbidden) { + if (_peerChat && !_peerChat->amIn()) { int32 w = st::btnShareContact.font->width(lang(lng_profile_chat_unaccessible)); p.setFont(st::btnShareContact.font->f); p.setPen(st::profileOfflineColor->p); @@ -840,7 +842,13 @@ void ProfileInner::paintEvent(QPaintEvent *e) { } else { data->online = App::onlineText(user, l_time); } - data->cankick = (user != App::self()) && (_amCreator || (_peerChat->cankick.constFind(user) != _peerChat->cankick.cend())); + if (_amCreator) { + data->cankick = (user != App::self()); + } else if (_peerChat->amAdmin()) { + data->cankick = (user != App::self()) && (_peerChat->admins.constFind(user) == _peerChat->admins.cend()); + } else { + data->cankick = (user != App::self()) && (_peerChat->invitedByMe.constFind(user) != _peerChat->invitedByMe.cend()); + } } p.setPen(st::profileListNameColor->p); p.setFont(st::linkFont->f); @@ -875,12 +883,12 @@ void ProfileInner::mouseMoveEvent(QMouseEvent *e) { bool photoOver = QRect(_left, st::profilePadding.top(), st::setPhotoSize, st::setPhotoSize).contains(e->pos()); if (photoOver != _photoOver) { _photoOver = photoOver; - if (!_photoLink && ((_peerChat && !_peerChat->isForbidden) || (_peerChannel && _amCreator))) { + if (!_photoLink && ((_peerChat && _peerChat->canEdit()) || (_peerChannel && _amCreator))) { a_photo.start(_photoOver ? 1 : 0); anim::start(this); } } - if (!_photoLink && (_peerUser || (_peerChat && _peerChat->isForbidden) || (_peerChannel && !_amCreator))) { + if (!_photoLink && (_peerUser || (_peerChat && !_peerChat->canEdit()) || (_peerChannel && !_amCreator))) { setCursor((_kickOver || _kickDown || textlnkOver()) ? style::cur_pointer : style::cur_default); } else { setCursor((_kickOver || _kickDown || _photoOver || textlnkOver()) ? style::cur_pointer : style::cur_default); @@ -946,7 +954,7 @@ void ProfileInner::mousePressEvent(QMouseEvent *e) { } else if (QRect(_left, st::profilePadding.top(), st::setPhotoSize, st::setPhotoSize).contains(e->pos())) { if (_photoLink) { _photoLink->onClick(e->button()); - } else if ((_peerChat && !_peerChat->isForbidden) || (_peerChannel && _amCreator)) { + } else if ((_peerChat && _peerChat->amIn()) || (_peerChannel && _amCreator)) { onUpdatePhoto(); } } @@ -978,7 +986,7 @@ void ProfileInner::mouseReleaseEvent(QMouseEvent *e) { } } _kickDown = 0; - if (!_photoLink && (_peerUser || (_peerChat && _peerChat->isForbidden) || (_peerChannel && !_amCreator))) { + if (!_photoLink && (_peerUser || (_peerChat && !_peerChat->canEdit()) || (_peerChannel && !_amCreator))) { setCursor((_kickOver || _kickDown || textlnkOver()) ? style::cur_pointer : style::cur_default); } else { setCursor((_kickOver || _kickDown || _photoOver || textlnkOver()) ? style::cur_pointer : style::cur_default); @@ -1377,7 +1385,7 @@ void ProfileInner::showAll() { _sendMessage.hide(); _shareContact.hide(); _inviteToGroup.hide(); - if (_peerChat->isForbidden) { + if (!_peerChat->canEdit()) { _uploadPhoto.hide(); _cancelPhoto.hide(); _addParticipant.hide(); @@ -1412,7 +1420,11 @@ void ProfileInner::showAll() { _deleteChannel.hide(); _username.hide(); _members.hide(); - _admins.hide(); + if (_amCreator) { + _admins.show(); + } else { + _admins.hide(); + } } else if (_peerChannel) { _sendMessage.hide(); _shareContact.hide(); diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 26abbf0517..daa3167f83 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -372,9 +372,16 @@ public: class ChatData : public PeerData { public: - ChatData(const PeerId &id) : PeerData(id), inputChat(MTP_int(bareId())), count(0), date(0), version(0), creator(0), inviterForSpamReport(0), isForbidden(false), haveLeft(true), botStatus(0) { + ChatData(const PeerId &id) : PeerData(id), inputChat(MTP_int(bareId())), count(0), date(0), version(0), creator(0), inviterForSpamReport(0), flags(0), isForbidden(false), botStatus(0) { } void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId); + void invalidateParticipants(bool invalidateCount = true) { + participants = ChatData::Participants(); + admins = ChatData::Admins(); + invitedByMe = ChatData::InvitedByMe(); + botStatus = 0; + if (invalidateCount) count = 0; + } MTPint inputChat; @@ -384,12 +391,35 @@ public: int32 creator; int32 inviterForSpamReport; // > 0 - user who invited me to chat in unread service msg, < 0 - have outgoing message + int32 flags; bool isForbidden; - bool haveLeft; + bool amIn() const { + return !isForbidden && !haveLeft() && !wasKicked(); + } + bool canEdit() const { + return amCreator() || (adminsEnabled() ? amAdmin() : amIn()); + } + bool haveLeft() const { + return flags & MTPDchat::flag_left; + } + bool wasKicked() const { + return flags & MTPDchat::flag_kicked; + } + bool adminsEnabled() const { + return flags & MTPDchat::flag_admins_enabled; + } + bool amCreator() const { + return flags & MTPDchat::flag_creator; + } + bool amAdmin() const { + return flags & MTPDchat::flag_admin; + } typedef QMap Participants; Participants participants; - typedef QMap CanKick; - CanKick cankick; + typedef QMap InvitedByMe; + InvitedByMe invitedByMe; + typedef QMap Admins; + Admins admins; typedef QList LastAuthors; LastAuthors lastAuthors; typedef QMap MarkupSenders;