added channels scheme, made Channel peers and composite ChannelId,MsgId message ids

This commit is contained in:
John Preston 2015-09-03 13:48:40 +03:00
parent 42d297f192
commit 04e1da81f3
38 changed files with 5487 additions and 3141 deletions

View file

@ -38,7 +38,7 @@ void ApiWrap::init() {
void ApiWrap::itemRemoved(HistoryItem *item) {
if (HistoryReply *reply = item->toHistoryReply()) {
ReplyToRequests::iterator i = _replyToRequests.find(reply->replyToId());
ReplyToRequests::iterator i = _replyToRequests.find(FullMsgId(reply->channelId(), reply->replyToId()));
if (i != _replyToRequests.cend()) {
for (QList<HistoryReply*>::iterator j = i->replies.begin(); j != i->replies.end();) {
if ((*j) == reply) {
@ -56,7 +56,7 @@ void ApiWrap::itemRemoved(HistoryItem *item) {
void ApiWrap::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
if (HistoryReply *reply = oldItem->toHistoryReply()) {
ReplyToRequests::iterator i = _replyToRequests.find(reply->replyToId());
ReplyToRequests::iterator i = _replyToRequests.find(FullMsgId(reply->channelId(), reply->replyToId()));
if (i != _replyToRequests.cend()) {
for (QList<HistoryReply*>::iterator j = i->replies.begin(); j != i->replies.end();) {
if ((*j) == reply) {
@ -77,7 +77,7 @@ void ApiWrap::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
}
}
void ApiWrap::requestReplyTo(HistoryReply *reply, MsgId to) {
void ApiWrap::requestReplyTo(HistoryReply *reply, const FullMsgId &to) {
ReplyToRequest &req(_replyToRequests[to]);
req.replies.append(reply);
if (!req.req) _replyToTimer.start(1);
@ -90,7 +90,7 @@ void ApiWrap::resolveReplyTo() {
ids.reserve(_replyToRequests.size());
for (ReplyToRequests::const_iterator i = _replyToRequests.cbegin(), e = _replyToRequests.cend(); i != e; ++i) {
if (!i.value().req) {
ids.push_back(MTP_int(i.key()));
ids.push_back(MTP_int(i.key().msg)); // CHANNELS_TODO
}
}
if (!ids.isEmpty()) {
@ -134,56 +134,88 @@ void ApiWrap::gotReplyTo(const MTPmessages_Messages &msgs, mtpRequestId req) {
void ApiWrap::requestFullPeer(PeerData *peer) {
if (!peer || _fullPeerRequests.contains(peer)) return;
mtpRequestId req;
if (peer->chat) {
req = MTP::send(MTPmessages_GetFullChat(MTP_int(App::chatFromPeer(peer->id))), rpcDone(&ApiWrap::gotChatFull, peer), rpcFail(&ApiWrap::gotPeerFullFailed, peer));
} else {
mtpRequestId req = 0;
if (peer->isUser()) {
req = MTP::send(MTPusers_GetFullUser(peer->asUser()->inputUser), rpcDone(&ApiWrap::gotUserFull, peer), rpcFail(&ApiWrap::gotPeerFullFailed, peer));
} else if (peer->isChat()) {
req = MTP::send(MTPmessages_GetFullChat(peer->asChat()->inputChat), rpcDone(&ApiWrap::gotChatFull, peer), rpcFail(&ApiWrap::gotPeerFullFailed, peer));
} else if (peer->isChannel()) {
req = MTP::send(MTPmessages_GetFullChat(peer->asChannel()->inputChat), rpcDone(&ApiWrap::gotChatFull, peer), rpcFail(&ApiWrap::gotPeerFullFailed, peer));
}
_fullPeerRequests.insert(peer, req);
if (req) _fullPeerRequests.insert(peer, req);
}
void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) {
const MTPDmessages_chatFull &d(result.c_messages_chatFull());
const MTPDchatFull &f(d.vfull_chat.c_chatFull());
const QVector<MTPChat> &vc(d.vchats.c_vector().v);
bool badVersion = (!vc.isEmpty() && vc.at(0).type() == mtpc_chat && vc.at(0).c_chat().vversion.v < peer->asChat()->version);
bool badVersion = false;
if (peer->isChat()) {
badVersion = (!vc.isEmpty() && vc.at(0).type() == mtpc_chat && vc.at(0).c_chat().vversion.v < peer->asChat()->version);
} else if (peer->isChannel()) {
badVersion = (!vc.isEmpty() && vc.at(0).type() == mtpc_channel && vc.at(0).c_channel().vversion.v < peer->asChannel()->version);
}
App::feedUsers(d.vusers, false);
App::feedChats(d.vchats, false);
App::feedParticipants(f.vparticipants, false, false);
const QVector<MTPBotInfo> &v(f.vbot_info.c_vector().v);
for (QVector<MTPBotInfo>::const_iterator i = v.cbegin(), e = v.cend(); i < e; ++i) {
switch (i->type()) {
case mtpc_botInfo: {
const MTPDbotInfo &b(i->c_botInfo());
UserData *user = App::userLoaded(b.vuser_id.v);
if (user) {
user->setBotInfo(*i);
App::clearPeerUpdated(user);
emit fullPeerUpdated(user);
}
} break;
if (peer->isChat()) {
if (d.vfull_chat.type() != mtpc_chatFull) {
LOG(("MTP Error: bad type in gotChatFull for chat: %1").arg(d.vfull_chat.type()));
return;
}
}
PhotoData *photo = App::feedPhoto(f.vchat_photo);
ChatData *chat = peer->asChat();
if (chat) {
const MTPDchatFull &f(d.vfull_chat.c_chatFull());
App::feedParticipants(f.vparticipants, false, false);
const QVector<MTPBotInfo> &v(f.vbot_info.c_vector().v);
for (QVector<MTPBotInfo>::const_iterator i = v.cbegin(), e = v.cend(); i < e; ++i) {
switch (i->type()) {
case mtpc_botInfo: {
const MTPDbotInfo &b(i->c_botInfo());
UserData *user = App::userLoaded(b.vuser_id.v);
if (user) {
user->setBotInfo(*i);
App::clearPeerUpdated(user);
emit fullPeerUpdated(user);
}
} break;
}
}
PhotoData *photo = App::feedPhoto(f.vchat_photo);
ChatData *chat = peer->asChat();
if (photo) {
chat->photoId = photo->id;
photo->chat = chat;
photo->peer = chat;
} else {
chat->photoId = 0;
}
chat->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString();
}
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
} else if (peer->isChannel()) {
if (d.vfull_chat.type() != mtpc_channelFull) {
LOG(("MTP Error: bad type in gotChatFull for channel: %1").arg(d.vfull_chat.type()));
return;
}
const MTPDchannelFull &f(d.vfull_chat.c_channelFull());
PhotoData *photo = App::feedPhoto(f.vchat_photo);
ChannelData *channel = peer->asChannel();
if (photo) {
channel->photoId = photo->id;
photo->peer = channel;
} else {
channel->photoId = 0;
}
channel->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString();
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
}
_fullPeerRequests.remove(peer);
if (badVersion) {
peer->asChat()->version = vc.at(0).c_chat().vversion.v;
if (peer->isChat()) {
peer->asChat()->version = vc.at(0).c_chat().vversion.v;
} else if (peer->isChannel()) {
peer->asChannel()->version = vc.at(0).c_channel().vversion.v;
}
requestPeer(peer);
}
App::clearPeerUpdated(peer);
@ -195,7 +227,7 @@ void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result) {
const MTPDuserFull &d(result.c_userFull());
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser), false);
App::feedPhoto(d.vprofile_photo);
App::feedUserLink(MTP_int(App::userFromPeer(peer->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link, false);
App::feedUserLink(MTP_int(peerToUser(peer->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link, false);
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vnotify_settings);
peer->asUser()->setBotInfo(d.vbot_info);
@ -217,29 +249,33 @@ bool ApiWrap::gotPeerFullFailed(PeerData *peer, const RPCError &error) {
void ApiWrap::requestPeer(PeerData *peer) {
if (!peer || _fullPeerRequests.contains(peer) || _peerRequests.contains(peer)) return;
mtpRequestId req;
if (peer->chat) {
req = MTP::send(MTPmessages_GetChats(MTP_vector<MTPint>(1, MTP_int(App::chatFromPeer(peer->id)))), rpcDone(&ApiWrap::gotChat, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
} else {
mtpRequestId req = 0;
if (peer->isUser()) {
req = MTP::send(MTPusers_GetUsers(MTP_vector<MTPInputUser>(1, peer->asUser()->inputUser)), rpcDone(&ApiWrap::gotUser, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
} else if (peer->isChat()) {
req = MTP::send(MTPmessages_GetChats(MTP_vector<MTPInputChat>(1, peer->asChat()->inputChat)), rpcDone(&ApiWrap::gotChat, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
} else if (peer->isChannel()) {
req = MTP::send(MTPmessages_GetChats(MTP_vector<MTPInputChat>(1, peer->asChannel()->inputChat)), rpcDone(&ApiWrap::gotChat, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
}
_peerRequests.insert(peer, req);
if (req) _peerRequests.insert(peer, req);
}
void ApiWrap::requestPeers(const QList<PeerData*> &peers) {
QVector<MTPint> chats;
QVector<MTPInputChat> chats;
QVector<MTPInputUser> users;
chats.reserve(peers.size());
users.reserve(peers.size());
for (QList<PeerData*>::const_iterator i = peers.cbegin(), e = peers.cend(); i != e; ++i) {
if (!*i || _fullPeerRequests.contains(*i) || _peerRequests.contains(*i)) continue;
if ((*i)->chat) {
chats.push_back(MTP_int(App::chatFromPeer((*i)->id)));
} else {
if ((*i)->isUser()) {
users.push_back((*i)->asUser()->inputUser);
} else if ((*i)->isChat()) {
chats.push_back((*i)->asChat()->inputChat);
} else if ((*i)->isChannel()) {
chats.push_back((*i)->asChannel()->inputChat);
}
}
if (!chats.isEmpty()) MTP::send(MTPmessages_GetChats(MTP_vector<MTPint>(chats)), rpcDone(&ApiWrap::gotChats));
if (!chats.isEmpty()) MTP::send(MTPmessages_GetChats(MTP_vector<MTPInputChat>(chats)), rpcDone(&ApiWrap::gotChats));
if (!users.isEmpty()) MTP::send(MTPusers_GetUsers(MTP_vector<MTPInputUser>(users)), rpcDone(&ApiWrap::gotUsers));
}
@ -248,11 +284,20 @@ void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) {
if (result.type() == mtpc_messages_chats) {
const QVector<MTPChat> &v(result.c_messages_chats().vchats.c_vector().v);
bool badVersion = (!v.isEmpty() && v.at(0).type() == mtpc_chat && v.at(0).c_chat().vversion.v < peer->asChat()->version);
ChatData *chat = App::feedChats(result.c_messages_chats().vchats);
bool badVersion = false;
if (peer->isChat()) {
badVersion = (!v.isEmpty() && v.at(0).type() == mtpc_chat && v.at(0).c_chat().vversion.v < peer->asChat()->version);
} else if (peer->isChannel()) {
badVersion = (!v.isEmpty() && v.at(0).type() == mtpc_channel && v.at(0).c_chat().vversion.v < peer->asChannel()->version);
}
PeerData *chat = App::feedChats(result.c_messages_chats().vchats);
if (chat == peer) {
if (badVersion) {
peer->asChat()->version = v.at(0).c_chat().vversion.v;
if (peer->isChat()) {
peer->asChat()->version = v.at(0).c_chat().vversion.v;
} else if (peer->isChannel()) {
peer->asChannel()->version = v.at(0).c_chat().vversion.v;
}
requestPeer(peer);
}
}

View file

@ -28,7 +28,7 @@ public:
void itemRemoved(HistoryItem *item);
void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem);
void requestReplyTo(HistoryReply *reply, MsgId to);
void requestReplyTo(HistoryReply *reply, const FullMsgId &to);
void requestFullPeer(PeerData *peer);
void requestPeer(PeerData *peer);
@ -61,7 +61,7 @@ private:
mtpRequestId req;
QList<HistoryReply*> replies;
};
typedef QMap<MsgId, ReplyToRequest> ReplyToRequests;
typedef QMap<FullMsgId, ReplyToRequest> ReplyToRequests;
ReplyToRequests _replyToRequests;
SingleTimer _replyToTimer;

View file

@ -62,6 +62,9 @@ namespace {
typedef QMap<MsgId, ReplyMarkup> ReplyMarkups;
ReplyMarkups replyMarkups;
ReplyMarkup zeroMarkup(MTPDreplyKeyboardMarkup_flag_ZERO);
typedef QMap<ChannelId, ReplyMarkups> ChannelReplyMarkups;
ChannelReplyMarkups channelReplyMarkups;
VideoItems videoItems;
AudioItems audioItems;
@ -77,13 +80,14 @@ namespace {
typedef QHash<MsgId, HistoryItem*> MsgsData;
MsgsData msgsData;
int32 maxMsgId = 0;
typedef QMap<ChannelId, MsgsData> ChannelMsgsData;
ChannelMsgsData channelMsgsData;
typedef QMap<uint64, MsgId> RandomData;
typedef QMap<uint64, FullMsgId> RandomData;
RandomData randomData;
typedef QMap<uint64, QString> SentTextData;
SentTextData sentTextData;
typedef QMap<uint64, QPair<PeerId, QString> > SentData;
SentData sentData;
HistoryItem *hoveredItem = 0, *pressedItem = 0, *hoveredLinkItem = 0, *pressedLinkItem = 0, *contextItem = 0, *mousedItem = 0;
@ -213,33 +217,6 @@ namespace App {
}
}
PeerId peerFromMTP(const MTPPeer &peer_id) {
switch (peer_id.type()) {
case mtpc_peerChat: return peerFromChat(peer_id.c_peerChat().vchat_id);
case mtpc_peerUser: return peerFromUser(peer_id.c_peerUser().vuser_id);
}
return 0;
}
PeerId peerFromChat(int32 chat_id) {
return 0x100000000L | uint64(uint32(chat_id));
}
PeerId peerFromUser(int32 user_id) {
return uint64(uint32(user_id));
}
MTPpeer peerToMTP(const PeerId &peer_id) {
return (peer_id & 0x100000000L) ? MTP_peerChat(MTP_int(int32(peer_id & 0xFFFFFFFFL))) : MTP_peerUser(MTP_int(int32(peer_id & 0xFFFFFFFFL)));
}
int32 userFromPeer(const PeerId &peer_id) {
return (peer_id & 0x100000000L) ? 0 : int32(peer_id & 0xFFFFFFFFL);
}
int32 chatFromPeer(const PeerId &peer_id) {
return (peer_id & 0x100000000L) ? int32(peer_id & 0xFFFFFFFFL) : 0;
}
int32 onlineForSort(UserData *user, int32 now) {
if (isServiceUser(user->id) || user->botInfo) {
return -1;
@ -469,12 +446,12 @@ namespace App {
case mtpc_userStatusOnline: data->onlineTill = status->c_userStatusOnline().vexpires.v; break;
}
if (data->contact < 0 && !data->phone.isEmpty() && int32(data->id & 0xFFFFFFFF) != MTP::authedId()) {
if (data->contact < 0 && !data->phone.isEmpty() && peerToUser(data->id) != MTP::authedId()) {
data->contact = 0;
}
if (App::main()) {
if (data->contact > 0 && !wasContact) {
App::main()->addNewContact(data->id & 0xFFFFFFFF, false);
App::main()->addNewContact(peerToUser(data->id), false);
} else if (wasContact && data->contact <= 0) {
App::main()->removeContact(data);
}
@ -490,8 +467,8 @@ namespace App {
return data;
}
ChatData *feedChats(const MTPVector<MTPChat> &chats, bool emitPeerUpdated) {
ChatData *data = 0;
PeerData *feedChats(const MTPVector<MTPChat> &chats, bool emitPeerUpdated) {
PeerData *data = 0;
const QVector<MTPChat> &v(chats.c_vector().v);
for (QVector<MTPChat>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
const MTPchat &chat(*i);
@ -502,32 +479,53 @@ namespace App {
const MTPDchat &d(chat.c_chat());
title = qs(d.vtitle);
PeerId peer(peerFromChat(d.vid.v));
data = App::chat(peer);
data = App::chat(peerFromChat(d.vid.v));
data->input = MTP_inputPeerChat(d.vid);
data->setPhoto(d.vphoto);
data->date = d.vdate.v;
data->count = d.vparticipants_count.v;
data->left = d.vleft.v;
data->forbidden = false;
if (data->version < d.vversion.v) {
data->version = d.vversion.v;
data->participants = ChatData::Participants();
data->botStatus = 0;
ChatData *cdata = data->asChat();
cdata->setPhoto(d.vphoto);
cdata->date = d.vdate.v;
cdata->count = d.vparticipants_count.v;
cdata->left = d.vleft.v;
cdata->forbidden = false;
if (cdata->version < d.vversion.v) {
cdata->version = d.vversion.v;
cdata->participants = ChatData::Participants();
cdata->botStatus = 0;
}
} break;
case mtpc_chatForbidden: {
const MTPDchatForbidden &d(chat.c_chatForbidden());
title = qs(d.vtitle);
PeerId peer(peerFromChat(d.vid.v));
data = App::chat(peer);
data = App::chat(peerFromChat(d.vid.v));
data->input = MTP_inputPeerChat(d.vid);
data->setPhoto(MTP_chatPhotoEmpty());
data->date = 0;
data->count = -1;
data->left = false;
data->forbidden = true;
ChatData *cdata = data->asChat();
cdata->setPhoto(MTP_chatPhotoEmpty());
cdata->date = 0;
cdata->count = -1;
cdata->left = false;
cdata->forbidden = true;
} break;
case mtpc_channel: {
const MTPDchannel &d(chat.c_channel());
title = qs(d.vtitle);
PeerId peer(peerFromChannel(d.vid.v));
data = App::channel(peer);
data->input = MTP_inputPeerChannel(d.vid, d.vaccess_hash);
ChannelData *cdata = data->asChannel();
cdata->inputChat = MTP_inputChannel(d.vid, d.vaccess_hash);
cdata->access = d.vaccess_hash.v;
cdata->setPhoto(d.vphoto);
cdata->date = d.vdate.v;
cdata->left = false;
cdata->forbidden = false;
if (cdata->version < d.vversion.v) {
cdata->version = d.vversion.v;
}
} break;
}
if (!data) continue;
@ -703,7 +701,11 @@ namespace App {
}
void checkEntitiesUpdate(const MTPDmessage &m) {
if (HistoryItem *existing = App::histItemById(m.vid.v)) {
PeerId peerId = peerFromMTP(m.vto_id);
if (m.has_from_id() && peerToUser(peerId) == MTP::authedId()) {
peerId = peerFromUser(m.vfrom_id);
}
if (HistoryItem *existing = App::histItemById(peerToChannel(peerId), m.vid.v)) {
bool hasLinks = m.has_entities() && !m.ventities.c_vector().v.isEmpty();
if ((hasLinks && !existing->hasTextLinks()) || (!hasLinks && existing->textHasLinks())) {
existing->setText(qs(m.vmessage), m.has_entities() ? linksFromMTP(m.ventities.c_vector().v) : LinksInText());
@ -738,10 +740,6 @@ namespace App {
}
}
int32 maxMsgId() {
return ::maxMsgId;
}
ImagePtr image(const MTPPhotoSize &size) {
switch (size.type()) {
case mtpc_photoSize: {
@ -789,38 +787,45 @@ namespace App {
}
return StorageImageLocation();
}
void feedWereRead(const QVector<MTPint> &msgsIds) {
for (QVector<MTPint>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
MsgsData::const_iterator j = msgsData.constFind(i->v);
if (j != msgsData.cend()) {
(*j)->markRead();
}
}
}
void feedInboxRead(const PeerId &peer, int32 upTo) {
void feedInboxRead(const PeerId &peer, MsgId upTo) {
History *h = App::historyLoaded(peer);
if (h) {
h->inboxRead(upTo);
}
}
void feedOutboxRead(const PeerId &peer, int32 upTo) {
void feedOutboxRead(const PeerId &peer, MsgId upTo) {
History *h = App::historyLoaded(peer);
if (h) {
h->outboxRead(upTo);
if (!h->peer->chat) {
if (h->peer->isUser()) {
h->peer->asUser()->madeAction();
}
}
}
void feedWereDeleted(const QVector<MTPint> &msgsIds) {
inline MsgsData *fetchMsgsData(ChannelId channelId, bool insert = true) {
if (channelId == NoChannel) return &msgsData;
ChannelMsgsData::iterator i = channelMsgsData.find(channelId);
if (i == channelMsgsData.cend()) {
if (insert) {
i = channelMsgsData.insert(channelId, MsgsData());
} else {
return 0;
}
}
return &(*i);
}
void feedWereDeleted(ChannelId channelId, const QVector<MTPint> &msgsIds) {
bool resized = false;
MsgsData *data = fetchMsgsData(channelId, false);
if (!data) return;
for (QVector<MTPint>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
MsgsData::const_iterator j = msgsData.constFind(i->v);
if (j != msgsData.cend()) {
MsgsData::const_iterator j = data->constFind(i->v);
if (j != data->cend()) {
History *h = (*j)->history();
(*j)->destroy();
if (App::main() && h->peer == App::main()->peer()) {
@ -875,10 +880,10 @@ namespace App {
}
if (user->contact > 0) {
if (!wasContact) {
App::main()->addNewContact(App::userFromPeer(user->id), false);
App::main()->addNewContact(peerToUser(user->id), false);
}
} else {
if (user->contact < 0 && !user->phone.isEmpty() && App::userFromPeer(user->id) != MTP::authedId()) {
if (user->contact < 0 && !user->phone.isEmpty() && peerToUser(user->id) != MTP::authedId()) {
user->contact = 0;
}
if (wasContact) {
@ -1098,50 +1103,73 @@ namespace App {
return 0;
}
UserData *userLoaded(const PeerId &user) {
PeerData *peer = peerLoaded(user);
return (peer && peer->loaded) ? peer->asUser() : 0;
}
ChatData *chatLoaded(const PeerId &chat) {
PeerData *peer = peerLoaded(chat);
return (peer && peer->loaded) ? peer->asChat() : 0;
}
PeerData *peerLoaded(const PeerId &peer) {
PeersData::const_iterator i = peersData.constFind(peer);
return (i != peersData.cend()) ? i.value() : 0;
}
UserData *userLoaded(int32 user) {
return userLoaded(App::peerFromUser(user));
UserData *userLoaded(const PeerId &id) {
PeerData *peer = peerLoaded(id);
return (peer && peer->loaded) ? peer->asUser() : 0;
}
ChatData *chatLoaded(int32 chat) {
return chatLoaded(App::peerFromChat(chat));
ChatData *chatLoaded(const PeerId &id) {
PeerData *peer = peerLoaded(id);
return (peer && peer->loaded) ? peer->asChat() : 0;
}
ChannelData *channelLoaded(const PeerId &id) {
PeerData *peer = peerLoaded(id);
return (peer && peer->loaded) ? peer->asChannel() : 0;
}
UserData *userLoaded(int32 user_id) {
return userLoaded(peerFromUser(user_id));
}
ChatData *chatLoaded(int32 chat_id) {
return chatLoaded(peerFromChat(chat_id));
}
ChannelData *channelLoaded(int32 channel_id) {
return channelLoaded(peerFromChannel(channel_id));
}
UserData *curUser() {
return user(MTP::authedId());
}
PeerData *peer(const PeerId &peer) {
PeersData::const_iterator i = peersData.constFind(peer);
PeerData *peer(const PeerId &id) {
PeersData::const_iterator i = peersData.constFind(id);
if (i == peersData.cend()) {
PeerData *newData = App::isChat(peer) ? (PeerData*)(new ChatData(peer)) : (PeerData*)(new UserData(peer));
PeerData *newData = 0;
if (peerIsUser(id)) {
newData = new UserData(id);
} else if (peerIsChat(id)) {
newData = new ChatData(id);
} else if (peerIsChannel(id)) {
newData = new ChannelData(id);
}
if (!newData) return 0;
newData->input = MTPinputPeer(MTP_inputPeerEmpty());
i = peersData.insert(peer, newData);
i = peersData.insert(id, newData);
}
return i.value();
}
UserData *user(const PeerId &peer) {
PeerData *d = App::peer(peer);
return d->asUser();
UserData *user(const PeerId &id) {
return peer(id)->asUser();
}
UserData *user(int32 user) {
return App::peer(App::peerFromUser(user))->asUser();
ChatData *chat(const PeerId &id) {
return peer(id)->asChat();
}
ChannelData *channel(const PeerId &id) {
return peer(id)->asChannel();
}
UserData *user(int32 user_id) {
return user(peerFromUser(user_id));
}
ChatData *chat(int32 chat_id) {
return chat(peerFromChat(chat_id));
}
ChannelData *channel(int32 channel_id) {
return channel(peerFromChannel(channel_id));
}
UserData *self() {
@ -1150,22 +1178,13 @@ namespace App {
UserData *userByName(const QString &username) {
for (PeersData::const_iterator i = peersData.cbegin(), e = peersData.cend(); i != e; ++i) {
if (!i.value()->chat && !i.value()->asUser()->username.compare(username.trimmed(), Qt::CaseInsensitive)) {
if (i.value()->isUser() && !i.value()->asUser()->username.compare(username.trimmed(), Qt::CaseInsensitive)) {
return i.value()->asUser();
}
}
return 0;
}
ChatData *chat(const PeerId &peer) {
PeerData *d = App::peer(peer);
return d->asChat();
}
ChatData *chat(int32 chat) {
return App::peer(App::peerFromChat(chat))->asChat();
}
PhotoData *photo(const PhotoId &photo) {
PhotosData::const_iterator i = photosData.constFind(photo);
if (i == photosData.cend()) {
@ -1575,9 +1594,12 @@ namespace App {
return (i == ::histories.cend()) ? 0 : i.value();
}
HistoryItem *histItemById(MsgId itemId) {
MsgsData::const_iterator i = msgsData.constFind(itemId);
if (i != msgsData.cend()) {
HistoryItem *histItemById(ChannelId channelId, MsgId itemId) {
MsgsData *data = fetchMsgsData(channelId, false);
if (!data) return 0;
MsgsData::const_iterator i = data->constFind(itemId);
if (i != data->cend()) {
return i.value();
}
return 0;
@ -1611,16 +1633,16 @@ namespace App {
}
HistoryItem *historyRegItem(HistoryItem *item) {
MsgsData::const_iterator i = msgsData.constFind(item->id);
if (i == msgsData.cend()) {
msgsData.insert(item->id, item);
if (item->id > ::maxMsgId) ::maxMsgId = item->id;
MsgsData *data = fetchMsgsData(item->channelId());
MsgsData::const_iterator i = data->constFind(item->id);
if (i == data->cend()) {
data->insert(item->id, item);
return 0;
}
if (i.value() != item && !i.value()->block() && item->block()) { // replace search item
itemReplaced(i.value(), item);
delete i.value();
msgsData.insert(item->id, item);
data->insert(item->id, item);
return 0;
}
return (i.value() == item) ? 0 : i.value();
@ -1651,10 +1673,13 @@ namespace App {
}
void historyUnregItem(HistoryItem *item) {
MsgsData::iterator i = msgsData.find(item->id);
if (i != msgsData.cend()) {
MsgsData *data = fetchMsgsData(item->channelId(), false);
if (!data) return;
MsgsData::iterator i = data->find(item->id);
if (i != data->cend()) {
if (i.value() == item) {
msgsData.erase(i);
data->erase(i);
}
}
historyItemDetached(item);
@ -1677,19 +1702,26 @@ namespace App {
toDelete.push_back(*i);
}
}
for (ChannelMsgsData::const_iterator j = channelMsgsData.cbegin(), end = channelMsgsData.cend(); j != end; ++j) {
for (MsgsData::const_iterator i = j->cbegin(), e = j->cend(); i != e; ++i) {
toDelete.push_back(*i);
}
}
msgsData.clear();
for (int i = 0, l = toDelete.size(); i < l; ++i) {
channelMsgsData.clear();
for (int32 i = 0, l = toDelete.size(); i < l; ++i) {
delete toDelete[i];
}
::maxMsgId = 0;
::hoveredItem = ::pressedItem = ::hoveredLinkItem = ::pressedLinkItem = ::contextItem = 0;
replyMarkups.clear();
channelReplyMarkups.clear();
}
void historyClearItems() {
historyClearMsgs();
randomData.clear();
sentTextData.clear();
sentData.clear();
mutedPeers.clear();
updatedPeers.clear();
cSetSavedPeers(SavedPeers());
@ -1750,7 +1782,7 @@ namespace App {
}
}
void historyRegRandom(uint64 randomId, MsgId itemId) {
void historyRegRandom(uint64 randomId, const FullMsgId &itemId) {
randomData.insert(randomId, itemId);
}
@ -1758,24 +1790,26 @@ namespace App {
randomData.remove(randomId);
}
MsgId histItemByRandom(uint64 randomId) {
FullMsgId histItemByRandom(uint64 randomId) {
RandomData::const_iterator i = randomData.constFind(randomId);
if (i != randomData.cend()) {
return i.value();
}
return 0;
return FullMsgId();
}
void historyRegSentText(uint64 randomId, const QString &text) {
sentTextData.insert(randomId, text);
void historyRegSentData(uint64 randomId, const PeerId &peerId, const QString &text) {
sentData.insert(randomId, qMakePair(peerId, text));
}
void historyUnregSentText(uint64 randomId) {
sentTextData.remove(randomId);
void historyUnregSentData(uint64 randomId) {
sentData.remove(randomId);
}
QString histSentTextByItem(uint64 randomId) {
return sentTextData.value(randomId);
void histSentDataByItem(uint64 randomId, PeerId &peerId, QString &text) {
QPair<PeerId, QString> d = sentData.value(randomId);
peerId = d.first;
text = d.second;
}
void prepareCorners(RoundCorners index, int32 radius, const style::color &color, const style::color *shadow = 0, QImage *cors = 0) {
@ -2157,7 +2191,15 @@ namespace App {
if (changeInMin) App::main()->updateMutedIn(changeInMin);
}
void feedReplyMarkup(MsgId msgId, const MTPReplyMarkup &markup) {
inline void insertReplyMarkup(ChannelId channelId, MsgId msgId, const ReplyMarkup &markup) {
if (channelId == NoChannel) {
replyMarkups.insert(msgId, markup);
} else {
channelReplyMarkups[channelId].insert(msgId, markup);
}
}
void feedReplyMarkup(ChannelId channelId, MsgId msgId, const MTPReplyMarkup &markup) {
ReplyMarkup data;
ReplyMarkup::Commands &commands(data.commands);
switch (markup.type()) {
@ -2189,7 +2231,7 @@ namespace App {
}
}
if (!commands.isEmpty()) {
replyMarkups.insert(msgId, data);
insertReplyMarkup(channelId, msgId, data);
}
}
} break;
@ -2197,27 +2239,44 @@ namespace App {
case mtpc_replyKeyboardHide: {
const MTPDreplyKeyboardHide &d(markup.c_replyKeyboardHide());
if (d.vflags.v) {
replyMarkups.insert(msgId, ReplyMarkup(d.vflags.v | MTPDreplyKeyboardMarkup_flag_ZERO));
insertReplyMarkup(channelId, msgId, ReplyMarkup(d.vflags.v | MTPDreplyKeyboardMarkup_flag_ZERO));
}
} break;
case mtpc_replyKeyboardForceReply: {
const MTPDreplyKeyboardForceReply &d(markup.c_replyKeyboardForceReply());
replyMarkups.insert(msgId, ReplyMarkup(d.vflags.v | MTPDreplyKeyboardMarkup_flag_FORCE_REPLY));
insertReplyMarkup(channelId, msgId, ReplyMarkup(d.vflags.v | MTPDreplyKeyboardMarkup_flag_FORCE_REPLY));
} break;
}
}
void clearReplyMarkup(MsgId msgId) {
replyMarkups.remove(msgId);
void clearReplyMarkup(ChannelId channelId, MsgId msgId) {
if (channelId == NoChannel) {
replyMarkups.remove(msgId);
} else {
ChannelReplyMarkups::iterator i = channelReplyMarkups.find(channelId);
if (i != channelReplyMarkups.cend()) {
i->remove(msgId);
}
if (i->isEmpty()) {
channelReplyMarkups.erase(i);
}
}
}
const ReplyMarkup &replyMarkup(MsgId msgId) {
static ReplyMarkup zeroMarkup(MTPDreplyKeyboardMarkup_flag_ZERO);
inline const ReplyMarkup &replyMarkup(const ReplyMarkups &markups, MsgId msgId) {
ReplyMarkups::const_iterator i = replyMarkups.constFind(msgId);
if (i == replyMarkups.cend()) return zeroMarkup;
if (i == replyMarkups.cend()) return zeroMarkup;
return i.value();
}
const ReplyMarkup &replyMarkup(ChannelId channelId, MsgId msgId) {
if (channelId == NoChannel) {
return replyMarkup(replyMarkups, msgId);
}
ChannelReplyMarkups::const_iterator j = channelReplyMarkups.constFind(channelId);
if (j == channelReplyMarkups.cend()) return zeroMarkup;
return replyMarkup(*j, msgId);
}
void setProxySettings(QNetworkAccessManager &manager) {
if (cConnectionType() == dbictHttpProxy) {

View file

@ -92,38 +92,21 @@ namespace App {
QString formatPhone(QString phone);
inline bool isChat(const PeerId &peer) {
return peer & 0x100000000L;
}
PeerId peerFromMTP(const MTPPeer &peer_id);
PeerId peerFromChat(int32 chat_id);
inline PeerId peerFromChat(const MTPint &chat_id) {
return peerFromChat(chat_id.v);
}
PeerId peerFromUser(int32 user_id);
inline PeerId peerFromUser(const MTPint &user_id) {
return peerFromUser(user_id.v);
}
MTPpeer peerToMTP(const PeerId &peer_id);
int32 userFromPeer(const PeerId &peer_id);
int32 chatFromPeer(const PeerId &peer_id);
int32 onlineForSort(UserData *user, int32 now);
int32 onlineWillChangeIn(UserData *user, int32 nowOnServer);
QString onlineText(UserData *user, int32 nowOnServer, bool precise = false);
bool onlineColorUse(UserData *user, int32 now);
UserData *feedUsers(const MTPVector<MTPUser> &users, bool emitPeerUpdated = true); // returns last user
ChatData *feedChats(const MTPVector<MTPChat> &chats, bool emitPeerUpdated = true); // returns last chat
PeerData *feedChats(const MTPVector<MTPChat> &chats, bool emitPeerUpdated = true); // returns last chat
void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos, bool emitPeerUpdated = true);
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d, bool emitPeerUpdated = true);
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d, bool emitPeerUpdated = true);
void checkEntitiesUpdate(const MTPDmessage &m);
void feedMsgs(const MTPVector<MTPMessage> &msgs, int msgsState = 0); // 2 - new read message, 1 - new unread message, 0 - not new message, -1 - searched message
void feedWereRead(const QVector<MTPint> &msgsIds);
void feedInboxRead(const PeerId &peer, int32 upTo);
void feedOutboxRead(const PeerId &peer, int32 upTo);
void feedWereDeleted(const QVector<MTPint> &msgsIds);
void feedInboxRead(const PeerId &peer, MsgId upTo);
void feedOutboxRead(const PeerId &peer, MsgId upTo);
void feedWereDeleted(ChannelId channelId, const QVector<MTPint> &msgsIds);
void feedUserLinks(const MTPVector<MTPcontacts_Link> &links, bool emitPeerUpdated = true);
void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink, bool emitPeerUpdated = true);
@ -131,8 +114,6 @@ namespace App {
void clearPeerUpdated(PeerData *data);
void emitPeerUpdated();
int32 maxMsgId();
ImagePtr image(const MTPPhotoSize &size);
StorageImageLocation imageLocation(int32 w, int32 h, const MTPFileLocation &loc);
StorageImageLocation imageLocation(const MTPPhotoSize &size);
@ -150,19 +131,23 @@ namespace App {
WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert = 0);
WebPageData *feedWebPage(const MTPWebPage &webpage);
UserData *userLoaded(const PeerId &user);
ChatData *chatLoaded(const PeerId &chat);
PeerData *peerLoaded(const PeerId &peer);
PeerData *peerLoaded(const PeerId &id);
UserData *userLoaded(const PeerId &id);
ChatData *chatLoaded(const PeerId &id);
ChannelData *channelLoaded(const PeerId &id);
UserData *userLoaded(int32 user);
ChatData *chatLoaded(int32 chat);
ChannelData *channelLoaded(int32 channel);
PeerData *peer(const PeerId &peer);
UserData *user(const PeerId &peer);
UserData *user(int32 user);
PeerData *peer(const PeerId &id);
UserData *user(const PeerId &id);
ChatData *chat(const PeerId &id);
ChannelData *channel(const PeerId &id);
UserData *user(int32 user_id);
ChatData *chat(int32 chat_id);
ChannelData *channel(int32 channel_id);
UserData *self();
UserData *userByName(const QString &username);
ChatData *chat(const PeerId &peer);
ChatData *chat(int32 chat);
QString peerName(const PeerData *peer, bool forDialogs = false);
PhotoData *photo(const PhotoId &photo);
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
@ -183,7 +168,10 @@ namespace App {
Histories &histories();
History *history(const PeerId &peer, int32 unreadCnt = 0, int32 maxInboxRead = 0);
History *historyLoaded(const PeerId &peer);
HistoryItem *histItemById(MsgId itemId);
HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
inline HistoryItem *histItemById(const FullMsgId &msgId) {
return histItemById(msgId.channel, msgId.msg);
}
HistoryItem *historyRegItem(HistoryItem *item);
void historyItemDetached(HistoryItem *item);
void historyUnregItem(HistoryItem *item);
@ -192,12 +180,12 @@ namespace App {
void historyRegReply(HistoryReply *reply, HistoryItem *to);
void historyUnregReply(HistoryReply *reply, HistoryItem *to);
void historyRegRandom(uint64 randomId, MsgId itemId);
void historyRegRandom(uint64 randomId, const FullMsgId &itemId);
void historyUnregRandom(uint64 randomId);
MsgId histItemByRandom(uint64 randomId);
void historyRegSentText(uint64 itemId, const QString &text);
void historyUnregSentText(uint64 itemId);
QString histSentTextByItem(uint64 itemId);
FullMsgId histItemByRandom(uint64 randomId);
void historyRegSentData(uint64 randomId, const PeerId &peerId, const QString &text);
void historyUnregSentData(uint64 randomId);
void histSentDataByItem(uint64 randomId, PeerId &peerId, QString &text);
void hoveredItem(HistoryItem *item);
HistoryItem *hoveredItem();
@ -255,9 +243,9 @@ namespace App {
void unregMuted(PeerData *peer);
void updateMuted();
void feedReplyMarkup(MsgId msgId, const MTPReplyMarkup &markup);
void clearReplyMarkup(MsgId msgId);
const ReplyMarkup &replyMarkup(MsgId msgId);
void feedReplyMarkup(ChannelId channelId, MsgId msgId, const MTPReplyMarkup &markup);
void clearReplyMarkup(ChannelId channelId, MsgId msgId);
const ReplyMarkup &replyMarkup(ChannelId channelId, MsgId msgId);
void setProxySettings(QNetworkAccessManager &manager);
void setProxySettings(QTcpSocket &socket);

View file

@ -266,7 +266,7 @@ void Application::onUpdateFailed() {
}
#endif
void Application::regPhotoUpdate(const PeerId &peer, MsgId msgId) {
void Application::regPhotoUpdate(const PeerId &peer, const FullMsgId &msgId) {
photoUpdates.insert(msgId, peer);
}
@ -275,7 +275,7 @@ void Application::clearPhotoUpdates() {
}
bool Application::isPhotoUpdating(const PeerId &peer) {
for (QMap<MsgId, PeerId>::iterator i = photoUpdates.begin(), e = photoUpdates.end(); i != e; ++i) {
for (QMap<FullMsgId, PeerId>::iterator i = photoUpdates.begin(), e = photoUpdates.end(); i != e; ++i) {
if (i.value() == peer) {
return true;
}
@ -284,7 +284,7 @@ bool Application::isPhotoUpdating(const PeerId &peer) {
}
void Application::cancelPhotoUpdate(const PeerId &peer) {
for (QMap<MsgId, PeerId>::iterator i = photoUpdates.begin(), e = photoUpdates.end(); i != e;) {
for (QMap<FullMsgId, PeerId>::iterator i = photoUpdates.begin(), e = photoUpdates.end(); i != e;) {
if (i.value() == peer) {
i = photoUpdates.erase(i);
} else {
@ -333,11 +333,15 @@ bool Application::peerPhotoFail(PeerId peer, const RPCError &error) {
return true;
}
void Application::peerClearPhoto(PeerId peer) {
if (App::self() && App::self()->id == peer) {
MTP::send(MTPphotos_UpdateProfilePhoto(MTP_inputPhotoEmpty(), MTP_inputPhotoCropAuto()), rpcDone(&Application::selfPhotoCleared), rpcFail(&Application::peerPhotoFail, peer));
} else {
MTP::send(MTPmessages_EditChatPhoto(MTP_int(int32(peer & 0xFFFFFFFF)), MTP_inputChatPhotoEmpty()), rpcDone(&Application::chatPhotoCleared, peer), rpcFail(&Application::peerPhotoFail, peer));
void Application::peerClearPhoto(PeerId id) {
if (MTP::authedId() && peerToUser(id) == MTP::authedId()) {
MTP::send(MTPphotos_UpdateProfilePhoto(MTP_inputPhotoEmpty(), MTP_inputPhotoCropAuto()), rpcDone(&Application::selfPhotoCleared), rpcFail(&Application::peerPhotoFail, id));
} else if (peerIsChat(id)) {
MTP::send(MTPmessages_EditChatPhoto(MTP_inputChat(peerToBareMTPInt(id)), MTP_inputChatPhotoEmpty()), rpcDone(&Application::chatPhotoCleared, id), rpcFail(&Application::peerPhotoFail, id));
} else if (peerIsChannel(id)) {
if (ChannelData *channel = App::channelLoaded(id)) {
MTP::send(MTPmessages_EditChatPhoto(channel->inputChat, MTP_inputChatPhotoEmpty()), rpcDone(&Application::chatPhotoCleared, id), rpcFail(&Application::peerPhotoFail, id));
}
}
}
@ -386,17 +390,17 @@ void Application::killDownloadSessions() {
}
}
void Application::photoUpdated(MsgId msgId, const MTPInputFile &file) {
void Application::photoUpdated(const FullMsgId &msgId, const MTPInputFile &file) {
if (!App::self()) return;
QMap<MsgId, PeerId>::iterator i = photoUpdates.find(msgId);
QMap<FullMsgId, PeerId>::iterator i = photoUpdates.find(msgId);
if (i != photoUpdates.end()) {
PeerId peer = i.value();
if (peer == App::self()->id) {
MTP::send(MTPphotos_UploadProfilePhoto(file, MTP_string(""), MTP_inputGeoPointEmpty(), MTP_inputPhotoCrop(MTP_double(0), MTP_double(0), MTP_double(100))), rpcDone(&Application::selfPhotoDone), rpcFail(&Application::peerPhotoFail, peer));
} else {
History *hist = App::history(peer);
hist->sendRequestId = MTP::send(MTPmessages_EditChatPhoto(MTP_int(peer & 0xFFFFFFFF), MTP_inputChatUploadedPhoto(file, MTP_inputPhotoCrop(MTP_double(0), MTP_double(0), MTP_double(100)))), rpcDone(&Application::chatPhotoDone, peer), rpcFail(&Application::peerPhotoFail, peer), 0, 0, hist->sendRequestId);
PeerId id = i.value();
if (MTP::authedId() && peerToUser(id) == MTP::authedId()) {
MTP::send(MTPphotos_UploadProfilePhoto(file, MTP_string(""), MTP_inputGeoPointEmpty(), MTP_inputPhotoCrop(MTP_double(0), MTP_double(0), MTP_double(100))), rpcDone(&Application::selfPhotoDone), rpcFail(&Application::peerPhotoFail, id));
} else if (peerIsChat(id) || peerIsChannel(id)) {
History *hist = App::history(id);
hist->sendRequestId = MTP::send(MTPmessages_EditChatPhoto(hist->peer->isChat() ? hist->peer->asChat()->inputChat : hist->peer->asChannel()->inputChat, MTP_inputChatUploadedPhoto(file, MTP_inputPhotoCrop(MTP_double(0), MTP_double(0), MTP_double(100)))), rpcDone(&Application::chatPhotoDone, id), rpcFail(&Application::peerPhotoFail, id), 0, 0, hist->sendRequestId);
}
}
}
@ -494,9 +498,9 @@ void Application::uploadProfilePhoto(const QImage &tosend, const PeerId &peerId)
ReadyLocalMedia ready(ToPreparePhoto, file, filename, filesize, data, id, id, qsl("jpg"), peerId, photo, MTP_audioEmpty(MTP_long(0)), photoThumbs, MTP_documentEmpty(MTP_long(0)), jpeg, false, 0);
connect(App::uploader(), SIGNAL(photoReady(MsgId, const MTPInputFile &)), App::app(), SLOT(photoUpdated(MsgId, const MTPInputFile &)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(photoReady(const FullMsgId&, const MTPInputFile&)), App::app(), SLOT(photoUpdated(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
MsgId newId = clientMsgId();
FullMsgId newId(peerToChannel(peerId), clientMsgId());
App::app()->regPhotoUpdate(peerId, newId);
App::uploader()->uploadMedia(newId, ready);
}

View file

@ -56,7 +56,7 @@ public:
FileUploader *uploader();
void uploadProfilePhoto(const QImage &tosend, const PeerId &peerId);
void regPhotoUpdate(const PeerId &peer, MsgId msgId);
void regPhotoUpdate(const PeerId &peer, const FullMsgId &msgId);
void clearPhotoUpdates();
bool isPhotoUpdating(const PeerId &peer);
void cancelPhotoUpdate(const PeerId &peer);
@ -117,7 +117,7 @@ public slots:
void onUpdateFailed();
#endif
void photoUpdated(MsgId msgId, const MTPInputFile &file);
void photoUpdated(const FullMsgId &msgId, const MTPInputFile &file);
void onSwitchDebugMode();
void onSwitchTestMode();
@ -127,7 +127,7 @@ public slots:
private:
QMap<MsgId, PeerId> photoUpdates;
QMap<FullMsgId, PeerId> photoUpdates;
QMap<int32, uint64> killDownloadSessionTimes;
SingleTimer killDownloadSessionsTimer;

View file

@ -489,7 +489,8 @@ void AudioPlayer::play(const SongMsgId &song, int64 position) {
setStoppedState(current);
if (!song.song->loader) {
DocumentOpenLink::doOpen(song.song);
song.song->openOnSave = song.song->openOnSaveMsgId = 0;
song.song->openOnSave = 0;
song.song->openOnSaveMsgId = FullMsgId();
if (song.song->loader) song.song->loader->start(true, true);
}
} else {

View file

@ -45,8 +45,8 @@ AddContactBox::AddContactBox(PeerData *peer) :
_addButton(this, lang(lng_settings_save), st::btnSelectDone),
_retryButton(this, lang(lng_try_other_contact), st::btnSelectDone),
_cancelButton(this, lang(lng_cancel), st::btnSelectCancel),
_firstInput(this, st::inpAddContact, lang(peer->chat ? lng_dlg_new_group_name : lng_signup_firstname), peer->chat ? peer->name : peer->asUser()->firstName),
_lastInput(this, st::inpAddContact, lang(lng_signup_lastname), peer->chat ? QString() : peer->asUser()->lastName),
_firstInput(this, st::inpAddContact, lang(peer->isUser() ? lng_signup_firstname : lng_dlg_new_group_name), peer->isUser() ? peer->asUser()->firstName : peer->name),
_lastInput(this, st::inpAddContact, lang(lng_signup_lastname), peer->isUser() ? peer->asUser()->lastName : QString()),
_phoneInput(this, st::inpAddContact, lang(lng_contact_phone)),
_contactId(0), _addRequest(0) {
@ -55,12 +55,16 @@ AddContactBox::AddContactBox(PeerData *peer) :
void AddContactBox::initBox() {
if (_peer) {
if (_peer->chat) {
_boxTitle = lang(lng_edit_group_title);
setMaxHeight(st::boxTitleHeight + st::addContactPadding.top() + 1 * _firstInput.height() + st::addContactPadding.bottom() + _addButton.height());
} else {
if (_peer->isUser()) {
_boxTitle = lang(_peer == App::self() ? lng_edit_self_title : lng_edit_contact_title);
setMaxHeight(st::boxTitleHeight + st::addContactPadding.top() + 2 * _firstInput.height() + 1 * st::addContactDelta + st::addContactPadding.bottom() + _addButton.height());
} else if (_peer->isChat()) {
_boxTitle = lang(lng_edit_group_title);
setMaxHeight(st::boxTitleHeight + st::addContactPadding.top() + 1 * _firstInput.height() + st::addContactPadding.bottom() + _addButton.height());
} else if (_peer->isChannel()) {
// CHANNELS_UX
_boxTitle = lang(lng_edit_group_title);
setMaxHeight(st::boxTitleHeight + st::addContactPadding.top() + 1 * _firstInput.height() + st::addContactPadding.bottom() + _addButton.height());
}
} else {
bool readyToAdd = !_phoneInput.text().isEmpty() && (!_firstInput.text().isEmpty() || !_lastInput.text().isEmpty());
@ -87,7 +91,7 @@ void AddContactBox::hideAll() {
void AddContactBox::showAll() {
_firstInput.show();
if (_peer && _peer->chat) {
if (_peer && (_peer->isChat() || _peer->isChannel())) {
_lastInput.hide();
} else {
_lastInput.show();
@ -112,7 +116,7 @@ void AddContactBox::showDone() {
void AddContactBox::keyPressEvent(QKeyEvent *e) {
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
if (_firstInput.hasFocus()) {
if (_peer && _peer->chat) {
if (_peer && (_peer->isChat() || _peer->isChannel())) {
if (_firstInput.text().trimmed().isEmpty()) {
_firstInput.setFocus();
_firstInput.notaBene();
@ -206,8 +210,10 @@ void AddContactBox::onSend() {
if (_peer == App::self()) {
_addRequest = MTP::send(MTPaccount_UpdateProfile(MTP_string(firstName), MTP_string(lastName)), rpcDone(&AddContactBox::onSaveSelfDone), rpcFail(&AddContactBox::onSaveSelfFail));
} else if (_peer) {
if (_peer->chat) {
_addRequest = MTP::send(MTPmessages_EditChatTitle(MTP_int(App::chatFromPeer(_peer->id)), MTP_string(firstName)), rpcDone(&AddContactBox::onSaveChatDone), rpcFail(&AddContactBox::onSaveFail));
if (_peer->isChat()) {
_addRequest = MTP::send(MTPmessages_EditChatTitle(_peer->asChat()->inputChat, MTP_string(firstName)), rpcDone(&AddContactBox::onSaveChatDone), rpcFail(&AddContactBox::onSaveFail));
} else if (_peer->isChannel()) {
_addRequest = MTP::send(MTPmessages_EditChatTitle(_peer->asChannel()->inputChat, MTP_string(firstName)), rpcDone(&AddContactBox::onSaveChatDone), rpcFail(&AddContactBox::onSaveFail));
} else {
_contactId = MTP::nonce<uint64>();
QVector<MTPInputContact> v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(_peer->asUser()->phone), MTP_string(firstName), MTP_string(lastName)));

View file

@ -60,7 +60,7 @@ _byUsernameSel(-1),
_addContactLnk(this, lang(lng_add_contact_button)) {
DialogsIndexed &v(App::main()->dialogsList());
for (DialogRow *r = v.list.begin; r != v.list.end; r = r->next) {
if (r->history->peer->chat && !r->history->peer->asChat()->forbidden && !r->history->peer->asChat()->left) {
if (r->history->peer->isChat() && !r->history->peer->asChat()->forbidden && !r->history->peer->asChat()->left) {
_contacts->addToEnd(r->history);
}
}
@ -93,7 +93,7 @@ void ContactsInner::onPeerNameChanged(PeerData *peer, const PeerData::Names &old
void ContactsInner::onAddBot() {
if (_bot->botInfo && !_bot->botInfo->startGroupToken.isEmpty()) {
uint64 randomId = MTP::nonce<uint64>();
MTP::send(MTPmessages_StartBot(_bot->inputUser, MTP_int(App::chatFromPeer(_addToChat->id)), MTP_long(randomId), MTP_string(_bot->botInfo->startGroupToken)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, _bot));
MTP::send(MTPmessages_StartBot(_bot->inputUser, _addToChat->inputChat, MTP_long(randomId), MTP_string(_bot->botInfo->startGroupToken)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, _bot));
App::wnd()->hideLayer();
App::main()->showPeerHistory(_addToChat->id, ShowAtUnreadMsgId);
@ -179,18 +179,20 @@ ContactsInner::ContactData *ContactsInner::contactData(DialogRow *row) {
ContactsData::const_iterator i = _contactsData.constFind(peer);
if (i == _contactsData.cend()) {
_contactsData.insert(peer, data = new ContactData());
data->inchat = (_chat && !peer->chat) ? _chat->participants.contains(peer->asUser()) : false;
data->inchat = (_chat && peer->isUser()) ? _chat->participants.contains(peer->asUser()) : false;
data->check = _checkedContacts.contains(peer);
data->name.setText(st::profileListNameFont, peer->name, _textNameOptions);
if (peer->chat) {
if (peer->isUser()) {
data->online = App::onlineText(peer->asUser(), _time);
} else if (peer->isChat()) {
ChatData *chat = peer->asChat();
if (chat->forbidden || chat->left) {
data->online = lang(lng_chat_status_unaccessible);
} else {
data->online = lng_chat_status_members(lt_count, chat->count);
}
} else {
data->online = App::onlineText(peer->asUser(), _time);
} else if (peer->isChannel()) {
data->online = lang(lng_chat_status_unaccessible); // CHANNELS_UX
}
} else {
data = i.value();
@ -203,7 +205,7 @@ ContactsInner::ContactData *ContactsInner::contactData(DialogRow *row) {
void ContactsInner::paintDialog(QPainter &p, PeerData *peer, ContactData *data, bool sel) {
int32 left = st::profileListPadding.width();
UserData *user = peer->chat ? 0 : peer->asUser();
UserData *user = peer->asUser();
if (data->inchat || data->check || _selCount + (_chat ? _chat->count : 0) >= cMaxGroupCount()) {
sel = false;
@ -454,7 +456,7 @@ void ContactsInner::chooseParticipant() {
}
}
if (peer) {
if (bot() && peer->chat) {
if (bot() && peer->isChat()) {
_addToChat = peer->asChat();
ConfirmBox *box = new ConfirmBox(lng_bot_sure_invite(lt_group, peer->name));
connect(box, SIGNAL(confirmed()), this, SLOT(onAddBot()));
@ -686,7 +688,7 @@ void ContactsInner::peopleReceived(const QString &query, const QVector<MTPContac
for (QVector<MTPContactFound>::const_iterator i = people.cbegin(), e = people.cend(); i != e; ++i) {
int32 uid = i->c_contactFound().vuser_id.v, j = 0;
for (; j < already; ++j) {
if (_byUsernameFiltered[j]->id == App::peerFromUser(uid)) break;
if (_byUsernameFiltered[j]->id == peerFromUser(uid)) break;
}
if (j == already) {
UserData *u = App::user(uid);
@ -889,7 +891,7 @@ QVector<UserData*> ContactsInner::selected() {
}
result.reserve(_contactsData.size());
for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
if (i.value()->check && !i.key()->chat) {
if (i.value()->check && i.key()->isUser()) {
result.push_back(i.key()->asUser());
}
}
@ -910,7 +912,7 @@ QVector<MTPInputUser> ContactsInner::selectedInputs() {
}
result.reserve(_contactsData.size());
for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
if (i.value()->check && !i.key()->chat) {
if (i.value()->check && i.key()->isUser()) {
result.push_back(i.key()->asUser()->inputUser);
}
}
@ -1277,7 +1279,7 @@ void CreateGroupBox::created(const MTPUpdates &updates) {
} break;
}
if (v && !v->isEmpty() && v->front().type() == mtpc_chat) {
App::main()->choosePeer(App::peerFromChat(v->front().c_chat().vid.v), ShowAtUnreadMsgId);
App::main()->choosePeer(peerFromChat(v->front().c_chat().vid.v), ShowAtUnreadMsgId);
}
}

View file

@ -219,7 +219,7 @@ void DialogsListWidget::paintEvent(QPaintEvent *e) {
int32 to = ((r.bottom() - skip) / int32(st::dlgHeight)) + 1, w = width();
if (to > searchResults.size()) to = searchResults.size();
for (; from < to; ++from) {
bool active = (searchResults[from]->_item->id == App::main()->activeMsgId());
bool active = (searchResults[from]->_item->history()->peer == App::main()->activePeer() && searchResults[from]->_item->id == App::main()->activeMsgId());
bool selected = (from == searchedSel);
searchResults[from]->paint(p, w, active, selected);
p.translate(0, st::dlgHeight);
@ -242,7 +242,7 @@ void DialogsListWidget::peopleResultPaint(UserData *user, QPainter &p, int32 w,
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height);
// draw chat icon
if (history->peer->chat) {
if (history->peer->isChat()) { // CHANNELS_UI
p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), (act ? st::dlgActiveChatImg : st::dlgChatImg));
rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip);
}
@ -281,7 +281,7 @@ void DialogsListWidget::searchInPeerPaint(QPainter &p, int32 w) const {
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height);
// draw chat icon
if (_searchInPeer->chat) {
if (_searchInPeer->isChat()) { // CHANNELS_UI
p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), st::dlgChatImg);
rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip);
}
@ -830,7 +830,7 @@ void DialogsListWidget::contactsReceived(const QVector<MTPContact> &contacts) {
}
int32 DialogsListWidget::addNewContact(int32 uid, bool select) { // -2 - err, -1 - don't scroll, >= 0 - scroll
PeerId peer = App::peerFromUser(uid);
PeerId peer = peerFromUser(uid);
if (!App::peerLoaded(peer)) return -2;
History *history = App::history(peer);
@ -942,7 +942,7 @@ void DialogsListWidget::clearFilter() {
}
void DialogsListWidget::addDialog(const MTPDdialog &dialog) {
History *history = App::history(App::peerFromMTP(dialog.vpeer), dialog.vunread_count.v, dialog.vread_inbox_max_id.v);
History *history = App::history(peerFromMTP(dialog.vpeer), dialog.vunread_count.v, dialog.vread_inbox_max_id.v);
if (history->lastMsg) {
SavedPeersByTime &saved(cRefSavedPeersByTime());
while (!saved.isEmpty() && history->lastMsg->date < saved.lastKey()) {
@ -1451,10 +1451,11 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent)
, _drawShadow(true)
, _dragInScroll(false)
, _dragForward(false)
, dlgOffset(0)
, dlgCount(-1)
, dlgPreloading(0)
, contactsRequest(0)
, _dialogsOffset(0)
, _dialogsCount(-1)
, _dialogsRequest(0)
, _channelDialogsRequest(0)
, _contactsRequest(0)
, _filter(this, st::dlgFilter, lang(lng_dlg_filter))
, _newGroup(this, st::btnNewGroup)
, _addContact(this, st::btnAddContact)
@ -1585,7 +1586,7 @@ void DialogsWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
void DialogsWidget::unreadCountsReceived(const QVector<MTPDialog> &dialogs) {
for (QVector<MTPDialog>::const_iterator i = dialogs.cbegin(), e = dialogs.cend(); i != e; ++i) {
const MTPDdialog &d(i->c_dialog());
Histories::iterator j = App::histories().find(App::peerFromMTP(d.vpeer));
Histories::iterator j = App::histories().find(peerFromMTP(d.vpeer));
if (j != App::histories().end()) {
App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, j.value());
if (d.vunread_count.v >= j.value()->unreadCount) {
@ -1605,7 +1606,7 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs) {
App::feedChats(data.vchats);
App::feedMsgs(data.vmessages);
dlgList = &data.vdialogs.c_vector().v;
dlgCount = dlgList->size();
_dialogsCount = dlgList->size();
} break;
case mtpc_messages_dialogsSlice: {
const MTPDmessages_dialogsSlice &data(dialogs.c_messages_dialogsSlice());
@ -1613,14 +1614,14 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs) {
App::feedChats(data.vchats);
App::feedMsgs(data.vmessages);
dlgList = &data.vdialogs.c_vector().v;
dlgCount = data.vcount.v;
_dialogsCount = data.vcount.v;
} break;
}
unreadCountsReceived(*dlgList);
if (!contactsRequest) {
contactsRequest = MTP::send(MTPcontacts_GetContacts(MTP_string("")), rpcDone(&DialogsWidget::contactsReceived), rpcFail(&DialogsWidget::contactsFailed));
if (!_contactsRequest) {
_contactsRequest = MTP::send(MTPcontacts_GetContacts(MTP_string("")), rpcDone(&DialogsWidget::contactsReceived), rpcFail(&DialogsWidget::contactsFailed));
}
if (dlgList) {
@ -1628,15 +1629,15 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs) {
onListScroll();
if (dlgList->size()) {
dlgOffset += dlgList->size();
_dialogsOffset += dlgList->size();
} else {
dlgCount = dlgOffset;
_dialogsCount = _dialogsOffset;
}
} else {
dlgCount = dlgOffset;
_dialogsCount = _dialogsOffset;
}
dlgPreloading = 0;
_dialogsRequest = 0;
if (dlgList) {
loadDialogs();
}
@ -1646,7 +1647,7 @@ bool DialogsWidget::dialogsFailed(const RPCError &error) {
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
LOG(("RPC Error: %1 %2: %3").arg(error.code()).arg(error.type()).arg(error.description()));
dlgPreloading = 0;
_dialogsRequest = 0;
return true;
}
@ -1727,15 +1728,15 @@ void DialogsWidget::onSearchMore(MsgId minMsgId) {
}
void DialogsWidget::loadDialogs() {
if (dlgPreloading) return;
if (dlgCount >= 0 && dlgOffset >= dlgCount) {
if (_dialogsRequest) return;
if (_dialogsCount >= 0 && _dialogsOffset >= _dialogsCount) {
list.addAllSavedPeers();
cSetDialogsReceived(true);
return;
}
int32 loadCount = dlgOffset ? DialogsPerPage : DialogsFirstLoad;
dlgPreloading = MTP::send(MTPmessages_GetDialogs(MTP_int(dlgOffset), MTP_int(0), MTP_int(loadCount)), rpcDone(&DialogsWidget::dialogsReceived), rpcFail(&DialogsWidget::dialogsFailed));
int32 loadCount = _dialogsOffset ? DialogsPerPage : DialogsFirstLoad;
_dialogsRequest = MTP::send(MTPmessages_GetDialogs(MTP_int(_dialogsOffset), MTP_int(loadCount)), rpcDone(&DialogsWidget::dialogsReceived), rpcFail(&DialogsWidget::dialogsFailed));
}
void DialogsWidget::contactsReceived(const MTPcontacts_Contacts &contacts) {

View file

@ -260,9 +260,8 @@ private:
bool searchFailed(const RPCError &error, mtpRequestId req);
bool peopleFailed(const RPCError &error, mtpRequestId req);
int32 dlgOffset, dlgCount;
mtpRequestId dlgPreloading;
mtpRequestId contactsRequest;
int32 _dialogsOffset, _dialogsCount;
mtpRequestId _dialogsRequest, _channelDialogsRequest, _contactsRequest;
FlatInput _filter;
IconedButton _newGroup, _addContact, _cancelSearch;

View file

@ -2746,8 +2746,8 @@ void MentionsDropdown::paintEvent(QPaintEvent *e) {
}
void MentionsDropdown::showFiltered(PeerData *peer, QString start) {
_chat = peer->chat ? peer->asChat() : 0;
_user = peer->chat ? 0 : peer->asUser();
_chat = peer->asChat();
_user = peer->asUser();
start = start.toLower();
bool toDown = (_filter != start);
if (toDown) {

View file

@ -18,7 +18,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
#include "stdafx.h"
#include "fileuploader.h"
FileUploader::FileUploader() : sentSize(0), uploading(0) {
FileUploader::FileUploader() : sentSize(0) {
memset(sentSizes, 0, sizeof(sentSizes));
nextTimer.setSingleShot(true);
connect(&nextTimer, SIGNAL(timeout()), this, SLOT(sendNext()));
@ -26,7 +26,7 @@ FileUploader::FileUploader() : sentSize(0), uploading(0) {
connect(&killSessionsTimer, SIGNAL(timeout()), this, SLOT(killSessions()));
}
void FileUploader::uploadMedia(MsgId msgId, const ReadyLocalMedia &media) {
void FileUploader::uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &media) {
if (media.type == ToPreparePhoto) {
App::feedPhoto(media.photo, media.photoThumbs);
} else if (media.type == ToPrepareDocument) {
@ -73,7 +73,7 @@ void FileUploader::currentFailed() {
requestsSent.clear();
docRequestsSent.clear();
dcMap.clear();
uploading = 0;
uploading = FullMsgId();
sentSize = 0;
for (int i = 0; i < MTPUploadSessionsCount; ++i) {
sentSizes[i] = 0;
@ -102,8 +102,8 @@ void FileUploader::sendNext() {
if (killing) {
killSessionsTimer.stop();
}
Queue::iterator i = uploading ? queue.find(uploading) : queue.begin();
if (!uploading) {
Queue::iterator i = uploading.msg ? queue.find(uploading) : queue.begin();
if (!uploading.msg) {
uploading = i.key();
} else if (i == queue.end()) {
i = queue.begin();
@ -138,7 +138,7 @@ void FileUploader::sendNext() {
emit audioReady(uploading, audio);
}
queue.remove(uploading);
uploading = 0;
uploading = FullMsgId();
sendNext();
}
return;
@ -193,7 +193,7 @@ void FileUploader::sendNext() {
nextTimer.start(UploadRequestInterval);
}
void FileUploader::cancel(MsgId msgId) {
void FileUploader::cancel(const FullMsgId &msgId) {
uploaded.remove(msgId);
if (uploading == msgId) {
currentFailed();
@ -202,7 +202,7 @@ void FileUploader::cancel(MsgId msgId) {
}
}
void FileUploader::confirm(MsgId msgId) {
void FileUploader::confirm(const FullMsgId &msgId) {
}
void FileUploader::clear() {

View file

@ -25,13 +25,13 @@ class FileUploader : public QObject, public RPCSender {
public:
FileUploader();
void uploadMedia(MsgId msgId, const ReadyLocalMedia &image);
void uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &image);
int32 currentOffset(MsgId msgId) const; // -1 means file not found
int32 fullSize(MsgId msgId) const;
int32 currentOffset(const FullMsgId &msgId) const; // -1 means file not found
int32 fullSize(const FullMsgId &msgId) const;
void cancel(MsgId msgId);
void confirm(MsgId msgId);
void cancel(const FullMsgId &msgId);
void confirm(const FullMsgId &msgId);
void clear();
@ -42,18 +42,18 @@ public slots:
signals:
void photoReady(MsgId msgId, const MTPInputFile &file);
void documentReady(MsgId msgId, const MTPInputFile &file);
void thumbDocumentReady(MsgId msgId, const MTPInputFile &file, const MTPInputFile &thumb);
void audioReady(MsgId msgId, const MTPInputFile &file);
void photoReady(const FullMsgId &msgId, const MTPInputFile &file);
void documentReady(const FullMsgId &msgId, const MTPInputFile &file);
void thumbDocumentReady(const FullMsgId &msgId, const MTPInputFile &file, const MTPInputFile &thumb);
void audioReady(const FullMsgId &msgId, const MTPInputFile &file);
void photoProgress(MsgId msgId);
void documentProgress(MsgId msgId);
void audioProgress(MsgId msgId);
void photoProgress(const FullMsgId &msgId);
void documentProgress(const FullMsgId &msgId);
void audioProgress(const FullMsgId &msgId);
void photoFailed(MsgId msgId);
void documentFailed(MsgId msgId);
void audioFailed(MsgId msgId);
void photoFailed(const FullMsgId &msgId);
void documentFailed(const FullMsgId &msgId);
void audioFailed(const FullMsgId &msgId);
private:
@ -94,7 +94,7 @@ private:
int32 docPartSize;
int32 docPartsCount;
};
typedef QMap<MsgId, File> Queue;
typedef QMap<FullMsgId, File> Queue;
void partLoaded(const MTPBool &result, mtpRequestId requestId);
bool partFailed(const RPCError &err, mtpRequestId requestId);
@ -107,7 +107,7 @@ private:
uint32 sentSize;
uint32 sentSizes[MTPUploadSessionsCount];
MsgId uploading;
FullMsgId uploading;
Queue queue;
Queue uploaded;
QTimer nextTimer, killSessionsTimer;

View file

@ -115,7 +115,7 @@ namespace {
}
const TextParseOptions &itemTextParseOptions(History *h, UserData *f) {
if ((!h->peer->chat && h->peer->asUser()->botInfo) || (!f->chat && f->asUser()->botInfo) || (h->peer->chat && h->peer->asChat()->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->isChannel() && h->peer->asChannel()->botStatus >= 0)) {
return _historyBotOptions;
}
return _historyTextOptions;
@ -160,9 +160,11 @@ void DialogRow::paint(QPainter &p, int32 w, bool act, bool sel) const {
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height);
// draw chat icon
if (history->peer->chat) {
if (history->peer->isChat()) {
p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), (act ? st::dlgActiveChatImg : st::dlgChatImg));
rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip);
} else if (history->peer->isChannel()) {
// CHANNELS_UI
}
HistoryItem *last = history->lastMsg;
@ -250,9 +252,11 @@ void FakeDialogRow::paint(QPainter &p, int32 w, bool act, bool sel) const {
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height);
// draw chat icon
if (history->peer->chat) {
if (history->peer->isChat()) {
p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), (act ? st::dlgActiveChatImg : st::dlgChatImg));
rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip);
} else if (history->peer->isChannel()) {
// CHANNELS_UI
}
// draw date
@ -364,17 +368,17 @@ bool History::updateTyping(uint64 ms, uint32 dots, bool force) {
} else if (cnt > 1) {
newTypingStr = lng_users_typing(lt_user, typing.begin().key()->firstName, lt_second_user, (typing.end() - 1).key()->firstName);
} else if (cnt) {
newTypingStr = peer->chat ? lng_user_typing(lt_user, typing.begin().key()->firstName) : lang(lng_typing);
newTypingStr = peer->isUser() ? lang(lng_typing) : lng_user_typing(lt_user, typing.begin().key()->firstName);
} else if (!sendActions.isEmpty()) {
switch (sendActions.begin().value().type) {
case SendActionRecordVideo: newTypingStr = peer->chat ? lng_user_action_record_video(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_record_video); break;
case SendActionUploadVideo: newTypingStr = peer->chat ? lng_user_action_upload_video(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_video); break;
case SendActionRecordAudio: newTypingStr = peer->chat ? lng_user_action_record_audio(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_record_audio); break;
case SendActionUploadAudio: newTypingStr = peer->chat ? lng_user_action_upload_audio(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_audio); break;
case SendActionUploadPhoto: newTypingStr = peer->chat ? lng_user_action_upload_photo(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_photo); break;
case SendActionUploadFile: newTypingStr = peer->chat ? lng_user_action_upload_file(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_file); break;
case SendActionChooseLocation: newTypingStr = peer->chat ? lng_user_action_geo_location(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_geo_location); break;
case SendActionChooseContact: newTypingStr = peer->chat ? lng_user_action_choose_contact(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_choose_contact); break;
case SendActionRecordVideo: newTypingStr = peer->isUser() ? lang(lng_send_action_record_video) : lng_user_action_record_video(lt_user, sendActions.begin().key()->firstName); break;
case SendActionUploadVideo: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_video) : lng_user_action_upload_video(lt_user, sendActions.begin().key()->firstName); break;
case SendActionRecordAudio: newTypingStr = peer->isUser() ? lang(lng_send_action_record_audio) : lng_user_action_record_audio(lt_user, sendActions.begin().key()->firstName); break;
case SendActionUploadAudio: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_audio) : lng_user_action_upload_audio(lt_user, sendActions.begin().key()->firstName); break;
case SendActionUploadPhoto: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_photo) : lng_user_action_upload_photo(lt_user, sendActions.begin().key()->firstName); break;
case SendActionUploadFile: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_file) : lng_user_action_upload_file(lt_user, sendActions.begin().key()->firstName); break;
case SendActionChooseLocation: newTypingStr = peer->isUser() ? lang(lng_send_action_geo_location) : lng_user_action_geo_location(lt_user, sendActions.begin().key()->firstName); break;
case SendActionChooseContact: newTypingStr = peer->isUser() ? lang(lng_send_action_choose_contact) : lng_user_action_choose_contact(lt_user, sendActions.begin().key()->firstName); break;
}
}
if (!newTypingStr.isEmpty()) {
@ -593,15 +597,15 @@ HistoryItem *Histories::addToBack(const MTPmessage &msg, int msgState) {
PeerId from_id = 0, to_id = 0;
switch (msg.type()) {
case mtpc_message:
from_id = App::peerFromUser(msg.c_message().vfrom_id);
to_id = App::peerFromMTP(msg.c_message().vto_id);
from_id = peerFromUser(msg.c_message().vfrom_id);
to_id = peerFromMTP(msg.c_message().vto_id);
break;
case mtpc_messageService:
from_id = App::peerFromUser(msg.c_messageService().vfrom_id);
to_id = App::peerFromMTP(msg.c_messageService().vto_id);
from_id = peerFromUser(msg.c_messageService().vfrom_id);
to_id = peerFromMTP(msg.c_messageService().vto_id);
break;
}
PeerId peer = (to_id == App::peerFromUser(MTP::authedId())) ? from_id : to_id;
PeerId peer = (peerToUser(to_id) == MTP::authedId()) ? from_id : to_id;
if (!peer) return 0;
@ -635,7 +639,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, boo
case mtpc_messageService: msgId = msg.c_messageService().vid.v; break;
}
HistoryItem *existing = App::histItemById(msgId);
HistoryItem *existing = App::histItemById(channelId(), msgId);
if (existing) {
bool regged = false;
if (existing->detached() && block) {
@ -730,7 +734,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, boo
result = new HistoryMessage(this, block, m);
}
if (m.has_reply_markup()) {
App::feedReplyMarkup(msgId, m.vreply_markup);
App::feedReplyMarkup(channelId(), msgId, m.vreply_markup);
}
}
} break;
@ -759,7 +763,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, boo
case mtpc_messageActionChatDeleteUser: {
const MTPDmessageActionChatDeleteUser &d(action.c_messageActionChatDeleteUser());
if (lastKeyboardFrom == App::peerFromUser(d.vuser_id)) {
if (lastKeyboardFrom == peerFromUser(d.vuser_id)) {
clearLastKeyboard();
}
// App::peer(App::peerFromUser(d.vuser_id)); left
@ -770,24 +774,25 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, boo
if (d.vphoto.type() == mtpc_photo) {
const QVector<MTPPhotoSize> &sizes(d.vphoto.c_photo().vsizes.c_vector().v);
if (!sizes.isEmpty()) {
ChatData *chat = peer->asChat();
if (chat) {
PhotoData *photo = App::feedPhoto(d.vphoto.c_photo());
if (photo) photo->chat = chat;
const MTPPhotoSize &smallSize(sizes.front()), &bigSize(sizes.back());
const MTPFileLocation *smallLoc = 0, *bigLoc = 0;
switch (smallSize.type()) {
case mtpc_photoSize: smallLoc = &smallSize.c_photoSize().vlocation; break;
case mtpc_photoCachedSize: smallLoc = &smallSize.c_photoCachedSize().vlocation; break;
}
switch (bigSize.type()) {
case mtpc_photoSize: bigLoc = &bigSize.c_photoSize().vlocation; break;
case mtpc_photoCachedSize: bigLoc = &bigSize.c_photoCachedSize().vlocation; break;
}
if (smallLoc && bigLoc) {
chat->setPhoto(MTP_chatPhoto(*smallLoc, *bigLoc), photo ? photo->id : 0);
chat->photo->load();
PhotoData *photo = App::feedPhoto(d.vphoto.c_photo());
if (photo) photo->peer = peer;
const MTPPhotoSize &smallSize(sizes.front()), &bigSize(sizes.back());
const MTPFileLocation *smallLoc = 0, *bigLoc = 0;
switch (smallSize.type()) {
case mtpc_photoSize: smallLoc = &smallSize.c_photoSize().vlocation; break;
case mtpc_photoCachedSize: smallLoc = &smallSize.c_photoCachedSize().vlocation; break;
}
switch (bigSize.type()) {
case mtpc_photoSize: bigLoc = &bigSize.c_photoSize().vlocation; break;
case mtpc_photoCachedSize: bigLoc = &bigSize.c_photoCachedSize().vlocation; break;
}
if (smallLoc && bigLoc) {
if (peer->isChat()) {
peer->asChat()->setPhoto(MTP_chatPhoto(*smallLoc, *bigLoc), photo ? photo->id : 0);
} else if (peer->isChannel()) {
peer->asChannel()->setPhoto(MTP_chatPhoto(*smallLoc, *bigLoc), photo ? photo->id : 0);
}
peer->photo->load();
}
}
}
@ -958,7 +963,7 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
addToOverview(adding, OverviewLinks);
}
if (adding->from()->id) {
if (peer->chat) {
if (peer->isChat()) {
QList<UserData*> *lastAuthors = &(peer->asChat()->lastAuthors);
int prev = lastAuthors->indexOf(adding->from());
if (prev > 0) {
@ -969,16 +974,16 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
}
}
if (adding->hasReplyMarkup()) {
int32 markupFlags = App::replyMarkup(adding->id).flags;
int32 markupFlags = App::replyMarkup(channelId(), adding->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_personal) || adding->notifyByFrom()) {
if (peer->chat) {
if (peer->isChat()) { // CHANNELS_UX
peer->asChat()->markupSenders.insert(adding->from(), true);
}
if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) { // zero markup means replyKeyboardHide
if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->chat && !adding->out())) {
if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->isChat() && !adding->out())) {
clearLastKeyboard();
}
} else if (peer->chat && (peer->asChat()->count < 1 || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from())) {
} else if (peer->isChat() && (peer->asChat()->count < 1 || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from())) {
clearLastKeyboard();
} else {
lastKeyboardInited = true;
@ -1097,7 +1102,7 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
if (loadedAtBottom()) { // add photos to overview and authors to lastAuthors
int32 mask = 0;
QList<UserData*> *lastAuthors = peer->chat ? &(peer->asChat()->lastAuthors) : 0;
QList<UserData*> *lastAuthors = peer->isChat() ? &(peer->asChat()->lastAuthors) : 0;
for (int32 i = block->size(); i > 0; --i) {
HistoryItem *item = (*block)[i - 1];
HistoryMedia *media = item->getMedia(true);
@ -1120,7 +1125,7 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
lastAuthors->push_back(item->from());
}
if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // chats with bots
int32 markupFlags = App::replyMarkup(item->id).flags;
int32 markupFlags = App::replyMarkup(channelId(), item->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_personal) || item->notifyByFrom()) {
bool wasKeyboardHide = peer->asChat()->markupSenders.contains(item->from());
if (!wasKeyboardHide) {
@ -1141,7 +1146,7 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
}
}
} else if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // conversations with bots
int32 markupFlags = App::replyMarkup(item->id).flags;
int32 markupFlags = App::replyMarkup(channelId(), item->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_personal) || item->notifyByFrom()) {
if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) {
clearLastKeyboard();
@ -1426,7 +1431,7 @@ bool History::isReadyFor(MsgId msgId, bool check) const {
} else if (msgId == ShowAtUnreadMsgId) {
return check ? (loadedAtBottom() && (msgCount >= unreadCount)) : !isEmpty();
} else if (check) {
HistoryItem *item = App::histItemById(msgId);
HistoryItem *item = App::histItemById(channelId(), msgId);
return item && item->history() == this && !item->detached();
}
return !isEmpty();
@ -1549,7 +1554,7 @@ void History::clear(bool leaveItems) {
}
height = 0;
oldLoaded = false;
if (peer->chat) {
if (peer->isChat()) {
peer->asChat()->lastAuthors.clear();
peer->asChat()->markupSenders.clear();
}
@ -1818,7 +1823,7 @@ HistoryItem::~HistoryItem() {
itemAnimations().remove(this);
App::historyUnregItem(this);
if (id < 0) {
App::app()->uploader()->cancel(id);
App::app()->uploader()->cancel(fullId());
}
}
@ -1878,14 +1883,14 @@ void HistoryPhoto::initDimensions(const HistoryItem *parent) {
if (reply) {
_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
} else {
if (parent->out() || !parent->history()->peer->chat || !fwd) {
if (!parent->displayFromName() || !fwd) {
_minh += st::msgPadding.top();
}
if (fwd) {
_minh += st::msgServiceNameFont->height + st::msgPadding.top();
}
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
_minh += st::msgPadding.top() + st::msgNameFont->height;
}
if (!_caption.isEmpty()) {
@ -1931,14 +1936,14 @@ int32 HistoryPhoto::resize(int32 width, bool dontRecountText, const HistoryItem
if (reply) {
_height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
} else {
if (parent->out() || !parent->history()->peer->chat || !fwd) {
if (!parent->displayFromName() || !fwd) {
_height += st::msgPadding.top();
}
if (fwd) {
_height += st::msgServiceNameFont->height + st::msgPadding.top();
}
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
_height += st::msgPadding.top() + st::msgNameFont->height;
}
if (!_caption.isEmpty()) {
@ -1982,7 +1987,7 @@ void HistoryPhoto::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
} else if (fwd) {
skipy = st::msgServiceNameFont->height + st::msgPadding.top();
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -2094,7 +2099,7 @@ void HistoryPhoto::draw(QPainter &p, const HistoryItem *parent, bool selected, i
App::roundRect(p, 0, 0, width, _height, bg, cors, &sh);
int replyFrom = 0, fwdFrom = 0;
if (!out && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -2292,13 +2297,13 @@ void HistoryVideo::initDimensions(const HistoryItem *parent) {
_maxw += st::mediaSaveDelta + _buttonWidth;
}
_minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
_minh += st::msgPadding.top() + st::msgNameFont->height;
}
if (const HistoryReply *reply = toHistoryReply(parent)) {
_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
} else if (const HistoryForwarded *fwd = toHistoryForwarded(parent)) {
if (parent->out() || !parent->history()->peer->chat) {
if (!parent->displayFromName()) {
_minh += st::msgPadding.top();
}
_minh += st::msgServiceNameFont->height;
@ -2348,13 +2353,13 @@ int32 HistoryVideo::countHeight(const HistoryItem *parent, int32 width) const {
}
int32 h = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
h += st::msgPadding.top() + st::msgNameFont->height;
}
if (const HistoryReply *reply = toHistoryReply(parent)) {
h += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
} else if (const HistoryForwarded *fwd = toHistoryForwarded(parent)) {
if (parent->out() || !parent->history()->peer->chat) {
if (!parent->displayFromName()) {
h += st::msgPadding.top();
}
h += st::msgServiceNameFont->height;
@ -2386,7 +2391,7 @@ void HistoryVideo::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
} else if (fwd) {
skipy = st::msgServiceNameFont->height;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -2413,7 +2418,7 @@ void HistoryVideo::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
width -= btnw + st::mediaSaveDelta;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
lnk = parent->from()->lnk;
return;
@ -2470,7 +2475,7 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
} else if (fwd) {
skipy = st::msgServiceNameFont->height;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -2515,7 +2520,7 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
RoundCorners cors(selected ? (out ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out ? MessageOutCorners : MessageInCorners));
App::roundRect(p, 0, 0, width, height, bg, cors, &sh);
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
p.setFont(st::msgNameFont->f);
p.setPen(parent->from()->color->p);
parent->from()->nameText.drawElided(p, st::mediaPadding.left(), st::msgPadding.top(), width - st::mediaPadding.left() - st::mediaPadding.right());
@ -2613,13 +2618,13 @@ int32 HistoryVideo::resize(int32 width, bool dontRecountText, const HistoryItem
if (_caption.isEmpty()) return _height;
_height = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
_height += st::msgPadding.top() + st::msgNameFont->height;
}
if (const HistoryReply *reply = toHistoryReply(parent)) {
_height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
} else if (const HistoryForwarded *fwd = toHistoryForwarded(parent)) {
if (parent->out() || !parent->history()->peer->chat) {
if (!parent->displayFromName()) {
_height += st::msgPadding.top();
}
_height += st::msgServiceNameFont->height;
@ -2674,13 +2679,13 @@ void HistoryAudio::initDimensions(const HistoryItem *parent) {
}
_minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
_minh += st::msgPadding.top() + st::msgNameFont->height;
}
if (const HistoryReply *reply = toHistoryReply(parent)) {
_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
} else if (const HistoryForwarded *fwd = toHistoryForwarded(parent)) {
if (parent->out() || !parent->history()->peer->chat) {
if (!parent->displayFromName()) {
_minh += st::msgPadding.top();
}
_minh += st::msgServiceNameFont->height;
@ -2700,7 +2705,7 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
} else if (fwd) {
skipy = st::msgServiceNameFont->height;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -2742,7 +2747,7 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
RoundCorners cors(selected ? (out ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out ? MessageOutCorners : MessageInCorners));
App::roundRect(p, 0, 0, width, _height, bg, cors, &sh);
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
p.setFont(st::msgNameFont->f);
p.setPen(parent->from()->color->p);
parent->from()->nameText.drawElided(p, st::mediaPadding.left(), st::msgPadding.top(), width - st::mediaPadding.left() - st::mediaPadding.right());
@ -2775,7 +2780,7 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
img = out ? st::mediaAudioOutImg : st::mediaAudioInImg;
} else if (already || hasdata) {
bool showPause = false;
if (playing.msgId == parent->id && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
if (playing.msgId == parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
statusText = formatDurationText(playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)) + qsl(" / ") + formatDurationText(playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
} else {
@ -2891,7 +2896,7 @@ void HistoryAudio::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
} else if (fwd) {
skipy = st::msgServiceNameFont->height;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -2914,7 +2919,7 @@ void HistoryAudio::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
width -= btnw + st::mediaSaveDelta;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
lnk = parent->from()->lnk;
return;
@ -3006,14 +3011,14 @@ void HistoryDocument::initDimensions(const HistoryItem *parent) {
}
_minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
_minh += st::msgPadding.top() + st::msgNameFont->height;
}
if (const HistoryReply *reply = toHistoryReply(parent)) {
_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
} else if (const HistoryForwarded *fwd = toHistoryForwarded(parent)) {
if (!data->song()) {
if (parent->out() || !parent->history()->peer->chat) {
if (!parent->displayFromName()) {
_minh += st::msgPadding.top();
}
_minh += st::msgServiceNameFont->height;
@ -3053,7 +3058,7 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected
} else if (fwd) {
skipy = st::msgServiceNameFont->height;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -3090,7 +3095,7 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected
RoundCorners cors(selected ? (out ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out ? MessageOutCorners : MessageInCorners));
App::roundRect(p, 0, 0, width, _height, bg, cors, &sh);
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
p.setFont(st::msgNameFont->f);
p.setPen(parent->from()->color->p);
parent->from()->nameText.drawElided(p, st::mediaPadding.left(), st::msgPadding.top(), width - st::mediaPadding.left() - st::mediaPadding.right());
@ -3124,13 +3129,13 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected
img = out ? st::mediaMusicOutImg : st::mediaMusicInImg;
} else if (already || hasdata) {
bool showPause = false;
if (playing.msgId == parent->id && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
if (playing.msgId == parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
statusText = formatDurationText(playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)) + qsl(" / ") + formatDurationText(playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
} else {
statusText = formatDurationText(data->song()->duration);
}
if (!showPause && playing.msgId == parent->id && App::main() && App::main()->player()->seekingSong(playing)) showPause = true;
if (!showPause && playing.msgId == parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) showPause = true;
img = out ? (showPause ? st::mediaPauseOutImg : st::mediaPlayOutImg) : (showPause ? st::mediaPauseInImg : st::mediaPlayInImg);
} else {
if (data->loader) {
@ -3247,15 +3252,15 @@ void HistoryDocument::drawInPlaylist(QPainter &p, const HistoryItem *parent, boo
statusText = _uplTextCache;
img = st::mediaMusicInImg;
} else if (already || hasdata) {
bool isPlaying = (playing.msgId == parent->id);
bool isPlaying = (playing.msgId == parent->fullId());
bool showPause = false;
if (playing.msgId == parent->id && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
if (playing.msgId == parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
statusText = formatDurationText(playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)) + qsl(" / ") + formatDurationText(playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
} else {
statusText = formatDurationText(data->song()->duration);
}
if (!showPause && playing.msgId == parent->id && App::main() && App::main()->player()->seekingSong(playing)) showPause = true;
if (!showPause && playing.msgId == parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) showPause = true;
img = isPlaying ? (showPause ? st::mediaPauseOutImg : st::mediaPlayOutImg) : (showPause ? st::mediaPauseInImg : st::mediaPlayInImg);
} else {
if (data->loader) {
@ -3416,7 +3421,7 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
} else if (fwd) {
skipy = st::msgServiceNameFont->height;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -3434,7 +3439,7 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
width -= btnw + st::mediaSaveDelta;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
lnk = parent->from()->lnk;
return;
@ -3686,13 +3691,13 @@ void HistoryContact::initDimensions(const HistoryItem *parent) {
_maxw = phonew + tleft + st::mediaPadding.right();
}
_minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
_minh += st::msgPadding.top() + st::msgNameFont->height;
}
if (const HistoryReply *reply = toHistoryReply(parent)) {
_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
} else if (const HistoryForwarded *fwd = toHistoryForwarded(parent)) {
if (parent->out() || !parent->history()->peer->chat) {
if (!parent->displayFromName()) {
_minh += st::msgPadding.top();
}
_minh += st::msgServiceNameFont->height;
@ -3724,7 +3729,7 @@ void HistoryContact::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
} else if (fwd) {
skipy = st::msgServiceNameFont->height;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -3733,7 +3738,7 @@ void HistoryContact::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
skipy += fwdFrom;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
lnk = parent->from()->lnk;
return;
@ -3779,7 +3784,7 @@ void HistoryContact::draw(QPainter &p, const HistoryItem *parent, bool selected,
} else if (fwd) {
skipy = st::msgServiceNameFont->height;
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -3798,7 +3803,7 @@ void HistoryContact::draw(QPainter &p, const HistoryItem *parent, bool selected,
RoundCorners cors(selected ? (out ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out ? MessageOutCorners : MessageInCorners));
App::roundRect(p, 0, 0, width, _height, bg, cors, &sh);
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
p.setFont(st::msgNameFont->f);
p.setPen(parent->from()->color->p);
parent->from()->nameText.drawElided(p, st::mediaPadding.left(), st::msgPadding.top(), width - st::mediaPadding.left() - st::mediaPadding.right());
@ -4210,13 +4215,13 @@ void HistoryWebPage::draw(QPainter &p, const HistoryItem *parent, bool selected,
img = parent->out() ? st::mediaMusicOutImg : st::mediaMusicInImg;
} else if (already || hasdata) {
bool showPause = false;
if (playing.msgId == parent->id && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
if (playing.msgId == parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
statusText = formatDurationText(playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)) + qsl(" / ") + formatDurationText(playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
} else {
statusText = formatDurationText(data->doc->song()->duration);
}
if (!showPause && playing.msgId == parent->id && App::main() && App::main()->player()->seekingSong(playing)) showPause = true;
if (!showPause && playing.msgId == parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) showPause = true;
img = parent->out() ? (showPause ? st::mediaPauseOutImg : st::mediaPlayOutImg) : (showPause ? st::mediaPauseInImg : st::mediaPlayInImg);
} else {
if (data->doc->loader) {
@ -4925,14 +4930,14 @@ void HistoryImageLink::initDimensions(const HistoryItem *parent) {
if (reply) {
_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
} else {
if (parent->out() || !parent->history()->peer->chat || !fwd) {
if (!parent->displayFromName() || !fwd) {
_minh += st::msgPadding.top();
}
if (fwd) {
_minh += st::msgServiceNameFont->height + st::msgPadding.top();
}
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
_minh += st::msgPadding.top() + st::msgNameFont->height;
}
if (!_title.isEmpty()) {
@ -4967,7 +4972,7 @@ void HistoryImageLink::draw(QPainter &p, const HistoryItem *parent, bool selecte
App::roundRect(p, 0, 0, width, _height, bg, cors, &sh);
int replyFrom = 0, fwdFrom = 0;
if (!out && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -5111,13 +5116,13 @@ int32 HistoryImageLink::resize(int32 width, bool dontRecountText, const HistoryI
_height = st::minPhotoSize;
}
if (reply || !_title.isEmpty() || !_description.isEmpty()) {
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
_height += st::msgPadding.top() + st::msgNameFont->height;
}
if (reply) {
_height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
} else {
if (parent->out() || !parent->history()->peer->chat || !fwd) {
if (!parent->displayFromName() || !fwd) {
_height += st::msgPadding.top();
}
if (fwd) {
@ -5181,7 +5186,7 @@ void HistoryImageLink::getState(TextLinkPtr &lnk, HistoryCursorState &state, int
} if (fwd) {
skipy = st::msgServiceNameFont->height + st::msgPadding.top();
}
if (!parent->out() && parent->history()->peer->chat) {
if (parent->displayFromName()) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -5398,7 +5403,7 @@ void HistoryMessage::initDimensions(const HistoryItem *parent) {
void HistoryMessage::fromNameUpdated() const {
if (_media) return;
int32 _namew = ((!out() && _history->peer->chat) ? _from->nameText.maxWidth() : 0) + st::msgPadding.left() + st::msgPadding.right();
int32 _namew = (displayFromName() ? _from->nameText.maxWidth() : 0) + st::msgPadding.left() + st::msgPadding.right();
if (_namew > _maxw) _maxw = _namew;
}
@ -5514,7 +5519,7 @@ void HistoryMessage::draw(QPainter &p, uint32 selection) const {
width = mwidth;
}
if (!out() && _history->peer->chat) {
if (displayFromName()) {
p.drawPixmap(left, _height - st::msgMargin.bottom() - st::msgPhotoSize, _from->photo->pixRounded(st::msgPhotoSize));
// width -= st::msgPhotoSkip;
left += st::msgPhotoSkip;
@ -5538,7 +5543,7 @@ void HistoryMessage::draw(QPainter &p, uint32 selection) const {
RoundCorners cors(selected ? (out() ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out() ? MessageOutCorners : MessageInCorners));
App::roundRect(p, r, bg, cors, &sh);
if (!out() && _history->peer->chat) {
if (displayFromName()) {
p.setFont(st::msgNameFont->f);
p.setPen(_from->color->p);
_from->nameText.drawElided(p, r.left() + st::msgPadding.left(), r.top() + st::msgPadding.top(), width - st::msgPadding.left() - st::msgPadding.right());
@ -5612,7 +5617,7 @@ int32 HistoryMessage::resize(int32 width, bool dontRecountText, const HistoryIte
_height = _textHeight;
if (_media && _media->isDisplayed()) _height += st::msgPadding.bottom() + _media->resize(nwidth, dontRecountText, this);
}
if (!out() && _history->peer->chat) {
if (displayFromName()) {
_height += st::msgNameFont->height;
}
_height += st::msgPadding.top() + st::msgPadding.bottom();
@ -5632,7 +5637,7 @@ bool HistoryMessage::hasPoint(int32 x, int32 y) const {
width = mwidth;
}
if (!out() && _history->peer->chat) { // from user left photo
if (displayFromName()) { // from user left photo
left += st::msgPhotoSkip;
}
if (width < 1) return false;
@ -5662,12 +5667,12 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
width = mwidth;
}
if (!out() && _history->peer->chat) { // from user left photo
if (displayFromName()) { // from user left photo
if (x >= left && x < left + st::msgPhotoSize && y >= _height - st::msgMargin.bottom() - st::msgPhotoSize && y < _height - st::msgMargin.bottom()) {
lnk = _from->lnk;
return;
}
// width -= st::msgPhotoSkip;
// width -= st::msgPhotoSkip;
left += st::msgPhotoSkip;
}
if (width < 1) return;
@ -5681,7 +5686,7 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
return;
}
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
if (!out() && _history->peer->chat) { // from user left name
if (displayFromName()) { // from user left name
if (x >= r.left() + st::msgPadding.left() && y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + st::msgNameFont->height && x < r.left() + r.width() - st::msgPadding.right() && x < r.left() + st::msgPadding.left() + _from->nameText.maxWidth()) {
lnk = _from->lnk;
return;
@ -5731,7 +5736,7 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x,
width = st::msgMaxWidth;
}
if (!out() && _history->peer->chat) { // from user left photo
if (displayFromName()) { // from user left photo
// width -= st::msgPhotoSkip;
left += st::msgPhotoSkip;
}
@ -5742,7 +5747,7 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x,
width = _maxw;
}
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
if (!out() && _history->peer->chat) { // from user left name
if (displayFromName()) { // from user left name
r.setTop(r.top() + st::msgNameFont->height);
}
QRect trect(r.marginsAdded(-st::msgPadding));
@ -5756,7 +5761,7 @@ void HistoryMessage::drawInDialog(QPainter &p, const QRect &r, bool act, const H
if (cacheFor != this) {
cacheFor = this;
QString msg(inDialogsText());
if (_history->peer->chat || out()) {
if (!_history->peer->isUser() || out()) { // CHANNELS_UI
TextCustomTagsMap custom;
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
msg = lng_message_with_from(lt_from, textRichPrepare((_from == App::self()) ? lang(lng_from_you) : _from->firstName), lt_message, textRichPrepare(msg));
@ -5775,7 +5780,7 @@ void HistoryMessage::drawInDialog(QPainter &p, const QRect &r, bool act, const H
}
QString HistoryMessage::notificationHeader() const {
return _history->peer->chat ? from()->name : QString();
return !_history->peer->isUser() ? from()->name : QString();
}
QString HistoryMessage::notificationText() const {
@ -5790,7 +5795,7 @@ HistoryMessage::~HistoryMessage() {
delete _media;
}
if (_flags & MTPDmessage::flag_reply_markup) {
App::clearReplyMarkup(id);
App::clearReplyMarkup(channelId(), id);
}
}
@ -5880,7 +5885,7 @@ bool HistoryForwarded::hasPoint(int32 x, int32 y) const {
width = st::msgMaxWidth;
}
if (!out() && _history->peer->chat) { // from user left photo
if (displayFromName()) { // from user left photo
// width -= st::msgPhotoSkip;
left += st::msgPhotoSkip;
}
@ -5907,7 +5912,7 @@ void HistoryForwarded::getState(TextLinkPtr &lnk, HistoryCursorState &state, int
width = st::msgMaxWidth;
}
if (!out() && _history->peer->chat) { // from user left photo
if (displayFromName()) { // from user left photo
if (x >= left && x < left + st::msgPhotoSize) {
return HistoryMessage::getState(lnk, state, x, y);
}
@ -5921,7 +5926,7 @@ void HistoryForwarded::getState(TextLinkPtr &lnk, HistoryCursorState &state, int
width = _maxw;
}
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
if (!out() && _history->peer->chat) {
if (displayFromName()) {
style::font nameFont(st::msgNameFont);
if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + nameFont->height) {
return HistoryMessage::getState(lnk, state, x, y);
@ -5965,7 +5970,7 @@ void HistoryForwarded::getSymbol(uint16 &symbol, bool &after, bool &upon, int32
width = st::msgMaxWidth;
}
if (!out() && _history->peer->chat) { // from user left photo
if (displayFromName()) { // from user left photo
// width -= st::msgPhotoSkip;
left += st::msgPhotoSkip;
}
@ -5976,7 +5981,7 @@ void HistoryForwarded::getSymbol(uint16 &symbol, bool &after, bool &upon, int32
width = _maxw;
}
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
if (!out() && _history->peer->chat) {
if (displayFromName()) {
style::font nameFont(st::msgNameFont);
if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + nameFont->height) {
return HistoryMessage::getSymbol(symbol, after, upon, x, y);
@ -5997,7 +6002,7 @@ HistoryReply::HistoryReply(History *history, HistoryBlock *block, const MTPDmess
, _maxReplyWidth(0)
{
if (!updateReplyTo()) {
App::api()->requestReplyTo(this, replyToMsgId);
App::api()->requestReplyTo(this, FullMsgId(history->channelId(), replyToMsgId));
}
}
@ -6008,7 +6013,7 @@ HistoryReply::HistoryReply(History *history, HistoryBlock *block, MsgId msgId, i
, _maxReplyWidth(0)
{
if (!updateReplyTo()) {
App::api()->requestReplyTo(this, replyToMsgId);
App::api()->requestReplyTo(this, FullMsgId(history->channelId(), replyToMsgId));
}
}
@ -6035,7 +6040,7 @@ void HistoryReply::initDimensions(const HistoryItem *parent) {
bool HistoryReply::updateReplyTo(bool force) {
if (replyToMsg || !replyToMsgId) return true;
replyToMsg = App::histItemById(replyToMsgId);
replyToMsg = App::histItemById(channelId(), replyToMsgId);
if (replyToMsg) {
App::historyRegReply(this, replyToMsg);
replyToText.setText(st::msgFont, replyToMsg->inReplyText(), _textDlgOptions);
@ -6183,7 +6188,7 @@ bool HistoryReply::hasPoint(int32 x, int32 y) const {
width = st::msgMaxWidth;
}
if (!out() && _history->peer->chat) { // from user left photo
if (displayFromName()) { // from user left photo
// width -= st::msgPhotoSkip;
left += st::msgPhotoSkip;
}
@ -6210,7 +6215,7 @@ void HistoryReply::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
width = st::msgMaxWidth;
}
if (!out() && _history->peer->chat) { // from user left photo
if (displayFromName()) { // from user left photo
if (x >= left && x < left + st::msgPhotoSize) {
return HistoryMessage::getState(lnk, state, x, y);
}
@ -6224,7 +6229,7 @@ void HistoryReply::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
width = _maxw;
}
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
if (!out() && _history->peer->chat) {
if (displayFromName()) {
style::font nameFont(st::msgNameFont);
if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + nameFont->height) {
return HistoryMessage::getState(lnk, state, x, y);
@ -6265,7 +6270,7 @@ void HistoryReply::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, i
width = st::msgMaxWidth;
}
if (!out() && _history->peer->chat) { // from user left photo
if (displayFromName()) { // from user left photo
// width -= st::msgPhotoSkip;
left += st::msgPhotoSkip;
}
@ -6276,7 +6281,7 @@ void HistoryReply::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, i
width = _maxw;
}
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
if (!out() && _history->peer->chat) {
if (displayFromName()) {
style::font nameFont(st::msgNameFont);
if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + nameFont->height) {
return HistoryMessage::getSymbol(symbol, after, upon, x, y);
@ -6307,10 +6312,10 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
switch (action.type()) {
case mtpc_messageActionChatAddUser: {
const MTPDmessageActionChatAddUser &d(action.c_messageActionChatAddUser());
if (App::peerFromUser(d.vuser_id) == _from->id) {
if (peerFromUser(d.vuser_id) == _from->id) {
text = lng_action_user_joined(lt_from, from);
} else {
UserData *u = App::user(App::peerFromUser(d.vuser_id));
UserData *u = App::user(peerFromUser(d.vuser_id));
second = TextLinkPtr(new PeerLink(u));
text = lng_action_add_user(lt_from, from, lt_user, textcmdLink(2, u->name));
}
@ -6318,7 +6323,7 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
case mtpc_messageActionChatJoinedByLink: {
const MTPDmessageActionChatJoinedByLink &d(action.c_messageActionChatJoinedByLink());
if (true || App::peerFromUser(d.vinviter_id) == _from->id) {
if (true || peerFromUser(d.vinviter_id) == _from->id) {
text = lng_action_user_joined_by_link(lt_from, from);
//} else {
//UserData *u = App::user(App::peerFromUser(d.vinviter_id));
@ -6338,10 +6343,10 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
case mtpc_messageActionChatDeleteUser: {
const MTPDmessageActionChatDeleteUser &d(action.c_messageActionChatDeleteUser());
if (App::peerFromUser(d.vuser_id) == _from->id) {
if (peerFromUser(d.vuser_id) == _from->id) {
text = lng_action_user_left(lt_from, from);
} else {
UserData *u = App::user(App::peerFromUser(d.vuser_id));
UserData *u = App::user(peerFromUser(d.vuser_id));
second = TextLinkPtr(new PeerLink(u));
text = lng_action_kick_user(lt_from, from, lt_user, textcmdLink(2, u->name));
}

View file

@ -160,6 +160,9 @@ class HistoryMessage;
class HistoryUnreadBar;
struct History : public QList<HistoryBlock*> {
History(const PeerId &peerId);
ChannelId channelId() const {
return peerToChannel(peer->id);
}
typedef QList<HistoryBlock*> Parent;
void clear(bool leaveItems = false);
@ -774,9 +777,17 @@ public:
virtual QString notificationText() const = 0;
void markRead();
int32 y, id;
int32 y;
MsgId id;
QDateTime date;
ChannelId channelId() const {
return _history->channelId();
}
FullMsgId fullId() const {
return FullMsgId(channelId(), id);
}
virtual HistoryMedia *getMedia(bool inOverview = false) const {
return 0;
}
@ -818,6 +829,10 @@ public:
return 0;
}
bool displayFromName() const {
return !out() && !history()->peer->isUser();
}
virtual ~HistoryItem();
protected:

View file

@ -37,7 +37,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
HistoryList::HistoryList(HistoryWidget *historyWidget, ScrollArea *scroll, History *history) : QWidget(0)
, hist(history)
, ySkip(0)
, botInfo(history->peer->chat ? 0 : history->peer->asUser()->botInfo)
, botInfo(history->peer->isUser() ? history->peer->asUser()->botInfo : 0)
, botDescWidth(0), botDescHeight(0)
, historyWidget(historyWidget)
, scrollArea(scroll)
@ -1636,7 +1636,7 @@ void MessageField::focusInEvent(QFocusEvent *e) {
emit focused();
}
BotKeyboard::BotKeyboard() : _wasForMsgId(0), _height(0), _maxOuterHeight(0), _maximizeSize(false), _singleUse(false), _forceReply(false),
BotKeyboard::BotKeyboard() : _height(0), _maxOuterHeight(0), _maximizeSize(false), _singleUse(false), _forceReply(false),
_sel(-1), _down(-1), _hoverAnim(animFunc(this, &BotKeyboard::hoverStep)), _st(&st::botKbButton) {
setGeometry(0, 0, _st->margin, _st->margin);
_height = _st->margin;
@ -1749,7 +1749,7 @@ void BotKeyboard::mouseReleaseEvent(QMouseEvent *e) {
updateSelected();
if (_sel == down && down >= 0) {
int row = (down / MatrixRowShift), col = down % MatrixRowShift;
App::sendBotCommand(_btns.at(row).at(col).cmd, _wasForMsgId);
App::sendBotCommand(_btns.at(row).at(col).cmd, _wasForMsgId.msg);
}
}
@ -1760,12 +1760,12 @@ void BotKeyboard::leaveEvent(QEvent *e) {
bool BotKeyboard::updateMarkup(HistoryItem *to) {
if (to && to->hasReplyMarkup()) {
if (_wasForMsgId == to->id) return false;
if (_wasForMsgId == FullMsgId(to->channelId(), to->id)) return false;
_wasForMsgId = to->id;
_wasForMsgId = FullMsgId(to->channelId(), to->id);
clearSelection();
_btns.clear();
const ReplyMarkup &markup(App::replyMarkup(to->id));
const ReplyMarkup &markup(App::replyMarkup(to->channelId(), to->id));
_forceReply = markup.flags & MTPDreplyKeyboardMarkup_flag_FORCE_REPLY;
_maximizeSize = !(markup.flags & MTPDreplyKeyboardMarkup_flag_resize);
_singleUse = _forceReply || (markup.flags & MTPDreplyKeyboardMarkup_flag_single_use);
@ -1796,9 +1796,9 @@ bool BotKeyboard::updateMarkup(HistoryItem *to) {
}
return true;
}
if (_wasForMsgId) {
if (_wasForMsgId.msg) {
_maximizeSize = _singleUse = _forceReply = false;
_wasForMsgId = 0;
_wasForMsgId = FullMsgId();
clearSelection();
_btns.clear();
return true;
@ -2145,7 +2145,7 @@ bool HistoryHider::offerPeer(PeerId peer) {
}
offered = App::peer(peer);
LangString phrase;
QString recipient = offered->chat ? '\xAB' + offered->name + '\xBB' : offered->name;
QString recipient = offered->isUser() ? offered->name : '\xAB' + offered->name + '\xBB';
if (_sharedContact) {
phrase = lng_forward_share_contact(lt_recipient, recipient);
} else if (_sendPath) {
@ -2205,6 +2205,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _replyReturn(0)
, _stickersUpdateRequest(0)
, _peer(0)
, _channel(NoChannel)
, _showAtMsgId(0)
, _preloadRequest(0), _preloadDownRequest(0)
, _delayedShowAtMsgId(-1)
@ -2547,7 +2548,7 @@ void HistoryWidget::updateStickers() {
}
void HistoryWidget::botCommandsChanged(UserData *user) {
if (_peer && (_peer == user || _peer->chat)) {
if (_peer && (_peer == user || !_peer->isUser())) {
if (_attachMention.clearFilteredCommands()) {
checkMentionDropdown();
}
@ -2659,10 +2660,10 @@ void HistoryWidget::setReplyReturns(PeerId peer, const QList<MsgId> &replyReturn
if (!_peer || _peer->id != peer) return;
_replyReturns = replyReturns;
_replyReturn = _replyReturns.isEmpty() ? 0 : App::histItemById(_replyReturns.back());
_replyReturn = _replyReturns.isEmpty() ? 0 : App::histItemById(_channel, _replyReturns.back());
while (!_replyReturns.isEmpty() && !_replyReturn) {
_replyReturns.pop_back();
_replyReturn = _replyReturns.isEmpty() ? 0 : App::histItemById(_replyReturns.back());
_replyReturn = _replyReturns.isEmpty() ? 0 : App::histItemById(_channel, _replyReturns.back());
}
updateControlsVisibility();
}
@ -2671,7 +2672,7 @@ void HistoryWidget::calcNextReplyReturn() {
_replyReturn = 0;
while (!_replyReturns.isEmpty() && !_replyReturn) {
_replyReturns.pop_back();
_replyReturn = _replyReturns.isEmpty() ? 0 : App::histItemById(_replyReturns.back());
_replyReturn = _replyReturns.isEmpty() ? 0 : App::histItemById(_channel, _replyReturns.back());
}
if (!_replyReturn) updateControlsVisibility();
}
@ -2795,6 +2796,8 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) {
}
_peer = peerId ? App::peer(peerId) : 0;
_channel = _peer ? peerToChannel(_peer->id) : NoChannel;
_unblockRequest = 0;
_titlePeerText = QString();
@ -2871,7 +2874,7 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) {
}
if (_replyToId) {
updateReplyTo();
if (!_replyTo) App::api()->requestReplyTo(0, _replyToId);
if (!_replyTo) App::api()->requestReplyTo(0, FullMsgId(_channel, _replyToId));
resizeEvent(0);
}
if (!_previewCancelled) {
@ -2933,7 +2936,15 @@ void HistoryWidget::updateControlsVisibility() {
} else {
_scroll.show();
}
if ((_peer->chat && !_peer->asChat()->forbidden && !_peer->asChat()->left) || (!_peer->chat && _peer->asUser()->access != UserNoAccess)) {
bool avail = false;
if (_peer->isUser()) {
avail = _peer->asUser()->access != UserNoAccess;
} else if (_peer->isChat()) {
avail = !_peer->asChat()->forbidden && !_peer->asChat()->left;
} else if (_peer->isChannel()) {
avail = !_peer->asChannel()->forbidden && !_peer->asChannel()->left;
}
if (avail) {
checkMentionDropdown();
if (isBlocked()) {
_botStart.hide();
@ -3240,7 +3251,7 @@ void HistoryWidget::firstLoadMessages() {
offset = -loadCount / 2;
from = _showAtMsgId;
}
_firstLoadRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(from), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed));
_firstLoadRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(from), MTP_int(0), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed));
}
void HistoryWidget::loadMessages() {
@ -3248,7 +3259,7 @@ void HistoryWidget::loadMessages() {
MsgId min = _history->minMsgId();
int32 offset = 0, loadCount = min ? MessagesPerPage : MessagesFirstLoad;
_preloadRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(min), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed));
_preloadRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(min), MTP_int(0), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed));
}
void HistoryWidget::loadMessagesDown() {
@ -3258,7 +3269,7 @@ void HistoryWidget::loadMessagesDown() {
if (!max) return;
int32 loadCount = MessagesPerPage, offset = -loadCount - 1;
_preloadDownRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(max + 1), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed));
_preloadDownRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(max + 1), MTP_int(0), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed));
}
void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
@ -3277,7 +3288,7 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
} else if (_delayedShowAtMsgId > 0) {
offset = -loadCount / 2;
}
_delayedShowAtRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(from), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed));
_delayedShowAtRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(from), MTP_int(0), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed));
}
void HistoryWidget::onListScroll() {
@ -3332,7 +3343,7 @@ void HistoryWidget::onHistoryToEnd() {
void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
if (!_history) return;
bool lastKeyboardUsed = lastForceReplyReplied(replyTo);
bool lastKeyboardUsed = lastForceReplyReplied(FullMsgId(_channel, replyTo));
QString text = prepareMessage(_field.getLastText());
if (!text.isEmpty()) {
App::main()->readServerHistory(_history, false);
@ -3364,7 +3375,7 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
void HistoryWidget::onUnblock() {
if (_unblockRequest) return;
if (!_peer || _peer->chat || _peer->asUser()->blocked != UserIsBlocked) {
if (!_peer || !_peer->isUser() || _peer->asUser()->blocked != UserIsBlocked) {
updateControlsVisibility();
return;
}
@ -3373,7 +3384,7 @@ void HistoryWidget::onUnblock() {
}
void HistoryWidget::unblockDone(PeerData *peer, const MTPBool &result) {
if (peer->chat) return;
if (!peer->isUser()) return;
_unblockRequest = 0;
peer->asUser()->blocked = UserIsNotBlocked;
emit App::main()->peerUpdated(peer);
@ -3386,7 +3397,7 @@ bool HistoryWidget::unblockFail(const RPCError &error) {
}
void HistoryWidget::onBotStart() {
if (!_peer || _peer->chat || !_peer->asUser()->botInfo) {
if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo) {
updateControlsVisibility();
return;
}
@ -3396,11 +3407,11 @@ void HistoryWidget::onBotStart() {
sendBotCommand(qsl("/start"), 0);
} else {
uint64 randomId = MTP::nonce<uint64>();
MTP::send(MTPmessages_StartBot(_peer->asUser()->inputUser, MTP_int(0), MTP_long(randomId), MTP_string(token)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, _peer->asUser()));
MTP::send(MTPmessages_StartBot(_peer->asUser()->inputUser, MTP_inputChat(MTP_int(0)), MTP_long(randomId), MTP_string(token)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, _peer->asUser()));
_peer->asUser()->botInfo->startToken = QString();
if (_keyboard.hasMarkup()) {
if (_keyboard.singleUse() && _keyboard.forMsgId() == _history->lastKeyboardId && _history->lastKeyboardUsed) {
if (_keyboard.singleUse() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) {
_kbWasHidden = true;
}
if (!_kbWasHidden) _kbShown = _keyboard.hasMarkup();
@ -3416,14 +3427,14 @@ void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) {
App::main()->showPeerHistory(peer, ShowAtTheEndMsgId);
if (!_history) return;
shareContact(peer, contact->phone, contact->firstName, contact->lastName, replyToId(), int32(contact->id & 0xFFFFFFFF));
shareContact(peer, contact->phone, contact->firstName, contact->lastName, replyToId(), peerToUser(contact->id));
}
void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, int32 userId) {
History *h = App::history(peer);
uint64 randomId = MTP::nonce<uint64>();
MsgId newId = clientMsgId();
FullMsgId newId(peerToChannel(peer), clientMsgId());
App::main()->readServerHistory(h, false);
fastShowAtEnd(h);
@ -3431,14 +3442,14 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
PeerData *p = App::peer(peer);
int32 flags = newMessageFlags(p) | MTPDmessage::flag_media; // unread, out
bool lastKeyboardUsed = lastForceReplyReplied(replyTo);
bool lastKeyboardUsed = lastForceReplyReplied(FullMsgId(peerToChannel(peer), replyTo));
int32 sendFlags = 0;
if (replyTo) {
flags |= MTPDmessage::flag_reply_to_msg_id;
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
}
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(peer), MTPint(), MTPint(), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId)), MTPnullMarkup, MTPnullEntities));
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(MTP::authedId()), peerToMTP(peer), MTPint(), MTPint(), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId)), MTPnullMarkup, MTPnullEntities));
h->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), p->input, MTP_int(replyTo), MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, h->sendRequestId);
App::historyRegRandom(randomId, newId);
@ -3722,17 +3733,17 @@ void HistoryWidget::sendBotCommand(const QString &cmd, MsgId replyTo) { // reply
App::main()->readServerHistory(_history, false);
fastShowAtEnd(_history);
bool lastKeyboardUsed = (_keyboard.forMsgId() == _history->lastKeyboardId) && (_keyboard.forMsgId() == replyTo);
bool lastKeyboardUsed = (_keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId)) && (_keyboard.forMsgId() == FullMsgId(_channel, replyTo));
QString toSend = cmd;
UserData *bot = _peer->chat ? (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0) : _peer->asUser();
UserData *bot = _peer->isUser() ? _peer->asUser() : (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0);
QString username = (bot && bot->botInfo) ? bot->username : QString();
if (!replyTo && toSend.indexOf('@') < 2 && _peer->chat && !username.isEmpty() && (_peer->asChat()->botStatus == 0 || _peer->asChat()->botStatus == 2)) {
int32 botStatus = _peer->isChat() ? _peer->asChat()->botStatus : (_peer->isChannel() ? _peer->asChannel()->botStatus : -1);
if (!replyTo && toSend.indexOf('@') < 2 && !username.isEmpty() && (botStatus == 0 || botStatus == 2)) {
toSend += '@' + username;
}
int32 botStatus = _peer->chat ? _peer->asChat()->botStatus : -1;
App::main()->sendPreparedText(_history, toSend, replyTo ? ((_peer->chat/* && (botStatus == 0 || botStatus == 2)*/) ? replyTo : -1) : 0);
App::main()->sendPreparedText(_history, toSend, replyTo ? ((!_peer->isUser()/* && (botStatus == 0 || botStatus == 2)*/) ? replyTo : -1) : 0);
if (replyTo) {
cancelReply();
if (_keyboard.singleUse() && _keyboard.hasMarkup() && lastKeyboardUsed) {
@ -3748,9 +3759,10 @@ void HistoryWidget::insertBotCommand(const QString &cmd) {
if (!_history) return;
QString toInsert = cmd;
UserData *bot = _peer->chat ? (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0) : _peer->asUser();
UserData *bot = _peer->isUser() ? _peer->asUser() : (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0);
QString username = (bot && bot->botInfo) ? bot->username : QString();
if (toInsert.indexOf('@') < 2 && _peer->chat && !username.isEmpty() && (_peer->asChat()->botStatus == 0 || _peer->asChat()->botStatus == 2)) {
int32 botStatus = _peer->isChat() ? _peer->asChat()->botStatus : (_peer->isChannel() ? _peer->asChannel()->botStatus : -1);
if (toInsert.indexOf('@') < 2 && !username.isEmpty() && (botStatus == 0 || botStatus == 2)) {
toInsert += '@' + username;
}
toInsert += ' ';
@ -3848,17 +3860,17 @@ void HistoryWidget::updateDragAreas() {
}
bool HistoryWidget::isBotStart() const {
if (!_peer || _peer->chat || !_peer->asUser()->botInfo) return false;
if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo) return false;
return !_peer->asUser()->botInfo->startToken.isEmpty() || (_history->isEmpty() && !_history->lastMsg);
}
bool HistoryWidget::isBlocked() const {
return _peer && !_peer->chat && _peer->asUser()->blocked == UserIsBlocked;
return _peer && _peer->isUser() && _peer->asUser()->blocked == UserIsBlocked;
}
bool HistoryWidget::updateCmdStartShown() {
bool cmdStartShown = false;
if (_history && _peer && ((_peer->chat && _peer->asChat()->botStatus > 0) || (!_peer->chat && _peer->asUser()->botInfo))) {
if (_history && _peer && ((_peer->isChat() && _peer->asChat()->botStatus > 0) || (_peer->isChannel() && _peer->asChannel()->botStatus > 0) || (_peer->isUser() && _peer->asUser()->botInfo))) {
if (!isBotStart() && !isBlocked() && !_keyboard.hasMarkup() && !_keyboard.forceReply()) {
if (_field.getLastText().isEmpty()) {
cmdStartShown = true;
@ -3948,7 +3960,7 @@ void HistoryWidget::onKbToggle(bool manual) {
_field.setMaxHeight(st::maxFieldHeight);
_kbReplyTo = (_history->peer->chat || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
_kbReplyTo = (_history->peer->isChat() || _history->peer->isChannel() || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
if (_kbReplyTo && !_replyToId) {
updateReplyToName();
_replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
@ -3964,7 +3976,7 @@ void HistoryWidget::onKbToggle(bool manual) {
int32 maxh = qMin(_keyboard.height(), int(st::maxFieldHeight) - (int(st::maxFieldHeight) / 2));
_field.setMaxHeight(st::maxFieldHeight - maxh);
_kbReplyTo = (_history->peer->chat || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
_kbReplyTo = (_history->peer->isChat() || _history->peer->isChannel() || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
if (_kbReplyTo && !_replyToId) {
updateReplyToName();
_replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
@ -4069,7 +4081,9 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) {
QString text;
int32 t = unixtime();
if (_peer->chat) {
if (_peer->isUser()) {
text = App::onlineText(_peer->asUser(), t);
} else if (_peer->isChat()) {
ChatData *chat = _peer->asChat();
if (chat->forbidden || chat->left) {
text = lang(lng_chat_status_unaccessible);
@ -4090,8 +4104,8 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) {
text = lng_chat_status_members(lt_count, chat->participants.size());
}
}
} else {
text = App::onlineText(_peer->asUser(), t);
} else if (_peer->isChannel()) {
// CHANNELS_UI
}
if (_titlePeerText != text) {
_titlePeerText = text;
@ -4107,7 +4121,9 @@ void HistoryWidget::updateOnlineDisplayTimer() {
if (!_history) return;
int32 t = unixtime(), minIn = 86400;
if (_peer->chat) {
if (_peer->isUser()) {
minIn = App::onlineWillChangeIn(_peer->asUser(), t);
} else if (_peer->isChat()) {
ChatData *chat = _peer->asChat();
if (chat->participants.isEmpty()) return;
@ -4117,8 +4133,8 @@ void HistoryWidget::updateOnlineDisplayTimer() {
minIn = onlineWillChangeIn;
}
}
} else {
minIn = App::onlineWillChangeIn(_peer->asUser(), t);
} else if (_peer->isChannel()) {
// CHANNELS_UI
}
App::main()->updateOnlineDisplayIn(minIn * 1000);
}
@ -4163,8 +4179,8 @@ void HistoryWidget::checkMentionDropdown() {
_field.getMentionHashtagBotCommandStart(start);
if (!start.isEmpty()) {
if (start.at(0) == '#' && cRecentWriteHashtags().isEmpty() && cRecentSearchHashtags().isEmpty()) Local::readRecentHashtags();
if (start.at(0) == '@' && !_history->peer->chat) return;
if (start.at(0) == '/' && !_history->peer->chat && !_history->peer->asUser()->botInfo) return;
if (start.at(0) == '@' && _history->peer->isUser()) return;
if (start.at(0) == '/' && _history->peer->isUser() && !_history->peer->asUser()->botInfo) return;
_attachMention.showFiltered(_history->peer, start);
} else if (!_attachMention.isHidden()) {
_attachMention.hideStart();
@ -4211,7 +4227,7 @@ void HistoryWidget::uploadConfirmImageUncompressed(bool ctrlShiftEnter, MsgId re
if (_confirmWithText) {
onSend(ctrlShiftEnter, replyTo);
}
bool lastKeyboardUsed = lastForceReplyReplied(replyTo);
bool lastKeyboardUsed = lastForceReplyReplied(FullMsgId(_channel, replyTo));
_imageLoader.append(_confirmImage, peerId, replyTo, ToPrepareDocument, ctrlShiftEnter);
_confirmImageId = 0;
_confirmWithText = false;
@ -4290,18 +4306,18 @@ void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
_confirmWithText = false;
_confirmImage = QImage();
}
MsgId newId = clientMsgId();
FullMsgId newId(peerToChannel(img.peer), clientMsgId());
connect(App::uploader(), SIGNAL(photoReady(MsgId, const MTPInputFile &)), this, SLOT(onPhotoUploaded(MsgId, const MTPInputFile &)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(documentReady(MsgId, const MTPInputFile &)), this, SLOT(onDocumentUploaded(MsgId, const MTPInputFile &)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(thumbDocumentReady(MsgId, const MTPInputFile &, const MTPInputFile &)), this, SLOT(onThumbDocumentUploaded(MsgId, const MTPInputFile &, const MTPInputFile &)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioReady(MsgId, const MTPInputFile &)), this, SLOT(onAudioUploaded(MsgId, const MTPInputFile &)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(photoProgress(MsgId)), this, SLOT(onPhotoProgress(MsgId)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(documentProgress(MsgId)), this, SLOT(onDocumentProgress(MsgId)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioProgress(MsgId)), this, SLOT(onAudioProgress(MsgId)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(photoFailed(MsgId)), this, SLOT(onPhotoFailed(MsgId)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(documentFailed(MsgId)), this, SLOT(onDocumentFailed(MsgId)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioFailed(MsgId)), this, SLOT(onAudioFailed(MsgId)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(photoReady(const FullMsgId&, const MTPInputFile&)), this, SLOT(onPhotoUploaded(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(documentReady(const FullMsgId&, const MTPInputFile&)), this, SLOT(onDocumentUploaded(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(thumbDocumentReady(const FullMsgId&, const MTPInputFile&, const MTPInputFile&)), this, SLOT(onThumbDocumentUploaded(const FullMsgId&, const MTPInputFile&, const MTPInputFile&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioReady(const FullMsgId&, const MTPInputFile&)), this, SLOT(onAudioUploaded(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(photoProgress(const FullMsgId&)), this, SLOT(onPhotoProgress(const FullMsgId&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(documentProgress(const FullMsgId&)), this, SLOT(onDocumentProgress(const FullMsgId&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioProgress(const FullMsgId&)), this, SLOT(onAudioProgress(const FullMsgId&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(photoFailed(const FullMsgId&)), this, SLOT(onPhotoFailed(const FullMsgId&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(documentFailed(const FullMsgId&)), this, SLOT(onDocumentFailed(const FullMsgId&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioFailed(const FullMsgId&)), this, SLOT(onAudioFailed(const FullMsgId&)), Qt::UniqueConnection);
App::uploader()->uploadMedia(newId, img);
@ -4312,12 +4328,12 @@ void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
int32 flags = newMessageFlags(h->peer) | MTPDmessage::flag_media; // unread, out
if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
if (img.type == ToPreparePhoto) {
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo, MTP_string("")), MTPnullMarkup, MTPnullEntities));
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(MTP::authedId()), peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo, MTP_string("")), MTPnullMarkup, MTPnullEntities));
} else if (img.type == ToPrepareDocument) {
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document), MTPnullMarkup, MTPnullEntities));
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(MTP::authedId()), peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document), MTPnullMarkup, MTPnullEntities));
} else if (img.type == ToPrepareAudio) {
flags |= MTPDmessage_flag_media_unread;
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(img.audio), MTPnullMarkup, MTPnullEntities));
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(MTP::authedId()), peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(img.audio), MTPnullMarkup, MTPnullEntities));
}
if (_peer && img.peer == _peer->id) {
@ -4334,7 +4350,7 @@ void HistoryWidget::cancelSendImage() {
_confirmImage = QImage();
}
void HistoryWidget::onPhotoUploaded(MsgId newId, const MTPInputFile &file) {
void HistoryWidget::onPhotoUploaded(const FullMsgId &newId, const MTPInputFile &file) {
if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId);
if (item) {
@ -4367,7 +4383,7 @@ namespace {
}
}
void HistoryWidget::onDocumentUploaded(MsgId newId, const MTPInputFile &file) {
void HistoryWidget::onDocumentUploaded(const FullMsgId &newId, const MTPInputFile &file) {
if (!MTP::authedId()) return;
HistoryMessage *item = dynamic_cast<HistoryMessage*>(App::histItemById(newId));
if (item) {
@ -4391,7 +4407,7 @@ void HistoryWidget::onDocumentUploaded(MsgId newId, const MTPInputFile &file) {
}
}
void HistoryWidget::onThumbDocumentUploaded(MsgId newId, const MTPInputFile &file, const MTPInputFile &thumb) {
void HistoryWidget::onThumbDocumentUploaded(const FullMsgId &newId, const MTPInputFile &file, const MTPInputFile &thumb) {
if (!MTP::authedId()) return;
HistoryMessage *item = dynamic_cast<HistoryMessage*>(App::histItemById(newId));
if (item) {
@ -4415,7 +4431,7 @@ void HistoryWidget::onThumbDocumentUploaded(MsgId newId, const MTPInputFile &fil
}
}
void HistoryWidget::onAudioUploaded(MsgId newId, const MTPInputFile &file) {
void HistoryWidget::onAudioUploaded(const FullMsgId &newId, const MTPInputFile &file) {
if (!MTP::authedId()) return;
HistoryMessage *item = dynamic_cast<HistoryMessage*>(App::histItemById(newId));
if (item) {
@ -4437,7 +4453,7 @@ void HistoryWidget::onAudioUploaded(MsgId newId, const MTPInputFile &file) {
}
}
void HistoryWidget::onPhotoProgress(MsgId newId) {
void HistoryWidget::onPhotoProgress(const FullMsgId &newId) {
if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId);
if (item) {
@ -4447,7 +4463,7 @@ void HistoryWidget::onPhotoProgress(MsgId newId) {
}
}
void HistoryWidget::onDocumentProgress(MsgId newId) {
void HistoryWidget::onDocumentProgress(const FullMsgId &newId) {
if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId);
if (item) {
@ -4457,7 +4473,7 @@ void HistoryWidget::onDocumentProgress(MsgId newId) {
}
}
void HistoryWidget::onAudioProgress(MsgId newId) {
void HistoryWidget::onAudioProgress(const FullMsgId &newId) {
if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId);
if (item) {
@ -4467,7 +4483,7 @@ void HistoryWidget::onAudioProgress(MsgId newId) {
}
}
void HistoryWidget::onPhotoFailed(MsgId newId) {
void HistoryWidget::onPhotoFailed(const FullMsgId &newId) {
if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId);
if (item) {
@ -4476,7 +4492,7 @@ void HistoryWidget::onPhotoFailed(MsgId newId) {
}
}
void HistoryWidget::onDocumentFailed(MsgId newId) {
void HistoryWidget::onDocumentFailed(const FullMsgId &newId) {
if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId);
if (item) {
@ -4485,7 +4501,7 @@ void HistoryWidget::onDocumentFailed(MsgId newId) {
}
}
void HistoryWidget::onAudioFailed(MsgId newId) {
void HistoryWidget::onAudioFailed(const FullMsgId &newId) {
if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId);
if (item) {
@ -4614,7 +4630,15 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown,
} else if (isBotStart()) {
newScrollHeight -= _botStart.height();
} else {
if ((_peer->chat && !_peer->asChat()->forbidden && !_peer->asChat()->left) || (!_peer->chat && _peer->asUser()->access != UserNoAccess)) {
bool avail = false;
if (_peer->isUser()) {
avail = (_peer->asUser()->access != UserNoAccess);
} else if (_peer->isChat()) {
avail = (!_peer->asChat()->forbidden && !_peer->asChat()->left);
} else if (_peer->isChannel()) {
avail = (!_peer->asChannel()->forbidden && !_peer->asChannel()->left);
}
if (avail) {
newScrollHeight -= (_field.height() + 2 * st::sendPadding);
}
if (replyToId() || App::main()->hasForwardingItems() || (_previewData && _previewData->pendingTill >= 0)) {
@ -4668,7 +4692,7 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown,
toY = newSt;
_history->lastWidth = 0;
} else if (initial && _showAtMsgId > 0) {
HistoryItem *item = App::histItemById(_showAtMsgId);
HistoryItem *item = App::histItemById(_channel, _showAtMsgId);
if (!item || item->detached()) {
_showAtMsgId = 0;
_histInited = false;
@ -4742,14 +4766,14 @@ void HistoryWidget::updateBotKeyboard() {
} else if (_replyTo) {
changed = _keyboard.updateMarkup(_replyTo);
} else {
changed = _keyboard.updateMarkup(_history->lastKeyboardId ? App::histItemById(_history->lastKeyboardId) : 0);
changed = _keyboard.updateMarkup(_history->lastKeyboardId ? App::histItemById(_channel, _history->lastKeyboardId) : 0);
}
updateCmdStartShown();
if (!changed) return;
bool hasMarkup = _keyboard.hasMarkup(), forceReply = _keyboard.forceReply() && !_replyTo;
if (hasMarkup || forceReply) {
if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == _history->lastKeyboardId && _history->lastKeyboardUsed) _kbWasHidden = true;
if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) _kbWasHidden = true;
if (!isBotStart() && !isBlocked() && (wasVisible || _replyTo || (_field.getLastText().isEmpty() && !_kbWasHidden))) {
if (!_showAnim.animating()) {
if (hasMarkup) {
@ -4767,7 +4791,7 @@ void HistoryWidget::updateBotKeyboard() {
int32 maxh = hasMarkup ? qMin(_keyboard.height(), int(st::maxFieldHeight) - (int(st::maxFieldHeight) / 2)) : 0;
_field.setMaxHeight(st::maxFieldHeight - maxh);
_kbShown = hasMarkup;
_kbReplyTo = (_history->peer->chat || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
_kbReplyTo = (_history->peer->isChat() || _history->peer->isChannel() || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
if (_kbReplyTo && !_replyToId) {
updateReplyToName();
_replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
@ -4911,7 +4935,7 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) {
fastShowAtEnd(_history);
uint64 randomId = MTP::nonce<uint64>();
MsgId newId = clientMsgId();
FullMsgId newId(_channel, clientMsgId());
bool lastKeyboardUsed = lastForceReplyReplied();
@ -4922,7 +4946,7 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) {
flags |= MTPDmessage::flag_reply_to_msg_id;
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
}
_history->addToBackDocument(newId, flags, replyToId(), date(MTP_int(unixtime())), MTP::authedId(), sticker);
_history->addToBackDocument(newId.msg, flags, replyToId(), date(MTP_int(unixtime())), MTP::authedId(), sticker);
_history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaDocument(MTP_inputDocument(MTP_long(sticker->id), MTP_long(sticker->access))), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, _history->sendRequestId);
App::main()->finishForwarding(_history);
@ -4981,8 +5005,9 @@ void HistoryWidget::onReplyToMessage() {
_field.setFocus();
}
bool HistoryWidget::lastForceReplyReplied(MsgId replyTo) const {
return _keyboard.forceReply() && _keyboard.forMsgId() == _history->lastKeyboardId && _keyboard.forMsgId() == (replyTo < 0 ? replyToId() : replyTo);
bool HistoryWidget::lastForceReplyReplied(const FullMsgId &replyTo) const {
if (replyTo.msg > 0 && replyTo.channel != _channel) return false;
return _keyboard.forceReply() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _keyboard.forMsgId().msg == (replyTo.msg < 0 ? replyToId() : replyTo.msg);
}
void HistoryWidget::cancelReply(bool lastKeyboardUsed) {
@ -5192,9 +5217,9 @@ void HistoryWidget::peerUpdated(PeerData *data) {
if (data && data == _peer) {
updateListSize();
if (!_showAnim.animating()) updateControlsVisibility();
if (data->chat && data->asChat()->count > 0 && data->asChat()->participants.isEmpty()) {
if (data->isChat() && data->asChat()->count > 0 && data->asChat()->participants.isEmpty()) {
App::api()->requestFullPeer(data);
} else if (!data->chat && data->asUser()->blocked == UserBlockUnknown) {
} else if (data->isUser() && data->asUser()->blocked == UserBlockUnknown) {
App::api()->requestFullPeer(data);
} else if (!_scroll.isHidden() && _unblock.isHidden() == isBlocked()) {
updateControlsVisibility();
@ -5278,7 +5303,7 @@ void HistoryWidget::onClearSelected() {
void HistoryWidget::onAnimActiveStep() {
if (!_history || _activeAnimMsgId <= 0) return _animActiveTimer.stop();
HistoryItem *item = App::histItemById(_activeAnimMsgId);
HistoryItem *item = App::histItemById(_channel, _activeAnimMsgId);
if (!item || item->detached()) return _animActiveTimer.stop();
if (getms() - _animActiveStart > st::activeFadeInDuration + st::activeFadeOutDuration) {
@ -5326,7 +5351,7 @@ void HistoryWidget::updateTopBarSelection() {
void HistoryWidget::updateReplyTo(bool force) {
if (!_replyToId || _replyTo) return;
_replyTo = App::histItemById(_replyToId);
_replyTo = App::histItemById(_channel, _replyToId);
if (_replyTo) {
_replyToText.setText(st::msgFont, _replyTo->inDialogsText(), _textDlgOptions);

View file

@ -232,7 +232,7 @@ public:
bool maximizeSize() const;
bool singleUse() const;
MsgId forMsgId() const {
FullMsgId forMsgId() const {
return _wasForMsgId;
}
@ -246,7 +246,7 @@ private:
void updateStyle(int32 w = -1);
void clearSelection();
MsgId _wasForMsgId;
FullMsgId _wasForMsgId;
int32 _height, _maxOuterHeight;
bool _maximizeSize, _singleUse, _forceReply;
QTimer _cmdTipTimer;
@ -442,7 +442,7 @@ public:
MsgId replyToId() const;
void updateReplyTo(bool force = false);
bool lastForceReplyReplied(MsgId replyTo = -1) const;
bool lastForceReplyReplied(const FullMsgId &replyTo = FullMsgId(NoChannel, -1)) const;
void cancelReply(bool lastKeyboardUsed = false);
void updateForwarding(bool force = false);
void cancelForwarding(); // called by MainWidget
@ -502,18 +502,18 @@ public slots:
void peerUpdated(PeerData *data);
void onFullPeerUpdated(PeerData *data);
void onPhotoUploaded(MsgId msgId, const MTPInputFile &file);
void onDocumentUploaded(MsgId msgId, const MTPInputFile &file);
void onThumbDocumentUploaded(MsgId msgId, const MTPInputFile &file, const MTPInputFile &thumb);
void onAudioUploaded(MsgId msgId, const MTPInputFile &file);
void onPhotoUploaded(const FullMsgId &msgId, const MTPInputFile &file);
void onDocumentUploaded(const FullMsgId &msgId, const MTPInputFile &file);
void onThumbDocumentUploaded(const FullMsgId &msgId, const MTPInputFile &file, const MTPInputFile &thumb);
void onAudioUploaded(const FullMsgId &msgId, const MTPInputFile &file);
void onPhotoProgress(MsgId msgId);
void onDocumentProgress(MsgId msgId);
void onAudioProgress(MsgId msgId);
void onPhotoProgress(const FullMsgId &msgId);
void onDocumentProgress(const FullMsgId &msgId);
void onAudioProgress(const FullMsgId &msgId);
void onPhotoFailed(MsgId msgId);
void onDocumentFailed(MsgId msgId);
void onAudioFailed(MsgId msgId);
void onPhotoFailed(const FullMsgId &msgId);
void onDocumentFailed(const FullMsgId &msgId);
void onAudioFailed(const FullMsgId &msgId);
void onListScroll();
void onHistoryToEnd();
@ -625,6 +625,7 @@ private:
void updateDragAreas();
PeerData *_peer;
ChannelId _channel;
MsgId _showAtMsgId;
mtpRequestId _firstLoadRequest, _preloadRequest, _preloadDownRequest;

View file

@ -43,7 +43,7 @@ void LocalImageLoaderPrivate::prepareImages() {
ToPrepareMediaType type;
bool animated = false;
bool ctrlShiftEnter = false;
MsgId replyTo = 0;
MsgId replyTo;
{
QMutexLocker lock(loader->toPrepareMutex());
ToPrepareMedias &list(loader->toPrepareMedias());

View file

@ -2762,16 +2762,21 @@ namespace Local {
uint32 _peerSize(PeerData *peer) {
uint32 result = sizeof(quint64) + sizeof(quint64) + _storageImageLocationSize();
if (peer->chat) {
ChatData *chat = peer->asChat();
// name + count + date + version + admin + forbidden + left + invitationUrl
result += _stringSize(chat->name) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(chat->invitationUrl);
} else {
if (peer->isUser()) {
UserData *user = peer->asUser();
// first + last + phone + username + access + onlineTill + contact + botInfoVersion
result += _stringSize(user->firstName) + _stringSize(user->lastName) + _stringSize(user->phone) + _stringSize(user->username) + sizeof(quint64) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32);
} else if (peer->isChat()) {
ChatData *chat = peer->asChat();
// name + count + date + version + admin + forbidden + left + invitationUrl
result += _stringSize(chat->name) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(chat->invitationUrl);
} else if (peer->isChannel()) {
ChannelData *channel = peer->asChannel();
// name + access + date + version + forbidden + left + invitationUrl
result += _stringSize(channel->name) + sizeof(quint64) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(channel->invitationUrl);
}
return result;
}
@ -2779,15 +2784,20 @@ namespace Local {
void _writePeer(QDataStream &stream, PeerData *peer) {
stream << quint64(peer->id) << quint64(peer->photoId);
_writeStorageImageLocation(stream, peer->photoLoc);
if (peer->chat) {
if (peer->isUser()) {
UserData *user = peer->asUser();
stream << user->firstName << user->lastName << user->phone << user->username << quint64(user->access) << qint32(user->onlineTill) << qint32(user->contact) << qint32(user->botInfo ? user->botInfo->version : -1);
} else if (peer->isChat()) {
ChatData *chat = peer->asChat();
stream << chat->name << qint32(chat->count) << qint32(chat->date) << qint32(chat->version) << qint32(chat->admin);
stream << qint32(chat->forbidden ? 1 : 0) << qint32(chat->left ? 1 : 0) << chat->invitationUrl;
} else {
UserData *user = peer->asUser();
} else if (peer->isChannel()) {
ChannelData *channel = peer->asChannel();
stream << user->firstName << user->lastName << user->phone << user->username << quint64(user->access) << qint32(user->onlineTill) << qint32(user->contact) << qint32(user->botInfo ? user->botInfo->version : -1);
stream << channel->name << quint64(channel->access) << qint32(channel->date) << qint32(channel->version);
stream << qint32(channel->forbidden ? 1 : 0) << qint32(channel->left ? 1 : 0) << channel->invitationUrl;
}
}
@ -2800,7 +2810,34 @@ namespace Local {
result = App::peer(peerId);
result->loaded = true;
if (result->chat) {
if (result->isUser()) {
UserData *user = result->asUser();
QString first, last, phone, username;
quint64 access;
qint32 onlineTill, contact, botInfoVersion;
from.stream >> first >> last >> phone >> username >> access >> onlineTill >> contact >> botInfoVersion;
bool showPhone = !isServiceUser(user->id) && (peerToUser(user->id) != MTP::authedId()) && (contact <= 0);
QString pname = (showPhone && !phone.isEmpty()) ? App::formatPhone(phone) : QString();
user->setName(first, last, pname, username);
user->access = access;
user->onlineTill = onlineTill;
user->contact = contact;
user->setBotInfoVersion(botInfoVersion);
if (peerToUser(user->id) == MTP::authedId()) {
user->input = MTP_inputPeerSelf();
user->inputUser = MTP_inputUserSelf();
} else {
user->input = MTP_inputPeerUser(MTP_int(peerToUser(user->id)), MTP_long((user->access == UserNoAccess) ? 0 : user->access));
user->inputUser = MTP_inputUser(MTP_int(peerToUser(user->id)), MTP_long((user->access == UserNoAccess) ? 0 : user->access));
}
user->photo = photoLoc.isNull() ? ImagePtr(userDefPhoto(user->colorIndex)) : ImagePtr(photoLoc);
} else if (result->isChat()) {
ChatData *chat = result->asChat();
QString name, invitationUrl;
@ -2816,36 +2853,30 @@ namespace Local {
chat->left = (left == 1);
chat->invitationUrl = invitationUrl;
chat->input = MTP_inputPeerChat(MTP_int(App::chatFromPeer(chat->id)));
chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id)));
chat->inputChat = MTP_inputChat(MTP_int(peerToChat(chat->id)));
chat->photo = photoLoc.isNull() ? ImagePtr(chatDefPhoto(chat->colorIndex)) : ImagePtr(photoLoc);
} else {
UserData *user = result->asUser();
} else if (result->isChannel()) {
ChannelData *channel = result->asChannel();
QString first, last, phone, username;
QString name, invitationUrl;
quint64 access;
qint32 onlineTill, contact, botInfoVersion;
from.stream >> first >> last >> phone >> username >> access >> onlineTill >> contact >> botInfoVersion;
qint32 date, version, forbidden, left;
from.stream >> name >> access >> date >> version >> forbidden >> left >> invitationUrl;
bool showPhone = !isServiceUser(user->id) && (App::userFromPeer(user->id) != MTP::authedId()) && (contact <= 0);
QString pname = (showPhone && !phone.isEmpty()) ? App::formatPhone(phone) : QString();
channel->updateName(name, QString(), QString());
channel->access = access;
channel->date = date;
channel->version = version;
channel->forbidden = (forbidden == 1);
channel->left = (left == 1);
channel->invitationUrl = invitationUrl;
user->setName(first, last, pname, username);
channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access));
channel->inputChat = MTP_inputChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access));
user->access = access;
user->onlineTill = onlineTill;
user->contact = contact;
user->setBotInfoVersion(botInfoVersion);
if (App::userFromPeer(user->id) == MTP::authedId()) {
user->input = MTP_inputPeerSelf();
user->inputUser = MTP_inputUserSelf();
} else {
user->input = MTP_inputPeerUser(MTP_int(App::userFromPeer(user->id)), MTP_long((user->access == UserNoAccess) ? 0 : user->access));
user->inputUser = MTP_inputUser(MTP_int(App::userFromPeer(user->id)), MTP_long((user->access == UserNoAccess) ? 0 : user->access));
}
user->photo = photoLoc.isNull() ? ImagePtr(userDefPhoto(user->colorIndex)) : ImagePtr(photoLoc);
channel->photo = photoLoc.isNull() ? ImagePtr(chatDefPhoto(channel->colorIndex)) : ImagePtr(photoLoc);
}
App::markPeerUpdated(result);
emit App::main()->peerPhotoChanged(result);

View file

@ -77,8 +77,8 @@ void TopBarWidget::onInfoClicked() {
void TopBarWidget::onAddContact() {
PeerData *p = App::main() ? App::main()->profilePeer() : 0;
UserData *u = (p && !p->chat) ? p->asUser() : 0;
if (u) App::wnd()->showLayer(new AddContactBox(u->firstName, u->lastName, u->phone.isEmpty() ? App::phoneFromSharedContact(App::userFromPeer(u->id)) : u->phone));
UserData *u = p ? p->asUser() : 0;
if (u) App::wnd()->showLayer(new AddContactBox(u->firstName, u->lastName, u->phone.isEmpty() ? App::phoneFromSharedContact(peerToUser(u->id)) : u->phone));
}
void TopBarWidget::onEdit() {
@ -88,7 +88,7 @@ void TopBarWidget::onEdit() {
void TopBarWidget::onDeleteContact() {
PeerData *p = App::main() ? App::main()->profilePeer() : 0;
UserData *u = (p && !p->chat) ? p->asUser() : 0;
UserData *u = p ? p->asUser() : 0;
if (u) {
ConfirmBox *box = new ConfirmBox(lng_sure_delete_contact(lt_contact, p->name));
connect(box, SIGNAL(confirmed()), this, SLOT(onDeleteContactSure()));
@ -98,7 +98,7 @@ void TopBarWidget::onDeleteContact() {
void TopBarWidget::onDeleteContactSure() {
PeerData *p = App::main() ? App::main()->profilePeer() : 0;
UserData *u = (p && !p->chat) ? p->asUser() : 0;
UserData *u = p ? p->asUser() : 0;
if (u) {
App::main()->showDialogs();
App::wnd()->hideLayer();
@ -108,7 +108,7 @@ void TopBarWidget::onDeleteContactSure() {
void TopBarWidget::onDeleteAndExit() {
PeerData *p = App::main() ? App::main()->profilePeer() : 0;
ChatData *c = (p && p->chat) ? p->asChat() : 0;
ChatData *c = p ? p->asChat() : 0;
if (c) {
ConfirmBox *box = new ConfirmBox(lng_sure_delete_and_exit(lt_group, p->name));
connect(box, SIGNAL(confirmed()), this, SLOT(onDeleteAndExitSure()));
@ -118,11 +118,11 @@ void TopBarWidget::onDeleteAndExit() {
void TopBarWidget::onDeleteAndExitSure() {
PeerData *p = App::main() ? App::main()->profilePeer() : 0;
ChatData *c = (p && p->chat) ? p->asChat() : 0;
ChatData *c = p ? p->asChat() : 0;
if (c) {
App::main()->showDialogs();
App::wnd()->hideLayer();
MTP::send(MTPmessages_DeleteChatUser(MTP_int(p->id & 0xFFFFFFFF), App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, p), App::main()->rpcFail(&MainWidget::leaveChatFailed, p));
MTP::send(MTPmessages_DeleteChatUser(c->inputChat, App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, p), App::main()->rpcFail(&MainWidget::leaveChatFailed, p));
}
}
@ -278,8 +278,8 @@ void TopBarWidget::showAll() {
return;
}
PeerData *p = App::main() ? App::main()->profilePeer() : 0, *o = App::main() ? App::main()->overviewPeer() : 0;
if (p && (p->chat || p->asUser()->contact >= 0 || !App::phoneFromSharedContact(App::userFromPeer(p->id)).isEmpty())) {
if (p->chat) {
if (p && (p->isChat() || (p->isUser() && (p->asUser()->contact >= 0 || !App::phoneFromSharedContact(peerToUser(p->id)).isEmpty())))) {
if (p->isChat()) {
if (p->asChat()->forbidden) {
_edit.hide();
} else {
@ -511,9 +511,9 @@ void MainWidget::finishForwarding(History *hist) {
App::main()->readServerHistory(hist, false);
if (_toForward.size() < 2) {
uint64 randomId = MTP::nonce<uint64>();
MsgId newId = clientMsgId();
FullMsgId newId(peerToChannel(hist->peer->id), clientMsgId());
HistoryMessage *msg = static_cast<HistoryMessage*>(_toForward.cbegin().value());
hist->addToBackForwarded(newId, msg);
hist->addToBackForwarded(newId.msg, msg);
App::historyRegRandom(randomId, newId);
hist->sendRequestId = MTP::send(MTPmessages_ForwardMessage(hist->peer->input, MTP_int(_toForward.cbegin().key()), MTP_long(randomId)), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
if (HistorySticker *sticker = dynamic_cast<HistorySticker*>(msg->getMedia())) {
@ -772,7 +772,7 @@ void MainWidget::deleteMessages(const QVector<MTPint> &ids) {
void MainWidget::deletedContact(UserData *user, const MTPcontacts_Link &result) {
const MTPDcontacts_link &d(result.c_contacts_link());
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser), false);
App::feedUserLink(MTP_int(user->id & 0xFFFFFFFF), d.vmy_link, d.vforeign_link, false);
App::feedUserLink(MTP_int(peerToUser(user->id)), d.vmy_link, d.vforeign_link, false);
App::emitPeerUpdated();
}
@ -802,7 +802,7 @@ void MainWidget::removeContact(UserData *user) {
void MainWidget::addParticipants(ChatData *chat, const QVector<UserData*> &users) {
for (QVector<UserData*>::const_iterator i = users.cbegin(), e = users.cend(); i != e; ++i) {
MTP::send(MTPmessages_AddChatUser(MTP_int(chat->id & 0xFFFFFFFF), (*i)->inputUser, MTP_int(ForwardOnAdd)), rpcDone(&MainWidget::sentUpdatesReceived), rpcFail(&MainWidget::addParticipantFail, *i), 0, 5);
MTP::send(MTPmessages_AddChatUser(chat->inputChat, (*i)->inputUser, MTP_int(ForwardOnAdd)), rpcDone(&MainWidget::sentUpdatesReceived), rpcFail(&MainWidget::addParticipantFail, *i), 0, 5);
}
App::wnd()->hideLayer();
showPeerHistory(chat->id, ShowAtTheEndMsgId);
@ -823,7 +823,7 @@ bool MainWidget::addParticipantFail(UserData *user, const RPCError &error) {
}
void MainWidget::kickParticipant(ChatData *chat, UserData *user) {
MTP::send(MTPmessages_DeleteChatUser(MTP_int(chat->id & 0xFFFFFFFF), user->inputUser), rpcDone(&MainWidget::sentUpdatesReceived), rpcFail(&MainWidget::kickParticipantFail, chat));
MTP::send(MTPmessages_DeleteChatUser(chat->inputChat, user->inputUser), rpcDone(&MainWidget::sentUpdatesReceived), rpcFail(&MainWidget::kickParticipantFail, chat));
App::wnd()->hideLayer();
showPeerHistory(chat->id, ShowAtTheEndMsgId);
}
@ -836,7 +836,7 @@ bool MainWidget::kickParticipantFail(ChatData *chat, const RPCError &error) {
}
void MainWidget::checkPeerHistory(PeerData *peer) {
MTP::send(MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(0), MTP_int(1)), rpcDone(&MainWidget::checkedHistory, peer));
MTP::send(MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(1)), rpcDone(&MainWidget::checkedHistory, peer));
}
void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &result) {
@ -858,7 +858,7 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu
if ((profile && profile->peer() == peer) || (overview && overview->peer() == peer) || _stack.contains(peer) || history.peer() == peer) {
showDialogs();
}
if (peer->chat && peer->asChat()->left) {
if (peer->isChat() && peer->asChat()->left) {
dialogs.removePeer(peer);
} else {
History *h = App::historyLoaded(peer->id);
@ -1043,13 +1043,13 @@ void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId repl
QString sendingText, leftText = text;
if (replyTo < 0) replyTo = history.replyToId();
while (textSplit(sendingText, leftText, MaxMessageSize)) {
MsgId newId = clientMsgId();
FullMsgId newId(peerToChannel(hist->peer->id), clientMsgId());
uint64 randomId = MTP::nonce<uint64>();
sendingText = cleanMessage(sendingText);
App::historyRegRandom(randomId, newId);
App::historyRegSentText(randomId, sendingText);
App::historyRegSentData(randomId, hist->peer->id, sendingText);
MTPstring msgText(MTP_string(sendingText));
int32 flags = newMessageFlags(hist->peer) | MTPDmessage::flag_entities; // unread, out
@ -1067,7 +1067,7 @@ void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId repl
flags |= MTPDmessage::flag_media;
}
MTPVector<MTPMessageEntity> localEntities = linksToMTP(textParseLinks(sendingText, itemTextParseOptions(hist, App::self()).flags));
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, localEntities));
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(MTP::authedId()), peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, localEntities));
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup, localEntities), App::main()->rpcDone(&MainWidget::sentUpdatesReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
}
@ -1485,7 +1485,7 @@ void MainWidget::audioLoadProgress(mtpFileLoader *loader) {
if (audio->loader->done()) {
audio->finish();
QString already = audio->already();
bool play = audio->openOnSave > 0 && audio->openOnSaveMsgId && audioPlayer();
bool play = audio->openOnSave > 0 && audio->openOnSaveMsgId.msg && audioPlayer();
if ((!already.isEmpty() && audio->openOnSave) || (!audio->data.isEmpty() && play)) {
if (play) {
AudioMsgId playing;
@ -1645,17 +1645,17 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
document->finish();
QString already = document->already();
HistoryItem *item = (document->openOnSave && document->openOnSaveMsgId) ? App::histItemById(document->openOnSaveMsgId) : 0;
HistoryItem *item = (document->openOnSave && document->openOnSaveMsgId.msg) ? App::histItemById(document->openOnSaveMsgId) : 0;
bool play = document->song() && audioPlayer() && document->openOnSave && item;
if ((!already.isEmpty() || (!document->data.isEmpty() && play)) && document->openOnSave) {
if (play) {
SongMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped;
audioPlayer()->currentState(&playing, &playingState);
if (playing.msgId == item->id && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
audioPlayer()->pauseresume(OverviewDocuments);
} else {
SongMsgId song(document, item->id);
SongMsgId song(document, item->fullId());
audioPlayer()->play(song);
if (App::main()) App::main()->documentPlayProgress(song);
}
@ -1773,7 +1773,7 @@ void MainWidget::confirmShareContact(bool ctrlShiftEnter, const QString &phone,
}
void MainWidget::confirmSendImage(const ReadyLocalMedia &img) {
bool lastKeyboardUsed = history.lastForceReplyReplied(img.replyTo);
bool lastKeyboardUsed = history.lastForceReplyReplied(FullMsgId(peerToChannel(img.peer), img.replyTo));
history.confirmSendImage(img);
history.cancelReply(lastKeyboardUsed);
}
@ -1962,7 +1962,7 @@ void MainWidget::choosePeer(PeerId peerId, MsgId showAtMsgId) {
}
void MainWidget::clearBotStartToken(PeerData *peer) {
if (peer && !peer->chat && peer->asUser()->botInfo) {
if (peer && peer->isUser() && peer->asUser()->botInfo) {
peer->asUser()->botInfo->startToken = QString();
}
}
@ -2925,9 +2925,9 @@ void MainWidget::inviteCheckDone(QString hash, const MTPChatInvite &invite) {
case mtpc_chatInviteAlready: {
const MTPDchatInviteAlready &d(invite.c_chatInviteAlready());
ChatData *chat = App::feedChats(MTP_vector<MTPChat>(1, d.vchat));
PeerData *chat = App::feedChats(MTP_vector<MTPChat>(1, d.vchat));
if (chat) {
if (chat->left) {
if ((chat->isChat() && chat->asChat()->left) || (chat->isChannel() && chat->asChannel()->left)) {
ConfirmBox *box = new ConfirmBox(lng_group_invite_want_join(lt_title, chat->name), lang(lng_group_invite_join));
_inviteHash = '/' + QString::number(chat->id);
connect(box, SIGNAL(confirmed()), this, SLOT(onInviteImport()));
@ -2952,8 +2952,8 @@ bool MainWidget::inviteCheckFail(const RPCError &error) {
void MainWidget::onInviteImport() {
if (_inviteHash.isEmpty()) return;
if (_inviteHash.at(0) == '/') {
PeerId peer = _inviteHash.midRef(1).toULongLong();
MTP::send(MTPmessages_AddChatUser(MTP_int(peer & 0xFFFFFFFF), App::self()->inputUser, MTP_int(ForwardOnAdd)), rpcDone(&MainWidget::inviteImportDone), rpcFail(&MainWidget::inviteImportFail), 0, 5);
PeerId id = _inviteHash.midRef(1).toULongLong();
MTP::send(MTPmessages_AddChatUser(MTP_inputChat(MTP_int(peerToChat(id))), App::self()->inputUser, MTP_int(ForwardOnAdd)), rpcDone(&MainWidget::inviteImportDone), rpcFail(&MainWidget::inviteImportFail), 0, 5);
} else {
MTP::send(MTPmessages_ImportChatInvite(MTP_string(_inviteHash)), rpcDone(&MainWidget::inviteImportDone), rpcFail(&MainWidget::inviteImportFail));
}
@ -2979,7 +2979,7 @@ void MainWidget::inviteImportDone(const MTPUpdates &updates) {
} break;
}
if (v && !v->isEmpty() && v->front().type() == mtpc_chat) {
App::main()->showPeerHistory(App::peerFromChat(v->front().c_chat().vid.v), ShowAtTheEndMsgId);
App::main()->showPeerHistory(peerFromChat(v->front().c_chat().vid.v), ShowAtTheEndMsgId);
}
}
@ -3008,7 +3008,7 @@ void MainWidget::applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNoti
case mtpc_notifyUsers: globalNotifyUsersPtr = EmptyNotifySettings; break;
case mtpc_notifyChats: globalNotifyChatsPtr = EmptyNotifySettings; break;
case mtpc_notifyPeer: {
PeerData *data = App::peerLoaded(App::peerFromMTP(peer.c_notifyPeer().vpeer));
PeerData *data = App::peerLoaded(peerFromMTP(peer.c_notifyPeer().vpeer));
if (data && data->notify != EmptyNotifySettings) {
if (data->notify != UnknownNotifySettings) {
delete data->notify;
@ -3030,7 +3030,7 @@ void MainWidget::applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNoti
case mtpc_notifyUsers: setTo = globalNotifyUsersPtr = &globalNotifyUsers; break;
case mtpc_notifyChats: setTo = globalNotifyChatsPtr = &globalNotifyChats; break;
case mtpc_notifyPeer: {
data = App::peerLoaded(App::peerFromMTP(peer.c_notifyPeer().vpeer));
data = App::peerLoaded(peerFromMTP(peer.c_notifyPeer().vpeer));
if (!data) break;
if (data->notify == UnknownNotifySettings || data->notify == EmptyNotifySettings) {
@ -3215,7 +3215,7 @@ void MainWidget::updateOnlineDisplayIn(int32 msecs) {
void MainWidget::addNewContact(int32 uid, bool show) {
if (dialogs.addNewContact(uid, show)) {
showPeerHistory(App::peerFromUser(uid), ShowAtTheEndMsgId);
showPeerHistory(peerFromUser(uid), ShowAtTheEndMsgId);
}
}
@ -3412,22 +3412,30 @@ void MainWidget::handleUpdates(const MTPUpdates &updates, uint64 randomId) {
case mtpc_updateShortSentMessage: {
const MTPDupdateShortSentMessage &d(updates.c_updateShortSentMessage());
HistoryItem *item = 0;
if (randomId) {
QString text = App::histSentTextByItem(randomId);
PeerId peerId = 0;
QString text;
App::histSentDataByItem(randomId, peerId, text);
feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date
if (!text.isEmpty()) {
bool hasLinks = d.has_entities() && !d.ventities.c_vector().v.isEmpty();
item = App::histItemById(d.vid.v);
if (item && ((hasLinks && !item->hasTextLinks()) || (!hasLinks && item->textHasLinks()))) {
bool was = item->hasTextLinks();
item->setText(text, d.has_entities() ? linksFromMTP(d.ventities.c_vector().v) : LinksInText());
item->initDimensions(0);
itemResized(item);
if (!was && item->hasTextLinks()) {
item->history()->addToOverview(item, OverviewLinks);
if (peerId) {
HistoryItem *item = App::histItemById(peerToChannel(peerId), d.vid.v);
if (!text.isEmpty()) {
bool hasLinks = d.has_entities() && !d.ventities.c_vector().v.isEmpty();
if (item && ((hasLinks && !item->hasTextLinks()) || (!hasLinks && item->textHasLinks()))) {
bool was = item->hasTextLinks();
item->setText(text, d.has_entities() ? linksFromMTP(d.ventities.c_vector().v) : LinksInText());
item->initDimensions(0);
itemResized(item);
if (!was && item->hasTextLinks()) {
item->history()->addToOverview(item, OverviewLinks);
}
}
}
if (item) {
item->setMedia(d.has_media() ? (&d.vmedia) : 0);
}
}
}
@ -3435,12 +3443,6 @@ void MainWidget::handleUpdates(const MTPUpdates &updates, uint64 randomId) {
_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
return;
}
if (!item) {
item = App::histItemById(d.vid.v);
}
if (item) {
item->setMedia(d.has_media() ? (&d.vmedia) : 0);
}
updSetState(0, d.vdate.v, updQts, updSeq);
} break;
@ -3474,8 +3476,8 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
case mtpc_updateMessageID: {
const MTPDupdateMessageID &d(update.c_updateMessageID());
MsgId msg = App::histItemByRandom(d.vrandom_id.v);
if (msg) {
FullMsgId msg = App::histItemByRandom(d.vrandom_id.v);
if (msg.msg) {
HistoryItem *msgRow = App::histItemById(msg);
if (msgRow) {
App::historyUnregItem(msgRow);
@ -3506,7 +3508,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
}
App::historyUnregRandom(d.vrandom_id.v);
}
App::historyUnregSentText(d.vrandom_id.v);
App::historyUnregSentData(d.vrandom_id.v);
} break;
case mtpc_updateReadMessagesContents: {
@ -3517,11 +3519,11 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
}
const QVector<MTPint> &v(d.vmessages.c_vector().v);
for (int32 i = 0, l = v.size(); i < l; ++i) {
if (HistoryItem *item = App::histItemById(v.at(i).v)) {
if (HistoryItem *item = App::histItemById(NoChannel, v.at(i).v)) {
if (item->isMediaUnread()) {
item->markMediaRead();
msgUpdated(item->history()->peer->id, item);
if (item->out() && !item->history()->peer->chat) {
if (item->out() && item->history()->peer->isUser()) {
item->history()->peer->asUser()->madeAction();
}
}
@ -3535,7 +3537,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
return;
}
App::feedInboxRead(App::peerFromMTP(d.vpeer), d.vmax_id.v);
App::feedInboxRead(peerFromMTP(d.vpeer), d.vmax_id.v);
} break;
case mtpc_updateReadHistoryOutbox: {
@ -3544,9 +3546,9 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
return;
}
PeerId peer = App::peerFromMTP(d.vpeer);
App::feedOutboxRead(peer, d.vmax_id.v);
if (history.peer() && history.peer()->id == peer) history.update();
PeerId id = peerFromMTP(d.vpeer);
App::feedOutboxRead(id, d.vmax_id.v);
if (history.peer() && history.peer()->id == id) history.update();
} break;
case mtpc_updateWebPage: {
@ -3562,13 +3564,13 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
return;
}
App::feedWereDeleted(d.vmessages.c_vector().v);
App::feedWereDeleted(NoChannel, d.vmessages.c_vector().v);
history.peerMessagesUpdated();
} break;
case mtpc_updateUserTyping: {
const MTPDupdateUserTyping &d(update.c_updateUserTyping());
History *history = App::historyLoaded(App::peerFromUser(d.vuser_id));
History *history = App::historyLoaded(peerFromUser(d.vuser_id));
UserData *user = App::userLoaded(d.vuser_id.v);
if (history && user) {
App::histories().regSendAction(history, user, d.vaction);
@ -3577,7 +3579,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
case mtpc_updateChatUserTyping: {
const MTPDupdateChatUserTyping &d(update.c_updateChatUserTyping());
History *history = App::historyLoaded(App::peerFromChat(d.vchat_id));
History *history = App::historyLoaded(peerFromChat(d.vchat_id));
UserData *user = (d.vuser_id.v == MTP::authedId()) ? 0 : App::userLoaded(d.vuser_id.v);
if (history && user) {
App::histories().regSendAction(history, user, d.vaction);

View file

@ -64,7 +64,7 @@ _docRadialFirst(0), _docRadialStart(0), _docRadialLast(0), _docRadialOpacity(1),
_docDownload(this, lang(lng_media_download), st::mvDocLink),
_docSaveAs(this, lang(lng_mediaview_save_as), st::mvDocLink),
_docCancel(this, lang(lng_cancel), st::mvDocLink),
_history(0), _peer(0), _user(0), _from(0), _index(-1), _msgid(0),
_history(0), _peer(0), _user(0), _from(0), _index(-1), _msgid(0), _channel(NoChannel),
_loadRequest(0), _over(OverNone), _down(OverNone), _lastAction(-st::mvDeltaFromLastAction, -st::mvDeltaFromLastAction), _ignoringDropdown(false),
_controlsState(ControlsShown), _controlsAnimStarted(0),
_menu(0), _dropdown(this, st::mvDropdown), _receiveMouse(true), _touchPress(false), _touchMove(false), _touchRightButton(false),
@ -266,7 +266,7 @@ void MediaView::updateControls() {
d = date(_photo->date);
} else if (_doc) {
d = date(_doc->date);
} else if (HistoryItem *item = App::histItemById(_msgid)) {
} else if (HistoryItem *item = App::histItemById(_channel, _msgid)) {
d = item->date;
}
if (d.date() == dNow.date()) {
@ -315,7 +315,7 @@ void MediaView::updateDropdown() {
_btnSaveAs->setVisible(true);
_btnCopy->setVisible((_doc && !_current.isNull()) || (_photo && _photo->full->loaded()));
_btnForward->setVisible(_msgid > 0);
_btnDelete->setVisible(_msgid > 0 || (_photo && App::self() && App::self()->photoId == _photo->id) || (_photo && _photo->chat && _photo->chat->photoId == _photo->id));
_btnDelete->setVisible(_msgid > 0 || (_photo && App::self() && App::self()->photoId == _photo->id) || (_photo && _photo->peer && _photo->peer->photoId == _photo->id));
_btnViewAll->setVisible((_overview != OverviewCount) && _history);
_btnViewAll->setText(lang(_doc ? lng_mediaview_files_all : lng_mediaview_photos_all));
_dropdown.updateButtons();
@ -383,7 +383,7 @@ bool MediaView::animStep(float64 msp) {
QString fname(_doc->already(true));
QImageReader reader(fname);
if (reader.canRead()) {
displayDocument(_doc, App::histItemById(_msgid));
displayDocument(_doc, App::histItemById(_channel, _msgid));
}
}
} else {
@ -443,7 +443,7 @@ void MediaView::onDropdownHiding() {
void MediaView::onToMessage() {
if (_menu) _menu->fastHide();
if (HistoryItem *item = _msgid ? App::histItemById(_msgid) : 0) {
if (HistoryItem *item = _msgid ? App::histItemById(_channel, _msgid) : 0) {
if (App::wnd()) {
close();
if (App::main()) App::main()->showPeerHistory(item->history()->peer->id, _msgid);
@ -581,7 +581,7 @@ void MediaView::onShowInFolder() {
}
void MediaView::onForward() {
HistoryItem *item = App::histItemById(_msgid);
HistoryItem *item = App::histItemById(_channel, _msgid);
if (!_msgid || !item) return;
if (App::wnd()) {
@ -598,11 +598,11 @@ void MediaView::onDelete() {
if (!_msgid) {
if (App::self() && _photo && App::self()->photoId == _photo->id) {
App::app()->peerClearPhoto(App::self()->id);
} else if (_photo->chat && _photo->chat->photoId == _photo->id) {
App::app()->peerClearPhoto(_photo->chat->id);
} else if (_photo->peer && _photo->peer->photoId == _photo->id) {
App::app()->peerClearPhoto(_photo->peer->id);
}
} else {
HistoryItem *item = App::histItemById(_msgid);
HistoryItem *item = App::histItemById(_channel, _msgid);
if (item) {
App::contextItem(item);
App::main()->deleteLayer();
@ -654,6 +654,7 @@ void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) {
_index = -1;
_msgid = context ? context->id : 0;
_channel = context ? context->channelId() : NoChannel;
_photo = photo;
if (_history) {
_overview = OverviewPhotos;
@ -668,7 +669,7 @@ void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) {
void MediaView::showPhoto(PhotoData *photo, PeerData *context) {
_history = 0;
_peer = context;
_user = context->chat ? 0 : context->asUser();
_user = context->asUser();
_saveMsgStarted = 0;
_loadRequest = 0;
_over = OverNone;
@ -680,6 +681,7 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) {
if (!_animOpacities.isEmpty()) _animOpacities.clear();
_msgid = 0;
_channel = NoChannel;
_index = -1;
_photo = photo;
_overview = OverviewCount;
@ -722,6 +724,7 @@ void MediaView::showDocument(DocumentData *doc, HistoryItem *context) {
_index = -1;
_msgid = context ? context->id : 0;
_channel = context ? context->channelId() : NoChannel;
if (_history) {
_overview = OverviewDocuments;
@ -1379,8 +1382,9 @@ void MediaView::moveToNext(int32 delta) {
if (_history && _overview != OverviewCount) {
if (newIndex >= 0 && newIndex < _history->_overview[_overview].size()) {
_index = newIndex;
if (HistoryItem *item = App::histItemById(_history->_overview[_overview][_index])) {
if (HistoryItem *item = App::histItemById(_history->channelId(), _history->_overview[_overview][_index])) {
_msgid = item->id;
_channel = item->channelId();
if (item->getMedia()) {
switch (item->getMedia()->type()) {
case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo(), item); preloadData(delta); break;
@ -1416,7 +1420,7 @@ void MediaView::preloadData(int32 delta) {
if (_history && _overview != OverviewCount) {
for (int32 i = from; i <= to; ++i) {
if (i >= 0 && i < _history->_overview[_overview].size() && i != _index) {
if (HistoryItem *item = App::histItemById(_history->_overview[_overview][i])) {
if (HistoryItem *item = App::histItemById(_history->channelId(), _history->_overview[_overview][i])) {
if (HistoryMedia *media = item->getMedia()) {
switch (media->type()) {
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->full->load(); break;
@ -1428,7 +1432,7 @@ void MediaView::preloadData(int32 delta) {
}
}
if (forget >= 0 && forget < _history->_overview[_overview].size() && forget != _index) {
if (HistoryItem *item = App::histItemById(_history->_overview[_overview][forget])) {
if (HistoryItem *item = App::histItemById(_history->channelId(), _history->_overview[_overview][forget])) {
if (HistoryMedia *media = item->getMedia()) {
switch (media->type()) {
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->forget(); break;

View file

@ -160,6 +160,7 @@ private:
int32 _index; // index in photos or files array, -1 if just photo
MsgId _msgid; // msgId of current photo or file
ChannelId _channel;
mtpRequestId _loadRequest;

View file

@ -366,7 +366,7 @@ static const mtpTypeId mtpLayers[] = {
mtpc_invokeWithLayer17,
mtpc_invokeWithLayer18,
}, mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
static const mtpPrime mtpCurrentLayer = 36;
static const mtpPrime mtpCurrentLayer = 40;
template <typename bareT>
class MTPBoxed : public bareT {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -133,13 +133,17 @@ null#56730bcc = Null;
inputPeerEmpty#7f3b18ea = InputPeer;
inputPeerSelf#7da07ec9 = InputPeer;
inputPeerChat#179be863 chat_id:int = InputPeer;
inputPeerUser#7b8e7de6 user_id:int access_hash:long = InputPeer;
inputPeerChannel#20adaef8 channel_id:int access_hash:long = InputPeer;
inputUserEmpty#b98886cf = InputUser;
inputUserSelf#f7c1b13f = InputUser;
inputUser#d8292816 user_id:int access_hash:long = InputUser;
inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_name:string = InputContact;
inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile;
inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile;
inputMediaEmpty#9664f57f = InputMedia;
inputMediaUploadedPhoto#f7aff1c0 file:InputFile caption:string = InputMedia;
@ -149,6 +153,12 @@ inputMediaContact#a6e45987 phone_number:string first_name:string last_name:strin
inputMediaUploadedVideo#82713fdf file:InputFile duration:int w:int h:int mime_type:string caption:string = InputMedia;
inputMediaUploadedThumbVideo#7780ddf9 file:InputFile thumb:InputFile duration:int w:int h:int mime_type:string caption:string = InputMedia;
inputMediaVideo#936a4ebd id:InputVideo caption:string = InputMedia;
inputMediaUploadedAudio#4e498cab file:InputFile duration:int mime_type:string = InputMedia;
inputMediaAudio#89938781 id:InputAudio = InputMedia;
inputMediaUploadedDocument#ffe76b78 file:InputFile mime_type:string attributes:Vector<DocumentAttribute> = InputMedia;
inputMediaUploadedThumbDocument#41481486 file:InputFile thumb:InputFile mime_type:string attributes:Vector<DocumentAttribute> = InputMedia;
inputMediaDocument#d184e841 id:InputDocument = InputMedia;
inputMediaVenue#2827a81a geo_point:InputGeoPoint title:string address:string provider:string venue_id:string = InputMedia;
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
inputChatUploadedPhoto#94254732 file:InputFile crop:InputPhotoCrop = InputChatPhoto;
@ -165,6 +175,9 @@ inputVideo#ee579652 id:long access_hash:long = InputVideo;
inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
inputVideoFileLocation#3d0364ec id:long access_hash:long = InputFileLocation;
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
inputAudioFileLocation#74dc404d id:long access_hash:long = InputFileLocation;
inputDocumentFileLocation#4e45abe9 id:long access_hash:long = InputFileLocation;
inputPhotoCropAuto#ade6b004 = InputPhotoCrop;
inputPhotoCrop#d9915325 crop_left:double crop_top:double crop_width:double = InputPhotoCrop;
@ -173,6 +186,7 @@ inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppE
peerUser#9db1bc6d user_id:int = Peer;
peerChat#bad0e5bb chat_id:int = Peer;
peerChannel#bddde532 channel_id:int = Peer;
storage.fileUnknown#aa963b05 = storage.FileType;
storage.fileJpeg#7efe0e = storage.FileType;
@ -189,6 +203,7 @@ fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileL
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
userEmpty#200250ba id:int = User;
user#22e49072 flags:# id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
@ -196,12 +211,17 @@ userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileL
userStatusEmpty#9d05049 = UserStatus;
userStatusOnline#edb93949 expires:int = UserStatus;
userStatusOffline#8c703f was_online:int = UserStatus;
userStatusRecently#e26f42f1 = UserStatus;
userStatusLastWeek#7bf09fc = UserStatus;
userStatusLastMonth#77ebc742 = UserStatus;
chatEmpty#9ba2d800 id:int = Chat;
chat#6e9c9bc7 id:int title:string photo:ChatPhoto participants_count:int date:int left:Bool version:int = Chat;
chatForbidden#fb0ccc41 id:int title:string date:int = Chat;
channel#8dbb1461 flags:# id:int access_hash:long title:string photo:ChatPhoto date:int version:int = Chat;
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
channelFull#eb8a0d68 id:int read_inbox_max_id:int unread_count:int unread_important_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite = ChatFull;
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
@ -212,8 +232,8 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
messageEmpty#83e5de54 id:int = Message;
message#2bebfa86 flags:# id:int from_id:int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> = Message;
messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message;
message#ab406723 flags:# id:int from_id:flags.8?int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> = Message;
messageService#c06b9607 flags:# id:int from_id:flags.8?int to_id:Peer date:int action:MessageAction = Message;
messageMediaEmpty#3ded6320 = MessageMedia;
messageMediaPhoto#3d8ce53d photo:Photo caption:string = MessageMedia;
@ -221,6 +241,10 @@ messageMediaVideo#5bcf1675 video:Video caption:string = MessageMedia;
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
messageMediaUnsupported#9f84f49e = MessageMedia;
messageMediaDocument#2fda2204 document:Document = MessageMedia;
messageMediaAudio#c6b68300 audio:Audio = MessageMedia;
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
messageMediaVenue#7912b71f geo:GeoPoint title:string address:string provider:string venue_id:string = MessageMedia;
messageActionEmpty#b6aef7b0 = MessageAction;
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
@ -229,8 +253,11 @@ messageActionChatEditPhoto#7fcb13a8 photo:Photo = MessageAction;
messageActionChatDeletePhoto#95e3fbef = MessageAction;
messageActionChatAddUser#5e3cfc4b user_id:int = MessageAction;
messageActionChatDeleteUser#b2ae9b0c user_id:int = MessageAction;
messageActionChatJoinedByLink#f89cf5e8 inviter_id:int = MessageAction;
messageActionChannelCreate#95d2ac92 title:string = MessageAction;
dialog#c1dd804a peer:Peer top_message:int read_inbox_max_id:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
dialogChannel#5b8496b2 peer:Peer top_message:int top_important_message:int read_inbox_max_id:int unread_count:int unread_important_count:int notify_settings:PeerNotifySettings pts:int = Dialog;
photoEmpty#2331b22d id:long = Photo;
photo#cded42fe id:long access_hash:long date:int sizes:Vector<PhotoSize> = Photo;
@ -248,6 +275,7 @@ geoPoint#2049d70c long:double lat:double = GeoPoint;
auth.checkedPhone#811ea28e phone_registered:Bool = auth.CheckedPhone;
auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
auth.sentAppCode#e325edcf phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
auth.authorization#ff036af1 user:User = auth.Authorization;
@ -270,6 +298,7 @@ peerNotifySettingsEmpty#70a68512 = PeerNotifySettings;
peerNotifySettings#8d5e11ee mute_until:int sound:string show_previews:Bool events_mask:int = PeerNotifySettings;
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
userFull#5a89ac5b user:User link:contacts.Link profile_photo:Photo notify_settings:PeerNotifySettings blocked:Bool bot_info:BotInfo = UserFull;
@ -300,6 +329,7 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.channelMessages#bc0f17bc flags:# pts:int count:int messages:Vector<Message> collapsed:flags.0?Vector<MessageGroup> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
@ -329,6 +359,26 @@ updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bo
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
updateContactLink#9d2e67c5 user_id:int my_link:ContactLink foreign_link:ContactLink = Update;
updateNewAuthorization#8f06529a auth_key_id:long date:int device:string location:string = Update;
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
updateEncryptedMessagesRead#38fe25b7 chat_id:int max_date:int date:int = Update;
updateChatParticipantAdd#3a0eeb22 chat_id:int user_id:int inviter_id:int version:int = Update;
updateChatParticipantDelete#6e5f8c22 chat_id:int user_id:int version:int = Update;
updateDcOptions#8e5e9873 dc_options:Vector<DcOption> = Update;
updateUserBlocked#80ece81a user_id:int blocked:Bool = Update;
updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings = Update;
updateServiceNotification#382dd3e4 type:string message:string media:MessageMedia popup:Bool = Update;
updatePrivacy#ee3b272a key:PrivacyKey rules:Vector<PrivacyRule> = Update;
updateUserPhone#12b9417b user_id:int phone:string = Update;
updateReadHistoryInbox#9961fd5c peer:Peer max_id:int pts:int pts_count:int = Update;
updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Update;
updateWebPage#2cc36971 webpage:WebPage = Update;
updateReadMessagesContents#68c13933 messages:Vector<int> pts:int pts_count:int = Update;
updateChannelTooLong#60946422 channel_id:int = Update;
updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update;
updateReadChannelInbox#87b87b7d peer:Peer max_id:int = Update;
updateDeleteChannelMessages#11da3046 peer:Peer messages:Vector<int> pts:int pts_count:int = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -342,6 +392,7 @@ updateShortChatMessage#f9409b3d flags:# id:int from_id:int chat_id:int message:s
updateShort#78d4dec1 update:Update date:int = Updates;
updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
updateShortSentMessage#11f1331c flags:# id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector<MessageEntity> = Updates;
photos.photos#8dca6aa5 photos:Vector<Photo> users:Vector<User> = photos.Photos;
photos.photosSlice#15051f54 count:int photos:Vector<Photo> users:Vector<User> = photos.Photos;
@ -361,13 +412,6 @@ help.noAppUpdate#c45a6536 = help.AppUpdate;
help.inviteText#18cb9f78 message:string = help.InviteText;
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
updateEncryptedMessagesRead#38fe25b7 chat_id:int max_date:int date:int = Update;
encryptedChatEmpty#ab7ec0a0 id:int = EncryptedChat;
encryptedChatWaiting#3bf703dc id:int access_hash:long date:int admin_id:int participant_id:int = EncryptedChat;
encryptedChatRequested#c878527e id:int access_hash:long date:int admin_id:int participant_id:int g_a:bytes = EncryptedChat;
@ -382,8 +426,7 @@ encryptedFile#4a70994c id:long access_hash:long size:int dc_id:int key_fingerpri
inputEncryptedFileEmpty#1837c364 = InputEncryptedFile;
inputEncryptedFileUploaded#64bd0306 id:long parts:int md5_checksum:string key_fingerprint:int = InputEncryptedFile;
inputEncryptedFile#5a17b5e5 id:long access_hash:long = InputEncryptedFile;
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
inputEncryptedFileBigUploaded#2dc173c8 id:long parts:int key_fingerprint:int = InputEncryptedFile;
encryptedMessage#ed18c118 random_id:long chat_id:int date:int bytes:bytes file:EncryptedFile = EncryptedMessage;
encryptedMessageService#23734b06 random_id:long chat_id:int date:int bytes:bytes = EncryptedMessage;
@ -394,32 +437,12 @@ messages.dhConfig#2c221edd g:int p:bytes version:int random:bytes = messages.DhC
messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage;
messages.sentEncryptedFile#9493ff32 date:int file:EncryptedFile = messages.SentEncryptedMessage;
inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile;
inputEncryptedFileBigUploaded#2dc173c8 id:long parts:int key_fingerprint:int = InputEncryptedFile;
updateChatParticipantAdd#3a0eeb22 chat_id:int user_id:int inviter_id:int version:int = Update;
updateChatParticipantDelete#6e5f8c22 chat_id:int user_id:int version:int = Update;
updateDcOptions#8e5e9873 dc_options:Vector<DcOption> = Update;
inputMediaUploadedAudio#4e498cab file:InputFile duration:int mime_type:string = InputMedia;
inputMediaAudio#89938781 id:InputAudio = InputMedia;
inputMediaUploadedDocument#ffe76b78 file:InputFile mime_type:string attributes:Vector<DocumentAttribute> = InputMedia;
inputMediaUploadedThumbDocument#41481486 file:InputFile thumb:InputFile mime_type:string attributes:Vector<DocumentAttribute> = InputMedia;
inputMediaDocument#d184e841 id:InputDocument = InputMedia;
messageMediaDocument#2fda2204 document:Document = MessageMedia;
messageMediaAudio#c6b68300 audio:Audio = MessageMedia;
inputAudioEmpty#d95adc84 = InputAudio;
inputAudio#77d440ff id:long access_hash:long = InputAudio;
inputDocumentEmpty#72f0eaae = InputDocument;
inputDocument#18798952 id:long access_hash:long = InputDocument;
inputAudioFileLocation#74dc404d id:long access_hash:long = InputFileLocation;
inputDocumentFileLocation#4e45abe9 id:long access_hash:long = InputFileLocation;
audioEmpty#586988d8 id:long = Audio;
audio#f9e35055 id:long access_hash:long date:int duration:int mime_type:string size:int dc_id:int = Audio;
@ -433,11 +456,6 @@ notifyUsers#b4c83b4c = NotifyPeer;
notifyChats#c007cec3 = NotifyPeer;
notifyAll#74d07c60 = NotifyPeer;
updateUserBlocked#80ece81a user_id:int blocked:Bool = Update;
updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings = Update;
auth.sentAppCode#e325edcf phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
sendMessageTypingAction#16bf744e = SendMessageAction;
sendMessageCancelAction#fd5ec8f5 = SendMessageAction;
sendMessageRecordVideoAction#a187d66f = SendMessageAction;
@ -453,14 +471,6 @@ contactFound#ea879f95 user_id:int = ContactFound;
contacts.found#566000e results:Vector<ContactFound> users:Vector<User> = contacts.Found;
updateServiceNotification#382dd3e4 type:string message:string media:MessageMedia popup:Bool = Update;
userStatusRecently#e26f42f1 = UserStatus;
userStatusLastWeek#7bf09fc = UserStatus;
userStatusLastMonth#77ebc742 = UserStatus;
updatePrivacy#ee3b272a key:PrivacyKey rules:Vector<PrivacyRule> = Update;
inputPrivacyKeyStatusTimestamp#4f96cb18 = InputPrivacyKey;
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
@ -485,8 +495,6 @@ accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
account.sentChangePhoneCode#a4f58c4c phone_code_hash:string send_call_timeout:int = account.SentChangePhoneCode;
updateUserPhone#12b9417b user_id:int phone:string = Update;
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
documentAttributeAnimated#11b58939 = DocumentAttribute;
documentAttributeSticker#3a556302 alt:string stickerset:InputStickerSet = DocumentAttribute;
@ -504,9 +512,6 @@ messages.allStickers#d51dafdb hash:string sets:Vector<StickerSet> = messages.All
disabledFeature#ae636f24 feature:string description:string = DisabledFeature;
updateReadHistoryInbox#9961fd5c peer:Peer max_id:int pts:int pts_count:int = Update;
updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Update;
messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages;
contactLinkUnknown#5f4f9247 = ContactLink;
@ -514,14 +519,10 @@ contactLinkNone#feedd3ad = ContactLink;
contactLinkHasPhone#268f3f59 = ContactLink;
contactLinkContact#d502c2d0 = ContactLink;
updateWebPage#2cc36971 webpage:WebPage = Update;
webPageEmpty#eb1477e8 id:long = WebPage;
webPagePending#c586da1c id:long date:int = WebPage;
webPage#ca820ed7 flags:# id:long url:string display_url:string type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document = WebPage;
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
authorization#7bf2e6f6 hash:long flags:int device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
account.authorizations#1250abde authorizations:Vector<Authorization> = account.Authorizations;
@ -535,10 +536,6 @@ account.passwordInputSettings#bcfc532c flags:# new_salt:flags.0?bytes new_passwo
auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery;
inputMediaVenue#2827a81a geo_point:InputGeoPoint title:string address:string provider:string venue_id:string = InputMedia;
messageMediaVenue#7912b71f geo:GeoPoint title:string address:string provider:string venue_id:string = MessageMedia;
receivedNotifyMessage#a384b779 id:int flags:int = ReceivedNotifyMessage;
chatInviteEmpty#69df3769 = ExportedChatInvite;
@ -547,10 +544,6 @@ chatInviteExported#fc2e05bc link:string = ExportedChatInvite;
chatInviteAlready#5a686d7c chat:Chat = ChatInvite;
chatInvite#ce917dcd title:string = ChatInvite;
messageActionChatJoinedByLink#f89cf5e8 inviter_id:int = MessageAction;
updateReadMessagesContents#68c13933 messages:Vector<int> pts:int pts_count:int = Update;
inputStickerSetEmpty#ffb62b95 = InputStickerSet;
inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
@ -559,8 +552,6 @@ stickerSet#cd303b41 flags:# id:long access_hash:long title:string short_name:str
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
user#22e49072 flags:# id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int = User;
botCommand#c27ac8c7 command:string description:string = BotCommand;
botInfoEmpty#bb2e37ce = BotInfo;
@ -574,10 +565,6 @@ replyKeyboardHide#a03e5b85 flags:# = ReplyMarkup;
replyKeyboardForceReply#f4108aa0 flags:# = ReplyMarkup;
replyKeyboardMarkup#3502758c flags:# rows:Vector<KeyboardButtonRow> = ReplyMarkup;
inputPeerUser#7b8e7de6 user_id:int access_hash:long = InputPeer;
inputUser#d8292816 user_id:int access_hash:long = InputUser;
help.appChangelogEmpty#af7e0394 = help.AppChangelog;
help.appChangelog#4668e6bd text:string = help.AppChangelog;
@ -593,13 +580,28 @@ messageEntityCode#28a20571 offset:int length:int = MessageEntity;
messageEntityPre#73924be0 offset:int length:int language:string = MessageEntity;
messageEntityTextUrl#76a6d327 offset:int length:int url:string = MessageEntity;
updateShortSentMessage#11f1331c flags:# id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector<MessageEntity> = Updates;
inputChatEmpty#d9ff343c = InputChat;
inputChat#43a5b9c3 chat_id:int = InputChat;
inputChannel#30c6ce73 channel_id:int access_hash:long = InputChat;
messageRange#ae30253 min_id:int max_id:int = MessageRange;
messageGroup#e8346f53 min_id:int max_id:int count:int date:int = MessageGroup;
updates.channelDifferenceEmpty#3e11affb flags:# pts:int timeout:flags.1?int = updates.ChannelDifference;
updates.channelDifferenceTooLong#5e167646 flags:# pts:int timeout:flags.1?int top_message:int top_important_message:int read_inbox_max_id:int unread_count:int unread_important_count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = updates.ChannelDifference;
updates.channelDifference#2064674e flags:# pts:int timeout:flags.1?int new_messages:Vector<Message> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> = updates.ChannelDifference;
channelMessagesFilterEmpty#94d42ee7 = ChannelMessagesFilter;
channelMessagesFilter#cd77d957 flags:# ranges:Vector<MessageRange> = ChannelMessagesFilter;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
initConnection#69796de9 {X:Type} api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone;
auth.sendCode#768d5f4d phone_number:string sms_type:int api_id:int api_hash:string lang_code:string = auth.SentCode;
@ -612,6 +614,11 @@ auth.sendInvites#771c1d97 phone_numbers:Vector<string> message:string = Bool;
auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
auth.importAuthorization#e3ef9613 id:int bytes:bytes = auth.Authorization;
auth.bindTempAuthKey#cdd42a05 perm_auth_key_id:long nonce:long expires_at:int encrypted_message:bytes = Bool;
auth.sendSms#da9f3e8 phone_number:string phone_code_hash:string = Bool;
auth.importBotAuthorization#67a3ff2c flags:int api_id:int api_hash:string bot_auth_token:string = auth.Authorization;
auth.checkPassword#a63011e password_hash:bytes = auth.Authorization;
auth.requestPasswordRecovery#d897bc66 = auth.PasswordRecovery;
auth.recoverPassword#4ea56e92 code:string = auth.Authorization;
account.registerDevice#446c712c token_type:int token:string device_model:string system_version:string app_version:string app_sandbox:Bool lang_code:string = Bool;
account.unregisterDevice#65c55b40 token_type:int token:string = Bool;
@ -621,6 +628,21 @@ account.resetNotifySettings#db7e1747 = Bool;
account.updateProfile#f0888d68 first_name:string last_name:string = User;
account.updateStatus#6628562c offline:Bool = Bool;
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
account.checkUsername#2714d86c username:string = Bool;
account.updateUsername#3e0bdd7c username:string = User;
account.getPrivacy#dadbc950 key:InputPrivacyKey = account.PrivacyRules;
account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector<InputPrivacyRule> = account.PrivacyRules;
account.deleteAccount#418d4e0b reason:string = Bool;
account.getAccountTTL#8fc711d = AccountDaysTTL;
account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
account.sendChangePhoneCode#a407a8f4 phone_number:string = account.SentChangePhoneCode;
account.changePhone#70c32edb phone_number:string phone_code_hash:string phone_code:string = User;
account.updateDeviceLocked#38df3532 period:int = Bool;
account.getAuthorizations#e320c158 = account.Authorizations;
account.resetAuthorization#df77f3bc hash:long = Bool;
account.getPassword#548a30f5 = account.Password;
account.getPasswordSettings#bc8d11bb current_password_hash:bytes = account.PasswordSettings;
account.updatePasswordSettings#fa7c4b86 current_password_hash:bytes new_settings:account.PasswordInputSettings = Bool;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
@ -636,10 +658,12 @@ contacts.unblock#e54100bd id:InputUser = Bool;
contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
contacts.exportCard#84e53737 = Vector<int>;
contacts.importCard#4fe196fe export_card:Vector<int> = User;
contacts.search#11f812d8 q:string limit:int = contacts.Found;
contacts.resolveUsername#bf0131c username:string = User;
messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
messages.getDialogs#eccf1df6 offset:int max_id:int limit:int = messages.Dialogs;
messages.getHistory#92a1df2f peer:InputPeer offset:int max_id:int limit:int = messages.Messages;
messages.getDialogs#859b3d3c offset:int limit:int = messages.Dialogs;
messages.getHistory#e1ded325 peer:InputPeer offset:int max_id:int min_id:int limit:int = messages.Messages;
messages.search#7e9f2ab peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
messages.readHistory#b04f2510 peer:InputPeer max_id:int offset:int = messages.AffectedHistory;
messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory;
@ -649,32 +673,13 @@ messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
messages.sendMessage#fa88427a flags:# peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
messages.sendMedia#c8f16791 flags:# peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
messages.forwardMessages#55e1728d peer:InputPeer id:Vector<int> random_id:Vector<long> = Updates;
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
messages.editChatTitle#dc452855 chat_id:int title:string = Updates;
messages.editChatPhoto#ca4c79d8 chat_id:int photo:InputChatPhoto = Updates;
messages.addChatUser#f9a0aa09 chat_id:int user_id:InputUser fwd_limit:int = Updates;
messages.deleteChatUser#e0611f16 chat_id:int user_id:InputUser = Updates;
messages.getChats#27ae65b id:Vector<InputChat> = messages.Chats;
messages.getFullChat#36a4dfe chat_id:InputChat = messages.ChatFull;
messages.editChatTitle#6699d506 chat_id:InputChat title:string = Updates;
messages.editChatPhoto#dd75758d chat_id:InputChat photo:InputChatPhoto = Updates;
messages.addChatUser#819183f4 chat_id:InputChat user_id:InputUser fwd_limit:int = Updates;
messages.deleteChatUser#9392c06f chat_id:InputChat user_id:InputUser = Updates;
messages.createChat#9cb126e users:Vector<InputUser> title:string = Updates;
updates.getState#edd4882a = updates.State;
updates.getDifference#a041495 pts:int date:int qts:int = updates.Difference;
photos.updateProfilePhoto#eef579a0 id:InputPhoto crop:InputPhotoCrop = UserProfilePhoto;
photos.uploadProfilePhoto#d50f9c88 file:InputFile caption:string geo_point:InputGeoPoint crop:InputPhotoCrop = photos.Photo;
photos.deletePhotos#87cf7f2f id:Vector<InputPhoto> = Vector<long>;
upload.saveFilePart#b304a621 file_id:long file_part:int bytes:bytes = Bool;
upload.getFile#e3a6cfb5 location:InputFileLocation offset:int limit:int = upload.File;
help.getConfig#c4f9186b = Config;
help.getNearestDc#1fb33026 = NearestDc;
help.getAppUpdate#c812ac7e device_model:string system_version:string app_version:string lang_code:string = help.AppUpdate;
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
help.getInviteText#a4a95186 lang_code:string = help.InviteText;
photos.getUserPhotos#91cd32a8 user_id:InputUser offset:int max_id:long limit:int = photos.Photos;
messages.forwardMessage#33963bf9 peer:InputPeer id:int random_id:long = Updates;
messages.sendBroadcast#bf73f4da contacts:Vector<InputUser> random_id:Vector<long> message:string media:InputMedia = Updates;
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
@ -687,62 +692,40 @@ messages.sendEncrypted#a9776773 peer:InputEncryptedChat random_id:long data:byte
messages.sendEncryptedFile#9a901b66 peer:InputEncryptedChat random_id:long data:bytes file:InputEncryptedFile = messages.SentEncryptedMessage;
messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
initConnection#69796de9 {X:Type} api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
help.getSupport#9cdf08cd = help.Support;
auth.sendSms#da9f3e8 phone_number:string phone_code_hash:string = Bool;
messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
account.checkUsername#2714d86c username:string = Bool;
account.updateUsername#3e0bdd7c username:string = User;
contacts.search#11f812d8 q:string limit:int = contacts.Found;
account.getPrivacy#dadbc950 key:InputPrivacyKey = account.PrivacyRules;
account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector<InputPrivacyRule> = account.PrivacyRules;
account.deleteAccount#418d4e0b reason:string = Bool;
account.getAccountTTL#8fc711d = AccountDaysTTL;
account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
contacts.resolveUsername#bf0131c username:string = User;
account.sendChangePhoneCode#a407a8f4 phone_number:string = account.SentChangePhoneCode;
account.changePhone#70c32edb phone_number:string phone_code_hash:string phone_code:string = User;
messages.getStickers#ae22e045 emoticon:string hash:string = messages.Stickers;
messages.getAllStickers#aa3bc868 hash:string = messages.AllStickers;
account.updateDeviceLocked#38df3532 period:int = Bool;
auth.importBotAuthorization#67a3ff2c flags:int api_id:int api_hash:string bot_auth_token:string = auth.Authorization;
messages.getWebPagePreview#25223e24 message:string = MessageMedia;
account.getAuthorizations#e320c158 = account.Authorizations;
account.resetAuthorization#df77f3bc hash:long = Bool;
account.getPassword#548a30f5 = account.Password;
account.getPasswordSettings#bc8d11bb current_password_hash:bytes = account.PasswordSettings;
account.updatePasswordSettings#fa7c4b86 current_password_hash:bytes new_settings:account.PasswordInputSettings = Bool;
auth.checkPassword#a63011e password_hash:bytes = auth.Authorization;
auth.requestPasswordRecovery#d897bc66 = auth.PasswordRecovery;
auth.recoverPassword#4ea56e92 code:string = auth.Authorization;
invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
messages.exportChatInvite#c26902ba chat_id:InputChat = ExportedChatInvite;
messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
messages.importChatInvite#6c50051c hash:string = Updates;
messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet;
messages.installStickerSet#7b30c3a6 stickerset:InputStickerSet disabled:Bool = Bool;
messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
messages.startBot#1b3e0ffc bot:InputUser chat_id:int random_id:long start_param:string = Updates;
messages.startBot#f4cc052d bot:InputUser chat_id:InputChat random_id:long start_param:string = Updates;
messages.getChannelDialogs#92689583 offset:int limit:int = messages.Dialogs;
messages.getImportantHistory#25b7f3b2 peer:InputPeer max_id:int min_id:int limit:int = messages.Messages;
messages.readChannelHistory#36a1210e peer:InputPeer max_id:int = Bool;
messages.createChannel#d9bc5fd2 title:string = Updates;
messages.deleteChannelMessages#9995a84f peer:InputPeer id:Vector<int> = messages.AffectedMessages;
updates.getState#edd4882a = updates.State;
updates.getDifference#a041495 pts:int date:int qts:int = updates.Difference;
updates.getChannelDifference#248af4f5 peer:InputPeer filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference;
photos.updateProfilePhoto#eef579a0 id:InputPhoto crop:InputPhotoCrop = UserProfilePhoto;
photos.uploadProfilePhoto#d50f9c88 file:InputFile caption:string geo_point:InputGeoPoint crop:InputPhotoCrop = photos.Photo;
photos.deletePhotos#87cf7f2f id:Vector<InputPhoto> = Vector<long>;
photos.getUserPhotos#91cd32a8 user_id:InputUser offset:int max_id:long limit:int = photos.Photos;
upload.saveFilePart#b304a621 file_id:long file_part:int bytes:bytes = Bool;
upload.getFile#e3a6cfb5 location:InputFileLocation offset:int limit:int = upload.File;
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
help.getConfig#c4f9186b = Config;
help.getNearestDc#1fb33026 = NearestDc;
help.getAppUpdate#c812ac7e device_model:string system_version:string app_version:string lang_code:string = help.AppUpdate;
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
help.getInviteText#a4a95186 lang_code:string = help.InviteText;
help.getSupport#9cdf08cd = help.Support;
help.getAppChangelog#5bab7fb2 device_model:string system_version:string app_version:string lang_code:string = help.AppChangelog;

View file

@ -141,6 +141,7 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const
, _peer(App::peer(peer->id))
, _type(type)
, _hist(App::history(peer->id))
, _channel(peerToChannel(peer->id))
, _photosInRow(1)
, _photosToAdd(0)
, _selMode(false)
@ -398,13 +399,13 @@ bool OverviewInner::itemHasPoint(MsgId msgId, int32 index, int32 x, int32 y) con
return true;
}
} else {
HistoryItem *item = App::histItemById(msgId);
HistoryItem *item = App::histItemById(_channel, msgId);
HistoryMedia *media = item ? item->getMedia(true) : 0;
if (media) {
int32 w = _width - st::msgMargin.left() - st::msgMargin.right();
bool out = item->out();
int32 mw = media->maxWidth(), left = (out ? st::msgMargin.right() : st::msgMargin.left()) + (out && mw < w ? (w - mw) : 0);
if (!out && _hist->peer->chat) {
if (item->displayFromName()) {
left += st::msgPhotoSkip;
}
return media->hasPoint(x - left, y - st::msgMargin.top(), item, w);
@ -912,9 +913,9 @@ void OverviewInner::clear() {
_cached.clear();
}
int32 OverviewInner::itemTop(MsgId msgId) const {
if (_type == OverviewAudioDocuments) {
int32 index = _hist->_overview[_type].indexOf(msgId);
int32 OverviewInner::itemTop(const FullMsgId &msgId) const {
if (_type == OverviewAudioDocuments && msgId.channel == _channel) {
int32 index = _hist->_overview[_type].indexOf(msgId.msg);
if (index >= 0) {
return _addToY + int32(index * _audioHeight);
}
@ -1003,7 +1004,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
if (index < 0) continue;
if (index >= count) break;
HistoryItem *item = App::histItemById(overview[index]);
HistoryItem *item = App::histItemById(_channel, overview[index]);
HistoryMedia *m = item ? item->getMedia(true) : 0;
if (!m) continue;
@ -1082,7 +1083,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
for (int32 index = from; index < to; ++index) {
if (index >= count) break;
HistoryItem *item = App::histItemById(overview[index]);
HistoryItem *item = App::histItemById(_channel, overview[index]);
HistoryMedia *m = item ? item->getMedia(true) : 0;
if (!m || m->type() != MediaTypeDocument) continue;
@ -1201,12 +1202,12 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
p.translate(0, curY - y);
if (_items[i].msgid) { // draw item
HistoryItem *item = App::histItemById(_items[i].msgid);
HistoryItem *item = App::histItemById(_channel, _items[i].msgid);
HistoryMedia *media = item ? item->getMedia(true) : 0;
if (media) {
bool out = item->out();
int32 mw = media->maxWidth(), left = (out ? st::msgMargin.right() : st::msgMargin.left()) + (out && mw < w ? (w - mw) : 0);
if (!out && _hist->peer->chat) {
if (item->displayFromName()) {
p.drawPixmap(left, media->countHeight(item, w) - st::msgPhotoSize, item->from()->photo->pixRounded(st::msgPhotoSize));
left += st::msgPhotoSkip;
}
@ -1290,7 +1291,7 @@ void OverviewInner::onUpdateSelected() {
}
if (i >= 0) {
MsgId msgid = _hist->_overview[_type][i];
HistoryItem *histItem = App::histItemById(msgid);
HistoryItem *histItem = App::histItemById(_channel, msgid);
if (histItem) {
item = histItem;
index = i;
@ -1318,7 +1319,7 @@ void OverviewInner::onUpdateSelected() {
}
if (i >= 0) {
MsgId msgid = _hist->_overview[_type][i];
HistoryItem *histItem = App::histItemById(msgid);
HistoryItem *histItem = App::histItemById(_channel, msgid);
if (histItem) {
item = histItem;
index = i;
@ -1332,7 +1333,7 @@ void OverviewInner::onUpdateSelected() {
}
}
if (newsel != _selectedMsgId) {
if (_selectedMsgId) updateMsg(App::histItemById(_selectedMsgId));
if (_selectedMsgId) updateMsg(App::histItemById(_channel, _selectedMsgId));
_selectedMsgId = newsel;
updateMsg(item);
}
@ -1356,7 +1357,7 @@ void OverviewInner::onUpdateSelected() {
}
}
HistoryItem *histItem = App::histItemById(_items[i].msgid);
HistoryItem *histItem = App::histItemById(_channel, _items[i].msgid);
if (histItem) {
item = histItem;
index = i;
@ -1405,7 +1406,7 @@ void OverviewInner::onUpdateSelected() {
}
}
HistoryItem *histItem = App::histItemById(_items[i].msgid);
HistoryItem *histItem = App::histItemById(_channel, _items[i].msgid);
if (histItem) {
item = histItem;
index = i;
@ -1413,7 +1414,7 @@ void OverviewInner::onUpdateSelected() {
if (media) {
bool out = item->out();
int32 mw = media->maxWidth(), left = (out ? st::msgMargin.right() : st::msgMargin.left()) + (out && mw < w ? (w - mw) : 0);
if (!out && _hist->peer->chat) {
if (item->displayFromName()) {
if (QRect(left, y + st::msgMargin.top() + media->countHeight(item, w) - st::msgPhotoSize, st::msgPhotoSize, st::msgPhotoSize).contains(m)) {
lnk = item->from()->lnk;
}
@ -1449,7 +1450,7 @@ void OverviewInner::onUpdateSelected() {
}
if (lnkIndex != _lnkOverIndex || _mousedItem != oldMousedItem) {
lnkChanged = true;
if (oldMousedItem) updateMsg(App::histItemById(oldMousedItem));
if (oldMousedItem) updateMsg(App::histItemById(_channel, oldMousedItem));
_lnkOverIndex = lnkIndex;
if (item) updateMsg(item);
QToolTip::hideText();
@ -1622,7 +1623,7 @@ void OverviewInner::showLinkTip() {
QToolTip::showText(_dragPos, url, this, r);
}
} else if (_cursorState == HistoryInDateCursorState && _dragAction == NoDrag && _mousedItem) {
if (HistoryItem *item = App::histItemById(_mousedItem)) {
if (HistoryItem *item = App::histItemById(_channel, _mousedItem)) {
QToolTip::showText(_dragPos, item->date.toString(QLocale::system().dateTimeFormat(QLocale::LongFormat)), this, r);
}
}
@ -1674,7 +1675,7 @@ void OverviewInner::enterEvent(QEvent *e) {
void OverviewInner::leaveEvent(QEvent *e) {
if (_selectedMsgId > 0) {
updateMsg(App::histItemById(_selectedMsgId));
updateMsg(App::histItemById(_channel, _selectedMsgId));
_selectedMsgId = 0;
}
if (textlnkOver()) {
@ -1707,7 +1708,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
_menu->deleteLater();
_menu = 0;
updateMsg(App::contextItem());
if (_selectedMsgId > 0) updateMsg(App::histItemById(_selectedMsgId));
if (_selectedMsgId > 0) updateMsg(App::histItemById(_channel, _selectedMsgId));
}
if (e->reason() == QContextMenuEvent::Mouse) {
dragActionUpdate(e->globalPos());
@ -1776,7 +1777,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
}
App::contextItem(App::hoveredLinkItem());
updateMsg(App::contextItem());
if (_selectedMsgId > 0) updateMsg(App::histItemById(_selectedMsgId));
if (_selectedMsgId > 0) updateMsg(App::histItemById(_channel, _selectedMsgId));
} else if (!ignoreMousedItem && App::mousedItem() && App::mousedItem()->id == _mousedItem) {
_contextMenuUrl = _lnkOverIndex ? urlByIndex(_mousedItem, _mousedItemIndex, _lnkOverIndex) : QString();
_menu = new ContextMenu(_overview);
@ -1810,7 +1811,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
}
App::contextItem(App::mousedItem());
updateMsg(App::contextItem());
if (_selectedMsgId > 0) updateMsg(App::histItemById(_selectedMsgId));
if (_selectedMsgId > 0) updateMsg(App::histItemById(_channel, _selectedMsgId));
}
if (_menu) {
_menu->deleteOnHide();
@ -2052,7 +2053,7 @@ void OverviewInner::onMenuDestroy(QObject *obj) {
_menu = 0;
dragActionUpdate(QCursor::pos());
updateMsg(App::contextItem());
if (_selectedMsgId > 0) updateMsg(App::histItemById(_selectedMsgId));
if (_selectedMsgId > 0) updateMsg(App::histItemById(_channel, _selectedMsgId));
}
}
@ -2083,7 +2084,7 @@ void OverviewInner::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
if (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel) return;
for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) {
HistoryItem *item = App::histItemById(i.key());
HistoryItem *item = App::histItemById(_channel, i.key());
if (dynamic_cast<HistoryMessage*>(item) && item->id > 0) {
sel.insert(item->id, item);
}
@ -2158,7 +2159,7 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
}
allGood = false;
}
HistoryItem *item = App::histItemById(msgid);
HistoryItem *item = App::histItemById(_channel, msgid);
QDate date = item->date.date();
if (!in || (in > 0 && date != prevDate)) {
@ -2211,7 +2212,7 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
if (_items.size() > in && _items.at(in).msgid == msgid) {
prevDate = _items.at(in).date;
if (fromResize) {
HistoryItem *item = App::histItemById(msgid);
HistoryItem *item = App::histItemById(_channel, msgid);
HistoryMedia *media = item ? item->getMedia(true) : 0;
if (media) {
y += media->countHeight(item, w) + st::msgMargin.top() + st::msgMargin.bottom(); // item height
@ -2231,7 +2232,7 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
++in;
prevDate = _items.at(in).date;
if (fromResize) {
HistoryItem *item = App::histItemById(msgid);
HistoryItem *item = App::histItemById(_channel, msgid);
HistoryMedia *media = item ? item->getMedia(true) : 0;
if (media) {
y += media->countHeight(item, w) + st::msgMargin.top() + st::msgMargin.bottom(); // item height
@ -2245,7 +2246,7 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
}
allGood = false;
}
HistoryItem *item = App::histItemById(msgid);
HistoryItem *item = App::histItemById(_channel, msgid);
HistoryMedia *media = item ? item->getMedia(true) : 0;
if (!media) continue;
@ -2513,7 +2514,7 @@ OverviewWidget::OverviewWidget(QWidget *parent, const PeerData *peer, MediaOverv
connect(&_scrollTimer, SIGNAL(timeout()), this, SLOT(onScrollTimer()));
_scrollTimer.setSingleShot(false);
connect(App::main()->player(), SIGNAL(playerSongChanged(MsgId)), this, SLOT(onPlayerSongChanged(MsgId)));
connect(App::main()->player(), SIGNAL(playerSongChanged(const FullMsgId&)), this, SLOT(onPlayerSongChanged(const FullMsgId&)));
switchType(type);
}
@ -2848,7 +2849,7 @@ void OverviewWidget::onScrollTimer() {
_scroll.scrollToY(_scroll.scrollTop() + d);
}
void OverviewWidget::onPlayerSongChanged(MsgId msgId) {
void OverviewWidget::onPlayerSongChanged(const FullMsgId &msgId) {
if (type() == OverviewAudioDocuments) {
// int32 top = _inner.itemTop(msgId);
// if (top > 0) {

View file

@ -28,7 +28,7 @@ public:
void activate();
void clear();
int32 itemTop(MsgId msgId) const;
int32 itemTop(const FullMsgId &msgId) const;
bool preloadLocal();
void preloadMore();
@ -133,6 +133,7 @@ private:
PeerData *_peer;
MediaOverviewType _type;
History *_hist;
ChannelId _channel;
// photos
int32 _photosInRow, _photosToAdd, _vsize;
@ -319,7 +320,7 @@ public slots:
void onScroll();
void onScrollTimer();
void onPlayerSongChanged(MsgId msgId);
void onPlayerSongChanged(const FullMsgId &msgId);
void onForwardSelected();
void onDeleteSelected();

View file

@ -262,21 +262,24 @@ void PlayerWidget::findCurrent() {
if (!_history) return;
const History::MediaOverview *o = &_history->_overview[OverviewAudioDocuments];
for (int i = 0, l = o->size(); i < l; ++i) {
if (o->at(i) == _song.msgId) {
_index = i;
break;
if (_history->channelId() == _song.msgId.channel) {
for (int i = 0, l = o->size(); i < l; ++i) {
if (o->at(i) == _song.msgId.msg) {
_index = i;
break;
}
}
}
if (_index < 0) return;
if (_index < o->size() - 1) {
if (HistoryItem *next = App::histItemById(o->at(_index + 1))) {
if (HistoryItem *next = App::histItemById(_history->channelId(), o->at(_index + 1))) {
if (HistoryDocument *document = static_cast<HistoryDocument*>(next->getMedia())) {
if (document->document()->already(true).isEmpty() && document->document()->data.isEmpty()) {
if (!document->document()->loader) {
DocumentOpenLink::doOpen(document->document());
document->document()->openOnSave = document->document()->openOnSaveMsgId = 0;
document->document()->openOnSave = 0;
document->document()->openOnSaveMsgId = FullMsgId();
}
}
}
@ -284,10 +287,10 @@ void PlayerWidget::findCurrent() {
}
}
void PlayerWidget::startPlay(MsgId msgId) {
void PlayerWidget::startPlay(const FullMsgId &msgId) {
if (HistoryItem *item = App::histItemById(msgId)) {
if (HistoryDocument *doc = static_cast<HistoryDocument*>(item->getMedia())) {
audioPlayer()->play(SongMsgId(doc->document(), item->id));
audioPlayer()->play(SongMsgId(doc->document(), item->fullId()));
updateState();
}
}
@ -303,10 +306,12 @@ void PlayerWidget::clearSelection() {
void PlayerWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
if (_history && _history->peer == peer && type == OverviewAudioDocuments) {
_index = -1;
for (int i = 0, l = _history->_overview[OverviewAudioDocuments].size(); i < l; ++i) {
if (_history->_overview[OverviewAudioDocuments].at(i) == _song.msgId) {
_index = i;
break;
if (_history->channelId() == _song.msgId.channel) {
for (int i = 0, l = _history->_overview[OverviewAudioDocuments].size(); i < l; ++i) {
if (_history->_overview[OverviewAudioDocuments].at(i) == _song.msgId.msg) {
_index = i;
break;
}
}
}
updateControls();
@ -461,7 +466,7 @@ void PlayerWidget::prevPressed() {
const History::MediaOverview *o = _history ? &_history->_overview[OverviewAudioDocuments] : 0;
if (audioPlayer() && o && _index > 0 && _index <= o->size() && !o->isEmpty()) {
startPlay(o->at(_index - 1));
startPlay(FullMsgId(_history->channelId(), o->at(_index - 1)));
}
}
@ -470,7 +475,7 @@ void PlayerWidget::nextPressed() {
const History::MediaOverview *o = _history ? &_history->_overview[OverviewAudioDocuments] : 0;
if (audioPlayer() && o && _index >= 0 && _index < o->size() - 1) {
startPlay(o->at(_index + 1));
startPlay(FullMsgId(_history->channelId(), o->at(_index + 1)));
}
}

View file

@ -53,7 +53,7 @@ public:
signals:
void playerSongChanged(MsgId msgId);
void playerSongChanged(const FullMsgId &msgId);
private:
@ -77,7 +77,7 @@ private:
void updateControls();
void findCurrent();
void startPlay(MsgId msgId);
void startPlay(const FullMsgId &msgId);
QPoint _lastMousePos;
void updateSelected();

View file

@ -30,7 +30,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const PeerData *peer) : TWidget(0),
_profile(profile), _scroll(scroll), _peer(App::peer(peer->id)),
_peerUser(_peer->chat ? 0 : _peer->asUser()), _peerChat(_peer->chat ? _peer->asChat() : 0), _hist(App::history(peer->id)),
_peerUser(_peer->asUser()), _peerChat(_peer->asChat()), _peerChannel(_peer->asChannel()), _hist(App::history(peer->id)),
_chatAdmin(_peerChat ? (_peerChat->admin == MTP::authedId()) : false),
// profile
@ -63,7 +63,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
// actions
_searchInPeer(this, lang(lng_profile_search_messages)),
_clearHistory(this, lang(lng_profile_clear_history)),
_deleteConversation(this, lang(_peer->chat ? lng_profile_clear_and_exit : lng_profile_delete_conversation)),
_deleteConversation(this, lang(_peer->isUser() ? lng_profile_delete_conversation : lng_profile_clear_and_exit)),
_wasBlocked(_peerUser ? _peerUser->blocked : UserBlockUnknown),
_blockRequest(0),
_blockUser(this, lang((_peerUser && _peerUser->botInfo) ? lng_profile_block_bot : lng_profile_block_user), st::btnRedLink),
@ -82,7 +82,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
if (_peerUser->blocked == UserIsBlocked) {
_blockUser.setText(lang(_peerUser->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user));
}
_phoneText = App::formatPhone(_peerUser->phone.isEmpty() ? App::phoneFromSharedContact(App::userFromPeer(_peerUser->id)) : _peerUser->phone);
_phoneText = App::formatPhone(_peerUser->phone.isEmpty() ? App::phoneFromSharedContact(peerToUser(_peerUser->id)) : _peerUser->phone);
PhotoData *userPhoto = (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) ? App::photo(_peerUser->photoId) : 0;
if (userPhoto && userPhoto->date) {
_photoLink = TextLinkPtr(new PhotoLink(userPhoto, _peer));
@ -255,7 +255,7 @@ void ProfileInner::onUpdatePhoto() {
}
void ProfileInner::onClearHistory() {
ConfirmBox *box = new ConfirmBox(_peer->chat ? lng_sure_delete_group_history(lt_group, _peer->name) : lng_sure_delete_history(lt_contact, _peer->name));
ConfirmBox *box = new ConfirmBox(_peer->isUser() ? lng_sure_delete_history(lt_contact, _peer->name) : lng_sure_delete_group_history(lt_group, _peer->name));
connect(box, SIGNAL(confirmed()), this, SLOT(onClearHistorySure()));
App::wnd()->showLayer(box);
}
@ -266,18 +266,19 @@ void ProfileInner::onClearHistorySure() {
}
void ProfileInner::onDeleteConversation() {
ConfirmBox *box = new ConfirmBox(_peer->chat ? lng_sure_delete_and_exit(lt_group, _peer->name) : lng_sure_delete_history(lt_contact, _peer->name));
ConfirmBox *box = new ConfirmBox(_peer->isUser() ? lng_sure_delete_history(lt_contact, _peer->name) : lng_sure_delete_and_exit(lt_group, _peer->name));
connect(box, SIGNAL(confirmed()), this, SLOT(onDeleteConversationSure()));
App::wnd()->showLayer(box);
}
void ProfileInner::onDeleteConversationSure() {
if (_peer->chat) {
if (_peerUser) {
App::main()->deleteConversation(_peer);
} else if (_peerChat) {
App::wnd()->hideLayer();
App::main()->showDialogs();
MTP::send(MTPmessages_DeleteChatUser(MTP_int(_peer->id & 0xFFFFFFFF), App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, _peer), App::main()->rpcFail(&MainWidget::leaveChatFailed, _peer));
} else {
App::main()->deleteConversation(_peer);
MTP::send(MTPmessages_DeleteChatUser(_peerChat->inputChat, App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, _peer), App::main()->rpcFail(&MainWidget::leaveChatFailed, _peer));
} else if (_peerChannel) { // CHANNELS_UX
}
}
@ -370,7 +371,8 @@ void ProfileInner::onCreateInvitationLink() {
}
void ProfileInner::onCreateInvitationLinkSure() {
MTP::send(MTPmessages_ExportChatInvite(App::peerToMTP(_peerChat->id).c_peerChat().vchat_id), rpcDone(&ProfileInner::chatInviteDone));
if (!_peerChat) return;
MTP::send(MTPmessages_ExportChatInvite(_peerChat->inputChat), rpcDone(&ProfileInner::chatInviteDone));
}
void ProfileInner::chatInviteDone(const MTPExportedChatInvite &result) {
@ -434,7 +436,7 @@ void ProfileInner::peerUpdated(PeerData *data) {
if (data == _peer) {
PhotoData *photo = 0;
if (_peerUser) {
_phoneText = App::formatPhone(_peerUser->phone.isEmpty() ? App::phoneFromSharedContact(App::userFromPeer(_peerUser->id)) : _peerUser->phone);
_phoneText = App::formatPhone(_peerUser->phone.isEmpty() ? App::phoneFromSharedContact(peerToUser(_peerUser->id)) : _peerUser->phone);
if (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) photo = App::photo(_peerUser->photoId);
if (_wasBlocked != _peerUser->blocked) {
_wasBlocked = _peerUser->blocked;
@ -673,7 +675,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
top += st::profileHeaderSkip;
top += _searchInPeer.height() + st::setLittleSkip + _clearHistory.height() + st::setLittleSkip + _deleteConversation.height();
if (_peerUser && App::userFromPeer(_peerUser->id) != MTP::authedId()) top += st::setSectionSkip + _blockUser.height();
if (_peerUser && peerToUser(_peerUser->id) != MTP::authedId()) top += st::setSectionSkip + _blockUser.height();
// participants
if (_peerChat && (_peerChat->count > 0 || !_participants.isEmpty())) {
@ -944,7 +946,7 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
_searchInPeer.move(_left, top); top += _searchInPeer.height() + st::setLittleSkip;
_clearHistory.move(_left, top); top += _clearHistory.height() + st::setLittleSkip;
_deleteConversation.move(_left, top); top += _deleteConversation.height();
if (_peerUser && App::userFromPeer(_peerUser->id) != MTP::authedId()) {
if (_peerUser && peerToUser(_peerUser->id) != MTP::authedId()) {
top += st::setSectionSkip;
_blockUser.move(_left, top); top += _blockUser.height();
}
@ -1102,7 +1104,7 @@ void ProfileInner::showAll() {
_inviteToGroup.hide();
}
_clearHistory.show();
if (App::userFromPeer(_peerUser->id) != MTP::authedId()) {
if (peerToUser(_peerUser->id) != MTP::authedId()) {
_blockUser.show();
} else {
_blockUser.hide();
@ -1151,7 +1153,7 @@ void ProfileInner::showAll() {
reorderParticipants();
int32 h;
if (_peerUser) {
if (App::userFromPeer(_peerUser->id) == MTP::authedId()) {
if (peerToUser(_peerUser->id) == MTP::authedId()) {
h = _deleteConversation.y() + _deleteConversation.height() + st::profileHeaderSkip;
} else {
h = _blockUser.y() + _blockUser.height() + st::profileHeaderSkip;
@ -1269,7 +1271,7 @@ void ProfileWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth)
p.drawPixmap(QPoint(st::topBarBackPadding.left(), (st::topBarHeight - st::topBarBackImg.pxHeight()) / 2), App::sprite(), st::topBarBackImg);
p.setFont(st::topBarBackFont->f);
p.setPen(st::topBarBackColor->p);
p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::topBarBackFont->height) / 2 + st::topBarBackFont->ascent, lang(peer()->chat ? lng_profile_group_info : lng_profile_info));
p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::topBarBackFont->height) / 2 + st::topBarBackFont->ascent, lang(peer()->isUser() ? lng_profile_info : lng_profile_group_info));
}
}
@ -1362,7 +1364,7 @@ void ProfileWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type)
}
void ProfileWidget::clear() {
if (_inner.peer() && !_inner.peer()->chat && _inner.peer()->asUser()->botInfo) {
if (_inner.peer() && _inner.peer()->isUser() && _inner.peer()->asUser()->botInfo) {
_inner.peer()->asUser()->botInfo->startGroupToken = QString();
}
}

View file

@ -121,6 +121,7 @@ private:
PeerData *_peer;
UserData *_peerUser;
ChatData *_peerChat;
ChannelData *_peerChannel;
History *_hist;
bool _chatAdmin;

View file

@ -71,7 +71,7 @@ void MacPrivate::notifyClicked(unsigned long long peer, int msgid) {
App::wnd()->hideSettings();
bool tomsg = history->peer->chat && (msgid > 0);
if (tomsg) {
HistoryItem *item = App::histItemById(msgid);
HistoryItem *item = App::histItemById(peerToChannel(PeerId(peer)), MsgId(msgid));
if (!item || !item->notifyByFrom()) {
tomsg = false;
}

View file

@ -2569,7 +2569,8 @@ typedef ABI::Windows::Foundation::ITypedEventHandler<ToastNotification*, ToastFa
class ToastEventHandler : public Implements<DesktopToastActivatedEventHandler, DesktopToastDismissedEventHandler, DesktopToastFailedEventHandler> {
public:
ToastEventHandler::ToastEventHandler(uint64 peer, int32 msg) : _ref(1), _peerId(peer), _msgId(msg) {
ToastEventHandler::ToastEventHandler(const PeerId &peer, MsgId msg) : _ref(1), _peerId(peer), _msgId(msg) {
}
~ToastEventHandler() {
}
@ -2584,7 +2585,7 @@ public:
}
}
if (App::wnd()) {
History *history = App::history(PeerId(_peerId));
History *history = App::history(_peerId);
App::wnd()->showFromTray();
if (App::passcoded()) {
@ -2592,9 +2593,9 @@ public:
App::wnd()->notifyClear();
} else {
App::wnd()->hideSettings();
bool tomsg = history->peer->chat && (_msgId > 0);
bool tomsg = !history->peer->isUser() && (_msgId > 0);
if (tomsg) {
HistoryItem *item = App::histItemById(_msgId);
HistoryItem *item = App::histItemById(peerToChannel(_peerId), _msgId);
if (!item || !item->notifyByFrom()) {
tomsg = false;
}
@ -2673,9 +2674,10 @@ public:
}
private:
ULONG _ref;
uint64 _peerId;
int32 _msgId;
PeerId _peerId;
MsgId _msgId;
};
template<class T>
@ -2708,7 +2710,7 @@ QString toastImage(const StorageKey &key, PeerData *peer) {
if (peer->photo->loaded() && (key.first || key.second)) {
peer->photo->pix().save(v.path, "PNG");
} else if (!key.first && key.second) {
(peer->chat ? chatDefPhoto : userDefPhoto)(peer->colorIndex)->pix().save(v.path, "PNG");
(peer->isUser() ? userDefPhoto : chatDefPhoto)(peer->colorIndex)->pix().save(v.path, "PNG");
} else {
App::wnd()->iconLarge().save(v.path, "PNG");
}
@ -2734,7 +2736,7 @@ bool CreateToast(PeerData *peer, int32 msgId, bool showpix, const QString &title
QString imagePath;
if (showpix) {
if (peer->photoLoc.isNull() || !peer->photo->loaded()) {
key = StorageKey(0, (peer->chat ? 0x2000 : 0x1000) | peer->colorIndex);
key = StorageKey(0, (peer->isUser() ? 0x1000 : 0x2000) | peer->colorIndex);
} else {
key = storageKey(peer->photoLoc);
}

View file

@ -31,18 +31,14 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
namespace {
int32 peerColorIndex(const PeerId &peer) {
int32 myId(MTP::authedId()), peerId(peer & 0xFFFFFFFFL);
bool chat = (peer & 0x100000000L);
if (chat) {
int ch = 0;
}
int32 myId(MTP::authedId()), peerId(peerToBareInt(peer));
QByteArray both(qsl("%1%2").arg(peerId).arg(myId).toUtf8());
if (both.size() > 15) {
both = both.mid(0, 15);
}
uchar md5[16];
hashMd5(both.constData(), both.size(), md5);
return (md5[peerId & 0x0F] & (chat ? 0x03 : 0x07));
return (md5[peerId & 0x0F] & (peerIsUser(peer) ? 0x07 : 0x03));
}
}
@ -89,39 +85,23 @@ NotifySettingsPtr globalNotifyAllPtr = UnknownNotifySettings, globalNotifyUsersP
PeerData::PeerData(const PeerId &id) : id(id)
, loaded(false)
, chat(App::isChat(id))
, colorIndex(peerColorIndex(id))
, color(peerColor(colorIndex))
, photo(chat ? chatDefPhoto(colorIndex) : userDefPhoto(colorIndex))
, photo((isChat() || isChannel()) ? chatDefPhoto(colorIndex) : userDefPhoto(colorIndex))
, photoId(UnknownPeerPhotoId)
, nameVersion(0)
, notify(UnknownNotifySettings)
{
}
UserData *PeerData::asUser() {
return chat ? App::user(id & 0xFFFFFFFFL) : static_cast<UserData *>(this);
}
const UserData *PeerData::asUser() const {
return chat ? App::user(id & 0xFFFFFFFFL) : static_cast<const UserData *>(this);
}
ChatData *PeerData::asChat() {
return chat ? static_cast<ChatData *>(this) : App::chat(id | 0x100000000L);
}
const ChatData *PeerData::asChat() const {
return chat ? static_cast<const ChatData *>(this) : App::chat(id | 0x100000000L);
}
void PeerData::updateName(const QString &newName, const QString &newNameOrPhone, const QString &newUsername) {
if (name == newName && nameOrPhone == newNameOrPhone && (chat || asUser()->username == newUsername) && nameVersion > 0) return;
if (name == newName && nameOrPhone == newNameOrPhone && (!isUser() || asUser()->username == newUsername) && nameVersion > 0) return;
++nameVersion;
name = newName;
nameOrPhone = newNameOrPhone;
if (!chat) asUser()->username = newUsername;
if (isUser()) asUser()->username = newUsername;
Names oldNames = names;
NameFirstChars oldChars = chars;
fillNames();
@ -142,7 +122,7 @@ void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer a
newPhotoId = d.vphoto_id.v;
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
newPhoto = newPhotoLoc.isNull() ? userDefPhoto(colorIndex) : ImagePtr(newPhotoLoc);
//App::feedPhoto(App::photoFromUserPhoto(MTP_int(id & 0xFFFFFFFF), MTP_int(unixtime()), p));
//App::feedPhoto(App::photoFromUserPhoto(peerToUser(id), MTP_int(unixtime()), p));
} break;
default: {
newPhotoId = 0;
@ -171,7 +151,7 @@ void PeerData::fillNames() {
if (nameOrPhone != name) {
toIndex += ' ' + textAccentFold(nameOrPhone);
}
if (!chat) {
if (isUser()) {
toIndex += ' ' + textAccentFold(asUser()->username);
}
if (cRussianLetters().match(toIndex).hasMatch()) {
@ -242,7 +222,7 @@ void UserData::setBotInfo(const MTPBotInfo &info) {
break;
case mtpc_botInfo: {
const MTPDbotInfo &d(info.c_botInfo());
if (App::peerFromUser(d.vuser_id.v) != id) return;
if (peerFromUser(d.vuser_id.v) != id) return;
if (botInfo) {
botInfo->version = d.vversion.v;
@ -339,6 +319,35 @@ void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Loc
}
}
void ChannelData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Local::readPeer as well
PhotoId newPhotoId = photoId;
ImagePtr newPhoto = photo;
StorageImageLocation newPhotoLoc = photoLoc;
switch (p.type()) {
case mtpc_chatPhoto: {
const MTPDchatPhoto d(p.c_chatPhoto());
if (phId != UnknownPeerPhotoId) {
newPhotoId = phId;
}
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
newPhoto = newPhotoLoc.isNull() ? chatDefPhoto(colorIndex) : ImagePtr(newPhotoLoc);
// photoFull = ImagePtr(640, 640, d.vphoto_big, chatDefPhoto(colorIndex));
} break;
default: {
newPhotoId = 0;
newPhotoLoc = StorageImageLocation();
newPhoto = chatDefPhoto(colorIndex);
// photoFull = ImagePtr();
} break;
}
if (newPhotoId != photoId || newPhoto.v() != photo.v() || newPhotoLoc != photoLoc) {
photoId = newPhotoId;
photo = newPhoto;
photoLoc = newPhotoLoc;
emit App::main()->peerPhotoChanged(this);
}
}
void PhotoLink::onClick(Qt::MouseButton button) const {
if (button == Qt::LeftButton) {
App::wnd()->showPhoto(this, App::hoveredLinkItem());
@ -418,7 +427,7 @@ void VideoOpenLink::onClick(Qt::MouseButton button) const {
QString filename = saveFileName(lang(lng_save_video), qsl("MOV Video (*.mov);;All files (*.*)"), qsl("video"), qsl(".mov"), false);
if (!filename.isEmpty()) {
data->openOnSave = 1;
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->id : (App::contextItem() ? App::contextItem()->id : 0);
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
data->save(filename);
}
}
@ -442,7 +451,7 @@ void VideoSaveLink::doSave(VideoData *data, bool forceSavingAs) {
data->cancel();
} else if (!already.isEmpty()) {
data->openOnSave = -1;
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->id : 0;
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : FullMsgId();
}
data->save(filename);
}
@ -462,7 +471,7 @@ void VideoCancelLink::onClick(Qt::MouseButton button) const {
}
VideoData::VideoData(const VideoId &id, const uint64 &access, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size) :
id(id), access(access), date(date), duration(duration), w(w), h(h), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), fileType(0), openOnSave(0), openOnSaveMsgId(0), loader(0) {
id(id), access(access), date(date), duration(duration), w(w), h(h), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), fileType(0), openOnSave(0), loader(0) {
location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
}
@ -491,10 +500,10 @@ void AudioOpenLink::onClick(Qt::MouseButton button) const {
AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped;
audioPlayer()->currentState(&playing, &playingState);
if (playing.msgId == App::hoveredLinkItem()->id && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
if (playing.msgId == App::hoveredLinkItem()->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
audioPlayer()->pauseresume(OverviewAudios);
} else {
audioPlayer()->play(AudioMsgId(data, App::hoveredLinkItem()->id));
audioPlayer()->play(AudioMsgId(data, App::hoveredLinkItem()->fullId()));
if (App::main()) App::main()->audioMarkRead(data);
}
} else {
@ -510,7 +519,7 @@ void AudioOpenLink::onClick(Qt::MouseButton button) const {
QString filename = saveFileName(lang(lng_save_audio), mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), mp3 ? qsl(".mp3") : qsl(".ogg"), false);
if (!filename.isEmpty()) {
data->openOnSave = 1;
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->id : (App::contextItem() ? App::contextItem()->id : 0);
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
data->save(filename);
}
}
@ -535,7 +544,7 @@ void AudioSaveLink::doSave(AudioData *data, bool forceSavingAs) {
data->cancel();
} else if (!already.isEmpty()) {
data->openOnSave = -1;
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->id : (App::contextItem() ? App::contextItem()->id : 0);
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
}
data->save(filename);
}
@ -570,7 +579,7 @@ bool StickerData::setInstalled() const {
}
AudioData::AudioData(const AudioId &id, const uint64 &access, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) :
id(id), access(access), date(date), mime(mime), duration(duration), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), openOnSaveMsgId(0), loader(0) {
id(id), access(access), date(date), mime(mime), duration(duration), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), loader(0) {
location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
}
@ -598,10 +607,10 @@ void DocumentOpenLink::doOpen(DocumentData *data) {
SongMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped;
audioPlayer()->currentState(&playing, &playingState);
if (playing.msgId == App::hoveredLinkItem()->id && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
if (playing.msgId == App::hoveredLinkItem()->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
audioPlayer()->pauseresume(OverviewDocuments);
} else {
SongMsgId song(data, App::hoveredLinkItem()->id);
SongMsgId song(data, App::hoveredLinkItem()->fullId());
audioPlayer()->play(song);
if (App::main()) App::main()->documentPlayProgress(song);
}
@ -643,7 +652,7 @@ void DocumentOpenLink::doOpen(DocumentData *data) {
QString filename = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, false);
if (!filename.isEmpty()) {
data->openOnSave = 1;
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->id : (App::contextItem() ? App::contextItem()->id : 0);
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
data->save(filename);
}
}
@ -685,7 +694,7 @@ void DocumentSaveLink::doSave(DocumentData *data, bool forceSavingAs) {
data->cancel();
} else if (!already.isEmpty()) {
data->openOnSave = -1;
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->id : (App::contextItem() ? App::contextItem()->id : 0);
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
}
data->save(filename);
}
@ -705,7 +714,7 @@ void DocumentCancelLink::onClick(Qt::MouseButton button) const {
}
DocumentData::DocumentData(const DocumentId &id, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size) :
id(id), type(FileDocument), access(access), date(date), mime(mime), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), openOnSaveMsgId(0), loader(0), _additional(0) {
id(id), type(FileDocument), access(access), date(date), mime(mime), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), loader(0), _additional(0) {
setattributes(attributes);
location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
}

View file

@ -17,13 +17,98 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
*/
#pragma once
typedef int32 ChannelId;
static const ChannelId NoChannel = 0;
typedef uint64 PeerId;
static const uint64 PeerIdMask = 0xFFFFFFFFULL;
static const uint64 PeerIdTypeMask = 0x300000000ULL;
static const uint64 PeerIdUserShift = 0x000000000ULL;
static const uint64 PeerIdChatShift = 0x100000000ULL;
static const uint64 PeerIdChannelShift = 0x200000000ULL;
inline bool peerIsUser(const PeerId &id) {
return (id & PeerIdTypeMask) == PeerIdUserShift;
}
inline bool peerIsChat(const PeerId &id) {
return (id & PeerIdTypeMask) == PeerIdChatShift;
}
inline bool peerIsChannel(const PeerId &id) {
return (id & PeerIdTypeMask) == PeerIdChannelShift;
}
inline PeerId peerFromUser(int32 user_id) {
return PeerIdUserShift | uint64(uint32(user_id));
}
inline PeerId peerFromChat(int32 chat_id) {
return PeerIdChatShift | uint64(uint32(chat_id));
}
inline PeerId peerFromChannel(ChannelId channel_id) {
return PeerIdChannelShift | uint64(uint32(channel_id));
}
inline PeerId peerFromUser(const MTPint &user_id) {
return peerFromUser(user_id.v);
}
inline PeerId peerFromChat(const MTPint &chat_id) {
return peerFromChat(chat_id.v);
}
inline PeerId peerFromChannel(const MTPint &channel_id) {
return peerFromChannel(channel_id.v);
}
inline int32 peerToBareInt(const PeerId &id) {
return int32(uint32(id & PeerIdMask));
}
inline int32 peerToUser(const PeerId &id) {
return peerIsUser(id) ? peerToBareInt(id) : 0;
}
inline int32 peerToChat(const PeerId &id) {
return peerIsChat(id) ? peerToBareInt(id) : 0;
}
inline ChannelId peerToChannel(const PeerId &id) {
return peerIsChannel(id) ? peerToBareInt(id) : NoChannel;
}
inline MTPint peerToBareMTPInt(const PeerId &id) {
return MTP_int(peerToBareInt(id));
}
inline PeerId peerFromMTP(const MTPPeer &peer) {
switch (peer.type()) {
case mtpc_peerUser: return peerFromUser(peer.c_peerUser().vuser_id);
case mtpc_peerChat: return peerFromChat(peer.c_peerChat().vchat_id);
case mtpc_peerChannel: return peerFromChannel(peer.c_peerChannel().vchannel_id);
}
return 0;
}
inline MTPpeer peerToMTP(const PeerId &id) {
if (peerIsUser(id)) {
return MTP_peerUser(peerToBareMTPInt(id));
} else if (peerIsChat(id)) {
return MTP_peerChat(peerToBareMTPInt(id));
} else if (peerIsChannel(id)) {
return MTP_peerChannel(peerToBareMTPInt(id));
}
return MTP_peerUser(MTP_int(0));
}
typedef uint64 PhotoId;
typedef uint64 VideoId;
typedef uint64 AudioId;
typedef uint64 DocumentId;
typedef uint64 WebPageId;
typedef int32 MsgId;
struct FullMsgId {
FullMsgId() : channel(NoChannel), msg(0) {
}
FullMsgId(ChannelId channel, MsgId msg) : channel(channel), msg(msg) {
}
ChannelId channel;
MsgId msg;
};
inline bool operator==(const FullMsgId &a, const FullMsgId &b) {
return (a.channel == b.channel) && (a.msg == b.msg);
}
inline bool operator<(const FullMsgId &a, const FullMsgId &b) {
if (a.msg < b.msg) return true;
if (a.msg > b.msg) return false;
return a.channel < b.channel;
}
static const MsgId ShowAtTheEndMsgId = -0x40000000;
static const MsgId ShowAtUnreadMsgId = 0;
@ -61,10 +146,12 @@ ImagePtr chatDefPhoto(int32 index);
static const PhotoId UnknownPeerPhotoId = 0xFFFFFFFFFFFFFFFFULL;
struct UserData;
struct ChatData;
struct PeerData {
PeerData(const PeerId &id);
class UserData;
class ChatData;
class ChannelData;
class PeerData {
public:
virtual ~PeerData() {
if (notify != UnknownNotifySettings && notify != EmptyNotifySettings) {
delete notify;
@ -72,11 +159,21 @@ struct PeerData {
}
}
bool isUser() const {
return peerIsUser(id);
}
bool isChat() const {
return peerIsChat(id);
}
bool isChannel() const {
return peerIsChannel(id);
}
UserData *asUser();
const UserData *asUser() const;
ChatData *asChat();
const ChatData *asChat() const;
ChannelData *asChannel();
const ChannelData *asChannel() const;
void updateName(const QString &newName, const QString &newNameOrPhone, const QString &newUsername);
@ -85,7 +182,10 @@ struct PeerData {
virtual void nameUpdated() {
}
PeerId id;
const PeerId id;
int32 bareId() const {
return int32(uint32(id & 0xFFFFFFFFULL));
}
QString name;
QString nameOrPhone;
@ -95,7 +195,6 @@ struct PeerData {
NameFirstChars chars;
bool loaded;
bool chat;
MTPinputPeer input;
int32 colorIndex;
@ -107,7 +206,15 @@ struct PeerData {
int32 nameVersion;
NotifySettingsPtr notify;
private:
PeerData(const PeerId &id);
friend class UserData;
friend class ChatData;
friend class ChannelData;
};
static const uint64 UserNoAccess = 0xFFFFFFFFFFFFFFFFULL;
class PeerLink : public ITextLink {
@ -174,7 +281,9 @@ enum UserBlockedStatus {
};
struct PhotoData;
struct UserData : public PeerData {
class UserData : public PeerData {
public:
UserData(const PeerId &id) : PeerData(id), access(0), lnk(new PeerLink(this)), onlineTill(0), contact(-1), blocked(UserBlockUnknown), photosCount(-1), botInfo(0) {
}
void setPhoto(const MTPUserProfilePhoto &photo);
@ -188,7 +297,7 @@ struct UserData : public PeerData {
uint64 access;
MTPinputUser inputUser;
MTPInputUser inputUser;
QString firstName;
QString lastName;
@ -207,10 +316,15 @@ struct UserData : public PeerData {
BotInfo *botInfo;
};
struct ChatData : public PeerData {
ChatData(const PeerId &id) : PeerData(id), count(0), date(0), version(0), left(false), forbidden(true), botStatus(0) {
class ChatData : public PeerData {
public:
ChatData(const PeerId &id) : PeerData(id), inputChat(MTP_inputChat(MTP_int(bareId()))), count(0), date(0), version(0), left(false), forbidden(true), botStatus(0) {
}
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
MTPInputChat inputChat;
int32 count;
int32 date;
int32 version;
@ -228,17 +342,56 @@ struct ChatData : public PeerData {
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
// ImagePtr photoFull;
QString invitationUrl;
// geo
};
class ChannelData : public PeerData {
public:
ChannelData(const PeerId &id) : PeerData(id), access(0), inputChat(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))), date(0), version(0), left(false), forbidden(true), botStatus(-1) {
}
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
uint64 access;
MTPInputChat inputChat;
int32 date;
int32 version;
bool left;
bool forbidden;
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
// ImagePtr photoFull;
QString invitationUrl;
};
inline UserData *PeerData::asUser() {
return isUser() ? static_cast<UserData*>(this) : 0;
}
inline const UserData *PeerData::asUser() const {
return isUser() ? static_cast<const UserData*>(this) : 0;
}
inline ChatData *PeerData::asChat() {
return isChat() ? static_cast<ChatData*>(this) : 0;
}
inline const ChatData *PeerData::asChat() const {
return isChat() ? static_cast<const ChatData*>(this) : 0;
}
inline ChannelData *PeerData::asChannel() {
return isChannel() ? static_cast<ChannelData*>(this) : 0;
}
inline const ChannelData *PeerData::asChannel() const {
return isChannel() ? static_cast<const ChannelData*>(this) : 0;
}
inline int32 newMessageFlags(PeerData *p) {
return (p->input.type() == mtpc_inputPeerSelf) ? 0 : (((p->chat || !p->asUser()->botInfo) ? MTPDmessage_flag_unread : 0) | MTPDmessage_flag_out);
return (p->input.type() == mtpc_inputPeerSelf) ? 0 : (((p->isChat() || (p->isUser() && !p->asUser()->botInfo)) ? MTPDmessage_flag_unread : 0) | MTPDmessage_flag_out);
}
typedef QMap<char, QPixmap> PreparedPhotoThumbs;
struct PhotoData {
PhotoData(const PhotoId &id, const uint64 &access = 0, int32 date = 0, const ImagePtr &thumb = ImagePtr(), const ImagePtr &medium = ImagePtr(), const ImagePtr &full = ImagePtr()) :
id(id), access(access), date(date), thumb(thumb), medium(medium), full(full), chat(0) {
id(id), access(access), date(date), thumb(thumb), medium(medium), full(full), peer(0) {
}
void forget() {
thumb->forget();
@ -265,7 +418,8 @@ struct PhotoData {
ImagePtr thumb, replyPreview;
ImagePtr medium;
ImagePtr full;
ChatData *chat; // for chat photos connection
PeerData *peer; // for chat and channel photos connection
// geo, caption
int32 cachew;
@ -319,7 +473,8 @@ struct VideoData {
}
location = FileLocation();
if (!beforeDownload) {
openOnSave = openOnSaveMsgId = 0;
openOnSave = 0;
openOnSaveMsgId = FullMsgId();
}
}
@ -347,7 +502,8 @@ struct VideoData {
int32 uploadOffset;
mtpTypeId fileType;
int32 openOnSave, openOnSaveMsgId;
int32 openOnSave;
FullMsgId openOnSaveMsgId;
mtpFileLoader *loader;
FileLocation location;
};
@ -412,7 +568,8 @@ struct AudioData {
}
location = FileLocation();
if (!beforeDownload) {
openOnSave = openOnSaveMsgId = 0;
openOnSave = 0;
openOnSaveMsgId = FullMsgId();
}
}
@ -439,7 +596,8 @@ struct AudioData {
FileStatus status;
int32 uploadOffset;
int32 openOnSave, openOnSaveMsgId;
int32 openOnSave;
FullMsgId openOnSaveMsgId;
mtpFileLoader *loader;
FileLocation location;
QByteArray data;
@ -447,15 +605,17 @@ struct AudioData {
};
struct AudioMsgId {
AudioMsgId() : audio(0), msgId(0) {
AudioMsgId() : audio(0) {
}
AudioMsgId(AudioData *audio, MsgId msgId) : audio(audio), msgId(msgId) {
AudioMsgId(AudioData *audio, const FullMsgId &msgId) : audio(audio), msgId(msgId) {
}
AudioMsgId(AudioData *audio, ChannelId channelId, MsgId msgId) : audio(audio), msgId(channelId, msgId) {
}
operator bool() const {
return audio;
}
AudioData *audio;
MsgId msgId;
FullMsgId msgId;
};
inline bool operator<(const AudioMsgId &a, const AudioMsgId &b) {
return quintptr(a.audio) < quintptr(b.audio) || (quintptr(a.audio) == quintptr(b.audio) && a.msgId < b.msgId);
@ -574,7 +734,8 @@ struct DocumentData {
}
location = FileLocation();
if (!beforeDownload) {
openOnSave = openOnSaveMsgId = 0;
openOnSave = 0;
openOnSaveMsgId = FullMsgId();
}
}
@ -612,7 +773,8 @@ struct DocumentData {
FileStatus status;
int32 uploadOffset;
int32 openOnSave, openOnSaveMsgId;
int32 openOnSave;
FullMsgId openOnSaveMsgId;
mtpFileLoader *loader;
FileLocation location;
@ -623,15 +785,17 @@ struct DocumentData {
};
struct SongMsgId {
SongMsgId() : song(0), msgId(0) {
SongMsgId() : song(0) {
}
SongMsgId(DocumentData *song, MsgId msgId) : song(song), msgId(msgId) {
SongMsgId(DocumentData *song, const FullMsgId &msgId) : song(song), msgId(msgId) {
}
SongMsgId(DocumentData *song, ChannelId channelId, MsgId msgId) : song(song), msgId(channelId, msgId) {
}
operator bool() const {
return song;
}
DocumentData *song;
MsgId msgId;
FullMsgId msgId;
};
inline bool operator<(const SongMsgId &a, const SongMsgId &b) {
return quintptr(a.song) < quintptr(b.song) || (quintptr(a.song) == quintptr(b.song) && a.msgId < b.msgId);

View file

@ -174,7 +174,7 @@ void NotifyWindow::updateNotifyDisplay() {
QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height);
if (!App::passcoded() && cNotifyView() <= dbinvShowName) {
if (history->peer->chat) {
if (history->peer->isChat()) { // CHANNELS_UI
p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), st::dlgChatImg);
rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip);
}
@ -198,7 +198,7 @@ void NotifyWindow::updateNotifyDisplay() {
item->drawInDialog(p, r, active, textCachedFor, itemTextCache);
} else {
p.setFont(st::dlgHistFont->f);
if (history->peer->chat) {
if (item->displayFromName()) {
itemTextCache.setText(st::dlgHistFont, item->from()->name);
p.setPen(st::dlgSystemColor->p);
itemTextCache.drawElided(p, r.left(), r.top(), r.width(), st::dlgHistFont->height);
@ -287,7 +287,7 @@ void NotifyWindow::mousePressEvent(QMouseEvent *e) {
App::wnd()->notifyClear();
} else {
App::wnd()->hideSettings();
App::main()->showPeerHistory(peer, (history->peer->chat && item && item->notifyByFrom() && item->id > 0) ? item->id : ShowAtUnreadMsgId);
App::main()->showPeerHistory(peer, (!history->peer->isUser() && item && item->notifyByFrom() && item->id > 0) ? item->id : ShowAtUnreadMsgId);
}
e->ignore();
}
@ -609,7 +609,7 @@ void Window::sendServiceHistoryRequest() {
int32 userFlags = MTPDuser::flag_first_name | MTPDuser::flag_phone | MTPDuser::flag_status;
user = App::feedUsers(MTP_vector<MTPUser>(1, MTP_user(MTP_int(userFlags), MTP_int(ServiceUserId), MTPlong(), MTP_string("Telegram"), MTPstring(), MTPstring(), MTP_string("42777"), MTP_userProfilePhotoEmpty(), MTP_userStatusRecently(), MTPint())));
}
_serviceHistoryRequest = MTP::send(MTPmessages_GetHistory(user->input, MTP_int(0), MTP_int(0), MTP_int(1)), main->rpcDone(&MainWidget::serviceHistoryDone), main->rpcFail(&MainWidget::serviceHistoryFail));
_serviceHistoryRequest = MTP::send(MTPmessages_GetHistory(user->input, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(1)), main->rpcDone(&MainWidget::serviceHistoryDone), main->rpcFail(&MainWidget::serviceHistoryFail));
}
void Window::setupMain(bool anim, const MTPUser *self) {
@ -1229,7 +1229,7 @@ void Window::quit() {
void Window::notifySchedule(History *history, HistoryItem *item) {
if (App::quiting() || !history->currentNotification() || !main) return;
UserData *notifyByFrom = (history->peer->chat && item->notifyByFrom()) ? item->from() : 0;
UserData *notifyByFrom = (!history->peer->isUser() && item->notifyByFrom()) ? item->from() : 0;
bool haveSetting = (history->peer->notify != UnknownNotifySettings);
if (haveSetting) {