all MTP flags made strictly typed by scoped enums, in-message date display added for non-service messages

This commit is contained in:
John Preston 2016-03-19 19:55:15 +03:00
parent 9d00ec273b
commit 2ef8c44445
43 changed files with 6141 additions and 4167 deletions

View file

@ -230,7 +230,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
} }
if (f.has_migrated_from_chat_id()) { if (f.has_migrated_from_chat_id()) {
if (!channel->mgInfo) { if (!channel->mgInfo) {
channel->flags |= MTPDchannel::flag_megagroup; channel->flags |= MTPDchannel::Flag::f_megagroup;
channel->flagsUpdated(); channel->flagsUpdated();
} }
ChatData *cfrom = App::chat(peerFromChat(f.vmigrated_from_chat_id)); ChatData *cfrom = App::chat(peerFromChat(f.vmigrated_from_chat_id));
@ -685,8 +685,8 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
if (d.vset.type() != mtpc_stickerSet) return; if (d.vset.type() != mtpc_stickerSet) return;
const MTPDstickerSet &s(d.vset.c_stickerSet()); const MTPDstickerSet &s(d.vset.c_stickerSet());
StickerSets &sets(cRefStickerSets()); Stickers::Sets &sets(Global::RefStickerSets());
StickerSets::iterator it = sets.find(setId); auto it = sets.find(setId);
if (it == sets.cend()) return; if (it == sets.cend()) return;
it->access = s.vaccess_hash.v; it->access = s.vaccess_hash.v;
@ -696,7 +696,7 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
it->flags = s.vflags.v; it->flags = s.vflags.v;
const QVector<MTPDocument> &d_docs(d.vdocuments.c_vector().v); const QVector<MTPDocument> &d_docs(d.vdocuments.c_vector().v);
StickerSets::iterator custom = sets.find(CustomStickerSetId); auto custom = sets.find(Stickers::CustomSetId);
StickerPack pack; StickerPack pack;
pack.reserve(d_docs.size()); pack.reserve(d_docs.size());
@ -729,8 +729,8 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
} }
if (pack.isEmpty()) { if (pack.isEmpty()) {
int32 removeIndex = cStickerSetsOrder().indexOf(setId); int removeIndex = Global::StickerSetsOrder().indexOf(setId);
if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex); if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex);
sets.erase(it); sets.erase(it);
} else { } else {
it->stickers = pack; it->stickers = pack;
@ -903,10 +903,8 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs
} }
for (QMap<uint64, int32>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) { for (QMap<uint64, int32>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
HistoryItem *item = App::histories().addNewMessage(v->at(i.value()), NewMessageExisting); if (HistoryItem *item = App::histories().addNewMessage(v->at(i.value()), NewMessageExisting)) {
if (item) { item->setPendingInitDimensions();
item->initDimensions();
Notify::historyItemResized(item);
} }
} }
@ -918,8 +916,7 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs
WebPageItems::const_iterator j = items.constFind(i.key()); WebPageItems::const_iterator j = items.constFind(i.key());
if (j != items.cend()) { if (j != items.cend()) {
for (HistoryItemsMap::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) { for (HistoryItemsMap::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
k.key()->initDimensions(); k.key()->setPendingInitDimensions();
Notify::historyItemResized(k.key());
} }
} }
} }

View file

