From 550ccef09ab07b463edde9ed542d095edb7b63ec Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 30 Oct 2015 11:57:22 -0400 Subject: [PATCH] chat admins edit done --- Telegram/Resources/lang.strings | 4 + Telegram/Resources/style.txt | 8 + Telegram/SourceFiles/apiwrap.cpp | 26 +- Telegram/SourceFiles/apiwrap.h | 7 +- Telegram/SourceFiles/app.cpp | 13 +- Telegram/SourceFiles/boxes/contactsbox.cpp | 343 +++++++++++++++++---- Telegram/SourceFiles/boxes/contactsbox.h | 38 ++- Telegram/SourceFiles/gui/flatcheckbox.cpp | 6 +- Telegram/SourceFiles/gui/style_core.h | 27 +- Telegram/SourceFiles/gui/twidget.h | 31 -- Telegram/SourceFiles/profilewidget.cpp | 11 +- 11 files changed, 392 insertions(+), 122 deletions(-) diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index f826ffd2d..beeae5c0b 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -432,6 +432,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org "lng_channel_admin_sure" = "Add {user} to administrators?"; "lng_channel_admins_too_much" = "Sorry, you have reached the limit of channel administrators. Please remove one administrator first."; +"lng_chat_all_members_admins" = "All Members Are Admins"; +"lng_chat_about_all_admins" = "Group members can add new members, edit name and photo of the group."; +"lng_chat_about_admins" = "Group admins can add and remove members, edit name and photo of the group."; + "lng_participant_filter" = "Search"; "lng_participant_invite" = "Invite"; "lng_participant_invite_sorry" = "Sorry, you can only add the first {count:_not_used|# member|# members} to a channel personally.\n\nFrom now on, people will need to join via your invite link."; diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index afea7808d..d01b5f6c6 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -1412,6 +1412,14 @@ contactsNewItemIcon: sprite(307px, 248px, 22px, 16px); contactsNewItemIconPosition: point(29px, 19px); contactsNewItemTop: 18px; contactsNewItemFg: #4b82af; +contactsAboutBg: #f7f7f7; +contactsAdminCheckbox: Checkbox(defaultCheckbox) { + font: semiboldFont; + textBg: #f7f7f7; + textPosition: point(34px, 1px); +} +contactsAboutHeight: 80px; +contactsAboutTop: 9px; contactsScroll: flatScroll(boxScroll) { deltab: 0px; } diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 9d2a529c5..0d72d61b6 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -218,7 +218,15 @@ void ApiWrap::requestFullPeer(PeerData *peer) { if (req) _fullPeerRequests.insert(peer, req); } -void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) { +void ApiWrap::processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result) { + gotChatFull(peer, result, 0); +} + +void ApiWrap::processFullPeer(PeerData *peer, const MTPUserFull &result) { + gotUserFull(peer, result, 0); +} + +void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req) { const MTPDmessages_chatFull &d(result.c_messages_chatFull()); const QVector &vc(d.vchats.c_vector().v); bool badVersion = false; @@ -294,7 +302,12 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) { App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), f.vnotify_settings); } - _fullPeerRequests.remove(peer); + if (req) { + QMap::iterator i = _fullPeerRequests.find(peer); + if (i != _fullPeerRequests.cend() && i.value() == req) { + _fullPeerRequests.erase(i); + } + } if (badVersion) { if (peer->isChat()) { peer->asChat()->version = vc.at(0).c_chat().vversion.v; @@ -308,7 +321,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) { App::emitPeerUpdated(); } -void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result) { +void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req) { const MTPDuserFull &d(result.c_userFull()); App::feedUsers(MTP_vector(1, d.vuser), false); App::feedPhoto(d.vprofile_photo); @@ -318,7 +331,12 @@ void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result) { peer->asUser()->setBotInfo(d.vbot_info); peer->asUser()->blocked = mtpIsTrue(d.vblocked) ? UserIsBlocked : UserIsNotBlocked; - _fullPeerRequests.remove(peer); + if (req) { + QMap::iterator i = _fullPeerRequests.find(peer); + if (i != _fullPeerRequests.cend() && i.value() == req) { + _fullPeerRequests.erase(i); + } + } App::clearPeerUpdated(peer); emit fullPeerUpdated(peer); App::emitPeerUpdated(); diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 03b5d98a7..4529d935f 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -37,6 +37,9 @@ public: void requestPeer(PeerData *peer); void requestPeers(const QList &peers); + void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result); + void processFullPeer(PeerData *peer, const MTPUserFull &result); + void requestSelfParticipant(ChannelData *channel); void requestWebPageDelayed(WebPageData *page); @@ -75,8 +78,8 @@ private: MessageIds collectMessageIds(const ReplyToRequests &requests); ReplyToRequests *replyToRequests(ChannelData *channel, bool onlyExisting = false); - void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result); - void gotUserFull(PeerData *peer, const MTPUserFull &result); + void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req); + void gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req); bool gotPeerFullFailed(PeerData *peer, const RPCError &err); typedef QMap PeerRequests; PeerRequests _fullPeerRequests; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index af51a095e..69acb8537 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -512,8 +512,7 @@ namespace App { cdata->isForbidden = false; if (cdata->version < d.vversion.v) { cdata->version = d.vversion.v; - cdata->participants = ChatData::Participants(); - cdata->botStatus = 0; + cdata->invalidateParticipants(false); } } break; case mtpc_chatForbidden: { @@ -528,6 +527,7 @@ namespace App { cdata->setPhoto(MTP_chatPhotoEmpty()); cdata->date = 0; cdata->count = -1; + cdata->invalidateParticipants(false); cdata->flags = 0; cdata->isForbidden = true; } break; @@ -594,9 +594,7 @@ 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(); + chat->invalidateParticipants(false); } break; case mtpc_chatParticipants: { @@ -640,10 +638,7 @@ namespace App { chat->admins[user] = true; } } else { - chat->participants = ChatData::Participants(); - chat->invitedByMe = ChatData::InvitedByMe(); - chat->admins = ChatData::Admins(); - chat->botStatus = 0; + chat->invalidateParticipants(false); break; } } diff --git a/Telegram/SourceFiles/boxes/contactsbox.cpp b/Telegram/SourceFiles/boxes/contactsbox.cpp index 8a3a7904b..85ee39efd 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.cpp +++ b/Telegram/SourceFiles/boxes/contactsbox.cpp @@ -39,9 +39,10 @@ ContactsInner::ContactsInner(CreatingGroupType creating) : TWidget() , _newItemSel(false) , _chat(0) , _channel(0) -, _channelFilter(MembersFilterRecent) +, _membersFilter(MembersFilterRecent) , _bot(0) , _creating(creating) +, _allAdmins(this, lang(lng_chat_all_members_admins), false, st::contactsAdminCheckbox) , _addToChat(0) , _addAdmin(0) , _addAdminRequestId(0) @@ -53,20 +54,22 @@ ContactsInner::ContactsInner(CreatingGroupType creating) : TWidget() , _selCount(0) , _searching(false) , _byUsernameSel(-1) -, _addContactLnk(this, lang(lng_add_contact_button)) { +, _addContactLnk(this, lang(lng_add_contact_button)) +, _saving(false) { init(); } -ContactsInner::ContactsInner(ChannelData *channel, MembersFilter channelFilter, const MembersAlreadyIn &already) : TWidget() +ContactsInner::ContactsInner(ChannelData *channel, MembersFilter membersFilter, const MembersAlreadyIn &already) : TWidget() , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) , _newItemHeight(0) , _newItemSel(false) , _chat(0) , _channel(channel) -, _channelFilter(channelFilter) +, _membersFilter(membersFilter) , _bot(0) , _creating(CreatingGroupChannel) , _already(already) +, _allAdmins(this, lang(lng_chat_all_members_admins), false, st::contactsAdminCheckbox) , _addToChat(0) , _addAdmin(0) , _addAdminRequestId(0) @@ -78,31 +81,47 @@ ContactsInner::ContactsInner(ChannelData *channel, MembersFilter channelFilter, , _selCount(0) , _searching(false) , _byUsernameSel(-1) -, _addContactLnk(this, lang(lng_add_contact_button)) { +, _addContactLnk(this, lang(lng_add_contact_button)) +, _saving(false) { init(); } -ContactsInner::ContactsInner(ChatData *chat) : TWidget() +namespace { + bool _sortByName(UserData *a, UserData *b) { + return a->name.compare(b->name, Qt::CaseInsensitive) < 0; + } +} + +ContactsInner::ContactsInner(ChatData *chat, MembersFilter membersFilter) : TWidget() , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) -, _newItemHeight(0) +, _newItemHeight((membersFilter == MembersFilterAdmins) ? (st::contactsNewItemHeight + st::contactsAboutHeight) : 0) , _newItemSel(false) , _chat(chat) , _channel(0) -, _channelFilter(MembersFilterRecent) +, _membersFilter(membersFilter) , _bot(0) , _creating(CreatingGroupNone) +, _allAdmins(this, lang(lng_chat_all_members_admins), !_chat->adminsEnabled(), st::contactsAdminCheckbox) +, _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.right() - st::contactsCheckPosition.x() * 2 - st::contactsCheckIcon.pxWidth()) +, _aboutAllAdmins(st::boxTextFont, lang(lng_chat_about_all_admins), _defaultOptions, _aboutWidth) +, _aboutAdmins(st::boxTextFont, lang(lng_chat_about_admins), _defaultOptions, _aboutWidth) , _addToChat(0) , _addAdmin(0) , _addAdminRequestId(0) , _addAdminBox(0) -, _contacts(&App::main()->contactsList()) +, _contacts((membersFilter == MembersFilterRecent) ? (&App::main()->contactsList()) : (new DialogsIndexed(DialogsSortByAdd))) , _sel(0) , _filteredSel(-1) , _mouseSel(false) , _selCount(0) , _searching(false) , _byUsernameSel(-1) -, _addContactLnk(this, lang(lng_add_contact_button)) { +, _addContactLnk(this, lang(lng_add_contact_button)) +, _saving(false) { + initList(); + if (membersFilter == MembersFilterAdmins && !_contacts->list.count) { + App::api()->requestFullPeer(_chat); + } init(); } @@ -112,9 +131,10 @@ ContactsInner::ContactsInner(UserData *bot) : TWidget() , _newItemSel(false) , _chat(0) , _channel(0) -, _channelFilter(MembersFilterRecent) +, _membersFilter(MembersFilterRecent) , _bot(bot) , _creating(CreatingGroupNone) +, _allAdmins(this, lang(lng_chat_all_members_admins), false, st::contactsAdminCheckbox) , _addToChat(0) , _addAdmin(0) , _addAdminRequestId(0) @@ -126,7 +146,8 @@ ContactsInner::ContactsInner(UserData *bot) : TWidget() , _selCount(0) , _searching(false) , _byUsernameSel(-1) -, _addContactLnk(this, lang(lng_add_contact_button)) { +, _addContactLnk(this, lang(lng_add_contact_button)) +, _saving(false) { 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()->amIn()) { @@ -139,6 +160,7 @@ ContactsInner::ContactsInner(UserData *bot) : TWidget() void ContactsInner::init() { connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact())); + connect(&_allAdmins, SIGNAL(changed()), this, SLOT(onAllAdminsChanged())); setAttribute(Qt::WA_OpaquePaintEvent); @@ -155,6 +177,39 @@ void ContactsInner::init() { connect(App::main(), SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(peerUpdated(PeerData*))); } +void ContactsInner::initList() { + if (!_chat || _membersFilter != MembersFilterAdmins) return; + + QList admins, others; + admins.reserve(_chat->admins.size() + 1); + if (!_chat->participants.isEmpty()) { + others.reserve(_chat->participants.size()); + } + + for (ChatData::Participants::const_iterator i = _chat->participants.cbegin(), e = _chat->participants.cend(); i != e; ++i) { + if (i.key()->id == peerFromUser(_chat->creator)) continue; + if (!_allAdmins.checked() && _chat->admins.contains(i.key())) { + admins.push_back(i.key()); + _checkedContacts.insert(i.key(), true); + } else { + others.push_back(i.key()); + } + } + std::sort(admins.begin(), admins.end(), _sortByName); + std::sort(others.begin(), others.end(), _sortByName); + if (UserData *creator = App::userLoaded(_chat->creator)) { + if (_chat->participants.contains(creator)) { + admins.push_front(creator); + } + } + for (int32 i = 0, l = admins.size(); i < l; ++i) { + _contacts->addToEnd(App::history(admins.at(i)->id)); + } + for (int32 i = 0, l = others.size(); i < l; ++i) { + _contacts->addToEnd(App::history(others.at(i)->id)); + } +} + void ContactsInner::onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) { if (bot()) { _contacts->peerNameChanged(peer, oldNames, oldChars); @@ -183,6 +238,15 @@ void ContactsInner::onNoAddAdminBox(QObject *obj) { } } +void ContactsInner::onAllAdminsChanged() { + if (_saving) { + if (_allAdmins.checked() != _allAdminsChecked) { + _allAdmins.setChecked(_allAdminsChecked); + } + } + update(); +} + void ContactsInner::addAdminDone(const MTPBool &result, mtpRequestId req) { if (req != _addAdminRequestId) return; @@ -208,8 +272,19 @@ bool ContactsInner::addAdminFail(const RPCError &error, mtpRequestId req) { return true; } +void ContactsInner::saving(bool flag) { + _saving = flag; + _allAdminsChecked = _allAdmins.checked(); + update(); +} + void ContactsInner::peerUpdated(PeerData *peer) { if (_chat && (!peer || peer == _chat)) { + bool inited = false; + if (_membersFilter == MembersFilterAdmins && !_contacts->list.count && !_chat->participants.isEmpty()) { + initList(); + inited = true; + } if (!_chat->amIn()) { App::wnd()->hideLayer(); } else if (!_chat->participants.isEmpty() || _chat->count <= 0) { @@ -226,6 +301,10 @@ void ContactsInner::peerUpdated(PeerData *peer) { } } } + if (inited) { + _filter += 'a'; + updateFilter(_lastQuery); + } update(); } else { ContactsData::iterator i = _contactsData.find(peer); @@ -291,7 +370,11 @@ ContactsInner::ContactData *ContactsInner::contactData(DialogRow *row) { _contactsData.insert(peer, data = new ContactData()); if (peer->isUser()) { if (_chat) { - data->inchat = _chat->participants.contains(peer->asUser()); + if (_membersFilter == MembersFilterRecent) { + data->inchat = _chat->participants.contains(peer->asUser()); + } else { + data->inchat = false; + } } else if (_creating == CreatingGroupGroup) { data->inchat = (peerToUser(peer->id) == MTP::authedId()); } else if (_channel) { @@ -327,15 +410,21 @@ ContactsInner::ContactData *ContactsInner::contactData(DialogRow *row) { void ContactsInner::paintDialog(Painter &p, PeerData *peer, ContactData *data, bool sel) { UserData *user = peer->asUser(); - if (data->inchat || data->check || selectedCount() >= cMaxGroupCount()) { - sel = false; + bool inverse = data->inchat || data->check; + if (_chat && _membersFilter == MembersFilterAdmins) { + inverse = false; + if (_allAdmins.checked() || peer->id == peerFromUser(_chat->creator) || _saving) { + sel = false; + } + } else { + if (data->inchat || data->check || selectedCount() >= cMaxGroupCount()) { + sel = false; + } } - - p.fillRect(0, 0, width(), _rowHeight, ((data->inchat || data->check) ? st::contactsBgActive : (sel ? st::contactsBgOver : st::white))->b); + p.fillRect(0, 0, width(), _rowHeight, inverse ? st::contactsBgActive : (sel ? st::contactsBgOver : st::white)); + p.setPen(inverse ? st::white : st::black); p.drawPixmapLeft(st::contactsPadding.left(), st::contactsPadding.top(), width(), peer->photo->pix(st::contactsPhotoSize)); - p.setPen((data->inchat || data->check) ? st::white : st::black); - int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left(); int32 iconw = (_chat || _creating != CreatingGroupNone) ? (st::contactsCheckPosition.x() * 2 + st::contactsCheckIcon.pxWidth()) : 0; int32 namew = width() - namex - st::contactsPadding.right() - iconw; @@ -345,8 +434,14 @@ void ContactsInner::paintDialog(Painter &p, PeerData *peer, ContactData *data, b } data->name.drawLeftElided(p, namex, st::contactsPadding.top() + st::contactsNameTop, namew, width()); - if (_chat || (_creating != CreatingGroupNone && (!_channel || _channelFilter != MembersFilterAdmins))) { - if (sel || data->check) { + if (_chat || (_creating != CreatingGroupNone && (!_channel || _membersFilter != MembersFilterAdmins))) { + if (_chat && _membersFilter == MembersFilterAdmins) { + if (sel || data->check || peer->id == peerFromUser(_chat->creator) || _allAdmins.checked()) { + if (!data->check || peer->id == peerFromUser(_chat->creator) || _allAdmins.checked()) p.setOpacity(0.5); + p.drawSpriteRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + st::contactsCheckPosition.y(), width(), st::contactsCheckIcon); + if (!data->check || peer->id == peerFromUser(_chat->creator) || _allAdmins.checked()) p.setOpacity(1); + } + } else if (sel || data->check) { p.drawSpriteRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + st::contactsCheckPosition.y(), width(), (data->check ? st::contactsCheckActiveIcon : st::contactsCheckIcon)); } } @@ -369,7 +464,7 @@ void ContactsInner::paintDialog(Painter &p, PeerData *peer, ContactData *data, b p.drawTextLeft(namex + w, st::contactsPadding.top() + st::contactsStatusTop, width() + w, second); } } else { - if (data->inchat || data->check) { + if (inverse) { p.setPen(st::white); } else if ((user && (uname || App::onlineColorUse(user, _time))) || (peer->isChannel() && uname)) { p.setPen(st::contactsStatusFgOnline); @@ -392,12 +487,21 @@ void ContactsInner::paintEvent(QPaintEvent *e) { if (_filter.isEmpty()) { if (_contacts->list.count || !_byUsername.isEmpty()) { if (_newItemHeight) { - p.fillRect(0, 0, width(), _newItemHeight, (_newItemSel ? st::contactsBgOver : st::white)->b); - p.drawSpriteLeft(st::contactsNewItemIconPosition.x(), st::contactsNewItemIconPosition.y(), width(), st::contactsNewItemIcon); - p.setFont(st::contactsNameFont); - p.setPen(st::contactsNewItemFg); - p.drawTextLeft(st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left(), st::contactsNewItemTop, width(), lang(lng_add_contact_button)); - + if (_chat) { + p.fillRect(0, 0, width(), _newItemHeight - st::contactsPadding.bottom() - st::lineWidth, st::contactsAboutBg); + p.fillRect(0, _newItemHeight - st::contactsPadding.bottom() - st::lineWidth, width(), st::lineWidth, st::shadowColor); + p.setPen(st::black); + p.drawTextLeft(st::contactsPadding.left(), st::contactsNewItemTop, width(), lang(lng_chat_all_members_admins)); + int32 iconw = st::contactsCheckPosition.x() * 2 + st::contactsCheckIcon.pxWidth(); + int32 aboutw = width() - st::contactsPadding.left() - st::contactsPadding.right() - iconw; + (_allAdmins.checked() ? _aboutAllAdmins : _aboutAdmins).draw(p, st::contactsPadding.left(), st::contactsNewItemHeight + st::contactsAboutTop, aboutw); + } else { + p.fillRect(0, 0, width(), st::contactsNewItemHeight, (_newItemSel ? st::contactsBgOver : st::white)->b); + p.setFont(st::contactsNameFont); + p.drawSpriteLeft(st::contactsNewItemIconPosition.x(), st::contactsNewItemIconPosition.y(), width(), st::contactsNewItemIcon); + p.setPen(st::contactsNewItemFg); + p.drawTextLeft(st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left(), st::contactsNewItemTop, width(), lang(lng_add_contact_button)); + } yFrom -= _newItemHeight; yTo -= _newItemHeight; p.translate(0, _newItemHeight); @@ -434,18 +538,28 @@ void ContactsInner::paintEvent(QPaintEvent *e) { } } } else { - p.setFont(st::noContactsFont->f); - p.setPen(st::noContactsColor->p); QString text; int32 skip = 0; if (bot()) { text = lang(cDialogsReceived() ? lng_bot_no_groups : lng_contacts_loading); + } else if (_chat && _membersFilter == MembersFilterAdmins) { + text = lang(lng_contacts_loading); + p.fillRect(0, 0, width(), _newItemHeight - st::contactsPadding.bottom() - st::lineWidth, st::contactsAboutBg); + p.fillRect(0, _newItemHeight - st::contactsPadding.bottom() - st::lineWidth, width(), st::lineWidth, st::shadowColor); + p.setPen(st::black); + p.drawTextLeft(st::contactsPadding.left(), st::contactsNewItemTop, width(), lang(lng_chat_all_members_admins)); + int32 iconw = st::contactsCheckPosition.x() * 2 + st::contactsCheckIcon.pxWidth(); + int32 aboutw = width() - st::contactsPadding.left() - st::contactsPadding.right() - iconw; + (_allAdmins.checked() ? _aboutAllAdmins : _aboutAdmins).draw(p, st::contactsPadding.left(), st::contactsNewItemHeight + st::contactsAboutTop, aboutw); + p.translate(0, _newItemHeight); } else if (cContactsReceived() && !_searching) { text = lang(lng_no_contacts); skip = st::noContactsFont->height; } else { text = lang(lng_contacts_loading); } + p.setFont(st::noContactsFont->f); + p.setPen(st::noContactsColor->p); p.drawText(QRect(0, 0, width(), st::noContactsHeight - skip), text, style::al_center); } } else { @@ -455,6 +569,8 @@ void ContactsInner::paintEvent(QPaintEvent *e) { QString text; if (bot()) { text = lang(cDialogsReceived() ? lng_bot_groups_not_found : lng_contacts_loading); + } else if (_chat && _membersFilter == MembersFilterAdmins) { + text = lang(_chat->participants.isEmpty() ? lng_contacts_loading : lng_contacts_not_found); } else { text = lang((cContactsReceived() && !_searching) ? lng_contacts_not_found : lng_contacts_loading); } @@ -497,7 +613,7 @@ void ContactsInner::enterEvent(QEvent *e) { void ContactsInner::updateSelectedRow() { if (_filter.isEmpty()) { if (_newItemSel) { - update(0, 0, width(), _newItemHeight); + update(0, 0, width(), st::contactsNewItemHeight); } if (_sel) { update(0, _newItemHeight + _sel->pos * _rowHeight, width(), _rowHeight); @@ -542,7 +658,8 @@ void ContactsInner::mousePressEvent(QMouseEvent *e) { } void ContactsInner::chooseParticipant() { - bool addingAdmin = (_channel && _channelFilter == MembersFilterAdmins); + if (_saving) return; + bool addingAdmin = (_channel && _membersFilter == MembersFilterAdmins); if (!addingAdmin && (_chat || _creating != CreatingGroupNone)) { _time = unixtime(); if (_filter.isEmpty()) { @@ -668,7 +785,7 @@ void ContactsInner::updateSel() { if (_filter.isEmpty()) { bool newItemSel = false; if (_newItemHeight) { - if (in && (p.y() >= 0) && (p.y() < _newItemHeight)) { + if (in && (p.y() >= 0) && (p.y() < _newItemHeight) && !(_chat && _membersFilter == MembersFilterAdmins)) { newItemSel = true; } p.setY(p.y() - _newItemHeight); @@ -729,6 +846,7 @@ void ContactsInner::updateFilter(QString filter) { refresh(); } else { if (!_addContactLnk.isHidden()) _addContactLnk.hide(); + if (!_allAdmins.isHidden()) _allAdmins.hide(); QStringList::const_iterator fb = f.cbegin(), fe = f.cend(), fi; _filtered.clear(); @@ -808,7 +926,7 @@ void ContactsInner::updateFilter(QString filter) { _mouseSel = false; refresh(); - if (!bot()) { + if (!bot() && (!_chat || _membersFilter != MembersFilterAdmins)) { _searching = true; emit searchByUsername(); } @@ -864,7 +982,7 @@ void ContactsInner::peopleReceived(const QString &query, const QVector if ((!p->isUser() || (p->asUser()->botInfo && p->asUser()->botInfo->cantJoinGroups)) && (_chat || _creating == CreatingGroupGroup)) continue; // skip bot's that can't be invited to groups if (_channel && !p->isUser()) continue; - if (p->isUser() && p->asUser()->botInfo && _channel && _channelFilter != MembersFilterAdmins) continue; // skip bots in channels + if (p->isUser() && p->asUser()->botInfo && _channel && _membersFilter != MembersFilterAdmins) continue; // skip bots in channels ContactData *d = new ContactData(); _byUsernameDatas.push_back(d); @@ -883,9 +1001,17 @@ void ContactsInner::peopleReceived(const QString &query, const QVector void ContactsInner::refresh() { if (_filter.isEmpty()) { + if (_chat && _membersFilter == MembersFilterAdmins) { + if (_allAdmins.isHidden()) _allAdmins.show(); + } else { + if (!_allAdmins.isHidden()) _allAdmins.hide(); + } if (_contacts->list.count || !_byUsername.isEmpty()) { if (!_addContactLnk.isHidden()) _addContactLnk.hide(); resize(width(), _newItemHeight + (_contacts->list.count * _rowHeight) + (_byUsername.isEmpty() ? 0 : (st::searchedBarHeight + _byUsername.size() * _rowHeight))); + } else if (_chat && _membersFilter == MembersFilterAdmins) { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); + resize(width(), _newItemHeight + st::noContactsHeight); } else { if (cContactsReceived() && !bot()) { if (_addContactLnk.isHidden()) _addContactLnk.show(); @@ -895,6 +1021,7 @@ void ContactsInner::refresh() { resize(width(), st::noContactsHeight); } } else { + if (!_allAdmins.isHidden()) _allAdmins.hide(); if (_filtered.isEmpty() && _byUsernameFiltered.isEmpty()) { if (!_addContactLnk.isHidden()) _addContactLnk.hide(); resize(width(), st::noContactsHeight); @@ -913,8 +1040,8 @@ ChannelData *ContactsInner::channel() const { return _channel; } -MembersFilter ContactsInner::channelFilter() const { - return _channelFilter; +MembersFilter ContactsInner::membersFilter() const { + return _membersFilter; } UserData *ContactsInner::bot() const { @@ -929,14 +1056,15 @@ ContactsInner::~ContactsInner() { for (ContactsData::iterator i = _contactsData.begin(), e = _contactsData.end(); i != e; ++i) { delete *i; } - if (_bot) { + if (_bot || (_chat && _membersFilter == MembersFilterAdmins)) { delete _contacts; - if (_bot->botInfo) _bot->botInfo->startGroupToken = QString(); + if (_bot && _bot->botInfo) _bot->botInfo->startGroupToken = QString(); } } void ContactsInner::resizeEvent(QResizeEvent *e) { _addContactLnk.move((width() - _addContactLnk.width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2); + _allAdmins.moveToLeft(st::contactsPadding.left(), st::contactsNewItemTop); } void ContactsInner::selectSkip(int32 dir) { @@ -957,7 +1085,7 @@ void ContactsInner::selectSkip(int32 dir) { } cur += dir; if (cur <= 0) { - _newItemSel = _newItemHeight ? true : false; + _newItemSel = (_chat && _membersFilter == MembersFilterAdmins) ? false : (_newItemHeight ? true : false); _sel = (!_newItemHeight && _contacts->list.count) ? _contacts->list.begin : 0; _byUsernameSel = (!_newItemHeight && !_contacts->list.count && !_byUsername.isEmpty()) ? 0 : -1; } else if (cur >= _contacts->list.count + (_newItemHeight ? 1 : 0)) { @@ -1138,7 +1266,7 @@ ContactsBox::ContactsBox() : ItemListBox(st::contactsScroll) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) , _topShadow(this) , _bottomShadow(0) -, _creationRequestId(0) { +, _saveRequestId(0) { init(); } @@ -1150,21 +1278,21 @@ ContactsBox::ContactsBox(const QString &name, const QImage &photo) : ItemListBox , _cancel(this, lang(lng_create_group_back), st::cancelBoxButton) , _topShadow(this) , _bottomShadow(0) -, _creationRequestId(0) +, _saveRequestId(0) , _creationName(name) , _creationPhoto(photo) { init(); } ContactsBox::ContactsBox(ChannelData *channel) : ItemListBox(st::boxScroll) -, _inner(channel) +, _inner(channel, MembersFilterRecent, MembersAlreadyIn()) , _filter(this, st::boxSearchField, lang(lng_participant_filter)) , _filterCancel(this, st::boxSearchCancel) , _next(this, lang(lng_participant_invite), st::defaultBoxButton) , _cancel(this, lang(lng_create_group_skip), st::cancelBoxButton) , _topShadow(this) , _bottomShadow(0) -, _creationRequestId(0) { +, _saveRequestId(0) { init(); } @@ -1176,19 +1304,19 @@ ContactsBox::ContactsBox(ChannelData *channel, MembersFilter filter, const Membe , _cancel(this, lang(lng_cancel), st::cancelBoxButton) , _topShadow(this) , _bottomShadow(0) -, _creationRequestId(0) { +, _saveRequestId(0) { init(); } -ContactsBox::ContactsBox(ChatData *chat) : ItemListBox(st::boxScroll) -, _inner(chat) +ContactsBox::ContactsBox(ChatData *chat, MembersFilter filter) : ItemListBox(st::boxScroll) +, _inner(chat, filter) , _filter(this, st::boxSearchField, lang(lng_participant_filter)) , _filterCancel(this, st::boxSearchCancel) -, _next(this, lang(lng_participant_invite), st::defaultBoxButton) +, _next(this, lang((filter == MembersFilterAdmins) ? lng_settings_save : lng_participant_invite), st::defaultBoxButton) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) , _topShadow(this) , _bottomShadow(0) -, _creationRequestId(0) { +, _saveRequestId(0) { init(); } @@ -1200,21 +1328,24 @@ ContactsBox::ContactsBox(UserData *bot) : ItemListBox(st::contactsScroll) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) , _topShadow(this) , _bottomShadow(0) -, _creationRequestId(0) { +, _saveRequestId(0) { init(); } void ContactsBox::init() { - bool inviting = (_inner.creating() == CreatingGroupGroup) || (_inner.channel() && _inner.channelFilter() == MembersFilterRecent) || _inner.chat(); + bool inviting = (_inner.creating() == CreatingGroupGroup) || (_inner.channel() && _inner.membersFilter() == MembersFilterRecent) || _inner.chat(); int32 topSkip = st::boxTitleHeight + _filter.height(); int32 bottomSkip = inviting ? (st::boxButtonPadding.top() + _next.height() + st::boxButtonPadding.bottom()) : st::boxScrollSkip; ItemListBox::init(&_inner, bottomSkip, topSkip); connect(&_inner, SIGNAL(chosenChanged()), this, SLOT(onChosenChanged())); connect(&_inner, SIGNAL(addRequested()), App::wnd(), SLOT(onShowAddContact())); - if (_inner.channel() && _inner.channelFilter() == MembersFilterAdmins) { + if (_inner.channel() && _inner.membersFilter() == MembersFilterAdmins) { _next.hide(); _cancel.hide(); + } else if (_inner.chat() && _inner.membersFilter() == MembersFilterAdmins) { + connect(&_next, SIGNAL(clicked()), this, SLOT(onSaveAdmins())); + _bottomShadow = new ScrollableBoxShadow(this); } else if (_inner.chat() || _inner.channel()) { connect(&_next, SIGNAL(clicked()), this, SLOT(onInvite())); _bottomShadow = new ScrollableBoxShadow(this); @@ -1328,7 +1459,7 @@ void ContactsBox::showAll() { } else { _filterCancel.show(); } - if (_inner.channel() && _inner.channelFilter() == MembersFilterAdmins) { + if (_inner.channel() && _inner.membersFilter() == MembersFilterAdmins) { _next.hide(); _cancel.hide(); } else if (_inner.chat() || _inner.channel()) { @@ -1378,8 +1509,10 @@ void ContactsBox::paintEvent(QPaintEvent *e) { Painter p(this); if (paint(p)) return; - bool addingAdmin = _inner.channel() && _inner.channelFilter() == MembersFilterAdmins; - if (_inner.chat() || _inner.creating() != CreatingGroupNone) { + bool addingAdmin = _inner.channel() && _inner.membersFilter() == MembersFilterAdmins; + if (_inner.chat() && _inner.membersFilter() == MembersFilterAdmins) { + paintTitle(p, lang(lng_channel_admins)); + } else if (_inner.chat() || _inner.creating() != CreatingGroupNone) { QString title(lang(addingAdmin ? lng_channel_add_admin : lng_profile_add_participant)); QString additional(addingAdmin ? QString() : QString("%1 / %2").arg(_inner.selectedCount()).arg(cMaxGroupCount())); paintTitle(p, title, additional); @@ -1444,7 +1577,7 @@ void ContactsBox::onInvite() { } void ContactsBox::onCreate() { - if (_creationRequestId) return; + if (_saveRequestId) return; MTPVector users(MTP_vector(_inner.selectedInputs())); const QVector &v(users.c_vector().v); @@ -1453,7 +1586,101 @@ void ContactsBox::onCreate() { _filter.showError(); return; } - _creationRequestId = MTP::send(MTPmessages_CreateChat(MTP_vector(v), MTP_string(_creationName)), rpcDone(&ContactsBox::creationDone), rpcFail(&ContactsBox::creationFail)); + _saveRequestId = MTP::send(MTPmessages_CreateChat(MTP_vector(v), MTP_string(_creationName)), rpcDone(&ContactsBox::creationDone), rpcFail(&ContactsBox::creationFail)); +} + +void ContactsBox::onSaveAdmins() { + if (_saveRequestId) return; + + _inner.saving(true); + _saveRequestId = MTP::send(MTPmessages_ToggleChatAdmins(_inner.chat()->inputChat, MTP_bool(!_inner.allAdmins())), rpcDone(&ContactsBox::saveAdminsDone), rpcFail(&ContactsBox::saveAdminsFail)); +} + +void ContactsBox::saveAdminsDone(const MTPUpdates &result) { + App::main()->sentUpdatesReceived(result); + saveSelectedAdmins(); +} + +void ContactsBox::saveSelectedAdmins() { + if (_inner.allAdmins() && !_inner.chat()->participants.isEmpty()) { + onClose(); + } else { + _saveRequestId = MTP::send(MTPmessages_GetFullChat(_inner.chat()->inputChat), rpcDone(&ContactsBox::getAdminsDone), rpcFail(&ContactsBox::saveAdminsFail)); + } +} + +void ContactsBox::getAdminsDone(const MTPmessages_ChatFull &result) { + App::api()->processFullPeer(_inner.chat(), result); + if (_inner.allAdmins()) { + onClose(); + return; + } + ChatData::Admins curadmins = _inner.chat()->admins; + QVector newadmins = _inner.selected(), appoint; + if (!newadmins.isEmpty()) { + appoint.reserve(newadmins.size()); + for (int32 i = 0, l = newadmins.size(); i < l; ++i) { + ChatData::Admins::iterator c = curadmins.find(newadmins.at(i)); + if (c == curadmins.cend()) { + if (newadmins.at(i)->id != peerFromUser(_inner.chat()->creator)) { + appoint.push_back(newadmins.at(i)); + } + } else { + curadmins.erase(c); + } + } + } + _saveRequestId = 0; + for (ChatData::Admins::const_iterator i = curadmins.cbegin(), e = curadmins.cend(); i != e; ++i) { + MTP::send(MTPmessages_EditChatAdmin(_inner.chat()->inputChat, i.key()->inputUser, MTP_boolFalse()), rpcDone(&ContactsBox::removeAdminDone, i.key()), rpcFail(&ContactsBox::editAdminFail), 0, (appoint.isEmpty() && i + 1 == e) ? 0 : 10); + } + for (int32 i = 0, l = appoint.size(); i < l; ++i) { + MTP::send(MTPmessages_EditChatAdmin(_inner.chat()->inputChat, appoint.at(i)->inputUser, MTP_boolTrue()), rpcDone(&ContactsBox::setAdminDone, appoint.at(i)), rpcFail(&ContactsBox::editAdminFail), 0, (i + 1 == l) ? 0 : 10); + } + _saveRequestId = curadmins.size() + appoint.size(); + if (!_saveRequestId) { + onClose(); + } +} + +void ContactsBox::setAdminDone(UserData *user, const MTPBool &result) { + if (mtpIsTrue(result)) { + _inner.chat()->admins.insert(user, true); + } + --_saveRequestId; + if (!_saveRequestId) { + emit App::main()->peerUpdated(_inner.chat()); + onClose(); + } +} + +void ContactsBox::removeAdminDone(UserData *user, const MTPBool &result) { + if (mtpIsTrue(result)) { + _inner.chat()->admins.remove(user); + } + --_saveRequestId; + if (!_saveRequestId) { + emit App::main()->peerUpdated(_inner.chat()); + onClose(); + } +} + +bool ContactsBox::saveAdminsFail(const RPCError &error) { + if (mtpIsFlood(error)) return true; + _saveRequestId = 0; + _inner.saving(false); + if (error.type() == qstr("CHAT_NOT_MODIFIED")) { + saveSelectedAdmins(); + } + return false; +} + +bool ContactsBox::editAdminFail(const RPCError &error) { + if (mtpIsFlood(error)) return true; + --_saveRequestId; + _inner.chat()->invalidateParticipants(false); + if (!_saveRequestId) onClose(); + return false; } void ContactsBox::onScroll() { @@ -1488,7 +1715,7 @@ void ContactsBox::creationDone(const MTPUpdates &updates) { bool ContactsBox::creationFail(const RPCError &error) { if (mtpIsFlood(error)) return false; - _creationRequestId = 0; + _saveRequestId = 0; if (error.type() == "NO_CHAT_TITLE") { emit closed(); return true; diff --git a/Telegram/SourceFiles/boxes/contactsbox.h b/Telegram/SourceFiles/boxes/contactsbox.h index 6d2a63fd9..a513bb1f2 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.h +++ b/Telegram/SourceFiles/boxes/contactsbox.h @@ -39,10 +39,11 @@ private: public: ContactsInner(CreatingGroupType creating = CreatingGroupNone); - ContactsInner(ChannelData *channel, MembersFilter channelFilter = MembersFilterRecent, const MembersAlreadyIn &already = MembersAlreadyIn()); - ContactsInner(ChatData *chat); + ContactsInner(ChannelData *channel, MembersFilter membersFilter, const MembersAlreadyIn &already); + ContactsInner(ChatData *chat, MembersFilter membersFilter); ContactsInner(UserData *bot); void init(); + void initList(); void paintEvent(QPaintEvent *e); void enterEvent(QEvent *e); @@ -60,6 +61,9 @@ public: QVector selected(); QVector selectedInputs(); PeerData *selectedUser(); + bool allAdmins() const { + return _allAdmins.checked(); + } void loadProfilePhotos(int32 yFrom); void chooseParticipant(); @@ -72,7 +76,7 @@ public: ChatData *chat() const; ChannelData *channel() const; - MembersFilter channelFilter() const; + MembersFilter membersFilter() const; UserData *bot() const; CreatingGroupType creating() const; @@ -81,6 +85,8 @@ public: return !_already.isEmpty(); } + void saving(bool flag); + ~ContactsInner(); signals: @@ -104,6 +110,8 @@ public slots: void onAddAdmin(); void onNoAddAdminBox(QObject *obj); + void onAllAdminsChanged(); + private: void updateSelectedRow(); @@ -115,11 +123,15 @@ private: ChatData *_chat; ChannelData *_channel; - MembersFilter _channelFilter; + MembersFilter _membersFilter; UserData *_bot; CreatingGroupType _creating; MembersAlreadyIn _already; + Checkbox _allAdmins; + int32 _aboutWidth; + Text _aboutAllAdmins, _aboutAdmins; + ChatData *_addToChat; UserData *_addAdmin; mtpRequestId _addAdminRequestId; @@ -162,6 +174,9 @@ private: QPoint _lastMousePos; LinkButton _addContactLnk; + bool _saving; + bool _allAdminsChecked; + }; class ContactsBox : public ItemListBox, public RPCSender { @@ -173,7 +188,7 @@ public: ContactsBox(const QString &name, const QImage &photo); // group creation ContactsBox(ChannelData *channel); // channel setup ContactsBox(ChannelData *channel, MembersFilter filter, const MembersAlreadyIn &already); - ContactsBox(ChatData *chat); + ContactsBox(ChatData *chat, MembersFilter filter); ContactsBox(UserData *bot); void keyPressEvent(QKeyEvent *e); void paintEvent(QPaintEvent *e); @@ -198,6 +213,7 @@ public slots: void onInvite(); void onCreate(); + void onSaveAdmins(); bool onSearchByUsername(bool searchCache = false); void onNeedSearchByUsername(); @@ -235,8 +251,18 @@ private: typedef QMap PeopleQueries; PeopleQueries _peopleQueries; + int32 _saveRequestId; + + // saving admins + void saveAdminsDone(const MTPUpdates &result); + void saveSelectedAdmins(); + void getAdminsDone(const MTPmessages_ChatFull &result); + void setAdminDone(UserData *user, const MTPBool &result); + void removeAdminDone(UserData *user, const MTPBool &result); + bool saveAdminsFail(const RPCError &error); + bool editAdminFail(const RPCError &error); + // group creation - int32 _creationRequestId; QString _creationName; QImage _creationPhoto; diff --git a/Telegram/SourceFiles/gui/flatcheckbox.cpp b/Telegram/SourceFiles/gui/flatcheckbox.cpp index b327f72e9..7e4b8225e 100644 --- a/Telegram/SourceFiles/gui/flatcheckbox.cpp +++ b/Telegram/SourceFiles/gui/flatcheckbox.cpp @@ -331,10 +331,12 @@ void Checkbox::paintEvent(QPaintEvent *e) { pen.setWidth(_st.thickness); p.setPen(pen); if (checked > 0) { - color.setAlphaF(checked); + color.setRedF(color.redF() * checked + st::white->c.redF() * (1. - checked)); + color.setGreenF(color.greenF() * checked + st::white->c.greenF() * (1. - checked)); + color.setBlueF(color.blueF() * checked + st::white->c.blueF() * (1. - checked)); p.setBrush(color); } else { - p.setBrush(Qt::NoBrush); + p.setBrush(st::white); } p.drawRoundedRect(QRectF(_checkRect).marginsRemoved(QMarginsF(_st.thickness / 2, _st.thickness / 2, _st.thickness / 2, _st.thickness / 2)), st::msgRadius, st::msgRadius); p.setRenderHint(QPainter::HighQualityAntialiasing, false); diff --git a/Telegram/SourceFiles/gui/style_core.h b/Telegram/SourceFiles/gui/style_core.h index 676a70927..8939118bc 100644 --- a/Telegram/SourceFiles/gui/style_core.h +++ b/Telegram/SourceFiles/gui/style_core.h @@ -71,6 +71,8 @@ namespace style { return !!ptr; } + operator const QFont &() const; + private: FontData *ptr; @@ -143,12 +145,16 @@ namespace style { }; -inline bool operator==(const Font &a, const Font &b) { - return a.v() == b.v(); -} -inline bool operator!=(const Font &a, const Font &b) { - return a.v() != b.v(); -} + inline bool operator==(const Font &a, const Font &b) { + return a.v() == b.v(); + } + inline bool operator!=(const Font &a, const Font &b) { + return a.v() != b.v(); + } + + inline Font::operator const QFont &() const { + return ptr->f; + } class ColorData; class Color { @@ -164,6 +170,9 @@ inline bool operator!=(const Font &a, const Font &b) { void set(const QColor &newv); void set(uchar r, uchar g, uchar b, uchar a = 255); + operator const QBrush &() const; + operator const QPen &() const; + ColorData *operator->() const { return ptr; } @@ -217,6 +226,12 @@ inline bool operator!=(const Font &a, const Font &b) { return a->c != b->c; } + inline Color::operator const QBrush &() const { + return ptr->b; + } + inline Color::operator const QPen &() const { + return ptr->p; + } typedef QVector FontFamilies; extern FontFamilies _fontFamilies; diff --git a/Telegram/SourceFiles/gui/twidget.h b/Telegram/SourceFiles/gui/twidget.h index 9cf324075..411762e1b 100644 --- a/Telegram/SourceFiles/gui/twidget.h +++ b/Telegram/SourceFiles/gui/twidget.h @@ -29,37 +29,6 @@ public: explicit Painter(QPaintDevice *device) : QPainter(device) { } - void setFont(const style::font &font) { - QPainter::setFont(font->f); - } - void setFont(const QFont &font) { - QPainter::setFont(font); - } - void setBrush(const style::color &color) { - QPainter::setBrush(color->b); - } - void setBrush(const QColor &color) { - QPainter::setBrush(color); - } - void setBrush(const QBrush &brush) { - QPainter::setBrush(brush); - } - void setBrush(Qt::BrushStyle style) { - QPainter::setBrush(style); - } - void setPen(const style::color &color) { - QPainter::setPen(color->p); - } - void setPen(const QPen &pen) { - QPainter::setPen(pen); - } - void setPen(const QColor &color) { - QPainter::setPen(color); - } - void setPen(Qt::PenStyle style) { - QPainter::setPen(style); - } - void drawTextLeft(int x, int y, int outerw, const QString &text, int textWidth = -1) { QFontMetrics m(fontMetrics()); if (rtl() && textWidth < 0) textWidth = m.width(text); diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index e12e201d0..cc7b89af8 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -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) : ((_peerChat && _peerChat->adminsEnabled() && !_peerChat->admins.isEmpty()) ? _peerChat->admins.size() : 0)))), + _admins(this, lng_channel_admins_link(lt_count, (_peerChannel ? (_peerChannel->adminsCount > 0 ? _peerChannel->adminsCount : 1) : ((_peerChat && _peerChat->adminsEnabled()) ? (_peerChat->admins.size() + 1) : 0)))), // about _about(st::wndMinWidth - st::profilePadding.left() - st::profilePadding.right()), @@ -351,7 +351,7 @@ bool ProfileInner::blockFail(const RPCError &error) { void ProfileInner::onAddParticipant() { if (!_peerChat) return; - App::wnd()->showLayer(new ContactsBox(_peerChat)); + App::wnd()->showLayer(new ContactsBox(_peerChat, MembersFilterRecent)); } void ProfileInner::onUpdatePhotoCancel() { @@ -430,6 +430,7 @@ void ProfileInner::onAdmins() { if (_peerChannel) { App::wnd()->showLayer(new MembersBox(_peerChannel, MembersFilterAdmins)); } else if (_peerChat) { + App::wnd()->showLayer(new ContactsBox(_peerChat, MembersFilterAdmins)); } } @@ -486,10 +487,11 @@ void ProfileInner::onFullPeerUpdated(PeerData *peer) { updateInvitationLink(); showAll(); resizeEvent(0); + _admins.setText(lng_channel_admins_link(lt_count, _peerChat->adminsEnabled() ? (_peerChat->admins.size() + 1) : 0)); } 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 ? (_peerChannel->adminsCount > 0 ? _peerChannel->adminsCount : 1) : ((_peerChat && _peerChat->adminsEnabled() && !_peerChat->admins.isEmpty()) ? _peerChat->admins.size() : 0)))); + _admins.setText(lng_channel_admins_link(lt_count, (_peerChannel->adminsCount > 0) ? _peerChannel->adminsCount : 1)); _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()); @@ -541,13 +543,14 @@ void ProfileInner::peerUpdated(PeerData *data) { } } else if (_peerChat) { if (_peerChat->photoId && _peerChat->photoId != UnknownPeerPhotoId) photo = App::photo(_peerChat->photoId); + _admins.setText(lng_channel_admins_link(lt_count, _peerChat->adminsEnabled() ? (_peerChat->admins.size() + 1) : 0)); } else if (_peerChannel) { if (_peerChannel->photoId && _peerChannel->photoId != UnknownPeerPhotoId) photo = App::photo(_peerChannel->photoId); if (_peerChannel->isPublic() != _invitationLink.isHidden()) { peerUsernameChanged(); } _members.setText(lng_channel_members_link(lt_count, (_peerChannel->count > 0) ? _peerChannel->count : 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)))); + _admins.setText(lng_channel_admins_link(lt_count, (_peerChannel->adminsCount > 0) ? _peerChannel->adminsCount : 1)); _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();