mirror of https://github.com/procxx/kepka.git
megagroup members support improved
This commit is contained in:
parent
b630c451f1
commit
fd339e401f
|
@ -286,8 +286,20 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
|||
} else {
|
||||
channel->photoId = 0;
|
||||
}
|
||||
if (channel->mgInfo) {
|
||||
if (f.has_migrated_from_chat_id()) {
|
||||
channel->mgInfo->migrateFrom = App::chat(peerFromChat(f.vmigrated_from_chat_id));
|
||||
channel->mgInfo->migrateFrom->migrateTo = channel;
|
||||
}
|
||||
}
|
||||
channel->about = qs(f.vabout);
|
||||
channel->count = f.has_participants_count() ? f.vparticipants_count.v : 0;
|
||||
int32 newCount = f.has_participants_count() ? f.vparticipants_count.v : 0;
|
||||
if (newCount != channel->count) {
|
||||
channel->count = newCount;
|
||||
if (channel->isMegagroup() && !channel->mgInfo->lastParticipants.isEmpty()) {
|
||||
requestLastParticipants(channel);
|
||||
}
|
||||
}
|
||||
channel->adminsCount = f.has_admins_count() ? f.vadmins_count.v : 0;
|
||||
channel->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString();
|
||||
if (History *h = App::historyLoaded(channel->id)) {
|
||||
|
@ -296,6 +308,9 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
|||
h->inboxReadBefore = f.vread_inbox_max_id.v + 1;
|
||||
h->asChannelHistory()->unreadCountAll = f.vunread_count.v;
|
||||
}
|
||||
if (channel->mgInfo && channel->mgInfo->migrateFrom) {
|
||||
h->asChannelHistory()->removeJoinedMessage();
|
||||
}
|
||||
}
|
||||
channel->fullUpdated();
|
||||
|
||||
|
@ -385,6 +400,13 @@ void ApiWrap::requestPeers(const QList<PeerData*> &peers) {
|
|||
if (!users.isEmpty()) MTP::send(MTPusers_GetUsers(MTP_vector<MTPInputUser>(users)), rpcDone(&ApiWrap::gotUsers));
|
||||
}
|
||||
|
||||
void ApiWrap::requestLastParticipants(ChannelData *peer) {
|
||||
if (!peer || !peer->isMegagroup() || _participantsRequests.contains(peer)) return;
|
||||
mtpRequestId req = MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsRecent(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer));
|
||||
_participantsRequests.insert(peer, req);
|
||||
MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsBots(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer));
|
||||
}
|
||||
|
||||
void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) {
|
||||
_peerRequests.remove(peer);
|
||||
|
||||
|
@ -433,6 +455,64 @@ bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &error) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req) {
|
||||
bool bots = (_participantsRequests.value(peer) != req);
|
||||
|
||||
if (!bots) {
|
||||
_participantsRequests.remove(peer);
|
||||
}
|
||||
if (!peer->mgInfo) return;
|
||||
|
||||
if (result.type() == mtpc_channels_channelParticipants) {
|
||||
const MTPDchannels_channelParticipants &d(result.c_channels_channelParticipants());
|
||||
const QVector<MTPChannelParticipant> &v(d.vparticipants.c_vector().v);
|
||||
App::feedUsers(d.vusers);
|
||||
int32 botStatus = peer->mgInfo->botStatus;
|
||||
if (bots) {
|
||||
peer->mgInfo->bots.clear();
|
||||
botStatus = -1;
|
||||
} else {
|
||||
peer->mgInfo->lastParticipants.clear();
|
||||
peer->mgInfo->lastAdmins.clear();
|
||||
}
|
||||
for (QVector<MTPChannelParticipant>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
|
||||
int32 userId = 0;
|
||||
bool admin = false;
|
||||
|
||||
switch (i->type()) {
|
||||
case mtpc_channelParticipant: userId = i->c_channelParticipant().vuser_id.v; break;
|
||||
case mtpc_channelParticipantSelf: userId = i->c_channelParticipantSelf().vuser_id.v; break;
|
||||
case mtpc_channelParticipantModerator: userId = i->c_channelParticipantModerator().vuser_id.v; break;
|
||||
case mtpc_channelParticipantEditor: userId = i->c_channelParticipantEditor().vuser_id.v; admin = true; break;
|
||||
case mtpc_channelParticipantKicked: userId = i->c_channelParticipantKicked().vuser_id.v; break;
|
||||
case mtpc_channelParticipantCreator: userId = i->c_channelParticipantCreator().vuser_id.v; admin = true; break;
|
||||
}
|
||||
UserData *u = App::user(userId);
|
||||
if (bots) {
|
||||
if (u->botInfo) {
|
||||
peer->mgInfo->bots.insert(u, true);
|
||||
botStatus = (botStatus > 0/* || i.key()->botInfo->readsAllHistory*/) ? 2 : 1;
|
||||
}
|
||||
} else {
|
||||
peer->mgInfo->lastParticipants.push_back(u);
|
||||
if (admin) peer->mgInfo->lastAdmins.insert(u, true);
|
||||
}
|
||||
}
|
||||
if (d.vcount.v > peer->count) {
|
||||
peer->count = d.vcount.v;
|
||||
} else if (v.count() > peer->count) {
|
||||
peer->count = v.count();
|
||||
}
|
||||
if (App::main()) emit fullPeerUpdated(peer);
|
||||
}
|
||||
}
|
||||
|
||||
bool ApiWrap::lastParticipantsFail(ChannelData *peer, const RPCError &error) {
|
||||
if (mtpIsFlood(error)) return false;
|
||||
_participantsRequests.remove(peer);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApiWrap::requestSelfParticipant(ChannelData *channel) {
|
||||
if (_selfParticipantRequests.contains(channel)) return;
|
||||
_selfParticipantRequests.insert(channel, MTP::send(MTPchannels_GetParticipant(channel->inputChannel, MTP_inputUserSelf()), rpcDone(&ApiWrap::gotSelfParticipant, channel), rpcFail(&ApiWrap::gotSelfParticipantFail, channel), 0, 5));
|
||||
|
@ -487,6 +567,36 @@ bool ApiWrap::gotSelfParticipantFail(ChannelData *channel, const RPCError &error
|
|||
return true;
|
||||
}
|
||||
|
||||
void ApiWrap::kickParticipant(PeerData *peer, UserData *user) {
|
||||
KickRequest req(peer, user);
|
||||
if (_kickRequests.contains(req));
|
||||
if (peer->isChannel()) {
|
||||
_kickRequests.insert(req, MTP::send(MTPchannels_KickFromChannel(peer->asChannel()->inputChannel, user->inputUser, MTP_bool(true)), rpcDone(&ApiWrap::kickParticipantDone, req), rpcFail(&ApiWrap::kickParticipantFail, req)));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (i >= 0) {
|
||||
kick.first->asChannel()->mgInfo->lastParticipants.removeAt(i);
|
||||
kick.first->asChannel()->mgInfo->lastAdmins.remove(kick.second);
|
||||
kick.first->asChannel()->mgInfo->bots.remove(kick.second);
|
||||
}
|
||||
if (kick.first->asChannel()->count > 1) {
|
||||
kick.first->asChannel()->count--;
|
||||
}
|
||||
}
|
||||
emit fullPeerUpdated(kick.first);
|
||||
}
|
||||
|
||||
bool ApiWrap::kickParticipantFail(KickRequest kick, const RPCError &error, mtpRequestId req) {
|
||||
if (mtpIsFlood(error)) return false;
|
||||
_kickRequests.remove(kick);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApiWrap::scheduleStickerSetRequest(uint64 setId, uint64 access) {
|
||||
if (!_stickerSetRequests.contains(setId)) {
|
||||
_stickerSetRequests.insert(setId, qMakePair(access, 0));
|
||||
|
|
|
@ -36,11 +36,13 @@ public:
|
|||
void requestFullPeer(PeerData *peer);
|
||||
void requestPeer(PeerData *peer);
|
||||
void requestPeers(const QList<PeerData*> &peers);
|
||||
void requestLastParticipants(ChannelData *peer);
|
||||
|
||||
void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result);
|
||||
void processFullPeer(PeerData *peer, const MTPUserFull &result);
|
||||
|
||||
void requestSelfParticipant(ChannelData *channel);
|
||||
void kickParticipant(PeerData *peer, UserData *user);
|
||||
|
||||
void requestWebPageDelayed(WebPageData *page);
|
||||
void clearWebPageRequest(WebPageData *page);
|
||||
|
@ -91,6 +93,16 @@ private:
|
|||
bool gotPeerFailed(PeerData *peer, const RPCError &err);
|
||||
PeerRequests _peerRequests;
|
||||
|
||||
void lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req);
|
||||
bool lastParticipantsFail(ChannelData *peer, const RPCError &error);
|
||||
PeerRequests _participantsRequests;
|
||||
|
||||
typedef QPair<PeerData*, UserData*> KickRequest;
|
||||
typedef QMap<KickRequest, mtpRequestId> KickRequests;
|
||||
void kickParticipantDone(KickRequest kick, const MTPUpdates &updates, mtpRequestId req);
|
||||
bool kickParticipantFail(KickRequest kick, const RPCError &error, mtpRequestId req);
|
||||
KickRequests _kickRequests;
|
||||
|
||||
void gotSelfParticipant(ChannelData *channel, const MTPchannels_ChannelParticipant &result);
|
||||
bool gotSelfParticipantFail(ChannelData *channel, const RPCError &error);
|
||||
typedef QMap<ChannelData*, mtpRequestId> SelfParticipantRequests;
|
||||
|
|
|
@ -593,7 +593,7 @@ void GroupInfoBox::onPhoto() {
|
|||
if (img.isNull() || img.width() > 10 * img.height() || img.height() > 10 * img.width()) {
|
||||
return;
|
||||
}
|
||||
PhotoCropBox *box = new PhotoCropBox(img, (_creating == CreatingGroupChannel) ? peerFromChannel(0) : peerFromChat(0), false);
|
||||
PhotoCropBox *box = new PhotoCropBox(img, (_creating == CreatingGroupChannel) ? peerFromChannel(0) : peerFromChat(0));
|
||||
connect(box, SIGNAL(ready(const QImage&)), this, SLOT(onPhotoReady(const QImage&)));
|
||||
App::wnd()->replaceLayer(box);
|
||||
}
|
||||
|
|
|
@ -27,13 +27,26 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
|||
#include "photocropbox.h"
|
||||
#include "fileuploader.h"
|
||||
|
||||
PhotoCropBox::PhotoCropBox(const QImage &img, const PeerId &peer, bool upload) : AbstractBox()
|
||||
PhotoCropBox::PhotoCropBox(const QImage &img, const PeerId &peer) : AbstractBox()
|
||||
, _downState(0)
|
||||
, _done(this, lang(lng_settings_save), st::defaultBoxButton)
|
||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||
, _img(img)
|
||||
, _peerId(peer) {
|
||||
if (peerIsChat(_peerId)) {
|
||||
init(img, 0);
|
||||
}
|
||||
|
||||
PhotoCropBox::PhotoCropBox(const QImage &img, PeerData *peer) : AbstractBox()
|
||||
, _downState(0)
|
||||
, _done(this, lang(lng_settings_save), st::defaultBoxButton)
|
||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||
, _img(img)
|
||||
, _peerId(peer->id) {
|
||||
init(img, peer);
|
||||
}
|
||||
|
||||
void PhotoCropBox::init(const QImage &img, PeerData *peer) {
|
||||
if (peerIsChat(_peerId) || (peer && peer->isMegagroup())) {
|
||||
_title = lang(lng_create_group_crop);
|
||||
} else if (peerIsChannel(_peerId)) {
|
||||
_title = lang(lng_create_channel_crop);
|
||||
|
@ -43,7 +56,7 @@ PhotoCropBox::PhotoCropBox(const QImage &img, const PeerId &peer, bool upload) :
|
|||
|
||||
connect(&_done, SIGNAL(clicked()), this, SLOT(onSend()));
|
||||
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||
if (_peerId && upload) {
|
||||
if (peerToBareInt(_peerId)) {
|
||||
connect(this, SIGNAL(ready(const QImage&)), this, SLOT(onReady(const QImage&)));
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@ class PhotoCropBox : public AbstractBox {
|
|||
|
||||
public:
|
||||
|
||||
PhotoCropBox(const QImage &img, const PeerId &peer, bool upload = true);
|
||||
PhotoCropBox(const QImage &img, const PeerId &peer);
|
||||
PhotoCropBox(const QImage &img, PeerData *peer);
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
@ -53,6 +54,8 @@ protected:
|
|||
|
||||
private:
|
||||
|
||||
void init(const QImage &img, PeerData *peer);
|
||||
|
||||
QString _title;
|
||||
int32 _downState;
|
||||
int32 _thumbx, _thumby, _thumbw, _thumbh;
|
||||
|
|
|
@ -2740,7 +2740,7 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
|
|||
|
||||
const BotCommand *command = _crows->at(i).second;
|
||||
QString toHighlight = command->command;
|
||||
int32 botStatus = _parent->chat() ? _parent->chat()->botStatus : -1;
|
||||
int32 botStatus = _parent->chat() ? _parent->chat()->botStatus : ((_parent->channel() && _parent->channel()->isMegagroup()) ? _parent->channel()->mgInfo->botStatus : -1);
|
||||
if (hasUsername || botStatus == 0 || botStatus == 2) {
|
||||
toHighlight += '@' + user->username;
|
||||
}
|
||||
|
@ -2828,7 +2828,7 @@ QString MentionsInner::getSelected() const {
|
|||
} else {
|
||||
UserData *user = _crows->at(_sel).first;
|
||||
const BotCommand *command(_crows->at(_sel).second);
|
||||
int32 botStatus = _parent->chat() ? _parent->chat()->botStatus : -1;
|
||||
int32 botStatus = _parent->chat() ? _parent->chat()->botStatus : ((_parent->channel() && _parent->channel()->isMegagroup()) ? _parent->channel()->mgInfo->botStatus : -1);
|
||||
if (botStatus == 0 || botStatus == 2 || _parent->filter().indexOf('@') > 1) {
|
||||
result = '/' + command->command + '@' + user->username;
|
||||
} else {
|
||||
|
@ -3004,6 +3004,19 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
|||
rows.push_back(i.value());
|
||||
}
|
||||
}
|
||||
} else if (_filter.at(0) == '@' && _channel && _channel->isMegagroup()) {
|
||||
QMultiMap<int32, UserData*> ordered;
|
||||
if (_channel->mgInfo->lastParticipants.isEmpty()) {
|
||||
if (App::api()) App::api()->requestLastParticipants(_channel);
|
||||
} else {
|
||||
rows.reserve(_channel->mgInfo->lastParticipants.size());
|
||||
for (MegagroupInfo::LastParticipants::const_iterator i = _channel->mgInfo->lastParticipants.cbegin(), e = _channel->mgInfo->lastParticipants.cend(); i != e; ++i) {
|
||||
UserData *user = *i;
|
||||
if (user->username.isEmpty()) continue;
|
||||
if (_filter.size() > 1 && (!user->username.startsWith(_filter.midRef(1), Qt::CaseInsensitive) || user->username.size() + 1 == _filter.size())) continue;
|
||||
rows.push_back(user);
|
||||
}
|
||||
}
|
||||
} else if (_filter.at(0) == '#') {
|
||||
const RecentHashtagPack &recent(cRecentWriteHashtags());
|
||||
hrows.reserve(recent.size());
|
||||
|
@ -3019,7 +3032,6 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
|||
if (_chat->noParticipantInfo()) {
|
||||
if (App::api()) App::api()->requestFullPeer(_chat);
|
||||
} else if (!_chat->participants.isEmpty()) {
|
||||
int32 index = 0;
|
||||
for (ChatData::Participants::const_iterator i = _chat->participants.cbegin(), e = _chat->participants.cend(); i != e; ++i) {
|
||||
UserData *user = i.key();
|
||||
if (!user->botInfo) continue;
|
||||
|
@ -3033,10 +3045,23 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
|||
if (!_user->botInfo->inited && App::api()) App::api()->requestFullPeer(_user);
|
||||
cnt = _user->botInfo->commands.size();
|
||||
bots.insert(_user, true);
|
||||
} else if (_channel && _channel->isMegagroup()) {
|
||||
if (_channel->mgInfo->bots.isEmpty()) {
|
||||
if (!_channel->mgInfo->botStatus && App::api()) App::api()->requestLastParticipants(_channel);
|
||||
} else {
|
||||
for (MegagroupInfo::Bots::const_iterator i = _channel->mgInfo->bots.cbegin(), e = _channel->mgInfo->bots.cend(); i != e; ++i) {
|
||||
UserData *user = i.key();
|
||||
if (!user->botInfo) continue;
|
||||
if (!user->botInfo->inited && App::api()) App::api()->requestFullPeer(user);
|
||||
if (user->botInfo->commands.isEmpty()) continue;
|
||||
bots.insert(user, true);
|
||||
cnt += user->botInfo->commands.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cnt) {
|
||||
crows.reserve(cnt);
|
||||
int32 botStatus = _chat ? _chat->botStatus : -1;
|
||||
int32 botStatus = _chat ? _chat->botStatus : ((_channel && _channel->isMegagroup()) ? _channel->mgInfo->botStatus : -1);
|
||||
if (_chat) {
|
||||
for (MentionRows::const_iterator i = _chat->lastAuthors.cbegin(), e = _chat->lastAuthors.cend(); i != e; ++i) {
|
||||
UserData *user = *i;
|
||||
|
@ -3196,6 +3221,14 @@ ChatData *MentionsDropdown::chat() const {
|
|||
return _chat;
|
||||
}
|
||||
|
||||
ChannelData *MentionsDropdown::channel() const {
|
||||
return _channel;
|
||||
}
|
||||
|
||||
UserData *MentionsDropdown::user() const {
|
||||
return _user;
|
||||
}
|
||||
|
||||
int32 MentionsDropdown::innerTop() {
|
||||
return _scroll.scrollTop();
|
||||
}
|
||||
|
|
|
@ -649,6 +649,8 @@ public:
|
|||
|
||||
const QString &filter() const;
|
||||
ChatData *chat() const;
|
||||
ChannelData *channel() const;
|
||||
UserData *user() const;
|
||||
|
||||
int32 innerTop();
|
||||
int32 innerBottom();
|
||||
|
|
|
@ -133,14 +133,14 @@ namespace {
|
|||
}
|
||||
|
||||
const TextParseOptions &itemTextOptions(History *h, PeerData *f) {
|
||||
if ((h->peer->isUser() && h->peer->asUser()->botInfo) || (f->isUser() && f->asUser()->botInfo) || (h->peer->isChat() && h->peer->asChat()->botStatus >= 0) || (h->peer->isChannel() && h->peer->asChannel()->botStatus >= 0)) {
|
||||
if ((h->peer->isUser() && h->peer->asUser()->botInfo) || (f->isUser() && f->asUser()->botInfo) || (h->peer->isChat() && h->peer->asChat()->botStatus >= 0) || (h->peer->isMegagroup() && h->peer->asChannel()->mgInfo->botStatus >= 0)) {
|
||||
return _historyBotOptions;
|
||||
}
|
||||
return _historyTextOptions;
|
||||
}
|
||||
|
||||
const TextParseOptions &itemTextNoMonoOptions(History *h, PeerData *f) {
|
||||
if ((h->peer->isUser() && h->peer->asUser()->botInfo) || (f->isUser() && f->asUser()->botInfo) || (h->peer->isChat() && h->peer->asChat()->botStatus >= 0) || (h->peer->isChannel() && h->peer->asChannel()->botStatus >= 0)) {
|
||||
if ((h->peer->isUser() && h->peer->asUser()->botInfo) || (f->isUser() && f->asUser()->botInfo) || (h->peer->isChat() && h->peer->asChat()->botStatus >= 0) || (h->peer->isMegagroup() && h->peer->asChannel()->mgInfo->botStatus >= 0)) {
|
||||
return _historyBotNoMonoOptions;
|
||||
}
|
||||
return _historyTextNoMonoOptions;
|
||||
|
@ -684,7 +684,9 @@ void ChannelHistory::addNewGroup(const MTPMessageGroup &group) {
|
|||
}
|
||||
|
||||
HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
|
||||
if (_joinedMessage || !peer->asChannel()->amIn()) return _joinedMessage;
|
||||
if (_joinedMessage || !peer->asChannel()->amIn() || (peer->asChannel()->mgInfo && peer->asChannel()->mgInfo->migrateFrom)) {
|
||||
return _joinedMessage;
|
||||
}
|
||||
|
||||
UserData *inviter = (peer->asChannel()->inviter > 0) ? App::userLoaded(peer->asChannel()->inviter) : 0;
|
||||
if (!inviter) return 0;
|
||||
|
@ -809,7 +811,9 @@ HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
|
|||
}
|
||||
|
||||
void ChannelHistory::checkJoinedMessage(bool createUnread) {
|
||||
if (_joinedMessage || peer->asChannel()->inviter <= 0) return;
|
||||
if (_joinedMessage || peer->asChannel()->inviter <= 0 || (peer->asChannel()->mgInfo && peer->asChannel()->mgInfo->migrateFrom)) {
|
||||
return;
|
||||
}
|
||||
if (isEmpty()) {
|
||||
if (loadedAtTop() && loadedAtBottom()) {
|
||||
if (insertJoinedMessage(createUnread)) {
|
||||
|
@ -857,6 +861,13 @@ void ChannelHistory::checkJoinedMessage(bool createUnread) {
|
|||
}
|
||||
}
|
||||
|
||||
void ChannelHistory::removeJoinedMessage() {
|
||||
if (_joinedMessage) {
|
||||
_joinedMessage->destroy();
|
||||
_joinedMessage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelHistory::checkMaxReadMessageDate() {
|
||||
if (_maxReadMessageDate.isValid()) return;
|
||||
|
||||
|
@ -1713,33 +1724,54 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
|
|||
}
|
||||
}
|
||||
if (adding->from()->id) {
|
||||
if (peer->isChat() && adding->from()->isUser()) {
|
||||
QList<UserData*> *lastAuthors = &(peer->asChat()->lastAuthors);
|
||||
int prev = lastAuthors->indexOf(adding->from()->asUser());
|
||||
if (prev > 0) {
|
||||
lastAuthors->removeAt(prev);
|
||||
if (adding->from()->isUser()) {
|
||||
QList<UserData*> *lastAuthors = 0;
|
||||
if (peer->isChat()) {
|
||||
lastAuthors = &peer->asChat()->lastAuthors;
|
||||
} else if (peer->isMegagroup() && !peer->asChannel()->mgInfo->lastParticipants.isEmpty()) {
|
||||
lastAuthors = &peer->asChannel()->mgInfo->lastParticipants;
|
||||
}
|
||||
if (prev) {
|
||||
lastAuthors->push_front(adding->from()->asUser());
|
||||
if (lastAuthors) {
|
||||
int prev = lastAuthors->indexOf(adding->from()->asUser());
|
||||
if (prev > 0) {
|
||||
lastAuthors->removeAt(prev);
|
||||
}
|
||||
if (prev) {
|
||||
lastAuthors->push_front(adding->from()->asUser());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (adding->hasReplyMarkup()) {
|
||||
int32 markupFlags = App::replyMarkup(channelId(), adding->id).flags;
|
||||
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || adding->mentionsMe()) {
|
||||
QMap<PeerData*, bool> *markupSenders = 0;
|
||||
if (peer->isChat()) {
|
||||
peer->asChat()->markupSenders.insert(adding->from(), true);
|
||||
markupSenders = &peer->asChat()->markupSenders;
|
||||
} else if (peer->isMegagroup()) {
|
||||
markupSenders = &peer->asChannel()->mgInfo->markupSenders;
|
||||
}
|
||||
if (markupSenders) {
|
||||
markupSenders->insert(adding->from(), true);
|
||||
}
|
||||
if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) { // zero markup means replyKeyboardHide
|
||||
if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->isChat() && !adding->out())) {
|
||||
if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->isChat() && !peer->isMegagroup() && !adding->out())) {
|
||||
clearLastKeyboard();
|
||||
}
|
||||
} else if (peer->isChat() && adding->from()->isUser() && (!peer->asChat()->canWrite() || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from()->asUser())) {
|
||||
clearLastKeyboard();
|
||||
} else {
|
||||
lastKeyboardInited = true;
|
||||
lastKeyboardId = adding->id;
|
||||
lastKeyboardFrom = adding->from()->id;
|
||||
lastKeyboardUsed = false;
|
||||
bool botNotInChat = false;
|
||||
if (peer->isChat()) {
|
||||
botNotInChat = adding->from()->isUser() && (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from()->asUser());
|
||||
} else if (peer->isMegagroup()) {
|
||||
botNotInChat = adding->from()->isUser() && (!peer->canWrite() || !peer->asChannel()->mgInfo->bots.isEmpty()) && !peer->asChannel()->mgInfo->bots.contains(adding->from()->asUser());
|
||||
}
|
||||
if (botNotInChat) {
|
||||
clearLastKeyboard();
|
||||
} else {
|
||||
lastKeyboardInited = true;
|
||||
lastKeyboardId = adding->id;
|
||||
lastKeyboardFrom = adding->from()->id;
|
||||
lastKeyboardUsed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1904,10 +1936,20 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
|
|||
++skip;
|
||||
}
|
||||
|
||||
if (loadedAtBottom()) { // add photos to overview and authors to lastAuthors
|
||||
if (loadedAtBottom()) { // add photos to overview and authors to lastAuthors / lastParticipants
|
||||
bool channel = isChannel();
|
||||
int32 mask = 0;
|
||||
QList<UserData*> *lastAuthors = peer->isChat() ? &(peer->asChat()->lastAuthors) : 0;
|
||||
QList<UserData*> *lastAuthors = 0;
|
||||
QMap<PeerData*, bool> *markupSenders = 0;
|
||||
if (peer->isChat()) {
|
||||
lastAuthors = &peer->asChat()->lastAuthors;
|
||||
markupSenders = &peer->asChat()->markupSenders;
|
||||
} else if (peer->isMegagroup()) {
|
||||
if (!peer->asChannel()->mgInfo->lastParticipants.isEmpty()) {
|
||||
lastAuthors = &peer->asChannel()->mgInfo->lastParticipants;
|
||||
}
|
||||
markupSenders = &peer->asChannel()->mgInfo->markupSenders;
|
||||
}
|
||||
for (int32 i = block->items.size(); i > 0; --i) {
|
||||
HistoryItem *item = block->items[i - 1];
|
||||
if (!item->indexInOverview()) continue;
|
||||
|
@ -1932,16 +1974,24 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
|
|||
if (item->from()->isUser() && !lastAuthors->contains(item->from()->asUser())) {
|
||||
lastAuthors->push_back(item->from()->asUser());
|
||||
}
|
||||
if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // chats with bots
|
||||
}
|
||||
if (markupSenders) { // chats with bots
|
||||
if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) {
|
||||
int32 markupFlags = App::replyMarkup(channelId(), item->id).flags;
|
||||
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || item->mentionsMe()) {
|
||||
bool wasKeyboardHide = peer->asChat()->markupSenders.contains(item->from());
|
||||
bool wasKeyboardHide = markupSenders->contains(item->from());
|
||||
if (!wasKeyboardHide) {
|
||||
peer->asChat()->markupSenders.insert(item->from(), true);
|
||||
markupSenders->insert(item->from(), true);
|
||||
}
|
||||
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO)) {
|
||||
if (!lastKeyboardInited) {
|
||||
if (wasKeyboardHide || ((!peer->asChat()->canWrite() || !peer->asChat()->participants.isEmpty()) && item->from()->isUser() && !peer->asChat()->participants.contains(item->from()->asUser()))) {
|
||||
bool botNotInChat = false;
|
||||
if (peer->isChat()) {
|
||||
botNotInChat = (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && item->from()->isUser() && !peer->asChat()->participants.contains(item->from()->asUser());
|
||||
} else if (peer->isMegagroup()) {
|
||||
botNotInChat = (!peer->canWrite() || !peer->asChannel()->mgInfo->bots.isEmpty()) && item->from()->isUser() && !peer->asChannel()->mgInfo->bots.contains(item->from()->asUser());
|
||||
}
|
||||
if (wasKeyboardHide || botNotInChat) {
|
||||
clearLastKeyboard();
|
||||
} else {
|
||||
lastKeyboardInited = true;
|
||||
|
@ -2485,6 +2535,9 @@ void History::clear(bool leaveItems) {
|
|||
peer->asChat()->markupSenders.clear();
|
||||
} else if (isChannel()) {
|
||||
asChannelHistory()->cleared();
|
||||
if (isMegagroup()) {
|
||||
peer->asChannel()->mgInfo->markupSenders.clear();
|
||||
}
|
||||
}
|
||||
if (leaveItems && App::main()) App::main()->historyCleared(this);
|
||||
}
|
||||
|
@ -7450,6 +7503,10 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
|
|||
const MTPDmessageActionChannelMigrateFrom &d(action.c_messageActionChannelMigrateFrom());
|
||||
if (true/*PeerData *chat = App::peerLoaded(peerFromChannel(d.vchat_id))*/) {
|
||||
text = lang(lng_action_group_migrate);
|
||||
if (history()->peer->asChannel()->mgInfo) {
|
||||
history()->peer->asChannel()->mgInfo->migrateFrom = App::chat(peerFromChat(d.vchat_id));
|
||||
history()->peer->asChannel()->mgInfo->migrateFrom->migrateTo = history()->peer->asChannel();
|
||||
}
|
||||
} else {
|
||||
text = lang(lng_contacts_loading);
|
||||
}
|
||||
|
|
|
@ -398,6 +398,7 @@ public:
|
|||
|
||||
HistoryJoined *insertJoinedMessage(bool unread);
|
||||
void checkJoinedMessage(bool createUnread = false);
|
||||
void removeJoinedMessage();
|
||||
const QDateTime &maxReadMessageDate();
|
||||
|
||||
private:
|
||||
|
|
|
@ -2921,7 +2921,7 @@ void HistoryWidget::applyDraft(bool parseLinks) {
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) {
|
||||
void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId) {
|
||||
MsgId wasMsgId = _showAtMsgId;
|
||||
History *wasHistory = _history;
|
||||
|
||||
|
@ -3811,9 +3811,9 @@ void HistoryWidget::onVisibleChanged() {
|
|||
|
||||
void HistoryWidget::onHistoryToEnd() {
|
||||
if (_replyReturn) {
|
||||
showPeerHistory(_peer->id, _replyReturn->id);
|
||||
showHistory(_peer->id, _replyReturn->id);
|
||||
} else if (_peer) {
|
||||
showPeerHistory(_peer->id, ShowAtUnreadMsgId);
|
||||
showHistory(_peer->id, ShowAtUnreadMsgId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3830,7 +3830,7 @@ void HistoryWidget::onCollapseComments() {
|
|||
}
|
||||
}
|
||||
}
|
||||
showPeerHistory(_peer->id, switchAt);
|
||||
showHistory(_peer->id, switchAt);
|
||||
}
|
||||
|
||||
void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
|
||||
|
@ -4318,7 +4318,7 @@ void HistoryWidget::sendBotCommand(const QString &cmd, MsgId replyTo) { // reply
|
|||
PeerData *bot = _peer->isUser() ? _peer : (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0);
|
||||
if (bot && (!bot->isUser() || !bot->asUser()->botInfo)) bot = 0;
|
||||
QString username = bot ? bot->asUser()->username : QString();
|
||||
int32 botStatus = _peer->isChat() ? _peer->asChat()->botStatus : (_peer->isChannel() ? _peer->asChannel()->botStatus : -1);
|
||||
int32 botStatus = _peer->isChat() ? _peer->asChat()->botStatus : (_peer->isMegagroup() ? _peer->asChannel()->mgInfo->botStatus : -1);
|
||||
if (!replyTo && toSend.indexOf('@') < 2 && !username.isEmpty() && (botStatus == 0 || botStatus == 2)) {
|
||||
toSend += '@' + username;
|
||||
}
|
||||
|
@ -4342,7 +4342,7 @@ void HistoryWidget::insertBotCommand(const QString &cmd) {
|
|||
PeerData *bot = _peer->isUser() ? _peer : (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0);
|
||||
if (!bot->isUser() || !bot->asUser()->botInfo) bot = 0;
|
||||
QString username = bot ? bot->asUser()->username : QString();
|
||||
int32 botStatus = _peer->isChat() ? _peer->asChat()->botStatus : (_peer->isChannel() ? _peer->asChannel()->botStatus : -1);
|
||||
int32 botStatus = _peer->isChat() ? _peer->asChat()->botStatus : (_peer->isMegagroup() ? _peer->asChannel()->mgInfo->botStatus : -1);
|
||||
if (toInsert.indexOf('@') < 2 && !username.isEmpty() && (botStatus == 0 || botStatus == 2)) {
|
||||
toInsert += '@' + username;
|
||||
}
|
||||
|
@ -4444,16 +4444,7 @@ void HistoryWidget::updateDragAreas() {
|
|||
}
|
||||
|
||||
bool HistoryWidget::canSendMessages(PeerData *peer) const {
|
||||
if (peer) {
|
||||
if (peer->isUser()) {
|
||||
return peer->asUser()->access != UserNoAccess;
|
||||
} else if (peer->isChat()) {
|
||||
return peer->asChat()->canWrite();
|
||||
} else if (peer->isChannel()) {
|
||||
return peer->asChannel()->amIn() && (peer->asChannel()->canPublish() || !peer->asChannel()->isBroadcast());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return peer && peer->canWrite();
|
||||
}
|
||||
|
||||
bool HistoryWidget::readyToForward() const {
|
||||
|
@ -4483,7 +4474,7 @@ bool HistoryWidget::isMuteUnmute() const {
|
|||
|
||||
bool HistoryWidget::updateCmdStartShown() {
|
||||
bool cmdStartShown = false;
|
||||
if (_history && _peer && ((_peer->isChat() && _peer->asChat()->botStatus > 0) || (_peer->isChannel() && _peer->asChannel()->botStatus > 0) || (_peer->isUser() && _peer->asUser()->botInfo))) {
|
||||
if (_history && _peer && ((_peer->isChat() && _peer->asChat()->botStatus > 0) || (_peer->isMegagroup() && _peer->asChannel()->mgInfo->botStatus > 0) || (_peer->isUser() && _peer->asUser()->botInfo))) {
|
||||
if (!isBotStart() && !isBlocked() && !_keyboard.hasMarkup() && !_keyboard.forceReply()) {
|
||||
if (!_field.hasSendText()) {
|
||||
cmdStartShown = true;
|
||||
|
@ -6347,7 +6338,7 @@ QRect HistoryWidget::historyRect() const {
|
|||
}
|
||||
|
||||
void HistoryWidget::destroyData() {
|
||||
showPeerHistory(0, 0);
|
||||
showHistory(0, 0);
|
||||
}
|
||||
|
||||
QStringList HistoryWidget::getMediasFromMime(const QMimeData *d) {
|
||||
|
|
|
@ -516,7 +516,7 @@ public:
|
|||
|
||||
void fastShowAtEnd(History *h);
|
||||
void applyDraft(bool parseLinks = true);
|
||||
void showPeerHistory(const PeerId &peer, MsgId showAtMsgId);
|
||||
void showHistory(const PeerId &peer, MsgId showAtMsgId);
|
||||
void clearDelayedShowAt();
|
||||
void clearAllLoadRequests();
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ void IntroSignup::mousePressEvent(QMouseEvent *e) {
|
|||
showError(lang(lng_bad_photo));
|
||||
return;
|
||||
}
|
||||
PhotoCropBox *box = new PhotoCropBox(img, 0);
|
||||
PhotoCropBox *box = new PhotoCropBox(img, PeerId(0));
|
||||
connect(box, SIGNAL(ready(const QImage &)), this, SLOT(onPhotoReady(const QImage &)));
|
||||
App::wnd()->showLayer(box);
|
||||
}
|
||||
|
|
|
@ -2314,7 +2314,7 @@ void MainWidget::showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back)
|
|||
history.show();
|
||||
}
|
||||
if (history.peer() && history.peer()->id != peerId) clearBotStartToken(history.peer());
|
||||
history.showPeerHistory(peerId, showAtMsgId);
|
||||
history.showHistory(peerId, showAtMsgId);
|
||||
|
||||
bool noPeer = (!history.peer() || !history.peer()->id), onlyDialogs = noPeer && !cWideMode();
|
||||
if (profile || overview) {
|
||||
|
@ -2487,7 +2487,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
|
|||
}
|
||||
history.animStop();
|
||||
if (back) clearBotStartToken(history.peer());
|
||||
history.showPeerHistory(0, 0);
|
||||
history.showHistory(0, 0);
|
||||
history.hide();
|
||||
if (!cWideMode()) dialogs.hide();
|
||||
|
||||
|
@ -2533,7 +2533,7 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop)
|
|||
profile->animShow(animCache, animTopBarCache, back, lastScrollTop);
|
||||
history.animStop();
|
||||
if (back) clearBotStartToken(history.peer());
|
||||
history.showPeerHistory(0, 0);
|
||||
history.showHistory(0, 0);
|
||||
history.hide();
|
||||
|
||||
orderWidgets();
|
||||
|
@ -3639,7 +3639,7 @@ void MainWidget::inviteCheckDone(QString hash, const MTPChatInvite &invite) {
|
|||
switch (invite.type()) {
|
||||
case mtpc_chatInvite: {
|
||||
const MTPDchatInvite &d(invite.c_chatInvite());
|
||||
ConfirmBox *box = new ConfirmBox((d.is_channel() ? lng_group_invite_want_join_channel : lng_group_invite_want_join)(lt_title, qs(d.vtitle)), lang(lng_group_invite_join));
|
||||
ConfirmBox *box = new ConfirmBox(((d.is_channel() && !d.is_megagroup()) ? lng_group_invite_want_join_channel : lng_group_invite_want_join)(lt_title, qs(d.vtitle)), lang(lng_group_invite_join));
|
||||
_inviteHash = hash;
|
||||
connect(box, SIGNAL(confirmed()), this, SLOT(onInviteImport()));
|
||||
App::wnd()->showLayer(box);
|
||||
|
@ -3954,7 +3954,7 @@ int32 MainWidget::dlgsWidth() const {
|
|||
}
|
||||
|
||||
MainWidget::~MainWidget() {
|
||||
if (App::main() == this) history.showPeerHistory(0, 0);
|
||||
if (App::main() == this) history.showHistory(0, 0);
|
||||
|
||||
delete _background;
|
||||
|
||||
|
|
|
@ -129,6 +129,9 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
|||
if (chatPhoto && chatPhoto->date) {
|
||||
_photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer));
|
||||
}
|
||||
if (_peerChannel->isMegagroup() && _peerChannel->mgInfo->lastParticipants.isEmpty()) {
|
||||
if (App::api()) App::api()->requestLastParticipants(_peerChannel);
|
||||
}
|
||||
_peerChannel->updateFull();
|
||||
}
|
||||
|
||||
|
@ -294,7 +297,7 @@ void ProfileInner::onUpdatePhoto() {
|
|||
saveError(lang(lng_bad_photo));
|
||||
return;
|
||||
}
|
||||
PhotoCropBox *box = new PhotoCropBox(img, _peer->id);
|
||||
PhotoCropBox *box = new PhotoCropBox(img, _peer);
|
||||
connect(box, SIGNAL(closed()), this, SLOT(onPhotoUpdateStart()));
|
||||
App::wnd()->showLayer(box);
|
||||
}
|
||||
|
@ -369,9 +372,15 @@ bool ProfileInner::blockFail(const RPCError &error) {
|
|||
}
|
||||
|
||||
void ProfileInner::onAddParticipant() {
|
||||
if (!_peerChat) return;
|
||||
|
||||
App::wnd()->showLayer(new ContactsBox(_peerChat, MembersFilterRecent));
|
||||
if (_peerChat) {
|
||||
App::wnd()->showLayer(new ContactsBox(_peerChat, MembersFilterRecent));
|
||||
} else if (_peerChannel && _peerChannel->mgInfo) {
|
||||
MembersAlreadyIn already;
|
||||
for (MegagroupInfo::LastParticipants::const_iterator i = _peerChannel->mgInfo->lastParticipants.cbegin(), e = _peerChannel->mgInfo->lastParticipants.cend(); i != e; ++i) {
|
||||
already.insert(*i, true);
|
||||
}
|
||||
App::wnd()->showLayer(new ContactsBox(_peerChannel, MembersFilterRecent, already));
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileInner::onMigrate() {
|
||||
|
@ -669,6 +678,28 @@ void ProfileInner::reorderParticipants() {
|
|||
_onlineText = lng_chat_status_members(lt_count, _participants.size());
|
||||
}
|
||||
loadProfilePhotos(_lastPreload);
|
||||
} else if (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn() && !_peerChannel->mgInfo->lastParticipants.isEmpty()) {
|
||||
if (!_peerChannel->mgInfo->lastParticipants.isEmpty()) {
|
||||
_participants.clear();
|
||||
for (ParticipantsData::iterator i = _participantsData.begin(), e = _participantsData.end(); i != e; ++i) {
|
||||
if (*i) {
|
||||
delete *i;
|
||||
*i = 0;
|
||||
}
|
||||
}
|
||||
_participants.reserve(_peerChannel->mgInfo->lastParticipants.size());
|
||||
_participantsData.resize(_peerChannel->mgInfo->lastParticipants.size());
|
||||
}
|
||||
UserData *self = App::self();
|
||||
bool onlyMe = true;
|
||||
for (MegagroupInfo::LastParticipants::const_iterator i = _peerChannel->mgInfo->lastParticipants.cbegin(), e = _peerChannel->mgInfo->lastParticipants.cend(); i != e; ++i) {
|
||||
_participants.push_back(*i);
|
||||
}
|
||||
if (_peerChannel->mgInfo->lastParticipants.isEmpty()) {
|
||||
if (App::api()) App::api()->requestLastParticipants(_peerChannel);
|
||||
}
|
||||
_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
|
||||
loadProfilePhotos(_lastPreload);
|
||||
} else {
|
||||
_participants.clear();
|
||||
if (_peerUser) {
|
||||
|
@ -744,10 +775,10 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
|||
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||
p.setPen(st::black->p);
|
||||
p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + st::profileStatusTop + st::linkFont->ascent, '@' + _peerUser->username);
|
||||
} else if (_peerChannel && (_peerChannel->isPublic() || _amCreator)) {
|
||||
} else if (_peerChannel && !_peerChannel->isMegagroup() && (_peerChannel->isPublic() || _amCreator )) {
|
||||
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||
}
|
||||
if (!_peerChannel || !_peerChannel->canViewParticipants()) {
|
||||
if (!_peerChannel || !_peerChannel->canViewParticipants() || _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);
|
||||
}
|
||||
|
@ -855,21 +886,21 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
|||
p.drawText(_left + st::profileHeaderLeft, top + st::profileHeaderTop + st::profileHeaderFont->ascent, lang(lng_profile_actions_section));
|
||||
top += st::profileHeaderSkip;
|
||||
|
||||
top += _searchInPeer.height();
|
||||
top += _searchInPeer.height() + st::setLittleSkip;
|
||||
if (_peerUser || _peerChat) {
|
||||
top += st::setLittleSkip + _clearHistory.height();
|
||||
top += _clearHistory.height() + st::setLittleSkip;
|
||||
}
|
||||
if (_peerUser || _peerChat || (_peerChannel->amIn() && !_amCreator)) {
|
||||
top += st::setLittleSkip + _deleteConversation.height();
|
||||
top += _deleteConversation.height();
|
||||
}
|
||||
if (_peerUser && peerToUser(_peerUser->id) != MTP::authedId()) {
|
||||
top += st::setSectionSkip + _blockUser.height();
|
||||
} else if (_peerChannel && _amCreator) {
|
||||
top += st::setSectionSkip + _deleteChannel.height();
|
||||
top += (_peerChannel->isMegagroup() ? 0 : (st::setSectionSkip - st::setLittleSkip)) + _deleteChannel.height();
|
||||
}
|
||||
|
||||
// participants
|
||||
if (_peerChat && _peerChat->amIn()) {
|
||||
if ((_peerChat && _peerChat->amIn()) || (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn())) {
|
||||
QString sectionHeader = lang(_participants.isEmpty() ? lng_profile_loading : lng_profile_participants_section);
|
||||
p.setFont(st::profileHeaderFont->f);
|
||||
p.setPen(st::profileHeaderColor->p);
|
||||
|
@ -905,10 +936,12 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
if (_amCreator) {
|
||||
data->cankick = (user != App::self());
|
||||
} else if (_peerChat->amAdmin()) {
|
||||
} else if (_peerChat && _peerChat->amAdmin()) {
|
||||
data->cankick = (user != App::self()) && (_peerChat->admins.constFind(user) == _peerChat->admins.cend()) && (peerFromUser(_peerChat->creator) != user->id);
|
||||
} else if (_peerChannel && _peerChannel->amEditor()) {
|
||||
data->cankick = (user != App::self()) && (_peerChannel->mgInfo->lastAdmins.constFind(user) == _peerChannel->mgInfo->lastAdmins.cend());
|
||||
} else {
|
||||
data->cankick = (user != App::self()) && (_peerChat->invitedByMe.constFind(user) != _peerChat->invitedByMe.cend());
|
||||
data->cankick = (user != App::self()) && !_peerChannel && (_peerChat->invitedByMe.constFind(user) != _peerChat->invitedByMe.cend());
|
||||
}
|
||||
}
|
||||
p.setPen(st::profileListNameColor->p);
|
||||
|
@ -971,21 +1004,20 @@ void ProfileInner::updateSelected() {
|
|||
update(QRect(_left, _aboutTop, _width, _aboutHeight));
|
||||
}
|
||||
|
||||
int32 partfrom = _searchInPeer.y() + _searchInPeer.height();
|
||||
if (_peerUser || _peerChat) {
|
||||
partfrom = _clearHistory.y() + _clearHistory.height();
|
||||
int32 participantsTop = 0;
|
||||
if (_peerChannel && _amCreator) {
|
||||
participantsTop = _deleteChannel.y() + _deleteChannel.height();
|
||||
} else {
|
||||
participantsTop = _deleteConversation.y() + _deleteConversation.height();
|
||||
}
|
||||
if (_peerUser || _peerChat || (_peerChannel->amIn() && !_amCreator)) {
|
||||
partfrom = _deleteConversation.y() + _deleteConversation.height();
|
||||
}
|
||||
partfrom += st::profileHeaderSkip;
|
||||
int32 newSelected = (lp.x() >= _left - st::profileListPadding.width() && lp.x() < _left + _width + st::profileListPadding.width() && lp.y() >= partfrom) ? (lp.y() - partfrom) / _pHeight : -1;
|
||||
participantsTop += st::profileHeaderSkip;
|
||||
int32 newSelected = (lp.x() >= _left - st::profileListPadding.width() && lp.x() < _left + _width + st::profileListPadding.width() && lp.y() >= participantsTop) ? (lp.y() - participantsTop) / _pHeight : -1;
|
||||
|
||||
UserData *newKickOver = 0;
|
||||
if (newSelected >= 0 && newSelected < _participants.size()) {
|
||||
ParticipantData *data = _participantsData[newSelected];
|
||||
if (data && data->cankick) {
|
||||
int32 top = partfrom + newSelected * _pHeight + st::profileListNameTop;
|
||||
int32 top = participantsTop + newSelected * _pHeight + st::profileListNameTop;
|
||||
if ((lp.x() >= _left + _width - _kickWidth) && (lp.x() < _left + _width) && (lp.y() >= top) && (lp.y() < top + st::linkFont->height)) {
|
||||
newKickOver = _participants[newSelected];
|
||||
}
|
||||
|
@ -1056,9 +1088,12 @@ void ProfileInner::mouseReleaseEvent(QMouseEvent *e) {
|
|||
}
|
||||
|
||||
void ProfileInner::onKickConfirm() {
|
||||
if (!_peerChat) return;
|
||||
|
||||
App::main()->kickParticipant(_peerChat, _kickConfirm);
|
||||
if (_peerChat) {
|
||||
App::main()->kickParticipant(_peerChat, _kickConfirm);
|
||||
} else if (_peerChannel) {
|
||||
App::wnd()->hideLayer();
|
||||
App::api()->kickParticipant(_peerChannel, _kickConfirm);
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileInner::keyPressEvent(QKeyEvent *e) {
|
||||
|
@ -1299,12 +1334,12 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
|||
top += st::setSectionSkip;
|
||||
_blockUser.move(_left, top); top += _blockUser.height();
|
||||
} else if (_peerChannel && _amCreator) {
|
||||
top += st::setSectionSkip;
|
||||
top += (_peerChannel->isMegagroup() ? 0 : (st::setSectionSkip - st::setLittleSkip));
|
||||
_deleteChannel.move(_left, top); top += _deleteChannel.height();
|
||||
}
|
||||
|
||||
// participants
|
||||
if (_peerChat && _peerChat->amIn()) {
|
||||
if ((_peerChat && _peerChat->amIn()) || (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn())) {
|
||||
top += st::profileHeaderSkip;
|
||||
if (!_participants.isEmpty()) {
|
||||
int32 fullCnt = _participants.size();
|
||||
|
@ -1427,6 +1462,13 @@ int32 ProfileInner::countMinHeight() {
|
|||
} else {
|
||||
h = _searchInPeer.y() + _searchInPeer.height() + st::profileHeaderSkip;
|
||||
}
|
||||
if (_peerChannel->isMegagroup()) {
|
||||
if (!_participants.isEmpty()) {
|
||||
h += st::profileHeaderSkip + _participants.size() * _pHeight;
|
||||
} else if (_peerChannel->amIn()) {
|
||||
h += st::profileHeaderSkip;
|
||||
}
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
@ -1555,7 +1597,11 @@ void ProfileInner::showAll() {
|
|||
_invitationLink.hide();
|
||||
}
|
||||
}
|
||||
_addParticipant.hide();
|
||||
if (_peerChannel->count < cMaxMegaGroupCount() && _peerChannel->isMegagroup() && (_amCreator || _peerChannel->amEditor())) {
|
||||
_addParticipant.show();
|
||||
} else {
|
||||
_addParticipant.hide();
|
||||
}
|
||||
_blockUser.hide();
|
||||
if (_amCreator) {
|
||||
_deleteChannel.show();
|
||||
|
@ -1572,7 +1618,7 @@ void ProfileInner::showAll() {
|
|||
} else {
|
||||
_admins.hide();
|
||||
}
|
||||
if (_peerChannel->canViewParticipants()) {
|
||||
if (_peerChannel->canViewParticipants() && !_peerChannel->isMegagroup()) {
|
||||
_members.show();
|
||||
} else {
|
||||
_members.hide();
|
||||
|
|
|
@ -1169,7 +1169,7 @@ void SettingsInner::onUpdatePhoto() {
|
|||
saveError(lang(lng_bad_photo));
|
||||
return;
|
||||
}
|
||||
PhotoCropBox *box = new PhotoCropBox(img, self()->id);
|
||||
PhotoCropBox *box = new PhotoCropBox(img, self());
|
||||
connect(box, SIGNAL(closed()), this, SLOT(onPhotoUpdateStart()));
|
||||
App::wnd()->showLayer(box);
|
||||
}
|
||||
|
|
|
@ -1026,6 +1026,7 @@ void CommentsLink::onClick(Qt::MouseButton button) const {
|
|||
}
|
||||
|
||||
MsgId clientMsgId() {
|
||||
static MsgId current = -2000000000;
|
||||
return ++current;
|
||||
static MsgId currentClientMsgId = StartClientMsgId;
|
||||
Q_ASSERT(currentClientMsgId < EndClientMsgId);
|
||||
return currentClientMsgId++;
|
||||
}
|
||||
|
|
|
@ -142,8 +142,14 @@ inline bool operator<(const FullMsgId &a, const FullMsgId &b) {
|
|||
return a.channel < b.channel;
|
||||
}
|
||||
|
||||
static const MsgId StartClientMsgId = -0x7FFFFFFF;
|
||||
static const MsgId EndClientMsgId = -0x40000000;
|
||||
inline bool isClientMsgId(MsgId id) {
|
||||
return id >= StartClientMsgId && id < EndClientMsgId;
|
||||
}
|
||||
static const MsgId ShowAtTheEndMsgId = -0x40000000;
|
||||
static const MsgId SwitchAtTopMsgId = -0x3FFFFFFF;
|
||||
static const MsgId ServerMaxMsgId = 0x3FFFFFFF;
|
||||
static const MsgId ShowAtUnreadMsgId = 0;
|
||||
|
||||
struct NotifySettings {
|
||||
|
@ -212,6 +218,7 @@ public:
|
|||
}
|
||||
bool isVerified() const;
|
||||
bool isMegagroup() const;
|
||||
bool canWrite() const;
|
||||
UserData *asUser();
|
||||
const UserData *asUser() const;
|
||||
ChatData *asChat();
|
||||
|
@ -350,6 +357,9 @@ public:
|
|||
bool isVerified() const {
|
||||
return flags & MTPDuser::flag_verified;
|
||||
}
|
||||
bool canWrite() const {
|
||||
return access != UserNoAccess;
|
||||
}
|
||||
|
||||
MTPInputUser inputUser;
|
||||
|
||||
|
@ -373,7 +383,7 @@ public:
|
|||
class ChatData : public PeerData {
|
||||
public:
|
||||
|
||||
ChatData(const PeerId &id) : PeerData(id), inputChat(MTP_int(bareId())), count(0), date(0), version(0), creator(0), inviterForSpamReport(0), flags(0), isForbidden(false), botStatus(0) {
|
||||
ChatData(const PeerId &id) : PeerData(id), inputChat(MTP_int(bareId())), migrateTo(0), count(0), date(0), version(0), creator(0), inviterForSpamReport(0), flags(0), isForbidden(false), botStatus(0) {
|
||||
}
|
||||
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
||||
void invalidateParticipants() {
|
||||
|
@ -389,6 +399,8 @@ public:
|
|||
|
||||
MTPint inputChat;
|
||||
|
||||
ChannelData *migrateTo;
|
||||
|
||||
int32 count;
|
||||
int32 date;
|
||||
int32 version;
|
||||
|
@ -504,19 +516,24 @@ private:
|
|||
};
|
||||
|
||||
struct MegagroupInfo {
|
||||
MegagroupInfo() : botStatus(-1) {
|
||||
MegagroupInfo() : botStatus(-1), migrateFrom(0) {
|
||||
}
|
||||
typedef QList<UserData*> LastParticipants;
|
||||
LastParticipants lastParticipants;
|
||||
typedef QMap<UserData*, bool> LastAdmins;
|
||||
LastAdmins lastAdmins;
|
||||
typedef QMap<PeerData*, bool> MarkupSenders;
|
||||
MarkupSenders markupSenders;
|
||||
typedef QMap<UserData*, bool> Bots;
|
||||
Bots bots;
|
||||
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
||||
ChatData *migrateFrom;
|
||||
};
|
||||
|
||||
class ChannelData : public PeerData {
|
||||
public:
|
||||
|
||||
ChannelData(const PeerId &id) : PeerData(id), access(0), inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))), count(1), adminsCount(1), date(0), version(0), flags(0), flagsFull(0), mgInfo(0), isForbidden(true), botStatus(-1), inviter(0), _lastFullUpdate(0) {
|
||||
ChannelData(const PeerId &id) : PeerData(id), access(0), inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))), count(1), adminsCount(1), date(0), version(0), flags(0), flagsFull(0), mgInfo(0), isForbidden(true), inviter(0), _lastFullUpdate(0) {
|
||||
setName(QString(), QString());
|
||||
}
|
||||
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
||||
|
@ -566,6 +583,9 @@ public:
|
|||
bool canPublish() const {
|
||||
return amCreator() || amEditor();
|
||||
}
|
||||
bool canWrite() const {
|
||||
return amIn() && (canPublish() || !isBroadcast());
|
||||
}
|
||||
bool canViewParticipants() const {
|
||||
return flagsFull & MTPDchannelFull::flag_can_view_participants;
|
||||
}
|
||||
|
@ -574,7 +594,6 @@ public:
|
|||
return flags & MTPDchannel::flag_verified;
|
||||
}
|
||||
|
||||
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
||||
// ImagePtr photoFull;
|
||||
QString invitationUrl;
|
||||
|
||||
|
@ -655,6 +674,9 @@ inline bool PeerData::isVerified() const {
|
|||
inline bool PeerData::isMegagroup() const {
|
||||
return isChannel() ? asChannel()->isMegagroup() : false;
|
||||
}
|
||||
inline bool PeerData::canWrite() const {
|
||||
return isChannel() ? asChannel()->canWrite() : (isChat() ? asChat()->canWrite() : (isUser() ? asUser()->canWrite() : false));
|
||||
}
|
||||
|
||||
inline int32 newMessageFlags(PeerData *p) {
|
||||
return p->isSelf() ? 0 : (((p->isChat() || (p->isUser() && !p->asUser()->botInfo)) ? MTPDmessage::flag_unread : 0) | MTPDmessage::flag_out);
|
||||
|
|
Loading…
Reference in New Issue