@ -57,7 +57,7 @@ namespace {
typedef QMap<MsgId, ReplyMarkup> ReplyMarkups; typedef QMap<MsgId, ReplyMarkup> ReplyMarkups;
ReplyMarkups replyMarkups; ReplyMarkups replyMarkups;
ReplyMarkup zeroMarkup(MTPDreplyKeyboardMarkup_flag_ZERO); ReplyMarkup zeroMarkup(qFlags(MTPDreplyKeyboardMarkup_ClientFlag::f_zero));
typedef QMap<ChannelId, ReplyMarkups> ChannelReplyMarkups; typedef QMap<ChannelId, ReplyMarkups> ChannelReplyMarkups;
ChannelReplyMarkups channelReplyMarkups; ChannelReplyMarkups channelReplyMarkups;
@ -507,7 +507,7 @@ namespace App {
const MTPDinputChannel &c(d.vmigrated_to.c_inputChannel()); const MTPDinputChannel &c(d.vmigrated_to.c_inputChannel());
ChannelData *channel = App::channel(peerFromChannel(c.vchannel_id)); ChannelData *channel = App::channel(peerFromChannel(c.vchannel_id));
if (!channel->mgInfo) { if (!channel->mgInfo) {
channel->flags |= MTPDchannel::flag_megagroup; channel->flags |= MTPDchannel::Flag::f_megagroup;
channel->flagsUpdated(); channel->flagsUpdated();
} }
if (!channel->access) { if (!channel->access) {
@ -538,7 +538,7 @@ namespace App {
} }
} }
if (!(cdata->flags & MTPDchat::flag_admins_enabled) && (d.vflags.v & MTPDchat::flag_admins_enabled)) { if (!(cdata->flags & MTPDchat::Flag::f_admins_enabled) && (d.vflags.v & MTPDchat::Flag::f_admins_enabled)) {
cdata->invalidateParticipants(); cdata->invalidateParticipants();
} }
cdata->flags = d.vflags.v; cdata->flags = d.vflags.v;
@ -583,7 +583,7 @@ namespace App {
ChannelData *cdata = data->asChannel(); ChannelData *cdata = data->asChannel();
if (minimal) { if (minimal) {
int32 mask = MTPDchannel::flag_broadcast | MTPDchannel::flag_verified | MTPDchannel::flag_megagroup | MTPDchannel::flag_democracy; int32 mask = MTPDchannel::Flag::f_broadcast | MTPDchannel::Flag::f_verified | MTPDchannel::Flag::f_megagroup | MTPDchannel::Flag::f_democracy;
cdata->flags = (cdata->flags & ~mask) | (d.vflags.v & mask); cdata->flags = (cdata->flags & ~mask) | (d.vflags.v & mask);
} else { } else {
cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash); cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash);
@ -654,7 +654,7 @@ namespace App {
int32 pversion = chat->participants.isEmpty() ? 1 : (chat->participants.begin().value() + 1); int32 pversion = chat->participants.isEmpty() ? 1 : (chat->participants.begin().value() + 1);
chat->invitedByMe = ChatData::InvitedByMe(); chat->invitedByMe = ChatData::InvitedByMe();
chat->admins = ChatData::Admins(); chat->admins = ChatData::Admins();
chat->flags &= ~MTPDchat::flag_admin; chat->flags &= ~MTPDchat::Flag::f_admin;
for (QVector<MTPChatParticipant>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { for (QVector<MTPChatParticipant>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
int32 uid = 0, inviter = 0; int32 uid = 0, inviter = 0;
switch (i->type()) { switch (i->type()) {
@ -685,7 +685,7 @@ namespace App {
if (i->type() == mtpc_chatParticipantAdmin) { if (i->type() == mtpc_chatParticipantAdmin) {
chat->admins.insert(user); chat->admins.insert(user);
if (user->isSelf()) { if (user->isSelf()) {
chat->flags |= MTPDchat::flag_admin; chat->flags |= MTPDchat::Flag::f_admin;
} }
} }
} else { } else {
@ -805,7 +805,7 @@ namespace App {
chat->invitedByMe.remove(user); chat->invitedByMe.remove(user);
chat->admins.remove(user); chat->admins.remove(user);
if (user->isSelf()) { if (user->isSelf()) {
chat->flags &= ~MTPDchat::flag_admin; chat->flags &= ~MTPDchat::Flag::f_admin;
} }
History *h = App::historyLoaded(chat->id); History *h = App::historyLoaded(chat->id);
@ -852,13 +852,13 @@ namespace App {
} }
chat->version = d.vversion.v; chat->version = d.vversion.v;
if (mtpIsTrue(d.venabled)) { if (mtpIsTrue(d.venabled)) {
chat->flags |= MTPDchat::flag_admins_enabled; chat->flags |= MTPDchat::Flag::f_admins_enabled;
if (!badVersion) { if (!badVersion) {
chat->invalidateParticipants(); chat->invalidateParticipants();
} }
} else { } else {
chat->flags &= ~MTPDchat::flag_admins_enabled; chat->flags &= ~MTPDchat::Flag::f_admins_enabled;
chat->flags &= ~MTPDchat::flag_admin; chat->flags &= ~MTPDchat::Flag::f_admin;
} }
if (emitPeerUpdated) { if (emitPeerUpdated) {
App::main()->peerUpdated(chat); App::main()->peerUpdated(chat);
@ -887,7 +887,7 @@ namespace App {
if (user) { if (user) {
if (mtpIsTrue(d.vis_admin)) { if (mtpIsTrue(d.vis_admin)) {
if (user->isSelf()) { if (user->isSelf()) {
chat->flags |= MTPDchat::flag_admin; chat->flags |= MTPDchat::Flag::f_admin;
} }
if (chat->noParticipantInfo()) { if (chat->noParticipantInfo()) {
App::api()->requestFullPeer(chat); App::api()->requestFullPeer(chat);
@ -896,7 +896,7 @@ namespace App {
} }
} else { } else {
if (user->isSelf()) { if (user->isSelf()) {
chat->flags &= ~MTPDchat::flag_admin; chat->flags &= ~MTPDchat::Flag::f_admin;
} }
chat->admins.remove(user); chat->admins.remove(user);
} }
@ -921,10 +921,7 @@ namespace App {
if (HistoryItem *existing = App::histItemById(peerToChannel(peerId), m.vid.v)) { if (HistoryItem *existing = App::histItemById(peerToChannel(peerId), m.vid.v)) {
existing->setText(qs(m.vmessage), m.has_entities() ? entitiesFromMTP(m.ventities.c_vector().v) : EntitiesInText()); existing->setText(qs(m.vmessage), m.has_entities() ? entitiesFromMTP(m.ventities.c_vector().v) : EntitiesInText());
existing->updateMedia(m.has_media() ? (&m.vmedia) : 0); existing->updateMedia(m.has_media() ? (&m.vmedia) : 0);
existing->setViewsCount(m.has_views() ? m.vviews.v : -1, false); existing->setViewsCount(m.has_views() ? m.vviews.v : -1);
existing->initDimensions();
Notify::historyItemResized(existing);
existing->addToOverview(AddToOverviewNew); existing->addToOverview(AddToOverviewNew);
if (!existing->detached()) { if (!existing->detached()) {
@ -945,16 +942,13 @@ namespace App {
if (HistoryItem *existing = App::histItemById(peerToChannel(peerId), m.vid.v)) { if (HistoryItem *existing = App::histItemById(peerToChannel(peerId), m.vid.v)) {
existing->setText(qs(m.vmessage), m.has_entities() ? entitiesFromMTP(m.ventities.c_vector().v) : EntitiesInText()); existing->setText(qs(m.vmessage), m.has_entities() ? entitiesFromMTP(m.ventities.c_vector().v) : EntitiesInText());
existing->updateMedia(m.has_media() ? (&m.vmedia) : 0, true); existing->updateMedia(m.has_media() ? (&m.vmedia) : 0, true);
existing->setViewsCount(m.has_views() ? m.vviews.v : -1, false); existing->setViewsCount(m.has_views() ? m.vviews.v : -1);
existing->initDimensions();
if (existing->history()->textCachedFor == existing) { if (existing->history()->textCachedFor == existing) {
existing->history()->textCachedFor = 0; existing->history()->textCachedFor = 0;
} }
if (App::main()) { if (App::main()) {
App::main()->dlgUpdated(existing->history(), existing->id); App::main()->dlgUpdated(existing->history(), existing->id);
} }
App::historyUpdateDependent(existing);
Notify::historyItemResized(existing);
} }
} }
@ -1095,7 +1089,6 @@ namespace App {
} }
void feedWereDeleted(ChannelId channelId, const QVector<MTPint> &msgsIds) { void feedWereDeleted(ChannelId channelId, const QVector<MTPint> &msgsIds) {
bool resized = false;
MsgsData *data = fetchMsgsData(channelId, false); MsgsData *data = fetchMsgsData(channelId, false);
if (!data) return; if (!data) return;
@ -1106,9 +1099,6 @@ namespace App {
MsgsData::const_iterator j = data->constFind(i->v); MsgsData::const_iterator j = data->constFind(i->v);
if (j != data->cend()) { if (j != data->cend()) {
History *h = (*j)->history(); History *h = (*j)->history();
if (App::main() && (h->peer == App::main()->peer() || (App::main()->peer() && h->peer->migrateTo() == App::main()->peer())) && !(*j)->detached()) {
resized = true;
}
(*j)->destroy(); (*j)->destroy();
if (!h->lastMsg) historiesToCheck.insert(h, true); if (!h->lastMsg) historiesToCheck.insert(h, true);
} else { } else {
@ -1120,9 +1110,6 @@ namespace App {
} }
} }
} }
if (resized) {
Notify::historyItemsResized();
}
if (main()) { if (main()) {
for (QMap<History*, bool>::const_iterator i = historiesToCheck.cbegin(), e = historiesToCheck.cend(); i != e; ++i) { for (QMap<History*, bool>::const_iterator i = historiesToCheck.cbegin(), e = historiesToCheck.cend(); i != e; ++i) {
main()->checkPeerHistory(i.key()->peer); main()->checkPeerHistory(i.key()->peer);
@ -1788,6 +1775,7 @@ namespace App {
if (App::wnd()) { if (App::wnd()) {
App::wnd()->notifyItemRemoved(item); App::wnd()->notifyItemRemoved(item);
} }
item->history()->setPendingResize();
} }
void historyUnregItem(HistoryItem *item) { void historyUnregItem(HistoryItem *item) {
@ -1878,9 +1866,9 @@ namespace App {
webPagesData.clear(); webPagesData.clear();
if (api()) api()->clearWebPageRequests(); if (api()) api()->clearWebPageRequests();
cSetRecentStickers(RecentStickerPack()); cSetRecentStickers(RecentStickerPack());
cSetStickerSets(StickerSets()); Global::SetStickerSets(Stickers::Sets());
cSetStickerSetsOrder(StickerSetsOrder()); Global::SetStickerSetsOrder(Stickers::Order());
cSetLastStickersUpdate(0); Global::SetLastStickersUpdate(0);
cSetSavedGifs(SavedGifs()); cSetSavedGifs(SavedGifs());
cSetLastSavedGifsUpdate(0); cSetLastSavedGifsUpdate(0);
cSetReportSpamStatuses(ReportSpamStatuses()); cSetReportSpamStatuses(ReportSpamStatuses());
@ -2446,13 +2434,13 @@ namespace App {
case mtpc_replyKeyboardHide: { case mtpc_replyKeyboardHide: {
const MTPDreplyKeyboardHide &d(markup.c_replyKeyboardHide()); const MTPDreplyKeyboardHide &d(markup.c_replyKeyboardHide());
if (d.vflags.v) { if (d.vflags.v) {
insertReplyMarkup(channelId, msgId, ReplyMarkup(d.vflags.v | MTPDreplyKeyboardMarkup_flag_ZERO)); insertReplyMarkup(channelId, msgId, ReplyMarkup(mtpCastFlags(d.vflags.v) | MTPDreplyKeyboardMarkup_ClientFlag::f_zero));
} }
} break; } break;
case mtpc_replyKeyboardForceReply: { case mtpc_replyKeyboardForceReply: {
const MTPDreplyKeyboardForceReply &d(markup.c_replyKeyboardForceReply()); const MTPDreplyKeyboardForceReply &d(markup.c_replyKeyboardForceReply());
insertReplyMarkup(channelId, msgId, ReplyMarkup(d.vflags.v | MTPDreplyKeyboardMarkup_flag_FORCE_REPLY)); insertReplyMarkup(channelId, msgId, ReplyMarkup(mtpCastFlags(d.vflags.v) | MTPDreplyKeyboardMarkup_ClientFlag::f_force_reply));
} break; } break;
} }
} }

View file

@ -45,11 +45,11 @@ typedef QHash<PhotoId, PhotoData*> PhotosData;
typedef QHash<DocumentId, DocumentData*> DocumentsData; typedef QHash<DocumentId, DocumentData*> DocumentsData;
struct ReplyMarkup { struct ReplyMarkup {
ReplyMarkup(int32 flags = 0) : flags(flags) { ReplyMarkup(MTPDreplyKeyboardMarkup::Flags flags = 0) : flags(flags) {
} }
typedef QList<QList<QString> > Commands; typedef QList<QList<QString> > Commands;
Commands commands; Commands commands;
int32 flags; MTPDreplyKeyboardMarkup::Flags flags;
}; };
class LayeredWidget; class LayeredWidget;

View file

@ -899,6 +899,10 @@ void AppClass::onAppStateChanged(Qt::ApplicationState state) {
} }
} }
void AppClass::call_handleHistoryUpdate() {
Notify::handlePendingHistoryUpdate();
}
void AppClass::killDownloadSessions() { void AppClass::killDownloadSessions() {
uint64 ms = getms(), left = MTPAckSendWaiting + MTPKillFileSessionTimeout; uint64 ms = getms(), left = MTPAckSendWaiting + MTPKillFileSessionTimeout;
for (QMap<int32, uint64>::iterator i = killDownloadSessionTimes.begin(); i != killDownloadSessionTimes.end(); ) { for (QMap<int32, uint64>::iterator i = killDownloadSessionTimes.begin(); i != killDownloadSessionTimes.end(); ) {

View file

@ -200,6 +200,8 @@ public slots:
void killDownloadSessions(); void killDownloadSessions();
void onAppStateChanged(Qt::ApplicationState state); void onAppStateChanged(Qt::ApplicationState state);
void call_handleHistoryUpdate();
private: private:
QMap<FullMsgId, PeerId> photoUpdates; QMap<FullMsgId, PeerId> photoUpdates;

View file

@ -2505,7 +2505,7 @@ MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteAr
cover = reader.cover(); cover = reader.cover();
coverBytes = reader.coverBytes(); coverBytes = reader.coverBytes();
coverFormat = reader.coverFormat(); coverFormat = reader.coverFormat();
return MTP_documentAttributeAudio(MTP_int(MTPDdocumentAttributeAudio::flag_title | MTPDdocumentAttributeAudio::flag_performer), MTP_int(duration), MTP_string(reader.title()), MTP_string(reader.performer()), MTPstring()); return MTP_documentAttributeAudio(MTP_flags(MTPDdocumentAttributeAudio::Flag::f_title | MTPDdocumentAttributeAudio::Flag::f_performer), MTP_int(duration), MTP_string(reader.title()), MTP_string(reader.performer()), MTPstring());
} }
} }
return MTP_documentAttributeFilename(MTP_string(fname)); return MTP_documentAttributeFilename(MTP_string(fname));

View file

@ -499,8 +499,8 @@ void GroupInfoBox::onNext() {
Ui::showLayer(new ContactsBox(title, _photoBig), KeepOtherLayers); Ui::showLayer(new ContactsBox(title, _photoBig), KeepOtherLayers);
} else { } else {
bool mega = false; bool mega = false;
int32 flags = mega ? MTPchannels_CreateChannel::flag_megagroup : MTPchannels_CreateChannel::flag_broadcast; MTPchannels_CreateChannel::Flags flags = mega ? MTPchannels_CreateChannel::Flag::f_megagroup : MTPchannels_CreateChannel::Flag::f_broadcast;
_creationRequestId = MTP::send(MTPchannels_CreateChannel(MTP_int(flags), MTP_string(title), MTP_string(description)), rpcDone(&GroupInfoBox::creationDone), rpcFail(&GroupInfoBox::creationFail)); _creationRequestId = MTP::send(MTPchannels_CreateChannel(MTP_flags(flags), MTP_string(title), MTP_string(description)), rpcDone(&GroupInfoBox::creationDone), rpcFail(&GroupInfoBox::creationFail));
} }
} }
@ -1115,8 +1115,8 @@ void EditNameTitleBox::onSave() {
} }
_sentName = first; _sentName = first;
if (_peer == App::self()) { if (_peer == App::self()) {
int32 flags = MTPaccount_UpdateProfile::flag_first_name | MTPaccount_UpdateProfile::flag_last_name; MTPaccount_UpdateProfile::Flags flags = MTPaccount_UpdateProfile::Flag::f_first_name | MTPaccount_UpdateProfile::Flag::f_last_name;
_requestId = MTP::send(MTPaccount_UpdateProfile(MTP_int(flags), MTP_string(first), MTP_string(last), MTPstring()), rpcDone(&EditNameTitleBox::onSaveSelfDone), rpcFail(&EditNameTitleBox::onSaveSelfFail)); _requestId = MTP::send(MTPaccount_UpdateProfile(MTP_flags(flags), MTP_string(first), MTP_string(last), MTPstring()), rpcDone(&EditNameTitleBox::onSaveSelfDone), rpcFail(&EditNameTitleBox::onSaveSelfFail));
} else if (_peer->isChat()) { } else if (_peer->isChat()) {
_requestId = MTP::send(MTPmessages_EditChatTitle(_peer->asChat()->inputChat, MTP_string(first)), rpcDone(&EditNameTitleBox::onSaveChatDone), rpcFail(&EditNameTitleBox::onSaveChatFail)); _requestId = MTP::send(MTPmessages_EditChatTitle(_peer->asChat()->inputChat, MTP_string(first)), rpcDone(&EditNameTitleBox::onSaveChatDone), rpcFail(&EditNameTitleBox::onSaveChatFail));
} }

View file

@ -404,8 +404,11 @@ void PinMessageBox::resizeEvent(QResizeEvent *e) {
void PinMessageBox::onPin() { void PinMessageBox::onPin() {
if (_requestId) return; if (_requestId) return;
int32 flags = _notify.checked() ? 0 : MTPchannels_UpdatePinnedMessage::flag_silent; MTPchannels_UpdatePinnedMessage::Flags flags = 0;
_requestId = MTP::send(MTPchannels_UpdatePinnedMessage(MTP_int(flags), _channel->inputChannel, MTP_int(_msgId)), rpcDone(&PinMessageBox::pinDone), rpcFail(&PinMessageBox::pinFail)); if (_notify.checked()) {
flags |= MTPchannels_UpdatePinnedMessage::Flag::f_silent;
}
_requestId = MTP::send(MTPchannels_UpdatePinnedMessage(MTP_flags(flags), _channel->inputChannel, MTP_int(_msgId)), rpcDone(&PinMessageBox::pinDone), rpcFail(&PinMessageBox::pinFail));
} }
void PinMessageBox::showAll() { void PinMessageBox::showAll() {
@ -482,7 +485,6 @@ void RichDeleteMessageBox::onDelete() {
App::main()->checkPeerHistory(_channel); App::main()->checkPeerHistory(_channel);
} }
} }
Notify::historyItemsResized();
Ui::hideLayer(); Ui::hideLayer();
} }

View file

@ -400,11 +400,11 @@ void PasscodeBox::onSave(bool force) {
if (!_oldPasscode.isHidden()) { if (!_oldPasscode.isHidden()) {
hashSha256(oldPasswordData.constData(), oldPasswordData.size(), oldPasswordHash.data()); hashSha256(oldPasswordData.constData(), oldPasswordData.size(), oldPasswordHash.data());
} }
int32 flags = MTPDaccount_passwordInputSettings::flag_new_salt | MTPDaccount_passwordInputSettings::flag_new_password_hash | MTPDaccount_passwordInputSettings::flag_hint; MTPDaccount_passwordInputSettings::Flags flags = MTPDaccount_passwordInputSettings::Flag::f_new_salt | MTPDaccount_passwordInputSettings::Flag::f_new_password_hash | MTPDaccount_passwordInputSettings::Flag::f_hint;
if (_oldPasscode.isHidden() || _newPasscode.isHidden()) { if (_oldPasscode.isHidden() || _newPasscode.isHidden()) {
flags |= MTPDaccount_passwordInputSettings::flag_email; flags |= MTPDaccount_passwordInputSettings::Flag::f_email;
} }
MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_int(flags), MTP_string(_newSalt), MTP_string(newPasswordHash), MTP_string(hint), MTP_string(email))); MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_flags(flags), MTP_string(_newSalt), MTP_string(newPasswordHash), MTP_string(hint), MTP_string(email)));
_setRequest = MTP::send(MTPaccount_UpdatePasswordSettings(MTP_string(oldPasswordHash), settings), rpcDone(&PasscodeBox::setPasswordDone), rpcFail(&PasscodeBox::setPasswordFail)); _setRequest = MTP::send(MTPaccount_UpdatePasswordSettings(MTP_string(oldPasswordHash), settings), rpcDone(&PasscodeBox::setPasswordDone), rpcFail(&PasscodeBox::setPasswordFail));
} }
} else { } else {

View file

@ -648,15 +648,15 @@ void EditCaptionBox::onSave(bool ctrlShiftEnter) {
return; return;
} }
int32 flags = 0; MTPchannels_EditMessage::Flags flags = 0;
if (_previewCancelled) { if (_previewCancelled) {
flags |= MTPchannels_EditMessage::flag_no_webpage; flags |= MTPchannels_EditMessage::Flag::f_no_webpage;
} }
MTPVector<MTPMessageEntity> sentEntities; MTPVector<MTPMessageEntity> sentEntities;
if (!sentEntities.c_vector().v.isEmpty()) { if (!sentEntities.c_vector().v.isEmpty()) {
flags |= MTPmessages_SendMessage::flag_entities; flags |= MTPchannels_EditMessage::Flag::f_entities;
} }
_saveRequestId = MTP::send(MTPchannels_EditMessage(MTP_int(flags), item->history()->peer->asChannel()->inputChannel, MTP_int(item->id), MTP_string(_field->getLastText()), sentEntities), rpcDone(&EditCaptionBox::saveDone), rpcFail(&EditCaptionBox::saveFail)); _saveRequestId = MTP::send(MTPchannels_EditMessage(MTP_flags(flags), item->history()->peer->asChannel()->inputChannel, MTP_int(item->id), MTP_string(_field->getLastText()), sentEntities), rpcDone(&EditCaptionBox::saveDone), rpcFail(&EditCaptionBox::saveFail));
} }
void EditCaptionBox::saveDone(const MTPUpdates &updates) { void EditCaptionBox::saveDone(const MTPUpdates &updates) {

View file

@ -117,17 +117,17 @@ bool StickerSetInner::failedSet(const RPCError &error) {
} }
void StickerSetInner::installDone(const MTPBool &result) { void StickerSetInner::installDone(const MTPBool &result) {
StickerSets &sets(cRefStickerSets()); Stickers::Sets &sets(Global::RefStickerSets());
_setFlags &= ~MTPDstickerSet::flag_disabled; _setFlags &= ~MTPDstickerSet::Flag::f_disabled;
StickerSets::iterator it = sets.find(_setId); auto it = sets.find(_setId);
if (it == sets.cend()) { if (it == sets.cend()) {
it = sets.insert(_setId, StickerSet(_setId, _setAccess, _setTitle, _setShortName, _setCount, _setHash, _setFlags)); it = sets.insert(_setId, Stickers::Set(_setId, _setAccess, _setTitle, _setShortName, _setCount, _setHash, _setFlags));
} }
it.value().stickers = _pack; it.value().stickers = _pack;
it.value().emoji = _emoji; it.value().emoji = _emoji;
StickerSetsOrder &order(cRefStickerSetsOrder()); Stickers::Order &order(Global::RefStickerSetsOrder());
int32 insertAtIndex = 0, currentIndex = order.indexOf(_setId); int32 insertAtIndex = 0, currentIndex = order.indexOf(_setId);
if (currentIndex != insertAtIndex) { if (currentIndex != insertAtIndex) {
if (currentIndex > 0) { if (currentIndex > 0) {
@ -136,7 +136,7 @@ void StickerSetInner::installDone(const MTPBool &result) {
order.insert(insertAtIndex, _setId); order.insert(insertAtIndex, _setId);
} }
StickerSets::iterator custom = sets.find(CustomStickerSetId); auto custom = sets.find(Stickers::CustomSetId);
if (custom != sets.cend()) { if (custom != sets.cend()) {
for (int32 i = 0, l = _pack.size(); i < l; ++i) { for (int32 i = 0, l = _pack.size(); i < l; ++i) {
int32 removeIndex = custom->stickers.indexOf(_pack.at(i)); int32 removeIndex = custom->stickers.indexOf(_pack.at(i));
@ -256,8 +256,8 @@ bool StickerSetInner::loaded() const {
int32 StickerSetInner::notInstalled() const { int32 StickerSetInner::notInstalled() const {
if (!_loaded) return 0; if (!_loaded) return 0;
StickerSets::const_iterator it = cStickerSets().constFind(_setId); auto it = Global::StickerSets().constFind(_setId);
if (it == cStickerSets().cend() || (it->flags & MTPDstickerSet::flag_disabled)) return _pack.size(); if (it == Global::StickerSets().cend() || (it->flags & MTPDstickerSet::Flag::f_disabled)) return _pack.size();
return 0; return 0;
} }
@ -682,14 +682,14 @@ void StickersInner::rebuild() {
int32 namew = st::boxWideWidth - namex - st::contactsPadding.right() - st::contactsCheckPosition.x() - qMax(qMax(_returnWidth, _removeWidth), _restoreWidth); int32 namew = st::boxWideWidth - namex - st::contactsPadding.right() - st::contactsCheckPosition.x() - qMax(qMax(_returnWidth, _removeWidth), _restoreWidth);
clear(); clear();
const StickerSetsOrder &order(cStickerSetsOrder()); const Stickers::Order &order(Global::StickerSetsOrder());
_animStartTimes.reserve(order.size()); _animStartTimes.reserve(order.size());
const StickerSets &sets(cStickerSets()); const Stickers::Sets &sets(Global::StickerSets());
for (int32 i = 0, l = order.size(); i < l; ++i) { for (int i = 0, l = order.size(); i < l; ++i) {
StickerSets::const_iterator it = sets.constFind(order.at(i)); auto it = sets.constFind(order.at(i));
if (it != sets.cend()) { if (it != sets.cend()) {
bool disabled = (it->flags & MTPDstickerSet::flag_disabled); bool disabled = (it->flags & MTPDstickerSet::Flag::f_disabled);
DocumentData *sticker = it->stickers.isEmpty() ? 0 : it->stickers.at(0); DocumentData *sticker = it->stickers.isEmpty() ? 0 : it->stickers.at(0);
int32 pixw = 0, pixh = 0; int32 pixw = 0, pixh = 0;
@ -714,10 +714,10 @@ void StickersInner::rebuild() {
if (titleWidth > namew) { if (titleWidth > namew) {
title = st::contactsNameFont->elided(title, namew); title = st::contactsNameFont->elided(title, namew);
} }
bool official = (it->flags & MTPDstickerSet::flag_official); bool official = (it->flags & MTPDstickerSet::Flag::f_official);
(disabled ? rowsDisabled : rows).push_back(new StickerSetRow(it->id, sticker, it->stickers.size(), title, official, disabled, pixw, pixh)); (disabled ? rowsDisabled : rows).push_back(new StickerSetRow(it->id, sticker, it->stickers.size(), title, official, disabled, pixw, pixh));
_animStartTimes.push_back(0); _animStartTimes.push_back(0);
if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_flag_NOT_LOADED)) { if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) {
App::api()->scheduleStickerSetRequest(it->id, it->access); App::api()->scheduleStickerSetRequest(it->id, it->access);
} }
} }
@ -732,8 +732,8 @@ QVector<uint64> StickersInner::getOrder() const {
result.reserve(_rows.size()); result.reserve(_rows.size());
for (int32 i = 0, l = _rows.size(); i < l; ++i) { for (int32 i = 0, l = _rows.size(); i < l; ++i) {
if (_rows.at(i)->disabled) { if (_rows.at(i)->disabled) {
StickerSets::const_iterator it = cStickerSets().constFind(_rows.at(i)->id); auto it = Global::StickerSets().constFind(_rows.at(i)->id);
if (it == cStickerSets().cend() || !(it->flags & MTPDstickerSet::flag_official)) { if (it == Global::StickerSets().cend() || !(it->flags & MTPDstickerSet::Flag::f_official)) {
continue; continue;
} }
} }
@ -833,7 +833,7 @@ void StickersBox::reorderDone(const MTPBool &result) {
bool StickersBox::reorderFail(const RPCError &result) { bool StickersBox::reorderFail(const RPCError &result) {
if (mtpIsFlood(result)) return false; if (mtpIsFlood(result)) return false;
_reorderRequest = 0; _reorderRequest = 0;
cSetLastStickersUpdate(0); Global::SetLastStickersUpdate(0);
App::main()->updateStickers(); App::main()->updateStickers();
onClose(); onClose();
return true; return true;
@ -857,12 +857,12 @@ void StickersBox::closePressed() {
MTP::cancel(i.key()); MTP::cancel(i.key());
} }
_disenableRequests.clear(); _disenableRequests.clear();
cSetLastStickersUpdate(0); Global::SetLastStickersUpdate(0);
App::main()->updateStickers(); App::main()->updateStickers();
} else if (_reorderRequest) { } else if (_reorderRequest) {
MTP::cancel(_reorderRequest); MTP::cancel(_reorderRequest);
_reorderRequest = 0; _reorderRequest = 0;
cSetLastStickersUpdate(0); Global::SetLastStickersUpdate(0);
App::main()->updateStickers(); App::main()->updateStickers();
} }
} }
@ -914,11 +914,11 @@ void StickersBox::onSave() {
bool writeRecent = false; bool writeRecent = false;
RecentStickerPack &recent(cGetRecentStickers()); RecentStickerPack &recent(cGetRecentStickers());
StickerSets &sets(cRefStickerSets()); Stickers::Sets &sets(Global::RefStickerSets());
QVector<uint64> reorder = _inner.getOrder(), disabled = _inner.getDisabledSets(); QVector<uint64> reorder = _inner.getOrder(), disabled = _inner.getDisabledSets();
for (int32 i = 0, l = disabled.size(); i < l; ++i) { for (int32 i = 0, l = disabled.size(); i < l; ++i) {
StickerSets::iterator it = sets.find(disabled.at(i)); auto it = sets.find(disabled.at(i));
if (it != sets.cend()) { if (it != sets.cend()) {
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) { for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
if (it->stickers.indexOf(i->first) >= 0) { if (it->stickers.indexOf(i->first) >= 0) {
@ -928,35 +928,35 @@ void StickersBox::onSave() {
++i; ++i;
} }
} }
if (!(it->flags & MTPDstickerSet::flag_disabled)) { if (!(it->flags & MTPDstickerSet::Flag::f_disabled)) {
MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName)); MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
if (it->flags & MTPDstickerSet::flag_official) { if (it->flags & MTPDstickerSet::Flag::f_official) {
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolTrue()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType()); _disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolTrue()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
it->flags |= MTPDstickerSet::flag_disabled; it->flags |= MTPDstickerSet::Flag::f_disabled;
} else { } else {
_disenableRequests.insert(MTP::send(MTPmessages_UninstallStickerSet(setId), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType()); _disenableRequests.insert(MTP::send(MTPmessages_UninstallStickerSet(setId), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
int32 removeIndex = cStickerSetsOrder().indexOf(it->id); int removeIndex = Global::StickerSetsOrder().indexOf(it->id);
if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex); if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex);
sets.erase(it); sets.erase(it);
} }
} }
} }
} }
StickerSetsOrder &order(cRefStickerSetsOrder()); Stickers::Order &order(Global::RefStickerSetsOrder());
order.clear(); order.clear();
for (int32 i = 0, l = reorder.size(); i < l; ++i) { for (int i = 0, l = reorder.size(); i < l; ++i) {
StickerSets::iterator it = sets.find(reorder.at(i)); auto it = sets.find(reorder.at(i));
if (it != sets.cend()) { if (it != sets.cend()) {
if ((it->flags & MTPDstickerSet::flag_disabled) && !disabled.contains(it->id)) { if ((it->flags & MTPDstickerSet::Flag::f_disabled) && !disabled.contains(it->id)) {
MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName)); MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolFalse()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType()); _disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolFalse()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
it->flags &= ~MTPDstickerSet::flag_disabled; it->flags &= ~MTPDstickerSet::Flag::f_disabled;
} }
order.push_back(reorder.at(i)); order.push_back(reorder.at(i));
} }
} }
for (StickerSets::iterator it = sets.begin(); it != sets.cend();) { for (auto it = sets.begin(); it != sets.cend();) {
if (it->id == CustomStickerSetId || it->id == RecentStickerSetId || order.contains(it->id)) { if (it->id == Stickers::CustomSetId || it->id == Stickers::RecentSetId || order.contains(it->id)) {
++it; ++it;
} else { } else {
it = sets.erase(it); it = sets.erase(it);
@ -992,12 +992,12 @@ void StickersBox::showAll() {
int32 stickerPacksCount(bool includeDisabledOfficial) { int32 stickerPacksCount(bool includeDisabledOfficial) {
int32 result = 0; int32 result = 0;
const StickerSetsOrder &order(cStickerSetsOrder()); const Stickers::Order &order(Global::StickerSetsOrder());
const StickerSets &sets(cStickerSets()); const Stickers::Sets &sets(Global::StickerSets());
for (int32 i = 0, l = order.size(); i < l; ++i) { for (int i = 0, l = order.size(); i < l; ++i) {
StickerSets::const_iterator it = sets.constFind(order.at(i)); auto it = sets.constFind(order.at(i));
if (it != sets.cend()) { if (it != sets.cend()) {
if (!(it->flags & MTPDstickerSet::flag_disabled) || ((it->flags & MTPDstickerSet::flag_official) && includeDisabledOfficial)) { if (!(it->flags & MTPDstickerSet::Flag::f_disabled) || ((it->flags & MTPDstickerSet::Flag::f_official) && includeDisabledOfficial)) {
++result; ++result;
} }
} }

View file

@ -70,7 +70,8 @@ private:
bool _loaded; bool _loaded;
uint64 _setId, _setAccess; uint64 _setId, _setAccess;
QString _title, _setTitle, _setShortName; QString _title, _setTitle, _setShortName;
int32 _setCount, _setHash, _setFlags; int32 _setCount, _setHash;
MTPDstickerSet::Flags _setFlags;
int32 _bottom; int32 _bottom;
MTPInputStickerSet _input; MTPInputStickerSet _input;

View file

@ -2052,8 +2052,11 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
MTP::cancel(_searchRequest); MTP::cancel(_searchRequest);
} }
if (_searchInPeer) { if (_searchInPeer) {
int32 flags = (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; MTPmessages_Search::Flags flags = 0;
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _searchInPeer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, DialogsSearchPeerFromStart), rpcFail(&DialogsWidget::searchFailed, DialogsSearchPeerFromStart)); if (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) {
flags |= MTPmessages_Search::Flag::f_important_only;
}
_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _searchInPeer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, DialogsSearchPeerFromStart), rpcFail(&DialogsWidget::searchFailed, DialogsSearchPeerFromStart));
} else { } else {
_searchRequest = MTP::send(MTPmessages_SearchGlobal(MTP_string(_searchQuery), MTP_int(0), MTP_inputPeerEmpty(), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, DialogsSearchFromStart), rpcFail(&DialogsWidget::searchFailed, DialogsSearchFromStart)); _searchRequest = MTP::send(MTPmessages_SearchGlobal(MTP_string(_searchQuery), MTP_int(0), MTP_inputPeerEmpty(), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, DialogsSearchFromStart), rpcFail(&DialogsWidget::searchFailed, DialogsSearchFromStart));
} }
@ -2113,8 +2116,11 @@ void DialogsWidget::onSearchMore() {
PeerData *offsetPeer = _inner.lastSearchPeer(); PeerData *offsetPeer = _inner.lastSearchPeer();
MsgId offsetId = _inner.lastSearchId(); MsgId offsetId = _inner.lastSearchId();
if (_searchInPeer) { if (_searchInPeer) {
int32 flags = (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; MTPmessages_Search::Flags flags = 0;
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _searchInPeer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart), rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart)); if (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) {
flags |= MTPmessages_Search::Flag::f_important_only;
}
_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _searchInPeer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart), rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart));
} else { } else {
_searchRequest = MTP::send(MTPmessages_SearchGlobal(MTP_string(_searchQuery), MTP_int(offsetDate), offsetPeer ? offsetPeer->input : MTP_inputPeerEmpty(), MTP_int(offsetId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart), rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart)); _searchRequest = MTP::send(MTPmessages_SearchGlobal(MTP_string(_searchQuery), MTP_int(offsetDate), offsetPeer ? offsetPeer->input : MTP_inputPeerEmpty(), MTP_int(offsetId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart), rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart));
} }
@ -2123,8 +2129,11 @@ void DialogsWidget::onSearchMore() {
} }
} else if (_searchInMigrated && !_searchFullMigrated) { } else if (_searchInMigrated && !_searchFullMigrated) {
MsgId offsetMigratedId = _inner.lastSearchMigratedId(); MsgId offsetMigratedId = _inner.lastSearchMigratedId();
int32 flags = (_searchInMigrated->isChannel() && !_searchInMigrated->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; MTPmessages_Search::Flags flags = 0;
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _searchInMigrated->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetMigratedId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart), rpcFail(&DialogsWidget::searchFailed, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart)); if (_searchInMigrated->isChannel() && !_searchInMigrated->isMegagroup()) {
flags |= MTPmessages_Search::Flag::f_important_only;
}
_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _searchInMigrated->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetMigratedId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart), rpcFail(&DialogsWidget::searchFailed, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart));
} }
} }
} }

View file

@ -1097,7 +1097,7 @@ void EmojiPanInner::fillPanels(QVector<EmojiPanel*> &panels) {
int y = 0; int y = 0;
panels.reserve(emojiTabCount); panels.reserve(emojiTabCount);
for (int c = 0; c < emojiTabCount; ++c) { for (int c = 0; c < emojiTabCount; ++c) {
panels.push_back(new EmojiPanel(parentWidget(), lang(LangKey(lng_emoji_category0 + c)), NoneStickerSetId, true, y)); panels.push_back(new EmojiPanel(parentWidget(), lang(LangKey(lng_emoji_category0 + c)), Stickers::NoneSetId, true, y));
connect(panels.back(), SIGNAL(mousePressed()), this, SLOT(checkPickerHide())); connect(panels.back(), SIGNAL(mousePressed()), this, SLOT(checkPickerHide()));
int cnt = _counts[c], rows = (cnt / EmojiPanPerRow) + ((cnt % EmojiPanPerRow) ? 1 : 0); int cnt = _counts[c], rows = (cnt / EmojiPanPerRow) + ((cnt % EmojiPanPerRow) ? 1 : 0);
panels.back()->show(); panels.back()->show();
@ -1352,7 +1352,7 @@ void StickerPanInner::paintStickers(Painter &p, const QRect &r) {
tilly = y + st::emojiPanHeader + (rows * st::stickerPanSize.height()); tilly = y + st::emojiPanHeader + (rows * st::stickerPanSize.height());
if (r.top() >= tilly) continue; if (r.top() >= tilly) continue;
bool special = (_sets[c].flags & MTPDstickerSet::flag_official); bool special = (_sets[c].flags & MTPDstickerSet::Flag::f_official);
y += st::emojiPanHeader; y += st::emojiPanHeader;
int32 fromrow = floorclamp(r.y() - y, st::stickerPanSize.height(), 0, rows); int32 fromrow = floorclamp(r.y() - y, st::stickerPanSize.height(), 0, rows);
@ -1395,7 +1395,7 @@ void StickerPanInner::paintStickers(Painter &p, const QRect &r) {
p.drawPixmapLeft(ppos, width(), sticker->sticker()->img->pix(w, h)); p.drawPixmapLeft(ppos, width(), sticker->sticker()->img->pix(w, h));
} }
if (hover > 0 && _sets[c].id == RecentStickerSetId && _custom.at(index)) { if (hover > 0 && _sets[c].id == Stickers::RecentSetId && _custom.at(index)) {
float64 xHover = _sets[c].hovers[_sets[c].pack.size() + index]; float64 xHover = _sets[c].hovers[_sets[c].pack.size() + index];
QPoint xPos = pos + QPoint(st::stickerPanSize.width() - st::stickerPanDelete.pxWidth(), 0); QPoint xPos = pos + QPoint(st::stickerPanSize.width() - st::stickerPanDelete.pxWidth(), 0);
@ -1509,7 +1509,7 @@ void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
} }
int tab = (_selected / MatrixRowShift), sel = _selected % MatrixRowShift; int tab = (_selected / MatrixRowShift), sel = _selected % MatrixRowShift;
if (_sets[tab].id == RecentStickerSetId && sel >= _sets[tab].pack.size() && sel < _sets[tab].pack.size() * 2 && _custom.at(sel - _sets[tab].pack.size())) { if (_sets[tab].id == Stickers::RecentSetId && sel >= _sets[tab].pack.size() && sel < _sets[tab].pack.size() * 2 && _custom.at(sel - _sets[tab].pack.size())) {
clearSelection(true); clearSelection(true);
bool refresh = false; bool refresh = false;
DocumentData *sticker = _sets[tab].pack.at(sel - _sets[tab].pack.size()); DocumentData *sticker = _sets[tab].pack.at(sel - _sets[tab].pack.size());
@ -1522,8 +1522,8 @@ void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
break; break;
} }
} }
StickerSets &sets(cRefStickerSets()); Stickers::Sets &sets(Global::RefStickerSets());
StickerSets::iterator it = sets.find(CustomStickerSetId); auto it = sets.find(Stickers::CustomSetId);
if (it != sets.cend()) { if (it != sets.cend()) {
for (int32 i = 0, l = it->stickers.size(); i < l; ++i) { for (int32 i = 0, l = it->stickers.size(); i < l; ++i) {
if (it->stickers.at(i) == sticker) { if (it->stickers.at(i) == sticker) {
@ -1595,7 +1595,7 @@ void StickerPanInner::clearSelection(bool fast) {
_animations.clear(); _animations.clear();
if (_selected >= 0) { if (_selected >= 0) {
int index = qAbs(_selected), tab = (index / MatrixRowShift), sel = index % MatrixRowShift; int index = qAbs(_selected), tab = (index / MatrixRowShift), sel = index % MatrixRowShift;
if (index >= 0 && tab < _sets.size() && _sets[tab].id == RecentStickerSetId && sel >= tab * MatrixRowShift + _sets[tab].pack.size()) { if (index >= 0 && tab < _sets.size() && _sets[tab].id == Stickers::RecentSetId && sel >= tab * MatrixRowShift + _sets[tab].pack.size()) {
_sets[tab].hovers[sel] = 0; _sets[tab].hovers[sel] = 0;
sel -= _sets[tab].pack.size(); sel -= _sets[tab].pack.size();
} }
@ -1603,7 +1603,7 @@ void StickerPanInner::clearSelection(bool fast) {
} }
if (_pressedSel >= 0) { if (_pressedSel >= 0) {
int index = qAbs(_pressedSel), tab = (index / MatrixRowShift), sel = index % MatrixRowShift; int index = qAbs(_pressedSel), tab = (index / MatrixRowShift), sel = index % MatrixRowShift;
if (index >= 0 && tab < _sets.size() && _sets[tab].id == RecentStickerSetId && sel >= tab * MatrixRowShift + _sets[tab].pack.size()) { if (index >= 0 && tab < _sets.size() && _sets[tab].id == Stickers::RecentSetId && sel >= tab * MatrixRowShift + _sets[tab].pack.size()) {
_sets[tab].hovers[sel] = 0; _sets[tab].hovers[sel] = 0;
sel -= _sets[tab].pack.size(); sel -= _sets[tab].pack.size();
} }
@ -1640,11 +1640,11 @@ void StickerPanInner::hideFinish(bool completely) {
void StickerPanInner::refreshStickers() { void StickerPanInner::refreshStickers() {
clearSelection(true); clearSelection(true);
const StickerSets &sets(cStickerSets()); const Stickers::Sets &sets(Global::StickerSets());
_sets.clear(); _sets.reserve(sets.size() + 1); _sets.clear(); _sets.reserve(sets.size() + 1);
refreshRecentStickers(false); refreshRecentStickers(false);
for (StickerSetsOrder::const_iterator i = cStickerSetsOrder().cbegin(), e = cStickerSetsOrder().cend(); i != e; ++i) { for (auto i = Global::StickerSetsOrder().cbegin(), e = Global::StickerSetsOrder().cend(); i != e; ++i) {
appendSet(*i); appendSet(*i);
} }
@ -1703,7 +1703,7 @@ void StickerPanInner::refreshSavedGifs() {
if (_showingInlineItems) { if (_showingInlineItems) {
const SavedGifs &saved(cSavedGifs()); const SavedGifs &saved(cSavedGifs());
if (saved.isEmpty()) { if (saved.isEmpty()) {
showStickerSet(RecentStickerSetId); showStickerSet(Stickers::RecentSetId);
return; return;
} else { } else {
_inlineRows.reserve(saved.size()); _inlineRows.reserve(saved.size());
@ -1871,7 +1871,7 @@ void StickerPanInner::preloadImages() {
} }
uint64 StickerPanInner::currentSet(int yOffset) const { uint64 StickerPanInner::currentSet(int yOffset) const {
if (_showingInlineItems) return NoneStickerSetId; if (_showingInlineItems) return Stickers::NoneSetId;
int y, ytill = 0; int y, ytill = 0;
for (int i = 0, l = _sets.size(); i < l; ++i) { for (int i = 0, l = _sets.size(); i < l; ++i) {
@ -1882,7 +1882,7 @@ uint64 StickerPanInner::currentSet(int yOffset) const {
return _sets.at(i).id; return _sets.at(i).id;
} }
} }
return _sets.isEmpty() ? RecentStickerSetId : _sets.back().id; return _sets.isEmpty() ? Stickers::RecentSetId : _sets.back().id;
} }
void StickerPanInner::hideInlineRowsPanel() { void StickerPanInner::hideInlineRowsPanel() {
@ -1894,7 +1894,7 @@ void StickerPanInner::hideInlineRowsPanel() {
emit scrollToY(0); emit scrollToY(0);
emit scrollUpdated(); emit scrollUpdated();
} else { } else {
showStickerSet(RecentStickerSetId); showStickerSet(Stickers::RecentSetId);
} }
} }
} }
@ -2039,9 +2039,9 @@ bool StickerPanInner::ui_isInlineItemBeingChosen() {
} }
void StickerPanInner::appendSet(uint64 setId) { void StickerPanInner::appendSet(uint64 setId) {
const StickerSets &sets(cStickerSets()); const Stickers::Sets &sets(Global::StickerSets());
StickerSets::const_iterator it = sets.constFind(setId); auto it = sets.constFind(setId);
if (it == sets.cend() || (it->flags & MTPDstickerSet::flag_disabled) || it->stickers.isEmpty()) return; if (it == sets.cend() || (it->flags & MTPDstickerSet::Flag::f_disabled) || it->stickers.isEmpty()) return;
StickerPack pack; StickerPack pack;
pack.reserve(it->stickers.size()); pack.reserve(it->stickers.size());
@ -2064,14 +2064,14 @@ void StickerPanInner::refreshRecent() {
void StickerPanInner::refreshRecentStickers(bool performResize) { void StickerPanInner::refreshRecentStickers(bool performResize) {
_custom.clear(); _custom.clear();
clearSelection(true); clearSelection(true);
StickerSets::const_iterator customIt = cStickerSets().constFind(CustomStickerSetId); auto customIt = Global::StickerSets().constFind(Stickers::CustomSetId);
if (cGetRecentStickers().isEmpty() && (customIt == cStickerSets().cend() || customIt->stickers.isEmpty())) { if (cGetRecentStickers().isEmpty() && (customIt == Global::StickerSets().cend() || customIt->stickers.isEmpty())) {
if (!_sets.isEmpty() && _sets.at(0).id == RecentStickerSetId) { if (!_sets.isEmpty() && _sets.at(0).id == Stickers::RecentSetId) {
_sets.pop_front(); _sets.pop_front();
} }
} else { } else {
StickerPack recent; StickerPack recent;
int32 customCnt = (customIt == cStickerSets().cend() ? 0 : customIt->stickers.size()); int32 customCnt = (customIt == Global::StickerSets().cend() ? 0 : customIt->stickers.size());
QMap<DocumentData*, bool> recentOnly; QMap<DocumentData*, bool> recentOnly;
recent.reserve(cGetRecentStickers().size() + customCnt); recent.reserve(cGetRecentStickers().size() + customCnt);
_custom.reserve(cGetRecentStickers().size() + customCnt); _custom.reserve(cGetRecentStickers().size() + customCnt);
@ -2090,8 +2090,8 @@ void StickerPanInner::refreshRecentStickers(bool performResize) {
_custom.push_back(true); _custom.push_back(true);
} }
} }
if (_sets.isEmpty() || _sets.at(0).id != RecentStickerSetId) { if (_sets.isEmpty() || _sets.at(0).id != Stickers::RecentSetId) {
_sets.push_back(DisplayedSet(RecentStickerSetId, MTPDstickerSet::flag_official, lang(lng_emoji_category0), recent.size() * 2, recent)); _sets.push_back(DisplayedSet(Stickers::RecentSetId, MTPDstickerSet::Flag::f_official, lang(lng_emoji_category0), recent.size() * 2, recent));
} else { } else {
_sets[0].pack = recent; _sets[0].pack = recent;
_sets[0].hovers.resize(recent.size() * 2); _sets[0].hovers.resize(recent.size() * 2);
@ -2112,12 +2112,12 @@ void StickerPanInner::refreshRecentStickers(bool performResize) {
void StickerPanInner::fillIcons(QList<StickerIcon> &icons) { void StickerPanInner::fillIcons(QList<StickerIcon> &icons) {
icons.clear(); icons.clear();
icons.reserve(_sets.size() + 1); icons.reserve(_sets.size() + 1);
if (!cSavedGifs().isEmpty()) icons.push_back(StickerIcon(NoneStickerSetId)); if (!cSavedGifs().isEmpty()) icons.push_back(StickerIcon(Stickers::NoneSetId));
if (_sets.isEmpty()) return; if (_sets.isEmpty()) return;
int32 i = 0; int32 i = 0;
if (_sets.at(0).id == RecentStickerSetId) ++i; if (_sets.at(0).id == Stickers::RecentSetId) ++i;
if (i > 0) icons.push_back(StickerIcon(RecentStickerSetId)); if (i > 0) icons.push_back(StickerIcon(Stickers::RecentSetId));
for (int32 l = _sets.size(); i < l; ++i) { for (int32 l = _sets.size(); i < l; ++i) {
DocumentData *s = _sets.at(i).pack.at(0); DocumentData *s = _sets.at(i).pack.at(0);
int32 availw = st::rbEmoji.width - 2 * st::stickerIconPadding, availh = st::rbEmoji.height - 2 * st::stickerIconPadding; int32 availw = st::rbEmoji.width - 2 * st::stickerIconPadding, availh = st::rbEmoji.height - 2 * st::stickerIconPadding;
@ -2143,7 +2143,7 @@ void StickerPanInner::fillPanels(QVector<EmojiPanel*> &panels) {
panels.clear(); panels.clear();
if (_showingInlineItems) { if (_showingInlineItems) {
panels.push_back(new EmojiPanel(parentWidget(), _showingSavedGifs ? lang(lng_saved_gifs) : _inlineBotTitle, NoneStickerSetId, true, 0)); panels.push_back(new EmojiPanel(parentWidget(), _showingSavedGifs ? lang(lng_saved_gifs) : _inlineBotTitle, Stickers::NoneSetId, true, 0));
panels.back()->show(); panels.back()->show();
return; return;
} }
@ -2153,7 +2153,7 @@ void StickerPanInner::fillPanels(QVector<EmojiPanel*> &panels) {
int y = 0; int y = 0;
panels.reserve(_sets.size()); panels.reserve(_sets.size());
for (int32 i = 0, l = _sets.size(); i < l; ++i) { for (int32 i = 0, l = _sets.size(); i < l; ++i) {
bool special = (_sets.at(i).flags & MTPDstickerSet::flag_official); bool special = (_sets.at(i).flags & MTPDstickerSet::Flag::f_official);
panels.push_back(new EmojiPanel(parentWidget(), _sets.at(i).title, _sets.at(i).id, special, y)); panels.push_back(new EmojiPanel(parentWidget(), _sets.at(i).title, _sets.at(i).id, special, y));
panels.back()->show(); panels.back()->show();
connect(panels.back(), SIGNAL(deleteClicked(quint64)), this, SIGNAL(removing(quint64))); connect(panels.back(), SIGNAL(deleteClicked(quint64)), this, SIGNAL(removing(quint64)));
@ -2260,7 +2260,7 @@ void StickerPanInner::updateSelected() {
for (int c = 0, l = _sets.size(); c < l; ++c) { for (int c = 0, l = _sets.size(); c < l; ++c) {
const DisplayedSet &set(_sets.at(c)); const DisplayedSet &set(_sets.at(c));
int cnt = set.pack.size(); int cnt = set.pack.size();
bool special = (set.flags & MTPDstickerSet::flag_official); bool special = (set.flags & MTPDstickerSet::Flag::f_official);
y = ytill; y = ytill;
ytill = y + st::emojiPanHeader + ((cnt / StickerPanPerRow) + ((cnt % StickerPanPerRow) ? 1 : 0)) * st::stickerPanSize.height(); ytill = y + st::emojiPanHeader + ((cnt / StickerPanPerRow) + ((cnt % StickerPanPerRow) ? 1 : 0)) * st::stickerPanSize.height();
@ -2271,7 +2271,7 @@ void StickerPanInner::updateSelected() {
if (selIndex >= set.pack.size()) { if (selIndex >= set.pack.size()) {
selIndex = -1; selIndex = -1;
} else { } else {
if (set.id == RecentStickerSetId && _custom[selIndex]) { if (set.id == Stickers::RecentSetId && _custom[selIndex]) {
int32 inx = sx - (selIndex % StickerPanPerRow) * st::stickerPanSize.width(), iny = p.y() - y - ((selIndex / StickerPanPerRow) * st::stickerPanSize.height()); int32 inx = sx - (selIndex % StickerPanPerRow) * st::stickerPanSize.width(), iny = p.y() - y - ((selIndex / StickerPanPerRow) * st::stickerPanSize.height());
if (inx >= st::stickerPanSize.width() - st::stickerPanDelete.pxWidth() && iny < st::stickerPanDelete.pxHeight()) { if (inx >= st::stickerPanSize.width() - st::stickerPanDelete.pxWidth() && iny < st::stickerPanDelete.pxHeight()) {
selIndex += set.pack.size(); selIndex += set.pack.size();
@ -2286,11 +2286,11 @@ void StickerPanInner::updateSelected() {
bool startanim = false; bool startanim = false;
int oldSel = _selected, oldSelTab = oldSel / MatrixRowShift, xOldSel = -1, newSel = selIndex, newSelTab = newSel / MatrixRowShift, xNewSel = -1; int oldSel = _selected, oldSelTab = oldSel / MatrixRowShift, xOldSel = -1, newSel = selIndex, newSelTab = newSel / MatrixRowShift, xNewSel = -1;
if (oldSel >= 0 && oldSelTab < _sets.size() && _sets[oldSelTab].id == RecentStickerSetId && oldSel >= oldSelTab * MatrixRowShift + _sets[oldSelTab].pack.size()) { if (oldSel >= 0 && oldSelTab < _sets.size() && _sets[oldSelTab].id == Stickers::RecentSetId && oldSel >= oldSelTab * MatrixRowShift + _sets[oldSelTab].pack.size()) {
xOldSel = oldSel; xOldSel = oldSel;
oldSel -= _sets[oldSelTab].pack.size(); oldSel -= _sets[oldSelTab].pack.size();
} }
if (newSel >= 0 && newSelTab < _sets.size() && _sets[newSelTab].id == RecentStickerSetId && newSel >= newSelTab * MatrixRowShift + _sets[newSelTab].pack.size()) { if (newSel >= 0 && newSelTab < _sets.size() && _sets[newSelTab].id == Stickers::RecentSetId && newSel >= newSelTab * MatrixRowShift + _sets[newSelTab].pack.size()) {
xNewSel = newSel; xNewSel = newSel;
newSel -= _sets[newSelTab].pack.size(); newSel -= _sets[newSelTab].pack.size();
} }
@ -2390,7 +2390,7 @@ void StickerPanInner::step_selected(uint64 ms, bool timer) {
void StickerPanInner::showStickerSet(uint64 setId) { void StickerPanInner::showStickerSet(uint64 setId) {
clearSelection(true); clearSelection(true);
if (setId == NoneStickerSetId) { if (setId == Stickers::NoneSetId) {
bool wasNotShowingGifs = !_showingInlineItems; bool wasNotShowingGifs = !_showingInlineItems;
if (wasNotShowingGifs) { if (wasNotShowingGifs) {
_showingInlineItems = true; _showingInlineItems = true;
@ -2460,7 +2460,7 @@ EmojiPanel::EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool
, _setId(setId) , _setId(setId)
, _special(special) , _special(special)
, _deleteVisible(false) , _deleteVisible(false)
, _delete(special ? 0 : new IconedButton(this, st::notifyClose)) { // NoneStickerSetId if in emoji , _delete(special ? 0 : new IconedButton(this, st::notifyClose)) { // Stickers::NoneSetId if in emoji
resize(st::emojiPanWidth, st::emojiPanHeader); resize(st::emojiPanWidth, st::emojiPanHeader);
setMouseTracking(true); setMouseTracking(true);
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
@ -2484,11 +2484,11 @@ void EmojiPanel::setText(const QString &text) {
void EmojiPanel::updateText() { void EmojiPanel::updateText() {
int32 availw = st::emojiPanWidth - st::emojiPanHeaderLeft * 2; int32 availw = st::emojiPanWidth - st::emojiPanHeaderLeft * 2;
if (_deleteVisible) { if (_deleteVisible) {
if (!_special && _setId != NoneStickerSetId) { if (!_special && _setId != Stickers::NoneSetId) {
availw -= st::notifyClose.icon.pxWidth() + st::emojiPanHeaderLeft; availw -= st::notifyClose.icon.pxWidth() + st::emojiPanHeaderLeft;
} }
} else { } else {
QString switchText = lang((_setId != NoneStickerSetId) ? lng_switch_emoji : (cSavedGifs().isEmpty() ? lng_switch_stickers : lng_switch_stickers_gifs)); QString switchText = lang((_setId != Stickers::NoneSetId) ? lng_switch_emoji : (cSavedGifs().isEmpty() ? lng_switch_stickers : lng_switch_stickers_gifs));
availw -= st::emojiSwitchSkip + st::emojiPanHeaderFont->width(switchText); availw -= st::emojiSwitchSkip + st::emojiPanHeaderFont->width(switchText);
} }
_text = st::emojiPanHeaderFont->elided(_fullText, availw); _text = st::emojiPanHeaderFont->elided(_fullText, availw);
@ -2781,7 +2781,7 @@ void EmojiPan::paintEvent(QPaintEvent *e) {
if (!_icons.isEmpty()) { if (!_icons.isEmpty()) {
int32 x = _iconsLeft, i = 0, selxrel = _iconsLeft + _iconSelX.current(), selx = selxrel - _iconsX.current(); int32 x = _iconsLeft, i = 0, selxrel = _iconsLeft + _iconSelX.current(), selx = selxrel - _iconsX.current();
for (int32 l = _icons.size(); i < l && !_icons.at(i).sticker; ++i) { for (int32 l = _icons.size(); i < l && !_icons.at(i).sticker; ++i) {
bool gifs = (_icons.at(i).setId == NoneStickerSetId); bool gifs = (_icons.at(i).setId == Stickers::NoneSetId);
if (selxrel != x) { if (selxrel != x) {
p.drawSpriteLeft(x + st::rbEmojiRecent.imagePos.x(), _iconsTop + st::rbEmojiRecent.imagePos.y(), width(), gifs ? st::savedGifsOver : st::rbEmojiRecent.imageRect); p.drawSpriteLeft(x + st::rbEmojiRecent.imagePos.x(), _iconsTop + st::rbEmojiRecent.imagePos.y(), width(), gifs ? st::savedGifsOver : st::rbEmojiRecent.imageRect);
} }
@ -3512,9 +3512,9 @@ void EmojiPan::onSwitch() {
Notify::clipStopperHidden(ClipStopperSavedGifsPanel); Notify::clipStopperHidden(ClipStopperSavedGifsPanel);
} else { } else {
if (cShowingSavedGifs() && cSavedGifs().isEmpty()) { if (cShowingSavedGifs() && cSavedGifs().isEmpty()) {
s_inner.showStickerSet(DefaultStickerSetId); s_inner.showStickerSet(Stickers::DefaultSetId);
} else if (!cShowingSavedGifs() && !cSavedGifs().isEmpty() && cStickerSets().isEmpty()) { } else if (!cShowingSavedGifs() && !cSavedGifs().isEmpty() && Global::StickerSets().isEmpty()) {
s_inner.showStickerSet(NoneStickerSetId); s_inner.showStickerSet(Stickers::NoneSetId);
} else { } else {
s_inner.updateShowingSavedGifs(); s_inner.updateShowingSavedGifs();
} }
@ -3552,8 +3552,8 @@ void EmojiPan::onSwitch() {
} }
void EmojiPan::onRemoveSet(quint64 setId) { void EmojiPan::onRemoveSet(quint64 setId) {
StickerSets::const_iterator it = cStickerSets().constFind(setId); auto it = Global::StickerSets().constFind(setId);
if (it != cStickerSets().cend() && !(it->flags & MTPDstickerSet::flag_official)) { if (it != Global::StickerSets().cend() && !(it->flags & MTPDstickerSet::Flag::f_official)) {
_removingSetId = it->id; _removingSetId = it->id;
ConfirmBox *box = new ConfirmBox(lng_stickers_remove_pack(lt_sticker_pack, it->title), lang(lng_box_remove)); ConfirmBox *box = new ConfirmBox(lng_stickers_remove_pack(lt_sticker_pack, it->title), lang(lng_box_remove));
connect(box, SIGNAL(confirmed()), this, SLOT(onRemoveSetSure())); connect(box, SIGNAL(confirmed()), this, SLOT(onRemoveSetSure()));
@ -3564,8 +3564,8 @@ void EmojiPan::onRemoveSet(quint64 setId) {
void EmojiPan::onRemoveSetSure() { void EmojiPan::onRemoveSetSure() {
Ui::hideLayer(); Ui::hideLayer();
StickerSets::iterator it = cRefStickerSets().find(_removingSetId); auto it = Global::RefStickerSets().find(_removingSetId);
if (it != cRefStickerSets().cend() && !(it->flags & MTPDstickerSet::flag_official)) { if (it != Global::RefStickerSets().cend() && !(it->flags & MTPDstickerSet::Flag::f_official)) {
if (it->id && it->access) { if (it->id && it->access) {
MTP::send(MTPmessages_UninstallStickerSet(MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)))); MTP::send(MTPmessages_UninstallStickerSet(MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access))));
} else if (!it->shortName.isEmpty()) { } else if (!it->shortName.isEmpty()) {
@ -3581,9 +3581,9 @@ void EmojiPan::onRemoveSetSure() {
++i; ++i;
} }
} }
cRefStickerSets().erase(it); Global::RefStickerSets().erase(it);
int32 removeIndex = cStickerSetsOrder().indexOf(_removingSetId); int removeIndex = Global::StickerSetsOrder().indexOf(_removingSetId);
if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex); if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex);
refreshStickers(); refreshStickers();
Local::writeStickers(); Local::writeStickers();
if (writeRecent) Local::writeUserSettings(); if (writeRecent) Local::writeUserSettings();
@ -4371,15 +4371,15 @@ void MentionsDropdown::updateFiltered(bool resetScroll) {
StickerPack srows; StickerPack srows;
if (_emoji) { if (_emoji) {
QMap<uint64, uint64> setsToRequest; QMap<uint64, uint64> setsToRequest;
StickerSets &sets(cRefStickerSets()); Stickers::Sets &sets(Global::RefStickerSets());
const StickerSetsOrder &order(cStickerSetsOrder()); const Stickers::Order &order(Global::StickerSetsOrder());
for (int32 i = 0, l = order.size(); i < l; ++i) { for (int i = 0, l = order.size(); i < l; ++i) {
StickerSets::iterator it = sets.find(order.at(i)); auto it = sets.find(order.at(i));
if (it != sets.cend()) { if (it != sets.cend()) {
if (it->emoji.isEmpty()) { if (it->emoji.isEmpty()) {
setsToRequest.insert(it->id, it->access); setsToRequest.insert(it->id, it->access);
it->flags |= MTPDstickerSet_flag_NOT_LOADED; it->flags |= MTPDstickerSet_ClientFlag::f_not_loaded;
} else if (!(it->flags & MTPDstickerSet::flag_disabled)) { } else if (!(it->flags & MTPDstickerSet::Flag::f_disabled)) {
StickersByEmojiMap::const_iterator i = it->emoji.constFind(emojiGetNoColor(_emoji)); StickersByEmojiMap::const_iterator i = it->emoji.constFind(emojiGetNoColor(_emoji));
if (i != it->emoji.cend()) { if (i != it->emoji.cend()) {
srows += *i; srows += *i;

View file

@ -420,10 +420,10 @@ private:
int32 _top; int32 _top;
struct DisplayedSet { struct DisplayedSet {
DisplayedSet(uint64 id, int32 flags, const QString &title, int32 hoversSize, const StickerPack &pack = StickerPack()) : id(id), flags(flags), title(title), hovers(hoversSize, 0), pack(pack) { DisplayedSet(uint64 id, MTPDstickerSet::Flags flags, const QString &title, int32 hoversSize, const StickerPack &pack = StickerPack()) : id(id), flags(flags), title(title), hovers(hoversSize, 0), pack(pack) {
} }
uint64 id; uint64 id;
int32 flags; MTPDstickerSet::Flags flags;
QString title; QString title;
QVector<float64> hovers; QVector<float64> hovers;
StickerPack pack; StickerPack pack;
@ -482,7 +482,7 @@ class EmojiPanel : public TWidget {
public: public:
EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool special, int32 wantedY); // NoneStickerSetId if in emoji EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool special, int32 wantedY); // Stickers::NoneSetId if in emoji
void setText(const QString &text); void setText(const QString &text);
void setDeleteVisible(bool isVisible); void setDeleteVisible(bool isVisible);

View file

@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "window.h" #include "window.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "application.h"
#include "layerwidget.h" #include "layerwidget.h"
#include "lang.h" #include "lang.h"
@ -143,6 +144,12 @@ namespace Ui {
return false; return false;
} }
void autoplayMediaInlineAsync(const FullMsgId &msgId) {
if (MainWidget *m = App::main()) {
QMetaObject::invokeMethod(m, "ui_autoplayMediaInlineAsync", Qt::QueuedConnection, Q_ARG(qint32, msgId.channel), Q_ARG(qint32, msgId.msg));
}
}
void showPeerHistory(const PeerId &peer, MsgId msgId, bool back) { void showPeerHistory(const PeerId &peer, MsgId msgId, bool back) {
if (MainWidget *m = App::main()) m->ui_showPeerHistory(peer, msgId, back); if (MainWidget *m = App::main()) m->ui_showPeerHistory(peer, msgId, back);
} }
@ -197,10 +204,6 @@ namespace Notify {
if (MainWidget *m = App::main()) m->notify_clipStopperHidden(type); if (MainWidget *m = App::main()) m->notify_clipStopperHidden(type);
} }
void historyItemResized(const HistoryItem *item, bool scrollToIt) {
if (MainWidget *m = App::main()) m->notify_historyItemResized(item, scrollToIt);
}
void historyItemLayoutChanged(const HistoryItem *item) { void historyItemLayoutChanged(const HistoryItem *item) {
if (MainWidget *m = App::main()) m->notify_historyItemLayoutChanged(item); if (MainWidget *m = App::main()) m->notify_historyItemLayoutChanged(item);
} }
@ -209,6 +212,16 @@ namespace Notify {
if (MainWidget *m = App::main()) m->notify_automaticLoadSettingsChangedGif(); if (MainWidget *m = App::main()) m->notify_automaticLoadSettingsChangedGif();
} }
void handlePendingHistoryUpdate() {
if (MainWidget *m = App::main()) {
m->notify_handlePendingHistoryUpdate();
}
for (auto i = Global::PendingRepaintItems().cbegin(), e = Global::PendingRepaintItems().cend(); i != e; ++i) {
Ui::repaintHistoryItem(i.key());
}
Global::RefPendingRepaintItems().clear();
}
} }
#define DefineReadOnlyVar(Namespace, Type, Name) const Type &Name() { \ #define DefineReadOnlyVar(Namespace, Type, Name) const Type &Name() { \
@ -362,6 +375,7 @@ namespace Global {
struct Data { struct Data {
uint64 LaunchId = 0; uint64 LaunchId = 0;
SingleDelayedCall HandleHistoryUpdate = { App::app(), "call_handleHistoryUpdate" };
Adaptive::Layout AdaptiveLayout = Adaptive::NormalLayout; Adaptive::Layout AdaptiveLayout = Adaptive::NormalLayout;
bool AdaptiveForWide = true; bool AdaptiveForWide = true;
@ -387,9 +401,14 @@ namespace Global {
HiddenPinnedMessagesMap HiddenPinnedMessages; HiddenPinnedMessagesMap HiddenPinnedMessages;
PendingItemsMap PendingInitDimensionsItems;
PendingItemsMap PendingRepaintItems; PendingItemsMap PendingRepaintItems;
Stickers::Sets StickerSets;
Stickers::Order StickerSetsOrder;
uint64 LastStickersUpdate = 0;
MTP::DcOptions DcOptions;
CircleMasksMap CircleMasks; CircleMasksMap CircleMasks;
}; };
@ -416,6 +435,7 @@ namespace Global {
} }
DefineReadOnlyVar(Global, uint64, LaunchId); DefineReadOnlyVar(Global, uint64, LaunchId);
DefineRefVar(Global, SingleDelayedCall, HandleHistoryUpdate);
DefineVar(Global, Adaptive::Layout, AdaptiveLayout); DefineVar(Global, Adaptive::Layout, AdaptiveLayout);
DefineVar(Global, bool, AdaptiveForWide); DefineVar(Global, bool, AdaptiveForWide);
@ -441,9 +461,14 @@ namespace Global {
DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages); DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages);
DefineRefVar(Global, PendingItemsMap, PendingInitDimensionsItems);
DefineRefVar(Global, PendingItemsMap, PendingRepaintItems); DefineRefVar(Global, PendingItemsMap, PendingRepaintItems);
DefineVar(Global, Stickers::Sets, StickerSets);
DefineVar(Global, Stickers::Order, StickerSetsOrder);
DefineVar(Global, uint64, LastStickersUpdate);
DefineVar(Global, MTP::DcOptions, DcOptions);
DefineRefVar(Global, CircleMasksMap, CircleMasks); DefineRefVar(Global, CircleMasksMap, CircleMasks);
}; };

View file

@ -53,6 +53,7 @@ namespace Ui {
void repaintHistoryItem(const HistoryItem *item); void repaintHistoryItem(const HistoryItem *item);
void repaintInlineItem(const LayoutInlineItem *layout); void repaintInlineItem(const LayoutInlineItem *layout);
bool isInlineItemVisible(const LayoutInlineItem *reader); bool isInlineItemVisible(const LayoutInlineItem *reader);
void autoplayMediaInlineAsync(const FullMsgId &msgId);
void showPeerHistory(const PeerId &peer, MsgId msgId, bool back = false); void showPeerHistory(const PeerId &peer, MsgId msgId, bool back = false);
inline void showPeerHistory(const PeerData *peer, MsgId msgId, bool back = false) { inline void showPeerHistory(const PeerData *peer, MsgId msgId, bool back = false) {
@ -90,14 +91,13 @@ namespace Notify {
void clipStopperHidden(ClipStopperType type); void clipStopperHidden(ClipStopperType type);
void historyItemResized(const HistoryItem *item, bool scrollToIt = false);
inline void historyItemsResized() {
historyItemResized(0);
}
void historyItemLayoutChanged(const HistoryItem *item); void historyItemLayoutChanged(const HistoryItem *item);
void automaticLoadSettingsChangedGif(); void automaticLoadSettingsChangedGif();
// handle pending resize() / paint() on history items
void handlePendingHistoryUpdate();
}; };
#define DeclareReadOnlyVar(Type, Name) const Type &Name(); #define DeclareReadOnlyVar(Type, Name) const Type &Name();
@ -137,6 +137,24 @@ namespace DebugLogging {
}; };
} }
namespace Stickers {
static const uint64 DefaultSetId = 0; // for backward compatibility
static const uint64 CustomSetId = 0xFFFFFFFFFFFFFFFFULL, RecentSetId = 0xFFFFFFFFFFFFFFFEULL;
static const uint64 NoneSetId = 0xFFFFFFFFFFFFFFFDULL; // for emoji/stickers panel
struct Set {
Set(uint64 id, uint64 access, const QString &title, const QString &shortName, int32 count, int32 hash, MTPDstickerSet::Flags flags) : id(id), access(access), title(title), shortName(shortName), count(count), hash(hash), flags(flags) {
}
uint64 id, access;
QString title, shortName;
int32 count, hash;
MTPDstickerSet::Flags flags;
StickerPack stickers;
StickersByEmojiMap emoji;
};
typedef QMap<uint64, Set> Sets;
typedef QList<uint64> Order;
}
namespace Global { namespace Global {
bool started(); bool started();
@ -144,6 +162,7 @@ namespace Global {
void finish(); void finish();
DeclareReadOnlyVar(uint64, LaunchId); DeclareReadOnlyVar(uint64, LaunchId);
DeclareRefVar(SingleDelayedCall, HandleHistoryUpdate);
DeclareVar(Adaptive::Layout, AdaptiveLayout); DeclareVar(Adaptive::Layout, AdaptiveLayout);
DeclareVar(bool, AdaptiveForWide); DeclareVar(bool, AdaptiveForWide);
@ -171,9 +190,14 @@ namespace Global {
DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages); DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages);
typedef OrderedSet<HistoryItem*> PendingItemsMap; typedef OrderedSet<HistoryItem*> PendingItemsMap;
DeclareRefVar(PendingItemsMap, PendingInitDimensionsItems);
DeclareRefVar(PendingItemsMap, PendingRepaintItems); DeclareRefVar(PendingItemsMap, PendingRepaintItems);
DeclareVar(Stickers::Sets, StickerSets);
DeclareVar(Stickers::Order, StickerSetsOrder);
DeclareVar(uint64, LastStickersUpdate);
DeclareVar(MTP::DcOptions, DcOptions);
typedef QMap<uint64, QPixmap> CircleMasksMap; typedef QMap<uint64, QPixmap> CircleMasksMap;
DeclareRefVar(CircleMasksMap, CircleMasks); DeclareRefVar(CircleMasksMap, CircleMasks);

View file

@ -309,6 +309,11 @@ void History::clearLastKeyboard() {
lastKeyboardFrom = 0; lastKeyboardFrom = 0;
} }
void History::setHasPendingResizedItems() {
_flags |= Flag::f_has_pending_resized_items;
Global::RefHandleHistoryUpdate().call();
}
bool History::updateTyping(uint64 ms, bool force) { bool History::updateTyping(uint64 ms, bool force) {
bool changed = force; bool changed = force;
for (TypingUsers::iterator i = typing.begin(), e = typing.end(); i != e;) { for (TypingUsers::iterator i = typing.begin(), e = typing.end(); i != e;) {
@ -552,7 +557,7 @@ void ChannelHistory::getRangeDifferenceNext(int32 pts) {
if (!App::main() || _rangeDifferenceToId < _rangeDifferenceFromId) return; if (!App::main() || _rangeDifferenceToId < _rangeDifferenceFromId) return;
int32 limit = _rangeDifferenceToId + 1 - _rangeDifferenceFromId; int32 limit = _rangeDifferenceToId + 1 - _rangeDifferenceFromId;
_rangeDifferenceRequestId = MTP::send(MTPupdates_GetChannelDifference(peer->asChannel()->inputChannel, MTP_channelMessagesFilter(MTP_int(0), MTP_vector<MTPMessageRange>(1, MTP_messageRange(MTP_int(_rangeDifferenceFromId), MTP_int(_rangeDifferenceToId)))), MTP_int(pts), MTP_int(limit)), App::main()->rpcDone(&MainWidget::gotRangeDifference, peer->asChannel())); _rangeDifferenceRequestId = MTP::send(MTPupdates_GetChannelDifference(peer->asChannel()->inputChannel, MTP_channelMessagesFilter(MTP_flags(MTPDchannelMessagesFilter::Flags(0)), MTP_vector<MTPMessageRange>(1, MTP_messageRange(MTP_int(_rangeDifferenceFromId), MTP_int(_rangeDifferenceToId)))), MTP_int(pts), MTP_int(limit)), App::main()->rpcDone(&MainWidget::gotRangeDifference, peer->asChannel()));
} }
void ChannelHistory::addNewGroup(const MTPMessageGroup &group) { void ChannelHistory::addNewGroup(const MTPMessageGroup &group) {
@ -598,7 +603,10 @@ HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
if (!inviter) return 0; if (!inviter) return 0;
if (peerToUser(inviter->id) == MTP::authedId()) unread = false; if (peerToUser(inviter->id) == MTP::authedId()) unread = false;
int32 flags = (unread ? MTPDmessage::flag_unread : 0); MTPDmessage::Flags flags = 0;
if (unread) {
flags |= MTPDmessage::Flag::f_unread;
}
QDateTime inviteDate = peer->asChannel()->inviteDate; QDateTime inviteDate = peer->asChannel()->inviteDate;
if (unread) _maxReadMessageDate = inviteDate; if (unread) _maxReadMessageDate = inviteDate;
if (isEmpty()) { if (isEmpty()) {
@ -1254,10 +1262,6 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
} }
if (msg.type() == mtpc_message) { if (msg.type() == mtpc_message) {
result->updateMedia(msg.c_message().has_media() ? (&msg.c_message().vmedia) : 0); result->updateMedia(msg.c_message().has_media() ? (&msg.c_message().vmedia) : 0);
result->initDimensions();
if (!block) {
Notify::historyItemResized(result);
}
if (applyServiceAction) { if (applyServiceAction) {
App::checkSavedGif(result); App::checkSavedGif(result);
} }
@ -1453,7 +1457,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
} break; } break;
case mtpc_messageActionChatMigrateTo: { case mtpc_messageActionChatMigrateTo: {
peer->asChat()->flags |= MTPDchat::flag_deactivated; peer->asChat()->flags |= MTPDchat::Flag::f_deactivated;
//const MTPDmessageActionChatMigrateTo &d(action.c_messageActionChatMigrateTo()); //const MTPDmessageActionChatMigrateTo &d(action.c_messageActionChatMigrateTo());
//PeerData *channel = App::peerLoaded(peerFromChannel(d.vchannel_id)); //PeerData *channel = App::peerLoaded(peerFromChannel(d.vchannel_id));
@ -1482,25 +1486,25 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
return result; return result;
} }
HistoryItem *History::createItemForwarded(MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *msg) { HistoryItem *History::createItemForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *msg) {
return HistoryMessage::create(this, id, flags, date, from, msg); return HistoryMessage::create(this, id, flags, date, from, msg);
} }
HistoryItem *History::createItemDocument(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) { HistoryItem *History::createItemDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) {
if ((flags & MTPDmessage::flag_reply_to_msg_id) && replyTo > 0) { if ((flags & MTPDmessage::Flag::f_reply_to_msg_id) && replyTo > 0) {
return HistoryReply::create(this, id, flags, viaBotId, replyTo, date, from, doc, caption); return HistoryReply::create(this, id, flags, viaBotId, replyTo, date, from, doc, caption);
} }
return HistoryMessage::create(this, id, flags, viaBotId, date, from, doc, caption); return HistoryMessage::create(this, id, flags, viaBotId, date, from, doc, caption);
} }
HistoryItem *History::createItemPhoto(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) { HistoryItem *History::createItemPhoto(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) {
if ((flags & MTPDmessage::flag_reply_to_msg_id) && replyTo > 0) { if ((flags & MTPDmessage::Flag::f_reply_to_msg_id) && replyTo > 0) {
return HistoryReply::create(this, id, flags, viaBotId, replyTo, date, from, photo, caption); return HistoryReply::create(this, id, flags, viaBotId, replyTo, date, from, photo, caption);
} }
return HistoryMessage::create(this, id, flags, viaBotId, date, from, photo, caption); return HistoryMessage::create(this, id, flags, viaBotId, date, from, photo, caption);
} }
HistoryItem *History::addNewService(MsgId msgId, QDateTime date, const QString &text, int32 flags, HistoryMedia *media, bool newMsg) { HistoryItem *History::addNewService(MsgId msgId, QDateTime date, const QString &text, MTPDmessage::Flags flags, HistoryMedia *media, bool newMsg) {
HistoryBlock *to = 0; HistoryBlock *to = 0;
bool newBlock = blocks.isEmpty(); bool newBlock = blocks.isEmpty();
if (newBlock) { if (newBlock) {
@ -1553,7 +1557,7 @@ HistoryItem *History::addToHistory(const MTPMessage &msg) {
return createItem(nullptr, msg, false); return createItem(nullptr, msg, false);
} }
HistoryItem *History::addNewForwarded(MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *item) { HistoryItem *History::addNewForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *item) {
HistoryBlock *to = nullptr; HistoryBlock *to = nullptr;
bool newBlock = blocks.isEmpty(); bool newBlock = blocks.isEmpty();
if (newBlock) { if (newBlock) {
@ -1566,7 +1570,7 @@ HistoryItem *History::addNewForwarded(MsgId id, int32 flags, QDateTime date, int
return addNewItem(to, newBlock, createItemForwarded(id, flags, date, from, item), true); return addNewItem(to, newBlock, createItemForwarded(id, flags, date, from, item), true);
} }
HistoryItem *History::addNewDocument(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) { HistoryItem *History::addNewDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) {
HistoryBlock *to = 0; HistoryBlock *to = 0;
bool newBlock = blocks.isEmpty(); bool newBlock = blocks.isEmpty();
if (newBlock) { if (newBlock) {
@ -1579,7 +1583,7 @@ HistoryItem *History::addNewDocument(MsgId id, int32 flags, int32 viaBotId, MsgI
return addNewItem(to, newBlock, createItemDocument(id, flags, viaBotId, replyTo, date, from, doc, caption), true); return addNewItem(to, newBlock, createItemDocument(id, flags, viaBotId, replyTo, date, from, doc, caption), true);
} }
HistoryItem *History::addNewPhoto(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) { HistoryItem *History::addNewPhoto(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) {
HistoryBlock *to = 0; HistoryBlock *to = 0;
bool newBlock = blocks.isEmpty(); bool newBlock = blocks.isEmpty();
if (newBlock) { if (newBlock) {
@ -1647,6 +1651,7 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
} }
adding->attachToBlock(to, to->items.size()); adding->attachToBlock(to, to->items.size());
to->items.push_back(adding); to->items.push_back(adding);
adding->previousItemChanged();
setLastMessage(adding); setLastMessage(adding);
adding->y = to->height; adding->y = to->height;
@ -1687,8 +1692,8 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
} }
} }
if (adding->hasReplyMarkup()) { if (adding->hasReplyMarkup()) {
int32 markupFlags = App::replyMarkup(channelId(), adding->id).flags; MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), adding->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || adding->mentionsMe()) { if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || adding->mentionsMe()) {
OrderedSet<PeerData*> *markupSenders = 0; OrderedSet<PeerData*> *markupSenders = 0;
if (peer->isChat()) { if (peer->isChat()) {
markupSenders = &peer->asChat()->markupSenders; markupSenders = &peer->asChat()->markupSenders;
@ -1698,7 +1703,7 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
if (markupSenders) { if (markupSenders) {
markupSenders->insert(adding->from()); markupSenders->insert(adding->from());
} }
if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) { // zero markup means replyKeyboardHide if (markupFlags & MTPDreplyKeyboardMarkup_ClientFlag::f_zero) { // zero markup means replyKeyboardHide
if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->isChat() && !peer->isMegagroup() && !adding->out())) { if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->isChat() && !peer->isMegagroup() && !adding->out())) {
clearLastKeyboard(); clearLastKeyboard();
} }
@ -1769,6 +1774,7 @@ void History::newItemAdded(HistoryItem *item) {
HistoryItem *History::addItemAfterPrevToBlock(HistoryItem *item, HistoryItem *prev, HistoryBlock *block) { HistoryItem *History::addItemAfterPrevToBlock(HistoryItem *item, HistoryItem *prev, HistoryBlock *block) {
item->attachToBlock(block, block->items.size()); item->attachToBlock(block, block->items.size());
block->items.push_back(item); block->items.push_back(item);
item->previousItemChanged();
if (width) { if (width) {
item->y = block->height; item->y = block->height;
block->height += item->resize(width); block->height += item->resize(width);
@ -1902,13 +1908,13 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
if (item->author()->id) { if (item->author()->id) {
if (markupSenders) { // chats with bots if (markupSenders) { // chats with bots
if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) {
int32 markupFlags = App::replyMarkup(channelId(), item->id).flags; MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), item->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || item->mentionsMe()) { if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
bool wasKeyboardHide = markupSenders->contains(item->author()); bool wasKeyboardHide = markupSenders->contains(item->author());
if (!wasKeyboardHide) { if (!wasKeyboardHide) {
markupSenders->insert(item->author()); markupSenders->insert(item->author());
} }
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO)) { if (!(markupFlags & MTPDreplyKeyboardMarkup_ClientFlag::f_zero)) {
if (!lastKeyboardInited) { if (!lastKeyboardInited) {
bool botNotInChat = false; bool botNotInChat = false;
if (peer->isChat()) { if (peer->isChat()) {
@ -1929,9 +1935,9 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
} }
} }
} else if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // conversations with bots } else if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // conversations with bots
int32 markupFlags = App::replyMarkup(channelId(), item->id).flags; MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), item->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || item->mentionsMe()) { if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) { if (markupFlags & MTPDreplyKeyboardMarkup_ClientFlag::f_zero) {
clearLastKeyboard(); clearLastKeyboard();
} else { } else {
lastKeyboardInited = true; lastKeyboardInited = true;
@ -2219,6 +2225,7 @@ HistoryItem *History::addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex,
newItem->attachToBlock(block, itemIndex); newItem->attachToBlock(block, itemIndex);
block->items.insert(itemIndex, newItem); block->items.insert(itemIndex, newItem);
newItem->previousItemChanged();
for (int i = itemIndex + 1, l = block->items.size(); i < l; ++i) { for (int i = itemIndex + 1, l = block->items.size(); i < l; ++i) {
block->items.at(i)->setIndexInBlock(i); block->items.at(i)->setIndexInBlock(i);
} }
@ -2389,9 +2396,12 @@ MsgId History::msgIdForRead() const {
return result; return result;
} }
int32 History::geomResize(int32 newWidth, int32 *ytransform, const HistoryItem *resizedItem) { int32 History::resize(int32 newWidth, int32 *ytransform) {
if (width != newWidth) resizedItem = 0; // recount all items if (width != newWidth) _flags |= Flag::f_pending_resize;
if (width != newWidth || resizedItem) { bool force = (_flags | Flag::f_pending_resize);
_flags &= ~(Flag::f_pending_resize | Flag::f_has_pending_resized_items);
if (force || hasPendingResizedItems()) {
width = newWidth; width = newWidth;
int32 y = 0; int32 y = 0;
for (Blocks::iterator i = blocks.begin(), e = blocks.end(); i != e; ++i) { for (Blocks::iterator i = blocks.begin(), e = blocks.end(); i != e; ++i) {
@ -2401,7 +2411,7 @@ int32 History::geomResize(int32 newWidth, int32 *ytransform, const HistoryItem *
if (block->y != y) { if (block->y != y) {
block->y = y; block->y = y;
} }
y += block->geomResize(newWidth, ytransform, resizedItem); y += block->resize(newWidth, ytransform, force);
if (updTransform) { if (updTransform) {
*ytransform += block->y; *ytransform += block->y;
ytransform = 0; ytransform = 0;
@ -2645,13 +2655,13 @@ History::~History() {
deleteAndMark(editDraft); deleteAndMark(editDraft);
} }
int32 HistoryBlock::geomResize(int32 newWidth, int32 *ytransform, const HistoryItem *resizedItem) { int32 HistoryBlock::resize(int32 newWidth, int32 *ytransform, bool force) {
int32 y = 0; int32 y = 0;
for_const (HistoryItem *item , items) { for_const (HistoryItem *item , items) {
bool updTransform = ytransform && (*ytransform >= item->y) && (*ytransform < item->y + item->height()); bool updTransform = ytransform && (*ytransform >= item->y) && (*ytransform < item->y + item->height());
if (updTransform) *ytransform -= item->y; if (updTransform) *ytransform -= item->y;
item->y = y; item->y = y;
if (!resizedItem || resizedItem == item) { if (force || item->pendingResize()) {
y += item->resize(newWidth); y += item->resize(newWidth);
} else { } else {
y += item->height(); y += item->height();
@ -2783,27 +2793,52 @@ void HistoryMessageUnreadBar::init(int count) {
_width = st::semiboldFont->width(_text); _width = st::semiboldFont->width(_text);
} }
int HistoryMessageUnreadBar::height() const {
return st::unreadBarHeight;
}
void HistoryMessageUnreadBar::paint(Painter &p, int y, int w) const {
p.fillRect(0, y + st::lineWidth, w, st::unreadBarHeight - 2 * st::lineWidth, st::unreadBarBG);
p.fillRect(0, y + st::unreadBarHeight - st::lineWidth, w, st::lineWidth, st::unreadBarBorder);
p.setFont(st::unreadBarFont);
p.setPen(st::unreadBarColor);
p.drawText((w - _width) / 2, y + (st::unreadBarHeight - st::lineWidth - st::unreadBarFont->height) / 2 + st::unreadBarFont->ascent, _text);
}
HistoryMessageDate::HistoryMessageDate(Interfaces*) : _width(0) { HistoryMessageDate::HistoryMessageDate(Interfaces*) : _width(0) {
} }
void HistoryMessageDate::init(const QDateTime &date) { void HistoryMessageDate::init(const QDateTime &date) {
_text = langDayOfMonthFull(date.date()); _text = langDayOfMonthFull(date.date());
_width = st::semiboldFont->width(_text); _width = st::msgServiceFont->width(_text);
} }
HistoryItem::HistoryItem(History *history, MsgId msgId, int32 flags, QDateTime msgDate, int32 from) : HistoryElem() int HistoryMessageDate::height() const {
return st::msgServiceMargin.top() + st::msgServicePadding.top() + st::msgServiceFont->height + st::msgServicePadding.bottom() + st::msgServiceMargin.bottom();
}
void HistoryMessageDate::paint(Painter &p, int y, int w) const {
int left = (w - _width - st::msgServicePadding.left() - st::msgServicePadding.right()) / 2;
int height = st::msgServicePadding.top() + st::msgServiceFont->height + st::msgServicePadding.bottom();
App::roundRect(p, left, y + st::msgServiceMargin.top(), _width + st::msgServicePadding.left() + st::msgServicePadding.left(), height, App::msgServiceBg(), ServiceCorners);
p.setFont(st::msgServiceFont);
p.setPen(st::msgServiceColor);
p.drawText(left + st::msgServicePadding.left(), y + st::msgServiceMargin.top() + st::msgServicePadding.top() + st::msgServiceFont->ascent, _text);
}
HistoryItem::HistoryItem(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime msgDate, int32 from) : HistoryElem()
, y(0) , y(0)
, id(msgId) , id(msgId)
, date(msgDate) , date(msgDate)
, _from(from ? App::user(from) : history->peer) , _from(from ? App::user(from) : history->peer)
, _history(history) , _history(history)
, _flags(flags) , _flags(flags | MTPDmessage_ClientFlag::f_pending_init_dimensions | MTPDmessage_ClientFlag::f_pending_resize)
, _authorNameVersion(author()->nameVersion) { , _authorNameVersion(author()->nameVersion) {
} }
void HistoryItem::finishCreate() { void HistoryItem::finishCreate() {
App::historyRegItem(this); App::historyRegItem(this);
initDimensions();
} }
void HistoryItem::destroy() { void HistoryItem::destroy() {
@ -2827,18 +2862,18 @@ void HistoryItem::destroy() {
} }
void HistoryItem::detach() { void HistoryItem::detach() {
if (_history) { if (_history->unreadBar == this) {
if (_history->unreadBar == this) { _history->unreadBar = 0;
_history->unreadBar = 0; }
} if (_history->isChannel()) {
if (_history->isChannel()) { _history->asChannelHistory()->messageDetached(this);
_history->asChannelHistory()->messageDetached(this);
}
} }
if (_block) { if (_block) {
_block->removeItem(this); _block->removeItem(this);
detachFast(); detachFast();
App::historyItemDetached(this); App::historyItemDetached(this);
_history->setPendingResize();
} else { } else {
if (_history->showFrom == this) { if (_history->showFrom == this) {
_history->showFrom = 0; _history->showFrom = 0;
@ -2856,11 +2891,11 @@ void HistoryItem::previousItemChanged() {
if (!Is<HistoryMessageDate>()) { if (!Is<HistoryMessageDate>()) {
AddInterfaces(HistoryMessageDate::Bit()); AddInterfaces(HistoryMessageDate::Bit());
Get<HistoryMessageDate>()->init(date); Get<HistoryMessageDate>()->init(date);
Global::RefPendingInitDimensionsItems().insert(this); setPendingInitDimensions();
} }
} else if (Is<HistoryMessageDate>()) { } else if (Is<HistoryMessageDate>()) {
RemoveInterfaces(HistoryMessageDate::Bit()); RemoveInterfaces(HistoryMessageDate::Bit());
Global::RefPendingInitDimensionsItems().insert(this); setPendingInitDimensions();
} }
} }
@ -2904,7 +2939,7 @@ bool HistoryItem::canEdit(const QDateTime &cur) const {
void HistoryItem::destroyUnreadBar() { void HistoryItem::destroyUnreadBar() {
if (Is<HistoryMessageUnreadBar>()) { if (Is<HistoryMessageUnreadBar>()) {
RemoveInterfaces(HistoryMessageUnreadBar::Bit()); RemoveInterfaces(HistoryMessageUnreadBar::Bit());
Global::RefPendingInitDimensionsItems().insert(this); setPendingInitDimensions();
if (_history->unreadBar == this) { if (_history->unreadBar == this) {
_history->unreadBar = nullptr; _history->unreadBar = nullptr;
} }
@ -2916,7 +2951,7 @@ void HistoryItem::setUnreadBarCount(int count) {
HistoryMessageUnreadBar *bar; HistoryMessageUnreadBar *bar;
if (!Is<HistoryMessageUnreadBar>()) { if (!Is<HistoryMessageUnreadBar>()) {
AddInterfaces(HistoryMessageUnreadBar::Bit()); AddInterfaces(HistoryMessageUnreadBar::Bit());
Global::RefPendingInitDimensionsItems().insert(this); setPendingInitDimensions();
bar = Get<HistoryMessageUnreadBar>(); bar = Get<HistoryMessageUnreadBar>();
} else { } else {
bar = Get<HistoryMessageUnreadBar>(); bar = Get<HistoryMessageUnreadBar>();
@ -2959,8 +2994,7 @@ void HistoryItem::clipCallback(ClipReaderNotification notification) {
} }
} }
if (!stopped) { if (!stopped) {
initDimensions(); setPendingInitDimensions();
Notify::historyItemResized(this);
Notify::historyItemLayoutChanged(this); Notify::historyItemLayoutChanged(this);
} }
} break; } break;
@ -4516,8 +4550,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
_data->automaticLoad(parent); _data->automaticLoad(parent);
bool loaded = _data->loaded(), displayLoading = (parent->id < 0) || _data->displayLoading(); bool loaded = _data->loaded(), displayLoading = (parent->id < 0) || _data->displayLoading();
if (loaded && !gif() && _gif != BadClipReader && cAutoPlayGif()) { if (loaded && !gif() && _gif != BadClipReader && cAutoPlayGif()) {
const_cast<HistoryGif*>(this)->playInline(const_cast<HistoryItem*>(parent)); Ui::autoplayMediaInlineAsync(parent->fullId());
if (gif()) _gif->setAutoplay();
} }
int32 skipx = 0, skipy = 0, width = _width, height = _height; int32 skipx = 0, skipy = 0, width = _width, height = _height;
@ -4711,7 +4744,7 @@ ImagePtr HistoryGif::replyPreview() {
return _data->makeReplyPreview(); return _data->makeReplyPreview();
} }
bool HistoryGif::playInline(HistoryItem *parent) { bool HistoryGif::playInline(HistoryItem *parent, bool autoplay) {
if (gif()) { if (gif()) {
stopInline(parent); stopInline(parent);
} else { } else {
@ -4720,6 +4753,7 @@ bool HistoryGif::playInline(HistoryItem *parent) {
} }
_gif = new ClipReader(_data->location(), _data->data(), func(parent, &HistoryItem::clipCallback)); _gif = new ClipReader(_data->location(), _data->data(), func(parent, &HistoryItem::clipCallback));
App::regGifItem(_gif, parent); App::regGifItem(_gif, parent);
if (gif()) _gif->setAutoplay();
} }
return true; return true;
} }
@ -4731,8 +4765,7 @@ void HistoryGif::stopInline(HistoryItem *parent) {
_gif = 0; _gif = 0;
} }
parent->initDimensions(); parent->setPendingInitDimensions();
Notify::historyItemResized(parent);
Notify::historyItemLayoutChanged(parent); Notify::historyItemLayoutChanged(parent);
} }
@ -6062,7 +6095,7 @@ HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg) :
setText(text, msg.has_entities() ? entitiesFromMTP(msg.ventities.c_vector().v) : EntitiesInText()); setText(text, msg.has_entities() ? entitiesFromMTP(msg.ventities.c_vector().v) : EntitiesInText());
} }
HistoryMessage::HistoryMessage(History *history, MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *fwd) HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *fwd)
: HistoryItem(history, id, newForwardedFlags(history->peer, from, fwd) | flags, date, from) : HistoryItem(history, id, newForwardedFlags(history->peer, from, fwd) | flags, date, from)
, _text(st::msgMinWidth) , _text(st::msgMinWidth)
, _textWidth(0) , _textWidth(0)
@ -6080,36 +6113,36 @@ HistoryMessage::HistoryMessage(History *history, MsgId id, int32 flags, QDateTim
setText(fwd->originalText(), fwd->originalEntities()); setText(fwd->originalText(), fwd->originalEntities());
} }
HistoryMessage::HistoryMessage(History *history, MsgId id, int32 flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities) HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities)
: HistoryItem(history, id, flags, date, (flags & MTPDmessage::flag_from_id) ? from : 0) : HistoryItem(history, id, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0)
, _text(st::msgMinWidth) , _text(st::msgMinWidth)
, _textWidth(0) , _textWidth(0)
, _textHeight(0) , _textHeight(0)
, _media(nullptr) { , _media(nullptr) {
createInterfaces((flags & MTPDmessage::flag_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1); createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1);
setText(msg, entities); setText(msg, entities);
} }
HistoryMessage::HistoryMessage(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) : HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) :
HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::flag_from_id) ? from : 0) HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0)
, _text(st::msgMinWidth) , _text(st::msgMinWidth)
, _textWidth(0) , _textWidth(0)
, _textHeight(0) , _textHeight(0)
, _media(nullptr) { , _media(nullptr) {
createInterfaces((flags & MTPDmessage::flag_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1); createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1);
initMediaFromDocument(doc, caption); initMediaFromDocument(doc, caption);
setText(QString(), EntitiesInText()); setText(QString(), EntitiesInText());
} }
HistoryMessage::HistoryMessage(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) : HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) :
HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::flag_from_id) ? from : 0) HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0)
, _text(st::msgMinWidth) , _text(st::msgMinWidth)
, _textWidth(0) , _textWidth(0)
, _textHeight(0) , _textHeight(0)
, _media(nullptr) { , _media(nullptr) {
createInterfaces((flags & MTPDmessage::flag_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1); createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1);
_media = new HistoryPhoto(photo, caption, this); _media = new HistoryPhoto(photo, caption, this);
_media->attachToItem(this); _media->attachToItem(this);
@ -6433,7 +6466,7 @@ void HistoryMessage::setText(const QString &text, const EntitiesInText &entities
for (int32 i = 0, l = entities.size(); i != l; ++i) { for (int32 i = 0, l = entities.size(); i != l; ++i) {
if (entities.at(i).type == EntityInTextUrl || entities.at(i).type == EntityInTextCustomUrl || entities.at(i).type == EntityInTextEmail) { if (entities.at(i).type == EntityInTextUrl || entities.at(i).type == EntityInTextCustomUrl || entities.at(i).type == EntityInTextEmail) {
_flags |= MTPDmessage_flag_HAS_TEXT_LINKS; _flags |= MTPDmessage_ClientFlag::f_has_text_links;
break; break;
} }
} }
@ -6528,7 +6561,7 @@ void HistoryMessage::drawInfo(Painter &p, int32 right, int32 bottom, int32 width
} }
} }
void HistoryMessage::setViewsCount(int32 count, bool reinit) { void HistoryMessage::setViewsCount(int32 count) {
HistoryMessageViews *views = Get<HistoryMessageViews>(); HistoryMessageViews *views = Get<HistoryMessageViews>();
if (!views || views->_views == count || (count >= 0 && views->_views > count)) return; if (!views || views->_views == count || (count >= 0 && views->_views > count)) return;
@ -6544,10 +6577,7 @@ void HistoryMessage::setViewsCount(int32 count, bool reinit) {
_textWidth = 0; _textWidth = 0;
_textHeight = 0; _textHeight = 0;
} }
if (reinit) { setPendingInitDimensions();
initDimensions();
Notify::historyItemResized(this);
}
} }
} }
@ -6562,8 +6592,7 @@ void HistoryMessage::setId(MsgId newId) {
_textWidth = 0; _textWidth = 0;
_textHeight = 0; _textHeight = 0;
} }
initDimensions(); setPendingInitDimensions();
Notify::historyItemResized(this);
} }
} }
@ -6572,6 +6601,24 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle)); textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle));
int left = 0, width = 0, height = _height;
countPositionAndSize(left, width);
if (width < 1) return;
int dateh = 0, unreadbarh = 0;
if (auto *date = Get<HistoryMessageDate>()) {
dateh = date->height();
date->paint(p, 0, _history->width);
p.translate(0, dateh);
height -= dateh;
}
if (auto *unreadbar = Get<HistoryMessageUnreadBar>()) {
unreadbarh = unreadbar->height();
unreadbar->paint(p, 0, _history->width);
p.translate(0, unreadbarh);
height -= unreadbarh;
}
uint64 animms = App::main() ? App::main()->animActiveTimeStart(this) : 0; uint64 animms = App::main() ? App::main()->animActiveTimeStart(this) : 0;
if (animms > 0 && animms <= ms) { if (animms > 0 && animms <= ms) {
animms = ms - animms; animms = ms - animms;
@ -6581,19 +6628,15 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
float64 dt = (animms > st::activeFadeInDuration) ? (1 - (animms - st::activeFadeInDuration) / float64(st::activeFadeOutDuration)) : (animms / float64(st::activeFadeInDuration)); float64 dt = (animms > st::activeFadeInDuration) ? (1 - (animms - st::activeFadeInDuration) / float64(st::activeFadeOutDuration)) : (animms / float64(st::activeFadeInDuration));
float64 o = p.opacity(); float64 o = p.opacity();
p.setOpacity(o * dt); p.setOpacity(o * dt);
p.fillRect(0, 0, _history->width, _height, textstyleCurrent()->selectOverlay->b); p.fillRect(0, 0, _history->width, height, textstyleCurrent()->selectOverlay->b);
p.setOpacity(o); p.setOpacity(o);
} }
} }
int32 left = 0, width = 0;
countPositionAndSize(left, width);
if (displayFromPhoto()) { if (displayFromPhoto()) {
int32 photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); int32 photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
author()->paintUserpic(p, st::msgPhotoSize, photoleft, _height - st::msgMargin.bottom() - st::msgPhotoSize); author()->paintUserpic(p, st::msgPhotoSize, photoleft, height - st::msgMargin.bottom() - st::msgPhotoSize);
} }
if (width < 1) return;
if (bubble) { if (bubble) {
const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>(); const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>();
@ -6602,7 +6645,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
fromNameUpdated(width); fromNameUpdated(width);
} }
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom()); QRect r(left, st::msgMargin.top(), width, height - st::msgMargin.top() - st::msgMargin.bottom());
style::color bg(selected ? (outbg ? st::msgOutBgSelected : st::msgInBgSelected) : (outbg ? st::msgOutBg : st::msgInBg)); style::color bg(selected ? (outbg ? st::msgOutBgSelected : st::msgInBgSelected) : (outbg ? st::msgOutBg : st::msgInBg));
style::color sh(selected ? (outbg ? st::msgOutShadowSelected : st::msgInShadowSelected) : (outbg ? st::msgOutShadow : st::msgInShadow)); style::color sh(selected ? (outbg ? st::msgOutShadowSelected : st::msgInShadowSelected) : (outbg ? st::msgOutShadow : st::msgInShadow));
@ -6628,11 +6671,10 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
drawMessageText(p, trect, selection); drawMessageText(p, trect, selection);
if (_media && _media->isDisplayed()) { if (_media && _media->isDisplayed()) {
p.save(); int32 top = height - st::msgMargin.bottom() - _media->height();
int32 top = _height - st::msgMargin.bottom() - _media->height();
p.translate(left, top); p.translate(left, top);
_media->draw(p, this, r.translated(-left, -top), selected, ms); _media->draw(p, this, r.translated(-left, -top), selected, ms);
p.restore(); p.translate(-left, -top);
if (!_media->customInfoLayout()) { if (!_media->customInfoLayout()) {
HistoryMessage::drawInfo(p, r.x() + r.width(), r.y() + r.height(), 2 * r.x() + r.width(), selected, InfoDisplayDefault); HistoryMessage::drawInfo(p, r.x() + r.width(), r.y() + r.height(), 2 * r.x() + r.width(), selected, InfoDisplayDefault);
} }
@ -6640,11 +6682,13 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
HistoryMessage::drawInfo(p, r.x() + r.width(), r.y() + r.height(), 2 * r.x() + r.width(), selected, InfoDisplayDefault); HistoryMessage::drawInfo(p, r.x() + r.width(), r.y() + r.height(), 2 * r.x() + r.width(), selected, InfoDisplayDefault);
} }
} else { } else {
p.save();
int32 top = st::msgMargin.top(); int32 top = st::msgMargin.top();
p.translate(left, top); p.translate(left, top);
_media->draw(p, this, r.translated(-left, -top), selected, ms); _media->draw(p, this, r.translated(-left, -top), selected, ms);
p.restore(); p.translate(-left, -top);
}
if (int skiph = dateh + unreadbarh) {
p.translate(0, -skiph);
} }
textstyleRestore(); textstyleRestore();
@ -6689,7 +6733,7 @@ void HistoryMessage::destroy() {
HistoryItem::destroy(); HistoryItem::destroy();
} }
int32 HistoryMessage::resize(int32 width) { int HistoryMessage::resizeImpl(int width) {
if (width < st::msgMinWidth) return _height; if (width < st::msgMinWidth) return _height;
width -= st::msgMargin.left() + st::msgMargin.right(); width -= st::msgMargin.left() + st::msgMargin.right();
@ -6757,16 +6801,33 @@ int32 HistoryMessage::resize(int32 width) {
_height = _media->resize(width, this); _height = _media->resize(width, this);
} }
_height += st::msgMargin.top() + st::msgMargin.bottom(); _height += st::msgMargin.top() + st::msgMargin.bottom();
if (auto *date = Get<HistoryMessageDate>()) {
_height += date->height();
}
if (auto *unreadbar = Get<HistoryMessageUnreadBar>()) {
_height += unreadbar->height();
}
return _height; return _height;
} }
bool HistoryMessage::hasPoint(int32 x, int32 y) const { bool HistoryMessage::hasPoint(int32 x, int32 y) const {
int32 left = 0, width = 0; int left = 0, width = 0, height = _height;
countPositionAndSize(left, width); countPositionAndSize(left, width);
if (width < 1) return false; if (width < 1) return false;
if (auto *date = Get<HistoryMessageDate>()) {
int dateh = date->height();
y -= dateh;
height -= dateh;
}
if (auto *unreadbar = Get<HistoryMessageUnreadBar>()) {
int unreadbarh = unreadbar->height();
y -= unreadbarh;
height -= unreadbarh;
}
if (drawBubble()) { if (drawBubble()) {
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom()); QRect r(left, st::msgMargin.top(), width, height - st::msgMargin.top() - st::msgMargin.bottom());
return r.contains(x, y); return r.contains(x, y);
} else { } else {
return _media->hasPoint(x - left, y - st::msgMargin.top(), this); return _media->hasPoint(x - left, y - st::msgMargin.top(), this);
@ -6794,12 +6855,23 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
lnk = TextLinkPtr(); lnk = TextLinkPtr();
state = HistoryDefaultCursorState; state = HistoryDefaultCursorState;
int32 left = 0, width = 0; int left = 0, width = 0, height = _height;
countPositionAndSize(left, width); countPositionAndSize(left, width);
if (auto *date = Get<HistoryMessageDate>()) {
int dateh = date->height();
y -= dateh;
height -= dateh;
}
if (auto *unreadbar = Get<HistoryMessageUnreadBar>()) {
int unreadbarh = unreadbar->height();
y -= unreadbarh;
height -= unreadbarh;
}
if (displayFromPhoto()) { if (displayFromPhoto()) {
int32 photoleft = left + ((!isPost() && out() && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); int32 photoleft = left + ((!isPost() && out() && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
if (x >= photoleft && x < photoleft + st::msgPhotoSize && y >= _height - st::msgMargin.bottom() - st::msgPhotoSize && y < _height - st::msgMargin.bottom()) { if (x >= photoleft && x < photoleft + st::msgPhotoSize && y >= height - st::msgMargin.bottom() - st::msgPhotoSize && y < height - st::msgMargin.bottom()) {
lnk = author()->lnk; lnk = author()->lnk;
return; return;
} }
@ -6810,7 +6882,7 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>(); const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>();
const HistoryMessageVia *via = Get<HistoryMessageVia>(); const HistoryMessageVia *via = Get<HistoryMessageVia>();
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom()); QRect r(left, st::msgMargin.top(), width, height - st::msgMargin.top() - st::msgMargin.bottom());
if (displayFromName()) { // from user left name if (displayFromName()) { // from user left name
if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + st::msgNameFont->height) { if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + st::msgNameFont->height) {
if (x >= r.left() + st::msgPadding.left() && x < r.left() + r.width() - st::msgPadding.right() && x < r.left() + st::msgPadding.left() + author()->nameText.maxWidth()) { if (x >= r.left() + st::msgPadding.left() && x < r.left() + r.width() - st::msgPadding.right() && x < r.left() + st::msgPadding.left() + author()->nameText.maxWidth()) {
@ -6897,14 +6969,25 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x,
after = false; after = false;
upon = false; upon = false;
if (drawBubble()) { if (drawBubble()) {
int32 left = 0, width = 0; int left = 0, width = 0, height = _height;
countPositionAndSize(left, width); countPositionAndSize(left, width);
if (width < 1) return; if (width < 1) return;
if (auto *date = Get<HistoryMessageDate>()) {
int dateh = date->height();
y -= dateh;
height -= dateh;
}
if (auto *unreadbar = Get<HistoryMessageUnreadBar>()) {
int unreadbarh = unreadbar->height();
y -= unreadbarh;
height -= unreadbarh;
}
const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>(); const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>();
const HistoryMessageVia *via = Get<HistoryMessageVia>(); const HistoryMessageVia *via = Get<HistoryMessageVia>();
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom()); QRect r(left, st::msgMargin.top(), width, height - st::msgMargin.top() - st::msgMargin.bottom());
if (displayFromName()) { // from user left name if (displayFromName()) { // from user left name
r.setTop(r.top() + st::msgNameFont->height); r.setTop(r.top() + st::msgNameFont->height);
} else if (via && !fwd) { } else if (via && !fwd) {
@ -6963,7 +7046,7 @@ HistoryMessage::~HistoryMessage() {
_media->detachFromItem(this); _media->detachFromItem(this);
deleteAndMark(_media); deleteAndMark(_media);
} }
if (_flags & MTPDmessage::flag_reply_markup) { if (_flags & MTPDmessage::Flag::f_reply_markup) {
App::clearReplyMarkup(channelId(), id); App::clearReplyMarkup(channelId(), id);
} }
} }
@ -6979,7 +7062,7 @@ HistoryReply::HistoryReply(History *history, const MTPDmessage &msg) : HistoryMe
} }
} }
HistoryReply::HistoryReply(History *history, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) HistoryReply::HistoryReply(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption)
: HistoryMessage(history, msgId, flags, viaBotId, date, from, doc, caption) : HistoryMessage(history, msgId, flags, viaBotId, date, from, doc, caption)
, replyToMsgId(replyTo) , replyToMsgId(replyTo)
, replyToMsg(0) , replyToMsg(0)
@ -6991,7 +7074,7 @@ HistoryReply::HistoryReply(History *history, MsgId msgId, int32 flags, int32 via
} }
} }
HistoryReply::HistoryReply(History *history, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) HistoryReply::HistoryReply(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption)
: HistoryMessage(history, msgId, flags, viaBotId, date, from, photo, caption) : HistoryMessage(history, msgId, flags, viaBotId, date, from, photo, caption)
, replyToMsgId(replyTo) , replyToMsgId(replyTo)
, replyToMsg(0) , replyToMsg(0)
@ -7053,8 +7136,7 @@ bool HistoryReply::updateReplyTo(bool force) {
replyToMsgId = 0; replyToMsgId = 0;
} }
if (force) { if (force) {
initDimensions(); setPendingInitDimensions();
Notify::historyItemResized(this);
} }
return (replyToMsg || !replyToMsgId); return (replyToMsg || !replyToMsgId);
} }
@ -7178,8 +7260,8 @@ void HistoryReply::drawMessageText(Painter &p, QRect trect, uint32 selection) co
HistoryMessage::drawMessageText(p, trect, selection); HistoryMessage::drawMessageText(p, trect, selection);
} }
int32 HistoryReply::resize(int32 width) { int32 HistoryReply::resizeImpl(int32 width) {
HistoryMessage::resize(width); HistoryMessage::resizeImpl(width);
if (drawBubble()) { if (drawBubble()) {
if (emptyText() && !displayFromName() && !Is<HistoryMessageVia>()) { if (emptyText() && !displayFromName() && !Is<HistoryMessageVia>()) {
@ -7405,7 +7487,7 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
} break; } break;
case mtpc_messageActionChatMigrateTo: { case mtpc_messageActionChatMigrateTo: {
_flags |= MTPDmessage_flag_IS_GROUP_MIGRATE; _flags |= MTPDmessage_ClientFlag::f_is_group_migrate;
const MTPDmessageActionChatMigrateTo &d(action.c_messageActionChatMigrateTo()); const MTPDmessageActionChatMigrateTo &d(action.c_messageActionChatMigrateTo());
if (true/*PeerData *channel = App::peerLoaded(peerFromChannel(d.vchannel_id))*/) { if (true/*PeerData *channel = App::peerLoaded(peerFromChannel(d.vchannel_id))*/) {
text = lang(lng_action_group_migrate); text = lang(lng_action_group_migrate);
@ -7415,7 +7497,7 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
} break; } break;
case mtpc_messageActionChannelMigrateFrom: { case mtpc_messageActionChannelMigrateFrom: {
_flags |= MTPDmessage_flag_IS_GROUP_MIGRATE; _flags |= MTPDmessage_ClientFlag::f_is_group_migrate;
const MTPDmessageActionChannelMigrateFrom &d(action.c_messageActionChannelMigrateFrom()); const MTPDmessageActionChannelMigrateFrom &d(action.c_messageActionChannelMigrateFrom());
if (true/*PeerData *chat = App::peerLoaded(peerFromChannel(d.vchat_id))*/) { if (true/*PeerData *chat = App::peerLoaded(peerFromChannel(d.vchat_id))*/) {
text = lang(lng_action_group_migrate); text = lang(lng_action_group_migrate);
@ -7478,8 +7560,7 @@ bool HistoryServiceMsg::updatePinned(bool force) {
updatePinnedText(); updatePinnedText();
} }
if (force) { if (force) {
initDimensions(); setPendingInitDimensions();
Notify::historyItemResized(this);
if (gotDependencyItem && App::wnd()) { if (gotDependencyItem && App::wnd()) {
App::wnd()->notifySettingGot(); App::wnd()->notifySettingGot();
} }
@ -7560,7 +7641,7 @@ bool HistoryServiceMsg::updatePinnedText(const QString *pfrom, QString *ptext) {
} }
HistoryServiceMsg::HistoryServiceMsg(History *history, const MTPDmessageService &msg) : HistoryServiceMsg::HistoryServiceMsg(History *history, const MTPDmessageService &msg) :
HistoryItem(history, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0) HistoryItem(history, msg.vid.v, mtpCastFlags(msg.vflags.v), ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0)
, _text(st::msgMinWidth) , _text(st::msgMinWidth)
, _media(0) { , _media(0) {
if (msg.has_reply_to_msg_id()) { if (msg.has_reply_to_msg_id()) {
@ -7573,7 +7654,7 @@ HistoryServiceMsg::HistoryServiceMsg(History *history, const MTPDmessageService
setMessageByAction(msg.vaction); setMessageByAction(msg.vaction);
} }
HistoryServiceMsg::HistoryServiceMsg(History *history, MsgId msgId, QDateTime date, const QString &msg, int32 flags, HistoryMedia *media, int32 from) : HistoryServiceMsg::HistoryServiceMsg(History *history, MsgId msgId, QDateTime date, const QString &msg, MTPDmessage::Flags flags, HistoryMedia *media, int32 from) :
HistoryItem(history, msgId, flags, date, from) HistoryItem(history, msgId, flags, date, from)
, _text(st::msgServiceFont, msg, _historySrvOptions, st::dlgMinWidth) , _text(st::msgServiceFont, msg, _historySrvOptions, st::dlgMinWidth)
, _media(media) { , _media(media) {
@ -7656,15 +7737,15 @@ void HistoryServiceMsg::draw(Painter &p, const QRect &r, uint32 selection, uint6
App::roundRect(p, left, st::msgServiceMargin.top(), width, height, App::msgServiceBg(), (selection == FullSelection) ? ServiceSelectedCorners : ServiceCorners); App::roundRect(p, left, st::msgServiceMargin.top(), width, height, App::msgServiceBg(), (selection == FullSelection) ? ServiceSelectedCorners : ServiceCorners);
p.setBrush(Qt::NoBrush); p.setBrush(Qt::NoBrush);
p.setPen(st::msgServiceColor->p); p.setPen(st::msgServiceColor);
p.setFont(st::msgServiceFont->f); p.setFont(st::msgServiceFont);
uint16 selectedFrom = (selection == FullSelection) ? 0 : (selection >> 16) & 0xFFFF; uint16 selectedFrom = (selection == FullSelection) ? 0 : (selection >> 16) & 0xFFFF;
uint16 selectedTo = (selection == FullSelection) ? 0 : selection & 0xFFFF; uint16 selectedTo = (selection == FullSelection) ? 0 : selection & 0xFFFF;
_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignCenter, 0, -1, selectedFrom, selectedTo); _text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignCenter, 0, -1, selectedFrom, selectedTo);
textstyleRestore(); textstyleRestore();
} }
int32 HistoryServiceMsg::resize(int32 width) { int32 HistoryServiceMsg::resizeImpl(int32 width) {
int32 maxwidth = _history->width; int32 maxwidth = _history->width;
if (Adaptive::Wide()) { if (Adaptive::Wide()) {
maxwidth = qMin(maxwidth, int32(st::msgMaxWidth + 2 * st::msgPhotoSkip)); maxwidth = qMin(maxwidth, int32(st::msgMaxWidth + 2 * st::msgPhotoSkip));
@ -7861,7 +7942,7 @@ void HistoryCollapse::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
state = HistoryDefaultCursorState; state = HistoryDefaultCursorState;
} }
HistoryJoined::HistoryJoined(History *history, const QDateTime &inviteDate, UserData *inviter, int32 flags) : HistoryJoined::HistoryJoined(History *history, const QDateTime &inviteDate, UserData *inviter, MTPDmessage::Flags flags) :
HistoryServiceMsg(history, clientMsgId(), inviteDate, QString(), flags) { HistoryServiceMsg(history, clientMsgId(), inviteDate, QString(), flags) {
textstyleSet(&st::serviceTextStyle); textstyleSet(&st::serviceTextStyle);
if (peerToUser(inviter->id) == MTP::authedId()) { if (peerToUser(inviter->id) == MTP::authedId()) {

View file

@ -242,16 +242,16 @@ public:
virtual ~History(); virtual ~History();
HistoryItem *createItem(HistoryBlock *block, const MTPMessage &msg, bool applyServiceAction); HistoryItem *createItem(HistoryBlock *block, const MTPMessage &msg, bool applyServiceAction);
HistoryItem *createItemForwarded(MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *msg); HistoryItem *createItemForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *msg);
HistoryItem *createItemDocument(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption); HistoryItem *createItemDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption);
HistoryItem *createItemPhoto(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption); HistoryItem *createItemPhoto(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
HistoryItem *addNewService(MsgId msgId, QDateTime date, const QString &text, int32 flags = 0, HistoryMedia *media = 0, bool newMsg = true); HistoryItem *addNewService(MsgId msgId, QDateTime date, const QString &text, MTPDmessage::Flags flags = 0, HistoryMedia *media = 0, bool newMsg = true);
HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type); HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type);
HistoryItem *addToHistory(const MTPMessage &msg); HistoryItem *addToHistory(const MTPMessage &msg);
HistoryItem *addNewForwarded(MsgId id, int32 flags, QDateTime date, int32 from, HistoryMessage *item); HistoryItem *addNewForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *item);
HistoryItem *addNewDocument(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption); HistoryItem *addNewDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption);
HistoryItem *addNewPhoto(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption); HistoryItem *addNewPhoto(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
void addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed); void addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed);
void addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed); void addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed);
@ -309,7 +309,7 @@ public:
MsgId maxMsgId() const; MsgId maxMsgId() const;
MsgId msgIdForRead() const; MsgId msgIdForRead() const;
int32 geomResize(int32 newWidth, int32 *ytransform = 0, const HistoryItem *resizedItem = 0); // return new size int resize(int newWidth, int32 *ytransform = nullptr); // return new size
void removeNotification(HistoryItem *item) { void removeNotification(HistoryItem *item) {
if (!notifies.isEmpty()) { if (!notifies.isEmpty()) {
@ -336,6 +336,15 @@ public:
if (!notifies.isEmpty() && notifies.back() == item) notifies.pop_back(); if (!notifies.isEmpty() && notifies.back() == item) notifies.pop_back();
} }
bool hasPendingResizedItems() const {
return _flags & Flag::f_has_pending_resized_items;
}
void setHasPendingResizedItems();
void setPendingResize() {
_flags |= Flag::f_pending_resize;
setHasPendingResizedItems();
}
void paintDialog(Painter &p, int32 w, bool sel) const; void paintDialog(Painter &p, int32 w, bool sel) const;
bool updateTyping(uint64 ms, bool force = false); bool updateTyping(uint64 ms, bool force = false);
void clearLastKeyboard(); void clearLastKeyboard();
@ -433,6 +442,19 @@ protected:
private: private:
enum Flag {
f_has_pending_resized_items = (1 << 0),
f_pending_resize = (1 << 1),
};
Q_DECLARE_FLAGS(Flags, Flag);
Q_DECL_CONSTEXPR friend inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, Flags::enum_type f2) Q_DECL_NOTHROW {
return QFlags<Flags::enum_type>(f1) | f2;
}
Q_DECL_CONSTEXPR friend inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, QFlags<Flags::enum_type> f2) Q_DECL_NOTHROW {
return f2 | f1;
}
Flags _flags;
ChatListLinksMap _chatListLinks; ChatListLinksMap _chatListLinks;
uint64 _sortKeyInChatList; // like ((unixtime) << 32) | (incremented counter) uint64 _sortKeyInChatList; // like ((unixtime) << 32) | (incremented counter)
@ -822,7 +844,7 @@ public:
} }
void removeItem(HistoryItem *item); void removeItem(HistoryItem *item);
int32 geomResize(int32 newWidth, int32 *ytransform, const HistoryItem *resizedItem); // return new size int resize(int newWidth, int *ytransform, bool force); // return new size
int32 y, height; int32 y, height;
History *history; History *history;
@ -877,8 +899,8 @@ enum InfoDisplayType {
InfoDisplayOverImage, InfoDisplayOverImage,
}; };
inline bool isImportantChannelMessage(MsgId id, int32 flags) { // client-side important msgs always has_views or has_from_id inline bool isImportantChannelMessage(MsgId id, MTPDmessage::Flags flags) { // client-side important msgs always has_views or has_from_id
return (flags & MTPDmessage::flag_out) || (flags & MTPDmessage::flag_mentioned) || (flags & MTPDmessage::flag_post); return (flags & MTPDmessage::Flag::f_out) || (flags & MTPDmessage::Flag::f_mentioned) || (flags & MTPDmessage::Flag::f_post);
} }
enum HistoryItemType { enum HistoryItemType {
@ -942,6 +964,9 @@ struct HistoryMessageDate : public BasicInterface<HistoryMessageDate> {
HistoryMessageDate(Interfaces *); HistoryMessageDate(Interfaces *);
void init(const QDateTime &date); void init(const QDateTime &date);
int height() const;
void paint(Painter &p, int y, int w) const;
QString _text; QString _text;
int _width; int _width;
}; };
@ -952,6 +977,9 @@ struct HistoryMessageUnreadBar : public BasicInterface<HistoryMessageUnreadBar>
HistoryMessageUnreadBar(Interfaces *); HistoryMessageUnreadBar(Interfaces *);
void init(int count); void init(int count);
int height() const;
void paint(Painter &p, int y, int w) const;
QString _text; QString _text;
int _width; int _width;
@ -971,8 +999,16 @@ public:
HistoryItem(const HistoryItem &) = delete; HistoryItem(const HistoryItem &) = delete;
HistoryItem &operator=(const HistoryItem &) = delete; HistoryItem &operator=(const HistoryItem &) = delete;
virtual void initDimensions() = 0; int resize(int width) {
virtual int32 resize(int32 width) = 0; // return new height if (_flags & MTPDmessage_ClientFlag::f_pending_init_dimensions) {
_flags &= ~MTPDmessage_ClientFlag::f_pending_init_dimensions;
initDimensions();
}
if (_flags & MTPDmessage_ClientFlag::f_pending_resize) {
_flags &= ~MTPDmessage_ClientFlag::f_pending_resize;
}
return resizeImpl(width);
}
virtual void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const = 0; virtual void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const = 0;
virtual void dependencyItemRemoved(HistoryItem *dependency) { virtual void dependencyItemRemoved(HistoryItem *dependency) {
@ -1011,14 +1047,18 @@ public:
} }
void attachToBlock(HistoryBlock *block, int index) { void attachToBlock(HistoryBlock *block, int index) {
t_assert(_block == nullptr && _indexInBlock < 0); t_assert(_block == nullptr && _indexInBlock < 0);
_block = block; _block = block;
_indexInBlock = index; _indexInBlock = index;
if (pendingResize()) {
_history->setHasPendingResizedItems();
}
} }
void setIndexInBlock(int index) { void setIndexInBlock(int index) {
_indexInBlock = index; _indexInBlock = index;
} }
bool out() const { bool out() const {
return _flags & MTPDmessage::flag_out; return _flags & MTPDmessage::Flag::f_out;
} }
bool unread() const { bool unread() const {
if (out() && id > 0 && id < _history->outboxReadBefore) return false; if (out() && id > 0 && id < _history->outboxReadBefore) return false;
@ -1028,31 +1068,31 @@ public:
} }
if (history()->peer->isSelf()) return false; // messages from myself are always read if (history()->peer->isSelf()) return false; // messages from myself are always read
if (out() && history()->peer->migrateTo()) return false; // outgoing messages in converted chats are always read if (out() && history()->peer->migrateTo()) return false; // outgoing messages in converted chats are always read
return (_flags & MTPDmessage::flag_unread); return (_flags & MTPDmessage::Flag::f_unread);
} }
bool mentionsMe() const { bool mentionsMe() const {
return _flags & MTPDmessage::flag_mentioned; return _flags & MTPDmessage::Flag::f_mentioned;
} }
bool isMediaUnread() const { bool isMediaUnread() const {
return (_flags & MTPDmessage::flag_media_unread) && (channelId() == NoChannel); return (_flags & MTPDmessage::Flag::f_media_unread) && (channelId() == NoChannel);
} }
void markMediaRead() { void markMediaRead() {
_flags &= ~MTPDmessage::flag_media_unread; _flags &= ~MTPDmessage::Flag::f_media_unread;
} }
bool hasReplyMarkup() const { bool hasReplyMarkup() const {
return _flags & MTPDmessage::flag_reply_markup; return _flags & MTPDmessage::Flag::f_reply_markup;
} }
bool hasTextLinks() const { bool hasTextLinks() const {
return _flags & MTPDmessage_flag_HAS_TEXT_LINKS; return _flags & MTPDmessage_ClientFlag::f_has_text_links;
} }
bool isGroupMigrate() const { bool isGroupMigrate() const {
return _flags & MTPDmessage_flag_IS_GROUP_MIGRATE; return _flags & MTPDmessage_ClientFlag::f_is_group_migrate;
} }
bool hasViews() const { bool hasViews() const {
return _flags & MTPDmessage::flag_views; return _flags & MTPDmessage::Flag::f_views;
} }
bool isPost() const { bool isPost() const {
return _flags & MTPDmessage::flag_post; return _flags & MTPDmessage::Flag::f_post;
} }
bool isImportant() const { bool isImportant() const {
return _history->isChannel() && isImportantChannelMessage(id, _flags); return _history->isChannel() && isImportantChannelMessage(id, _flags);
@ -1061,7 +1101,7 @@ public:
return (id > 0) && (!history()->isChannel() || history()->isMegagroup() || isPost()); return (id > 0) && (!history()->isChannel() || history()->isMegagroup() || isPost());
} }
bool isSilent() const { bool isSilent() const {
return _flags & MTPDmessage::flag_silent; return _flags & MTPDmessage::Flag::f_silent;
} }
virtual int32 viewsCount() const { virtual int32 viewsCount() const {
return hasViews() ? 1 : -1; return hasViews() ? 1 : -1;
@ -1117,7 +1157,7 @@ public:
virtual void drawInfo(Painter &p, int32 right, int32 bottom, int32 width, bool selected, InfoDisplayType type) const { virtual void drawInfo(Painter &p, int32 right, int32 bottom, int32 width, bool selected, InfoDisplayType type) const {
} }
virtual void setViewsCount(int32 count, bool reinit = true) { virtual void setViewsCount(int32 count) {
} }
virtual void setId(MsgId newId); virtual void setId(MsgId newId);
virtual void setDate(const QDateTime &date) { // for date items virtual void setDate(const QDateTime &date) { // for date items
@ -1131,7 +1171,7 @@ public:
bool canDelete() const { bool canDelete() const {
ChannelData *channel = _history->peer->asChannel(); ChannelData *channel = _history->peer->asChannel();
if (!channel) return !(_flags & MTPDmessage_flag_IS_GROUP_MIGRATE); if (!channel) return !(_flags & MTPDmessage_ClientFlag::f_is_group_migrate);
if (id == 1) return false; if (id == 1) return false;
if (channel->amCreator()) return true; if (channel->amCreator()) return true;
@ -1255,24 +1295,44 @@ public:
// when the new messages arrive in this chat history // when the new messages arrive in this chat history
void setUnreadBarFreezed(); void setUnreadBarFreezed();
bool pendingResize() const {
return _flags & MTPDmessage_ClientFlag::f_pending_resize;
}
void setPendingResize() {
_flags |= MTPDmessage_ClientFlag::f_pending_resize;
if (!detached()) {
_history->setHasPendingResizedItems();
}
}
bool pendingInitDimensions() const {
return _flags & MTPDmessage_ClientFlag::f_pending_init_dimensions;
}
void setPendingInitDimensions() {
_flags |= MTPDmessage_ClientFlag::f_pending_init_dimensions;
setPendingResize();
}
void clipCallback(ClipReaderNotification notification); void clipCallback(ClipReaderNotification notification);
virtual ~HistoryItem(); virtual ~HistoryItem();
protected: protected:
HistoryItem(History *history, MsgId msgId, int32 flags, QDateTime msgDate, int32 from); HistoryItem(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime msgDate, int32 from);
// to completely create history item we need to // to completely create history item we need to call
// call a virtual initDimensions() method, // a virtual method, it can not be done from constructor
// that can not be done from constructor virtual void finishCreate();
void finishCreate();
// called from resize() when MTPDmessage_ClientFlag::f_pending_init_dimensions is set
virtual void initDimensions() = 0;
virtual int resizeImpl(int width) = 0;
PeerData *_from; PeerData *_from;
History *_history; History *_history;
HistoryBlock *_block = nullptr; HistoryBlock *_block = nullptr;
int _indexInBlock = -1; int _indexInBlock = -1;
int32 _flags; MTPDmessage::Flags _flags;
mutable int32 _authorNameVersion; mutable int32 _authorNameVersion;
@ -1301,7 +1361,7 @@ protected:
// make all the constructors in HistoryItem children protected // make all the constructors in HistoryItem children protected
// and wrapped with a static create() call with the same args // and wrapped with a static create() call with the same args
// so that history item can not be created directly, without // so that history item can not be created directly, without
// a finishCreate() call, which calls a virtual method initDimensions() // calling a virtual finishCreate() method
template <typename T> template <typename T>
class HistoryItemInstantiated { class HistoryItemInstantiated {
public: public:
@ -1422,7 +1482,10 @@ public:
return 0; return 0;
} }
virtual bool playInline(HistoryItem *item) { bool playInline(HistoryItem *item/*, bool autoplay = false*/) {
return playInline(item, false);
}
virtual bool playInline(HistoryItem *item, bool autoplay) {
return false; return false;
} }
virtual void stopInline(HistoryItem *item) { virtual void stopInline(HistoryItem *item) {
@ -1851,8 +1914,8 @@ public:
return gif(); return gif();
} }
bool playInline(HistoryItem *item); bool playInline(HistoryItem *item, bool autoplay) override;
void stopInline(HistoryItem *item); void stopInline(HistoryItem *item) override;
void attachToItem(HistoryItem *item) override; void attachToItem(HistoryItem *item) override;
void detachFromItem(HistoryItem *item) override; void detachFromItem(HistoryItem *item) override;
@ -1894,10 +1957,10 @@ private:
ClipReader *_gif; ClipReader *_gif;
ClipReader *gif() { ClipReader *gif() {
return (_gif == BadClipReader) ? 0 : _gif; return (_gif == BadClipReader) ? nullptr : _gif;
} }
const ClipReader *gif() const { const ClipReader *gif() const {
return (_gif == BadClipReader) ? 0 : _gif; return (_gif == BadClipReader) ? nullptr : _gif;
} }
void setStatusSize(int32 newSize) const; void setStatusSize(int32 newSize) const;
@ -2057,10 +2120,10 @@ public:
ClipReader *getClipReader() { ClipReader *getClipReader() {
return _attach ? _attach->getClipReader() : 0; return _attach ? _attach->getClipReader() : 0;
} }
bool playInline(HistoryItem *item) { bool playInline(HistoryItem *item, bool autoplay) override {
return _attach ? _attach->playInline(item) : false; return _attach ? _attach->playInline(item, autoplay) : false;
} }
void stopInline(HistoryItem *item) { void stopInline(HistoryItem *item) override {
if (_attach) _attach->stopInline(item); if (_attach) _attach->stopInline(item);
} }
@ -2209,23 +2272,22 @@ public:
static HistoryMessage *create(History *history, const MTPDmessage &msg) { static HistoryMessage *create(History *history, const MTPDmessage &msg) {
return _create(history, msg); return _create(history, msg);
} }
static HistoryMessage *create(History *history, MsgId msgId, int32 flags, QDateTime date, int32 from, HistoryMessage *fwd) { static HistoryMessage *create(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *fwd) {
return _create(history, msgId, flags, date, from, fwd); return _create(history, msgId, flags, date, from, fwd);
} }
static HistoryMessage *create(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities) { static HistoryMessage *create(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities) {
return _create(history, msgId, flags, viaBotId, date, from, msg, entities); return _create(history, msgId, flags, viaBotId, date, from, msg, entities);
} }
static HistoryMessage *create(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) { static HistoryMessage *create(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) {
return _create(history, msgId, flags, viaBotId, date, from, doc, caption); return _create(history, msgId, flags, viaBotId, date, from, doc, caption);
} }
static HistoryMessage *create(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) { static HistoryMessage *create(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) {
return _create(history, msgId, flags, viaBotId, date, from, photo, caption); return _create(history, msgId, flags, viaBotId, date, from, photo, caption);
} }
void initTime(); void initTime();
void initMedia(const MTPMessageMedia *media, QString &currentText); void initMedia(const MTPMessageMedia *media, QString &currentText);
void initMediaFromDocument(DocumentData *doc, const QString &caption); void initMediaFromDocument(DocumentData *doc, const QString &caption);
void initDimensions() override;
void fromNameUpdated(int32 width) const; void fromNameUpdated(int32 width) const;
virtual UserData *viaBot() const { virtual UserData *viaBot() const {
@ -2255,7 +2317,7 @@ public:
} }
void drawInfo(Painter &p, int32 right, int32 bottom, int32 width, bool selected, InfoDisplayType type) const; void drawInfo(Painter &p, int32 right, int32 bottom, int32 width, bool selected, InfoDisplayType type) const;
void setViewsCount(int32 count, bool reinit = true); void setViewsCount(int32 count);
void setId(MsgId newId); void setId(MsgId newId);
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override; void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override;
@ -2263,7 +2325,6 @@ public:
void destroy(); void destroy();
int32 resize(int32 width);
bool hasPoint(int32 x, int32 y) const; bool hasPoint(int32 x, int32 y) const;
bool pointInTime(int32 right, int32 bottom, int32 x, int32 y, InfoDisplayType type) const; bool pointInTime(int32 right, int32 bottom, int32 x, int32 y, InfoDisplayType type) const;
@ -2285,12 +2346,13 @@ public:
QString notificationHeader() const; QString notificationHeader() const;
QString notificationText() const; QString notificationText() const;
void updateMedia(const MTPMessageMedia *media, bool edited = false) { void updateMedia(const MTPMessageMedia *media, bool edited = false) override {
if (!edited && media && _media && _media->type() != MediaTypeWebPage) { if (!edited && media && _media && _media->type() != MediaTypeWebPage) {
_media->updateFrom(*media, this); _media->updateFrom(*media, this);
} else { } else {
setMedia(media); setMedia(media);
} }
setPendingInitDimensions();
} }
int32 addToOverview(AddToOverviewMethod method); int32 addToOverview(AddToOverviewMethod method);
void eraseFromOverview(); void eraseFromOverview();
@ -2348,12 +2410,15 @@ public:
protected: protected:
HistoryMessage(History *history, const MTPDmessage &msg); HistoryMessage(History *history, const MTPDmessage &msg);
HistoryMessage(History *history, MsgId msgId, int32 flags, QDateTime date, int32 from, HistoryMessage *fwd); // local forwarded HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *fwd); // local forwarded
HistoryMessage(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities); // local message HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities); // local message
HistoryMessage(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption); // local document HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption); // local document
HistoryMessage(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption); // local photo HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption); // local photo
friend class HistoryItemInstantiated<HistoryMessage>; friend class HistoryItemInstantiated<HistoryMessage>;
void initDimensions() override;
int resizeImpl(int width) override;
void createInterfaces(int32 viaBotId, int32 viewsCount, const PeerId &authorIdOriginal = 0, const PeerId &fromIdOriginal = 0, MsgId originalId = 0); void createInterfaces(int32 viaBotId, int32 viewsCount, const PeerId &authorIdOriginal = 0, const PeerId &fromIdOriginal = 0, MsgId originalId = 0);
bool displayForwardedFrom() const { bool displayForwardedFrom() const {
@ -2380,15 +2445,13 @@ public:
static HistoryReply *create(History *history, const MTPDmessage &msg) { static HistoryReply *create(History *history, const MTPDmessage &msg) {
return _create(history, msg); return _create(history, msg);
} }
static HistoryReply *create(History *history, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) { static HistoryReply *create(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) {
return _create(history, msgId, flags, viaBotId, replyTo, date, from, doc, caption); return _create(history, msgId, flags, viaBotId, replyTo, date, from, doc, caption);
} }
static HistoryReply *create(History *history, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) { static HistoryReply *create(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) {
return _create(history, msgId, flags, viaBotId, replyTo, date, from, photo, caption); return _create(history, msgId, flags, viaBotId, replyTo, date, from, photo, caption);
} }
void initDimensions() override;
bool updateDependencyItem() override { bool updateDependencyItem() override {
return updateReplyTo(true); return updateReplyTo(true);
} }
@ -2406,7 +2469,6 @@ public:
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override; void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override;
void drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selected, bool likeService = false) const; void drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selected, bool likeService = false) const;
void drawMessageText(Painter &p, QRect trect, uint32 selection) const override; void drawMessageText(Painter &p, QRect trect, uint32 selection) const override;
int32 resize(int32 width) override;
void resizeVia(int32 w) const; void resizeVia(int32 w) const;
bool hasPoint(int32 x, int32 y) const override; bool hasPoint(int32 x, int32 y) const override;
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const override; void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const override;
@ -2430,11 +2492,14 @@ public:
protected: protected:
HistoryReply(History *history, const MTPDmessage &msg); HistoryReply(History *history, const MTPDmessage &msg);
HistoryReply(History *history, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption); HistoryReply(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption);
HistoryReply(History *history, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption); HistoryReply(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
using HistoryItemInstantiated<HistoryReply>::_create; using HistoryItemInstantiated<HistoryReply>::_create;
friend class HistoryItemInstantiated<HistoryReply>; friend class HistoryItemInstantiated<HistoryReply>;
void initDimensions() override;
int resizeImpl(int width) override;
bool updateReplyTo(bool force = false); bool updateReplyTo(bool force = false);
void replyToNameUpdated() const; void replyToNameUpdated() const;
@ -2449,18 +2514,28 @@ protected:
}; };
inline int32 newMessageFlags(PeerData *p) { inline MTPDmessage::Flags newMessageFlags(PeerData *p) {
return p->isSelf() ? 0 : (((p->isChat() || (p->isUser() && !p->asUser()->botInfo)) ? MTPDmessage::flag_unread : 0) | MTPDmessage::flag_out); MTPDmessage::Flags result = 0;
if (!p->isSelf()) {
result |= MTPDmessage::Flag::f_out;
if (p->isChat() || (p->isUser() && !p->asUser()->botInfo)) {
result |= MTPDmessage::Flag::f_unread;
}
}
return result;
} }
inline int32 newForwardedFlags(PeerData *p, int32 from, HistoryMessage *fwd) { inline MTPDmessage::Flags newForwardedFlags(PeerData *p, int32 from, HistoryMessage *fwd) {
int32 result = newMessageFlags(p) | (from ? MTPDmessage::flag_from_id : 0); MTPDmessage::Flags result = newMessageFlags(p);
if (from) {
result |= MTPDmessage::Flag::f_from_id;
}
if (fwd->Is<HistoryMessageVia>()) { if (fwd->Is<HistoryMessageVia>()) {
result |= MTPDmessage::flag_via_bot_id; result |= MTPDmessage::Flag::f_via_bot_id;
} }
if (!p->isChannel()) { if (!p->isChannel()) {
if (HistoryMedia *media = fwd->getMedia()) { if (HistoryMedia *media = fwd->getMedia()) {
if (media->type() == MediaTypeVoiceFile) { if (media->type() == MediaTypeVoiceFile) {
result |= MTPDmessage::flag_media_unread; result |= MTPDmessage::Flag::f_media_unread;
// } else if (media->type() == MediaTypeVideo) { // } else if (media->type() == MediaTypeVideo) {
// result |= MTPDmessage::flag_media_unread; // result |= MTPDmessage::flag_media_unread;
} }
@ -2483,12 +2558,10 @@ public:
static HistoryServiceMsg *create(History *history, const MTPDmessageService &msg) { static HistoryServiceMsg *create(History *history, const MTPDmessageService &msg) {
return _create(history, msg); return _create(history, msg);
} }
static HistoryServiceMsg *create(History *history, MsgId msgId, QDateTime date, const QString &msg, int32 flags = 0, HistoryMedia *media = 0, int32 from = 0) { static HistoryServiceMsg *create(History *history, MsgId msgId, QDateTime date, const QString &msg, MTPDmessage::Flags flags = 0, HistoryMedia *media = 0, int32 from = 0) {
return _create(history, msgId, date, msg, flags, media, from); return _create(history, msgId, date, msg, flags, media, from);
} }
void initDimensions() override;
bool updateDependencyItem() override { bool updateDependencyItem() override {
return updatePinned(true); return updatePinned(true);
} }
@ -2508,7 +2581,6 @@ public:
void countPositionAndSize(int32 &left, int32 &width) const; void countPositionAndSize(int32 &left, int32 &width) const;
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override; void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override;
int32 resize(int32 width) override;
bool hasPoint(int32 x, int32 y) const override; bool hasPoint(int32 x, int32 y) const override;
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const override; void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const override;
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const override; void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const override;
@ -2545,9 +2617,12 @@ public:
protected: protected:
HistoryServiceMsg(History *history, const MTPDmessageService &msg); HistoryServiceMsg(History *history, const MTPDmessageService &msg);
HistoryServiceMsg(History *history, MsgId msgId, QDateTime date, const QString &msg, int32 flags = 0, HistoryMedia *media = 0, int32 from = 0); HistoryServiceMsg(History *history, MsgId msgId, QDateTime date, const QString &msg, MTPDmessage::Flags flags = 0, HistoryMedia *media = 0, int32 from = 0);
friend class HistoryItemInstantiated<HistoryServiceMsg>; friend class HistoryItemInstantiated<HistoryServiceMsg>;
void initDimensions() override;
int resizeImpl(int width) override;
void setMessageByAction(const MTPmessageAction &action); void setMessageByAction(const MTPmessageAction &action);
bool updatePinned(bool force = false); bool updatePinned(bool force = false);
bool updatePinnedText(const QString *pfrom = nullptr, QString *ptext = nullptr); bool updatePinnedText(const QString *pfrom = nullptr, QString *ptext = nullptr);
@ -2652,7 +2727,7 @@ private:
class HistoryJoined : public HistoryServiceMsg, private HistoryItemInstantiated<HistoryJoined> { class HistoryJoined : public HistoryServiceMsg, private HistoryItemInstantiated<HistoryJoined> {
public: public:
static HistoryJoined *create(History *history, const QDateTime &date, UserData *from, int32 flags) { static HistoryJoined *create(History *history, const QDateTime &date, UserData *from, MTPDmessage::Flags flags) {
return _create(history, date, from, flags); return _create(history, date, from, flags);
} }
@ -2662,7 +2737,7 @@ public:
protected: protected:
HistoryJoined(History *history, const QDateTime &date, UserData *from, int32 flags); HistoryJoined(History *history, const QDateTime &date, UserData *from, MTPDmessage::Flags flags);
using HistoryItemInstantiated<HistoryJoined>::_create; using HistoryItemInstantiated<HistoryJoined>::_create;
friend class HistoryItemInstantiated<HistoryJoined>; friend class HistoryItemInstantiated<HistoryJoined>;

View file

@ -1211,7 +1211,7 @@ void HistoryInner::keyPressEvent(QKeyEvent *e) {
} }
} }
int32 HistoryInner::recountHeight(const HistoryItem *resizedItem) { int32 HistoryInner::recountHeight() {
int32 htop = historyTop(), mtop = migratedTop(); int32 htop = historyTop(), mtop = migratedTop();
int32 st1 = (htop >= 0) ? (_history->lastScrollTop - htop) : -1, st2 = (_migrated && mtop >= 0) ? (_history->lastScrollTop - mtop) : -1; int32 st1 = (htop >= 0) ? (_history->lastScrollTop - htop) : -1, st2 = (_migrated && mtop >= 0) ? (_history->lastScrollTop - mtop) : -1;
@ -1222,18 +1222,11 @@ int32 HistoryInner::recountHeight(const HistoryItem *resizedItem) {
} }
if (wasYSkip < minadd) wasYSkip = minadd; if (wasYSkip < minadd) wasYSkip = minadd;
if (resizedItem) { _history->resize(_scroll->width(), &st1);
if (resizedItem->history() == _history) { if (_migrated) {
_history->geomResize(_scroll->width(), &st1, resizedItem); _migrated->resize(_scroll->width(), &st2);
} else if (_migrated && resizedItem->history() == _migrated) {
_migrated->geomResize(_scroll->width(), &st2, resizedItem);
}
} else {
_history->geomResize(_scroll->width(), &st1, resizedItem);
if (_migrated) {
_migrated->geomResize(_scroll->width(), &st2, resizedItem);
}
} }
int32 skip = 0; int32 skip = 0;
if (_migrated) { // check first messages of _history - maybe no need to display them if (_migrated) { // check first messages of _history - maybe no need to display them
if (!_migrated->isEmpty() && !_history->isEmpty() && _migrated->loadedAtBottom() && _history->loadedAtTop()) { if (!_migrated->isEmpty() && !_history->isEmpty() && _migrated->loadedAtBottom() && _history->loadedAtTop()) {
@ -2147,9 +2140,9 @@ bool BotKeyboard::updateMarkup(HistoryItem *to) {
clearSelection(); clearSelection();
_btns.clear(); _btns.clear();
const ReplyMarkup &markup(App::replyMarkup(to->channelId(), to->id)); const ReplyMarkup &markup(App::replyMarkup(to->channelId(), to->id));
_forceReply = markup.flags & MTPDreplyKeyboardMarkup_flag_FORCE_REPLY; _forceReply = markup.flags & MTPDreplyKeyboardMarkup_ClientFlag::f_force_reply;
_maximizeSize = !(markup.flags & MTPDreplyKeyboardMarkup::flag_resize); _maximizeSize = !(markup.flags & MTPDreplyKeyboardMarkup::Flag::f_resize);
_singleUse = _forceReply || (markup.flags & MTPDreplyKeyboardMarkup::flag_single_use); _singleUse = _forceReply || (markup.flags & MTPDreplyKeyboardMarkup::Flag::f_single_use);
const ReplyMarkup::Commands &commands(markup.commands); const ReplyMarkup::Commands &commands(markup.commands);
if (!commands.isEmpty()) { if (!commands.isEmpty()) {
@ -3182,7 +3175,7 @@ void HistoryWidget::onRecordUpdate(quint16 level, qint32 samples) {
} }
void HistoryWidget::updateStickers() { void HistoryWidget::updateStickers() {
if (!cLastStickersUpdate() || getms(true) >= cLastStickersUpdate() + StickersUpdateTimeout) { if (!Global::LastStickersUpdate() || getms(true) >= Global::LastStickersUpdate() + StickersUpdateTimeout) {
if (!_stickersUpdateRequest) { if (!_stickersUpdateRequest) {
_stickersUpdateRequest = MTP::send(MTPmessages_GetAllStickers(MTP_int(Local::countStickersHash(true))), rpcDone(&HistoryWidget::stickersGot), rpcFail(&HistoryWidget::stickersFailed)); _stickersUpdateRequest = MTP::send(MTPmessages_GetAllStickers(MTP_int(Local::countStickersHash(true))), rpcDone(&HistoryWidget::stickersGot), rpcFail(&HistoryWidget::stickersFailed));
} }
@ -3240,10 +3233,6 @@ void HistoryWidget::notify_clipStopperHidden(ClipStopperType type) {
if (_list) _list->update(); if (_list) _list->update();
} }
void HistoryWidget::notify_historyItemResized(const HistoryItem *row, bool scrollToIt) {
updateListSize(false, false, { ScrollChangeNone, 0 }, row, scrollToIt);
}
void HistoryWidget::cmd_search() { void HistoryWidget::cmd_search() {
if (!inFocusChain() || !_peer) return; if (!inFocusChain() || !_peer) return;
@ -3265,7 +3254,7 @@ void HistoryWidget::cmd_previous_chat() {
} }
void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) { void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
cSetLastStickersUpdate(getms(true)); Global::SetLastStickersUpdate(getms(true));
_stickersUpdateRequest = 0; _stickersUpdateRequest = 0;
if (stickers.type() != mtpc_messages_allStickers) return; if (stickers.type() != mtpc_messages_allStickers) return;
@ -3273,21 +3262,21 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
const QVector<MTPStickerSet> &d_sets(d.vsets.c_vector().v); const QVector<MTPStickerSet> &d_sets(d.vsets.c_vector().v);
StickerSetsOrder &setsOrder(cRefStickerSetsOrder()); Stickers::Order &setsOrder(Global::RefStickerSetsOrder());
setsOrder.clear(); setsOrder.clear();
StickerSets &sets(cRefStickerSets()); Stickers::Sets &sets(Global::RefStickerSets());
QMap<uint64, uint64> setsToRequest; QMap<uint64, uint64> setsToRequest;
for (StickerSets::iterator i = sets.begin(), e = sets.end(); i != e; ++i) { for (auto i = sets.begin(), e = sets.end(); i != e; ++i) {
i->access = 0; // mark for removing i->access = 0; // mark for removing
} }
for (int32 i = 0, l = d_sets.size(); i != l; ++i) { for (int i = 0, l = d_sets.size(); i != l; ++i) {
if (d_sets.at(i).type() == mtpc_stickerSet) { if (d_sets.at(i).type() == mtpc_stickerSet) {
const MTPDstickerSet &set(d_sets.at(i).c_stickerSet()); const MTPDstickerSet &set(d_sets.at(i).c_stickerSet());
StickerSets::iterator it = sets.find(set.vid.v); auto it = sets.find(set.vid.v);
QString title = stickerSetTitle(set); QString title = stickerSetTitle(set);
if (it == sets.cend()) { if (it == sets.cend()) {
it = sets.insert(set.vid.v, StickerSet(set.vid.v, set.vaccess_hash.v, title, qs(set.vshort_name), set.vcount.v, set.vhash.v, set.vflags.v | MTPDstickerSet_flag_NOT_LOADED)); it = sets.insert(set.vid.v, Stickers::Set(set.vid.v, set.vaccess_hash.v, title, qs(set.vshort_name), set.vcount.v, set.vhash.v, set.vflags.v | MTPDstickerSet_ClientFlag::f_not_loaded));
} else { } else {
it->access = set.vaccess_hash.v; it->access = set.vaccess_hash.v;
it->title = title; it->title = title;
@ -3296,12 +3285,12 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
if (it->count != set.vcount.v || it->hash != set.vhash.v || it->emoji.isEmpty()) { if (it->count != set.vcount.v || it->hash != set.vhash.v || it->emoji.isEmpty()) {
it->count = set.vcount.v; it->count = set.vcount.v;
it->hash = set.vhash.v; it->hash = set.vhash.v;
it->flags |= MTPDstickerSet_flag_NOT_LOADED; // need to request this set it->flags |= MTPDstickerSet_ClientFlag::f_not_loaded; // need to request this set
} }
} }
if (!(it->flags & MTPDstickerSet::flag_disabled) || (it->flags & MTPDstickerSet::flag_official)) { if (!(it->flags & MTPDstickerSet::Flag::f_disabled) || (it->flags & MTPDstickerSet::Flag::f_official)) {
setsOrder.push_back(set.vid.v); setsOrder.push_back(set.vid.v);
if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_flag_NOT_LOADED)) { if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) {
setsToRequest.insert(set.vid.v, set.vaccess_hash.v); setsToRequest.insert(set.vid.v, set.vaccess_hash.v);
} }
} }
@ -3309,8 +3298,8 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
} }
bool writeRecent = false; bool writeRecent = false;
RecentStickerPack &recent(cGetRecentStickers()); RecentStickerPack &recent(cGetRecentStickers());
for (StickerSets::iterator it = sets.begin(), e = sets.end(); it != e;) { for (Stickers::Sets::iterator it = sets.begin(), e = sets.end(); it != e;) {
if (it->id == CustomStickerSetId || it->access != 0) { if (it->id == Stickers::CustomSetId || it->access != 0) {
++it; ++it;
} else { } else {
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) { for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
@ -3347,7 +3336,7 @@ bool HistoryWidget::stickersFailed(const RPCError &error) {
LOG(("App Fail: Failed to get stickers!")); LOG(("App Fail: Failed to get stickers!"));
cSetLastStickersUpdate(getms(true)); Global::SetLastStickersUpdate(getms(true));
_stickersUpdateRequest = 0; _stickersUpdateRequest = 0;
return true; return true;
} }
@ -3770,7 +3759,7 @@ void HistoryWidget::updateNotifySettings() {
_muteUnmute.setText(lang(_history->mute ? lng_channel_unmute : lng_channel_mute)); _muteUnmute.setText(lang(_history->mute ? lng_channel_unmute : lng_channel_mute));
if (_peer->notify != UnknownNotifySettings) { if (_peer->notify != UnknownNotifySettings) {
_silent.setChecked(_peer->notify != EmptyNotifySettings && (_peer->notify->flags & MTPDpeerNotifySettings::flag_silent)); _silent.setChecked(_peer->notify != EmptyNotifySettings && (_peer->notify->flags & MTPDpeerNotifySettings::Flag::f_silent));
if (_silent.isHidden() && hasSilentToggle()) { if (_silent.isHidden() && hasSilentToggle()) {
updateControlsVisibility(); updateControlsVisibility();
} }
@ -4610,15 +4599,15 @@ void HistoryWidget::saveEditMsg() {
return; return;
} }
int32 sendFlags = 0; MTPchannels_EditMessage::Flags sendFlags = 0;
if (webPageId == CancelledWebPageId) { if (webPageId == CancelledWebPageId) {
sendFlags |= MTPmessages_SendMessage::flag_no_webpage; sendFlags |= MTPchannels_EditMessage::Flag::f_no_webpage;
} }
MTPVector<MTPMessageEntity> localEntities = linksToMTP(sendingEntities), sentEntities = linksToMTP(sendingEntities, true); MTPVector<MTPMessageEntity> localEntities = linksToMTP(sendingEntities), sentEntities = linksToMTP(sendingEntities, true);
if (!sentEntities.c_vector().v.isEmpty()) { if (!sentEntities.c_vector().v.isEmpty()) {
sendFlags |= MTPmessages_SendMessage::flag_entities; sendFlags |= MTPchannels_EditMessage::Flag::f_entities;
} }
_saveEditMsgRequestId = MTP::send(MTPchannels_EditMessage(MTP_int(sendFlags), _history->peer->asChannel()->inputChannel, MTP_int(_editMsgId), MTP_string(sendingText), sentEntities), rpcDone(&HistoryWidget::saveEditMsgDone, _history), rpcFail(&HistoryWidget::saveEditMsgFail, _history)); _saveEditMsgRequestId = MTP::send(MTPchannels_EditMessage(MTP_flags(sendFlags), _history->peer->asChannel()->inputChannel, MTP_int(_editMsgId), MTP_string(sendingText), sentEntities), rpcDone(&HistoryWidget::saveEditMsgDone, _history), rpcFail(&HistoryWidget::saveEditMsgFail, _history));
} }
void HistoryWidget::saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req) { void HistoryWidget::saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req) {
@ -4798,32 +4787,32 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
fastShowAtEnd(h); fastShowAtEnd(h);
PeerData *p = App::peer(peer); PeerData *p = App::peer(peer);
int32 flags = newMessageFlags(p) | MTPDmessage::flag_media; // unread, out MTPDmessage::Flags flags = newMessageFlags(p) | MTPDmessage::Flag::f_media; // unread, out
bool lastKeyboardUsed = lastForceReplyReplied(FullMsgId(peerToChannel(peer), replyTo)); bool lastKeyboardUsed = lastForceReplyReplied(FullMsgId(peerToChannel(peer), replyTo));
int32 sendFlags = 0; MTPmessages_SendMedia::Flags sendFlags = 0;
if (replyTo) { if (replyTo) {
flags |= MTPDmessage::flag_reply_to_msg_id; flags |= MTPDmessage::Flag::f_reply_to_msg_id;
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
} }
bool channelPost = p->isChannel() && !p->isMegagroup() && p->asChannel()->canPublish() && (p->asChannel()->isBroadcast() || _broadcast.checked()); bool channelPost = p->isChannel() && !p->isMegagroup() && p->asChannel()->canPublish() && (p->asChannel()->isBroadcast() || _broadcast.checked());
bool showFromName = !channelPost || p->asChannel()->addsSignature(); bool showFromName = !channelPost || p->asChannel()->addsSignature();
bool silentPost = channelPost && _silent.checked(); bool silentPost = channelPost && _silent.checked();
if (channelPost) { if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast; sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
flags |= MTPDmessage::flag_views; flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::flag_post; flags |= MTPDmessage::Flag::f_post;
} }
if (showFromName) { if (showFromName) {
flags |= MTPDmessage::flag_from_id; flags |= MTPDmessage::Flag::f_from_id;
} }
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_SendMedia::flag_silent; sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
} }
h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(peer), MTPnullFwdHeader, 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, MTP_int(1), MTPint()), NewMessageUnread); h->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(peer), MTPnullFwdHeader, 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, MTP_int(1), MTPint()), NewMessageUnread);
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), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, h->sendRequestId); h->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(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), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, h->sendRequestId);
App::historyRegRandom(randomId, newId); App::historyRegRandom(randomId, newId);
@ -5822,30 +5811,30 @@ void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShif
fastShowAtEnd(h); fastShowAtEnd(h);
int32 flags = newMessageFlags(h->peer) | MTPDmessage::flag_media; // unread, out MTPDmessage::Flags flags = newMessageFlags(h->peer) | MTPDmessage::Flag::f_media; // unread, out
if (file->to.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id; if (file->to.replyTo) flags |= MTPDmessage::Flag::f_reply_to_msg_id;
bool channelPost = h->peer->isChannel() && !h->peer->isMegagroup() && h->peer->asChannel()->canPublish() && (h->peer->asChannel()->isBroadcast() || file->to.broadcast); bool channelPost = h->peer->isChannel() && !h->peer->isMegagroup() && h->peer->asChannel()->canPublish() && (h->peer->asChannel()->isBroadcast() || file->to.broadcast);
bool showFromName = !channelPost || h->peer->asChannel()->addsSignature(); bool showFromName = !channelPost || h->peer->asChannel()->addsSignature();
bool silentPost = channelPost && file->to.silent; bool silentPost = channelPost && file->to.silent;
if (channelPost) { if (channelPost) {
flags |= MTPDmessage::flag_views; flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::flag_post; flags |= MTPDmessage::Flag::f_post;
} }
if (showFromName) { if (showFromName) {
flags |= MTPDmessage::flag_from_id; flags |= MTPDmessage::Flag::f_from_id;
} }
if (silentPost) { if (silentPost) {
flags |= MTPDmessage::flag_silent; flags |= MTPDmessage::Flag::f_silent;
} }
if (file->type == PreparePhoto) { if (file->type == PreparePhoto) {
h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(file->to.peer), MTPnullFwdHeader, MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(file->photo, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread); h->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(file->to.peer), MTPnullFwdHeader, MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(file->photo, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread);
} else if (file->type == PrepareDocument) { } else if (file->type == PrepareDocument) {
h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(file->to.peer), MTPnullFwdHeader, MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(file->document, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread); h->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(file->to.peer), MTPnullFwdHeader, MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(file->document, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread);
} else if (file->type == PrepareAudio) { } else if (file->type == PrepareAudio) {
if (!h->peer->isChannel()) { if (!h->peer->isChannel()) {
flags |= MTPDmessage::flag_media_unread; flags |= MTPDmessage::Flag::f_media_unread;
} }
h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(file->to.peer), MTPnullFwdHeader, MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(file->document, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread); h->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(file->to.peer), MTPnullFwdHeader, MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(file->document, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread);
} }
if (_peer && file->to.peer == _peer->id) { if (_peer && file->to.peer == _peer->id) {
@ -5891,21 +5880,21 @@ void HistoryWidget::onPhotoUploaded(const FullMsgId &newId, bool silent, const M
App::historyRegRandom(randomId, newId); App::historyRegRandom(randomId, newId);
History *hist = item->history(); History *hist = item->history();
MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0; MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
int32 sendFlags = 0; MTPmessages_SendMedia::Flags sendFlags = 0;
if (replyTo) { if (replyTo) {
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
} }
bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost(); bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost();
bool silentPost = channelPost && silent; bool silentPost = channelPost && silent;
if (channelPost) { if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast; sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
} }
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_SendMedia::flag_silent; sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
} }
QString caption = item->getMedia() ? item->getMedia()->getCaption() : QString(); QString caption = item->getMedia() ? item->getMedia()->getCaption() : QString();
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedPhoto(file, MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId); hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedPhoto(file, MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId);
} }
} }
@ -5925,9 +5914,9 @@ namespace {
} else if (document->type == StickerDocument && document->sticker()) { } else if (document->type == StickerDocument && document->sticker()) {
attributes.push_back(MTP_documentAttributeSticker(MTP_string(document->sticker()->alt), document->sticker()->set)); attributes.push_back(MTP_documentAttributeSticker(MTP_string(document->sticker()->alt), document->sticker()->set));
} else if (document->type == SongDocument && document->song()) { } else if (document->type == SongDocument && document->song()) {
attributes.push_back(MTP_documentAttributeAudio(MTP_int(MTPDdocumentAttributeAudio::flag_title | MTPDdocumentAttributeAudio::flag_performer), MTP_int(document->song()->duration), MTP_string(document->song()->title), MTP_string(document->song()->performer), MTPstring())); attributes.push_back(MTP_documentAttributeAudio(MTP_flags(MTPDdocumentAttributeAudio::Flag::f_title | MTPDdocumentAttributeAudio::Flag::f_performer), MTP_int(document->song()->duration), MTP_string(document->song()->title), MTP_string(document->song()->performer), MTPstring()));
} else if (document->type == VoiceDocument && document->voice()) { } else if (document->type == VoiceDocument && document->voice()) {
attributes.push_back(MTP_documentAttributeAudio(MTP_int(MTPDdocumentAttributeAudio::flag_voice | MTPDdocumentAttributeAudio::flag_waveform), MTP_int(document->voice()->duration), MTPstring(), MTPstring(), MTP_string(documentWaveformEncode5bit(document->voice()->waveform)))); attributes.push_back(MTP_documentAttributeAudio(MTP_flags(MTPDdocumentAttributeAudio::Flag::f_voice | MTPDdocumentAttributeAudio::Flag::f_waveform), MTP_int(document->voice()->duration), MTPstring(), MTPstring(), MTP_string(documentWaveformEncode5bit(document->voice()->waveform))));
} }
return MTP_vector<MTPDocumentAttribute>(attributes); return MTP_vector<MTPDocumentAttribute>(attributes);
} }
@ -5943,21 +5932,21 @@ void HistoryWidget::onDocumentUploaded(const FullMsgId &newId, bool silent, cons
App::historyRegRandom(randomId, newId); App::historyRegRandom(randomId, newId);
History *hist = item->history(); History *hist = item->history();
MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0; MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
int32 sendFlags = 0; MTPmessages_SendMedia::Flags sendFlags = 0;
if (replyTo) { if (replyTo) {
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
} }
bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost(); bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost();
bool silentPost = channelPost && silent; bool silentPost = channelPost && silent;
if (channelPost) { if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast; sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
} }
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_SendMedia::flag_silent; sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
} }
QString caption = item->getMedia() ? item->getMedia()->getCaption() : QString(); QString caption = item->getMedia() ? item->getMedia()->getCaption() : QString();
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedDocument(file, MTP_string(document->mime), _composeDocumentAttributes(document), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId); hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedDocument(file, MTP_string(document->mime), _composeDocumentAttributes(document), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId);
} }
} }
} }
@ -5972,21 +5961,21 @@ void HistoryWidget::onThumbDocumentUploaded(const FullMsgId &newId, bool silent,
App::historyRegRandom(randomId, newId); App::historyRegRandom(randomId, newId);
History *hist = item->history(); History *hist = item->history();
MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0; MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
int32 sendFlags = 0; MTPmessages_SendMedia::Flags sendFlags = 0;
if (replyTo) { if (replyTo) {
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
} }
bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost(); bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost();
bool silentPost = channelPost && silent; bool silentPost = channelPost && silent;
if (channelPost) { if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast; sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
} }
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_SendMedia::flag_silent; sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
} }
QString caption = item->getMedia() ? item->getMedia()->getCaption() : QString(); QString caption = item->getMedia() ? item->getMedia()->getCaption() : QString();
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedThumbDocument(file, thumb, MTP_string(document->mime), _composeDocumentAttributes(document), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId); hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedThumbDocument(file, thumb, MTP_string(document->mime), _composeDocumentAttributes(document), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId);
} }
} }
} }
@ -6178,6 +6167,13 @@ void HistoryWidget::notify_automaticLoadSettingsChangedGif() {
_emojiPan.notify_automaticLoadSettingsChangedGif(); _emojiPan.notify_automaticLoadSettingsChangedGif();
} }
void HistoryWidget::notify_handlePendingHistoryUpdate() {
if (_history && _history->hasPendingResizedItems()) {
updateListSize();
_list->update();
}
}
void HistoryWidget::resizeEvent(QResizeEvent *e) { void HistoryWidget::resizeEvent(QResizeEvent *e) {
_reportSpamPanel.resize(width(), _reportSpamPanel.height()); _reportSpamPanel.resize(width(), _reportSpamPanel.height());
@ -6295,10 +6291,9 @@ MsgId HistoryWidget::replyToId() const {
return _replyToId ? _replyToId : (_kbReplyTo ? _kbReplyTo->id : 0); return _replyToId ? _replyToId : (_kbReplyTo ? _kbReplyTo->id : 0);
} }
void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollChange &change, const HistoryItem *resizedItem, bool scrollToIt) { void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollChange &change) {
if (!_history || (initial && _histInited) || (!initial && !_histInited)) return; if (!_history || (initial && _histInited) || (!initial && !_histInited)) return;
if (_firstLoadRequest) { if (_firstLoadRequest) {
if (resizedItem) _list->recountHeight(resizedItem);
return; // scrollTopMax etc are not working after recountHeight() return; // scrollTopMax etc are not working after recountHeight()
} }
@ -6330,25 +6325,13 @@ void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollCh
if (!initial) { if (!initial) {
_history->lastScrollTop = _scroll.scrollTop(); _history->lastScrollTop = _scroll.scrollTop();
} }
int32 newSt = _list->recountHeight(resizedItem); int32 newSt = _list->recountHeight();
bool washidden = _scroll.isHidden(); bool washidden = _scroll.isHidden();
if (washidden) { if (washidden) {
_scroll.show(); _scroll.show();
} }
_list->updateSize(); _list->updateSize();
int32 historyTop = _list->historyTop(), migratedTop = _list->migratedTop(); int32 historyTop = _list->historyTop(), migratedTop = _list->migratedTop();
if (resizedItem && !resizedItem->detached() && scrollToIt) {
int32 resizedTop = _list->itemTop(resizedItem);
if (resizedTop >= 0) {
if (newSt + _scroll.height() < resizedTop + resizedItem->height()) {
newSt = resizedTop + resizedItem->height() - _scroll.height();
}
if (newSt > resizedTop) {
newSt = resizedTop;
}
wasAtBottom = false;
}
}
if (washidden) { if (washidden) {
_scroll.hide(); _scroll.hide();
} }
@ -6692,28 +6675,28 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
bool lastKeyboardUsed = lastForceReplyReplied(); bool lastKeyboardUsed = lastForceReplyReplied();
bool out = !_peer->isSelf(), unread = !_peer->isSelf(); bool out = !_peer->isSelf(), unread = !_peer->isSelf();
int32 flags = newMessageFlags(_peer) | MTPDmessage::flag_media; // unread, out MTPDmessage::Flags flags = newMessageFlags(_peer) | MTPDmessage::Flag::f_media; // unread, out
int32 sendFlags = 0; MTPmessages_SendInlineBotResult::Flags sendFlags = 0;
if (replyToId()) { if (replyToId()) {
flags |= MTPDmessage::flag_reply_to_msg_id; flags |= MTPDmessage::Flag::f_reply_to_msg_id;
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_reply_to_msg_id;
} }
bool channelPost = _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && (_peer->asChannel()->isBroadcast() || _broadcast.checked()); bool channelPost = _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && (_peer->asChannel()->isBroadcast() || _broadcast.checked());
bool showFromName = !channelPost || _peer->asChannel()->addsSignature(); bool showFromName = !channelPost || _peer->asChannel()->addsSignature();
bool silentPost = channelPost && _silent.checked(); bool silentPost = channelPost && _silent.checked();
if (channelPost) { if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast; sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_broadcast;
flags |= MTPDmessage::flag_views; flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::flag_post; flags |= MTPDmessage::Flag::f_post;
} }
if (showFromName) { if (showFromName) {
flags |= MTPDmessage::flag_from_id; flags |= MTPDmessage::Flag::f_from_id;
} }
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_SendMedia::flag_silent; sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_silent;
} }
if (bot) { if (bot) {
flags |= MTPDmessage::flag_via_bot_id; flags |= MTPDmessage::Flag::f_via_bot_id;
} }
if (result->message.isEmpty()) { if (result->message.isEmpty()) {
@ -6750,7 +6733,7 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
App::feedDocument(document, thumb); App::feedDocument(document, thumb);
} }
Local::writeStickerImage(mediaKey(DocumentFileLocation, MTP::maindc(), docId), result->data()); Local::writeStickerImage(mediaKey(DocumentFileLocation, MTP::maindc(), docId), result->data());
_history->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(_history->peer->id), MTPnullFwdHeader, MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(document, MTP_string(result->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread); _history->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(_history->peer->id), MTPnullFwdHeader, MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(document, MTP_string(result->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread);
} else if (result->type == qstr("photo")) { } else if (result->type == qstr("photo")) {
QImage fileThumb(result->thumb->pix().toImage()); QImage fileThumb(result->thumb->pix().toImage());
@ -6769,16 +6752,13 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
PhotoData *ph = App::photoSet(photoId, 0, 0, unixtime(), thumbPtr, ImagePtr(medium.width(), medium.height()), ImagePtr(result->width, result->height)); PhotoData *ph = App::photoSet(photoId, 0, 0, unixtime(), thumbPtr, ImagePtr(medium.width(), medium.height()), ImagePtr(result->width, result->height));
MTPPhoto photo = MTP_photo(MTP_long(photoId), MTP_long(0), MTP_int(ph->date), MTP_vector<MTPPhotoSize>(photoSizes)); MTPPhoto photo = MTP_photo(MTP_long(photoId), MTP_long(0), MTP_int(ph->date), MTP_vector<MTPPhotoSize>(photoSizes));
_history->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(_history->peer->id), MTPnullFwdHeader, MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(photo, MTP_string(result->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread); _history->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(_history->peer->id), MTPnullFwdHeader, MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(photo, MTP_string(result->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread);
} }
} else { } else {
flags |= MTPDmessage::flag_entities; flags |= MTPDmessage::Flag::f_entities;
if (result->noWebPage) { _history->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(_history->peer->id), MTPnullFwdHeader, MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(result->message), MTP_messageMediaEmpty(), MTPnullMarkup, linksToMTP(result->entities), MTP_int(1), MTPint()), NewMessageUnread);
sendFlags |= MTPmessages_SendMessage::flag_no_webpage;
}
_history->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(_history->peer->id), MTPnullFwdHeader, MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(result->message), MTP_messageMediaEmpty(), MTPnullMarkup, linksToMTP(result->entities), MTP_int(1), MTPint()), NewMessageUnread);
} }
_history->sendRequestId = MTP::send(MTPmessages_SendInlineBotResult(MTP_int(sendFlags), _peer->input, MTP_int(replyToId()), MTP_long(randomId), MTP_long(result->queryId), MTP_string(result->id)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId); _history->sendRequestId = MTP::send(MTPmessages_SendInlineBotResult(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_long(randomId), MTP_long(result->queryId), MTP_string(result->id)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked()); App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked());
cancelReply(lastKeyboardUsed); cancelReply(lastKeyboardUsed);
@ -6916,29 +6896,29 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti
bool lastKeyboardUsed = lastForceReplyReplied(); bool lastKeyboardUsed = lastForceReplyReplied();
bool out = !_peer->isSelf(), unread = !_peer->isSelf(); bool out = !_peer->isSelf(), unread = !_peer->isSelf();
int32 flags = newMessageFlags(_peer) | MTPDmessage::flag_media; // unread, out MTPDmessage::Flags flags = newMessageFlags(_peer) | MTPDmessage::Flag::f_media; // unread, out
int32 sendFlags = 0; MTPmessages_SendMedia::Flags sendFlags = 0;
if (replyToId()) { if (replyToId()) {
flags |= MTPDmessage::flag_reply_to_msg_id; flags |= MTPDmessage::Flag::f_reply_to_msg_id;
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
} }
bool channelPost = _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && (_peer->asChannel()->isBroadcast() || _broadcast.checked()); bool channelPost = _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && (_peer->asChannel()->isBroadcast() || _broadcast.checked());
bool showFromName = !channelPost || _peer->asChannel()->addsSignature(); bool showFromName = !channelPost || _peer->asChannel()->addsSignature();
bool silentPost = channelPost && _silent.checked(); bool silentPost = channelPost && _silent.checked();
if (channelPost) { if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast; sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
flags |= MTPDmessage::flag_views; flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::flag_post; flags |= MTPDmessage::Flag::f_post;
} }
if (showFromName) { if (showFromName) {
flags |= MTPDmessage::flag_from_id; flags |= MTPDmessage::Flag::f_from_id;
} }
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_SendMedia::flag_silent; sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
} }
_history->addNewDocument(newId.msg, flags, 0, replyToId(), date(MTP_int(unixtime())), showFromName ? MTP::authedId() : 0, doc, caption); _history->addNewDocument(newId.msg, flags, 0, replyToId(), date(MTP_int(unixtime())), showFromName ? MTP::authedId() : 0, doc, caption);
_history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaDocument(MTP_inputDocument(MTP_long(doc->id), MTP_long(doc->access)), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId); _history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaDocument(MTP_inputDocument(MTP_long(doc->id), MTP_long(doc->access)), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked()); App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked());
cancelReply(lastKeyboardUsed); cancelReply(lastKeyboardUsed);
@ -6972,29 +6952,29 @@ void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption)
bool lastKeyboardUsed = lastForceReplyReplied(); bool lastKeyboardUsed = lastForceReplyReplied();
bool out = !_peer->isSelf(), unread = !_peer->isSelf(); bool out = !_peer->isSelf(), unread = !_peer->isSelf();
int32 flags = newMessageFlags(_peer) | MTPDmessage::flag_media; // unread, out MTPDmessage::Flags flags = newMessageFlags(_peer) | MTPDmessage::Flag::f_media; // unread, out
int32 sendFlags = 0; MTPmessages_SendMedia::Flags sendFlags = 0;
if (replyToId()) { if (replyToId()) {
flags |= MTPDmessage::flag_reply_to_msg_id; flags |= MTPDmessage::Flag::f_reply_to_msg_id;
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id; sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
} }
bool channelPost = _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && (_peer->asChannel()->isBroadcast() || _broadcast.checked()); bool channelPost = _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && (_peer->asChannel()->isBroadcast() || _broadcast.checked());
bool showFromName = !channelPost || _peer->asChannel()->addsSignature(); bool showFromName = !channelPost || _peer->asChannel()->addsSignature();
bool silentPost = channelPost && _silent.checked(); bool silentPost = channelPost && _silent.checked();
if (channelPost) { if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast; sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
flags |= MTPDmessage::flag_views; flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::flag_post; flags |= MTPDmessage::Flag::f_post;
} }
if (showFromName) { if (showFromName) {
flags |= MTPDmessage::flag_from_id; flags |= MTPDmessage::Flag::f_from_id;
} }
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_SendMedia::flag_silent; sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
} }
_history->addNewPhoto(newId.msg, flags, 0, replyToId(), date(MTP_int(unixtime())), showFromName ? MTP::authedId() : 0, photo, caption); _history->addNewPhoto(newId.msg, flags, 0, replyToId(), date(MTP_int(unixtime())), showFromName ? MTP::authedId() : 0, photo, caption);
_history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaPhoto(MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId); _history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaPhoto(MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked()); App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked());
cancelReply(lastKeyboardUsed); cancelReply(lastKeyboardUsed);
@ -7145,7 +7125,8 @@ void HistoryWidget::onUnpinMessageSure() {
} }
Ui::hideLayer(); Ui::hideLayer();
MTP::send(MTPchannels_UpdatePinnedMessage(MTP_int(0), _peer->asChannel()->inputChannel, MTP_int(0)), rpcDone(&HistoryWidget::unpinDone)); MTPchannels_UpdatePinnedMessage::Flags flags = 0;
MTP::send(MTPchannels_UpdatePinnedMessage(MTP_flags(flags), _peer->asChannel()->inputChannel, MTP_int(0)), rpcDone(&HistoryWidget::unpinDone));
} }
void HistoryWidget::unpinDone(const MTPUpdates &updates) { void HistoryWidget::unpinDone(const MTPUpdates &updates) {
@ -7535,7 +7516,6 @@ void HistoryWidget::onDeleteSelectedSure() {
for (SelectedItemSet::const_iterator i = sel.cbegin(), e = sel.cend(); i != e; ++i) { for (SelectedItemSet::const_iterator i = sel.cbegin(), e = sel.cend(); i != e; ++i) {
i.value()->destroy(); i.value()->destroy();
} }
Notify::historyItemsResized();
Ui::hideLayer(); Ui::hideLayer();
for (QMap<PeerData*, QVector<MTPint> >::const_iterator i = ids.cbegin(), e = ids.cend(); i != e; ++i) { for (QMap<PeerData*, QVector<MTPint> >::const_iterator i = ids.cbegin(), e = ids.cend(); i != e; ++i) {
@ -7557,7 +7537,6 @@ void HistoryWidget::onDeleteContextSure() {
App::main()->checkPeerHistory(h->peer); App::main()->checkPeerHistory(h->peer);
} }
Notify::historyItemsResized();
Ui::hideLayer(); Ui::hideLayer();
if (wasOnServer) { if (wasOnServer) {

View file

@ -66,7 +66,7 @@ public:
void touchScrollUpdated(const QPoint &screenPos); void touchScrollUpdated(const QPoint &screenPos);
QPoint mapMouseToItem(QPoint p, HistoryItem *item); QPoint mapMouseToItem(QPoint p, HistoryItem *item);
int32 recountHeight(const HistoryItem *resizedItem); int32 recountHeight();
void updateSize(); void updateSize();
void repaintItem(const HistoryItem *item); void repaintItem(const HistoryItem *item);
@ -589,13 +589,13 @@ public:
bool ui_isInlineItemBeingChosen(); bool ui_isInlineItemBeingChosen();
void notify_historyItemLayoutChanged(const HistoryItem *item); void notify_historyItemLayoutChanged(const HistoryItem *item);
void notify_automaticLoadSettingsChangedGif();
void notify_botCommandsChanged(UserData *user); void notify_botCommandsChanged(UserData *user);
void notify_inlineBotRequesting(bool requesting); void notify_inlineBotRequesting(bool requesting);
void notify_userIsBotChanged(UserData *user); void notify_userIsBotChanged(UserData *user);
void notify_migrateUpdated(PeerData *peer); void notify_migrateUpdated(PeerData *peer);
void notify_clipStopperHidden(ClipStopperType type); void notify_clipStopperHidden(ClipStopperType type);
void notify_historyItemResized(const HistoryItem *item, bool scrollToIt); void notify_automaticLoadSettingsChangedGif();
void notify_handlePendingHistoryUpdate();
void cmd_search(); void cmd_search();
void cmd_next_chat(); void cmd_next_chat();
@ -798,7 +798,7 @@ private:
ScrollChangeType type; ScrollChangeType type;
int value; int value;
}; };
void updateListSize(bool initial = false, bool loadedDown = false, const ScrollChange &change = { ScrollChangeNone, 0 }, const HistoryItem *resizedItem = 0, bool scrollToIt = false); void updateListSize(bool initial = false, bool loadedDown = false, const ScrollChange &change = { ScrollChangeNone, 0 });
void saveGifDone(DocumentData *doc, const MTPBool &result); void saveGifDone(DocumentData *doc, const MTPBool &result);

View file

@ -230,8 +230,8 @@ void IntroPhone::phoneCheckDone(const MTPauth_CheckedPhone &result) {
checkRequest.start(1000); checkRequest.start(1000);
int32 flags = 0; MTPauth_SendCode::Flags flags = 0;
sentRequest = MTP::send(MTPauth_SendCode(MTP_int(flags), MTP_string(sentPhone), MTPBool(), MTP_int(ApiId), MTP_string(ApiHash), MTP_string(Sandbox::LangSystemISO())), rpcDone(&IntroPhone::phoneSubmitDone), rpcFail(&IntroPhone::phoneSubmitFail)); sentRequest = MTP::send(MTPauth_SendCode(MTP_flags(flags), MTP_string(sentPhone), MTPBool(), MTP_int(ApiId), MTP_string(ApiHash), MTP_string(Sandbox::LangSystemISO())), rpcDone(&IntroPhone::phoneSubmitDone), rpcFail(&IntroPhone::phoneSubmitFail));
} else { } else {
showError(lang(lng_bad_phone_noreg), true); showError(lang(lng_bad_phone_noreg), true);
enableAll(true); enableAll(true);
@ -271,8 +271,8 @@ void IntroPhone::toSignUp() {
checkRequest.start(1000); checkRequest.start(1000);
int32 flags = 0; MTPauth_SendCode::Flags flags = 0;
sentRequest = MTP::send(MTPauth_SendCode(MTP_int(flags), MTP_string(sentPhone), MTPBool(), MTP_int(ApiId), MTP_string(ApiHash), MTP_string(Sandbox::LangSystemISO())), rpcDone(&IntroPhone::phoneSubmitDone), rpcFail(&IntroPhone::phoneSubmitFail)); sentRequest = MTP::send(MTPauth_SendCode(MTP_flags(flags), MTP_string(sentPhone), MTPBool(), MTP_int(ApiId), MTP_string(ApiHash), MTP_string(Sandbox::LangSystemISO())), rpcDone(&IntroPhone::phoneSubmitDone), rpcFail(&IntroPhone::phoneSubmitFail));
} }
bool IntroPhone::phoneSubmitFail(const RPCError &error) { bool IntroPhone::phoneSubmitFail(const RPCError &error) {

View file

@ -411,7 +411,7 @@ void FileLoadTask::process() {
} }
if (voice) { if (voice) {
attributes[0] = MTP_documentAttributeAudio(MTP_int(MTPDdocumentAttributeAudio::flag_voice | MTPDdocumentAttributeAudio::flag_waveform), MTP_int(_duration), MTPstring(), MTPstring(), MTP_string(documentWaveformEncode5bit(_waveform))); attributes[0] = MTP_documentAttributeAudio(MTP_flags(MTPDdocumentAttributeAudio::Flag::f_voice | MTPDdocumentAttributeAudio::Flag::f_waveform), MTP_int(_duration), MTPstring(), MTPstring(), MTP_string(documentWaveformEncode5bit(_waveform)));
attributes.resize(1); attributes.resize(1);
document = MTP_document(MTP_long(_id), MTP_long(0), MTP_int(unixtime()), MTP_string(filemime), MTP_int(filesize), thumbSize, MTP_int(MTP::maindc()), MTP_vector<MTPDocumentAttribute>(attributes)); document = MTP_document(MTP_long(_id), MTP_long(0), MTP_int(unixtime()), MTP_string(filemime), MTP_int(filesize), thumbSize, MTP_int(MTP::maindc()), MTP_vector<MTPDocumentAttribute>(attributes));
} else { } else {

View file

@ -864,7 +864,7 @@ namespace {
} }
} }
mtpDcOptions *_dcOpts = 0; MTP::DcOptions *_dcOpts = 0;
bool _readSetting(quint32 blockId, QDataStream &stream, int version) { bool _readSetting(quint32 blockId, QDataStream &stream, int version) {
switch (blockId) { switch (blockId) {
case dbiDcOptionOld: { case dbiDcOptionOld: {
@ -873,16 +873,17 @@ namespace {
stream >> dcId >> host >> ip >> port; stream >> dcId >> host >> ip >> port;
if (!_checkStreamStatus(stream)) return false; if (!_checkStreamStatus(stream)) return false;
if (_dcOpts) _dcOpts->insert(dcId, mtpDcOption(dcId, 0, ip.toUtf8().constData(), port)); if (_dcOpts) _dcOpts->insert(dcId, MTP::DcOption(dcId, 0, ip.toUtf8().constData(), port));
} break; } break;
case dbiDcOption: { case dbiDcOption: {
quint32 dcIdWithShift, flags, port; quint32 dcIdWithShift, port;
qint32 flags;
QString ip; QString ip;
stream >> dcIdWithShift >> flags >> ip >> port; stream >> dcIdWithShift >> flags >> ip >> port;
if (!_checkStreamStatus(stream)) return false; if (!_checkStreamStatus(stream)) return false;
if (_dcOpts) _dcOpts->insert(dcIdWithShift, mtpDcOption(dcIdWithShift % _mtp_internal::dcShift, flags, ip.toUtf8().constData(), port)); if (_dcOpts) _dcOpts->insert(dcIdWithShift, MTP::DcOption(dcIdWithShift % _mtp_internal::dcShift, MTPDdcOption::Flags(flags), ip.toUtf8().constData(), port));
} break; } break;
case dbiChatSizeMax: { case dbiChatSizeMax: {
@ -1462,16 +1463,16 @@ namespace {
LOG(("App Info: reading old user config..")); LOG(("App Info: reading old user config.."));
qint32 version = 0; qint32 version = 0;
mtpDcOptions dcOpts; MTP::DcOptions dcOpts;
{ {
QReadLocker lock(MTP::dcOptionsMutex()); QReadLocker lock(MTP::dcOptionsMutex());
dcOpts = cDcOptions(); dcOpts = Global::DcOptions();
} }
_dcOpts = &dcOpts; _dcOpts = &dcOpts;
_readOldUserSettingsFields(&file, version); _readOldUserSettingsFields(&file, version);
{ {
QWriteLocker lock(MTP::dcOptionsMutex()); QWriteLocker lock(MTP::dcOptionsMutex());
cSetDcOptions(dcOpts); Global::SetDcOptions(dcOpts);
} }
file.close(); file.close();
@ -1549,16 +1550,16 @@ namespace {
LOG(("App Info: reading old keys..")); LOG(("App Info: reading old keys.."));
qint32 version = 0; qint32 version = 0;
mtpDcOptions dcOpts; MTP::DcOptions dcOpts;
{ {
QReadLocker lock(MTP::dcOptionsMutex()); QReadLocker lock(MTP::dcOptionsMutex());
dcOpts = cDcOptions(); dcOpts = Global::DcOptions();
} }
_dcOpts = &dcOpts; _dcOpts = &dcOpts;
_readOldMtpDataFields(&file, version); _readOldMtpDataFields(&file, version);
{ {
QWriteLocker lock(MTP::dcOptionsMutex()); QWriteLocker lock(MTP::dcOptionsMutex());
cSetDcOptions(dcOpts); Global::SetDcOptions(dcOpts);
} }
file.close(); file.close();
@ -2116,10 +2117,10 @@ namespace Local {
LOG(("App Error: could not decrypt settings from settings file, maybe bad passcode..")); LOG(("App Error: could not decrypt settings from settings file, maybe bad passcode.."));
return writeSettings(); return writeSettings();
} }
mtpDcOptions dcOpts; MTP::DcOptions dcOpts;
{ {
QReadLocker lock(MTP::dcOptionsMutex()); QReadLocker lock(MTP::dcOptionsMutex());
dcOpts = cDcOptions(); dcOpts = Global::DcOptions();
} }
_dcOpts = &dcOpts; _dcOpts = &dcOpts;
LOG(("App Info: reading encrypted settings..")); LOG(("App Info: reading encrypted settings.."));
@ -2137,20 +2138,23 @@ namespace Local {
if (dcOpts.isEmpty()) { if (dcOpts.isEmpty()) {
const BuiltInDc *bdcs = builtInDcs(); const BuiltInDc *bdcs = builtInDcs();
for (int i = 0, l = builtInDcsCount(); i < l; ++i) { for (int i = 0, l = builtInDcsCount(); i < l; ++i) {
dcOpts.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, 0, bdcs[i].ip, bdcs[i].port)); MTPDdcOption::Flags flags = 0;
int idWithShift = bdcs[i].id + (flags * _mtp_internal::dcShift);
dcOpts.insert(idWithShift, MTP::DcOption(bdcs[i].id, flags, bdcs[i].ip, bdcs[i].port));
DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: %2:%3").arg(bdcs[i].id).arg(bdcs[i].ip).arg(bdcs[i].port)); DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: %2:%3").arg(bdcs[i].id).arg(bdcs[i].ip).arg(bdcs[i].port));
} }
const BuiltInDc *bdcsipv6 = builtInDcsIPv6(); const BuiltInDc *bdcsipv6 = builtInDcsIPv6();
for (int i = 0, l = builtInDcsCountIPv6(); i < l; ++i) { for (int i = 0, l = builtInDcsCountIPv6(); i < l; ++i) {
int32 flags = MTPDdcOption::flag_ipv6, idWithShift = bdcsipv6[i].id + (flags * _mtp_internal::dcShift); MTPDdcOption::Flags flags = MTPDdcOption::Flag::f_ipv6;
dcOpts.insert(idWithShift, mtpDcOption(bdcsipv6[i].id, flags, bdcsipv6[i].ip, bdcsipv6[i].port)); int idWithShift = bdcsipv6[i].id + (flags * _mtp_internal::dcShift);
dcOpts.insert(idWithShift, MTP::DcOption(bdcsipv6[i].id, flags, bdcsipv6[i].ip, bdcsipv6[i].port));
DEBUG_LOG(("MTP Info: adding built in DC %1 IPv6 connect option: %2:%3").arg(bdcsipv6[i].id).arg(bdcsipv6[i].ip).arg(bdcsipv6[i].port)); DEBUG_LOG(("MTP Info: adding built in DC %1 IPv6 connect option: %2:%3").arg(bdcsipv6[i].id).arg(bdcsipv6[i].ip).arg(bdcsipv6[i].port));
} }
} }
{ {
QWriteLocker lock(MTP::dcOptionsMutex()); QWriteLocker lock(MTP::dcOptionsMutex());
cSetDcOptions(dcOpts); Global::SetDcOptions(dcOpts);
} }
_oldSettingsVersion = settingsData.version; _oldSettingsVersion = settingsData.version;
@ -2173,30 +2177,34 @@ namespace Local {
} }
settings.writeData(_settingsSalt); settings.writeData(_settingsSalt);
mtpDcOptions dcOpts; MTP::DcOptions dcOpts;
{ {
QReadLocker lock(MTP::dcOptionsMutex()); QReadLocker lock(MTP::dcOptionsMutex());
dcOpts = cDcOptions(); dcOpts = Global::DcOptions();
} }
if (dcOpts.isEmpty()) { if (dcOpts.isEmpty()) {
const BuiltInDc *bdcs = builtInDcs(); const BuiltInDc *bdcs = builtInDcs();
for (int i = 0, l = builtInDcsCount(); i < l; ++i) { for (int i = 0, l = builtInDcsCount(); i < l; ++i) {
dcOpts.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, 0, bdcs[i].ip, bdcs[i].port)); MTPDdcOption::Flags flags = 0;
int idWithShift = bdcs[i].id + (flags * _mtp_internal::dcShift);
dcOpts.insert(idWithShift, MTP::DcOption(bdcs[i].id, flags, bdcs[i].ip, bdcs[i].port));
DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: %2:%3").arg(bdcs[i].id).arg(bdcs[i].ip).arg(bdcs[i].port)); DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: %2:%3").arg(bdcs[i].id).arg(bdcs[i].ip).arg(bdcs[i].port));
} }
const BuiltInDc *bdcsipv6 = builtInDcsIPv6(); const BuiltInDc *bdcsipv6 = builtInDcsIPv6();
for (int i = 0, l = builtInDcsCountIPv6(); i < l; ++i) { for (int i = 0, l = builtInDcsCountIPv6(); i < l; ++i) {
dcOpts.insert(bdcsipv6[i].id + (MTPDdcOption::flag_ipv6 * _mtp_internal::dcShift), mtpDcOption(bdcsipv6[i].id, MTPDdcOption::flag_ipv6, bdcsipv6[i].ip, bdcsipv6[i].port)); MTPDdcOption::Flags flags = MTPDdcOption::Flag::f_ipv6;
int idWithShift = bdcsipv6[i].id + (flags * _mtp_internal::dcShift);
dcOpts.insert(idWithShift, MTP::DcOption(bdcsipv6[i].id, flags, bdcsipv6[i].ip, bdcsipv6[i].port));
DEBUG_LOG(("MTP Info: adding built in DC %1 IPv6 connect option: %2:%3").arg(bdcsipv6[i].id).arg(bdcsipv6[i].ip).arg(bdcsipv6[i].port)); DEBUG_LOG(("MTP Info: adding built in DC %1 IPv6 connect option: %2:%3").arg(bdcsipv6[i].id).arg(bdcsipv6[i].ip).arg(bdcsipv6[i].port));
} }
QWriteLocker lock(MTP::dcOptionsMutex()); QWriteLocker lock(MTP::dcOptionsMutex());
cSetDcOptions(dcOpts); Global::SetDcOptions(dcOpts);
} }
quint32 size = 12 * (sizeof(quint32) + sizeof(qint32)); quint32 size = 12 * (sizeof(quint32) + sizeof(qint32));
for (mtpDcOptions::const_iterator i = dcOpts.cbegin(), e = dcOpts.cend(); i != e; ++i) { for (auto i = dcOpts.cbegin(), e = dcOpts.cend(); i != e; ++i) {
size += sizeof(quint32) + sizeof(quint32) + sizeof(quint32); size += sizeof(quint32) + sizeof(quint32) + sizeof(quint32);
size += sizeof(quint32) + _stringSize(QString::fromUtf8(i->ip.data(), i->ip.size())); size += sizeof(quint32) + _stringSize(QString::fromUtf8(i->ip.data(), i->ip.size()));
} }
@ -2223,9 +2231,9 @@ namespace Local {
data.stream << quint32(dbiLastUpdateCheck) << qint32(cLastUpdateCheck()); data.stream << quint32(dbiLastUpdateCheck) << qint32(cLastUpdateCheck());
data.stream << quint32(dbiScale) << qint32(cConfigScale()); data.stream << quint32(dbiScale) << qint32(cConfigScale());
data.stream << quint32(dbiLang) << qint32(cLang()); data.stream << quint32(dbiLang) << qint32(cLang());
for (mtpDcOptions::const_iterator i = dcOpts.cbegin(), e = dcOpts.cend(); i != e; ++i) { for (auto i = dcOpts.cbegin(), e = dcOpts.cend(); i != e; ++i) {
data.stream << quint32(dbiDcOption) << quint32(i.key()); data.stream << quint32(dbiDcOption) << quint32(i.key());
data.stream << quint32(i->flags) << QString::fromUtf8(i->ip.data(), i->ip.size()); data.stream << qint32(i->flags) << QString::fromUtf8(i->ip.data(), i->ip.size());
data.stream << quint32(i->port); data.stream << quint32(i->port);
} }
data.stream << quint32(dbiLangFile) << cLangFile(); data.stream << quint32(dbiLangFile) << cLangFile();
@ -3019,10 +3027,10 @@ namespace Local {
} }
void _writeStickerSet(QDataStream &stream, uint64 setId) { void _writeStickerSet(QDataStream &stream, uint64 setId) {
StickerSets::const_iterator it = cStickerSets().constFind(setId); auto it = Global::StickerSets().constFind(setId);
if (it == cStickerSets().cend()) return; if (it == Global::StickerSets().cend()) return;
bool notLoaded = (it->flags & MTPDstickerSet_flag_NOT_LOADED); bool notLoaded = (it->flags & MTPDstickerSet_ClientFlag::f_not_loaded);
if (notLoaded) { if (notLoaded) {
stream << quint64(it->id) << quint64(it->access) << it->title << it->shortName << qint32(-it->count) << qint32(it->hash) << qint32(it->flags); stream << quint64(it->id) << quint64(it->access) << it->title << it->shortName << qint32(-it->count) << qint32(it->hash) << qint32(it->flags);
return; return;
@ -3063,7 +3071,7 @@ namespace Local {
void writeStickers() { void writeStickers() {
if (!_working()) return; if (!_working()) return;
const StickerSets &sets(cStickerSets()); const Stickers::Sets &sets(Global::StickerSets());
if (sets.isEmpty()) { if (sets.isEmpty()) {
if (_stickersKey) { if (_stickersKey) {
clearKey(_stickersKey); clearKey(_stickersKey);
@ -3075,10 +3083,10 @@ namespace Local {
int32 setsCount = 0; int32 setsCount = 0;
QByteArray hashToWrite; QByteArray hashToWrite;
quint32 size = sizeof(quint32) + _bytearraySize(hashToWrite); quint32 size = sizeof(quint32) + _bytearraySize(hashToWrite);
for (StickerSets::const_iterator i = sets.cbegin(); i != sets.cend(); ++i) { for (auto i = sets.cbegin(); i != sets.cend(); ++i) {
bool notLoaded = (i->flags & MTPDstickerSet_flag_NOT_LOADED); bool notLoaded = (i->flags & MTPDstickerSet_ClientFlag::f_not_loaded);
if (notLoaded) { if (notLoaded) {
if (!(i->flags & MTPDstickerSet::flag_disabled) || (i->flags & MTPDstickerSet::flag_official)) { // waiting to receive if (!(i->flags & MTPDstickerSet::Flag::f_disabled) || (i->flags & MTPDstickerSet::Flag::f_official)) { // waiting to receive
return; return;
} }
} else { } else {
@ -3114,8 +3122,8 @@ namespace Local {
} }
EncryptedDescriptor data(size); EncryptedDescriptor data(size);
data.stream << quint32(setsCount) << hashToWrite; data.stream << quint32(setsCount) << hashToWrite;
_writeStickerSet(data.stream, CustomStickerSetId); _writeStickerSet(data.stream, Stickers::CustomSetId);
for (StickerSetsOrder::const_iterator i = cStickerSetsOrder().cbegin(), e = cStickerSetsOrder().cend(); i != e; ++i) { for (auto i = Global::StickerSetsOrder().cbegin(), e = Global::StickerSetsOrder().cend(); i != e; ++i) {
_writeStickerSet(data.stream, *i); _writeStickerSet(data.stream, *i);
} }
FileWriteDescriptor file(_stickersKey); FileWriteDescriptor file(_stickersKey);
@ -3134,17 +3142,17 @@ namespace Local {
return; return;
} }
StickerSets &sets(cRefStickerSets()); Stickers::Sets &sets(Global::RefStickerSets());
sets.clear(); sets.clear();
StickerSetsOrder &order(cRefStickerSetsOrder()); Stickers::Order &order(Global::RefStickerSetsOrder());
order.clear(); order.clear();
RecentStickerPack &recent(cRefRecentStickers()); RecentStickerPack &recent(cRefRecentStickers());
recent.clear(); recent.clear();
StickerSet &def(sets.insert(DefaultStickerSetId, StickerSet(DefaultStickerSetId, 0, lang(lng_stickers_default_set), QString(), 0, 0, MTPDstickerSet::flag_official)).value()); Stickers::Set &def(sets.insert(Stickers::DefaultSetId, Stickers::Set(Stickers::DefaultSetId, 0, lang(lng_stickers_default_set), QString(), 0, 0, MTPDstickerSet::Flag::f_official)).value());
StickerSet &custom(sets.insert(CustomStickerSetId, StickerSet(CustomStickerSetId, 0, lang(lng_custom_stickers), QString(), 0, 0, 0)).value()); Stickers::Set &custom(sets.insert(Stickers::CustomSetId, Stickers::Set(Stickers::CustomSetId, 0, lang(lng_custom_stickers), QString(), 0, 0, 0)).value());
QMap<uint64, bool> read; QMap<uint64, bool> read;
while (!stickers.stream.atEnd()) { while (!stickers.stream.atEnd()) {
@ -3183,11 +3191,11 @@ namespace Local {
if (recent.size() < StickerPanPerRow * StickerPanRowsPerPage && qAbs(value) > 1) recent.push_back(qMakePair(doc, qAbs(value))); if (recent.size() < StickerPanPerRow * StickerPanRowsPerPage && qAbs(value) > 1) recent.push_back(qMakePair(doc, qAbs(value)));
} }
if (def.stickers.isEmpty()) { if (def.stickers.isEmpty()) {
sets.remove(DefaultStickerSetId); sets.remove(Stickers::DefaultSetId);
} else { } else {
order.push_front(DefaultStickerSetId); order.push_front(Stickers::DefaultSetId);
} }
if (custom.stickers.isEmpty()) sets.remove(CustomStickerSetId); if (custom.stickers.isEmpty()) sets.remove(Stickers::CustomSetId);
writeStickers(); writeStickers();
writeUserSettings(); writeUserSettings();
@ -3210,10 +3218,10 @@ namespace Local {
return; return;
} }
StickerSets &sets(cRefStickerSets()); Stickers::Sets &sets(Global::RefStickerSets());
sets.clear(); sets.clear();
StickerSetsOrder &order(cRefStickerSetsOrder()); Stickers::Order &order(Global::RefStickerSetsOrder());
order.clear(); order.clear();
quint32 cnt; quint32 cnt;
@ -3231,20 +3239,24 @@ namespace Local {
qint32 setHash = 0, setFlags = 0; qint32 setHash = 0, setFlags = 0;
if (stickers.version > 8033) { if (stickers.version > 8033) {
stickers.stream >> setHash >> setFlags; stickers.stream >> setHash >> setFlags;
if (setFlags & qFlags(MTPDstickerSet_ClientFlag::f_not_loaded__old)) {
setFlags &= ~qFlags(MTPDstickerSet_ClientFlag::f_not_loaded__old);
setFlags |= qFlags(MTPDstickerSet_ClientFlag::f_not_loaded);
}
} }
if (setId == DefaultStickerSetId) { if (setId == Stickers::DefaultSetId) {
setTitle = lang(lng_stickers_default_set); setTitle = lang(lng_stickers_default_set);
setFlags |= MTPDstickerSet::flag_official; setFlags |= qFlags(MTPDstickerSet::Flag::f_official);
order.push_front(setId); order.push_front(setId);
} else if (setId == CustomStickerSetId) { } else if (setId == Stickers::CustomSetId) {
setTitle = lang(lng_custom_stickers); setTitle = lang(lng_custom_stickers);
} else if (setId) { } else if (setId) {
order.push_back(setId); order.push_back(setId);
} else { } else {
continue; continue;
} }
StickerSet &set(sets.insert(setId, StickerSet(setId, setAccess, setTitle, setShortName, 0, setHash, setFlags)).value()); Stickers::Set &set(sets.insert(setId, Stickers::Set(setId, setAccess, setTitle, setShortName, 0, setHash, MTPDstickerSet::Flags(setFlags))).value());
if (scnt < 0) { // disabled not loaded set if (scnt < 0) { // disabled not loaded set
set.count = -scnt; set.count = -scnt;
continue; continue;
@ -3264,7 +3276,7 @@ namespace Local {
if (read.contains(id)) continue; if (read.contains(id)) continue;
read.insert(id, true); read.insert(id, true);
if (setId == DefaultStickerSetId || setId == CustomStickerSetId) { if (setId == Stickers::DefaultSetId || setId == Stickers::CustomSetId) {
typeOfSet = StickerSetTypeEmpty; typeOfSet = StickerSetTypeEmpty;
} }
@ -3325,17 +3337,17 @@ namespace Local {
int32 countStickersHash(bool checkOfficial) { int32 countStickersHash(bool checkOfficial) {
uint32 acc = 0; uint32 acc = 0;
bool foundOfficial = false, foundBad = false;; bool foundOfficial = false, foundBad = false;;
const StickerSets &sets(cStickerSets()); const Stickers::Sets &sets(Global::StickerSets());
const StickerSetsOrder &order(cStickerSetsOrder()); const Stickers::Order &order(Global::StickerSetsOrder());
for (StickerSetsOrder::const_iterator i = order.cbegin(), e = order.cend(); i != e; ++i) { for (auto i = order.cbegin(), e = order.cend(); i != e; ++i) {
StickerSets::const_iterator j = sets.constFind(*i); auto j = sets.constFind(*i);
if (j != sets.cend()) { if (j != sets.cend()) {
if (j->id == 0) { if (j->id == 0) {
foundBad = true; foundBad = true;
} else if (j->flags & MTPDstickerSet::flag_official) { } else if (j->flags & MTPDstickerSet::Flag::f_official) {
foundOfficial = true; foundOfficial = true;
} }
if (!(j->flags & MTPDstickerSet::flag_disabled)) { if (!(j->flags & MTPDstickerSet::Flag::f_disabled)) {
acc = (acc * 20261) + j->hash; acc = (acc * 20261) + j->hash;
} }
} }
@ -3600,7 +3612,7 @@ namespace Local {
user->setName(first, last, pname, username); user->setName(first, last, pname, username);
user->access = access; user->access = access;
user->flags = flags; user->flags = MTPDuser::Flags(flags);
user->onlineTill = onlineTill; user->onlineTill = onlineTill;
user->contact = contact; user->contact = contact;
user->setBotInfoVersion(botInfoVersion); user->setBotInfoVersion(botInfoVersion);
@ -3629,7 +3641,7 @@ namespace Local {
flags = flagsData; flags = flagsData;
} else { } else {
// flagsData was haveLeft // flagsData was haveLeft
flags = (flagsData == 1 ? MTPDchat::flag_left : 0); flags = (flagsData == 1 ? MTPDchat::Flags(MTPDchat::Flag::f_left) : 0);
} }
if (!wasLoaded) { if (!wasLoaded) {
chat->updateName(name, QString(), QString()); chat->updateName(name, QString(), QString());
@ -3638,7 +3650,7 @@ namespace Local {
chat->version = version; chat->version = version;
chat->creator = creator; chat->creator = creator;
chat->isForbidden = (forbidden == 1); chat->isForbidden = (forbidden == 1);
chat->flags = flags; chat->flags = MTPDchat::Flags(flags);
chat->invitationUrl = invitationUrl; chat->invitationUrl = invitationUrl;
chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id))); chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id)));
@ -3660,7 +3672,7 @@ namespace Local {
channel->date = date; channel->date = date;
channel->version = version; channel->version = version;
channel->isForbidden = (forbidden == 1); channel->isForbidden = (forbidden == 1);
channel->flags = flags; channel->flags = MTPDchannel::Flags(flags);
channel->invitationUrl = invitationUrl; channel->invitationUrl = invitationUrl;
channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access)); channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access));

View file

@ -615,20 +615,21 @@ void MainWidget::finishForwarding(History *hist, bool broadcast, bool silent) {
PeerData *forwardFrom = 0; PeerData *forwardFrom = 0;
App::main()->readServerHistory(hist, false); App::main()->readServerHistory(hist, false);
int32 sendFlags = 0, flags = 0; MTPDmessage::Flags flags = 0;
MTPmessages_ForwardMessages::Flags sendFlags = 0;
bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && (hist->peer->asChannel()->isBroadcast() || broadcast); bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && (hist->peer->asChannel()->isBroadcast() || broadcast);
bool showFromName = !channelPost || hist->peer->asChannel()->addsSignature(); bool showFromName = !channelPost || hist->peer->asChannel()->addsSignature();
bool silentPost = channelPost && silent; bool silentPost = channelPost && silent;
if (channelPost) { if (channelPost) {
sendFlags |= MTPmessages_ForwardMessages::flag_broadcast; sendFlags |= MTPmessages_ForwardMessages::Flag::f_broadcast;
flags |= MTPDmessage::flag_views; flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::flag_post; flags |= MTPDmessage::Flag::f_post;
} }
if (showFromName) { if (showFromName) {
flags |= MTPDmessage::flag_from_id; flags |= MTPDmessage::Flag::f_from_id;
} }
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_ForwardMessages::flag_silent; sendFlags |= MTPmessages_ForwardMessages::Flag::f_silent;
} }
QVector<MTPint> ids; QVector<MTPint> ids;
@ -650,7 +651,7 @@ void MainWidget::finishForwarding(History *hist, bool broadcast, bool silent) {
} }
if (forwardFrom != i.value()->history()->peer) { if (forwardFrom != i.value()->history()->peer) {
if (forwardFrom) { if (forwardFrom) {
hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_int(sendFlags), forwardFrom->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds), hist->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId); hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_flags(sendFlags), forwardFrom->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds), hist->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
ids.resize(0); ids.resize(0);
randomIds.resize(0); randomIds.resize(0);
} }
@ -659,7 +660,7 @@ void MainWidget::finishForwarding(History *hist, bool broadcast, bool silent) {
ids.push_back(MTP_int(i.value()->id)); ids.push_back(MTP_int(i.value()->id));
randomIds.push_back(MTP_long(randomId)); randomIds.push_back(MTP_long(randomId));
} }
hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_int(sendFlags), forwardFrom->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds), hist->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId); hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_flags(sendFlags), forwardFrom->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds), hist->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
if (history.peer() == hist->peer) { if (history.peer() == hist->peer) {
history.peerMessagesUpdated(); history.peerMessagesUpdated();
@ -687,8 +688,7 @@ void MainWidget::webPagesUpdate() {
WebPageItems::const_iterator j = items.constFind(App::webPage(i.key())); WebPageItems::const_iterator j = items.constFind(App::webPage(i.key()));
if (j != items.cend()) { if (j != items.cend()) {
for (HistoryItemsMap::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) { for (HistoryItemsMap::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
k.key()->initDimensions(); k.key()->setPendingInitDimensions();
Notify::historyItemResized(k.key());
} }
} }
} }
@ -783,8 +783,7 @@ void MainWidget::notify_userIsContactChanged(UserData *user, bool fromThisApp) {
SharedContactItems::const_iterator i = items.constFind(peerToUser(user->id)); SharedContactItems::const_iterator i = items.constFind(peerToUser(user->id));
if (i != items.cend()) { if (i != items.cend()) {
for (HistoryItemsMap::const_iterator j = i->cbegin(), e = i->cend(); j != e; ++j) { for (HistoryItemsMap::const_iterator j = i->cbegin(), e = i->cend(); j != e; ++j) {
j.key()->initDimensions(); j.key()->setPendingInitDimensions();
Ui::repaintHistoryItem(j.key());
} }
} }
@ -830,6 +829,10 @@ void MainWidget::notify_automaticLoadSettingsChangedGif() {
history.notify_automaticLoadSettingsChangedGif(); history.notify_automaticLoadSettingsChangedGif();
} }
void MainWidget::notify_handlePendingHistoryUpdate() {
history.notify_handlePendingHistoryUpdate();
}
void MainWidget::cmd_search() { void MainWidget::cmd_search() {
history.cmd_search(); history.cmd_search();
} }
@ -842,18 +845,6 @@ void MainWidget::cmd_previous_chat() {
history.cmd_previous_chat(); history.cmd_previous_chat();
} }
void MainWidget::notify_historyItemResized(const HistoryItem *item, bool scrollToIt) {
if (!item || ((history.peer() == item->history()->peer || (history.peer() && history.peer() == item->history()->peer->migrateTo())) && !item->detached())) {
history.notify_historyItemResized(item, scrollToIt);
} else if (item) {
item->history()->width = 0;
if (history.peer() == item->history()->peer || (history.peer() && history.peer() == item->history()->peer->migrateTo())) {
history.resizeEvent(0);
}
}
if (item) Ui::repaintHistoryItem(item);
}
void MainWidget::noHider(HistoryHider *destroyed) { void MainWidget::noHider(HistoryHider *destroyed) {
if (_hider == destroyed) { if (_hider == destroyed) {
_hider = 0; _hider = 0;
@ -1379,40 +1370,40 @@ void MainWidget::sendMessage(History *hist, const QString &text, MsgId replyTo,
App::historyRegSentData(randomId, hist->peer->id, sendingText); App::historyRegSentData(randomId, hist->peer->id, sendingText);
MTPstring msgText(MTP_string(sendingText)); MTPstring msgText(MTP_string(sendingText));
int32 flags = newMessageFlags(hist->peer) | MTPDmessage::flag_entities; // unread, out MTPDmessage::Flags flags = newMessageFlags(hist->peer) | MTPDmessage::Flag::f_entities; // unread, out
int32 sendFlags = 0; MTPmessages_SendMessage::Flags sendFlags = 0;
if (replyTo) { if (replyTo) {
flags |= MTPDmessage::flag_reply_to_msg_id; flags |= MTPDmessage::Flag::f_reply_to_msg_id;
sendFlags |= MTPmessages_SendMessage::flag_reply_to_msg_id; sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to_msg_id;
} }
MTPMessageMedia media = MTP_messageMediaEmpty(); MTPMessageMedia media = MTP_messageMediaEmpty();
if (webPageId == CancelledWebPageId) { if (webPageId == CancelledWebPageId) {
sendFlags |= MTPmessages_SendMessage::flag_no_webpage; sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage;
} else if (webPageId) { } else if (webPageId) {
WebPageData *page = App::webPage(webPageId); WebPageData *page = App::webPage(webPageId);
media = MTP_messageMediaWebPage(MTP_webPagePending(MTP_long(page->id), MTP_int(page->pendingTill))); media = MTP_messageMediaWebPage(MTP_webPagePending(MTP_long(page->id), MTP_int(page->pendingTill)));
flags |= MTPDmessage::flag_media; flags |= MTPDmessage::Flag::f_media;
} }
bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && (hist->peer->asChannel()->isBroadcast() || broadcast); bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && (hist->peer->asChannel()->isBroadcast() || broadcast);
bool showFromName = !channelPost || hist->peer->asChannel()->addsSignature(); bool showFromName = !channelPost || hist->peer->asChannel()->addsSignature();
bool silentPost = channelPost && silent; bool silentPost = channelPost && silent;
if (channelPost) { if (channelPost) {
sendFlags |= MTPmessages_SendMessage::flag_broadcast; sendFlags |= MTPmessages_SendMessage::Flag::f_broadcast;
flags |= MTPDmessage::flag_views; flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::flag_post; flags |= MTPDmessage::Flag::f_post;
} }
if (showFromName) { if (showFromName) {
flags |= MTPDmessage::flag_from_id; flags |= MTPDmessage::Flag::f_from_id;
} }
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_SendMessage::flag_silent; sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
} }
MTPVector<MTPMessageEntity> localEntities = linksToMTP(sendingEntities), sentEntities = linksToMTP(sendingEntities, true); MTPVector<MTPMessageEntity> localEntities = linksToMTP(sendingEntities), sentEntities = linksToMTP(sendingEntities, true);
if (!sentEntities.c_vector().v.isEmpty()) { if (!sentEntities.c_vector().v.isEmpty()) {
sendFlags |= MTPmessages_SendMessage::flag_entities; sendFlags |= MTPmessages_SendMessage::Flag::f_entities;
} }
hist->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(hist->peer->id), MTPnullFwdHeader, MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, localEntities, MTP_int(1), MTPint()), NewMessageUnread); hist->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(hist->peer->id), MTPnullFwdHeader, MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, localEntities, MTP_int(1), MTPint()), NewMessageUnread);
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup, sentEntities), rpcDone(&MainWidget::sentUpdatesReceived, randomId), rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId); hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_flags(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup, sentEntities), rpcDone(&MainWidget::sentUpdatesReceived, randomId), rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId);
} }
finishForwarding(hist, broadcast, silent); finishForwarding(hist, broadcast, silent);
@ -1502,8 +1493,11 @@ bool MainWidget::preloadOverview(PeerData *peer, MediaOverviewType type) {
return false; return false;
} }
int32 flags = (peer->isChannel() && !peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; MTPmessages_Search::Flags flags = 0;
_overviewPreload[type].insert(peer, MTP::send(MTPmessages_Search(MTP_int(flags), peer->input, MTP_string(""), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::overviewPreloaded, peer), rpcFail(&MainWidget::overviewFailed, peer), 0, 10)); if (peer->isChannel() && !peer->isMegagroup()) {
flags |= MTPmessages_Search::Flag::f_important_only;
}
_overviewPreload[type].insert(peer, MTP::send(MTPmessages_Search(MTP_flags(flags), peer->input, MTP_string(""), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::overviewPreloaded, peer), rpcFail(&MainWidget::overviewFailed, peer), 0, 10));
return true; return true;
} }
@ -1635,8 +1629,11 @@ void MainWidget::loadMediaBack(PeerData *peer, MediaOverviewType type, bool many
MTPMessagesFilter filter = typeToMediaFilter(type); MTPMessagesFilter filter = typeToMediaFilter(type);
if (type == OverviewCount) return; if (type == OverviewCount) return;
int32 flags = (peer->isChannel() && !peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; MTPmessages_Search::Flags flags = 0;
_overviewLoad[type].insert(peer, MTP::send(MTPmessages_Search(MTP_int(flags), peer->input, MTPstring(), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(minId), MTP_int(limit)), rpcDone(&MainWidget::overviewLoaded, history))); if (peer->isChannel() && !peer->isMegagroup()) {
flags |= MTPmessages_Search::Flag::f_important_only;
}
_overviewLoad[type].insert(peer, MTP::send(MTPmessages_Search(MTP_flags(flags), peer->input, MTPstring(), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(minId), MTP_int(limit)), rpcDone(&MainWidget::overviewLoaded, history)));
} }
void MainWidget::peerUsernameChanged(PeerData *peer) { void MainWidget::peerUsernameChanged(PeerData *peer) {
@ -1762,6 +1759,14 @@ void MainWidget::ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId) {
Ui::showPeerHistory(peerId, showAtMsgId); Ui::showPeerHistory(peerId, showAtMsgId);
} }
void MainWidget::ui_autoplayMediaInlineAsync(qint32 channelId, qint32 msgId) {
if (HistoryItem *item = App::histItemById(channelId, msgId)) {
if (HistoryMedia *media = item->getMedia()) {
media->playInline(item, true);
}
}
}
void MainWidget::audioPlayProgress(const AudioMsgId &audioId) { void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState state = AudioPlayerStopped; AudioPlayerState state = AudioPlayerStopped;
@ -1953,13 +1958,13 @@ void MainWidget::dialogsCancelled() {
} }
void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia &media) { void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia &media) {
int32 flags = MTPDmessage::flag_unread | MTPDmessage::flag_entities | MTPDmessage::flag_from_id; MTPDmessage::Flags flags = MTPDmessage::Flag::f_unread | MTPDmessage::Flag::f_entities | MTPDmessage::Flag::f_from_id;
QString sendingText, leftText = msg; QString sendingText, leftText = msg;
EntitiesInText sendingEntities, leftEntities = textParseEntities(leftText, _historyTextNoMonoOptions.flags); EntitiesInText sendingEntities, leftEntities = textParseEntities(leftText, _historyTextNoMonoOptions.flags);
HistoryItem *item = 0; HistoryItem *item = 0;
while (textSplit(sendingText, sendingEntities, leftText, leftEntities, MaxMessageSize)) { while (textSplit(sendingText, sendingEntities, leftText, leftEntities, MaxMessageSize)) {
MTPVector<MTPMessageEntity> localEntities = linksToMTP(sendingEntities); MTPVector<MTPMessageEntity> localEntities = linksToMTP(sendingEntities);
item = App::histories().addNewMessage(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPnullFwdHeader, MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup, localEntities, MTPint(), MTPint()), NewMessageUnread); item = App::histories().addNewMessage(MTP_message(MTP_flags(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPnullFwdHeader, MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup, localEntities, MTPint(), MTPint()), NewMessageUnread);
} }
if (item) { if (item) {
history.peerMessagesUpdated(item->history()->peer->id); history.peerMessagesUpdated(item->history()->peer->id);
@ -2910,7 +2915,7 @@ void MainWidget::onUpdateNotifySettings() {
if (peer->notify == UnknownNotifySettings || peer->notify == EmptyNotifySettings) { if (peer->notify == UnknownNotifySettings || peer->notify == EmptyNotifySettings) {
peer->notify = new NotifySettings(); peer->notify = new NotifySettings();
} }
MTP::send(MTPaccount_UpdateNotifySettings(MTP_inputNotifyPeer(peer->input), MTP_inputPeerNotifySettings(MTP_int(peer->notify->flags), MTP_int(peer->notify->mute), MTP_string(peer->notify->sound))), RPCResponseHandler(), 0, updateNotifySettingPeers.isEmpty() ? 0 : 10); MTP::send(MTPaccount_UpdateNotifySettings(MTP_inputNotifyPeer(peer->input), MTP_inputPeerNotifySettings(MTP_flags(mtpCastFlags(peer->notify->flags)), MTP_int(peer->notify->mute), MTP_string(peer->notify->sound))), RPCResponseHandler(), 0, updateNotifySettingPeers.isEmpty() ? 0 : 10);
} }
} }
@ -3799,9 +3804,9 @@ void MainWidget::updateNotifySetting(PeerData *peer, NotifySettingStatus notify,
peer->notify->mute = (notify == NotifySettingSetMuted) ? (unixtime() + muteFor) : 0; peer->notify->mute = (notify == NotifySettingSetMuted) ? (unixtime() + muteFor) : 0;
} }
if (silent == SilentNotifiesSetSilent) { if (silent == SilentNotifiesSetSilent) {
peer->notify->flags |= MTPDpeerNotifySettings::flag_silent; peer->notify->flags |= MTPDpeerNotifySettings::Flag::f_silent;
} else if (silent == SilentNotifiesSetNotify) { } else if (silent == SilentNotifiesSetNotify) {
peer->notify->flags &= ~MTPDpeerNotifySettings::flag_silent; peer->notify->flags &= ~MTPDpeerNotifySettings::Flag::f_silent;
} }
} }
if (notify != NotifySettingDontChange) { if (notify != NotifySettingDontChange) {
@ -3864,9 +3869,9 @@ void MainWidget::incrementSticker(DocumentData *sticker) {
case mtpc_inputStickerSetID: setId = sticker->sticker()->set.c_inputStickerSetID().vid.v; break; case mtpc_inputStickerSetID: setId = sticker->sticker()->set.c_inputStickerSetID().vid.v; break;
case mtpc_inputStickerSetShortName: setName = qs(sticker->sticker()->set.c_inputStickerSetShortName().vshort_name).toLower().trimmed(); break; case mtpc_inputStickerSetShortName: setName = qs(sticker->sticker()->set.c_inputStickerSetShortName().vshort_name).toLower().trimmed(); break;
} }
StickerSets &sets(cRefStickerSets()); Stickers::Sets &sets(Global::RefStickerSets());
for (StickerSets::const_iterator i = sets.cbegin(); i != sets.cend(); ++i) { for (auto i = sets.cbegin(); i != sets.cend(); ++i) {
if (i->id == CustomStickerSetId || i->id == DefaultStickerSetId || (setId && i->id == setId) || (!setName.isEmpty() && i->shortName.toLower().trimmed() == setName)) { if (i->id == Stickers::CustomSetId || i->id == Stickers::DefaultSetId || (setId && i->id == setId) || (!setName.isEmpty() && i->shortName.toLower().trimmed() == setName)) {
for (int32 j = 0, l = i->stickers.size(); j < l; ++j) { for (int32 j = 0, l = i->stickers.size(); j < l; ++j) {
if (i->stickers.at(j) == sticker) { if (i->stickers.at(j) == sticker) {
found = true; found = true;
@ -3877,9 +3882,9 @@ void MainWidget::incrementSticker(DocumentData *sticker) {
} }
} }
if (!found) { if (!found) {
StickerSets::iterator it = sets.find(CustomStickerSetId); Stickers::Sets::iterator it = sets.find(Stickers::CustomSetId);
if (it == sets.cend()) { if (it == sets.cend()) {
it = sets.insert(CustomStickerSetId, StickerSet(CustomStickerSetId, 0, lang(lng_custom_stickers), QString(), 0, 0, 0)); it = sets.insert(Stickers::CustomSetId, Stickers::Set(Stickers::CustomSetId, 0, lang(lng_custom_stickers), QString(), 0, 0, 0));
} }
it->stickers.push_back(sticker); it->stickers.push_back(sticker);
++it->count; ++it->count;
@ -4094,8 +4099,8 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
} }
// update before applying skipped // update before applying skipped
int32 flags = d.vflags.v | MTPDmessage::flag_from_id; MTPDmessage::Flags flags = mtpCastFlags(d.vflags.v) | MTPDmessage::Flag::f_from_id;
HistoryItem *item = App::histories().addNewMessage(MTP_message(MTP_int(flags), d.vid, d.is_out() ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(d.is_out() ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from, d.vvia_bot_id, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint(), MTPint()), NewMessageUnread); HistoryItem *item = App::histories().addNewMessage(MTP_message(MTP_flags(flags), d.vid, d.is_out() ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(d.is_out() ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from, d.vvia_bot_id, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint(), MTPint()), NewMessageUnread);
if (item) { if (item) {
history.peerMessagesUpdated(item->history()->peer->id); history.peerMessagesUpdated(item->history()->peer->id);
} }
@ -4129,8 +4134,8 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
} }
// update before applying skipped // update before applying skipped
int32 flags = d.vflags.v | MTPDmessage::flag_from_id; MTPDmessage::Flags flags = mtpCastFlags(d.vflags.v) | MTPDmessage::Flag::f_from_id;
HistoryItem *item = App::histories().addNewMessage(MTP_message(MTP_int(flags), d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from, d.vvia_bot_id, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint(), MTPint()), NewMessageUnread); HistoryItem *item = App::histories().addNewMessage(MTP_message(MTP_flags(flags), d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from, d.vvia_bot_id, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities, MTPint(), MTPint()), NewMessageUnread);
if (item) { if (item) {
history.peerMessagesUpdated(item->history()->peer->id); history.peerMessagesUpdated(item->history()->peer->id);
} }
@ -4152,9 +4157,6 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
if (HistoryItem *item = App::histItemById(peerToChannel(peerId), d.vid.v)) { if (HistoryItem *item = App::histItemById(peerToChannel(peerId), d.vid.v)) {
item->setText(text, d.has_entities() ? entitiesFromMTP(d.ventities.c_vector().v) : EntitiesInText()); item->setText(text, d.has_entities() ? entitiesFromMTP(d.ventities.c_vector().v) : EntitiesInText());
item->updateMedia(d.has_media() ? (&d.vmedia) : 0); item->updateMedia(d.has_media() ? (&d.vmedia) : 0);
item->initDimensions();
Notify::historyItemResized(item);
item->addToOverview(AddToOverviewNew); item->addToOverview(AddToOverviewNew);
} }
} }
@ -4437,7 +4439,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
UserData *user = App::userLoaded(d.vuser_id.v); UserData *user = App::userLoaded(d.vuser_id.v);
if (user) { if (user) {
if (App::history(user->id)->loadedAtBottom()) { if (App::history(user->id)->loadedAtBottom()) {
App::history(user->id)->addNewService(clientMsgId(), date(d.vdate), lng_action_user_registered(lt_from, user->name), MTPDmessage::flag_unread); App::history(user->id)->addNewService(clientMsgId(), date(d.vdate), lng_action_user_registered(lt_from, user->name), MTPDmessage::Flag::f_unread);
} }
} }
} break; } break;
@ -4660,10 +4662,10 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
if (set.vset.type() == mtpc_stickerSet) { if (set.vset.type() == mtpc_stickerSet) {
const MTPDstickerSet &s(set.vset.c_stickerSet()); const MTPDstickerSet &s(set.vset.c_stickerSet());
StickerSets &sets(cRefStickerSets()); Stickers::Sets &sets(Global::RefStickerSets());
StickerSets::iterator it = sets.find(s.vid.v); auto it = sets.find(s.vid.v);
if (it == sets.cend()) { if (it == sets.cend()) {
it = sets.insert(s.vid.v, StickerSet(s.vid.v, s.vaccess_hash.v, stickerSetTitle(s), qs(s.vshort_name), s.vcount.v, s.vhash.v, s.vflags.v)); it = sets.insert(s.vid.v, Stickers::Set(s.vid.v, s.vaccess_hash.v, stickerSetTitle(s), qs(s.vshort_name), s.vcount.v, s.vhash.v, s.vflags.v));
} }
const QVector<MTPDocument> &v(set.vdocuments.c_vector().v); const QVector<MTPDocument> &v(set.vdocuments.c_vector().v);
@ -4694,7 +4696,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
} }
} }
StickerSetsOrder &order(cRefStickerSetsOrder()); auto &order(Global::RefStickerSetsOrder());
int32 insertAtIndex = 0, currentIndex = order.indexOf(s.vid.v); int32 insertAtIndex = 0, currentIndex = order.indexOf(s.vid.v);
if (currentIndex != insertAtIndex) { if (currentIndex != insertAtIndex) {
if (currentIndex > 0) { if (currentIndex > 0) {
@ -4703,7 +4705,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
order.insert(insertAtIndex, s.vid.v); order.insert(insertAtIndex, s.vid.v);
} }
StickerSets::iterator custom = sets.find(CustomStickerSetId); auto custom = sets.find(Stickers::CustomSetId);
if (custom != sets.cend()) { if (custom != sets.cend()) {
for (int32 i = 0, l = it->stickers.size(); i < l; ++i) { for (int32 i = 0, l = it->stickers.size(); i < l; ++i) {
int32 removeIndex = custom->stickers.indexOf(it->stickers.at(i)); int32 removeIndex = custom->stickers.indexOf(it->stickers.at(i));
@ -4722,26 +4724,26 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
case mtpc_updateStickerSetsOrder: { case mtpc_updateStickerSetsOrder: {
const MTPDupdateStickerSetsOrder &d(update.c_updateStickerSetsOrder()); const MTPDupdateStickerSetsOrder &d(update.c_updateStickerSetsOrder());
const QVector<MTPlong> &order(d.vorder.c_vector().v); const QVector<MTPlong> &order(d.vorder.c_vector().v);
const StickerSets &sets(cStickerSets()); const Stickers::Sets &sets(Global::StickerSets());
StickerSetsOrder result; Stickers::Order result;
for (int32 i = 0, l = order.size(); i < l; ++i) { for (int32 i = 0, l = order.size(); i < l; ++i) {
if (sets.constFind(order.at(i).v) == sets.cend()) { if (sets.constFind(order.at(i).v) == sets.cend()) {
break; break;
} }
result.push_back(order.at(i).v); result.push_back(order.at(i).v);
} }
if (result.size() != cStickerSetsOrder().size() || result.size() != order.size()) { if (result.size() != Global::StickerSetsOrder().size() || result.size() != order.size()) {
cSetLastStickersUpdate(0); Global::SetLastStickersUpdate(0);
App::main()->updateStickers(); App::main()->updateStickers();
} else { } else {
cSetStickerSetsOrder(result); Global::SetStickerSetsOrder(result);
Local::writeStickers(); Local::writeStickers();
emit stickersUpdated(); emit stickersUpdated();
} }
} break; } break;
case mtpc_updateStickerSets: { case mtpc_updateStickerSets: {
cSetLastStickersUpdate(0); Global::SetLastStickersUpdate(0);
App::main()->updateStickers(); App::main()->updateStickers();
} break; } break;

View file

@ -444,9 +444,9 @@ public:
void notify_userIsContactChanged(UserData *user, bool fromThisApp); void notify_userIsContactChanged(UserData *user, bool fromThisApp);
void notify_migrateUpdated(PeerData *peer); void notify_migrateUpdated(PeerData *peer);
void notify_clipStopperHidden(ClipStopperType type); void notify_clipStopperHidden(ClipStopperType type);
void notify_historyItemResized(const HistoryItem *row, bool scrollToIt);
void notify_historyItemLayoutChanged(const HistoryItem *item); void notify_historyItemLayoutChanged(const HistoryItem *item);
void notify_automaticLoadSettingsChangedGif(); void notify_automaticLoadSettingsChangedGif();
void notify_handlePendingHistoryUpdate();
void cmd_search(); void cmd_search();
void cmd_next_chat(); void cmd_next_chat();
@ -520,6 +520,7 @@ public slots:
void onDownloadPathSettings(); void onDownloadPathSettings();
void ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId); void ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId);
void ui_autoplayMediaInlineAsync(qint32 channelId, qint32 msgId);
private: private:

View file

@ -21,6 +21,28 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
import glob import glob
import re import re
# define some checked flag convertions
# the key flag type should be a subset of the value flag type
# with exact the same names, then the key flag can be implicitly
# casted to the value flag type
parentFlags = {};
parentFlagsList = [];
def addChildParentFlags(child, parent):
parentFlagsList.append(child);
parentFlags[child] = parent;
addChildParentFlags('MTPDmessageService', 'MTPDmessage');
addChildParentFlags('MTPDupdateShortMessage', 'MTPDmessage');
addChildParentFlags('MTPDupdateShortChatMessage', 'MTPDmessage');
addChildParentFlags('MTPDupdateShortSentMessage', 'MTPDmessage');
addChildParentFlags('MTPDreplyKeyboardHide', 'MTPDreplyKeyboardMarkup');
addChildParentFlags('MTPDreplyKeyboardForceReply', 'MTPDreplyKeyboardMarkup');
addChildParentFlags('MTPDinputPeerNotifySettings', 'MTPDpeerNotifySettings');
addChildParentFlags('MTPDpeerNotifySettings', 'MTPDinputPeerNotifySettings');
# this is a map (key flags -> map (flag name -> flag bit))
# each key flag of parentFlags should be a subset of the value flag here
parentFlagsCheck = {};
funcs = 0 funcs = 0
types = 0; types = 0;
consts = 0 consts = 0
@ -35,6 +57,7 @@ boxed = {};
funcsText = ''; funcsText = '';
typesText = ''; typesText = '';
dataTexts = ''; dataTexts = '';
creatorProxyText = '';
inlineMethods = ''; inlineMethods = '';
textSerializeInit = ''; textSerializeInit = '';
textSerializeMethods = ''; textSerializeMethods = '';
@ -150,7 +173,10 @@ with open('scheme.tl') as f:
continue; continue;
elif (ptypewide == '#'): elif (ptypewide == '#'):
hasFlags = pname; hasFlags = pname;
ptype = 'int'; if funcsNow:
ptype = 'flags<MTP' + name + '::Flags>';
else:
ptype = 'flags<MTPD' + name + '::Flags>';
else: else:
ptype = ptypewide; ptype = ptypewide;
if (ptype.find('?') >= 0): if (ptype.find('?') >= 0):
@ -195,6 +221,27 @@ with open('scheme.tl') as f:
prmsStr = []; prmsStr = [];
prmsInit = []; prmsInit = [];
prmsNames = []; prmsNames = [];
if (len(conditions)):
funcsText += '\tenum class Flag : int32 {\n';
maxbit = 0;
parentFlagsCheck['MTP' + name] = {};
for paramName in conditionsList:
funcsText += '\t\tf_' + paramName + ' = (1 << ' + conditions[paramName] + '),\n';
parentFlagsCheck['MTP' + name][paramName] = conditions[paramName];
maxbit = max(maxbit, int(conditions[paramName]));
if (maxbit > 0):
funcsText += '\n\t\tMAX_FIELD = (1 << ' + str(maxbit) + '),\n';
funcsText += '\t};\n';
funcsText += '\tQ_DECLARE_FLAGS(Flags, Flag);\n';
funcsText += '\tfriend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }\n';
funcsText += '\n';
for paramName in conditionsList:
if (paramName in trivialConditions):
funcsText += '\tbool is_' + paramName + '() const { return v' + hasFlags + '.v & Flag::f_' + paramName + '; }\n';
else:
funcsText += '\tbool has_' + paramName + '() const { return v' + hasFlags + '.v & Flag::f_' + paramName + '; }\n';
funcsText += '\n';
if (len(prms) > len(trivialConditions)): if (len(prms) > len(trivialConditions)):
for paramName in prmsList: for paramName in prmsList:
if (paramName in trivialConditions): if (paramName in trivialConditions):
@ -207,7 +254,7 @@ with open('scheme.tl') as f:
else: else:
ptypeFull = 'MTP' + paramType; ptypeFull = 'MTP' + paramType;
funcsText += '\t' + ptypeFull + ' v' + paramName + ';\n'; funcsText += '\t' + ptypeFull + ' v' + paramName + ';\n';
if (paramType in ['int', 'Int', 'bool', 'Bool']): if (paramType in ['int', 'Int', 'bool', 'Bool', 'flags<Flags>']):
prmsStr.append(ptypeFull + ' _' + paramName); prmsStr.append(ptypeFull + ' _' + paramName);
else: else:
prmsStr.append('const ' + ptypeFull + ' &_' + paramName); prmsStr.append('const ' + ptypeFull + ' &_' + paramName);
@ -218,19 +265,6 @@ with open('scheme.tl') as f:
if (len(prms) > len(trivialConditions)): if (len(prms) > len(trivialConditions)):
funcsText += '\tMTP' + name + '(' + ', '.join(prmsStr) + ') : ' + ', '.join(prmsInit) + ' {\n\t}\n'; funcsText += '\tMTP' + name + '(' + ', '.join(prmsStr) + ') : ' + ', '.join(prmsInit) + ' {\n\t}\n';
if (len(conditions)):
funcsText += '\n';
funcsText += '\tenum {\n';
for paramName in conditionsList:
funcsText += '\t\tflag_' + paramName + ' = (1 << ' + conditions[paramName] + '),\n';
funcsText += '\t};\n';
funcsText += '\n';
for paramName in conditionsList:
if (paramName in trivialConditions):
funcsText += '\tbool is_' + paramName + '() const { return v' + hasFlags + '.v & flag_' + paramName + '; }\n';
else:
funcsText += '\tbool has_' + paramName + '() const { return v' + hasFlags + '.v & flag_' + paramName + '; }\n';
funcsText += '\n'; funcsText += '\n';
funcsText += '\tuint32 innerLength() const {\n'; # count size funcsText += '\tuint32 innerLength() const {\n'; # count size
size = []; size = [];
@ -274,6 +308,8 @@ with open('scheme.tl') as f:
funcsText += '\n\ttypedef MTP' + resType + ' ResponseType;\n'; # method return type funcsText += '\n\ttypedef MTP' + resType + ' ResponseType;\n'; # method return type
funcsText += '};\n'; # class ending funcsText += '};\n'; # class ending
if (len(conditionsList)):
funcsText += 'Q_DECLARE_OPERATORS_FOR_FLAGS(MTP' + name + '::Flags)\n\n';
if (isTemplate != ''): if (isTemplate != ''):
funcsText += 'template <typename TQueryType>\n'; funcsText += 'template <typename TQueryType>\n';
funcsText += 'class MTP' + Name + ' : public MTPBoxed<MTP' + name + '<TQueryType> > {\n'; funcsText += 'class MTP' + Name + ' : public MTPBoxed<MTP' + name + '<TQueryType> > {\n';
@ -325,7 +361,9 @@ def addTextSerialize(lst, dct, dataLetter):
conditions = data[6]; conditions = data[6];
trivialConditions = data[7]; trivialConditions = data[7];
result += 'void _serialize_' + name + '(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {\n'; result += 'void _serialize_' + name + '(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {\n';
if (len(conditions)):
result += '\tMTP' + dataLetter + name + '::Flags flag(iflag);\n\n';
if (len(prms)): if (len(prms)):
result += '\tif (stage) {\n'; result += '\tif (stage) {\n';
result += '\t\tto.add(",\\n").addSpaces(lev);\n'; result += '\t\tto.add(",\\n").addSpaces(lev);\n';
@ -341,12 +379,12 @@ def addTextSerialize(lst, dct, dataLetter):
if (k == hasFlags): if (k == hasFlags):
result += 'if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; '; result += 'if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; ';
if (k in trivialConditions): if (k in trivialConditions):
result += 'if (flag & MTP' + dataLetter + name + '::flag_' + k + ') { '; result += 'if (flag & MTP' + dataLetter + name + '::Flag::f_' + k + ') { ';
result += 'to.add("YES [ BY BIT ' + conditions[k] + ' IN FIELD ' + hasFlags + ' ]"); '; result += 'to.add("YES [ BY BIT ' + conditions[k] + ' IN FIELD ' + hasFlags + ' ]"); ';
result += '} else { to.add("[ SKIPPED BY BIT ' + conditions[k] + ' IN FIELD ' + hasFlags + ' ]"); } '; result += '} else { to.add("[ SKIPPED BY BIT ' + conditions[k] + ' IN FIELD ' + hasFlags + ' ]"); } ';
else: else:
if (k in conditions): if (k in conditions):
result += 'if (flag & MTP' + dataLetter + name + '::flag_' + k + ') { '; result += 'if (flag & MTP' + dataLetter + name + '::Flag::f_' + k + ') { ';
result += 'types.push_back('; result += 'types.push_back(';
vtypeget = re.match(r'^[Vv]ector<MTP([A-Za-z0-9\._]+)>', v); vtypeget = re.match(r'^[Vv]ector<MTP([A-Za-z0-9\._]+)>', v);
if (vtypeget): if (vtypeget):
@ -383,7 +421,10 @@ def addTextSerialize(lst, dct, dataLetter):
except KeyError: except KeyError:
if (vtypeget): if (vtypeget):
result += '); vtypes.push_back('; result += '); vtypes.push_back(';
result += 'mtpc_' + restype; if (re.match(r'^flags<', restype)):
result += 'mtpc_flags';
else:
result += 'mtpc_' + restype + '+0';
if (not vtypeget): if (not vtypeget):
result += '); vtypes.push_back(0'; result += '); vtypes.push_back(0';
else: else:
@ -455,6 +496,28 @@ for restype in typesList:
creatorParamsList = []; creatorParamsList = [];
readText = ''; readText = '';
writeText = ''; writeText = '';
if (len(conditions)):
dataText += '\tenum class Flag : int32 {\n';
maxbit = 0;
parentFlagsCheck['MTPD' + name] = {};
for paramName in conditionsList:
dataText += '\t\tf_' + paramName + ' = (1 << ' + conditions[paramName] + '),\n';
parentFlagsCheck['MTPD' + name][paramName] = conditions[paramName];
maxbit = max(maxbit, int(conditions[paramName]));
if (maxbit > 0):
dataText += '\n\t\tMAX_FIELD = (1 << ' + str(maxbit) + '),\n';
dataText += '\t};\n';
dataText += '\tQ_DECLARE_FLAGS(Flags, Flag);\n';
dataText += '\tfriend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }\n';
dataText += '\n';
for paramName in conditionsList:
if (paramName in trivialConditions):
dataText += '\tbool is_' + paramName + '() const { return v' + hasFlags + '.v & Flag::f_' + paramName + '; }\n';
else:
dataText += '\tbool has_' + paramName + '() const { return v' + hasFlags + '.v & Flag::f_' + paramName + '; }\n';
dataText += '\n';
dataText += '\tMTPD' + name + '() {\n\t}\n'; # default constructor dataText += '\tMTPD' + name + '() {\n\t}\n'; # default constructor
switchLines += '\t\tcase mtpc_' + name + ': '; # for by-type-id type constructor switchLines += '\t\tcase mtpc_' + name + ': '; # for by-type-id type constructor
if (len(prms) > len(trivialConditions)): if (len(prms) > len(trivialConditions)):
@ -530,33 +593,25 @@ for restype in typesList:
sizeFast = '\treturn 0;\n'; sizeFast = '\treturn 0;\n';
switchLines += 'break;\n'; switchLines += 'break;\n';
if (len(conditions)):
dataText += '\n';
dataText += '\tenum {\n';
for paramName in conditionsList:
dataText += '\t\tflag_' + paramName + ' = (1 << ' + conditions[paramName] + '),\n';
dataText += '\t};\n';
dataText += '\n';
for paramName in conditionsList:
if (paramName in trivialConditions):
dataText += '\tbool is_' + paramName + '() const { return v' + hasFlags + '.v & flag_' + paramName + '; }\n';
else:
dataText += '\tbool has_' + paramName + '() const { return v' + hasFlags + '.v & flag_' + paramName + '; }\n';
dataText += '};\n'; # class ending dataText += '};\n'; # class ending
if (len(prms) > len(trivialConditions)): if (len(prms) > len(trivialConditions)):
dataTexts += dataText; # add data class dataTexts += dataText; # add data class
friendDecl += '\tfriend MTP' + restype + ' MTP_' + name + '(' + ', '.join(creatorParams) + ');\n'; friendDecl += '\tfriend class MTP::internal::TypeCreator;\n';
creatorsText += 'inline MTP' + restype + ' MTP_' + name + '(' + ', '.join(creatorParams) + ') {\n'; creatorProxyText += '\t\tinline static MTP' + restype + ' new_' + name + '(' + ', '.join(creatorParams) + ') {\n';
if (len(prms) > len(trivialConditions)): # creator with params if (len(prms) > len(trivialConditions)): # creator with params
creatorsText += '\treturn MTP' + restype + '(new MTPD' + name + '(' + ', '.join(creatorParamsList) + '));\n'; creatorProxyText += '\t\t\treturn MTP' + restype + '(new MTPD' + name + '(' + ', '.join(creatorParamsList) + '));\n';
else: else:
if (withType): # creator by type if (withType): # creator by type
creatorsText += '\treturn MTP' + restype + '(mtpc_' + name + ');\n'; creatorProxyText += '\t\t\treturn MTP' + restype + '(mtpc_' + name + ');\n';
else: # single creator else: # single creator
creatorsText += '\treturn MTP' + restype + '();\n'; creatorProxyText += '\t\t\treturn MTP' + restype + '();\n';
creatorProxyText += '\t\t}\n';
if (len(conditionsList)):
creatorsText += 'Q_DECLARE_OPERATORS_FOR_FLAGS(MTPD' + name + '::Flags)\n';
creatorsText += 'inline MTP' + restype + ' MTP_' + name + '(' + ', '.join(creatorParams) + ') {\n';
creatorsText += '\treturn MTP::internal::TypeCreator::new_' + name + '(' + ', '.join(creatorParamsList) + ');\n';
creatorsText += '}\n'; creatorsText += '}\n';
if (withType): if (withType):
@ -705,8 +760,19 @@ for restype in typesList:
inlineMethods += creatorsText; inlineMethods += creatorsText;
typesText += 'typedef MTPBoxed<MTP' + restype + '> MTP' + resType + ';\n'; # boxed type definition typesText += 'typedef MTPBoxed<MTP' + restype + '> MTP' + resType + ';\n'; # boxed type definition
for childName in parentFlagsList:
parentName = parentFlags[childName];
for flag in parentFlagsCheck[childName]:
if (not flag in parentFlagsCheck[parentName]):
print('Flag ' + flag + ' not found in ' + parentName + ' which should be a flags-parent of ' + childName);
error
elif (parentFlagsCheck[childName][flag] != parentFlagsCheck[parentName][flag]):
print('Flag ' + flag + ' has different value in ' + parentName + ' which should be a flags-parent of ' + childName);
error
inlineMethods += 'inline ' + parentName + '::Flags mtpCastFlags(' + childName + '::Flags flags) { return ' + parentName + '::Flags(QFlag(flags)); }\n';
# manual types added here # manual types added here
textSerializeMethods += 'void _serialize_rpc_result(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {\n'; textSerializeMethods += 'void _serialize_rpc_result(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {\n';
textSerializeMethods += '\tif (stage) {\n'; textSerializeMethods += '\tif (stage) {\n';
textSerializeMethods += '\t\tto.add(",\\n").addSpaces(lev);\n'; textSerializeMethods += '\t\tto.add(",\\n").addSpaces(lev);\n';
textSerializeMethods += '\t} else {\n'; textSerializeMethods += '\t} else {\n';
@ -721,7 +787,7 @@ textSerializeMethods += '\t}\n';
textSerializeMethods += '}\n\n'; textSerializeMethods += '}\n\n';
textSerializeInit += '\t\t_serializers.insert(mtpc_rpc_result, _serialize_rpc_result);\n'; textSerializeInit += '\t\t_serializers.insert(mtpc_rpc_result, _serialize_rpc_result);\n';
textSerializeMethods += 'void _serialize_msg_container(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {\n'; textSerializeMethods += 'void _serialize_msg_container(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {\n';
textSerializeMethods += '\tif (stage) {\n'; textSerializeMethods += '\tif (stage) {\n';
textSerializeMethods += '\t\tto.add(",\\n").addSpaces(lev);\n'; textSerializeMethods += '\t\tto.add(",\\n").addSpaces(lev);\n';
textSerializeMethods += '\t} else {\n'; textSerializeMethods += '\t} else {\n';
@ -735,7 +801,7 @@ textSerializeMethods += '\t}\n';
textSerializeMethods += '}\n\n'; textSerializeMethods += '}\n\n';
textSerializeInit += '\t\t_serializers.insert(mtpc_msg_container, _serialize_msg_container);\n'; textSerializeInit += '\t\t_serializers.insert(mtpc_msg_container, _serialize_msg_container);\n';
textSerializeMethods += 'void _serialize_core_message(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {\n'; textSerializeMethods += 'void _serialize_core_message(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {\n';
textSerializeMethods += '\tif (stage) {\n'; textSerializeMethods += '\tif (stage) {\n';
textSerializeMethods += '\t\tto.add(",\\n").addSpaces(lev);\n'; textSerializeMethods += '\t\tto.add(",\\n").addSpaces(lev);\n';
textSerializeMethods += '\t} else {\n'; textSerializeMethods += '\t} else {\n';
@ -786,12 +852,14 @@ textSerializeFull += '\t\t}\n';
textSerializeFull += '\t}\n'; textSerializeFull += '\t}\n';
textSerializeFull += '}\n'; textSerializeFull += '}\n';
out.write('\n// Creator proxy class declaration\nnamespace MTP {\nnamespace internal {\n\tclass TypeCreator;\n}\n}\n');
out.write('\n// Type id constants\nenum {\n' + ',\n'.join(enums) + '\n};\n'); out.write('\n// Type id constants\nenum {\n' + ',\n'.join(enums) + '\n};\n');
out.write('\n// Type forward declarations\n' + forwards); out.write('\n// Type forward declarations\n' + forwards);
out.write('\n// Boxed types definitions\n' + forwTypedefs); out.write('\n// Boxed types definitions\n' + forwTypedefs);
out.write('\n// Type classes definitions\n' + typesText); out.write('\n// Type classes definitions\n' + typesText);
out.write('\n// Type constructors with data\n' + dataTexts); out.write('\n// Type constructors with data\n' + dataTexts);
out.write('\n// RPC methods\n' + funcsText); out.write('\n// RPC methods\n' + funcsText);
out.write('\n// Creator proxy class definition\nnamespace MTP {\nnamespace internal {\n\tclass TypeCreator {\n\tpublic:\n' + creatorProxyText + '\t};\n}\n}\n');
out.write('\n// Inline methods definition\n' + inlineMethods); out.write('\n// Inline methods definition\n' + inlineMethods);
out.write('\n// Human-readable text serialization\nvoid mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons);\n'); out.write('\n// Human-readable text serialization\nvoid mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons);\n');
@ -819,7 +887,7 @@ outCpp.write('#include "stdafx.h"\n#include "mtpScheme.h"\n\n');
outCpp.write('typedef QVector<mtpTypeId> Types;\ntypedef QVector<int32> StagesFlags;\n\n'); outCpp.write('typedef QVector<mtpTypeId> Types;\ntypedef QVector<int32> StagesFlags;\n\n');
outCpp.write(textSerializeMethods); outCpp.write(textSerializeMethods);
outCpp.write('namespace {\n'); outCpp.write('namespace {\n');
outCpp.write('\ttypedef void(*mtpTextSerializer)(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag);\n'); outCpp.write('\ttypedef void(*mtpTextSerializer)(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag);\n');
outCpp.write('\ttypedef QMap<mtpTypeId, mtpTextSerializer> TextSerializers;\n\tTextSerializers _serializers;\n\n'); outCpp.write('\ttypedef QMap<mtpTypeId, mtpTextSerializer> TextSerializers;\n\tTextSerializers _serializers;\n\n');
outCpp.write('\tvoid initTextSerializers() {\n'); outCpp.write('\tvoid initTextSerializers() {\n');
outCpp.write(textSerializeInit); outCpp.write(textSerializeInit);

View file

@ -158,6 +158,17 @@ namespace MTP {
QReadWriteLock *dcOptionsMutex(); QReadWriteLock *dcOptionsMutex();
struct DcOption {
DcOption(int id, MTPDdcOption::Flags flags, const string &ip, int port) : id(id), flags(flags), ip(ip), port(port) {
}
int id;
MTPDdcOption::Flags flags;
string ip;
int port;
};
typedef QMap<int, DcOption> DcOptions;
}; };
#include "mtproto/mtpSessionImpl.h" #include "mtproto/mtpSessionImpl.h"

View file

@ -660,7 +660,7 @@ MTPautoConnection::MTPautoConnection(QThread *thread) : MTPabstractTcpConnection
void MTPautoConnection::onHttpStart() { void MTPautoConnection::onHttpStart() {
if (status == HttpReady) { if (status == HttpReady) {
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by timer").arg((_flagsHttp & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by timer").arg((_flagsHttp & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
status = UsingHttp; status = UsingHttp;
sock.disconnectFromHost(); sock.disconnectFromHost();
emit connected(); emit connected();
@ -671,7 +671,7 @@ void MTPautoConnection::onSocketConnected() {
if (status == HttpReady || status == WaitingBoth || status == WaitingTcp) { if (status == HttpReady || status == WaitingBoth || status == WaitingTcp) {
mtpBuffer buffer(_preparePQFake(tcpNonce)); mtpBuffer buffer(_preparePQFake(tcpNonce));
DEBUG_LOG(("Connection Info: sending fake req_pq through TCP/%1 transport").arg((_flagsTcp & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: sending fake req_pq through TCP/%1 transport").arg((_flagsTcp & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
if (_tcpTimeout < 0) _tcpTimeout = -_tcpTimeout; if (_tcpTimeout < 0) _tcpTimeout = -_tcpTimeout;
tcpTimeoutTimer.start(_tcpTimeout); tcpTimeoutTimer.start(_tcpTimeout);
@ -709,7 +709,7 @@ void MTPautoConnection::onSocketDisconnected() {
} else if (status == WaitingTcp || status == UsingTcp) { } else if (status == WaitingTcp || status == UsingTcp) {
emit disconnected(); emit disconnected();
} else if (status == HttpReady) { } else if (status == HttpReady) {
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by socket disconnect").arg((_flagsHttp & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by socket disconnect").arg((_flagsHttp & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
status = UsingHttp; status = UsingHttp;
emit connected(); emit connected();
} }
@ -801,7 +801,7 @@ void MTPautoConnection::disconnectFromServer() {
httpStartTimer.stop(); httpStartTimer.stop();
} }
void MTPautoConnection::connectTcp(const QString &addr, int32 port, int32 flags) { void MTPautoConnection::connectTcp(const QString &addr, int32 port, MTPDdcOption::Flags flags) {
_addrTcp = addr; _addrTcp = addr;
_portTcp = port; _portTcp = port;
_flagsTcp = flags; _flagsTcp = flags;
@ -810,8 +810,8 @@ void MTPautoConnection::connectTcp(const QString &addr, int32 port, int32 flags)
sock.connectToHost(QHostAddress(_addrTcp), _portTcp); sock.connectToHost(QHostAddress(_addrTcp), _portTcp);
} }
void MTPautoConnection::connectHttp(const QString &addr, int32 port, int32 flags) { void MTPautoConnection::connectHttp(const QString &addr, int32 port, MTPDdcOption::Flags flags) {
address = QUrl(((flags & MTPDdcOption::flag_ipv6) ? qsl("http://[%1]:%2/api") : qsl("http://%1:%2/api")).arg(addr).arg(80));//not p - always 80 port for http transport address = QUrl(((flags & MTPDdcOption::Flag::f_ipv6) ? qsl("http://[%1]:%2/api") : qsl("http://%1:%2/api")).arg(addr).arg(80));//not p - always 80 port for http transport
TCP_LOG(("HTTP Info: address is %1").arg(address.toDisplayString())); TCP_LOG(("HTTP Info: address is %1").arg(address.toDisplayString()));
connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*))); connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
@ -821,7 +821,7 @@ void MTPautoConnection::connectHttp(const QString &addr, int32 port, int32 flags
mtpBuffer buffer(_preparePQFake(httpNonce)); mtpBuffer buffer(_preparePQFake(httpNonce));
DEBUG_LOG(("Connection Info: sending fake req_pq through HTTP/%1 transport").arg((_flagsHttp & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: sending fake req_pq through HTTP/%1 transport").arg((_flagsHttp & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
httpSend(buffer); httpSend(buffer);
} }
@ -857,7 +857,7 @@ void MTPautoConnection::requestFinished(QNetworkReply *reply) {
status = HttpReady; status = HttpReady;
httpStartTimer.start(MTPTcpConnectionWaitTimeout); httpStartTimer.start(MTPTcpConnectionWaitTimeout);
} else { } else {
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by pq-response, awaited").arg((_flagsHttp & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by pq-response, awaited").arg((_flagsHttp & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
status = UsingHttp; status = UsingHttp;
sock.disconnectFromHost(); sock.disconnectFromHost();
emit connected(); emit connected();
@ -900,7 +900,7 @@ void MTPautoConnection::socketPacket(const char *packet, uint32 length) {
status = WaitingHttp; status = WaitingHttp;
sock.disconnectFromHost(); sock.disconnectFromHost();
} else if (status == HttpReady) { } else if (status == HttpReady) {
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by bad tcp response, ready").arg((_flagsHttp & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by bad tcp response, ready").arg((_flagsHttp & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
status = UsingHttp; status = UsingHttp;
sock.disconnectFromHost(); sock.disconnectFromHost();
emit connected(); emit connected();
@ -919,7 +919,7 @@ void MTPautoConnection::socketPacket(const char *packet, uint32 length) {
MTPResPQ res_pq = _readPQFakeReply(data); MTPResPQ res_pq = _readPQFakeReply(data);
const MTPDresPQ &res_pq_data(res_pq.c_resPQ()); const MTPDresPQ &res_pq_data(res_pq.c_resPQ());
if (res_pq_data.vnonce == tcpNonce) { if (res_pq_data.vnonce == tcpNonce) {
DEBUG_LOG(("Connection Info: TCP/%1-transport chosen by pq-response").arg((_flagsTcp & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: TCP/%1-transport chosen by pq-response").arg((_flagsTcp & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
status = UsingTcp; status = UsingTcp;
emit connected(); emit connected();
} }
@ -929,7 +929,7 @@ void MTPautoConnection::socketPacket(const char *packet, uint32 length) {
status = WaitingHttp; status = WaitingHttp;
sock.disconnectFromHost(); sock.disconnectFromHost();
} else if (status == HttpReady) { } else if (status == HttpReady) {
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by bad tcp response, awaited").arg((_flagsHttp & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by bad tcp response, awaited").arg((_flagsHttp & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
status = UsingHttp; status = UsingHttp;
sock.disconnectFromHost(); sock.disconnectFromHost();
emit connected(); emit connected();
@ -969,7 +969,7 @@ void MTPautoConnection::socketError(QAbstractSocket::SocketError e) {
if (status == WaitingBoth) { if (status == WaitingBoth) {
status = WaitingHttp; status = WaitingHttp;
} else if (status == HttpReady) { } else if (status == HttpReady) {
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by tcp error, ready").arg((_flagsHttp & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by tcp error, ready").arg((_flagsHttp & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
status = UsingHttp; status = UsingHttp;
emit connected(); emit connected();
} else if (status == WaitingTcp || status == UsingTcp) { } else if (status == WaitingTcp || status == UsingTcp) {
@ -998,7 +998,7 @@ void MTPtcpConnection::onSocketConnected() {
if (status == WaitingTcp) { if (status == WaitingTcp) {
mtpBuffer buffer(_preparePQFake(tcpNonce)); mtpBuffer buffer(_preparePQFake(tcpNonce));
DEBUG_LOG(("Connection Info: sending fake req_pq through TCP/%1 transport").arg((_flags & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: sending fake req_pq through TCP/%1 transport").arg((_flags & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
if (_tcpTimeout < 0) _tcpTimeout = -_tcpTimeout; if (_tcpTimeout < 0) _tcpTimeout = -_tcpTimeout;
tcpTimeoutTimer.start(_tcpTimeout); tcpTimeoutTimer.start(_tcpTimeout);
@ -1083,7 +1083,7 @@ void MTPtcpConnection::disconnectFromServer() {
sock.close(); sock.close();
} }
void MTPtcpConnection::connectTcp(const QString &addr, int32 port, int32 flags) { void MTPtcpConnection::connectTcp(const QString &addr, int32 port, MTPDdcOption::Flags flags) {
_addr = addr; _addr = addr;
_port = port; _port = port;
_flags = flags; _flags = flags;
@ -1108,7 +1108,7 @@ void MTPtcpConnection::socketPacket(const char *packet, uint32 length) {
MTPResPQ res_pq = _readPQFakeReply(data); MTPResPQ res_pq = _readPQFakeReply(data);
const MTPDresPQ &res_pq_data(res_pq.c_resPQ()); const MTPDresPQ &res_pq_data(res_pq.c_resPQ());
if (res_pq_data.vnonce == tcpNonce) { if (res_pq_data.vnonce == tcpNonce) {
DEBUG_LOG(("Connection Info: TCP/%1-transport chosen by pq-response").arg((_flags & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: TCP/%1-transport chosen by pq-response").arg((_flags & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
status = UsingTcp; status = UsingTcp;
emit connected(); emit connected();
} }
@ -1180,8 +1180,8 @@ void MTPhttpConnection::disconnectFromServer() {
address = QUrl(); address = QUrl();
} }
void MTPhttpConnection::connectHttp(const QString &addr, int32 p, int32 flags) { void MTPhttpConnection::connectHttp(const QString &addr, int32 p, MTPDdcOption::Flags flags) {
address = QUrl(((flags & MTPDdcOption::flag_ipv6) ? qsl("http://[%1]:%2/api") : qsl("http://%1:%2/api")).arg(addr).arg(80));//not p - always 80 port for http transport address = QUrl(((flags & MTPDdcOption::Flag::f_ipv6) ? qsl("http://[%1]:%2/api") : qsl("http://%1:%2/api")).arg(addr).arg(80));//not p - always 80 port for http transport
TCP_LOG(("HTTP Info: address is %1").arg(address.toDisplayString())); TCP_LOG(("HTTP Info: address is %1").arg(address.toDisplayString()));
connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*))); connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
@ -1189,7 +1189,7 @@ void MTPhttpConnection::connectHttp(const QString &addr, int32 p, int32 flags) {
mtpBuffer buffer(_preparePQFake(httpNonce)); mtpBuffer buffer(_preparePQFake(httpNonce));
DEBUG_LOG(("Connection Info: sending fake req_pq through HTTP/%1 transport").arg((flags & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: sending fake req_pq through HTTP/%1 transport").arg((flags & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
sendData(buffer); sendData(buffer);
} }
@ -1217,7 +1217,7 @@ void MTPhttpConnection::requestFinished(QNetworkReply *reply) {
MTPResPQ res_pq = _readPQFakeReply(data); MTPResPQ res_pq = _readPQFakeReply(data);
const MTPDresPQ &res_pq_data(res_pq.c_resPQ()); const MTPDresPQ &res_pq_data(res_pq.c_resPQ());
if (res_pq_data.vnonce == httpNonce) { if (res_pq_data.vnonce == httpNonce) {
DEBUG_LOG(("Connection Info: HTTP/%1-transport connected by pq-response").arg((_flags & MTPDdcOption::flag_ipv6) ? "IPv6" : "IPv4")); DEBUG_LOG(("Connection Info: HTTP/%1-transport connected by pq-response").arg((_flags & MTPDdcOption::Flag::f_ipv6) ? "IPv6" : "IPv4"));
status = UsingHttp; status = UsingHttp;
emit connected(); emit connected();
} }
@ -1354,7 +1354,7 @@ MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConne
if (!dc) { if (!dc) {
QReadLocker lock(mtpDcOptionsMutex()); QReadLocker lock(mtpDcOptionsMutex());
const mtpDcOptions &options(cDcOptions()); const MTP::DcOptions &options(Global::DcOptions());
if (options.isEmpty()) { if (options.isEmpty()) {
LOG(("MTP Error: connect failed, no DCs")); LOG(("MTP Error: connect failed, no DCs"));
dc = 0; dc = 0;
@ -1994,36 +1994,36 @@ void MTProtoConnectionPrivate::socketStart(bool afterConfig) {
static const int IPv4address = 0, IPv6address = 1; static const int IPv4address = 0, IPv6address = 1;
static const int TcpProtocol = 0, HttpProtocol = 1; static const int TcpProtocol = 0, HttpProtocol = 1;
int32 flags[2][2] = { { 0 } }; MTPDdcOption::Flags flags[2][2] = { { 0 } };
string ip[2][2]; string ip[2][2];
uint32 port[2][2] = { { 0 } }; uint32 port[2][2] = { { 0 } };
{ {
QReadLocker lock(mtpDcOptionsMutex()); QReadLocker lock(mtpDcOptionsMutex());
const mtpDcOptions &options(cDcOptions()); const MTP::DcOptions &options(Global::DcOptions());
int32 shifts[2][2][4] = { int32 shifts[2][2][4] = {
{ // IPv4 { // IPv4
{ // TCP IPv4 { // TCP IPv4
isDldDc ? (MTPDdcOption::flag_media_only | MTPDdcOption::flag_tcpo_only) : -1, isDldDc ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_tcpo_only) : -1,
MTPDdcOption::flag_tcpo_only, qFlags(MTPDdcOption::Flag::f_tcpo_only),
isDldDc ? (MTPDdcOption::flag_media_only) : -1, isDldDc ? qFlags(MTPDdcOption::Flag::f_media_only) : -1,
0 0
}, { // HTTP IPv4 }, { // HTTP IPv4
-1, -1,
-1, -1,
isDldDc ? (MTPDdcOption::flag_media_only) : -1, isDldDc ? qFlags(MTPDdcOption::Flag::f_media_only) : -1,
0 0
}, },
}, { // IPv6 }, { // IPv6
{ // TCP IPv6 { // TCP IPv6
isDldDc ? (MTPDdcOption::flag_media_only | MTPDdcOption::flag_tcpo_only | MTPDdcOption::flag_ipv6) : -1, isDldDc ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6) : -1,
MTPDdcOption::flag_tcpo_only | MTPDdcOption::flag_ipv6, MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6,
isDldDc ? (MTPDdcOption::flag_media_only | MTPDdcOption::flag_ipv6) : -1, isDldDc ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6) : -1,
MTPDdcOption::flag_ipv6 qFlags(MTPDdcOption::Flag::f_ipv6)
}, { // HTTP IPv6 }, { // HTTP IPv6
-1, -1,
-1, -1,
isDldDc ? (MTPDdcOption::flag_media_only | MTPDdcOption::flag_ipv6) : -1, isDldDc ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6) : -1,
MTPDdcOption::flag_ipv6 qFlags(MTPDdcOption::Flag::f_ipv6)
}, },
}, },
}; };
@ -2033,7 +2033,7 @@ void MTProtoConnectionPrivate::socketStart(bool afterConfig) {
int32 mask = shifts[address][protocol][shift]; int32 mask = shifts[address][protocol][shift];
if (mask < 0) continue; if (mask < 0) continue;
mtpDcOptions::const_iterator index = options.constFind(baseDc + _mtp_internal::dcShift * mask); auto index = options.constFind(baseDc + _mtp_internal::dcShift * mask);
if (index != options.cend()) { if (index != options.cend()) {
ip[address][protocol] = index->ip; ip[address][protocol] = index->ip;
flags[address][protocol] = index->flags; flags[address][protocol] = index->flags;

View file

@ -115,8 +115,8 @@ public:
virtual void sendData(mtpBuffer &buffer) = 0; // has size + 3, buffer[0] = len, buffer[1] = packetnum, buffer[last] = crc32 virtual void sendData(mtpBuffer &buffer) = 0; // has size + 3, buffer[0] = len, buffer[1] = packetnum, buffer[last] = crc32
virtual void disconnectFromServer() = 0; virtual void disconnectFromServer() = 0;
virtual void connectTcp(const QString &addr, int32 port, int32 flags) = 0; virtual void connectTcp(const QString &addr, int32 port, MTPDdcOption::Flags flags) = 0;
virtual void connectHttp(const QString &addr, int32 port, int32 flags) = 0; virtual void connectHttp(const QString &addr, int32 port, MTPDdcOption::Flags flags) = 0;
virtual bool isConnected() const = 0; virtual bool isConnected() const = 0;
virtual bool usingHttpWait() { virtual bool usingHttpWait() {
return false; return false;
@ -182,17 +182,17 @@ public:
MTPautoConnection(QThread *thread); MTPautoConnection(QThread *thread);
void sendData(mtpBuffer &buffer); void sendData(mtpBuffer &buffer) override;
void disconnectFromServer(); void disconnectFromServer() override;
void connectTcp(const QString &addr, int32 port, int32 flags); void connectTcp(const QString &addr, int32 port, MTPDdcOption::Flags flags) override;
void connectHttp(const QString &addr, int32 port, int32 flags); void connectHttp(const QString &addr, int32 port, MTPDdcOption::Flags flags) override;
bool isConnected() const; bool isConnected() const override;
bool usingHttpWait(); bool usingHttpWait() override;
bool needHttpWait(); bool needHttpWait() override;
int32 debugState() const; int32 debugState() const override;
QString transport() const; QString transport() const override;
public slots: public slots:
@ -233,7 +233,8 @@ private:
Requests requests; Requests requests;
QString _addrTcp, _addrHttp; QString _addrTcp, _addrHttp;
int32 _portTcp, _portHttp, _flagsTcp, _flagsHttp; int32 _portTcp, _portHttp;
MTPDdcOption::Flags _flagsTcp, _flagsHttp;
int32 _tcpTimeout; int32 _tcpTimeout;
QTimer tcpTimeoutTimer; QTimer tcpTimeoutTimer;
@ -246,16 +247,16 @@ public:
MTPtcpConnection(QThread *thread); MTPtcpConnection(QThread *thread);
void sendData(mtpBuffer &buffer); void sendData(mtpBuffer &buffer) override;
void disconnectFromServer(); void disconnectFromServer() override;
void connectTcp(const QString &addr, int32 port, int32 flags); void connectTcp(const QString &addr, int32 port, MTPDdcOption::Flags flags) override;
void connectHttp(const QString &addr, int32 port, int32 flags) { // not supported void connectHttp(const QString &addr, int32 port, MTPDdcOption::Flags flags) override { // not supported
} }
bool isConnected() const; bool isConnected() const override;
int32 debugState() const; int32 debugState() const override;
QString transport() const; QString transport() const override;
public slots: public slots:
@ -281,7 +282,8 @@ private:
MTPint128 tcpNonce; MTPint128 tcpNonce;
QString _addr; QString _addr;
int32 _port, _tcpTimeout, _flags; int32 _port, _tcpTimeout;
MTPDdcOption::Flags _flags;
QTimer tcpTimeoutTimer; QTimer tcpTimeoutTimer;
}; };
@ -293,18 +295,18 @@ public:
MTPhttpConnection(QThread *thread); MTPhttpConnection(QThread *thread);
void sendData(mtpBuffer &buffer); void sendData(mtpBuffer &buffer) override;
void disconnectFromServer(); void disconnectFromServer() override;
void connectTcp(const QString &addr, int32 port, int32 flags) { // not supported void connectTcp(const QString &addr, int32 port, MTPDdcOption::Flags flags) override { // not supported
} }
void connectHttp(const QString &addr, int32 port, int32 flags); void connectHttp(const QString &addr, int32 port, MTPDdcOption::Flags flags) override;
bool isConnected() const; bool isConnected() const override;
bool usingHttpWait(); bool usingHttpWait() override;
bool needHttpWait(); bool needHttpWait() override;
int32 debugState() const; int32 debugState() const override;
QString transport() const; QString transport() const override;
public slots: public slots:
@ -319,7 +321,7 @@ private:
}; };
Status status; Status status;
MTPint128 httpNonce; MTPint128 httpNonce;
int32 _flags; MTPDdcOption::Flags _flags;
QNetworkAccessManager manager; QNetworkAccessManager manager;
QUrl address; QUrl address;

View file

@ -149,13 +149,13 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
} }
} }
const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(MTP_int(0), MTP_vector<MTPKeyboardButtonRow>(0)); const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(MTP_flags(MTPDreplyKeyboardMarkup::Flags(0)), MTP_vector<MTPKeyboardButtonRow>(0));
const MTPVector<MTPMessageEntity> MTPnullEntities = MTP_vector<MTPMessageEntity>(0); const MTPVector<MTPMessageEntity> MTPnullEntities = MTP_vector<MTPMessageEntity>(0);
const MTPMessageFwdHeader MTPnullFwdHeader = MTP_messageFwdHeader(MTPint(), MTPint(), MTPint(), MTPint(), MTPint()); const MTPMessageFwdHeader MTPnullFwdHeader = MTP_messageFwdHeader(MTP_flags(MTPDmessageFwdHeader::Flags(0)), MTPint(), MTPint(), MTPint(), MTPint());
QString stickerSetTitle(const MTPDstickerSet &s) { QString stickerSetTitle(const MTPDstickerSet &s) {
QString title = qs(s.vtitle); QString title = qs(s.vtitle);
if ((s.vflags.v & MTPDstickerSet::flag_official) && !title.compare(qstr("Great Minds"), Qt::CaseInsensitive)) { if ((s.vflags.v & MTPDstickerSet::Flag::f_official) && !title.compare(qstr("Great Minds"), Qt::CaseInsensitive)) {
return lang(lng_stickers_default_set); return lang(lng_stickers_default_set);
} }
return title; return title;

View file

@ -346,6 +346,7 @@ enum {
mtpc_gzip_packed = 0x3072cfa1 mtpc_gzip_packed = 0x3072cfa1
}; };
static const mtpTypeId mtpc_bytes = mtpc_string; static const mtpTypeId mtpc_bytes = mtpc_string;
static const mtpTypeId mtpc_flags = mtpc_int;
static const mtpTypeId mtpc_core_message = -1; // undefined type, but is used static const mtpTypeId mtpc_core_message = -1; // undefined type, but is used
static const mtpTypeId mtpLayers[] = { static const mtpTypeId mtpLayers[] = {
mtpTypeId(mtpc_invokeWithLayer1), mtpTypeId(mtpc_invokeWithLayer1),
@ -446,6 +447,49 @@ inline MTPint MTP_int(int32 v) {
} }
typedef MTPBoxed<MTPint> MTPInt; typedef MTPBoxed<MTPint> MTPInt;
template <typename Flags>
class MTPflags {
public:
Flags v;
static_assert(sizeof(Flags) == sizeof(int32), "MTPflags are allowed only wrapping int32 flag types!");
MTPflags() {
}
MTPflags(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_flags) {
read(from, end, cons);
}
uint32 innerLength() const {
return sizeof(Flags);
}
mtpTypeId type() const {
return mtpc_flags;
}
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_flags) {
if (from + 1 > end) throw mtpErrorInsufficient();
if (cons != mtpc_flags) throw mtpErrorUnexpected(cons, "MTPflags");
v = static_cast<Flags>(*(from++));
}
void write(mtpBuffer &to) const {
to.push_back(static_cast<mtpPrime>(v));
}
private:
explicit MTPflags(Flags val) : v(val) {
}
template <typename T>
friend MTPflags<T> MTP_flags(T v);
};
template <typename T>
inline MTPflags<T> MTP_flags(T v) {
return MTPflags<T>(v);
}
template <typename Flags>
using MTPFlags = MTPBoxed<MTPflags<Flags>>;
inline bool operator==(const MTPint &a, const MTPint &b) { inline bool operator==(const MTPint &a, const MTPint &b) {
return a.v == b.v; return a.v == b.v;
} }
@ -871,19 +915,7 @@ inline MTPvector<T> MTP_vector(const QVector<T> &v) {
return MTPvector<T>(new MTPDvector<T>(v)); return MTPvector<T>(new MTPDvector<T>(v));
} }
template <typename T> template <typename T>
class MTPVector : public MTPBoxed<MTPvector<T> > { using MTPVector = MTPBoxed<MTPvector<T>>;
public:
MTPVector() {
}
MTPVector(uint32 count) : MTPBoxed<MTPvector<T> >(MTP_vector<T>(count)) {
}
MTPVector(uint32 count, const T &value) : MTPBoxed<MTPvector<T> >(MTP_vector<T>(count, value)) {
}
MTPVector(const MTPvector<T> &v) : MTPBoxed<MTPvector<T> >(v) {
}
MTPVector(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPvector<T> >(from, end, cons) {
}
};
template <typename T> template <typename T>
inline bool operator==(const MTPvector<T> &a, const MTPvector<T> &b) { inline bool operator==(const MTPvector<T> &a, const MTPvector<T> &b) {
@ -977,13 +1009,71 @@ inline bool mtpIsFalse(const MTPBool &v) {
return !mtpIsTrue(v); return !mtpIsTrue(v);
} }
enum { // client side flags #define CHECK_MTP_SCHEME_AND_CLIENT_FLAGS_CONFLICT(Type) \
MTPDmessage_flag_HAS_TEXT_LINKS = (1 << 31), // message has links for "shared links" indexing
MTPDmessage_flag_IS_GROUP_MIGRATE = (1 << 30), // message is a group migrate (group -> supergroup) service message // we must validate that MTProto scheme flags don't intersect with client side flags
MTPDreplyKeyboardMarkup_flag_FORCE_REPLY = (1 << 30), // markup just wants a text reply // and define common bit operators which allow use Type_ClientFlag together with Type::Flag
MTPDreplyKeyboardMarkup_flag_ZERO = (1 << 31), // none (zero) markup #define DEFINE_MTP_CLIENT_FLAGS(Type) \
MTPDstickerSet_flag_NOT_LOADED = (1 << 31), // sticker set is not yet loaded static_assert(static_cast<int32>(Type::Flag::MAX_FIELD) < static_cast<int32>(Type##_ClientFlag::MIN_FIELD), \
"MTProto flags conflict with client side flags!"); \
inline Type::Flags qFlags(Type##_ClientFlag v) { return Type::Flags(static_cast<int32>(v)); } \
inline Type::Flags operator&(Type::Flags i, Type##_ClientFlag v) { return i & qFlags(v); } \
inline Type::Flags operator&(Type::Flag i, Type##_ClientFlag v) { return qFlags(i) & v; } \
inline Type::Flags operator&(Type##_ClientFlag i, Type##_ClientFlag v) { return qFlags(i) & v; } \
inline Type::Flags operator&(Type##_ClientFlag i, Type::Flag v) { return qFlags(i) & v; } \
inline Type::Flags &operator&=(Type::Flags &i, Type##_ClientFlag v) { return i &= qFlags(v); } \
inline Type::Flags operator|(Type::Flags i, Type##_ClientFlag v) { return i | qFlags(v); } \
inline Type::Flags operator|(Type::Flag i, Type##_ClientFlag v) { return qFlags(i) | v; } \
inline Type::Flags operator|(Type##_ClientFlag i, Type##_ClientFlag v) { return qFlags(i) | v; } \
inline Type::Flags operator|(Type##_ClientFlag i, Type::Flag v) { return qFlags(i) | v; } \
inline Type::Flags &operator|=(Type::Flags &i, Type##_ClientFlag v) { return i |= qFlags(v); } \
inline Type::Flags operator~(Type##_ClientFlag v) { return ~qFlags(v); }
// we use the same flags field for some additional client side flags
enum class MTPDmessage_ClientFlag : int32 {
// message has links for "shared links" indexing
f_has_text_links = (1 << 30),
// message is a group migrate (group -> supergroup) service message
f_is_group_migrate = (1 << 29),
// message needs initDimensions() + resize() + paint()
f_pending_init_dimensions = (1 << 28),
// message needs resize() + paint()
f_pending_resize = (1 << 27),
// message needs paint()
f_pending_paint = (1 << 26),
// update this when adding new client side flags
MIN_FIELD = (1 << 26),
}; };
DEFINE_MTP_CLIENT_FLAGS(MTPDmessage)
enum class MTPDreplyKeyboardMarkup_ClientFlag : int32 {
// none (zero) markup
f_zero = (1 << 30),
// markup just wants a text reply
f_force_reply = (1 << 29),
// update this when adding new client side flags
MIN_FIELD = (1 << 29),
};
DEFINE_MTP_CLIENT_FLAGS(MTPDreplyKeyboardMarkup)
enum class MTPDstickerSet_ClientFlag : int32 {
// old value for sticker set is not yet loaded flag
f_not_loaded__old = (1 << 31),
// sticker set is not yet loaded
f_not_loaded = (1 << 30),
// update this when adding new client side flags
MIN_FIELD = (1 << 30),
};
DEFINE_MTP_CLIENT_FLAGS(MTPDstickerSet)
extern const MTPReplyMarkup MTPnullMarkup; extern const MTPReplyMarkup MTPnullMarkup;
extern const MTPVector<MTPMessageEntity> MTPnullEntities; extern const MTPVector<MTPMessageEntity> MTPnullEntities;

View file

@ -185,28 +185,28 @@ namespace {
void mtpUpdateDcOptions(const QVector<MTPDcOption> &options) { void mtpUpdateDcOptions(const QVector<MTPDcOption> &options) {
QSet<int32> already, restart; QSet<int32> already, restart;
{ {
mtpDcOptions opts; MTP::DcOptions opts;
{ {
QReadLocker lock(mtpDcOptionsMutex()); QReadLocker lock(mtpDcOptionsMutex());
opts = cDcOptions(); opts = Global::DcOptions();
} }
for (QVector<MTPDcOption>::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) { for (QVector<MTPDcOption>::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) {
const MTPDdcOption &optData(i->c_dcOption()); const MTPDdcOption &optData(i->c_dcOption());
int32 id = optData.vid.v, idWithShift = id + (optData.vflags.v * _mtp_internal::dcShift); int32 id = optData.vid.v, idWithShift = id + (optData.vflags.v * _mtp_internal::dcShift);
if (already.constFind(idWithShift) == already.cend()) { if (already.constFind(idWithShift) == already.cend()) {
already.insert(idWithShift); already.insert(idWithShift);
mtpDcOptions::const_iterator a = opts.constFind(idWithShift); auto a = opts.constFind(idWithShift);
if (a != opts.cend()) { if (a != opts.cend()) {
if (a.value().ip != optData.vip_address.c_string().v || a.value().port != optData.vport.v) { if (a.value().ip != optData.vip_address.c_string().v || a.value().port != optData.vport.v) {
restart.insert(id); restart.insert(id);
} }
} }
opts.insert(idWithShift, mtpDcOption(id, optData.vflags.v, optData.vip_address.c_string().v, optData.vport.v)); opts.insert(idWithShift, MTP::DcOption(id, optData.vflags.v, optData.vip_address.c_string().v, optData.vport.v));
} }
} }
{ {
QWriteLocker lock(mtpDcOptionsMutex()); QWriteLocker lock(mtpDcOptionsMutex());
cSetDcOptions(opts); Global::SetDcOptions(opts);
} }
} }
for (QSet<int32>::const_iterator i = restart.cbegin(), e = restart.cend(); i != e; ++i) { for (QSet<int32>::const_iterator i = restart.cbegin(), e = restart.cend(); i != e; ++i) {
@ -261,8 +261,8 @@ void MTProtoConfigLoader::enumDC() {
OrderedSet<int32> dcs; OrderedSet<int32> dcs;
{ {
QReadLocker lock(mtpDcOptionsMutex()); QReadLocker lock(mtpDcOptionsMutex());
const mtpDcOptions &options(cDcOptions()); const MTP::DcOptions &options(Global::DcOptions());
for (mtpDcOptions::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) { for (auto i = options.cbegin(), e = options.cend(); i != e; ++i) {
dcs.insert(i.key() % _mtp_internal::dcShift); dcs.insert(i.key() % _mtp_internal::dcShift);
} }
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -778,14 +778,20 @@ void OverviewInner::preloadMore() {
if (!_searchRequest) { if (!_searchRequest) {
MTPmessagesFilter filter = (_type == OverviewLinks) ? MTP_inputMessagesFilterUrl() : MTP_inputMessagesFilterDocument(); MTPmessagesFilter filter = (_type == OverviewLinks) ? MTP_inputMessagesFilterUrl() : MTP_inputMessagesFilterDocument();
if (!_searchFull) { if (!_searchFull) {
int32 flags = (_history->peer->isChannel() && !_history->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; MTPmessages_Search::Flags flags = 0;
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _history->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchId ? SearchFromOffset : SearchFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchId ? SearchFromOffset : SearchFromStart)); if (_history->peer->isChannel() && !_history->peer->isMegagroup()) {
flags |= MTPmessages_Search::Flag::f_important_only;
}
_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _history->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchId ? SearchFromOffset : SearchFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchId ? SearchFromOffset : SearchFromStart));
if (!_lastSearchId) { if (!_lastSearchId) {
_searchQueries.insert(_searchRequest, _searchQuery); _searchQueries.insert(_searchRequest, _searchQuery);
} }
} else if (_migrated && !_searchFullMigrated) { } else if (_migrated && !_searchFullMigrated) {
int32 flags = (_migrated->peer->isChannel() && !_migrated->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; MTPmessages_Search::Flags flags = 0;
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _migrated->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchMigratedId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart)); if (_migrated->peer->isChannel() && !_migrated->peer->isMegagroup()) {
flags |= MTPmessages_Search::Flag::f_important_only;
}
_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _migrated->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchMigratedId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart));
} }
} }
} else if (App::main()) { } else if (App::main()) {
@ -1530,9 +1536,12 @@ bool OverviewInner::onSearchMessages(bool searchCache) {
} else if (_searchQuery != q) { } else if (_searchQuery != q) {
_searchQuery = q; _searchQuery = q;
_searchFull = _searchFullMigrated = false; _searchFull = _searchFullMigrated = false;
int32 flags = (_history->peer->isChannel() && !_history->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; MTPmessages_Search::Flags flags = 0;
if (_history->peer->isChannel() && !_history->peer->isMegagroup()) {
flags |= MTPmessages_Search::Flag::f_important_only;
}
MTPmessagesFilter filter = (_type == OverviewLinks) ? MTP_inputMessagesFilterUrl() : MTP_inputMessagesFilterDocument(); MTPmessagesFilter filter = (_type == OverviewLinks) ? MTP_inputMessagesFilterUrl() : MTP_inputMessagesFilterDocument();
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _history->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, SearchFromStart), rpcFail(&OverviewInner::searchFailed, SearchFromStart)); _searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _history->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, SearchFromStart), rpcFail(&OverviewInner::searchFailed, SearchFromStart));
_searchQueries.insert(_searchRequest, _searchQuery); _searchQueries.insert(_searchRequest, _searchQuery);
} }
return false; return false;
@ -2386,7 +2395,6 @@ void OverviewWidget::onDeleteSelectedSure() {
for (SelectedItemSet::const_iterator i = sel.cbegin(), e = sel.cend(); i != e; ++i) { for (SelectedItemSet::const_iterator i = sel.cbegin(), e = sel.cend(); i != e; ++i) {
i.value()->destroy(); i.value()->destroy();
} }
Notify::historyItemsResized();
Ui::hideLayer(); Ui::hideLayer();
for (QMap<PeerData*, QVector<MTPint> >::const_iterator i = ids.cbegin(), e = ids.cend(); i != e; ++i) { for (QMap<PeerData*, QVector<MTPint> >::const_iterator i = ids.cbegin(), e = ids.cend(); i != e; ++i) {
@ -2408,7 +2416,6 @@ void OverviewWidget::onDeleteContextSure() {
App::main()->checkPeerHistory(h->peer); App::main()->checkPeerHistory(h->peer);
} }
Notify::historyItemsResized();
Ui::hideLayer(); Ui::hideLayer();
if (wasOnServer) { if (wasOnServer) {

View file

@ -28,8 +28,6 @@ Qt::LayoutDirection gLangDir = gRtl ? Qt::RightToLeft : Qt::LeftToRight;
QString gArguments; QString gArguments;
mtpDcOptions gDcOptions;
bool gDevVersion = DevVersion; bool gDevVersion = DevVersion;
uint64 gBetaVersion = BETA_VERSION; uint64 gBetaVersion = BETA_VERSION;
uint64 gRealBetaVersion = BETA_VERSION; uint64 gRealBetaVersion = BETA_VERSION;
@ -110,9 +108,6 @@ EmojiColorVariants gEmojiVariants;
RecentStickerPreload gRecentStickersPreload; RecentStickerPreload gRecentStickersPreload;
RecentStickerPack gRecentStickers; RecentStickerPack gRecentStickers;
StickerSets gStickerSets;
StickerSetsOrder gStickerSetsOrder;
uint64 gLastStickersUpdate = 0;
SavedGifs gSavedGifs; SavedGifs gSavedGifs;
uint64 gLastSavedGifsUpdate = 0; uint64 gLastSavedGifsUpdate = 0;

View file

@ -55,18 +55,6 @@ inline bool rtl() {
DeclareReadSetting(QString, Arguments); DeclareReadSetting(QString, Arguments);
struct mtpDcOption {
mtpDcOption(int id, int flags, const string &ip, int port) : id(id), flags(flags), ip(ip), port(port) {
}
int id;
int flags;
string ip;
int port;
};
typedef QMap<int, mtpDcOption> mtpDcOptions;
DeclareSetting(mtpDcOptions, DcOptions);
DeclareSetting(bool, DevVersion); DeclareSetting(bool, DevVersion);
DeclareSetting(uint64, BetaVersion); DeclareSetting(uint64, BetaVersion);
DeclareSetting(uint64, RealBetaVersion); DeclareSetting(uint64, RealBetaVersion);
@ -215,24 +203,6 @@ RecentStickerPack &cGetRecentStickers();
typedef QMap<EmojiPtr, StickerPack> StickersByEmojiMap; typedef QMap<EmojiPtr, StickerPack> StickersByEmojiMap;
static const uint64 DefaultStickerSetId = 0; // for backward compatibility
static const uint64 CustomStickerSetId = 0xFFFFFFFFFFFFFFFFULL, RecentStickerSetId = 0xFFFFFFFFFFFFFFFEULL;
static const uint64 NoneStickerSetId = 0xFFFFFFFFFFFFFFFDULL; // for emoji/stickers panel
struct StickerSet {
StickerSet(uint64 id, uint64 access, const QString &title, const QString &shortName, int32 count, int32 hash, int32 flags) : id(id), access(access), title(title), shortName(shortName), count(count), hash(hash), flags(flags) {
}
uint64 id, access;
QString title, shortName;
int32 count, hash, flags;
StickerPack stickers;
StickersByEmojiMap emoji;
};
typedef QMap<uint64, StickerSet> StickerSets;
DeclareRefSetting(StickerSets, StickerSets);
typedef QList<uint64> StickerSetsOrder;
DeclareRefSetting(StickerSetsOrder, StickerSetsOrder);
DeclareSetting(uint64, LastStickersUpdate);
typedef QVector<DocumentData*> SavedGifs; typedef QVector<DocumentData*> SavedGifs;
DeclareRefSetting(SavedGifs, SavedGifs); DeclareRefSetting(SavedGifs, SavedGifs);
DeclareSetting(uint64, LastSavedGifsUpdate); DeclareSetting(uint64, LastSavedGifsUpdate);

View file

@ -1355,8 +1355,8 @@ void SettingsInner::onPasswordOff() {
_passwordTurnOff.hide(); _passwordTurnOff.hide();
// int32 flags = MTPDaccount_passwordInputSettings::flag_new_salt | MTPDaccount_passwordInputSettings::flag_new_password_hash | MTPDaccount_passwordInputSettings::flag_hint | MTPDaccount_passwordInputSettings::flag_email; // int32 flags = MTPDaccount_passwordInputSettings::flag_new_salt | MTPDaccount_passwordInputSettings::flag_new_password_hash | MTPDaccount_passwordInputSettings::flag_hint | MTPDaccount_passwordInputSettings::flag_email;
int32 flags = MTPDaccount_passwordInputSettings::flag_email; MTPDaccount_passwordInputSettings::Flags flags = MTPDaccount_passwordInputSettings::Flag::f_email;
MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_int(flags), MTP_string(QByteArray()), MTP_string(QByteArray()), MTP_string(QString()), MTP_string(QString()))); MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_flags(flags), MTP_string(QByteArray()), MTP_string(QByteArray()), MTP_string(QString()), MTP_string(QString())));
MTP::send(MTPaccount_UpdatePasswordSettings(MTP_string(QByteArray()), settings), rpcDone(&SettingsInner::offPasswordDone), rpcFail(&SettingsInner::offPasswordFail)); MTP::send(MTPaccount_UpdatePasswordSettings(MTP_string(QByteArray()), settings), rpcDone(&SettingsInner::offPasswordDone), rpcFail(&SettingsInner::offPasswordFail));
} else { } else {
PasscodeBox *box = new PasscodeBox(_newPasswordSalt, _curPasswordSalt, _hasPasswordRecovery, _curPasswordHint, true); PasscodeBox *box = new PasscodeBox(_newPasswordSalt, _curPasswordSalt, _hasPasswordRecovery, _curPasswordHint, true);

View file

@ -135,9 +135,9 @@ void PeerData::updateName(const QString &newName, const QString &newNameOrPhone,
if (asChannel()->username != newUsername) { if (asChannel()->username != newUsername) {
asChannel()->username = newUsername; asChannel()->username = newUsername;
if (newUsername.isEmpty()) { if (newUsername.isEmpty()) {
asChannel()->flags &= ~MTPDchannel::flag_username; asChannel()->flags &= ~MTPDchannel::Flag::f_username;
} else { } else {
asChannel()->flags |= MTPDchannel::flag_username; asChannel()->flags |= MTPDchannel::Flag::f_username;
} }
if (App::main()) { if (App::main()) {
App::main()->peerUsernameChanged(this); App::main()->peerUsernameChanged(this);
@ -802,14 +802,14 @@ QString saveFileName(const QString &title, const QString &filter, const QString
bool StickerData::setInstalled() const { bool StickerData::setInstalled() const {
switch (set.type()) { switch (set.type()) {
case mtpc_inputStickerSetID: { case mtpc_inputStickerSetID: {
StickerSets::const_iterator it = cStickerSets().constFind(set.c_inputStickerSetID().vid.v); auto it = Global::StickerSets().constFind(set.c_inputStickerSetID().vid.v);
return (it != cStickerSets().cend()) && !(it->flags & MTPDstickerSet::flag_disabled); return (it != Global::StickerSets().cend()) && !(it->flags & MTPDstickerSet::Flag::f_disabled);
} break; } break;
case mtpc_inputStickerSetShortName: { case mtpc_inputStickerSetShortName: {
QString name = qs(set.c_inputStickerSetShortName().vshort_name).toLower(); QString name = qs(set.c_inputStickerSetShortName().vshort_name).toLower();
for (StickerSets::const_iterator it = cStickerSets().cbegin(), e = cStickerSets().cend(); it != e; ++it) { for (auto it = Global::StickerSets().cbegin(), e = Global::StickerSets().cend(); it != e; ++it) {
if (it->shortName.toLower() == name) { if (it->shortName.toLower() == name) {
return !(it->flags & MTPDstickerSet::flag_disabled); return !(it->flags & MTPDstickerSet::Flag::f_disabled);
} }
} }
} break; } break;

View file

@ -103,10 +103,12 @@ inline PeerId peerFromMessage(const MTPmessage &msg) {
} }
return (from_id && peerToUser(to_id) == MTP::authedId()) ? from_id : to_id; return (from_id && peerToUser(to_id) == MTP::authedId()) ? from_id : to_id;
} }
inline int32 flagsFromMessage(const MTPmessage &msg) { inline MTPDmessage::Flags flagsFromMessage(const MTPmessage &msg) {
switch (msg.type()) { switch (msg.type()) {
case mtpc_message: return msg.c_message().vflags.v; case mtpc_message: return msg.c_message().vflags.v;
case mtpc_messageService: return msg.c_messageService().vflags.v;
// dirty type hack :( we assume that MTPDmessage::Flags has the same flags and perhaps more
case mtpc_messageService: return MTPDmessage::Flags(QFlag(msg.c_messageService().vflags.v));
} }
return 0; return 0;
} }
@ -163,15 +165,16 @@ static const MsgId ServerMaxMsgId = 0x3FFFFFFF;
static const MsgId ShowAtUnreadMsgId = 0; static const MsgId ShowAtUnreadMsgId = 0;
struct NotifySettings { struct NotifySettings {
NotifySettings() : flags(MTPDinputPeerNotifySettings::flag_show_previews), mute(0), sound("default") { NotifySettings() : flags(MTPDpeerNotifySettings::Flag::f_show_previews), mute(0), sound("default") {
} }
int32 flags, mute; MTPDpeerNotifySettings::Flags flags;
int32 mute;
string sound; string sound;
bool previews() const { bool previews() const {
return flags & MTPDinputPeerNotifySettings::flag_show_previews; return flags & MTPDpeerNotifySettings::Flag::f_show_previews;
} }
bool silent() const { bool silent() const {
return flags & MTPDinputPeerNotifySettings::flag_silent; return flags & MTPDpeerNotifySettings::Flag::f_silent;
} }
}; };
typedef NotifySettings *NotifySettingsPtr; typedef NotifySettings *NotifySettingsPtr;
@ -386,9 +389,9 @@ public:
uint64 access; uint64 access;
int32 flags; MTPDuser::Flags flags;
bool isVerified() const { bool isVerified() const {
return flags & MTPDuser::flag_verified; return flags & MTPDuser::Flag::f_verified;
} }
bool canWrite() const { bool canWrite() const {
return access != UserNoAccess; return access != UserNoAccess;
@ -434,7 +437,7 @@ public:
void invalidateParticipants() { void invalidateParticipants() {
participants = ChatData::Participants(); participants = ChatData::Participants();
admins = ChatData::Admins(); admins = ChatData::Admins();
flags &= ~MTPDchat::flag_admin; flags &= ~MTPDchat::Flag::f_admin;
invitedByMe = ChatData::InvitedByMe(); invitedByMe = ChatData::InvitedByMe();
botStatus = 0; botStatus = 0;
} }
@ -451,7 +454,7 @@ public:
int32 version; int32 version;
int32 creator; int32 creator;
int32 flags; MTPDchat::Flags flags;
bool isForbidden; bool isForbidden;
bool amIn() const { bool amIn() const {
return !isForbidden && !haveLeft() && !wasKicked(); return !isForbidden && !haveLeft() && !wasKicked();
@ -463,25 +466,25 @@ public:
return !isDeactivated() && amIn(); return !isDeactivated() && amIn();
} }
bool haveLeft() const { bool haveLeft() const {
return flags & MTPDchat::flag_left; return flags & MTPDchat::Flag::f_left;
} }
bool wasKicked() const { bool wasKicked() const {
return flags & MTPDchat::flag_kicked; return flags & MTPDchat::Flag::f_kicked;
} }
bool adminsEnabled() const { bool adminsEnabled() const {
return flags & MTPDchat::flag_admins_enabled; return flags & MTPDchat::Flag::f_admins_enabled;
} }
bool amCreator() const { bool amCreator() const {
return flags & MTPDchat::flag_creator; return flags & MTPDchat::Flag::f_creator;
} }
bool amAdmin() const { bool amAdmin() const {
return flags & MTPDchat::flag_admin; return flags & MTPDchat::Flag::f_admin;
} }
bool isDeactivated() const { bool isDeactivated() const {
return flags & MTPDchat::flag_deactivated; return flags & MTPDchat::Flag::f_deactivated;
} }
bool isMigrated() const { bool isMigrated() const {
return flags & MTPDchat::flag_migrated_to; return flags & MTPDchat::Flag::f_migrated_to;
} }
typedef QMap<UserData*, int32> Participants; typedef QMap<UserData*, int32> Participants;
Participants participants; Participants participants;
@ -625,7 +628,8 @@ public:
int32 count, adminsCount; int32 count, adminsCount;
int32 date; int32 date;
int32 version; int32 version;
int32 flags, flagsFull; MTPDchannel::Flags flags;
MTPDchannelFull::Flags flagsFull;
MegagroupInfo *mgInfo; MegagroupInfo *mgInfo;
bool lastParticipantsCountOutdated() const { bool lastParticipantsCountOutdated() const {
if (!mgInfo || !(mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsCountOutdated)) { if (!mgInfo || !(mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsCountOutdated)) {
@ -639,31 +643,31 @@ public:
} }
void flagsUpdated(); void flagsUpdated();
bool isMegagroup() const { bool isMegagroup() const {
return flags & MTPDchannel::flag_megagroup; return flags & MTPDchannel::Flag::f_megagroup;
} }
bool isBroadcast() const { bool isBroadcast() const {
return flags & MTPDchannel::flag_broadcast; return flags & MTPDchannel::Flag::f_broadcast;
} }
bool isPublic() const { bool isPublic() const {
return flags & MTPDchannel::flag_username; return flags & MTPDchannel::Flag::f_username;
} }
bool canEditUsername() const { bool canEditUsername() const {
return amCreator() && (flagsFull & MTPDchannelFull::flag_can_set_username); return amCreator() && (flagsFull & MTPDchannelFull::Flag::f_can_set_username);
} }
bool amCreator() const { bool amCreator() const {
return flags & MTPDchannel::flag_creator; return flags & MTPDchannel::Flag::f_creator;
} }
bool amEditor() const { bool amEditor() const {
return flags & MTPDchannel::flag_editor; return flags & MTPDchannel::Flag::f_editor;
} }
bool amModerator() const { bool amModerator() const {
return flags & MTPDchannel::flag_moderator; return flags & MTPDchannel::Flag::f_moderator;
} }
bool haveLeft() const { bool haveLeft() const {
return flags & MTPDchannel::flag_left; return flags & MTPDchannel::Flag::f_left;
} }
bool wasKicked() const { bool wasKicked() const {
return flags & MTPDchannel::flag_kicked; return flags & MTPDchannel::Flag::f_kicked;
} }
bool amIn() const { bool amIn() const {
return !isForbidden && !haveLeft() && !wasKicked(); return !isForbidden && !haveLeft() && !wasKicked();
@ -675,17 +679,17 @@ public:
return amIn() && (canPublish() || !isBroadcast()); return amIn() && (canPublish() || !isBroadcast());
} }
bool canViewParticipants() const { bool canViewParticipants() const {
return flagsFull & MTPDchannelFull::flag_can_view_participants; return flagsFull & MTPDchannelFull::Flag::f_can_view_participants;
} }
bool addsSignature() const { bool addsSignature() const {
return flags & MTPDchannel::flag_signatures; return flags & MTPDchannel::Flag::f_signatures;
} }
bool isForbidden; bool isForbidden;
bool isVerified() const { bool isVerified() const {
return flags & MTPDchannel::flag_verified; return flags & MTPDchannel::Flag::f_verified;
} }
bool canAddParticipants() const { bool canAddParticipants() const {
return amCreator() || amEditor() || (flags & MTPDchannel::flag_democracy); return amCreator() || amEditor() || (flags & MTPDchannel::Flag::f_democracy);
} }
// ImagePtr photoFull; // ImagePtr photoFull;
@ -1220,7 +1224,7 @@ public:
int32 width, height, duration; int32 width, height, duration;
QString message; // botContextMessageText QString message; // botContextMessageText
bool noWebPage; bool noWebPage; //currently not used
EntitiesInText entities; EntitiesInText entities;
QString caption; // if message.isEmpty() use botContextMessageMediaAuto QString caption; // if message.isEmpty() use botContextMessageMediaAuto

View file

@ -59,6 +59,11 @@ struct ForConstTraits {
}; };
#define for_const(range_declaration, range_expression) for (range_declaration : static_cast<ForConstTraits<decltype(range_expression)>::ExpressionType>(range_expression)) #define for_const(range_declaration, range_expression) for (range_declaration : static_cast<ForConstTraits<decltype(range_expression)>::ExpressionType>(range_expression))
template <typename Enum>
inline QFlags<Enum> qFlags(Enum v) {
return QFlags<Enum>(v);
}
//typedef unsigned char uchar; // Qt has uchar //typedef unsigned char uchar; // Qt has uchar
typedef qint16 int16; typedef qint16 int16;
typedef quint16 uint16; typedef quint16 uint16;

View file

@ -661,8 +661,8 @@ void Window::sendServiceHistoryRequest() {
UserData *user = App::userLoaded(ServiceUserId); UserData *user = App::userLoaded(ServiceUserId);
if (!user) { if (!user) {
int32 userFlags = MTPDuser::flag_first_name | MTPDuser::flag_phone | MTPDuser::flag_status | MTPDuser::flag_verified; MTPDuser::Flags userFlags = MTPDuser::Flag::f_first_name | MTPDuser::Flag::f_phone | MTPDuser::Flag::f_status | MTPDuser::Flag::f_verified;
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(), MTPstring(), MTPstring()))); user = App::feedUsers(MTP_vector<MTPUser>(1, MTP_user(MTP_flags(userFlags), MTP_int(ServiceUserId), MTPlong(), MTP_string("Telegram"), MTPstring(), MTPstring(), MTP_string("42777"), MTP_userProfilePhotoEmpty(), MTP_userStatusRecently(), MTPint(), MTPstring(), MTPstring())));
} }
_serviceHistoryRequest = MTP::send(MTPmessages_GetHistory(user->input, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), 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), MTP_int(0), MTP_int(0)), main->rpcDone(&MainWidget::serviceHistoryDone), main->rpcFail(&MainWidget::serviceHistoryFail));
} }
@ -1037,7 +1037,6 @@ bool Window::eventFilter(QObject *obj, QEvent *e) {
break; break;
case QEvent::ShortcutOverride: // handle shortcuts ourselves case QEvent::ShortcutOverride: // handle shortcuts ourselves
DEBUG_LOG(("Shortcut override declined: %1").arg(static_cast<QKeyEvent*>(e)->key()));
return true; return true;
case QEvent::Shortcut: case QEvent::Shortcut: