Shared media block done in the new profile implementation.

Preparing to call Notify::peerUpdatedSendDelayed() only from event loop.
This commit is contained in:
John Preston 2016-06-02 16:02:55 +03:00
parent 3fc7cc3453
commit 2c4ec3d9f3
35 changed files with 646 additions and 193 deletions

View file

@ -117,8 +117,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_channel_status" = "channel";
"lng_group_status" = "group";
"lng_channel_members_link" = "{count:_not_used_|# member|# members} »";
"lng_channel_admins_link" = "{count:Manage administrators|# administrator|# administrators} »";
"lng_channel_members_link" = "{count:_not_used_|# member|# members}";
"lng_channel_admins_link" = "{count:_not_used_|# administrator|# administrators}";
"lng_server_error" = "Internal server error.";
"lng_flood_error" = "Too many tries. Please try again later.";
@ -446,17 +446,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_profile_loading" = "Loading...";
"lng_profile_shared_media" = "Shared media";
"lng_profile_no_media" = "No media in this conversation.";
"lng_profile_photos" = "{count:_not_used_|# photo|# photos} »";
"lng_profile_photos" = "{count:_not_used_|# photo|# photos}";
"lng_profile_photos_header" = "Photos overview";
"lng_profile_videos" = "{count:_not_used_|# video file|# video files} »";
"lng_profile_videos" = "{count:_not_used_|# video file|# video files}";
"lng_profile_videos_header" = "Video files overview";
"lng_profile_songs" = "{count:_not_used_|# audio file|# audio files} »";
"lng_profile_songs" = "{count:_not_used_|# audio file|# audio files}";
"lng_profile_songs_header" = "Audio files overview";
"lng_profile_files" = "{count:_not_used_|# file|# files} »";
"lng_profile_files" = "{count:_not_used_|# file|# files}";
"lng_profile_files_header" = "Files overview";
"lng_profile_audios" = "{count:_not_used_|# voice message|# voice messages} »";
"lng_profile_audios" = "{count:_not_used_|# voice message|# voice messages}";
"lng_profile_audios_header" = "Voice messages overview";
"lng_profile_shared_links" = "{count:_not_used_|# shared link|# shared links} »";
"lng_profile_shared_links" = "{count:_not_used_|# shared link|# shared links}";
"lng_profile_shared_links_header" = "Shared links overview";
"lng_profile_copy_phone" = "Copy phone number";
"lng_profile_copy_fullname" = "Copy name";

View file

