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 {
|
} else {
|
||||||
channel->photoId = 0;
|
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->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->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();
|
channel->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString();
|
||||||
if (History *h = App::historyLoaded(channel->id)) {
|
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->inboxReadBefore = f.vread_inbox_max_id.v + 1;
|
||||||
h->asChannelHistory()->unreadCountAll = f.vunread_count.v;
|
h->asChannelHistory()->unreadCountAll = f.vunread_count.v;
|
||||||
}
|
}
|
||||||
|
if (channel->mgInfo && channel->mgInfo->migrateFrom) {
|
||||||
|
h->asChannelHistory()->removeJoinedMessage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
channel->fullUpdated();
|
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));
|
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) {
|
void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) {
|
||||||
_peerRequests.remove(peer);
|
_peerRequests.remove(peer);
|
||||||
|
|
||||||
|
@ -433,6 +455,64 @@ bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &error) {
|
||||||
return true;
|
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) {
|
void ApiWrap::requestSelfParticipant(ChannelData *channel) {
|
||||||
if (_selfParticipantRequests.contains(channel)) return;
|
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));
|
_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;
|
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) {
|
void ApiWrap::scheduleStickerSetRequest(uint64 setId, uint64 access) {
|
||||||
if (!_stickerSetRequests.contains(setId)) {
|
if (!_stickerSetRequests.contains(setId)) {
|
||||||
_stickerSetRequests.insert(setId, qMakePair(access, 0));
|
_stickerSetRequests.insert(setId, qMakePair(access, 0));
|
||||||
|
|
|
@ -36,11 +36,13 @@ public:
|
||||||
void requestFullPeer(PeerData *peer);
|
void requestFullPeer(PeerData *peer);
|
||||||
void requestPeer(PeerData *peer);
|
void requestPeer(PeerData *peer);
|
||||||
void requestPeers(const QList<PeerData*> &peers);
|
void requestPeers(const QList<PeerData*> &peers);
|
||||||
|
void requestLastParticipants(ChannelData *peer);
|
||||||
|
|
||||||
void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result);
|
void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result);
|
||||||
void processFullPeer(PeerData *peer, const MTPUserFull &result);
|
void processFullPeer(PeerData *peer, const MTPUserFull &result);
|
||||||
|
|
||||||
void requestSelfParticipant(ChannelData *channel);
|
void requestSelfParticipant(ChannelData *channel);
|
||||||
|
void kickParticipant(PeerData *peer, UserData *user);
|
||||||
|
|
||||||
void requestWebPageDelayed(WebPageData *page);
|
void requestWebPageDelayed(WebPageData *page);
|
||||||
void clearWebPageRequest(WebPageData *page);
|
void clearWebPageRequest(WebPageData *page);
|
||||||
|
@ -91,6 +93,16 @@ private:
|
||||||
bool gotPeerFailed(PeerData *peer, const RPCError &err);
|
bool gotPeerFailed(PeerData *peer, const RPCError &err);
|
||||||
PeerRequests _peerRequests;
|
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);
|
void gotSelfParticipant(ChannelData *channel, const MTPchannels_ChannelParticipant &result);
|
||||||
bool gotSelfParticipantFail(ChannelData *channel, const RPCError &error);
|
bool gotSelfParticipantFail(ChannelData *channel, const RPCError &error);
|
||||||
typedef QMap<ChannelData*, mtpRequestId> SelfParticipantRequests;
|
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()) {
|
if (img.isNull() || img.width() > 10 * img.height() || img.height() > 10 * img.width()) {
|
||||||
return;
|
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&)));
|
connect(box, SIGNAL(ready(const QImage&)), this, SLOT(onPhotoReady(const QImage&)));
|
||||||
App::wnd()->replaceLayer(box);
|
App::wnd()->replaceLayer(box);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,26 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
#include "photocropbox.h"
|
#include "photocropbox.h"
|
||||||
#include "fileuploader.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)
|
, _downState(0)
|
||||||
, _done(this, lang(lng_settings_save), st::defaultBoxButton)
|
, _done(this, lang(lng_settings_save), st::defaultBoxButton)
|
||||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||||
, _img(img)
|
, _img(img)
|
||||||
, _peerId(peer) {
|
, _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);
|
_title = lang(lng_create_group_crop);
|
||||||
} else if (peerIsChannel(_peerId)) {
|
} else if (peerIsChannel(_peerId)) {
|
||||||
_title = lang(lng_create_channel_crop);
|
_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(&_done, SIGNAL(clicked()), this, SLOT(onSend()));
|
||||||
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
if (_peerId && upload) {
|
if (peerToBareInt(_peerId)) {
|
||||||
connect(this, SIGNAL(ready(const QImage&)), this, SLOT(onReady(const QImage&)));
|
connect(this, SIGNAL(ready(const QImage&)), this, SLOT(onReady(const QImage&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,8 @@ class PhotoCropBox : public AbstractBox {
|
||||||
|
|
||||||
public:
|
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 keyPressEvent(QKeyEvent *e);
|
||||||
void paintEvent(QPaintEvent *e);
|
void paintEvent(QPaintEvent *e);
|
||||||
void resizeEvent(QResizeEvent *e);
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
@ -53,6 +54,8 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void init(const QImage &img, PeerData *peer);
|
||||||
|
|
||||||
QString _title;
|
QString _title;
|
||||||
int32 _downState;
|
int32 _downState;
|
||||||
int32 _thumbx, _thumby, _thumbw, _thumbh;
|
int32 _thumbx, _thumby, _thumbw, _thumbh;
|
||||||
|
|
|
@ -2740,7 +2740,7 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
const BotCommand *command = _crows->at(i).second;
|
const BotCommand *command = _crows->at(i).second;
|
||||||
QString toHighlight = command->command;
|
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) {
|
if (hasUsername || botStatus == 0 || botStatus == 2) {
|
||||||
toHighlight += '@' + user->username;
|
toHighlight += '@' + user->username;
|
||||||
}
|
}
|
||||||
|
@ -2828,7 +2828,7 @@ QString MentionsInner::getSelected() const {
|
||||||
} else {
|
} else {
|
||||||
UserData *user = _crows->at(_sel).first;
|
UserData *user = _crows->at(_sel).first;
|
||||||
const BotCommand *command(_crows->at(_sel).second);
|
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) {
|
if (botStatus == 0 || botStatus == 2 || _parent->filter().indexOf('@') > 1) {
|
||||||
result = '/' + command->command + '@' + user->username;
|
result = '/' + command->command + '@' + user->username;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3004,6 +3004,19 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
||||||
rows.push_back(i.value());
|
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) == '#') {
|
} else if (_filter.at(0) == '#') {
|
||||||
const RecentHashtagPack &recent(cRecentWriteHashtags());
|
const RecentHashtagPack &recent(cRecentWriteHashtags());
|
||||||
hrows.reserve(recent.size());
|
hrows.reserve(recent.size());
|
||||||
|
@ -3019,7 +3032,6 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
||||||
if (_chat->noParticipantInfo()) {
|
if (_chat->noParticipantInfo()) {
|
||||||
if (App::api()) App::api()->requestFullPeer(_chat);
|
if (App::api()) App::api()->requestFullPeer(_chat);
|
||||||
} else if (!_chat->participants.isEmpty()) {
|
} else if (!_chat->participants.isEmpty()) {
|
||||||
int32 index = 0;
|
|
||||||
for (ChatData::Participants::const_iterator i = _chat->participants.cbegin(), e = _chat->participants.cend(); i != e; ++i) {
|
for (ChatData::Participants::const_iterator i = _chat->participants.cbegin(), e = _chat->participants.cend(); i != e; ++i) {
|
||||||
UserData *user = i.key();
|
UserData *user = i.key();
|
||||||
if (!user->botInfo) continue;
|
if (!user->botInfo) continue;
|
||||||
|
@ -3033,10 +3045,23 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
||||||
if (!_user->botInfo->inited && App::api()) App::api()->requestFullPeer(_user);
|
if (!_user->botInfo->inited && App::api()) App::api()->requestFullPeer(_user);
|
||||||
cnt = _user->botInfo->commands.size();
|
cnt = _user->botInfo->commands.size();
|
||||||
bots.insert(_user, true);
|
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) {
|
if (cnt) {
|
||||||
crows.reserve(cnt);
|
crows.reserve(cnt);
|
||||||
int32 botStatus = _chat ? _chat->botStatus : -1;
|
int32 botStatus = _chat ? _chat->botStatus : ((_channel && _channel->isMegagroup()) ? _channel->mgInfo->botStatus : -1);
|
||||||
if (_chat) {
|
if (_chat) {
|
||||||
for (MentionRows::const_iterator i = _chat->lastAuthors.cbegin(), e = _chat->lastAuthors.cend(); i != e; ++i) {
|
for (MentionRows::const_iterator i = _chat->lastAuthors.cbegin(), e = _chat->lastAuthors.cend(); i != e; ++i) {
|
||||||
UserData *user = *i;
|
UserData *user = *i;
|
||||||
|
@ -3196,6 +3221,14 @@ ChatData *MentionsDropdown::chat() const {
|
||||||
return _chat;
|
return _chat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChannelData *MentionsDropdown::channel() const {
|
||||||
|
return _channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserData *MentionsDropdown::user() const {
|
||||||
|
return _user;
|
||||||
|
}
|
||||||
|
|
||||||
int32 MentionsDropdown::innerTop() {
|
int32 MentionsDropdown::innerTop() {
|
||||||
return _scroll.scrollTop();
|
return _scroll.scrollTop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -649,6 +649,8 @@ public:
|
||||||
|
|
||||||
const QString &filter() const;
|
const QString &filter() const;
|
||||||
ChatData *chat() const;
|
ChatData *chat() const;
|
||||||
|
ChannelData *channel() const;
|
||||||
|
UserData *user() const;
|
||||||
|
|
||||||
int32 innerTop();
|
int32 innerTop();
|
||||||
int32 innerBottom();
|
int32 innerBottom();
|
||||||
|
|
|
@ -133,14 +133,14 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
const TextParseOptions &itemTextOptions(History *h, PeerData *f) {
|
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 _historyBotOptions;
|
||||||
}
|
}
|
||||||
return _historyTextOptions;
|
return _historyTextOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TextParseOptions &itemTextNoMonoOptions(History *h, PeerData *f) {
|
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 _historyBotNoMonoOptions;
|
||||||
}
|
}
|
||||||
return _historyTextNoMonoOptions;
|
return _historyTextNoMonoOptions;
|
||||||
|
@ -684,7 +684,9 @@ void ChannelHistory::addNewGroup(const MTPMessageGroup &group) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
|
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;
|
UserData *inviter = (peer->asChannel()->inviter > 0) ? App::userLoaded(peer->asChannel()->inviter) : 0;
|
||||||
if (!inviter) return 0;
|
if (!inviter) return 0;
|
||||||
|
@ -809,7 +811,9 @@ HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelHistory::checkJoinedMessage(bool createUnread) {
|
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 (isEmpty()) {
|
||||||
if (loadedAtTop() && loadedAtBottom()) {
|
if (loadedAtTop() && loadedAtBottom()) {
|
||||||
if (insertJoinedMessage(createUnread)) {
|
if (insertJoinedMessage(createUnread)) {
|
||||||
|
@ -857,6 +861,13 @@ void ChannelHistory::checkJoinedMessage(bool createUnread) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChannelHistory::removeJoinedMessage() {
|
||||||
|
if (_joinedMessage) {
|
||||||
|
_joinedMessage->destroy();
|
||||||
|
_joinedMessage = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChannelHistory::checkMaxReadMessageDate() {
|
void ChannelHistory::checkMaxReadMessageDate() {
|
||||||
if (_maxReadMessageDate.isValid()) return;
|
if (_maxReadMessageDate.isValid()) return;
|
||||||
|
|
||||||
|
@ -1713,8 +1724,14 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (adding->from()->id) {
|
if (adding->from()->id) {
|
||||||
if (peer->isChat() && adding->from()->isUser()) {
|
if (adding->from()->isUser()) {
|
||||||
QList<UserData*> *lastAuthors = &(peer->asChat()->lastAuthors);
|
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 (lastAuthors) {
|
||||||
int prev = lastAuthors->indexOf(adding->from()->asUser());
|
int prev = lastAuthors->indexOf(adding->from()->asUser());
|
||||||
if (prev > 0) {
|
if (prev > 0) {
|
||||||
lastAuthors->removeAt(prev);
|
lastAuthors->removeAt(prev);
|
||||||
|
@ -1723,17 +1740,31 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
|
||||||
lastAuthors->push_front(adding->from()->asUser());
|
lastAuthors->push_front(adding->from()->asUser());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (adding->hasReplyMarkup()) {
|
if (adding->hasReplyMarkup()) {
|
||||||
int32 markupFlags = App::replyMarkup(channelId(), adding->id).flags;
|
int32 markupFlags = App::replyMarkup(channelId(), adding->id).flags;
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || adding->mentionsMe()) {
|
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || adding->mentionsMe()) {
|
||||||
|
QMap<PeerData*, bool> *markupSenders = 0;
|
||||||
if (peer->isChat()) {
|
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 (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();
|
clearLastKeyboard();
|
||||||
}
|
}
|
||||||
} else if (peer->isChat() && adding->from()->isUser() && (!peer->asChat()->canWrite() || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from()->asUser())) {
|
} else {
|
||||||
|
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();
|
clearLastKeyboard();
|
||||||
} else {
|
} else {
|
||||||
lastKeyboardInited = true;
|
lastKeyboardInited = true;
|
||||||
|
@ -1744,6 +1775,7 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return adding;
|
return adding;
|
||||||
}
|
}
|
||||||
|
@ -1904,10 +1936,20 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
|
||||||
++skip;
|
++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();
|
bool channel = isChannel();
|
||||||
int32 mask = 0;
|
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) {
|
for (int32 i = block->items.size(); i > 0; --i) {
|
||||||
HistoryItem *item = block->items[i - 1];
|
HistoryItem *item = block->items[i - 1];
|
||||||
if (!item->indexInOverview()) continue;
|
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())) {
|
if (item->from()->isUser() && !lastAuthors->contains(item->from()->asUser())) {
|
||||||
lastAuthors->push_back(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;
|
int32 markupFlags = App::replyMarkup(channelId(), item->id).flags;
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || item->mentionsMe()) {
|
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || item->mentionsMe()) {
|
||||||
bool wasKeyboardHide = peer->asChat()->markupSenders.contains(item->from());
|
bool wasKeyboardHide = markupSenders->contains(item->from());
|
||||||
if (!wasKeyboardHide) {
|
if (!wasKeyboardHide) {
|
||||||
peer->asChat()->markupSenders.insert(item->from(), true);
|
markupSenders->insert(item->from(), true);
|
||||||
}
|
}
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO)) {
|
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO)) {
|
||||||
if (!lastKeyboardInited) {
|
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();
|
clearLastKeyboard();
|
||||||
} else {
|
} else {
|
||||||
lastKeyboardInited = true;
|
lastKeyboardInited = true;
|
||||||
|
@ -2485,6 +2535,9 @@ void History::clear(bool leaveItems) {
|
||||||
peer->asChat()->markupSenders.clear();
|
peer->asChat()->markupSenders.clear();
|
||||||
} else if (isChannel()) {
|
} else if (isChannel()) {
|
||||||
asChannelHistory()->cleared();
|
asChannelHistory()->cleared();
|
||||||
|
if (isMegagroup()) {
|
||||||
|
peer->asChannel()->mgInfo->markupSenders.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (leaveItems && App::main()) App::main()->historyCleared(this);
|
if (leaveItems && App::main()) App::main()->historyCleared(this);
|
||||||
}
|
}
|
||||||
|
@ -7450,6 +7503,10 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
|
||||||
const MTPDmessageActionChannelMigrateFrom &d(action.c_messageActionChannelMigrateFrom());
|
const MTPDmessageActionChannelMigrateFrom &d(action.c_messageActionChannelMigrateFrom());
|
||||||
if (true/*PeerData *chat = App::peerLoaded(peerFromChannel(d.vchat_id))*/) {
|
if (true/*PeerData *chat = App::peerLoaded(peerFromChannel(d.vchat_id))*/) {
|
||||||
text = lang(lng_action_group_migrate);
|
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 {
|
} else {
|
||||||
text = lang(lng_contacts_loading);
|
text = lang(lng_contacts_loading);
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,6 +398,7 @@ public:
|
||||||
|
|
||||||
HistoryJoined *insertJoinedMessage(bool unread);
|
HistoryJoined *insertJoinedMessage(bool unread);
|
||||||
void checkJoinedMessage(bool createUnread = false);
|
void checkJoinedMessage(bool createUnread = false);
|
||||||
|
void removeJoinedMessage();
|
||||||
const QDateTime &maxReadMessageDate();
|
const QDateTime &maxReadMessageDate();
|
||||||
|
|
||||||
private:
|
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;
|
MsgId wasMsgId = _showAtMsgId;
|
||||||
History *wasHistory = _history;
|
History *wasHistory = _history;
|
||||||
|
|
||||||
|
@ -3811,9 +3811,9 @@ void HistoryWidget::onVisibleChanged() {
|
||||||
|
|
||||||
void HistoryWidget::onHistoryToEnd() {
|
void HistoryWidget::onHistoryToEnd() {
|
||||||
if (_replyReturn) {
|
if (_replyReturn) {
|
||||||
showPeerHistory(_peer->id, _replyReturn->id);
|
showHistory(_peer->id, _replyReturn->id);
|
||||||
} else if (_peer) {
|
} 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) {
|
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);
|
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;
|
if (bot && (!bot->isUser() || !bot->asUser()->botInfo)) bot = 0;
|
||||||
QString username = bot ? bot->asUser()->username : QString();
|
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)) {
|
if (!replyTo && toSend.indexOf('@') < 2 && !username.isEmpty() && (botStatus == 0 || botStatus == 2)) {
|
||||||
toSend += '@' + username;
|
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);
|
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;
|
if (!bot->isUser() || !bot->asUser()->botInfo) bot = 0;
|
||||||
QString username = bot ? bot->asUser()->username : QString();
|
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)) {
|
if (toInsert.indexOf('@') < 2 && !username.isEmpty() && (botStatus == 0 || botStatus == 2)) {
|
||||||
toInsert += '@' + username;
|
toInsert += '@' + username;
|
||||||
}
|
}
|
||||||
|
@ -4444,16 +4444,7 @@ void HistoryWidget::updateDragAreas() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryWidget::canSendMessages(PeerData *peer) const {
|
bool HistoryWidget::canSendMessages(PeerData *peer) const {
|
||||||
if (peer) {
|
return peer && peer->canWrite();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryWidget::readyToForward() const {
|
bool HistoryWidget::readyToForward() const {
|
||||||
|
@ -4483,7 +4474,7 @@ bool HistoryWidget::isMuteUnmute() const {
|
||||||
|
|
||||||
bool HistoryWidget::updateCmdStartShown() {
|
bool HistoryWidget::updateCmdStartShown() {
|
||||||
bool cmdStartShown = false;
|
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 (!isBotStart() && !isBlocked() && !_keyboard.hasMarkup() && !_keyboard.forceReply()) {
|
||||||
if (!_field.hasSendText()) {
|
if (!_field.hasSendText()) {
|
||||||
cmdStartShown = true;
|
cmdStartShown = true;
|
||||||
|
@ -6347,7 +6338,7 @@ QRect HistoryWidget::historyRect() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::destroyData() {
|
void HistoryWidget::destroyData() {
|
||||||
showPeerHistory(0, 0);
|
showHistory(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList HistoryWidget::getMediasFromMime(const QMimeData *d) {
|
QStringList HistoryWidget::getMediasFromMime(const QMimeData *d) {
|
||||||
|
|
|
@ -516,7 +516,7 @@ public:
|
||||||
|
|
||||||
void fastShowAtEnd(History *h);
|
void fastShowAtEnd(History *h);
|
||||||
void applyDraft(bool parseLinks = true);
|
void applyDraft(bool parseLinks = true);
|
||||||
void showPeerHistory(const PeerId &peer, MsgId showAtMsgId);
|
void showHistory(const PeerId &peer, MsgId showAtMsgId);
|
||||||
void clearDelayedShowAt();
|
void clearDelayedShowAt();
|
||||||
void clearAllLoadRequests();
|
void clearAllLoadRequests();
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ void IntroSignup::mousePressEvent(QMouseEvent *e) {
|
||||||
showError(lang(lng_bad_photo));
|
showError(lang(lng_bad_photo));
|
||||||
return;
|
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 &)));
|
connect(box, SIGNAL(ready(const QImage &)), this, SLOT(onPhotoReady(const QImage &)));
|
||||||
App::wnd()->showLayer(box);
|
App::wnd()->showLayer(box);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2314,7 +2314,7 @@ void MainWidget::showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back)
|
||||||
history.show();
|
history.show();
|
||||||
}
|
}
|
||||||
if (history.peer() && history.peer()->id != peerId) clearBotStartToken(history.peer());
|
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();
|
bool noPeer = (!history.peer() || !history.peer()->id), onlyDialogs = noPeer && !cWideMode();
|
||||||
if (profile || overview) {
|
if (profile || overview) {
|
||||||
|
@ -2487,7 +2487,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
|
||||||
}
|
}
|
||||||
history.animStop();
|
history.animStop();
|
||||||
if (back) clearBotStartToken(history.peer());
|
if (back) clearBotStartToken(history.peer());
|
||||||
history.showPeerHistory(0, 0);
|
history.showHistory(0, 0);
|
||||||
history.hide();
|
history.hide();
|
||||||
if (!cWideMode()) dialogs.hide();
|
if (!cWideMode()) dialogs.hide();
|
||||||
|
|
||||||
|
@ -2533,7 +2533,7 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop)
|
||||||
profile->animShow(animCache, animTopBarCache, back, lastScrollTop);
|
profile->animShow(animCache, animTopBarCache, back, lastScrollTop);
|
||||||
history.animStop();
|
history.animStop();
|
||||||
if (back) clearBotStartToken(history.peer());
|
if (back) clearBotStartToken(history.peer());
|
||||||
history.showPeerHistory(0, 0);
|
history.showHistory(0, 0);
|
||||||
history.hide();
|
history.hide();
|
||||||
|
|
||||||
orderWidgets();
|
orderWidgets();
|
||||||
|
@ -3639,7 +3639,7 @@ void MainWidget::inviteCheckDone(QString hash, const MTPChatInvite &invite) {
|
||||||
switch (invite.type()) {
|
switch (invite.type()) {
|
||||||
case mtpc_chatInvite: {
|
case mtpc_chatInvite: {
|
||||||
const MTPDchatInvite &d(invite.c_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;
|
_inviteHash = hash;
|
||||||
connect(box, SIGNAL(confirmed()), this, SLOT(onInviteImport()));
|
connect(box, SIGNAL(confirmed()), this, SLOT(onInviteImport()));
|
||||||
App::wnd()->showLayer(box);
|
App::wnd()->showLayer(box);
|
||||||
|
@ -3954,7 +3954,7 @@ int32 MainWidget::dlgsWidth() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWidget::~MainWidget() {
|
MainWidget::~MainWidget() {
|
||||||
if (App::main() == this) history.showPeerHistory(0, 0);
|
if (App::main() == this) history.showHistory(0, 0);
|
||||||
|
|
||||||
delete _background;
|
delete _background;
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,9 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||||
if (chatPhoto && chatPhoto->date) {
|
if (chatPhoto && chatPhoto->date) {
|
||||||
_photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer));
|
_photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer));
|
||||||
}
|
}
|
||||||
|
if (_peerChannel->isMegagroup() && _peerChannel->mgInfo->lastParticipants.isEmpty()) {
|
||||||
|
if (App::api()) App::api()->requestLastParticipants(_peerChannel);
|
||||||
|
}
|
||||||
_peerChannel->updateFull();
|
_peerChannel->updateFull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +297,7 @@ void ProfileInner::onUpdatePhoto() {
|
||||||
saveError(lang(lng_bad_photo));
|
saveError(lang(lng_bad_photo));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PhotoCropBox *box = new PhotoCropBox(img, _peer->id);
|
PhotoCropBox *box = new PhotoCropBox(img, _peer);
|
||||||
connect(box, SIGNAL(closed()), this, SLOT(onPhotoUpdateStart()));
|
connect(box, SIGNAL(closed()), this, SLOT(onPhotoUpdateStart()));
|
||||||
App::wnd()->showLayer(box);
|
App::wnd()->showLayer(box);
|
||||||
}
|
}
|
||||||
|
@ -369,9 +372,15 @@ bool ProfileInner::blockFail(const RPCError &error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileInner::onAddParticipant() {
|
void ProfileInner::onAddParticipant() {
|
||||||
if (!_peerChat) return;
|
if (_peerChat) {
|
||||||
|
|
||||||
App::wnd()->showLayer(new ContactsBox(_peerChat, MembersFilterRecent));
|
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() {
|
void ProfileInner::onMigrate() {
|
||||||
|
@ -669,6 +678,28 @@ void ProfileInner::reorderParticipants() {
|
||||||
_onlineText = lng_chat_status_members(lt_count, _participants.size());
|
_onlineText = lng_chat_status_members(lt_count, _participants.size());
|
||||||
}
|
}
|
||||||
loadProfilePhotos(_lastPreload);
|
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 {
|
} else {
|
||||||
_participants.clear();
|
_participants.clear();
|
||||||
if (_peerUser) {
|
if (_peerUser) {
|
||||||
|
@ -744,10 +775,10 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||||
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||||
p.setPen(st::black->p);
|
p.setPen(st::black->p);
|
||||||
p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + st::profileStatusTop + st::linkFont->ascent, '@' + _peerUser->username);
|
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);
|
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.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);
|
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));
|
p.drawText(_left + st::profileHeaderLeft, top + st::profileHeaderTop + st::profileHeaderFont->ascent, lang(lng_profile_actions_section));
|
||||||
top += st::profileHeaderSkip;
|
top += st::profileHeaderSkip;
|
||||||
|
|
||||||
top += _searchInPeer.height();
|
top += _searchInPeer.height() + st::setLittleSkip;
|
||||||
if (_peerUser || _peerChat) {
|
if (_peerUser || _peerChat) {
|
||||||
top += st::setLittleSkip + _clearHistory.height();
|
top += _clearHistory.height() + st::setLittleSkip;
|
||||||
}
|
}
|
||||||
if (_peerUser || _peerChat || (_peerChannel->amIn() && !_amCreator)) {
|
if (_peerUser || _peerChat || (_peerChannel->amIn() && !_amCreator)) {
|
||||||
top += st::setLittleSkip + _deleteConversation.height();
|
top += _deleteConversation.height();
|
||||||
}
|
}
|
||||||
if (_peerUser && peerToUser(_peerUser->id) != MTP::authedId()) {
|
if (_peerUser && peerToUser(_peerUser->id) != MTP::authedId()) {
|
||||||
top += st::setSectionSkip + _blockUser.height();
|
top += st::setSectionSkip + _blockUser.height();
|
||||||
} else if (_peerChannel && _amCreator) {
|
} else if (_peerChannel && _amCreator) {
|
||||||
top += st::setSectionSkip + _deleteChannel.height();
|
top += (_peerChannel->isMegagroup() ? 0 : (st::setSectionSkip - st::setLittleSkip)) + _deleteChannel.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
// participants
|
// 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);
|
QString sectionHeader = lang(_participants.isEmpty() ? lng_profile_loading : lng_profile_participants_section);
|
||||||
p.setFont(st::profileHeaderFont->f);
|
p.setFont(st::profileHeaderFont->f);
|
||||||
p.setPen(st::profileHeaderColor->p);
|
p.setPen(st::profileHeaderColor->p);
|
||||||
|
@ -905,10 +936,12 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
if (_amCreator) {
|
if (_amCreator) {
|
||||||
data->cankick = (user != App::self());
|
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);
|
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 {
|
} 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);
|
p.setPen(st::profileListNameColor->p);
|
||||||
|
@ -971,21 +1004,20 @@ void ProfileInner::updateSelected() {
|
||||||
update(QRect(_left, _aboutTop, _width, _aboutHeight));
|
update(QRect(_left, _aboutTop, _width, _aboutHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 partfrom = _searchInPeer.y() + _searchInPeer.height();
|
int32 participantsTop = 0;
|
||||||
if (_peerUser || _peerChat) {
|
if (_peerChannel && _amCreator) {
|
||||||
partfrom = _clearHistory.y() + _clearHistory.height();
|
participantsTop = _deleteChannel.y() + _deleteChannel.height();
|
||||||
|
} else {
|
||||||
|
participantsTop = _deleteConversation.y() + _deleteConversation.height();
|
||||||
}
|
}
|
||||||
if (_peerUser || _peerChat || (_peerChannel->amIn() && !_amCreator)) {
|
participantsTop += st::profileHeaderSkip;
|
||||||
partfrom = _deleteConversation.y() + _deleteConversation.height();
|
int32 newSelected = (lp.x() >= _left - st::profileListPadding.width() && lp.x() < _left + _width + st::profileListPadding.width() && lp.y() >= participantsTop) ? (lp.y() - participantsTop) / _pHeight : -1;
|
||||||
}
|
|
||||||
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;
|
|
||||||
|
|
||||||
UserData *newKickOver = 0;
|
UserData *newKickOver = 0;
|
||||||
if (newSelected >= 0 && newSelected < _participants.size()) {
|
if (newSelected >= 0 && newSelected < _participants.size()) {
|
||||||
ParticipantData *data = _participantsData[newSelected];
|
ParticipantData *data = _participantsData[newSelected];
|
||||||
if (data && data->cankick) {
|
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)) {
|
if ((lp.x() >= _left + _width - _kickWidth) && (lp.x() < _left + _width) && (lp.y() >= top) && (lp.y() < top + st::linkFont->height)) {
|
||||||
newKickOver = _participants[newSelected];
|
newKickOver = _participants[newSelected];
|
||||||
}
|
}
|
||||||
|
@ -1056,9 +1088,12 @@ void ProfileInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileInner::onKickConfirm() {
|
void ProfileInner::onKickConfirm() {
|
||||||
if (!_peerChat) return;
|
if (_peerChat) {
|
||||||
|
|
||||||
App::main()->kickParticipant(_peerChat, _kickConfirm);
|
App::main()->kickParticipant(_peerChat, _kickConfirm);
|
||||||
|
} else if (_peerChannel) {
|
||||||
|
App::wnd()->hideLayer();
|
||||||
|
App::api()->kickParticipant(_peerChannel, _kickConfirm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileInner::keyPressEvent(QKeyEvent *e) {
|
void ProfileInner::keyPressEvent(QKeyEvent *e) {
|
||||||
|
@ -1299,12 +1334,12 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||||
top += st::setSectionSkip;
|
top += st::setSectionSkip;
|
||||||
_blockUser.move(_left, top); top += _blockUser.height();
|
_blockUser.move(_left, top); top += _blockUser.height();
|
||||||
} else if (_peerChannel && _amCreator) {
|
} else if (_peerChannel && _amCreator) {
|
||||||
top += st::setSectionSkip;
|
top += (_peerChannel->isMegagroup() ? 0 : (st::setSectionSkip - st::setLittleSkip));
|
||||||
_deleteChannel.move(_left, top); top += _deleteChannel.height();
|
_deleteChannel.move(_left, top); top += _deleteChannel.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
// participants
|
// participants
|
||||||
if (_peerChat && _peerChat->amIn()) {
|
if ((_peerChat && _peerChat->amIn()) || (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn())) {
|
||||||
top += st::profileHeaderSkip;
|
top += st::profileHeaderSkip;
|
||||||
if (!_participants.isEmpty()) {
|
if (!_participants.isEmpty()) {
|
||||||
int32 fullCnt = _participants.size();
|
int32 fullCnt = _participants.size();
|
||||||
|
@ -1427,6 +1462,13 @@ int32 ProfileInner::countMinHeight() {
|
||||||
} else {
|
} else {
|
||||||
h = _searchInPeer.y() + _searchInPeer.height() + st::profileHeaderSkip;
|
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;
|
return h;
|
||||||
}
|
}
|
||||||
|
@ -1555,7 +1597,11 @@ void ProfileInner::showAll() {
|
||||||
_invitationLink.hide();
|
_invitationLink.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_peerChannel->count < cMaxMegaGroupCount() && _peerChannel->isMegagroup() && (_amCreator || _peerChannel->amEditor())) {
|
||||||
|
_addParticipant.show();
|
||||||
|
} else {
|
||||||
_addParticipant.hide();
|
_addParticipant.hide();
|
||||||
|
}
|
||||||
_blockUser.hide();
|
_blockUser.hide();
|
||||||
if (_amCreator) {
|
if (_amCreator) {
|
||||||
_deleteChannel.show();
|
_deleteChannel.show();
|
||||||
|
@ -1572,7 +1618,7 @@ void ProfileInner::showAll() {
|
||||||
} else {
|
} else {
|
||||||
_admins.hide();
|
_admins.hide();
|
||||||
}
|
}
|
||||||
if (_peerChannel->canViewParticipants()) {
|
if (_peerChannel->canViewParticipants() && !_peerChannel->isMegagroup()) {
|
||||||
_members.show();
|
_members.show();
|
||||||
} else {
|
} else {
|
||||||
_members.hide();
|
_members.hide();
|
||||||
|
|
|
@ -1169,7 +1169,7 @@ void SettingsInner::onUpdatePhoto() {
|
||||||
saveError(lang(lng_bad_photo));
|
saveError(lang(lng_bad_photo));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PhotoCropBox *box = new PhotoCropBox(img, self()->id);
|
PhotoCropBox *box = new PhotoCropBox(img, self());
|
||||||
connect(box, SIGNAL(closed()), this, SLOT(onPhotoUpdateStart()));
|
connect(box, SIGNAL(closed()), this, SLOT(onPhotoUpdateStart()));
|
||||||
App::wnd()->showLayer(box);
|
App::wnd()->showLayer(box);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1026,6 +1026,7 @@ void CommentsLink::onClick(Qt::MouseButton button) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
MsgId clientMsgId() {
|
MsgId clientMsgId() {
|
||||||
static MsgId current = -2000000000;
|
static MsgId currentClientMsgId = StartClientMsgId;
|
||||||
return ++current;
|
Q_ASSERT(currentClientMsgId < EndClientMsgId);
|
||||||
|
return currentClientMsgId++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,8 +142,14 @@ inline bool operator<(const FullMsgId &a, const FullMsgId &b) {
|
||||||
return a.channel < b.channel;
|
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 ShowAtTheEndMsgId = -0x40000000;
|
||||||
static const MsgId SwitchAtTopMsgId = -0x3FFFFFFF;
|
static const MsgId SwitchAtTopMsgId = -0x3FFFFFFF;
|
||||||
|
static const MsgId ServerMaxMsgId = 0x3FFFFFFF;
|
||||||
static const MsgId ShowAtUnreadMsgId = 0;
|
static const MsgId ShowAtUnreadMsgId = 0;
|
||||||
|
|
||||||
struct NotifySettings {
|
struct NotifySettings {
|
||||||
|
@ -212,6 +218,7 @@ public:
|
||||||
}
|
}
|
||||||
bool isVerified() const;
|
bool isVerified() const;
|
||||||
bool isMegagroup() const;
|
bool isMegagroup() const;
|
||||||
|
bool canWrite() const;
|
||||||
UserData *asUser();
|
UserData *asUser();
|
||||||
const UserData *asUser() const;
|
const UserData *asUser() const;
|
||||||
ChatData *asChat();
|
ChatData *asChat();
|
||||||
|
@ -350,6 +357,9 @@ public:
|
||||||
bool isVerified() const {
|
bool isVerified() const {
|
||||||
return flags & MTPDuser::flag_verified;
|
return flags & MTPDuser::flag_verified;
|
||||||
}
|
}
|
||||||
|
bool canWrite() const {
|
||||||
|
return access != UserNoAccess;
|
||||||
|
}
|
||||||
|
|
||||||
MTPInputUser inputUser;
|
MTPInputUser inputUser;
|
||||||
|
|
||||||
|
@ -373,7 +383,7 @@ public:
|
||||||
class ChatData : public PeerData {
|
class ChatData : public PeerData {
|
||||||
public:
|
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 setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
||||||
void invalidateParticipants() {
|
void invalidateParticipants() {
|
||||||
|
@ -389,6 +399,8 @@ public:
|
||||||
|
|
||||||
MTPint inputChat;
|
MTPint inputChat;
|
||||||
|
|
||||||
|
ChannelData *migrateTo;
|
||||||
|
|
||||||
int32 count;
|
int32 count;
|
||||||
int32 date;
|
int32 date;
|
||||||
int32 version;
|
int32 version;
|
||||||
|
@ -504,19 +516,24 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MegagroupInfo {
|
struct MegagroupInfo {
|
||||||
MegagroupInfo() : botStatus(-1) {
|
MegagroupInfo() : botStatus(-1), migrateFrom(0) {
|
||||||
}
|
}
|
||||||
typedef QList<UserData*> LastParticipants;
|
typedef QList<UserData*> LastParticipants;
|
||||||
LastParticipants lastParticipants;
|
LastParticipants lastParticipants;
|
||||||
|
typedef QMap<UserData*, bool> LastAdmins;
|
||||||
|
LastAdmins lastAdmins;
|
||||||
typedef QMap<PeerData*, bool> MarkupSenders;
|
typedef QMap<PeerData*, bool> MarkupSenders;
|
||||||
MarkupSenders 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
|
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
||||||
|
ChatData *migrateFrom;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ChannelData : public PeerData {
|
class ChannelData : public PeerData {
|
||||||
public:
|
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());
|
setName(QString(), QString());
|
||||||
}
|
}
|
||||||
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
||||||
|
@ -566,6 +583,9 @@ public:
|
||||||
bool canPublish() const {
|
bool canPublish() const {
|
||||||
return amCreator() || amEditor();
|
return amCreator() || amEditor();
|
||||||
}
|
}
|
||||||
|
bool canWrite() const {
|
||||||
|
return amIn() && (canPublish() || !isBroadcast());
|
||||||
|
}
|
||||||
bool canViewParticipants() const {
|
bool canViewParticipants() const {
|
||||||
return flagsFull & MTPDchannelFull::flag_can_view_participants;
|
return flagsFull & MTPDchannelFull::flag_can_view_participants;
|
||||||
}
|
}
|
||||||
|
@ -574,7 +594,6 @@ public:
|
||||||
return flags & MTPDchannel::flag_verified;
|
return flags & MTPDchannel::flag_verified;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
|
||||||
// ImagePtr photoFull;
|
// ImagePtr photoFull;
|
||||||
QString invitationUrl;
|
QString invitationUrl;
|
||||||
|
|
||||||
|
@ -655,6 +674,9 @@ inline bool PeerData::isVerified() const {
|
||||||
inline bool PeerData::isMegagroup() const {
|
inline bool PeerData::isMegagroup() const {
|
||||||
return isChannel() ? asChannel()->isMegagroup() : false;
|
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) {
|
inline int32 newMessageFlags(PeerData *p) {
|
||||||
return p->isSelf() ? 0 : (((p->isChat() || (p->isUser() && !p->asUser()->botInfo)) ? MTPDmessage::flag_unread : 0) | MTPDmessage::flag_out);
|
return p->isSelf() ? 0 : (((p->isChat() || (p->isUser() && !p->asUser()->botInfo)) ? MTPDmessage::flag_unread : 0) | MTPDmessage::flag_out);
|
||||||
|
|
Loading…
Reference in New Issue