@ -226,6 +226,10 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
const auto &f(d.vfull_chat.c_channelFull());
PhotoData *photo = App::feedPhoto(f.vchat_photo);
ChannelData *channel = peer->asChannel();
auto canViewAdmins = channel->canViewAdmins();
auto canViewMembers = channel->canViewMembers();
channel->flagsFull = f.vflags.v;
if (photo) {
channel->photoId = photo->id;
@ -277,15 +281,8 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
}
}
channel->setAbout(qs(f.vabout));
int32 newCount = f.has_participants_count() ? f.vparticipants_count.v : 0;
if (newCount != channel->count) {
if (channel->isMegagroup() && !channel->mgInfo->lastParticipants.isEmpty()) {
channel->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
channel->mgInfo->lastParticipantsCount = channel->count;
}
channel->count = newCount;
}
channel->adminsCount = f.has_admins_count() ? f.vadmins_count.v : 0;
channel->setMembersCount(f.has_participants_count() ? f.vparticipants_count.v : 0);
channel->setAdminsCount(f.has_admins_count() ? f.vadmins_count.v : 0);
channel->setInviteLink((f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString());
if (History *h = App::historyLoaded(channel->id)) {
if (h->inboxReadBefore < f.vread_inbox_max_id.v + 1) {
@ -303,6 +300,9 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
}
channel->fullUpdated();
if (canViewAdmins != channel->canViewAdmins()) Notify::peerUpdatedDelayed(channel, Notify::PeerUpdate::Flag::ChannelCanViewAdmins);
if (canViewMembers != channel->canViewMembers()) Notify::peerUpdatedDelayed(channel, Notify::PeerUpdate::Flag::ChannelCanViewMembers);
notifySettingReceived(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
}
@ -549,16 +549,16 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP
h->clearLastKeyboard();
if (App::main()) App::main()->updateBotKeyboard(h);
}
if (d.vcount.v > peer->count) {
peer->count = d.vcount.v;
} else if (v.count() > peer->count) {
peer->count = v.count();
int newMembersCount = qMax(d.vcount.v, v.count());
if (newMembersCount > peer->membersCount()) {
peer->setMembersCount(newMembersCount);
}
if (!bots && v.isEmpty()) {
peer->count = peer->mgInfo->lastParticipants.size();
peer->setMembersCount(peer->mgInfo->lastParticipants.size());
}
peer->mgInfo->botStatus = botStatus;
if (App::main()) emit fullPeerUpdated(peer);
Notify::peerUpdatedSendDelayed();
}
bool ApiWrap::lastParticipantsFail(ChannelData *peer, const RPCError &error, mtpRequestId req) {
@ -637,28 +637,33 @@ void ApiWrap::kickParticipant(PeerData *peer, UserData *user) {
void ApiWrap::kickParticipantDone(KickRequest kick, const MTPUpdates &result, mtpRequestId req) {
_kickRequests.remove(kick);
if (kick.first->isMegagroup()) {
int32 i = kick.first->asChannel()->mgInfo->lastParticipants.indexOf(kick.second);
auto channel = kick.first->asChannel();
auto megagroupInfo = channel->mgInfo;
int32 i = megagroupInfo->lastParticipants.indexOf(kick.second);
if (i >= 0) {
kick.first->asChannel()->mgInfo->lastParticipants.removeAt(i);
megagroupInfo->lastParticipants.removeAt(i);
}
if (kick.first->asChannel()->count > 1) {
--kick.first->asChannel()->count;
if (channel->membersCount() > 1) {
channel->setMembersCount(channel->membersCount() - 1);
} else {
kick.first->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
kick.first->asChannel()->mgInfo->lastParticipantsCount = 0;
megagroupInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
megagroupInfo->lastParticipantsCount = 0;
}
if (kick.first->asChannel()->mgInfo->lastAdmins.contains(kick.second)) {
kick.first->asChannel()->mgInfo->lastAdmins.remove(kick.second);
if (kick.first->asChannel()->adminsCount > 1) {
--kick.first->asChannel()->adminsCount;
if (megagroupInfo->lastAdmins.contains(kick.second)) {
megagroupInfo->lastAdmins.remove(kick.second);
if (channel->adminsCount() > 1) {
channel->setAdminsCount(channel->adminsCount() - 1);
}
}
kick.first->asChannel()->mgInfo->bots.remove(kick.second);
if (kick.first->asChannel()->mgInfo->bots.isEmpty() && kick.first->asChannel()->mgInfo->botStatus > 0) {
kick.first->asChannel()->mgInfo->botStatus = -1;
megagroupInfo->bots.remove(kick.second);
if (megagroupInfo->bots.isEmpty() && megagroupInfo->botStatus > 0) {
megagroupInfo->botStatus = -1;
}
}
emit fullPeerUpdated(kick.first);
Notify::peerUpdatedSendDelayed();
}
bool ApiWrap::kickParticipantFail(KickRequest kick, const RPCError &error, mtpRequestId req) {

View file

@ -656,7 +656,9 @@ namespace {
auto cdata = data->asChannel();
auto wasInChannel = cdata->amIn();
auto canEditPhoto = cdata->canEditPhoto();
auto canAddMembers = cdata->canAddParticipants();
auto canViewAdmins = cdata->canViewAdmins();
auto canViewMembers = cdata->canViewMembers();
auto canAddMembers = cdata->canAddMembers();
auto wasEditor = cdata->amEditor();
if (minimal) {
@ -683,18 +685,12 @@ namespace {
cdata->flagsUpdated();
cdata->setPhoto(d.vphoto);
if (wasInChannel != cdata->amIn()) {
update.flags |= UpdateFlag::ChannelAmIn;
}
if (canEditPhoto != cdata->canEditPhoto()) {
update.flags |= UpdateFlag::ChannelCanEditPhoto;
}
if (canAddMembers != cdata->canAddParticipants()) {
update.flags |= UpdateFlag::ChannelCanAddMembers;
}
if (wasEditor != cdata->amEditor()) {
update.flags |= UpdateFlag::ChannelAmEditor;
}
if (wasInChannel != cdata->amIn()) update.flags |= UpdateFlag::ChannelAmIn;
if (canEditPhoto != cdata->canEditPhoto()) update.flags |= UpdateFlag::ChannelCanEditPhoto;
if (canViewAdmins != cdata->canViewAdmins()) update.flags |= UpdateFlag::ChannelCanViewAdmins;
if (canViewMembers != cdata->canViewMembers()) update.flags |= UpdateFlag::ChannelCanViewMembers;
if (canAddMembers != cdata->canAddMembers()) update.flags |= UpdateFlag::ChannelCanAddMembers;
if (wasEditor != cdata->amEditor()) update.flags |= UpdateFlag::ChannelAmEditor;
} break;
case mtpc_channelForbidden: {
auto &d(chat.c_channelForbidden());
@ -706,7 +702,9 @@ namespace {
auto cdata = data->asChannel();
auto wasInChannel = cdata->amIn();
auto canEditPhoto = cdata->canEditPhoto();
auto canAddMembers = cdata->canAddParticipants();
auto canViewAdmins = cdata->canViewAdmins();
auto canViewMembers = cdata->canViewMembers();
auto canAddMembers = cdata->canAddMembers();
auto wasEditor = cdata->amEditor();
cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash);
@ -716,21 +714,15 @@ namespace {
cdata->access = d.vaccess_hash.v;
cdata->setPhoto(MTP_chatPhotoEmpty());
cdata->date = 0;
cdata->count = 0;
cdata->setMembersCount(0);
cdata->isForbidden = true;
if (wasInChannel != cdata->amIn()) {
update.flags |= UpdateFlag::ChannelAmIn;
}
if (canEditPhoto != cdata->canEditPhoto()) {
update.flags |= UpdateFlag::ChannelCanEditPhoto;
}
if (canAddMembers != cdata->canAddParticipants()) {
update.flags |= UpdateFlag::ChannelCanAddMembers;
}
if (wasEditor != cdata->amEditor()) {
update.flags |= UpdateFlag::ChannelAmEditor;
}
if (wasInChannel != cdata->amIn()) update.flags |= UpdateFlag::ChannelAmIn;
if (canEditPhoto != cdata->canEditPhoto()) update.flags |= UpdateFlag::ChannelCanEditPhoto;
if (canViewAdmins != cdata->canViewAdmins()) update.flags |= UpdateFlag::ChannelCanViewAdmins;
if (canViewMembers != cdata->canViewMembers()) update.flags |= UpdateFlag::ChannelCanViewMembers;
if (canAddMembers != cdata->canAddMembers()) update.flags |= UpdateFlag::ChannelCanAddMembers;
if (wasEditor != cdata->amEditor()) update.flags |= UpdateFlag::ChannelAmEditor;
} break;
}
if (!data) continue;

View file

@ -917,6 +917,10 @@ void AppClass::call_handleFileDialogQueue() {
}
}
void AppClass::call_handleDelayedPeerUpdates() {
Notify::peerUpdatedSendDelayed();
}
void AppClass::killDownloadSessions() {
uint64 ms = getms(), left = MTPAckSendWaiting + MTPKillFileSessionTimeout;
for (QMap<int32, uint64>::iterator i = killDownloadSessionTimes.begin(); i != killDownloadSessionTimes.end(); ) {

View file

@ -204,6 +204,7 @@ public slots:
void call_handleHistoryUpdate();
void call_handleUnreadCounterUpdate();
void call_handleFileDialogQueue();
void call_handleDelayedPeerUpdates();
private:

View file

@ -477,6 +477,7 @@ void RichDeleteMessageBox::onDelete() {
if (HistoryItem *item = App::histItemById(_channel ? peerToChannel(_channel->id) : 0, _msgId)) {
bool wasLast = (item->history()->lastMsg == item);
item->destroy();
if (_msgId > 0) {
App::main()->deleteMessages(_channel, QVector<MTPint>(1, MTP_int(_msgId)));
} else if (wasLast) {

View file

@ -31,6 +31,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "ui/filedialog.h"
#include "boxes/photocropbox.h"
#include "boxes/confirmbox.h"
#include "observer_peer.h"
#include "apiwrap.h"
QString cantInviteError() {
@ -740,7 +741,7 @@ int32 ContactsInner::selectedCount() const {
if (_chat) {
result += qMax(_chat->count, 1);
} else if (_channel) {
result += qMax(_channel->count, _already.size());
result += qMax(_channel->membersCount(), _already.size());
} else if (_creating == CreatingGroupGroup) {
result += 1;
}
@ -1739,7 +1740,7 @@ bool ContactsBox::creationFail(const RPCError &error) {
MembersInner::MembersInner(ChannelData *channel, MembersFilter filter) : TWidget()
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _newItemHeight((channel->amCreator() && (channel->count < (channel->isMegagroup() ? Global::MegagroupSizeMax() : Global::ChatSizeMax()) || (!channel->isMegagroup() && !channel->isPublic()) || filter == MembersFilterAdmins)) ? st::contactsNewItemHeight : 0)
, _newItemHeight((channel->amCreator() && (channel->membersCount() < (channel->isMegagroup() ? Global::MegagroupSizeMax() : Global::ChatSizeMax()) || (!channel->isMegagroup() && !channel->isPublic()) || filter == MembersFilterAdmins)) ? st::contactsNewItemHeight : 0)
, _newItemSel(false)
, _channel(channel)
, _filter(filter)
@ -1808,7 +1809,7 @@ void MembersInner::paintEvent(QPaintEvent *e) {
paintDialog(p, _rows[from], data(from), sel, kickSel, kickDown);
p.translate(0, _rowHeight);
}
if (to == _rows.size() && _filter == MembersFilterRecent && (_rows.size() < _channel->count || _rows.size() >= Global::ChatSizeMax())) {
if (to == _rows.size() && _filter == MembersFilterRecent && (_rows.size() < _channel->membersCount() || _rows.size() >= Global::ChatSizeMax())) {
p.setPen(st::stickersReorderFg);
_about.draw(p, st::contactsPadding.left(), st::stickersReorderPadding.top(), _aboutWidth, style::al_center);
}
@ -1987,7 +1988,7 @@ void MembersInner::refresh() {
} else {
_about.setText(st::boxTextFont, lng_channel_only_last_shown(lt_count, _rows.size()));
_aboutHeight = st::stickersReorderPadding.top() + _about.countHeight(_aboutWidth) + st::stickersReorderPadding.bottom();
if (_filter != MembersFilterRecent || (_rows.size() >= _channel->count && _rows.size() < Global::ChatSizeMax())) {
if (_filter != MembersFilterRecent || (_rows.size() >= _channel->membersCount() && _rows.size() < Global::ChatSizeMax())) {
_aboutHeight = 0;
}
resize(width(), st::membersPadding.top() + _newItemHeight + _rows.size() * _rowHeight + st::membersPadding.bottom() + _aboutHeight);
@ -2115,14 +2116,16 @@ void MembersInner::membersReceived(const MTPchannels_ChannelParticipants &result
_datas.reserve(v.size());
_dates.reserve(v.size());
_roles.reserve(v.size());
if (_filter == MembersFilterRecent && _channel->count < d.vcount.v) {
_channel->count = d.vcount.v;
if (_filter == MembersFilterRecent && _channel->membersCount() < d.vcount.v) {
_channel->setMembersCount(d.vcount.v);
if (App::main()) emit App::main()->peerUpdated(_channel);
} else if (_filter == MembersFilterAdmins && _channel->adminsCount < d.vcount.v) {
_channel->adminsCount = d.vcount.v;
} else if (_filter == MembersFilterAdmins && _channel->adminsCount() < d.vcount.v) {
_channel->setAdminsCount(d.vcount.v);
if (App::main()) emit App::main()->peerUpdated(_channel);
}
App::feedUsers(d.vusers);
App::feedUsersDelayed(d.vusers);
for (QVector<MTPChannelParticipant>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
int32 userId = 0, addedTime = 0;
MemberRole role = MemberRoleNone;
@ -2229,11 +2232,11 @@ void MembersInner::removeKicked() {
_dates.removeAt(index);
_roles.removeAt(index);
clearSel();
if (_filter == MembersFilterRecent && _channel->count > 1) {
--_channel->count;
if (_filter == MembersFilterRecent && _channel->membersCount() > 1) {
_channel->setMembersCount(_channel->membersCount() - 1);
if (App::main()) emit App::main()->peerUpdated(_channel);
} else if (_filter == MembersFilterAdmins && _channel->adminsCount > 1) {
--_channel->adminsCount;
} else if (_filter == MembersFilterAdmins && _channel->adminsCount() > 1) {
_channel->setAdminsCount(_channel->adminsCount() - 1);
if (App::main()) emit App::main()->peerUpdated(_channel);
}
refresh();
@ -2290,7 +2293,7 @@ void MembersBox::onScroll() {
}
void MembersBox::onAdd() {
if (_inner.filter() == MembersFilterRecent && _inner.channel()->count >= (_inner.channel()->isMegagroup() ? Global::MegagroupSizeMax() : Global::ChatSizeMax())) {
if (_inner.filter() == MembersFilterRecent && _inner.channel()->membersCount() >= (_inner.channel()->isMegagroup() ? Global::MegagroupSizeMax() : Global::ChatSizeMax())) {
Ui::showLayer(new MaxInviteBox(_inner.channel()->inviteLink()), KeepOtherLayers);
return;
}

View file

@ -524,6 +524,7 @@ struct Data {
SingleDelayedCall HandleHistoryUpdate = { App::app(), "call_handleHistoryUpdate" };
SingleDelayedCall HandleUnreadCounterUpdate = { App::app(), "call_handleUnreadCounterUpdate" };
SingleDelayedCall HandleFileDialogQueue = { App::app(), "call_handleFileDialogQueue" };
SingleDelayedCall HandleDelayedPeerUpdates = { App::app(), "call_handleDelayedPeerUpdates" };
Adaptive::Layout AdaptiveLayout = Adaptive::NormalLayout;
bool AdaptiveForWide = true;
@ -588,6 +589,7 @@ DefineReadOnlyVar(Global, uint64, LaunchId);
DefineRefVar(Global, SingleDelayedCall, HandleHistoryUpdate);
DefineRefVar(Global, SingleDelayedCall, HandleUnreadCounterUpdate);
DefineRefVar(Global, SingleDelayedCall, HandleFileDialogQueue);
DefineRefVar(Global, SingleDelayedCall, HandleDelayedPeerUpdates);
DefineVar(Global, Adaptive::Layout, AdaptiveLayout);
DefineVar(Global, bool, AdaptiveForWide);

View file

@ -205,6 +205,7 @@ DeclareReadOnlyVar(uint64, LaunchId);
DeclareRefVar(SingleDelayedCall, HandleHistoryUpdate);
DeclareRefVar(SingleDelayedCall, HandleUnreadCounterUpdate);
DeclareRefVar(SingleDelayedCall, HandleFileDialogQueue);
DeclareRefVar(SingleDelayedCall, HandleDelayedPeerUpdates);
DeclareVar(Adaptive::Layout, AdaptiveLayout);
DeclareVar(bool, AdaptiveForWide);

View file

@ -1098,26 +1098,29 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
if (App::main()) App::main()->updateBotKeyboard(this);
}
if (peer->isMegagroup()) {
if (UserData *user = App::userLoaded(uid)) {
int32 index = peer->asChannel()->mgInfo->lastParticipants.indexOf(user);
if (auto user = App::userLoaded(uid)) {
auto channel = peer->asChannel();
auto megagroupInfo = channel->mgInfo;
int32 index = megagroupInfo->lastParticipants.indexOf(user);
if (index >= 0) {
peer->asChannel()->mgInfo->lastParticipants.removeAt(index);
megagroupInfo->lastParticipants.removeAt(index);
}
if (peer->asChannel()->count > 1) {
--peer->asChannel()->count;
if (peer->asChannel()->membersCount() > 1) {
peer->asChannel()->setMembersCount(channel->membersCount() - 1);
} else {
peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
peer->asChannel()->mgInfo->lastParticipantsCount = 0;
megagroupInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
megagroupInfo->lastParticipantsCount = 0;
}
if (peer->asChannel()->mgInfo->lastAdmins.contains(user)) {
peer->asChannel()->mgInfo->lastAdmins.remove(user);
if (peer->asChannel()->adminsCount > 1) {
--peer->asChannel()->adminsCount;
if (megagroupInfo->lastAdmins.contains(user)) {
megagroupInfo->lastAdmins.remove(user);
if (channel->adminsCount() > 1) {
channel->setAdminsCount(channel->adminsCount() - 1);
}
}
peer->asChannel()->mgInfo->bots.remove(user);
if (peer->asChannel()->mgInfo->bots.isEmpty() && peer->asChannel()->mgInfo->botStatus > 0) {
peer->asChannel()->mgInfo->botStatus = -1;
megagroupInfo->bots.remove(user);
if (megagroupInfo->bots.isEmpty() && megagroupInfo->botStatus > 0) {
megagroupInfo->botStatus = -1;
}
}
}
@ -2059,6 +2062,7 @@ void History::getReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScro
if (History *h = App::historyLoaded(peer->migrateFrom()->id)) {
if (h->unreadCount()) {
clear(true);
h->getReadyFor(msgId, fixInScrollMsgId, fixInScrollMsgTop);
return;
}
@ -2066,6 +2070,7 @@ void History::getReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScro
}
if (!isReadyFor(msgId, fixInScrollMsgId, fixInScrollMsgTop)) {
clear(true);
if (msgId == ShowAtTheEndMsgId) {
newLoaded = true;
}

View file

@ -4485,6 +4485,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
} else if (_migrated) {
_migrated->clear(true);
}
addMessagesToFront(peer, *histList, histCollapsed);
if (_fixedInScrollMsgId && _history->isChannel()) {
_history->asChannelHistory()->insertCollapseItem(_fixedInScrollMsgId);
@ -4507,6 +4508,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
} else if (_migrated) {
_migrated->clear(true);
}
_delayedShowAtRequest = 0;
bool wasOnlyImportant = _history->isChannel() ? _history->asChannelHistory()->onlyImportant() : true;
_history->getReadyFor(_delayedShowAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
@ -5094,6 +5096,8 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
App::main()->finishForwarding(h, _broadcast.checked(), _silent.checked());
cancelReply(lastKeyboardUsed);
Notify::peerUpdatedSendDelayed();
}
void HistoryWidget::onSendPaths(const PeerId &peer) {
@ -5999,8 +6003,8 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) {
}
}
} else if (_peer->isChannel()) {
if (_peer->isMegagroup() && _peer->asChannel()->count > 0 && _peer->asChannel()->count <= Global::ChatSizeMax()) {
if (_peer->asChannel()->mgInfo->lastParticipants.size() < _peer->asChannel()->count || _peer->asChannel()->lastParticipantsCountOutdated()) {
if (_peer->isMegagroup() && _peer->asChannel()->membersCount() > 0 && _peer->asChannel()->membersCount() <= Global::ChatSizeMax()) {
if (_peer->asChannel()->mgInfo->lastParticipants.size() < _peer->asChannel()->membersCount() || _peer->asChannel()->lastParticipantsCountOutdated()) {
if (App::api()) App::api()->requestLastParticipants(_peer->asChannel());
}
int32 onlineCount = 0;
@ -6012,12 +6016,12 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) {
}
}
if (onlineCount && !onlyMe) {
text = lng_chat_status_members_online(lt_count, _peer->asChannel()->count, lt_count_online, onlineCount);
text = lng_chat_status_members_online(lt_count, _peer->asChannel()->membersCount(), lt_count_online, onlineCount);
} else {
text = lng_chat_status_members(lt_count, _peer->asChannel()->count);
text = lng_chat_status_members(lt_count, _peer->asChannel()->membersCount());
}
} else {
text = _peer->asChannel()->count ? lng_chat_status_members(lt_count, _peer->asChannel()->count) : lang(_peer->isMegagroup() ? lng_group_status : lng_channel_status);
text = _peer->asChannel()->membersCount() ? lng_chat_status_members(lt_count, _peer->asChannel()->membersCount()) : lang(_peer->isMegagroup() ? lng_group_status : lng_channel_status);
}
}
if (_titlePeerText != text) {
@ -6286,6 +6290,8 @@ void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShif
}
App::main()->dialogsToUp();
peerMessagesUpdated(file->to.peer);
Notify::peerUpdatedSendDelayed();
}
void HistoryWidget::cancelSendFile(const FileLoadResultPtr &file) {
@ -6920,6 +6926,7 @@ void HistoryWidget::addMessagesToFront(PeerData *peer, const QVector<MTPMessage>
}
updateBotKeyboard();
}
Notify::peerUpdatedSendDelayed();
}
void HistoryWidget::addMessagesToBack(PeerData *peer, const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed) {
@ -6927,6 +6934,7 @@ void HistoryWidget::addMessagesToBack(PeerData *peer, const QVector<MTPMessage>
if (!_firstLoadRequest) {
updateListSize(false, true, { ScrollChangeNoJumpToBottom, 0 });
}
Notify::peerUpdatedSendDelayed();
}
void HistoryWidget::countHistoryShowFrom() {
@ -7174,6 +7182,8 @@ void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot
App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked());
cancelReply(lastKeyboardUsed);
Notify::peerUpdatedSendDelayed();
App::historyRegRandom(randomId, newId);
clearFieldText();
@ -7943,6 +7953,7 @@ void HistoryWidget::onDeleteSelected() {
}
void HistoryWidget::onDeleteSelectedSure() {
Ui::hideLayer();
if (!_list) return;
SelectedItemSet sel;
@ -7960,7 +7971,7 @@ void HistoryWidget::onDeleteSelectedSure() {
for (SelectedItemSet::const_iterator i = sel.cbegin(), e = sel.cend(); i != e; ++i) {
i.value()->destroy();
}
Ui::hideLayer();
Notify::peerUpdatedSendDelayed();
for (QMap<PeerData*, QVector<MTPint> >::const_iterator i = ids.cbegin(), e = ids.cend(); i != e; ++i) {
App::main()->deleteMessages(i.key(), i.value());
@ -7968,6 +7979,8 @@ void HistoryWidget::onDeleteSelectedSure() {
}
void HistoryWidget::onDeleteContextSure() {
Ui::hideLayer();
HistoryItem *item = App::contextItem();
if (!item || item->type() != HistoryItemMsg) {
return;
@ -7977,12 +7990,12 @@ void HistoryWidget::onDeleteContextSure() {
History *h = item->history();
bool wasOnServer = (item->id > 0), wasLast = (h->lastMsg == item);
item->destroy();
Notify::peerUpdatedSendDelayed();
if (!wasOnServer && wasLast && !h->lastMsg) {
App::main()->checkPeerHistory(h->peer);
}
Ui::hideLayer();
if (wasOnServer) {
App::main()->deleteMessages(h->peer, toDelete);
}

View file

@ -764,6 +764,7 @@ void MainWidget::deleteConversation(PeerData *peer, bool deleteHistory) {
if (deleteHistory) {
MTP::send(MTPmessages_DeleteHistory(peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, peer));
}
Notify::peerUpdatedSendDelayed();
}
void MainWidget::deleteAndExit(ChatData *chat) {
@ -788,6 +789,7 @@ void MainWidget::deleteAllFromUser(ChannelData *channel, UserData *from) {
item->destroy();
}
}
Notify::peerUpdatedSendDelayed();
}
MTP::send(MTPchannels_DeleteUserHistory(channel->inputChannel, from->inputUser), rpcDone(&MainWidget::deleteAllFromUserPart, { channel, from }));
}
@ -820,6 +822,7 @@ void MainWidget::clearHistory(PeerData *peer) {
}
Ui::showPeerHistory(peer->id, ShowAtUnreadMsgId);
MTP::send(MTPmessages_DeleteHistory(peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, peer));
Notify::peerUpdatedSendDelayed();
}
void MainWidget::addParticipants(PeerData *chatOrChannel, const QVector<UserData*> &users) {
@ -976,6 +979,7 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu
}
}
}
Notify::peerUpdatedSendDelayed();
}
bool MainWidget::sendMessageFail(const RPCError &error) {
@ -1240,7 +1244,7 @@ bool MainWidget::preloadOverview(PeerData *peer, MediaOverviewType type) {
if (type == OverviewCount) return false;
History *h = App::history(peer->id);
if (h->overviewCountLoaded(type) || _overviewPreload[type].constFind(peer) != _overviewPreload[type].cend()) {
if (h->overviewCountLoaded(type) || _overviewPreload[type].contains(peer)) {
return false;
}
@ -1280,11 +1284,11 @@ void MainWidget::overviewPreloaded(PeerData *peer, const MTPmessages_Messages &r
App::history(peer->id)->overviewSliceDone(type, result, true);
mediaOverviewUpdated(peer, type);
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, type);
Notify::peerUpdatedSendDelayed();
}
void MainWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
// if (_profile) _profile->mediaOverviewUpdated(peer, type); TODO
if (!_player->isHidden()) _player->mediaOverviewUpdated(peer, type);
if (_overview && (_overview->peer() == peer || _overview->peer()->migrateFrom() == peer)) {
_overview->mediaOverviewUpdated(peer, type);
@ -1419,6 +1423,7 @@ void MainWidget::overviewLoaded(History *history, const MTPmessages_Messages &re
history->overviewSliceDone(type, result);
if (App::wnd()) App::wnd()->mediaOverviewUpdated(history->peer, type);
Notify::peerUpdatedSendDelayed();
}
void MainWidget::sendReadRequest(PeerData *peer, MsgId upTo) {
@ -4451,7 +4456,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
// Request last active supergroup participants if the 'from' user was not loaded yet.
// This will optimize similar getDifference() calls for almost all next messages.
if (isDataLoaded == DataIsLoadedResult::FromNotLoaded && channel && channel->isMegagroup() && App::api()) {
if (channel->mgInfo->lastParticipants.size() < Global::ChatSizeMax() && (channel->mgInfo->lastParticipants.isEmpty() || channel->mgInfo->lastParticipants.size() < channel->count)) {
if (channel->mgInfo->lastParticipants.size() < Global::ChatSizeMax() && (channel->mgInfo->lastParticipants.isEmpty() || channel->mgInfo->lastParticipants.size() < channel->membersCount())) {
App::api()->requestLastParticipants(channel);
}
}

View file

@ -35,6 +35,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "boxes/confirmbox.h"
#include "boxes/contactsbox.h"
#include "boxes/addcontactbox.h"
#include "observer_peer.h"
#include "autoupdater.h"
#include "mediaview.h"
#include "localstorage.h"
@ -1880,8 +1881,15 @@ void MainWindow::sendPaths() {
void MainWindow::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
if (main) main->mediaOverviewUpdated(peer, type);
if (!_mediaView || _mediaView->isHidden()) return;
_mediaView->mediaOverviewUpdated(peer, type);
if (_mediaView && !_mediaView->isHidden()) {
_mediaView->mediaOverviewUpdated(peer, type);
}
if (type != OverviewCount) {
Notify::PeerUpdate update(peer);
update.flags |= Notify::PeerUpdate::Flag::SharedMediaChanged;
update.mediaTypesMask |= (1 << type);
Notify::peerUpdatedDelayed(update);
}
}
void MainWindow::documentUpdated(DocumentData *doc) {

View file

@ -65,12 +65,17 @@ void mergePeerUpdate(PeerUpdate &mergeTo, const PeerUpdate &mergeFrom) {
mergeTo.oldNameFirstChars = mergeFrom.oldNameFirstChars;
}
}
if (mergeFrom.flags & PeerUpdate::Flag::SharedMediaChanged) {
mergeTo.mediaTypesMask |= mergeFrom.mediaTypesMask;
}
mergeTo.flags |= mergeFrom.flags;
}
void peerUpdatedDelayed(const PeerUpdate &update) {
t_assert(creator.started());
Global::RefHandleDelayedPeerUpdates().call();
int existingUpdatesCount = SmallUpdates->size();
for (int i = 0; i < existingUpdatesCount; ++i) {
auto &existingUpdate = (*SmallUpdates)[i];
@ -96,9 +101,9 @@ void peerUpdatedDelayed(const PeerUpdate &update) {
}
void peerUpdatedSendDelayed() {
App::emitPeerUpdated();
if (!creator.started()) return;
t_assert(creator.started());
App::emitPeerUpdated();
if (SmallUpdates->isEmpty()) return;

View file

@ -34,25 +34,32 @@ struct PeerUpdate {
PeerData *peer;
enum class Flag {
NameChanged = 0x00000001U,
UsernameChanged = 0x00000002U,
PhotoChanged = 0x00000004U,
AboutChanged = 0x00000008U,
NotificationsEnabled = 0x00000010U,
InviteLinkChanged = 0x00000020U,
NameChanged = 0x00000001U,
UsernameChanged = 0x00000002U,
PhotoChanged = 0x00000004U,
AboutChanged = 0x00000008U,
NotificationsEnabled = 0x00000010U,
SharedMediaChanged = 0x00000020U,
UserCanShareContact = 0x00010000U,
UserIsContact = 0x00020000U,
UserPhoneChanged = 0x00040000U,
UserIsBlocked = 0x00080000U,
BotCommandsChanged = 0x00100000U,
// For chats and channels
InviteLinkChanged = 0x00000020U,
MembersChanged = 0x00000040U,
AdminsChanged = 0x00000080U,
ChatCanEdit = 0x00010000U,
UserCanShareContact = 0x00010000U,
UserIsContact = 0x00020000U,
UserPhoneChanged = 0x00040000U,
UserIsBlocked = 0x00080000U,
BotCommandsChanged = 0x00100000U,
ChannelAmIn = 0x00010000U,
ChannelAmEditor = 0x00020000U,
ChannelCanEditPhoto = 0x00040000U,
ChannelCanAddMembers = 0x00080000U,
ChatCanEdit = 0x00010000U,
ChannelAmIn = 0x00010000U,
ChannelAmEditor = 0x00020000U,
ChannelCanEditPhoto = 0x00040000U,
ChannelCanAddMembers = 0x00080000U,
ChannelCanViewAdmins = 0x00100000U,
ChannelCanViewMembers = 0x00200000U,
};
Q_DECLARE_FLAGS(Flags, Flag);
Flags flags = 0;
@ -60,6 +67,10 @@ struct PeerUpdate {
// NameChanged data
PeerData::Names oldNames;
PeerData::NameFirstChars oldNameFirstChars;
// SharedMediaChanged data
int32 mediaTypesMask = 0;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(PeerUpdate::Flags);

View file

@ -2336,6 +2336,8 @@ void OverviewWidget::onDeleteSelected() {
}
void OverviewWidget::onDeleteSelectedSure() {
Ui::hideLayer();
SelectedItemSet sel;
_inner.fillSelectedItems(sel);
if (sel.isEmpty()) return;
@ -2351,7 +2353,6 @@ void OverviewWidget::onDeleteSelectedSure() {
for (SelectedItemSet::const_iterator i = sel.cbegin(), e = sel.cend(); i != e; ++i) {
i.value()->destroy();
}
Ui::hideLayer();
for (QMap<PeerData*, QVector<MTPint> >::const_iterator i = ids.cbegin(), e = ids.cend(); i != e; ++i) {
App::main()->deleteMessages(i.key(), i.value());
@ -2359,6 +2360,8 @@ void OverviewWidget::onDeleteSelectedSure() {
}
void OverviewWidget::onDeleteContextSure() {
Ui::hideLayer();
HistoryItem *item = App::contextItem();
if (!item || item->type() != HistoryItemMsg) {
return;
@ -2368,12 +2371,11 @@ void OverviewWidget::onDeleteContextSure() {
History *h = item->history();
bool wasOnServer = (item->id > 0), wasLast = (h->lastMsg == item);
item->destroy();
if (!wasOnServer && wasLast && !h->lastMsg) {
App::main()->checkPeerHistory(h->peer);
}
Ui::hideLayer();
if (wasOnServer) {
App::main()->deleteMessages(h->peer, toDelete);
}

View file

@ -34,7 +34,10 @@ namespace Profile {
using UpdateFlag = Notify::PeerUpdate::Flag;
ActionsWidget::ActionsWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_actions_section)) {
auto observeEvents = UpdateFlag::ChannelAmIn | UpdateFlag::UserIsBlocked | UpdateFlag::BotCommandsChanged;
auto observeEvents = UpdateFlag::ChannelAmIn
| UpdateFlag::UserIsBlocked
| UpdateFlag::BotCommandsChanged
| UpdateFlag::MembersChanged;
Notify::registerPeerObserver(observeEvents, this, &ActionsWidget::notifyPeerUpdated);
validateBlockStatus();
@ -57,6 +60,9 @@ void ActionsWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
if (needFullRefresh()) {
refreshButtons();
} else {
if (update.flags & UpdateFlag::MembersChanged) {
refreshDeleteChannel();
}
if (update.flags & UpdateFlag::ChannelAmIn) {
refreshLeaveChannel();
}
@ -99,11 +105,11 @@ Ui::LeftOutlineButton *ActionsWidget::addButton(const QString &text, const char
};
void ActionsWidget::resizeButton(Ui::LeftOutlineButton *button, int top) {
int left = st::profileBlockTitlePosition.x();
int availableWidth = width() - left + st::defaultLeftOutlineButton.padding.left() - st::profileBlockMarginRight;
int left = defaultOutlineButtonLeft();
int availableWidth = width() - left - st::profileBlockMarginRight;
accumulate_min(availableWidth, st::profileBlockOneLineWidthMax);
button->resizeToWidth(availableWidth);
button->moveToLeft(left - st::defaultLeftOutlineButton.padding.left(), top);
button->moveToLeft(left, top);
}
void ActionsWidget::refreshButtons() {
@ -131,9 +137,7 @@ void ActionsWidget::refreshButtons() {
addButton(lang(lng_profile_clear_and_exit), SLOT(onDeleteConversation()));
} else if (auto channel = peer()->asChannel()) {
// addButton(lang(lng_profile_report), SLOT(onReport()));
if (channel->amCreator()) {
addButton(lang(channel->isMegagroup() ? lng_profile_delete_group : lng_profile_delete_channel), SLOT(onDeleteChannel()), st::attentionLeftOutlineButton);
}
refreshDeleteChannel();
refreshLeaveChannel();
}
@ -208,6 +212,18 @@ void ActionsWidget::refreshBlockUser() {
}
}
void ActionsWidget::refreshDeleteChannel() {
if (auto channel = peer()->asChannel()) {
if (channel->canDelete() && !_deleteChannel) {
_deleteChannel = addButton(lang(channel->isMegagroup() ? lng_profile_delete_group : lng_profile_delete_channel), SLOT(onDeleteChannel()), st::attentionLeftOutlineButton);
} else if (!channel->canDelete() && _deleteChannel) {
_buttons.removeOne(_deleteChannel);
delete _deleteChannel;
_deleteChannel = nullptr;
}
}
}
void ActionsWidget::refreshLeaveChannel() {
if (auto channel = peer()->asChannel()) {
if (!channel->amCreator()) {

View file

@ -21,7 +21,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#pragma once
#include "profile/profile_block_widget.h"
#include "core/observer.h"
namespace Ui {
class LeftOutlineButton;
@ -33,7 +32,7 @@ struct PeerUpdate;
namespace Profile {
class ActionsWidget : public BlockWidget, public Notify::Observer {
class ActionsWidget : public BlockWidget {
Q_OBJECT
public:
@ -67,6 +66,7 @@ private:
void refreshButtons();
void refreshBlockUser();
void refreshDeleteChannel();
void refreshLeaveChannel();
void refreshVisibility();
@ -93,6 +93,7 @@ private:
bool _hasBotHelp = false;
bool _hasBotSettings = false;
Ui::LeftOutlineButton *_blockUser = nullptr;
Ui::LeftOutlineButton *_deleteChannel = nullptr;
Ui::LeftOutlineButton *_leaveChannel = nullptr;
};

View file

@ -50,4 +50,8 @@ void BlockWidget::paintEvent(QPaintEvent *e) {
paintContents(p);
}
int defaultOutlineButtonLeft() {
return st::profileBlockTitlePosition.x() - st::defaultLeftOutlineButton.padding.left();
}
} // namespace Profile

View file

@ -20,9 +20,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "core/observer.h"
namespace Profile {
class BlockWidget : public TWidget {
class BlockWidget : public TWidget, public Notify::Observer {
Q_OBJECT
public:
@ -64,4 +66,6 @@ private:
};
int defaultOutlineButtonLeft();
} // namespace Profile

View file

@ -363,10 +363,10 @@ void CoverWidget::refreshStatusText() {
for_const (auto user, _peerMegagroup->mgInfo->lastParticipants) {
counter.feedUser(user);
}
_statusText = counter.result(_peerMegagroup->count);
_statusText = counter.result(_peerMegagroup->membersCount());
} else if (_peerChannel) {
if (_peerChannel->count > 0) {
_statusText = lng_chat_status_members(lt_count, _peerChannel->count);
if (_peerChannel->membersCount() > 0) {
_statusText = lng_chat_status_members(lt_count, _peerChannel->membersCount());
} else {
_statusText = lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
}
@ -381,7 +381,7 @@ bool CoverWidget::isUsingMegagroupOnlineCount() const {
return false;
}
if (_peerMegagroup->count <= 0 || _peerMegagroup->count > Global::ChatSizeMax()) {
if (_peerMegagroup->membersCount() <= 0 || _peerMegagroup->membersCount() > Global::ChatSizeMax()) {
return false;
}
@ -425,7 +425,7 @@ void CoverWidget::setMegagroupButtons() {
if (_peerMegagroup->canEditPhoto()) {
addButton(lang(lng_profile_set_group_photo), SLOT(onSetPhoto()));
}
if (_peerMegagroup->canAddParticipants()) {
if (_peerMegagroup->canAddMembers()) {
addButton(lang(lng_profile_add_participant), SLOT(onAddMember()), &st::profileAddMemberButton);
}
}

View file

@ -21,7 +21,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#pragma once
#include "profile/profile_block_widget.h"
#include "core/observer.h"
class FlatLabel;
@ -31,7 +30,7 @@ struct PeerUpdate;
namespace Profile {
class InfoWidget : public BlockWidget, public Notify::Observer {
class InfoWidget : public BlockWidget {
public:
InfoWidget(QWidget *parent, PeerData *peer);

View file

@ -54,10 +54,10 @@ void InnerWidget::createBlocks() {
_blocks.push_back({ new InviteLinkWidget(this, _peer), BlockSide::Right });
}
_blocks.push_back({ new SharedMediaWidget(this, _peer), BlockSide::Right });
_blocks.push_back({ new ActionsWidget(this, _peer), BlockSide::Right });
if (channel && !megagroup) {
_blocks.push_back({ new ChannelMembersWidget(this, _peer), BlockSide::Right });
}
_blocks.push_back({ new ActionsWidget(this, _peer), BlockSide::Right });
if (chat || megagroup) {
_blocks.push_back({ new MembersWidget(this, _peer), BlockSide::Left });
}
@ -82,7 +82,7 @@ void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
}
//loadProfilePhotos(_visibleTop);
if (peer()->isMegagroup() && !peer()->asChannel()->mgInfo->lastParticipants.isEmpty() && peer()->asChannel()->mgInfo->lastParticipants.size() < peer()->asChannel()->count) {
if (peer()->isMegagroup() && !peer()->asChannel()->mgInfo->lastParticipants.isEmpty() && peer()->asChannel()->mgInfo->lastParticipants.size() < peer()->asChannel()->membersCount()) {
if (_visibleTop + (PreloadHeightsCount + 1) * (_visibleBottom - _visibleTop) > height()) {
App::api()->requestLastParticipants(peer()->asChannel(), false);
}

View file

@ -21,7 +21,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#pragma once
#include "profile/profile_block_widget.h"
#include "core/observer.h"
class FlatLabel;
@ -31,7 +30,7 @@ struct PeerUpdate;
namespace Profile {
class InviteLinkWidget : public BlockWidget, public Notify::Observer {
class InviteLinkWidget : public BlockWidget {
public:
InviteLinkWidget(QWidget *parent, PeerData *peer);

View file

@ -22,10 +22,15 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "profile/profile_members_widget.h"
#include "styles/style_profile.h"
#include "ui/buttons/left_outline_button.h"
#include "boxes/contactsbox.h"
#include "observer_peer.h"
#include "lang.h"
namespace Profile {
using UpdateFlag = Notify::PeerUpdate::Flag;
MembersWidget::MembersWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_participants_section))
{
show();
@ -37,15 +42,113 @@ int MembersWidget::resizeGetHeight(int newWidth) {
return newHeight;
}
ChannelMembersWidget::ChannelMembersWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_participants_section))
{
show();
ChannelMembersWidget::ChannelMembersWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_participants_section)) {
auto observeEvents = UpdateFlag::ChannelCanViewAdmins
| UpdateFlag::ChannelCanViewMembers
| UpdateFlag::AdminsChanged
| UpdateFlag::MembersChanged;
Notify::registerPeerObserver(observeEvents, this, &ChannelMembersWidget::notifyPeerUpdated);
refreshButtons();
}
void ChannelMembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
if (update.peer != peer()) {
return;
}
if (update.flags & (UpdateFlag::ChannelCanViewAdmins | UpdateFlag::AdminsChanged)) {
refreshAdmins();
}
if (update.flags & (UpdateFlag::ChannelCanViewMembers | UpdateFlag::MembersChanged)) {
refreshMembers();
}
refreshVisibility();
contentSizeUpdated();
}
void ChannelMembersWidget::addButton(const QString &text, ChildWidget<Ui::LeftOutlineButton> *button, const char *slot) {
if (text.isEmpty()) {
button->destroy();
} else if (*button) {
(*button)->setText(text);
} else {
(*button) = new Ui::LeftOutlineButton(this, text);
(*button)->show();
connect(*button, SIGNAL(clicked()), this, slot);
}
}
void ChannelMembersWidget::refreshButtons() {
refreshAdmins();
refreshMembers();
refreshVisibility();
}
void ChannelMembersWidget::refreshAdmins() {
auto getAdminsText = [this]() -> QString {
if (auto channel = peer()->asChannel()) {
if (!channel->isMegagroup() && channel->canViewAdmins()) {
int adminsCount = qMax(channel->adminsCount(), 1);
return lng_channel_admins_link(lt_count, adminsCount);
}
}
return QString();
};
addButton(getAdminsText(), &_admins, SLOT(onAdmins()));
}
void ChannelMembersWidget::refreshMembers() {
auto getMembersText = [this]() -> QString {
if (auto channel = peer()->asChannel()) {
if (!channel->isMegagroup() && channel->canViewMembers()) {
int membersCount = qMax(channel->membersCount(), 1);
return lng_channel_members_link(lt_count, membersCount);
}
}
return QString();
};
addButton(getMembersText(), &_members, SLOT(onMembers()));
}
void ChannelMembersWidget::refreshVisibility() {
setVisible(_admins || _members);
}
int ChannelMembersWidget::resizeGetHeight(int newWidth) {
int newHeight = contentTop();
auto resizeButton = [this, &newHeight, newWidth](ChildWidget<Ui::LeftOutlineButton> &button) {
if (!button) {
return;
}
int left = defaultOutlineButtonLeft();
int availableWidth = newWidth - left - st::profileBlockMarginRight;
accumulate_min(availableWidth, st::profileBlockOneLineWidthMax);
button->resizeToWidth(availableWidth);
button->moveToLeft(left, newHeight);
newHeight += button->height();
};
resizeButton(_admins);
resizeButton(_members);
return newHeight;
}
void ChannelMembersWidget::onAdmins() {
if (auto channel = peer()->asChannel()) {
Ui::showLayer(new MembersBox(channel, MembersFilterAdmins));
}
}
void ChannelMembersWidget::onMembers() {
if (auto channel = peer()->asChannel()) {
Ui::showLayer(new MembersBox(channel, MembersFilterRecent));
}
}
} // namespace Profile

View file

@ -22,6 +22,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "profile/profile_block_widget.h"
namespace Ui {
class LeftOutlineButton;
} // namespace Ui
namespace Notify {
struct PeerUpdate;
} // namespace Notify
namespace Profile {
class MembersWidget : public BlockWidget {
@ -35,6 +43,8 @@ protected:
};
class ChannelMembersWidget : public BlockWidget {
Q_OBJECT
public:
ChannelMembersWidget(QWidget *parent, PeerData *peer);
@ -42,6 +52,24 @@ protected:
// Resizes content and counts natural widget height for the desired width.
int resizeGetHeight(int newWidth) override;
private slots:
void onAdmins();
void onMembers();
private:
// Observed notifications.
void notifyPeerUpdated(const Notify::PeerUpdate &update);
void refreshButtons();
void refreshAdmins();
void refreshMembers();
void refreshVisibility();
void addButton(const QString &text, ChildWidget<Ui::LeftOutlineButton> *button, const char *slot);
ChildWidget<Ui::LeftOutlineButton> _admins = { nullptr };
ChildWidget<Ui::LeftOutlineButton> _members = { nullptr };
};
} // namespace Profile

View file

@ -80,18 +80,17 @@ void SettingsWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
int SettingsWidget::resizeGetHeight(int newWidth) {
int newHeight = contentTop();
int left = st::profileBlockTitlePosition.x();
_enableNotifications->moveToLeft(left, newHeight);
_enableNotifications->moveToLeft(st::profileBlockTitlePosition.x(), newHeight);
newHeight += _enableNotifications->height() + st::profileBlockOneLineSkip;
auto moveLink = [&newHeight, left, newWidth](Ui::LeftOutlineButton *button) {
auto moveLink = [&newHeight, newWidth](Ui::LeftOutlineButton *button) {
if (!button) return;
int availableWidth = newWidth - left + st::defaultLeftOutlineButton.padding.left() - st::profileBlockMarginRight;
int left = defaultOutlineButtonLeft();
int availableWidth = newWidth - left - st::profileBlockMarginRight;
accumulate_min(availableWidth, st::profileBlockOneLineWidthMax);
button->resizeToWidth(availableWidth);
button->moveToLeft(left - st::defaultLeftOutlineButton.padding.left(), newHeight);
button->moveToLeft(left, newHeight);
newHeight += button->height();
};
moveLink(_manageAdmins);

View file

@ -21,7 +21,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#pragma once
#include "profile/profile_block_widget.h"
#include "core/observer.h"
class Checkbox;
@ -35,7 +34,7 @@ struct PeerUpdate;
namespace Profile {
class SettingsWidget : public BlockWidget, public Notify::Observer {
class SettingsWidget : public BlockWidget {
Q_OBJECT
public:

View file

@ -22,19 +22,132 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "profile/profile_shared_media_widget.h"
#include "styles/style_profile.h"
#include "observer_peer.h"
#include "ui/buttons/left_outline_button.h"
#include "mainwidget.h"
#include "lang.h"
namespace Profile {
namespace {
QString getButtonText(MediaOverviewType type, int count) {
if (count <= 0) {
return QString();
}
switch (type) {
case OverviewPhotos: return lng_profile_photos(lt_count, count);
case OverviewVideos: return lng_profile_videos(lt_count, count);
case OverviewMusicFiles: return lng_profile_songs(lt_count, count);
case OverviewFiles: return lng_profile_files(lt_count, count);
case OverviewVoiceFiles: return lng_profile_audios(lt_count, count);
case OverviewLinks: return lng_profile_shared_links(lt_count, count);
}
return QString();
}
} // namespace
SharedMediaWidget::SharedMediaWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_shared_media))
{
show();
, _history(App::history(peer))
, _migrated(peer->migrateFrom() ? App::history(peer->migrateFrom()) : nullptr) {
Notify::registerPeerObserver(Notify::PeerUpdate::Flag::SharedMediaChanged, this, &SharedMediaWidget::notifyPeerUpdated);
App::main()->preloadOverviews(peer);
if (_migrated) {
App::main()->preloadOverviews(_migrated->peer);
}
refreshButtons();
refreshVisibility();
}
void SharedMediaWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
if (update.peer != peer() && (!_migrated || update.peer != _migrated->peer)) {
return;
}
bool updated = false;
for (int i = 0; i < OverviewCount; ++i) {
if (update.mediaTypesMask & (1 << i)) {
refreshButton(static_cast<MediaOverviewType>(i));
updated = true;
}
}
if (updated) {
refreshVisibility();
contentSizeUpdated();
}
}
int SharedMediaWidget::resizeGetHeight(int newWidth) {
int newHeight = contentTop();
resizeButtons(&newHeight);
return newHeight;
}
void SharedMediaWidget::refreshButtons() {
for (int typeIndex = 0; typeIndex < OverviewCount; ++typeIndex) {
refreshButton(static_cast<MediaOverviewType>(typeIndex));
}
}
void SharedMediaWidget::refreshButton(MediaOverviewType type) {
int count = _history->overviewCount(type), migrated = _migrated ? _migrated->overviewCount(type) : 0;
int finalCount = (count >= 0 && migrated >= 0) ? (count + migrated) : -1;
auto text = getButtonText(type, finalCount);
if (text.isEmpty()) {
if (_mediaButtons[type]) {
delete _mediaButtons[type];
_mediaButtons[type] = nullptr;
}
} else {
if (_mediaButtons[type]) {
_mediaButtons[type]->setText(text);
} else {
_mediaButtons[type] = new Ui::LeftOutlineButton(this, text);
_mediaButtons[type]->show();
connect(_mediaButtons[type], SIGNAL(clicked()), this, SLOT(onMediaChosen()));
}
}
}
void SharedMediaWidget::refreshVisibility() {
for_const (auto button, _mediaButtons) {
if (button) {
show();
return;
}
}
hide();
}
void SharedMediaWidget::onMediaChosen() {
for (int i = 0; i < OverviewCount; ++i) {
auto button = _mediaButtons[i];
if (button && button == sender()) {
App::main()->showMediaOverview(peer(), static_cast<MediaOverviewType>(i));
return;
}
}
}
void SharedMediaWidget::resizeButtons(int *top) {
t_assert(top != nullptr);
int left = defaultOutlineButtonLeft();
int availableWidth = width() - left - st::profileBlockMarginRight;
accumulate_min(availableWidth, st::profileBlockOneLineWidthMax);
for_const (auto button, _mediaButtons) {
if (!button) continue;
button->resizeToWidth(availableWidth);
button->moveToLeft(left, *top);
*top += button->height();
}
}
} // namespace Profile

View file

@ -22,9 +22,19 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "profile/profile_block_widget.h"
namespace Ui {
class LeftOutlineButton;
} // namespace Ui
namespace Notify {
struct PeerUpdate;
} // namespace Notify
namespace Profile {
class SharedMediaWidget : public BlockWidget {
Q_OBJECT
public:
SharedMediaWidget(QWidget *parent, PeerData *peer);
@ -32,6 +42,23 @@ protected:
// Resizes content and counts natural widget height for the desired width.
int resizeGetHeight(int newWidth) override;
private slots:
void onMediaChosen();
private:
// Observed notifications.
void notifyPeerUpdated(const Notify::PeerUpdate &update);
void refreshButtons();
void refreshButton(MediaOverviewType type);
void refreshVisibility();
void resizeButtons(int *top);
Ui::LeftOutlineButton *_mediaButtons[OverviewCount] = { nullptr };
History *_history;
History *_migrated;
};
} // namespace Profile

View file

@ -61,8 +61,8 @@ ProfileInner::ProfileInner(ProfileWidget *profile, PeerData *peer) : TWidget(0)
, _botHelp(this, lang(lng_profile_bot_help))
, _pinnedMessage(this, lang(lng_pinned_message))
, _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.size() + 1) : 0))))
, _members(this, lng_channel_members_link(lt_count, (_peerChannel && _peerChannel->membersCount() > 0) ? _peerChannel->membersCount() : 1))
, _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())
@ -554,9 +554,9 @@ void ProfileInner::onFullPeerUpdated(PeerData *peer) {
_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->adminsCount > 0) ? _peerChannel->adminsCount : 1));
_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
_members.setText(lng_channel_members_link(lt_count, (_peerChannel->membersCount() > 0) ? _peerChannel->membersCount() : 1));
_admins.setText(lng_channel_admins_link(lt_count, (_peerChannel->adminsCount() > 0) ? _peerChannel->adminsCount() : 1));
_onlineText = (_peerChannel->membersCount() > 0) ? lng_chat_status_members(lt_count, _peerChannel->membersCount()) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
if (_peerChannel->about().isEmpty()) {
_about = Text(st::wndMinWidth - st::profilePadding.left() - st::profilePadding.right());
} else {
@ -623,9 +623,9 @@ void ProfileInner::peerUpdated(PeerData *data) {
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->adminsCount > 0) ? _peerChannel->adminsCount : 1));
_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
_members.setText(lng_channel_members_link(lt_count, (_peerChannel->membersCount() > 0) ? _peerChannel->membersCount() : 1));
_admins.setText(lng_channel_admins_link(lt_count, (_peerChannel->adminsCount() > 0) ? _peerChannel->adminsCount() : 1));
_onlineText = (_peerChannel->membersCount() > 0) ? lng_chat_status_members(lt_count, _peerChannel->membersCount()) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
updatePinnedMessageVisibility();
}
if (photo && photo->date) {
@ -719,7 +719,7 @@ void ProfileInner::reorderParticipants() {
loadProfilePhotos(_lastPreload);
} else if (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn() && !_peerChannel->mgInfo->lastParticipants.isEmpty()) {
bool needAdmins = true, adminsOutdated = (_peerChannel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated);
bool orderByOnline = (_peerChannel->count > 0) && (_peerChannel->count <= Global::ChatSizeMax());
bool orderByOnline = (_peerChannel->membersCount() > 0) && (_peerChannel->membersCount() <= Global::ChatSizeMax());
_onlineText.clear();
if (_peerChannel->mgInfo->lastParticipants.isEmpty() || (needAdmins && adminsOutdated) || _peerChannel->lastParticipantsCountOutdated()) {
@ -758,9 +758,9 @@ void ProfileInner::reorderParticipants() {
}
}
if (onlineCount && !onlyMe) {
_onlineText = lng_chat_status_members_online(lt_count, _peerChannel->count, lt_count_online, onlineCount);
_onlineText = lng_chat_status_members_online(lt_count, _peerChannel->membersCount(), lt_count_online, onlineCount);
} else {
_onlineText = lng_chat_status_members(lt_count, _peerChannel->count);
_onlineText = lng_chat_status_members(lt_count, _peerChannel->membersCount());
}
} else {
for (int32 i = 0, l = _participants.size(); i < l; ++i) {
@ -786,7 +786,7 @@ void ProfileInner::reorderParticipants() {
_participantsData.resize(s);
}
if (_onlineText.isEmpty()) {
_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
_onlineText = (_peerChannel->membersCount() > 0) ? lng_chat_status_members(lt_count, _peerChannel->membersCount()) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
}
loadProfilePhotos(_lastPreload);
} else {
@ -794,7 +794,7 @@ void ProfileInner::reorderParticipants() {
if (_peerUser) {
_onlineText = App::onlineText(_peerUser, t, true);
} else if (_peerChannel) {
_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
_onlineText = (_peerChannel->membersCount() > 0) ? lng_chat_status_members(lt_count, _peerChannel->membersCount()) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
} else {
_onlineText = lang(lng_chat_status_unaccessible);
}
@ -867,7 +867,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
} else if (_peerChannel && (_peerChannel->isPublic() || _peerChannel->canEditUsername())) {
// addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
}
if (!_peerChannel || !_peerChannel->canViewParticipants() || _peerChannel->isMegagroup()) {
if (!_peerChannel || !_peerChannel->canViewMembers() || _peerChannel->isMegagroup()) {
//p.setPen((_peerUser && App::onlineColorUse(_peerUser, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p);
//p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop + st::linkFont->ascent, _onlineText);
}
@ -889,7 +889,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
// top += st::profilePhotoSize;
// top += st::profileButtonTop;
if ((!_peerChat || _peerChat->canEdit()) && (!_peerChannel || _amCreator || (_peerChannel->canAddParticipants() && _peerChannel->isMegagroup()))) {
if ((!_peerChat || _peerChat->canEdit()) && (!_peerChannel || _amCreator || (_peerChannel->canAddMembers() && _peerChannel->isMegagroup()))) {
top += _shareContact.height();
} else {
// top -= st::profileButtonTop;
@ -1371,7 +1371,7 @@ bool ProfileInner::migrateFail(const RPCError &error) {
}
bool ProfileInner::canDeleteChannel() const {
return _peerChannel && _amCreator && (_peerChannel->count <= 1000);
return _peerChannel && _amCreator && (_peerChannel->membersCount() <= 1000);
}
void ProfileInner::resizeEvent(QResizeEvent *e) {
@ -1406,7 +1406,7 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
//top += st::profileButtonTop;
_uploadPhoto.setGeometry(_left, top, btnWidth, _uploadPhoto.height());
if (_peerChannel && _peerChannel->count < Global::MegagroupSizeMax() && _peerChannel->isMegagroup() && !_amCreator && !_peerChannel->amEditor() && _peerChannel->canAddParticipants()) {
if (_peerChannel && _peerChannel->membersCount() < Global::MegagroupSizeMax() && _peerChannel->isMegagroup() && !_amCreator && !_peerChannel->amEditor() && _peerChannel->canAddMembers()) {
_addParticipant.setGeometry(_left, top, btnWidth, _addParticipant.height());
} else {
_addParticipant.setGeometry(_left + _width - btnWidth, top, btnWidth, _addParticipant.height());
@ -1416,7 +1416,7 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
_shareContact.setGeometry(_left + _width - btnWidth, top, btnWidth, _shareContact.height());
_inviteToGroup.setGeometry(_left + _width - btnWidth, top, btnWidth, _inviteToGroup.height());
if ((!_peerChat || _peerChat->canEdit()) && (!_peerChannel || _amCreator || (_peerChannel->canAddParticipants() && _peerChannel->isMegagroup()))) {
if ((!_peerChat || _peerChat->canEdit()) && (!_peerChannel || _amCreator || (_peerChannel->canAddMembers() && _peerChannel->isMegagroup()))) {
top += _shareContact.height();
} else {
//top -= st::profileButtonTop;
@ -1766,7 +1766,7 @@ void ProfileInner::showAll() {
_invitationLink.hide();
}
}
if (_peerChannel->count < Global::MegagroupSizeMax() && _peerChannel->isMegagroup() && _peerChannel->canAddParticipants()) {
if (_peerChannel->membersCount() < Global::MegagroupSizeMax() && _peerChannel->isMegagroup() && _peerChannel->canAddMembers()) {
_addParticipant.show();
} else {
_addParticipant.hide();
@ -1787,7 +1787,7 @@ void ProfileInner::showAll() {
} else {
_admins.hide();
}
if (_peerChannel->canViewParticipants() && !_peerChannel->isMegagroup()) {
if (_peerChannel->canViewMembers() && !_peerChannel->isMegagroup()) {
_members.show();
} else {
_members.hide();
@ -1880,7 +1880,7 @@ void ProfileWidget::onScroll() {
if (!_scroll.isHidden() && _scroll.scrollTop() < _scroll.scrollTopMax()) {
_inner.allowDecreaseHeight(_scroll.scrollTopMax() - _scroll.scrollTop());
}
if (peer()->isMegagroup() && !peer()->asChannel()->mgInfo->lastParticipants.isEmpty() && peer()->asChannel()->mgInfo->lastParticipants.size() < peer()->asChannel()->count) {
if (peer()->isMegagroup() && !peer()->asChannel()->mgInfo->lastParticipants.isEmpty() && peer()->asChannel()->mgInfo->lastParticipants.size() < peer()->asChannel()->membersCount()) {
if (_scroll.scrollTop() + PreloadHeightsCount * _scroll.height() > _scroll.scrollTopMax()) {
App::api()->requestLastParticipants(peer()->asChannel(), false);
}

View file

@ -516,6 +516,24 @@ void ChannelData::setInviteLink(const QString &newInviteLink) {
}
}
void ChannelData::setMembersCount(int newMembersCount) {
if (_membersCount != newMembersCount) {
if (isMegagroup() && !mgInfo->lastParticipants.isEmpty()) {
mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
mgInfo->lastParticipantsCount = membersCount();
}
_membersCount = newMembersCount;
Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::MembersChanged);
}
}
void ChannelData::setAdminsCount(int newAdminsCount) {
if (_adminsCount != newAdminsCount) {
_adminsCount = newAdminsCount;
Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::AdminsChanged);
}
}
void ChannelData::flagsUpdated() {
if (isMegagroup()) {
if (!mgInfo) {

View file

@ -697,8 +697,16 @@ public:
return _about;
}
int count = 1;
int adminsCount = 1;
int membersCount() const {
return _membersCount;
}
void setMembersCount(int newMembersCount);
int adminsCount() const {
return _adminsCount;
}
void setAdminsCount(int newAdminsCount);
int32 date = 0;
int version = 0;
MTPDchannel::Flags flags = { 0 };
@ -708,7 +716,7 @@ public:
if (!mgInfo || !(mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsCountOutdated)) {
return false;
}
if (mgInfo->lastParticipantsCount == count) {
if (mgInfo->lastParticipantsCount == membersCount()) {
mgInfo->lastParticipantsStatus &= ~MegagroupInfo::LastParticipantsCountOutdated;
return false;
}
@ -748,9 +756,12 @@ public:
bool canWrite() const {
return amIn() && (canPublish() || !isBroadcast());
}
bool canViewParticipants() const {
bool canViewMembers() const {
return flagsFull & MTPDchannelFull::Flag::f_can_view_participants;
}
bool canViewAdmins() const {
return (isMegagroup() || amCreator() || amEditor() || amModerator());
}
bool addsSignature() const {
return flags & MTPDchannel::Flag::f_signatures;
}
@ -758,7 +769,7 @@ public:
bool isVerified() const {
return flags & MTPDchannel::Flag::f_verified;
}
bool canAddParticipants() const {
bool canAddMembers() const {
return amCreator() || amEditor() || (flags & MTPDchannel::Flag::f_democracy);
}
bool canEditPhoto() const {
@ -767,6 +778,9 @@ public:
bool canEditUsername() const {
return amCreator() && (flagsFull & MTPDchannelFull::Flag::f_can_set_username);
}
bool canDelete() const {
return amCreator() && (membersCount() <= 1000);
}
// ImagePtr photoFull;
@ -824,6 +838,9 @@ private:
PtsWaiter _ptsWaiter;
uint64 _lastFullUpdate = 0;
int _membersCount = 1;
int _adminsCount = 1;
QString _restrictionReason;
QString _about;

View file

@ -410,10 +410,18 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_profile_members_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_profile_settings_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_profile_shared_media_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_profile_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@ -733,10 +741,18 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Deploy\moc_profile_members_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Deploy\moc_profile_settings_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Deploy\moc_profile_shared_media_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Deploy\moc_profile_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@ -1082,10 +1098,18 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_profile_members_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_profile_settings_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_profile_shared_media_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_profile_widget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@ -1610,7 +1634,20 @@
<ClInclude Include="SourceFiles\profile\profile_cover_drop_area.h" />
<ClInclude Include="SourceFiles\profile\profile_info_widget.h" />
<ClInclude Include="SourceFiles\profile\profile_invite_link_widget.h" />
<ClInclude Include="SourceFiles\profile\profile_members_widget.h" />
<CustomBuild Include="SourceFiles\profile\profile_members_widget.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">Moc%27ing profile_members_widget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_members_widget.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing profile_members_widget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_members_widget.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl_debug\Debug\include"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing profile_members_widget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_members_widget.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
</CustomBuild>
<ClInclude Include="SourceFiles\profile\profile_section_memento.h" />
<CustomBuild Include="SourceFiles\profile\profile_settings_widget.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
@ -1626,7 +1663,20 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_settings_widget.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
</CustomBuild>
<ClInclude Include="SourceFiles\profile\profile_shared_media_widget.h" />
<CustomBuild Include="SourceFiles\profile\profile_shared_media_widget.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">Moc%27ing profile_shared_media_widget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_shared_media_widget.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing profile_shared_media_widget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_shared_media_widget.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl_debug\Debug\include"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing profile_shared_media_widget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_shared_media_widget.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
</CustomBuild>
<ClInclude Include="SourceFiles\profile\profile_userpic_button.h" />
<ClInclude Include="SourceFiles\serialize\serialize_common.h" />
<ClInclude Include="SourceFiles\serialize\serialize_document.h" />

View file

@ -1254,6 +1254,24 @@
<ClCompile Include="GeneratedFiles\Release\moc_profile_actions_widget.cpp">
<Filter>GeneratedFiles\Release</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Deploy\moc_profile_members_widget.cpp">
<Filter>GeneratedFiles\Deploy</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_profile_members_widget.cpp">
<Filter>GeneratedFiles\Debug</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_profile_members_widget.cpp">
<Filter>GeneratedFiles\Release</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Deploy\moc_profile_shared_media_widget.cpp">
<Filter>GeneratedFiles\Deploy</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_profile_shared_media_widget.cpp">
<Filter>GeneratedFiles\Debug</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_profile_shared_media_widget.cpp">
<Filter>GeneratedFiles\Release</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SourceFiles\stdafx.h">
@ -1463,12 +1481,6 @@
<ClInclude Include="SourceFiles\profile\profile_invite_link_widget.h">
<Filter>SourceFiles\profile</Filter>
</ClInclude>
<ClInclude Include="SourceFiles\profile\profile_members_widget.h">
<Filter>SourceFiles\profile</Filter>
</ClInclude>
<ClInclude Include="SourceFiles\profile\profile_shared_media_widget.h">
<Filter>SourceFiles\profile</Filter>
</ClInclude>
<ClInclude Include="SourceFiles\ui\buttons\left_outline_button.h">
<Filter>SourceFiles\ui\buttons</Filter>
</ClInclude>
@ -1741,6 +1753,12 @@
<CustomBuild Include="SourceFiles\profile\profile_actions_widget.h">
<Filter>SourceFiles\profile</Filter>
</CustomBuild>
<CustomBuild Include="SourceFiles\profile\profile_members_widget.h">
<Filter>SourceFiles\profile</Filter>
</CustomBuild>
<CustomBuild Include="SourceFiles\profile\profile_shared_media_widget.h">
<Filter>SourceFiles\profile</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="Resources\langs\lang_it.strings">