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 (!channel->mgInfo) {
channel->flags |= MTPDchannel::flag_megagroup;
channel->flags |= MTPDchannel::Flag::f_megagroup;
channel->flagsUpdated();
}
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;
const MTPDstickerSet &s(d.vset.c_stickerSet());
StickerSets &sets(cRefStickerSets());
StickerSets::iterator it = sets.find(setId);
Stickers::Sets &sets(Global::RefStickerSets());
auto it = sets.find(setId);
if (it == sets.cend()) return;
it->access = s.vaccess_hash.v;
@ -696,7 +696,7 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
it->flags = s.vflags.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;
pack.reserve(d_docs.size());
@ -729,8 +729,8 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
}
if (pack.isEmpty()) {
int32 removeIndex = cStickerSetsOrder().indexOf(setId);
if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex);
int removeIndex = Global::StickerSetsOrder().indexOf(setId);
if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex);
sets.erase(it);
} else {
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) {
HistoryItem *item = App::histories().addNewMessage(v->at(i.value()), NewMessageExisting);
if (item) {
item->initDimensions();
Notify::historyItemResized(item);
if (HistoryItem *item = App::histories().addNewMessage(v->at(i.value()), NewMessageExisting)) {
item->setPendingInitDimensions();
}
}
@ -918,8 +916,7 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs
WebPageItems::const_iterator j = items.constFind(i.key());
if (j != items.cend()) {
for (HistoryItemsMap::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
k.key()->initDimensions();
Notify::historyItemResized(k.key());
k.key()->setPendingInitDimensions();
}
}
}

View file

@ -57,7 +57,7 @@ namespace {
typedef QMap<MsgId, ReplyMarkup> ReplyMarkups;
ReplyMarkups replyMarkups;
ReplyMarkup zeroMarkup(MTPDreplyKeyboardMarkup_flag_ZERO);
ReplyMarkup zeroMarkup(qFlags(MTPDreplyKeyboardMarkup_ClientFlag::f_zero));
typedef QMap<ChannelId, ReplyMarkups> ChannelReplyMarkups;
ChannelReplyMarkups channelReplyMarkups;
@ -507,7 +507,7 @@ namespace App {
const MTPDinputChannel &c(d.vmigrated_to.c_inputChannel());
ChannelData *channel = App::channel(peerFromChannel(c.vchannel_id));
if (!channel->mgInfo) {
channel->flags |= MTPDchannel::flag_megagroup;
channel->flags |= MTPDchannel::Flag::f_megagroup;
channel->flagsUpdated();
}
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->flags = d.vflags.v;
@ -583,7 +583,7 @@ namespace App {
ChannelData *cdata = data->asChannel();
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);
} else {
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);
chat->invitedByMe = ChatData::InvitedByMe();
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) {
int32 uid = 0, inviter = 0;
switch (i->type()) {
@ -685,7 +685,7 @@ namespace App {
if (i->type() == mtpc_chatParticipantAdmin) {
chat->admins.insert(user);
if (user->isSelf()) {
chat->flags |= MTPDchat::flag_admin;
chat->flags |= MTPDchat::Flag::f_admin;
}
}
} else {
@ -805,7 +805,7 @@ namespace App {
chat->invitedByMe.remove(user);
chat->admins.remove(user);
if (user->isSelf()) {
chat->flags &= ~MTPDchat::flag_admin;
chat->flags &= ~MTPDchat::Flag::f_admin;
}
History *h = App::historyLoaded(chat->id);
@ -852,13 +852,13 @@ namespace App {
}
chat->version = d.vversion.v;
if (mtpIsTrue(d.venabled)) {
chat->flags |= MTPDchat::flag_admins_enabled;
chat->flags |= MTPDchat::Flag::f_admins_enabled;
if (!badVersion) {
chat->invalidateParticipants();
}
} else {
chat->flags &= ~MTPDchat::flag_admins_enabled;
chat->flags &= ~MTPDchat::flag_admin;
chat->flags &= ~MTPDchat::Flag::f_admins_enabled;
chat->flags &= ~MTPDchat::Flag::f_admin;
}
if (emitPeerUpdated) {
App::main()->peerUpdated(chat);
@ -887,7 +887,7 @@ namespace App {
if (user) {
if (mtpIsTrue(d.vis_admin)) {
if (user->isSelf()) {
chat->flags |= MTPDchat::flag_admin;
chat->flags |= MTPDchat::Flag::f_admin;
}
if (chat->noParticipantInfo()) {
App::api()->requestFullPeer(chat);
@ -896,7 +896,7 @@ namespace App {
}
} else {
if (user->isSelf()) {
chat->flags &= ~MTPDchat::flag_admin;
chat->flags &= ~MTPDchat::Flag::f_admin;
}
chat->admins.remove(user);
}
@ -921,10 +921,7 @@ namespace App {
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->updateMedia(m.has_media() ? (&m.vmedia) : 0);
existing->setViewsCount(m.has_views() ? m.vviews.v : -1, false);
existing->initDimensions();
Notify::historyItemResized(existing);
existing->setViewsCount(m.has_views() ? m.vviews.v : -1);
existing->addToOverview(AddToOverviewNew);
if (!existing->detached()) {
@ -945,16 +942,13 @@ namespace App {
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->updateMedia(m.has_media() ? (&m.vmedia) : 0, true);
existing->setViewsCount(m.has_views() ? m.vviews.v : -1, false);
existing->initDimensions();
existing->setViewsCount(m.has_views() ? m.vviews.v : -1);
if (existing->history()->textCachedFor == existing) {
existing->history()->textCachedFor = 0;
}
if (App::main()) {
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) {
bool resized = false;
MsgsData *data = fetchMsgsData(channelId, false);
if (!data) return;
@ -1106,9 +1099,6 @@ namespace App {
MsgsData::const_iterator j = data->constFind(i->v);
if (j != data->cend()) {
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();
if (!h->lastMsg) historiesToCheck.insert(h, true);
} else {
@ -1120,9 +1110,6 @@ namespace App {
}
}
}
if (resized) {
Notify::historyItemsResized();
}
if (main()) {
for (QMap<History*, bool>::const_iterator i = historiesToCheck.cbegin(), e = historiesToCheck.cend(); i != e; ++i) {
main()->checkPeerHistory(i.key()->peer);
@ -1788,6 +1775,7 @@ namespace App {
if (App::wnd()) {
App::wnd()->notifyItemRemoved(item);
}
item->history()->setPendingResize();
}
void historyUnregItem(HistoryItem *item) {
@ -1878,9 +1866,9 @@ namespace App {
webPagesData.clear();
if (api()) api()->clearWebPageRequests();
cSetRecentStickers(RecentStickerPack());
cSetStickerSets(StickerSets());
cSetStickerSetsOrder(StickerSetsOrder());
cSetLastStickersUpdate(0);
Global::SetStickerSets(Stickers::Sets());
Global::SetStickerSetsOrder(Stickers::Order());
Global::SetLastStickersUpdate(0);
cSetSavedGifs(SavedGifs());
cSetLastSavedGifsUpdate(0);
cSetReportSpamStatuses(ReportSpamStatuses());
@ -2446,13 +2434,13 @@ namespace App {
case mtpc_replyKeyboardHide: {
const MTPDreplyKeyboardHide &d(markup.c_replyKeyboardHide());
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;
case mtpc_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;
}
}

View file

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

View file

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

View file

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

View file

@ -2505,7 +2505,7 @@ MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteAr
cover = reader.cover();
coverBytes = reader.coverBytes();
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));

View file

@ -499,8 +499,8 @@ void GroupInfoBox::onNext() {
Ui::showLayer(new ContactsBox(title, _photoBig), KeepOtherLayers);
} else {
bool mega = false;
int32 flags = mega ? MTPchannels_CreateChannel::flag_megagroup : MTPchannels_CreateChannel::flag_broadcast;
_creationRequestId = MTP::send(MTPchannels_CreateChannel(MTP_int(flags), MTP_string(title), MTP_string(description)), rpcDone(&GroupInfoBox::creationDone), rpcFail(&GroupInfoBox::creationFail));
MTPchannels_CreateChannel::Flags flags = mega ? MTPchannels_CreateChannel::Flag::f_megagroup : MTPchannels_CreateChannel::Flag::f_broadcast;
_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;
if (_peer == App::self()) {
int32 flags = MTPaccount_UpdateProfile::flag_first_name | MTPaccount_UpdateProfile::flag_last_name;
_requestId = MTP::send(MTPaccount_UpdateProfile(MTP_int(flags), MTP_string(first), MTP_string(last), MTPstring()), rpcDone(&EditNameTitleBox::onSaveSelfDone), rpcFail(&EditNameTitleBox::onSaveSelfFail));
MTPaccount_UpdateProfile::Flags flags = MTPaccount_UpdateProfile::Flag::f_first_name | MTPaccount_UpdateProfile::Flag::f_last_name;
_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()) {
_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() {
if (_requestId) return;
int32 flags = _notify.checked() ? 0 : MTPchannels_UpdatePinnedMessage::flag_silent;
_requestId = MTP::send(MTPchannels_UpdatePinnedMessage(MTP_int(flags), _channel->inputChannel, MTP_int(_msgId)), rpcDone(&PinMessageBox::pinDone), rpcFail(&PinMessageBox::pinFail));
MTPchannels_UpdatePinnedMessage::Flags flags = 0;
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() {
@ -482,7 +485,6 @@ void RichDeleteMessageBox::onDelete() {
App::main()->checkPeerHistory(_channel);
}
}
Notify::historyItemsResized();
Ui::hideLayer();
}

View file

@ -400,11 +400,11 @@ void PasscodeBox::onSave(bool force) {
if (!_oldPasscode.isHidden()) {
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()) {
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));
}
} else {

View file

@ -648,15 +648,15 @@ void EditCaptionBox::onSave(bool ctrlShiftEnter) {
return;
}
int32 flags = 0;
MTPchannels_EditMessage::Flags flags = 0;
if (_previewCancelled) {
flags |= MTPchannels_EditMessage::flag_no_webpage;
flags |= MTPchannels_EditMessage::Flag::f_no_webpage;
}
MTPVector<MTPMessageEntity> sentEntities;
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) {

View file

@ -117,17 +117,17 @@ bool StickerSetInner::failedSet(const RPCError &error) {
}
void StickerSetInner::installDone(const MTPBool &result) {
StickerSets &sets(cRefStickerSets());
Stickers::Sets &sets(Global::RefStickerSets());
_setFlags &= ~MTPDstickerSet::flag_disabled;
StickerSets::iterator it = sets.find(_setId);
_setFlags &= ~MTPDstickerSet::Flag::f_disabled;
auto it = sets.find(_setId);
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().emoji = _emoji;
StickerSetsOrder &order(cRefStickerSetsOrder());
Stickers::Order &order(Global::RefStickerSetsOrder());
int32 insertAtIndex = 0, currentIndex = order.indexOf(_setId);
if (currentIndex != insertAtIndex) {
if (currentIndex > 0) {
@ -136,7 +136,7 @@ void StickerSetInner::installDone(const MTPBool &result) {
order.insert(insertAtIndex, _setId);
}
StickerSets::iterator custom = sets.find(CustomStickerSetId);
auto custom = sets.find(Stickers::CustomSetId);
if (custom != sets.cend()) {
for (int32 i = 0, l = _pack.size(); i < l; ++i) {
int32 removeIndex = custom->stickers.indexOf(_pack.at(i));
@ -256,8 +256,8 @@ bool StickerSetInner::loaded() const {
int32 StickerSetInner::notInstalled() const {
if (!_loaded) return 0;
StickerSets::const_iterator it = cStickerSets().constFind(_setId);
if (it == cStickerSets().cend() || (it->flags & MTPDstickerSet::flag_disabled)) return _pack.size();
auto it = Global::StickerSets().constFind(_setId);
if (it == Global::StickerSets().cend() || (it->flags & MTPDstickerSet::Flag::f_disabled)) return _pack.size();
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);
clear();
const StickerSetsOrder &order(cStickerSetsOrder());
const Stickers::Order &order(Global::StickerSetsOrder());
_animStartTimes.reserve(order.size());
const StickerSets &sets(cStickerSets());
for (int32 i = 0, l = order.size(); i < l; ++i) {
StickerSets::const_iterator it = sets.constFind(order.at(i));
const Stickers::Sets &sets(Global::StickerSets());
for (int i = 0, l = order.size(); i < l; ++i) {
auto it = sets.constFind(order.at(i));
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);
int32 pixw = 0, pixh = 0;
@ -714,10 +714,10 @@ void StickersInner::rebuild() {
if (titleWidth > 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));
_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);
}
}
@ -732,8 +732,8 @@ QVector<uint64> StickersInner::getOrder() const {
result.reserve(_rows.size());
for (int32 i = 0, l = _rows.size(); i < l; ++i) {
if (_rows.at(i)->disabled) {
StickerSets::const_iterator it = cStickerSets().constFind(_rows.at(i)->id);
if (it == cStickerSets().cend() || !(it->flags & MTPDstickerSet::flag_official)) {
auto it = Global::StickerSets().constFind(_rows.at(i)->id);
if (it == Global::StickerSets().cend() || !(it->flags & MTPDstickerSet::Flag::f_official)) {
continue;
}
}
@ -833,7 +833,7 @@ void StickersBox::reorderDone(const MTPBool &result) {
bool StickersBox::reorderFail(const RPCError &result) {
if (mtpIsFlood(result)) return false;
_reorderRequest = 0;
cSetLastStickersUpdate(0);
Global::SetLastStickersUpdate(0);
App::main()->updateStickers();
onClose();
return true;
@ -857,12 +857,12 @@ void StickersBox::closePressed() {
MTP::cancel(i.key());
}
_disenableRequests.clear();
cSetLastStickersUpdate(0);
Global::SetLastStickersUpdate(0);
App::main()->updateStickers();
} else if (_reorderRequest) {
MTP::cancel(_reorderRequest);
_reorderRequest = 0;
cSetLastStickersUpdate(0);
Global::SetLastStickersUpdate(0);
App::main()->updateStickers();
}
}
@ -914,11 +914,11 @@ void StickersBox::onSave() {
bool writeRecent = false;
RecentStickerPack &recent(cGetRecentStickers());
StickerSets &sets(cRefStickerSets());
Stickers::Sets &sets(Global::RefStickerSets());
QVector<uint64> reorder = _inner.getOrder(), disabled = _inner.getDisabledSets();
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()) {
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
if (it->stickers.indexOf(i->first) >= 0) {
@ -928,35 +928,35 @@ void StickersBox::onSave() {
++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));
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());
it->flags |= MTPDstickerSet::flag_disabled;
it->flags |= MTPDstickerSet::Flag::f_disabled;
} else {
_disenableRequests.insert(MTP::send(MTPmessages_UninstallStickerSet(setId), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
int32 removeIndex = cStickerSetsOrder().indexOf(it->id);
if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex);
int removeIndex = Global::StickerSetsOrder().indexOf(it->id);
if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex);
sets.erase(it);
}
}
}
}
StickerSetsOrder &order(cRefStickerSetsOrder());
Stickers::Order &order(Global::RefStickerSetsOrder());
order.clear();
for (int32 i = 0, l = reorder.size(); i < l; ++i) {
StickerSets::iterator it = sets.find(reorder.at(i));
for (int i = 0, l = reorder.size(); i < l; ++i) {
auto it = sets.find(reorder.at(i));
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));
_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));
}
}
for (StickerSets::iterator it = sets.begin(); it != sets.cend();) {
if (it->id == CustomStickerSetId || it->id == RecentStickerSetId || order.contains(it->id)) {
for (auto it = sets.begin(); it != sets.cend();) {
if (it->id == Stickers::CustomSetId || it->id == Stickers::RecentSetId || order.contains(it->id)) {
++it;
} else {
it = sets.erase(it);
@ -992,12 +992,12 @@ void StickersBox::showAll() {
int32 stickerPacksCount(bool includeDisabledOfficial) {
int32 result = 0;
const StickerSetsOrder &order(cStickerSetsOrder());
const StickerSets &sets(cStickerSets());
for (int32 i = 0, l = order.size(); i < l; ++i) {
StickerSets::const_iterator it = sets.constFind(order.at(i));
const Stickers::Order &order(Global::StickerSetsOrder());
const Stickers::Sets &sets(Global::StickerSets());
for (int i = 0, l = order.size(); i < l; ++i) {
auto it = sets.constFind(order.at(i));
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;
}
}

View file

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

View file

@ -2052,8 +2052,11 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
MTP::cancel(_searchRequest);
}
if (_searchInPeer) {
int32 flags = (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 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));
MTPmessages_Search::Flags flags = 0;
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 {
_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();
MsgId offsetId = _inner.lastSearchId();
if (_searchInPeer) {
int32 flags = (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 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));
MTPmessages_Search::Flags flags = 0;
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 {
_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) {
MsgId offsetMigratedId = _inner.lastSearchMigratedId();
int32 flags = (_searchInMigrated->isChannel() && !_searchInMigrated->isMegagroup()) ? MTPmessages_Search::flag_important_only : 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));
MTPmessages_Search::Flags flags = 0;
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;
panels.reserve(emojiTabCount);
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()));
int cnt = _counts[c], rows = (cnt / EmojiPanPerRow) + ((cnt % EmojiPanPerRow) ? 1 : 0);
panels.back()->show();
@ -1352,7 +1352,7 @@ void StickerPanInner::paintStickers(Painter &p, const QRect &r) {
tilly = y + st::emojiPanHeader + (rows * st::stickerPanSize.height());
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;
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));
}
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];
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;
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);
bool refresh = false;
DocumentData *sticker = _sets[tab].pack.at(sel - _sets[tab].pack.size());
@ -1522,8 +1522,8 @@ void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
break;
}
}
StickerSets &sets(cRefStickerSets());
StickerSets::iterator it = sets.find(CustomStickerSetId);
Stickers::Sets &sets(Global::RefStickerSets());
auto it = sets.find(Stickers::CustomSetId);
if (it != sets.cend()) {
for (int32 i = 0, l = it->stickers.size(); i < l; ++i) {
if (it->stickers.at(i) == sticker) {
@ -1595,7 +1595,7 @@ void StickerPanInner::clearSelection(bool fast) {
_animations.clear();
if (_selected >= 0) {
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;
sel -= _sets[tab].pack.size();
}
@ -1603,7 +1603,7 @@ void StickerPanInner::clearSelection(bool fast) {
}
if (_pressedSel >= 0) {
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;
sel -= _sets[tab].pack.size();
}
@ -1640,11 +1640,11 @@ void StickerPanInner::hideFinish(bool completely) {
void StickerPanInner::refreshStickers() {
clearSelection(true);
const StickerSets &sets(cStickerSets());
const Stickers::Sets &sets(Global::StickerSets());
_sets.clear(); _sets.reserve(sets.size() + 1);
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);
}
@ -1703,7 +1703,7 @@ void StickerPanInner::refreshSavedGifs() {
if (_showingInlineItems) {
const SavedGifs &saved(cSavedGifs());
if (saved.isEmpty()) {
showStickerSet(RecentStickerSetId);
showStickerSet(Stickers::RecentSetId);
return;
} else {
_inlineRows.reserve(saved.size());
@ -1871,7 +1871,7 @@ void StickerPanInner::preloadImages() {
}
uint64 StickerPanInner::currentSet(int yOffset) const {
if (_showingInlineItems) return NoneStickerSetId;
if (_showingInlineItems) return Stickers::NoneSetId;
int y, ytill = 0;
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.isEmpty() ? RecentStickerSetId : _sets.back().id;
return _sets.isEmpty() ? Stickers::RecentSetId : _sets.back().id;
}
void StickerPanInner::hideInlineRowsPanel() {
@ -1894,7 +1894,7 @@ void StickerPanInner::hideInlineRowsPanel() {
emit scrollToY(0);
emit scrollUpdated();
} else {
showStickerSet(RecentStickerSetId);
showStickerSet(Stickers::RecentSetId);
}
}
}
@ -2039,9 +2039,9 @@ bool StickerPanInner::ui_isInlineItemBeingChosen() {
}
void StickerPanInner::appendSet(uint64 setId) {
const StickerSets &sets(cStickerSets());
StickerSets::const_iterator it = sets.constFind(setId);
if (it == sets.cend() || (it->flags & MTPDstickerSet::flag_disabled) || it->stickers.isEmpty()) return;
const Stickers::Sets &sets(Global::StickerSets());
auto it = sets.constFind(setId);
if (it == sets.cend() || (it->flags & MTPDstickerSet::Flag::f_disabled) || it->stickers.isEmpty()) return;
StickerPack pack;
pack.reserve(it->stickers.size());
@ -2064,14 +2064,14 @@ void StickerPanInner::refreshRecent() {
void StickerPanInner::refreshRecentStickers(bool performResize) {
_custom.clear();
clearSelection(true);
StickerSets::const_iterator customIt = cStickerSets().constFind(CustomStickerSetId);
if (cGetRecentStickers().isEmpty() && (customIt == cStickerSets().cend() || customIt->stickers.isEmpty())) {
if (!_sets.isEmpty() && _sets.at(0).id == RecentStickerSetId) {
auto customIt = Global::StickerSets().constFind(Stickers::CustomSetId);
if (cGetRecentStickers().isEmpty() && (customIt == Global::StickerSets().cend() || customIt->stickers.isEmpty())) {
if (!_sets.isEmpty() && _sets.at(0).id == Stickers::RecentSetId) {
_sets.pop_front();
}
} else {
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;
recent.reserve(cGetRecentStickers().size() + customCnt);
_custom.reserve(cGetRecentStickers().size() + customCnt);
@ -2090,8 +2090,8 @@ void StickerPanInner::refreshRecentStickers(bool performResize) {
_custom.push_back(true);
}
}
if (_sets.isEmpty() || _sets.at(0).id != RecentStickerSetId) {
_sets.push_back(DisplayedSet(RecentStickerSetId, MTPDstickerSet::flag_official, lang(lng_emoji_category0), recent.size() * 2, recent));
if (_sets.isEmpty() || _sets.at(0).id != Stickers::RecentSetId) {
_sets.push_back(DisplayedSet(Stickers::RecentSetId, MTPDstickerSet::Flag::f_official, lang(lng_emoji_category0), recent.size() * 2, recent));
} else {
_sets[0].pack = recent;
_sets[0].hovers.resize(recent.size() * 2);
@ -2112,12 +2112,12 @@ void StickerPanInner::refreshRecentStickers(bool performResize) {
void StickerPanInner::fillIcons(QList<StickerIcon> &icons) {
icons.clear();
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;
int32 i = 0;
if (_sets.at(0).id == RecentStickerSetId) ++i;
if (i > 0) icons.push_back(StickerIcon(RecentStickerSetId));
if (_sets.at(0).id == Stickers::RecentSetId) ++i;
if (i > 0) icons.push_back(StickerIcon(Stickers::RecentSetId));
for (int32 l = _sets.size(); i < l; ++i) {
DocumentData *s = _sets.at(i).pack.at(0);
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();
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();
return;
}
@ -2153,7 +2153,7 @@ void StickerPanInner::fillPanels(QVector<EmojiPanel*> &panels) {
int y = 0;
panels.reserve(_sets.size());
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.back()->show();
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) {
const DisplayedSet &set(_sets.at(c));
int cnt = set.pack.size();
bool special = (set.flags & MTPDstickerSet::flag_official);
bool special = (set.flags & MTPDstickerSet::Flag::f_official);
y = ytill;
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()) {
selIndex = -1;
} 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());
if (inx >= st::stickerPanSize.width() - st::stickerPanDelete.pxWidth() && iny < st::stickerPanDelete.pxHeight()) {
selIndex += set.pack.size();
@ -2286,11 +2286,11 @@ void StickerPanInner::updateSelected() {
bool startanim = false;
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;
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;
newSel -= _sets[newSelTab].pack.size();
}
@ -2390,7 +2390,7 @@ void StickerPanInner::step_selected(uint64 ms, bool timer) {
void StickerPanInner::showStickerSet(uint64 setId) {
clearSelection(true);
if (setId == NoneStickerSetId) {
if (setId == Stickers::NoneSetId) {
bool wasNotShowingGifs = !_showingInlineItems;
if (wasNotShowingGifs) {
_showingInlineItems = true;
@ -2460,7 +2460,7 @@ EmojiPanel::EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool
, _setId(setId)
, _special(special)
, _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);
setMouseTracking(true);
setFocusPolicy(Qt::NoFocus);
@ -2484,11 +2484,11 @@ void EmojiPanel::setText(const QString &text) {
void EmojiPanel::updateText() {
int32 availw = st::emojiPanWidth - st::emojiPanHeaderLeft * 2;
if (_deleteVisible) {
if (!_special && _setId != NoneStickerSetId) {
if (!_special && _setId != Stickers::NoneSetId) {
availw -= st::notifyClose.icon.pxWidth() + st::emojiPanHeaderLeft;
}
} 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);
}
_text = st::emojiPanHeaderFont->elided(_fullText, availw);
@ -2781,7 +2781,7 @@ void EmojiPan::paintEvent(QPaintEvent *e) {
if (!_icons.isEmpty()) {
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) {
bool gifs = (_icons.at(i).setId == NoneStickerSetId);
bool gifs = (_icons.at(i).setId == Stickers::NoneSetId);
if (selxrel != x) {
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);
} else {
if (cShowingSavedGifs() && cSavedGifs().isEmpty()) {
s_inner.showStickerSet(DefaultStickerSetId);
} else if (!cShowingSavedGifs() && !cSavedGifs().isEmpty() && cStickerSets().isEmpty()) {
s_inner.showStickerSet(NoneStickerSetId);
s_inner.showStickerSet(Stickers::DefaultSetId);
} else if (!cShowingSavedGifs() && !cSavedGifs().isEmpty() && Global::StickerSets().isEmpty()) {
s_inner.showStickerSet(Stickers::NoneSetId);
} else {
s_inner.updateShowingSavedGifs();
}
@ -3552,8 +3552,8 @@ void EmojiPan::onSwitch() {
}
void EmojiPan::onRemoveSet(quint64 setId) {
StickerSets::const_iterator it = cStickerSets().constFind(setId);
if (it != cStickerSets().cend() && !(it->flags & MTPDstickerSet::flag_official)) {
auto it = Global::StickerSets().constFind(setId);
if (it != Global::StickerSets().cend() && !(it->flags & MTPDstickerSet::Flag::f_official)) {
_removingSetId = it->id;
ConfirmBox *box = new ConfirmBox(lng_stickers_remove_pack(lt_sticker_pack, it->title), lang(lng_box_remove));
connect(box, SIGNAL(confirmed()), this, SLOT(onRemoveSetSure()));
@ -3564,8 +3564,8 @@ void EmojiPan::onRemoveSet(quint64 setId) {
void EmojiPan::onRemoveSetSure() {
Ui::hideLayer();
StickerSets::iterator it = cRefStickerSets().find(_removingSetId);
if (it != cRefStickerSets().cend() && !(it->flags & MTPDstickerSet::flag_official)) {
auto it = Global::RefStickerSets().find(_removingSetId);
if (it != Global::RefStickerSets().cend() && !(it->flags & MTPDstickerSet::Flag::f_official)) {
if (it->id && it->access) {
MTP::send(MTPmessages_UninstallStickerSet(MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access))));
} else if (!it->shortName.isEmpty()) {
@ -3581,9 +3581,9 @@ void EmojiPan::onRemoveSetSure() {
++i;
}
}
cRefStickerSets().erase(it);
int32 removeIndex = cStickerSetsOrder().indexOf(_removingSetId);
if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex);
Global::RefStickerSets().erase(it);
int removeIndex = Global::StickerSetsOrder().indexOf(_removingSetId);
if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex);
refreshStickers();
Local::writeStickers();
if (writeRecent) Local::writeUserSettings();
@ -4371,15 +4371,15 @@ void MentionsDropdown::updateFiltered(bool resetScroll) {
StickerPack srows;
if (_emoji) {
QMap<uint64, uint64> setsToRequest;
StickerSets &sets(cRefStickerSets());
const StickerSetsOrder &order(cStickerSetsOrder());
for (int32 i = 0, l = order.size(); i < l; ++i) {
StickerSets::iterator it = sets.find(order.at(i));
Stickers::Sets &sets(Global::RefStickerSets());
const Stickers::Order &order(Global::StickerSetsOrder());
for (int i = 0, l = order.size(); i < l; ++i) {
auto it = sets.find(order.at(i));
if (it != sets.cend()) {
if (it->emoji.isEmpty()) {
setsToRequest.insert(it->id, it->access);
it->flags |= MTPDstickerSet_flag_NOT_LOADED;
} else if (!(it->flags & MTPDstickerSet::flag_disabled)) {
it->flags |= MTPDstickerSet_ClientFlag::f_not_loaded;
} else if (!(it->flags & MTPDstickerSet::Flag::f_disabled)) {
StickersByEmojiMap::const_iterator i = it->emoji.constFind(emojiGetNoColor(_emoji));
if (i != it->emoji.cend()) {
srows += *i;

View file

@ -420,10 +420,10 @@ private:
int32 _top;
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;
int32 flags;
MTPDstickerSet::Flags flags;
QString title;
QVector<float64> hovers;
StickerPack pack;
@ -482,7 +482,7 @@ class EmojiPanel : public TWidget {
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 setDeleteVisible(bool isVisible);

View file

@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "window.h"
#include "mainwidget.h"
#include "application.h"
#include "layerwidget.h"
#include "lang.h"
@ -143,6 +144,12 @@ namespace Ui {
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) {
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);
}
void historyItemResized(const HistoryItem *item, bool scrollToIt) {
if (MainWidget *m = App::main()) m->notify_historyItemResized(item, scrollToIt);
}
void historyItemLayoutChanged(const HistoryItem *item) {
if (MainWidget *m = App::main()) m->notify_historyItemLayoutChanged(item);
}
@ -209,6 +212,16 @@ namespace Notify {
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() { \
@ -362,6 +375,7 @@ namespace Global {
struct Data {
uint64 LaunchId = 0;
SingleDelayedCall HandleHistoryUpdate = { App::app(), "call_handleHistoryUpdate" };
Adaptive::Layout AdaptiveLayout = Adaptive::NormalLayout;
bool AdaptiveForWide = true;
@ -387,9 +401,14 @@ namespace Global {
HiddenPinnedMessagesMap HiddenPinnedMessages;
PendingItemsMap PendingInitDimensionsItems;
PendingItemsMap PendingRepaintItems;
Stickers::Sets StickerSets;
Stickers::Order StickerSetsOrder;
uint64 LastStickersUpdate = 0;
MTP::DcOptions DcOptions;
CircleMasksMap CircleMasks;
};
@ -416,6 +435,7 @@ namespace Global {
}
DefineReadOnlyVar(Global, uint64, LaunchId);
DefineRefVar(Global, SingleDelayedCall, HandleHistoryUpdate);
DefineVar(Global, Adaptive::Layout, AdaptiveLayout);
DefineVar(Global, bool, AdaptiveForWide);
@ -441,9 +461,14 @@ namespace Global {
DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages);
DefineRefVar(Global, PendingItemsMap, PendingInitDimensionsItems);
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);
};

View file

@ -53,6 +53,7 @@ namespace Ui {
void repaintHistoryItem(const HistoryItem *item);
void repaintInlineItem(const LayoutInlineItem *layout);
bool isInlineItemVisible(const LayoutInlineItem *reader);
void autoplayMediaInlineAsync(const FullMsgId &msgId);
void showPeerHistory(const PeerId &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 historyItemResized(const HistoryItem *item, bool scrollToIt = false);
inline void historyItemsResized() {
historyItemResized(0);
}
void historyItemLayoutChanged(const HistoryItem *item);
void automaticLoadSettingsChangedGif();
// handle pending resize() / paint() on history items
void handlePendingHistoryUpdate();
};
#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 {
bool started();
@ -144,6 +162,7 @@ namespace Global {
void finish();
DeclareReadOnlyVar(uint64, LaunchId);
DeclareRefVar(SingleDelayedCall, HandleHistoryUpdate);
DeclareVar(Adaptive::Layout, AdaptiveLayout);
DeclareVar(bool, AdaptiveForWide);
@ -171,9 +190,14 @@ namespace Global {
DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages);
typedef OrderedSet<HistoryItem*> PendingItemsMap;
DeclareRefVar(PendingItemsMap, PendingInitDimensionsItems);
DeclareRefVar(PendingItemsMap, PendingRepaintItems);
DeclareVar(Stickers::Sets, StickerSets);
DeclareVar(Stickers::Order, StickerSetsOrder);
DeclareVar(uint64, LastStickersUpdate);
DeclareVar(MTP::DcOptions, DcOptions);
typedef QMap<uint64, QPixmap> CircleMasksMap;
DeclareRefVar(CircleMasksMap, CircleMasks);

View file

@ -309,6 +309,11 @@ void History::clearLastKeyboard() {
lastKeyboardFrom = 0;
}
void History::setHasPendingResizedItems() {
_flags |= Flag::f_has_pending_resized_items;
Global::RefHandleHistoryUpdate().call();
}
bool History::updateTyping(uint64 ms, bool force) {
bool changed = force;
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;
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) {
@ -598,7 +603,10 @@ HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
if (!inviter) return 0;
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;
if (unread) _maxReadMessageDate = inviteDate;
if (isEmpty()) {
@ -1254,10 +1262,6 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
}
if (msg.type() == mtpc_message) {
result->updateMedia(msg.c_message().has_media() ? (&msg.c_message().vmedia) : 0);
result->initDimensions();
if (!block) {
Notify::historyItemResized(result);
}
if (applyServiceAction) {
App::checkSavedGif(result);
}
@ -1453,7 +1457,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
} break;
case mtpc_messageActionChatMigrateTo: {
peer->asChat()->flags |= MTPDchat::flag_deactivated;
peer->asChat()->flags |= MTPDchat::Flag::f_deactivated;
//const MTPDmessageActionChatMigrateTo &d(action.c_messageActionChatMigrateTo());
//PeerData *channel = App::peerLoaded(peerFromChannel(d.vchannel_id));
@ -1482,25 +1486,25 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
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);
}
HistoryItem *History::createItemDocument(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) {
if ((flags & MTPDmessage::flag_reply_to_msg_id) && replyTo > 0) {
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::f_reply_to_msg_id) && replyTo > 0) {
return HistoryReply::create(this, id, flags, viaBotId, replyTo, 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) {
if ((flags & MTPDmessage::flag_reply_to_msg_id) && replyTo > 0) {
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::f_reply_to_msg_id) && replyTo > 0) {
return HistoryReply::create(this, id, flags, viaBotId, replyTo, 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;
bool newBlock = blocks.isEmpty();
if (newBlock) {
@ -1553,7 +1557,7 @@ HistoryItem *History::addToHistory(const MTPMessage &msg) {
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;
bool newBlock = blocks.isEmpty();
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);
}
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;
bool newBlock = blocks.isEmpty();
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);
}
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;
bool newBlock = blocks.isEmpty();
if (newBlock) {
@ -1647,6 +1651,7 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
}
adding->attachToBlock(to, to->items.size());
to->items.push_back(adding);
adding->previousItemChanged();
setLastMessage(adding);
adding->y = to->height;
@ -1687,8 +1692,8 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
}
}
if (adding->hasReplyMarkup()) {
int32 markupFlags = App::replyMarkup(channelId(), adding->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || adding->mentionsMe()) {
MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), adding->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || adding->mentionsMe()) {
OrderedSet<PeerData*> *markupSenders = 0;
if (peer->isChat()) {
markupSenders = &peer->asChat()->markupSenders;
@ -1698,7 +1703,7 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
if (markupSenders) {
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())) {
clearLastKeyboard();
}
@ -1769,6 +1774,7 @@ void History::newItemAdded(HistoryItem *item) {
HistoryItem *History::addItemAfterPrevToBlock(HistoryItem *item, HistoryItem *prev, HistoryBlock *block) {
item->attachToBlock(block, block->items.size());
block->items.push_back(item);
item->previousItemChanged();
if (width) {
item->y = block->height;
block->height += item->resize(width);
@ -1902,13 +1908,13 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
if (item->author()->id) {
if (markupSenders) { // chats with bots
if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) {
int32 markupFlags = App::replyMarkup(channelId(), item->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || item->mentionsMe()) {
MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), item->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
bool wasKeyboardHide = markupSenders->contains(item->author());
if (!wasKeyboardHide) {
markupSenders->insert(item->author());
}
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO)) {
if (!(markupFlags & MTPDreplyKeyboardMarkup_ClientFlag::f_zero)) {
if (!lastKeyboardInited) {
bool botNotInChat = false;
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
int32 markupFlags = App::replyMarkup(channelId(), item->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || item->mentionsMe()) {
if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) {
MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), item->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
if (markupFlags & MTPDreplyKeyboardMarkup_ClientFlag::f_zero) {
clearLastKeyboard();
} else {
lastKeyboardInited = true;
@ -2219,6 +2225,7 @@ HistoryItem *History::addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex,
newItem->attachToBlock(block, itemIndex);
block->items.insert(itemIndex, newItem);
newItem->previousItemChanged();
for (int i = itemIndex + 1, l = block->items.size(); i < l; ++i) {
block->items.at(i)->setIndexInBlock(i);
}
@ -2389,9 +2396,12 @@ MsgId History::msgIdForRead() const {
return result;
}
int32 History::geomResize(int32 newWidth, int32 *ytransform, const HistoryItem *resizedItem) {
if (width != newWidth) resizedItem = 0; // recount all items
if (width != newWidth || resizedItem) {
int32 History::resize(int32 newWidth, int32 *ytransform) {
if (width != newWidth) _flags |= Flag::f_pending_resize;
bool force = (_flags | Flag::f_pending_resize);
_flags &= ~(Flag::f_pending_resize | Flag::f_has_pending_resized_items);
if (force || hasPendingResizedItems()) {
width = newWidth;
int32 y = 0;
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) {
block->y = y;
}
y += block->geomResize(newWidth, ytransform, resizedItem);
y += block->resize(newWidth, ytransform, force);
if (updTransform) {
*ytransform += block->y;
ytransform = 0;
@ -2645,13 +2655,13 @@ History::~History() {
deleteAndMark(editDraft);
}
int32 HistoryBlock::geomResize(int32 newWidth, int32 *ytransform, const HistoryItem *resizedItem) {
int32 HistoryBlock::resize(int32 newWidth, int32 *ytransform, bool force) {
int32 y = 0;
for_const (HistoryItem *item , items) {
bool updTransform = ytransform && (*ytransform >= item->y) && (*ytransform < item->y + item->height());
if (updTransform) *ytransform -= item->y;
item->y = y;
if (!resizedItem || resizedItem == item) {
if (force || item->pendingResize()) {
y += item->resize(newWidth);
} else {
y += item->height();
@ -2783,27 +2793,52 @@ void HistoryMessageUnreadBar::init(int count) {
_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) {
}
void HistoryMessageDate::init(const QDateTime &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)
, id(msgId)
, date(msgDate)
, _from(from ? App::user(from) : history->peer)
, _history(history)
, _flags(flags)
, _flags(flags | MTPDmessage_ClientFlag::f_pending_init_dimensions | MTPDmessage_ClientFlag::f_pending_resize)
, _authorNameVersion(author()->nameVersion) {
}
void HistoryItem::finishCreate() {
App::historyRegItem(this);
initDimensions();
}
void HistoryItem::destroy() {
@ -2827,18 +2862,18 @@ void HistoryItem::destroy() {
}
void HistoryItem::detach() {
if (_history) {
if (_history->unreadBar == this) {
_history->unreadBar = 0;
}
if (_history->isChannel()) {
_history->asChannelHistory()->messageDetached(this);
}
if (_history->unreadBar == this) {
_history->unreadBar = 0;
}
if (_history->isChannel()) {
_history->asChannelHistory()->messageDetached(this);
}
if (_block) {
_block->removeItem(this);
detachFast();
App::historyItemDetached(this);
_history->setPendingResize();
} else {
if (_history->showFrom == this) {
_history->showFrom = 0;
@ -2856,11 +2891,11 @@ void HistoryItem::previousItemChanged() {
if (!Is<HistoryMessageDate>()) {
AddInterfaces(HistoryMessageDate::Bit());
Get<HistoryMessageDate>()->init(date);
Global::RefPendingInitDimensionsItems().insert(this);
setPendingInitDimensions();
}
} else if (Is<HistoryMessageDate>()) {
RemoveInterfaces(HistoryMessageDate::Bit());
Global::RefPendingInitDimensionsItems().insert(this);
setPendingInitDimensions();
}
}
@ -2904,7 +2939,7 @@ bool HistoryItem::canEdit(const QDateTime &cur) const {
void HistoryItem::destroyUnreadBar() {
if (Is<HistoryMessageUnreadBar>()) {
RemoveInterfaces(HistoryMessageUnreadBar::Bit());
Global::RefPendingInitDimensionsItems().insert(this);
setPendingInitDimensions();
if (_history->unreadBar == this) {
_history->unreadBar = nullptr;
}
@ -2916,7 +2951,7 @@ void HistoryItem::setUnreadBarCount(int count) {
HistoryMessageUnreadBar *bar;
if (!Is<HistoryMessageUnreadBar>()) {
AddInterfaces(HistoryMessageUnreadBar::Bit());
Global::RefPendingInitDimensionsItems().insert(this);
setPendingInitDimensions();
bar = Get<HistoryMessageUnreadBar>();
} else {
bar = Get<HistoryMessageUnreadBar>();
@ -2959,8 +2994,7 @@ void HistoryItem::clipCallback(ClipReaderNotification notification) {
}
}
if (!stopped) {
initDimensions();
Notify::historyItemResized(this);
setPendingInitDimensions();
Notify::historyItemLayoutChanged(this);
}
} break;
@ -4516,8 +4550,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
_data->automaticLoad(parent);
bool loaded = _data->loaded(), displayLoading = (parent->id < 0) || _data->displayLoading();
if (loaded && !gif() && _gif != BadClipReader && cAutoPlayGif()) {
const_cast<HistoryGif*>(this)->playInline(const_cast<HistoryItem*>(parent));
if (gif()) _gif->setAutoplay();
Ui::autoplayMediaInlineAsync(parent->fullId());
}
int32 skipx = 0, skipy = 0, width = _width, height = _height;
@ -4711,7 +4744,7 @@ ImagePtr HistoryGif::replyPreview() {
return _data->makeReplyPreview();
}
bool HistoryGif::playInline(HistoryItem *parent) {
bool HistoryGif::playInline(HistoryItem *parent, bool autoplay) {
if (gif()) {
stopInline(parent);
} else {
@ -4720,6 +4753,7 @@ bool HistoryGif::playInline(HistoryItem *parent) {
}
_gif = new ClipReader(_data->location(), _data->data(), func(parent, &HistoryItem::clipCallback));
App::regGifItem(_gif, parent);
if (gif()) _gif->setAutoplay();
}
return true;
}
@ -4731,8 +4765,7 @@ void HistoryGif::stopInline(HistoryItem *parent) {
_gif = 0;
}
parent->initDimensions();
Notify::historyItemResized(parent);
parent->setPendingInitDimensions();
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());
}
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)
, _text(st::msgMinWidth)
, _textWidth(0)
@ -6080,36 +6113,36 @@ HistoryMessage::HistoryMessage(History *history, MsgId id, int32 flags, QDateTim
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)
: HistoryItem(history, id, flags, date, (flags & MTPDmessage::flag_from_id) ? from : 0)
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::f_from_id) ? from : 0)
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _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);
}
HistoryMessage::HistoryMessage(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) :
HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::flag_from_id) ? from : 0)
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::f_from_id) ? from : 0)
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _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);
setText(QString(), EntitiesInText());
}
HistoryMessage::HistoryMessage(History *history, MsgId msgId, int32 flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) :
HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::flag_from_id) ? from : 0)
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::f_from_id) ? from : 0)
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _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->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) {
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;
}
}
@ -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>();
if (!views || views->_views == count || (count >= 0 && views->_views > count)) return;
@ -6544,10 +6577,7 @@ void HistoryMessage::setViewsCount(int32 count, bool reinit) {
_textWidth = 0;
_textHeight = 0;
}
if (reinit) {
initDimensions();
Notify::historyItemResized(this);
}
setPendingInitDimensions();
}
}
@ -6562,8 +6592,7 @@ void HistoryMessage::setId(MsgId newId) {
_textWidth = 0;
_textHeight = 0;
}
initDimensions();
Notify::historyItemResized(this);
setPendingInitDimensions();
}
}
@ -6572,6 +6601,24 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
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;
if (animms > 0 && animms <= ms) {
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 o = p.opacity();
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);
}
}
int32 left = 0, width = 0;
countPositionAndSize(left, width);
if (displayFromPhoto()) {
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) {
const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>();
@ -6602,7 +6645,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
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 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);
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);
_media->draw(p, this, r.translated(-left, -top), selected, ms);
p.restore();
p.translate(-left, -top);
if (!_media->customInfoLayout()) {
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);
}
} else {
p.save();
int32 top = st::msgMargin.top();
p.translate(left, top);
_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();
@ -6689,7 +6733,7 @@ void HistoryMessage::destroy() {
HistoryItem::destroy();
}
int32 HistoryMessage::resize(int32 width) {
int HistoryMessage::resizeImpl(int width) {
if (width < st::msgMinWidth) return _height;
width -= st::msgMargin.left() + st::msgMargin.right();
@ -6757,16 +6801,33 @@ int32 HistoryMessage::resize(int32 width) {
_height = _media->resize(width, this);
}
_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;
}
bool HistoryMessage::hasPoint(int32 x, int32 y) const {
int32 left = 0, width = 0;
int left = 0, width = 0, height = _height;
countPositionAndSize(left, width);
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()) {
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);
} else {
return _media->hasPoint(x - left, y - st::msgMargin.top(), this);
@ -6794,12 +6855,23 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
lnk = TextLinkPtr();
state = HistoryDefaultCursorState;
int32 left = 0, width = 0;
int left = 0, width = 0, height = _height;
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()) {
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;
return;
}
@ -6810,7 +6882,7 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>();
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 (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()) {
@ -6897,14 +6969,25 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x,
after = false;
upon = false;
if (drawBubble()) {
int32 left = 0, width = 0;
int left = 0, width = 0, height = _height;
countPositionAndSize(left, width);
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 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
r.setTop(r.top() + st::msgNameFont->height);
} else if (via && !fwd) {
@ -6963,7 +7046,7 @@ HistoryMessage::~HistoryMessage() {
_media->detachFromItem(this);
deleteAndMark(_media);
}
if (_flags & MTPDmessage::flag_reply_markup) {
if (_flags & MTPDmessage::Flag::f_reply_markup) {
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)
, replyToMsgId(replyTo)
, 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)
, replyToMsgId(replyTo)
, replyToMsg(0)
@ -7053,8 +7136,7 @@ bool HistoryReply::updateReplyTo(bool force) {
replyToMsgId = 0;
}
if (force) {
initDimensions();
Notify::historyItemResized(this);
setPendingInitDimensions();
}
return (replyToMsg || !replyToMsgId);
}
@ -7178,8 +7260,8 @@ void HistoryReply::drawMessageText(Painter &p, QRect trect, uint32 selection) co
HistoryMessage::drawMessageText(p, trect, selection);
}
int32 HistoryReply::resize(int32 width) {
HistoryMessage::resize(width);
int32 HistoryReply::resizeImpl(int32 width) {
HistoryMessage::resizeImpl(width);
if (drawBubble()) {
if (emptyText() && !displayFromName() && !Is<HistoryMessageVia>()) {
@ -7405,7 +7487,7 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
} break;
case mtpc_messageActionChatMigrateTo: {
_flags |= MTPDmessage_flag_IS_GROUP_MIGRATE;
_flags |= MTPDmessage_ClientFlag::f_is_group_migrate;
const MTPDmessageActionChatMigrateTo &d(action.c_messageActionChatMigrateTo());
if (true/*PeerData *channel = App::peerLoaded(peerFromChannel(d.vchannel_id))*/) {
text = lang(lng_action_group_migrate);
@ -7415,7 +7497,7 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
} break;
case mtpc_messageActionChannelMigrateFrom: {
_flags |= MTPDmessage_flag_IS_GROUP_MIGRATE;
_flags |= MTPDmessage_ClientFlag::f_is_group_migrate;
const MTPDmessageActionChannelMigrateFrom &d(action.c_messageActionChannelMigrateFrom());
if (true/*PeerData *chat = App::peerLoaded(peerFromChannel(d.vchat_id))*/) {
text = lang(lng_action_group_migrate);
@ -7478,8 +7560,7 @@ bool HistoryServiceMsg::updatePinned(bool force) {
updatePinnedText();
}
if (force) {
initDimensions();
Notify::historyItemResized(this);
setPendingInitDimensions();
if (gotDependencyItem && App::wnd()) {
App::wnd()->notifySettingGot();
}
@ -7560,7 +7641,7 @@ bool HistoryServiceMsg::updatePinnedText(const QString *pfrom, QString *ptext) {
}
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)
, _media(0) {
if (msg.has_reply_to_msg_id()) {
@ -7573,7 +7654,7 @@ HistoryServiceMsg::HistoryServiceMsg(History *history, const MTPDmessageService
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)
, _text(st::msgServiceFont, msg, _historySrvOptions, st::dlgMinWidth)
, _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);
p.setBrush(Qt::NoBrush);
p.setPen(st::msgServiceColor->p);
p.setFont(st::msgServiceFont->f);
p.setPen(st::msgServiceColor);
p.setFont(st::msgServiceFont);
uint16 selectedFrom = (selection == FullSelection) ? 0 : (selection >> 16) & 0xFFFF;
uint16 selectedTo = (selection == FullSelection) ? 0 : selection & 0xFFFF;
_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignCenter, 0, -1, selectedFrom, selectedTo);
textstyleRestore();
}
int32 HistoryServiceMsg::resize(int32 width) {
int32 HistoryServiceMsg::resizeImpl(int32 width) {
int32 maxwidth = _history->width;
if (Adaptive::Wide()) {
maxwidth = qMin(maxwidth, int32(st::msgMaxWidth + 2 * st::msgPhotoSkip));
@ -7861,7 +7942,7 @@ void HistoryCollapse::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
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) {
textstyleSet(&st::serviceTextStyle);
if (peerToUser(inviter->id) == MTP::authedId()) {

View file

@ -242,16 +242,16 @@ public:
virtual ~History();
HistoryItem *createItem(HistoryBlock *block, const MTPMessage &msg, bool applyServiceAction);
HistoryItem *createItemForwarded(MsgId id, int32 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 *createItemPhoto(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
HistoryItem *createItemForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *msg);
HistoryItem *createItemDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, 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 *addToHistory(const MTPMessage &msg);
HistoryItem *addNewForwarded(MsgId id, int32 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 *addNewPhoto(MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
HistoryItem *addNewForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *item);
HistoryItem *addNewDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, 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 addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed);
@ -309,7 +309,7 @@ public:
MsgId maxMsgId() 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) {
if (!notifies.isEmpty()) {
@ -336,6 +336,15 @@ public:
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;
bool updateTyping(uint64 ms, bool force = false);
void clearLastKeyboard();
@ -433,6 +442,19 @@ protected:
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;
uint64 _sortKeyInChatList; // like ((unixtime) << 32) | (incremented counter)
@ -822,7 +844,7 @@ public:
}
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;
History *history;
@ -877,8 +899,8 @@ enum InfoDisplayType {
InfoDisplayOverImage,
};
inline bool isImportantChannelMessage(MsgId id, int32 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);
inline bool isImportantChannelMessage(MsgId id, MTPDmessage::Flags flags) { // client-side important msgs always has_views or has_from_id
return (flags & MTPDmessage::Flag::f_out) || (flags & MTPDmessage::Flag::f_mentioned) || (flags & MTPDmessage::Flag::f_post);
}
enum HistoryItemType {
@ -942,6 +964,9 @@ struct HistoryMessageDate : public BasicInterface<HistoryMessageDate> {
HistoryMessageDate(Interfaces *);
void init(const QDateTime &date);
int height() const;
void paint(Painter &p, int y, int w) const;
QString _text;
int _width;
};
@ -952,6 +977,9 @@ struct HistoryMessageUnreadBar : public BasicInterface<HistoryMessageUnreadBar>
HistoryMessageUnreadBar(Interfaces *);
void init(int count);
int height() const;
void paint(Painter &p, int y, int w) const;
QString _text;
int _width;
@ -971,8 +999,16 @@ public:
HistoryItem(const HistoryItem &) = delete;
HistoryItem &operator=(const HistoryItem &) = delete;
virtual void initDimensions() = 0;
virtual int32 resize(int32 width) = 0; // return new height
int resize(int width) {
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 dependencyItemRemoved(HistoryItem *dependency) {
@ -1011,14 +1047,18 @@ public:
}
void attachToBlock(HistoryBlock *block, int index) {
t_assert(_block == nullptr && _indexInBlock < 0);
_block = block;
_indexInBlock = index;
if (pendingResize()) {
_history->setHasPendingResizedItems();
}
}
void setIndexInBlock(int index) {
_indexInBlock = index;
}
bool out() const {
return _flags & MTPDmessage::flag_out;
return _flags & MTPDmessage::Flag::f_out;
}
bool unread() const {
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 (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 {
return _flags & MTPDmessage::flag_mentioned;
return _flags & MTPDmessage::Flag::f_mentioned;
}
bool isMediaUnread() const {
return (_flags & MTPDmessage::flag_media_unread) && (channelId() == NoChannel);
return (_flags & MTPDmessage::Flag::f_media_unread) && (channelId() == NoChannel);
}
void markMediaRead() {
_flags &= ~MTPDmessage::flag_media_unread;
_flags &= ~MTPDmessage::Flag::f_media_unread;
}
bool hasReplyMarkup() const {
return _flags & MTPDmessage::flag_reply_markup;
return _flags & MTPDmessage::Flag::f_reply_markup;
}
bool hasTextLinks() const {
return _flags & MTPDmessage_flag_HAS_TEXT_LINKS;
return _flags & MTPDmessage_ClientFlag::f_has_text_links;
}
bool isGroupMigrate() const {
return _flags & MTPDmessage_flag_IS_GROUP_MIGRATE;
return _flags & MTPDmessage_ClientFlag::f_is_group_migrate;
}
bool hasViews() const {
return _flags & MTPDmessage::flag_views;
return _flags & MTPDmessage::Flag::f_views;
}
bool isPost() const {
return _flags & MTPDmessage::flag_post;
return _flags & MTPDmessage::Flag::f_post;
}
bool isImportant() const {
return _history->isChannel() && isImportantChannelMessage(id, _flags);
@ -1061,7 +1101,7 @@ public:
return (id > 0) && (!history()->isChannel() || history()->isMegagroup() || isPost());
}
bool isSilent() const {
return _flags & MTPDmessage::flag_silent;
return _flags & MTPDmessage::Flag::f_silent;
}
virtual int32 viewsCount() const {
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 setViewsCount(int32 count, bool reinit = true) {
virtual void setViewsCount(int32 count) {
}
virtual void setId(MsgId newId);
virtual void setDate(const QDateTime &date) { // for date items
@ -1131,7 +1171,7 @@ public:
bool canDelete() const {
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 (channel->amCreator()) return true;
@ -1255,24 +1295,44 @@ public:
// when the new messages arrive in this chat history
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);
virtual ~HistoryItem();
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
// call a virtual initDimensions() method,
// that can not be done from constructor
void finishCreate();
// to completely create history item we need to call
// a virtual method, it can not be done from constructor
virtual 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;
History *_history;
HistoryBlock *_block = nullptr;
int _indexInBlock = -1;
int32 _flags;
MTPDmessage::Flags _flags;
mutable int32 _authorNameVersion;
@ -1301,7 +1361,7 @@ protected:
// make all the constructors in HistoryItem children protected
// and wrapped with a static create() call with the same args
// 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>
class HistoryItemInstantiated {
public:
@ -1422,7 +1482,10 @@ public:
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;
}
virtual void stopInline(HistoryItem *item) {
@ -1851,8 +1914,8 @@ public:
return gif();
}
bool playInline(HistoryItem *item);
void stopInline(HistoryItem *item);
bool playInline(HistoryItem *item, bool autoplay) override;
void stopInline(HistoryItem *item) override;
void attachToItem(HistoryItem *item) override;
void detachFromItem(HistoryItem *item) override;
@ -1894,10 +1957,10 @@ private:
ClipReader *_gif;
ClipReader *gif() {
return (_gif == BadClipReader) ? 0 : _gif;
return (_gif == BadClipReader) ? nullptr : _gif;
}
const ClipReader *gif() const {
return (_gif == BadClipReader) ? 0 : _gif;
return (_gif == BadClipReader) ? nullptr : _gif;
}
void setStatusSize(int32 newSize) const;
@ -2057,10 +2120,10 @@ public:
ClipReader *getClipReader() {
return _attach ? _attach->getClipReader() : 0;
}
bool playInline(HistoryItem *item) {
return _attach ? _attach->playInline(item) : false;
bool playInline(HistoryItem *item, bool autoplay) override {
return _attach ? _attach->playInline(item, autoplay) : false;
}
void stopInline(HistoryItem *item) {
void stopInline(HistoryItem *item) override {
if (_attach) _attach->stopInline(item);
}
@ -2209,23 +2272,22 @@ public:
static HistoryMessage *create(History *history, const MTPDmessage &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);
}
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);
}
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);
}
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);
}
void initTime();
void initMedia(const MTPMessageMedia *media, QString &currentText);
void initMediaFromDocument(DocumentData *doc, const QString &caption);
void initDimensions() override;
void fromNameUpdated(int32 width) 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 setViewsCount(int32 count, bool reinit = true);
void setViewsCount(int32 count);
void setId(MsgId newId);
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override;
@ -2263,7 +2325,6 @@ public:
void destroy();
int32 resize(int32 width);
bool hasPoint(int32 x, int32 y) const;
bool pointInTime(int32 right, int32 bottom, int32 x, int32 y, InfoDisplayType type) const;
@ -2285,12 +2346,13 @@ public:
QString notificationHeader() 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) {
_media->updateFrom(*media, this);
} else {
setMedia(media);
}
setPendingInitDimensions();
}
int32 addToOverview(AddToOverviewMethod method);
void eraseFromOverview();
@ -2348,12 +2410,15 @@ public:
protected:
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, int32 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, int32 flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption); // local photo
HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *fwd); // local forwarded
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, MTPDmessage::Flags 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, PhotoData *photo, const QString &caption); // local photo
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);
bool displayForwardedFrom() const {
@ -2380,15 +2445,13 @@ public:
static HistoryReply *create(History *history, const MTPDmessage &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);
}
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);
}
void initDimensions() override;
bool updateDependencyItem() override {
return updateReplyTo(true);
}
@ -2406,7 +2469,6 @@ public:
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 drawMessageText(Painter &p, QRect trect, uint32 selection) const override;
int32 resize(int32 width) override;
void resizeVia(int32 w) const;
bool hasPoint(int32 x, int32 y) const override;
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const override;
@ -2430,11 +2492,14 @@ public:
protected:
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, 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, DocumentData *doc, 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;
friend class HistoryItemInstantiated<HistoryReply>;
void initDimensions() override;
int resizeImpl(int width) override;
bool updateReplyTo(bool force = false);
void replyToNameUpdated() const;
@ -2449,18 +2514,28 @@ protected:
};
inline int32 newMessageFlags(PeerData *p) {
return p->isSelf() ? 0 : (((p->isChat() || (p->isUser() && !p->asUser()->botInfo)) ? MTPDmessage::flag_unread : 0) | MTPDmessage::flag_out);
inline MTPDmessage::Flags newMessageFlags(PeerData *p) {
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) {
int32 result = newMessageFlags(p) | (from ? MTPDmessage::flag_from_id : 0);
inline MTPDmessage::Flags newForwardedFlags(PeerData *p, int32 from, HistoryMessage *fwd) {
MTPDmessage::Flags result = newMessageFlags(p);
if (from) {
result |= MTPDmessage::Flag::f_from_id;
}
if (fwd->Is<HistoryMessageVia>()) {
result |= MTPDmessage::flag_via_bot_id;
result |= MTPDmessage::Flag::f_via_bot_id;
}
if (!p->isChannel()) {
if (HistoryMedia *media = fwd->getMedia()) {
if (media->type() == MediaTypeVoiceFile) {
result |= MTPDmessage::flag_media_unread;
result |= MTPDmessage::Flag::f_media_unread;
// } else if (media->type() == MediaTypeVideo) {
// result |= MTPDmessage::flag_media_unread;
}
@ -2483,12 +2558,10 @@ public:
static HistoryServiceMsg *create(History *history, const MTPDmessageService &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);
}
void initDimensions() override;
bool updateDependencyItem() override {
return updatePinned(true);
}
@ -2508,7 +2581,6 @@ public:
void countPositionAndSize(int32 &left, int32 &width) const;
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;
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;
@ -2545,9 +2617,12 @@ public:
protected:
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>;
void initDimensions() override;
int resizeImpl(int width) override;
void setMessageByAction(const MTPmessageAction &action);
bool updatePinned(bool force = false);
bool updatePinnedText(const QString *pfrom = nullptr, QString *ptext = nullptr);
@ -2652,7 +2727,7 @@ private:
class HistoryJoined : public HistoryServiceMsg, private HistoryItemInstantiated<HistoryJoined> {
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);
}
@ -2662,7 +2737,7 @@ public:
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;
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 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 (resizedItem) {
if (resizedItem->history() == _history) {
_history->geomResize(_scroll->width(), &st1, resizedItem);
} 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);
}
_history->resize(_scroll->width(), &st1);
if (_migrated) {
_migrated->resize(_scroll->width(), &st2);
}
int32 skip = 0;
if (_migrated) { // check first messages of _history - maybe no need to display them
if (!_migrated->isEmpty() && !_history->isEmpty() && _migrated->loadedAtBottom() && _history->loadedAtTop()) {
@ -2147,9 +2140,9 @@ bool BotKeyboard::updateMarkup(HistoryItem *to) {
clearSelection();
_btns.clear();
const ReplyMarkup &markup(App::replyMarkup(to->channelId(), to->id));
_forceReply = markup.flags & MTPDreplyKeyboardMarkup_flag_FORCE_REPLY;
_maximizeSize = !(markup.flags & MTPDreplyKeyboardMarkup::flag_resize);
_singleUse = _forceReply || (markup.flags & MTPDreplyKeyboardMarkup::flag_single_use);
_forceReply = markup.flags & MTPDreplyKeyboardMarkup_ClientFlag::f_force_reply;
_maximizeSize = !(markup.flags & MTPDreplyKeyboardMarkup::Flag::f_resize);
_singleUse = _forceReply || (markup.flags & MTPDreplyKeyboardMarkup::Flag::f_single_use);
const ReplyMarkup::Commands &commands(markup.commands);
if (!commands.isEmpty()) {
@ -3182,7 +3175,7 @@ void HistoryWidget::onRecordUpdate(quint16 level, qint32 samples) {
}
void HistoryWidget::updateStickers() {
if (!cLastStickersUpdate() || getms(true) >= cLastStickersUpdate() + StickersUpdateTimeout) {
if (!Global::LastStickersUpdate() || getms(true) >= Global::LastStickersUpdate() + StickersUpdateTimeout) {
if (!_stickersUpdateRequest) {
_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();
}
void HistoryWidget::notify_historyItemResized(const HistoryItem *row, bool scrollToIt) {
updateListSize(false, false, { ScrollChangeNone, 0 }, row, scrollToIt);
}
void HistoryWidget::cmd_search() {
if (!inFocusChain() || !_peer) return;
@ -3265,7 +3254,7 @@ void HistoryWidget::cmd_previous_chat() {
}
void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
cSetLastStickersUpdate(getms(true));
Global::SetLastStickersUpdate(getms(true));
_stickersUpdateRequest = 0;
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);
StickerSetsOrder &setsOrder(cRefStickerSetsOrder());
Stickers::Order &setsOrder(Global::RefStickerSetsOrder());
setsOrder.clear();
StickerSets &sets(cRefStickerSets());
Stickers::Sets &sets(Global::RefStickerSets());
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
}
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) {
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);
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 {
it->access = set.vaccess_hash.v;
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()) {
it->count = set.vcount.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);
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);
}
}
@ -3309,8 +3298,8 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
}
bool writeRecent = false;
RecentStickerPack &recent(cGetRecentStickers());
for (StickerSets::iterator it = sets.begin(), e = sets.end(); it != e;) {
if (it->id == CustomStickerSetId || it->access != 0) {
for (Stickers::Sets::iterator it = sets.begin(), e = sets.end(); it != e;) {
if (it->id == Stickers::CustomSetId || it->access != 0) {
++it;
} else {
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!"));
cSetLastStickersUpdate(getms(true));
Global::SetLastStickersUpdate(getms(true));
_stickersUpdateRequest = 0;
return true;
}
@ -3770,7 +3759,7 @@ void HistoryWidget::updateNotifySettings() {
_muteUnmute.setText(lang(_history->mute ? lng_channel_unmute : lng_channel_mute));
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()) {
updateControlsVisibility();
}
@ -4610,15 +4599,15 @@ void HistoryWidget::saveEditMsg() {
return;
}
int32 sendFlags = 0;
MTPchannels_EditMessage::Flags sendFlags = 0;
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);
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) {
@ -4798,32 +4787,32 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
fastShowAtEnd(h);
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));
int32 sendFlags = 0;
MTPmessages_SendMedia::Flags sendFlags = 0;
if (replyTo) {
flags |= MTPDmessage::flag_reply_to_msg_id;
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
flags |= MTPDmessage::Flag::f_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 showFromName = !channelPost || p->asChannel()->addsSignature();
bool silentPost = channelPost && _silent.checked();
if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast;
flags |= MTPDmessage::flag_views;
flags |= MTPDmessage::flag_post;
sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::Flag::f_post;
}
if (showFromName) {
flags |= MTPDmessage::flag_from_id;
flags |= MTPDmessage::Flag::f_from_id;
}
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->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->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_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);
@ -5822,30 +5811,30 @@ void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShif
fastShowAtEnd(h);
int32 flags = newMessageFlags(h->peer) | MTPDmessage::flag_media; // unread, out
if (file->to.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
MTPDmessage::Flags flags = newMessageFlags(h->peer) | MTPDmessage::Flag::f_media; // unread, out
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 showFromName = !channelPost || h->peer->asChannel()->addsSignature();
bool silentPost = channelPost && file->to.silent;
if (channelPost) {
flags |= MTPDmessage::flag_views;
flags |= MTPDmessage::flag_post;
flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::Flag::f_post;
}
if (showFromName) {
flags |= MTPDmessage::flag_from_id;
flags |= MTPDmessage::Flag::f_from_id;
}
if (silentPost) {
flags |= MTPDmessage::flag_silent;
flags |= MTPDmessage::Flag::f_silent;
}
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) {
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) {
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) {
@ -5891,21 +5880,21 @@ void HistoryWidget::onPhotoUploaded(const FullMsgId &newId, bool silent, const M
App::historyRegRandom(randomId, newId);
History *hist = item->history();
MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
int32 sendFlags = 0;
MTPmessages_SendMedia::Flags sendFlags = 0;
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 silentPost = channelPost && silent;
if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast;
sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
}
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::flag_silent;
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
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()) {
attributes.push_back(MTP_documentAttributeSticker(MTP_string(document->sticker()->alt), document->sticker()->set));
} 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()) {
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);
}
@ -5943,21 +5932,21 @@ void HistoryWidget::onDocumentUploaded(const FullMsgId &newId, bool silent, cons
App::historyRegRandom(randomId, newId);
History *hist = item->history();
MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
int32 sendFlags = 0;
MTPmessages_SendMedia::Flags sendFlags = 0;
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 silentPost = channelPost && silent;
if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast;
sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
}
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::flag_silent;
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
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);
History *hist = item->history();
MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
int32 sendFlags = 0;
MTPmessages_SendMedia::Flags sendFlags = 0;
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 silentPost = channelPost && silent;
if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast;
sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
}
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::flag_silent;
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
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();
}
void HistoryWidget::notify_handlePendingHistoryUpdate() {
if (_history && _history->hasPendingResizedItems()) {
updateListSize();
_list->update();
}
}
void HistoryWidget::resizeEvent(QResizeEvent *e) {
_reportSpamPanel.resize(width(), _reportSpamPanel.height());
@ -6295,10 +6291,9 @@ MsgId HistoryWidget::replyToId() const {
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 (_firstLoadRequest) {
if (resizedItem) _list->recountHeight(resizedItem);
return; // scrollTopMax etc are not working after recountHeight()
}
@ -6330,25 +6325,13 @@ void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollCh
if (!initial) {
_history->lastScrollTop = _scroll.scrollTop();
}
int32 newSt = _list->recountHeight(resizedItem);
int32 newSt = _list->recountHeight();
bool washidden = _scroll.isHidden();
if (washidden) {
_scroll.show();
}
_list->updateSize();
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) {
_scroll.hide();
}
@ -6692,28 +6675,28 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
bool lastKeyboardUsed = lastForceReplyReplied();
bool out = !_peer->isSelf(), unread = !_peer->isSelf();
int32 flags = newMessageFlags(_peer) | MTPDmessage::flag_media; // unread, out
int32 sendFlags = 0;
MTPDmessage::Flags flags = newMessageFlags(_peer) | MTPDmessage::Flag::f_media; // unread, out
MTPmessages_SendInlineBotResult::Flags sendFlags = 0;
if (replyToId()) {
flags |= MTPDmessage::flag_reply_to_msg_id;
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
flags |= MTPDmessage::Flag::f_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 showFromName = !channelPost || _peer->asChannel()->addsSignature();
bool silentPost = channelPost && _silent.checked();
if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast;
flags |= MTPDmessage::flag_views;
flags |= MTPDmessage::flag_post;
sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_broadcast;
flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::Flag::f_post;
}
if (showFromName) {
flags |= MTPDmessage::flag_from_id;
flags |= MTPDmessage::Flag::f_from_id;
}
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::flag_silent;
sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_silent;
}
if (bot) {
flags |= MTPDmessage::flag_via_bot_id;
flags |= MTPDmessage::Flag::f_via_bot_id;
}
if (result->message.isEmpty()) {
@ -6750,7 +6733,7 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
App::feedDocument(document, thumb);
}
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")) {
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));
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 {
flags |= MTPDmessage::flag_entities;
if (result->noWebPage) {
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);
flags |= MTPDmessage::Flag::f_entities;
_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);
}
_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());
cancelReply(lastKeyboardUsed);
@ -6916,29 +6896,29 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti
bool lastKeyboardUsed = lastForceReplyReplied();
bool out = !_peer->isSelf(), unread = !_peer->isSelf();
int32 flags = newMessageFlags(_peer) | MTPDmessage::flag_media; // unread, out
int32 sendFlags = 0;
MTPDmessage::Flags flags = newMessageFlags(_peer) | MTPDmessage::Flag::f_media; // unread, out
MTPmessages_SendMedia::Flags sendFlags = 0;
if (replyToId()) {
flags |= MTPDmessage::flag_reply_to_msg_id;
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
flags |= MTPDmessage::Flag::f_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 showFromName = !channelPost || _peer->asChannel()->addsSignature();
bool silentPost = channelPost && _silent.checked();
if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast;
flags |= MTPDmessage::flag_views;
flags |= MTPDmessage::flag_post;
sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::Flag::f_post;
}
if (showFromName) {
flags |= MTPDmessage::flag_from_id;
flags |= MTPDmessage::Flag::f_from_id;
}
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->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());
cancelReply(lastKeyboardUsed);
@ -6972,29 +6952,29 @@ void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption)
bool lastKeyboardUsed = lastForceReplyReplied();
bool out = !_peer->isSelf(), unread = !_peer->isSelf();
int32 flags = newMessageFlags(_peer) | MTPDmessage::flag_media; // unread, out
int32 sendFlags = 0;
MTPDmessage::Flags flags = newMessageFlags(_peer) | MTPDmessage::Flag::f_media; // unread, out
MTPmessages_SendMedia::Flags sendFlags = 0;
if (replyToId()) {
flags |= MTPDmessage::flag_reply_to_msg_id;
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
flags |= MTPDmessage::Flag::f_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 showFromName = !channelPost || _peer->asChannel()->addsSignature();
bool silentPost = channelPost && _silent.checked();
if (channelPost) {
sendFlags |= MTPmessages_SendMedia::flag_broadcast;
flags |= MTPDmessage::flag_views;
flags |= MTPDmessage::flag_post;
sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::Flag::f_post;
}
if (showFromName) {
flags |= MTPDmessage::flag_from_id;
flags |= MTPDmessage::Flag::f_from_id;
}
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->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());
cancelReply(lastKeyboardUsed);
@ -7145,7 +7125,8 @@ void HistoryWidget::onUnpinMessageSure() {
}
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) {
@ -7535,7 +7516,6 @@ void HistoryWidget::onDeleteSelectedSure() {
for (SelectedItemSet::const_iterator i = sel.cbegin(), e = sel.cend(); i != e; ++i) {
i.value()->destroy();
}
Notify::historyItemsResized();
Ui::hideLayer();
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);
}
Notify::historyItemsResized();
Ui::hideLayer();
if (wasOnServer) {

View file

@ -66,7 +66,7 @@ public:
void touchScrollUpdated(const QPoint &screenPos);
QPoint mapMouseToItem(QPoint p, HistoryItem *item);
int32 recountHeight(const HistoryItem *resizedItem);
int32 recountHeight();
void updateSize();
void repaintItem(const HistoryItem *item);
@ -589,13 +589,13 @@ public:
bool ui_isInlineItemBeingChosen();
void notify_historyItemLayoutChanged(const HistoryItem *item);
void notify_automaticLoadSettingsChangedGif();
void notify_botCommandsChanged(UserData *user);
void notify_inlineBotRequesting(bool requesting);
void notify_userIsBotChanged(UserData *user);
void notify_migrateUpdated(PeerData *peer);
void notify_clipStopperHidden(ClipStopperType type);
void notify_historyItemResized(const HistoryItem *item, bool scrollToIt);
void notify_automaticLoadSettingsChangedGif();
void notify_handlePendingHistoryUpdate();
void cmd_search();
void cmd_next_chat();
@ -798,7 +798,7 @@ private:
ScrollChangeType type;
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);

View file

@ -230,8 +230,8 @@ void IntroPhone::phoneCheckDone(const MTPauth_CheckedPhone &result) {
checkRequest.start(1000);
int32 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));
MTPauth_SendCode::Flags flags = 0;
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 {
showError(lang(lng_bad_phone_noreg), true);
enableAll(true);
@ -271,8 +271,8 @@ void IntroPhone::toSignUp() {
checkRequest.start(1000);
int32 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));
MTPauth_SendCode::Flags flags = 0;
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) {

View file

@ -411,7 +411,7 @@ void FileLoadTask::process() {
}
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);
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 {

View file

@ -864,7 +864,7 @@ namespace {
}
}
mtpDcOptions *_dcOpts = 0;
MTP::DcOptions *_dcOpts = 0;
bool _readSetting(quint32 blockId, QDataStream &stream, int version) {
switch (blockId) {
case dbiDcOptionOld: {
@ -873,16 +873,17 @@ namespace {
stream >> dcId >> host >> ip >> port;
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;
case dbiDcOption: {
quint32 dcIdWithShift, flags, port;
quint32 dcIdWithShift, port;
qint32 flags;
QString ip;
stream >> dcIdWithShift >> flags >> ip >> port;
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;
case dbiChatSizeMax: {
@ -1462,16 +1463,16 @@ namespace {
LOG(("App Info: reading old user config.."));
qint32 version = 0;
mtpDcOptions dcOpts;
MTP::DcOptions dcOpts;
{
QReadLocker lock(MTP::dcOptionsMutex());
dcOpts = cDcOptions();
dcOpts = Global::DcOptions();
}
_dcOpts = &dcOpts;
_readOldUserSettingsFields(&file, version);
{
QWriteLocker lock(MTP::dcOptionsMutex());
cSetDcOptions(dcOpts);
Global::SetDcOptions(dcOpts);
}
file.close();
@ -1549,16 +1550,16 @@ namespace {
LOG(("App Info: reading old keys.."));
qint32 version = 0;
mtpDcOptions dcOpts;
MTP::DcOptions dcOpts;
{
QReadLocker lock(MTP::dcOptionsMutex());
dcOpts = cDcOptions();
dcOpts = Global::DcOptions();
}
_dcOpts = &dcOpts;
_readOldMtpDataFields(&file, version);
{
QWriteLocker lock(MTP::dcOptionsMutex());
cSetDcOptions(dcOpts);
Global::SetDcOptions(dcOpts);
}
file.close();
@ -2116,10 +2117,10 @@ namespace Local {
LOG(("App Error: could not decrypt settings from settings file, maybe bad passcode.."));
return writeSettings();
}
mtpDcOptions dcOpts;
MTP::DcOptions dcOpts;
{
QReadLocker lock(MTP::dcOptionsMutex());
dcOpts = cDcOptions();
dcOpts = Global::DcOptions();
}
_dcOpts = &dcOpts;
LOG(("App Info: reading encrypted settings.."));
@ -2137,20 +2138,23 @@ namespace Local {
if (dcOpts.isEmpty()) {
const BuiltInDc *bdcs = builtInDcs();
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));
}
const BuiltInDc *bdcsipv6 = builtInDcsIPv6();
for (int i = 0, l = builtInDcsCountIPv6(); i < l; ++i) {
int32 flags = MTPDdcOption::flag_ipv6, idWithShift = bdcsipv6[i].id + (flags * _mtp_internal::dcShift);
dcOpts.insert(idWithShift, mtpDcOption(bdcsipv6[i].id, flags, 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));
}
}
{
QWriteLocker lock(MTP::dcOptionsMutex());
cSetDcOptions(dcOpts);
Global::SetDcOptions(dcOpts);
}
_oldSettingsVersion = settingsData.version;
@ -2173,30 +2177,34 @@ namespace Local {
}
settings.writeData(_settingsSalt);
mtpDcOptions dcOpts;
MTP::DcOptions dcOpts;
{
QReadLocker lock(MTP::dcOptionsMutex());
dcOpts = cDcOptions();
dcOpts = Global::DcOptions();
}
if (dcOpts.isEmpty()) {
const BuiltInDc *bdcs = builtInDcs();
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));
}
const BuiltInDc *bdcsipv6 = builtInDcsIPv6();
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));
}
QWriteLocker lock(MTP::dcOptionsMutex());
cSetDcOptions(dcOpts);
Global::SetDcOptions(dcOpts);
}
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) + _stringSize(QString::fromUtf8(i->ip.data(), i->ip.size()));
}
@ -2223,9 +2231,9 @@ namespace Local {
data.stream << quint32(dbiLastUpdateCheck) << qint32(cLastUpdateCheck());
data.stream << quint32(dbiScale) << qint32(cConfigScale());
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(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(dbiLangFile) << cLangFile();
@ -3019,10 +3027,10 @@ namespace Local {
}
void _writeStickerSet(QDataStream &stream, uint64 setId) {
StickerSets::const_iterator it = cStickerSets().constFind(setId);
if (it == cStickerSets().cend()) return;
auto it = Global::StickerSets().constFind(setId);
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) {
stream << quint64(it->id) << quint64(it->access) << it->title << it->shortName << qint32(-it->count) << qint32(it->hash) << qint32(it->flags);
return;
@ -3063,7 +3071,7 @@ namespace Local {
void writeStickers() {
if (!_working()) return;
const StickerSets &sets(cStickerSets());
const Stickers::Sets &sets(Global::StickerSets());
if (sets.isEmpty()) {
if (_stickersKey) {
clearKey(_stickersKey);
@ -3075,10 +3083,10 @@ namespace Local {
int32 setsCount = 0;
QByteArray hashToWrite;
quint32 size = sizeof(quint32) + _bytearraySize(hashToWrite);
for (StickerSets::const_iterator i = sets.cbegin(); i != sets.cend(); ++i) {
bool notLoaded = (i->flags & MTPDstickerSet_flag_NOT_LOADED);
for (auto i = sets.cbegin(); i != sets.cend(); ++i) {
bool notLoaded = (i->flags & MTPDstickerSet_ClientFlag::f_not_loaded);
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;
}
} else {
@ -3114,8 +3122,8 @@ namespace Local {
}
EncryptedDescriptor data(size);
data.stream << quint32(setsCount) << hashToWrite;
_writeStickerSet(data.stream, CustomStickerSetId);
for (StickerSetsOrder::const_iterator i = cStickerSetsOrder().cbegin(), e = cStickerSetsOrder().cend(); i != e; ++i) {
_writeStickerSet(data.stream, Stickers::CustomSetId);
for (auto i = Global::StickerSetsOrder().cbegin(), e = Global::StickerSetsOrder().cend(); i != e; ++i) {
_writeStickerSet(data.stream, *i);
}
FileWriteDescriptor file(_stickersKey);
@ -3134,17 +3142,17 @@ namespace Local {
return;
}
StickerSets &sets(cRefStickerSets());
Stickers::Sets &sets(Global::RefStickerSets());
sets.clear();
StickerSetsOrder &order(cRefStickerSetsOrder());
Stickers::Order &order(Global::RefStickerSetsOrder());
order.clear();
RecentStickerPack &recent(cRefRecentStickers());
recent.clear();
StickerSet &def(sets.insert(DefaultStickerSetId, StickerSet(DefaultStickerSetId, 0, lang(lng_stickers_default_set), QString(), 0, 0, MTPDstickerSet::flag_official)).value());
StickerSet &custom(sets.insert(CustomStickerSetId, StickerSet(CustomStickerSetId, 0, lang(lng_custom_stickers), QString(), 0, 0, 0)).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());
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;
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 (def.stickers.isEmpty()) {
sets.remove(DefaultStickerSetId);
sets.remove(Stickers::DefaultSetId);
} 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();
writeUserSettings();
@ -3210,10 +3218,10 @@ namespace Local {
return;
}
StickerSets &sets(cRefStickerSets());
Stickers::Sets &sets(Global::RefStickerSets());
sets.clear();
StickerSetsOrder &order(cRefStickerSetsOrder());
Stickers::Order &order(Global::RefStickerSetsOrder());
order.clear();
quint32 cnt;
@ -3231,20 +3239,24 @@ namespace Local {
qint32 setHash = 0, setFlags = 0;
if (stickers.version > 8033) {
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);
setFlags |= MTPDstickerSet::flag_official;
setFlags |= qFlags(MTPDstickerSet::Flag::f_official);
order.push_front(setId);
} else if (setId == CustomStickerSetId) {
} else if (setId == Stickers::CustomSetId) {
setTitle = lang(lng_custom_stickers);
} else if (setId) {
order.push_back(setId);
} else {
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
set.count = -scnt;
continue;
@ -3264,7 +3276,7 @@ namespace Local {
if (read.contains(id)) continue;
read.insert(id, true);
if (setId == DefaultStickerSetId || setId == CustomStickerSetId) {
if (setId == Stickers::DefaultSetId || setId == Stickers::CustomSetId) {
typeOfSet = StickerSetTypeEmpty;
}
@ -3325,17 +3337,17 @@ namespace Local {
int32 countStickersHash(bool checkOfficial) {
uint32 acc = 0;
bool foundOfficial = false, foundBad = false;;
const StickerSets &sets(cStickerSets());
const StickerSetsOrder &order(cStickerSetsOrder());
for (StickerSetsOrder::const_iterator i = order.cbegin(), e = order.cend(); i != e; ++i) {
StickerSets::const_iterator j = sets.constFind(*i);
const Stickers::Sets &sets(Global::StickerSets());
const Stickers::Order &order(Global::StickerSetsOrder());
for (auto i = order.cbegin(), e = order.cend(); i != e; ++i) {
auto j = sets.constFind(*i);
if (j != sets.cend()) {
if (j->id == 0) {
foundBad = true;
} else if (j->flags & MTPDstickerSet::flag_official) {
} else if (j->flags & MTPDstickerSet::Flag::f_official) {
foundOfficial = true;
}
if (!(j->flags & MTPDstickerSet::flag_disabled)) {
if (!(j->flags & MTPDstickerSet::Flag::f_disabled)) {
acc = (acc * 20261) + j->hash;
}
}
@ -3600,7 +3612,7 @@ namespace Local {
user->setName(first, last, pname, username);
user->access = access;
user->flags = flags;
user->flags = MTPDuser::Flags(flags);
user->onlineTill = onlineTill;
user->contact = contact;
user->setBotInfoVersion(botInfoVersion);
@ -3629,7 +3641,7 @@ namespace Local {
flags = flagsData;
} else {
// flagsData was haveLeft
flags = (flagsData == 1 ? MTPDchat::flag_left : 0);
flags = (flagsData == 1 ? MTPDchat::Flags(MTPDchat::Flag::f_left) : 0);
}
if (!wasLoaded) {
chat->updateName(name, QString(), QString());
@ -3638,7 +3650,7 @@ namespace Local {
chat->version = version;
chat->creator = creator;
chat->isForbidden = (forbidden == 1);
chat->flags = flags;
chat->flags = MTPDchat::Flags(flags);
chat->invitationUrl = invitationUrl;
chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id)));
@ -3660,7 +3672,7 @@ namespace Local {
channel->date = date;
channel->version = version;
channel->isForbidden = (forbidden == 1);
channel->flags = flags;
channel->flags = MTPDchannel::Flags(flags);
channel->invitationUrl = invitationUrl;
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;
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 showFromName = !channelPost || hist->peer->asChannel()->addsSignature();
bool silentPost = channelPost && silent;
if (channelPost) {
sendFlags |= MTPmessages_ForwardMessages::flag_broadcast;
flags |= MTPDmessage::flag_views;
flags |= MTPDmessage::flag_post;
sendFlags |= MTPmessages_ForwardMessages::Flag::f_broadcast;
flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::Flag::f_post;
}
if (showFromName) {
flags |= MTPDmessage::flag_from_id;
flags |= MTPDmessage::Flag::f_from_id;
}
if (silentPost) {
sendFlags |= MTPmessages_ForwardMessages::flag_silent;
sendFlags |= MTPmessages_ForwardMessages::Flag::f_silent;
}
QVector<MTPint> ids;
@ -650,7 +651,7 @@ void MainWidget::finishForwarding(History *hist, bool broadcast, bool silent) {
}
if (forwardFrom != i.value()->history()->peer) {
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);
randomIds.resize(0);
}
@ -659,7 +660,7 @@ void MainWidget::finishForwarding(History *hist, bool broadcast, bool silent) {
ids.push_back(MTP_int(i.value()->id));
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) {
history.peerMessagesUpdated();
@ -687,8 +688,7 @@ void MainWidget::webPagesUpdate() {
WebPageItems::const_iterator j = items.constFind(App::webPage(i.key()));
if (j != items.cend()) {
for (HistoryItemsMap::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
k.key()->initDimensions();
Notify::historyItemResized(k.key());
k.key()->setPendingInitDimensions();
}
}
}
@ -783,8 +783,7 @@ void MainWidget::notify_userIsContactChanged(UserData *user, bool fromThisApp) {
SharedContactItems::const_iterator i = items.constFind(peerToUser(user->id));
if (i != items.cend()) {
for (HistoryItemsMap::const_iterator j = i->cbegin(), e = i->cend(); j != e; ++j) {
j.key()->initDimensions();
Ui::repaintHistoryItem(j.key());
j.key()->setPendingInitDimensions();
}
}
@ -830,6 +829,10 @@ void MainWidget::notify_automaticLoadSettingsChangedGif() {
history.notify_automaticLoadSettingsChangedGif();
}
void MainWidget::notify_handlePendingHistoryUpdate() {
history.notify_handlePendingHistoryUpdate();
}
void MainWidget::cmd_search() {
history.cmd_search();
}
@ -842,18 +845,6 @@ void MainWidget::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) {
if (_hider == destroyed) {
_hider = 0;
@ -1379,40 +1370,40 @@ void MainWidget::sendMessage(History *hist, const QString &text, MsgId replyTo,
App::historyRegSentData(randomId, hist->peer->id, sendingText);
MTPstring msgText(MTP_string(sendingText));
int32 flags = newMessageFlags(hist->peer) | MTPDmessage::flag_entities; // unread, out
int32 sendFlags = 0;
MTPDmessage::Flags flags = newMessageFlags(hist->peer) | MTPDmessage::Flag::f_entities; // unread, out
MTPmessages_SendMessage::Flags sendFlags = 0;
if (replyTo) {
flags |= MTPDmessage::flag_reply_to_msg_id;
sendFlags |= MTPmessages_SendMessage::flag_reply_to_msg_id;
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to_msg_id;
}
MTPMessageMedia media = MTP_messageMediaEmpty();
if (webPageId == CancelledWebPageId) {
sendFlags |= MTPmessages_SendMessage::flag_no_webpage;
sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage;
} else if (webPageId) {
WebPageData *page = App::webPage(webPageId);
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 showFromName = !channelPost || hist->peer->asChannel()->addsSignature();
bool silentPost = channelPost && silent;
if (channelPost) {
sendFlags |= MTPmessages_SendMessage::flag_broadcast;
flags |= MTPDmessage::flag_views;
flags |= MTPDmessage::flag_post;
sendFlags |= MTPmessages_SendMessage::Flag::f_broadcast;
flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::Flag::f_post;
}
if (showFromName) {
flags |= MTPDmessage::flag_from_id;
flags |= MTPDmessage::Flag::f_from_id;
}
if (silentPost) {
sendFlags |= MTPmessages_SendMessage::flag_silent;
sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
}
MTPVector<MTPMessageEntity> localEntities = linksToMTP(sendingEntities), sentEntities = linksToMTP(sendingEntities, true);
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->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->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_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);
@ -1502,8 +1493,11 @@ bool MainWidget::preloadOverview(PeerData *peer, MediaOverviewType type) {
return false;
}
int32 flags = (peer->isChannel() && !peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 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));
MTPmessages_Search::Flags flags = 0;
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;
}
@ -1635,8 +1629,11 @@ void MainWidget::loadMediaBack(PeerData *peer, MediaOverviewType type, bool many
MTPMessagesFilter filter = typeToMediaFilter(type);
if (type == OverviewCount) return;
int32 flags = (peer->isChannel() && !peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 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)));
MTPmessages_Search::Flags flags = 0;
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) {
@ -1762,6 +1759,14 @@ void MainWidget::ui_showPeerHistoryAsync(quint64 peerId, qint32 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) {
AudioMsgId playing;
AudioPlayerState state = AudioPlayerStopped;
@ -1953,13 +1958,13 @@ void MainWidget::dialogsCancelled() {
}
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;
EntitiesInText sendingEntities, leftEntities = textParseEntities(leftText, _historyTextNoMonoOptions.flags);
HistoryItem *item = 0;
while (textSplit(sendingText, sendingEntities, leftText, leftEntities, MaxMessageSize)) {
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) {
history.peerMessagesUpdated(item->history()->peer->id);
@ -2910,7 +2915,7 @@ void MainWidget::onUpdateNotifySettings() {
if (peer->notify == UnknownNotifySettings || peer->notify == EmptyNotifySettings) {
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;
}
if (silent == SilentNotifiesSetSilent) {
peer->notify->flags |= MTPDpeerNotifySettings::flag_silent;
peer->notify->flags |= MTPDpeerNotifySettings::Flag::f_silent;
} else if (silent == SilentNotifiesSetNotify) {
peer->notify->flags &= ~MTPDpeerNotifySettings::flag_silent;
peer->notify->flags &= ~MTPDpeerNotifySettings::Flag::f_silent;
}
}
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_inputStickerSetShortName: setName = qs(sticker->sticker()->set.c_inputStickerSetShortName().vshort_name).toLower().trimmed(); break;
}
StickerSets &sets(cRefStickerSets());
for (StickerSets::const_iterator 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)) {
Stickers::Sets &sets(Global::RefStickerSets());
for (auto i = sets.cbegin(); i != sets.cend(); ++i) {
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) {
if (i->stickers.at(j) == sticker) {
found = true;
@ -3877,9 +3882,9 @@ void MainWidget::incrementSticker(DocumentData *sticker) {
}
}
if (!found) {
StickerSets::iterator it = sets.find(CustomStickerSetId);
Stickers::Sets::iterator it = sets.find(Stickers::CustomSetId);
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->count;
@ -4094,8 +4099,8 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
}
// update before applying skipped
int32 flags = d.vflags.v | MTPDmessage::flag_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);
MTPDmessage::Flags flags = mtpCastFlags(d.vflags.v) | MTPDmessage::Flag::f_from_id;
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) {
history.peerMessagesUpdated(item->history()->peer->id);
}
@ -4129,8 +4134,8 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
}
// update before applying skipped
int32 flags = d.vflags.v | MTPDmessage::flag_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);
MTPDmessage::Flags flags = mtpCastFlags(d.vflags.v) | MTPDmessage::Flag::f_from_id;
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) {
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)) {
item->setText(text, d.has_entities() ? entitiesFromMTP(d.ventities.c_vector().v) : EntitiesInText());
item->updateMedia(d.has_media() ? (&d.vmedia) : 0);
item->initDimensions();
Notify::historyItemResized(item);
item->addToOverview(AddToOverviewNew);
}
}
@ -4437,7 +4439,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
UserData *user = App::userLoaded(d.vuser_id.v);
if (user) {
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;
@ -4660,10 +4662,10 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
if (set.vset.type() == mtpc_stickerSet) {
const MTPDstickerSet &s(set.vset.c_stickerSet());
StickerSets &sets(cRefStickerSets());
StickerSets::iterator it = sets.find(s.vid.v);
Stickers::Sets &sets(Global::RefStickerSets());
auto it = sets.find(s.vid.v);
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);
@ -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);
if (currentIndex != insertAtIndex) {
if (currentIndex > 0) {
@ -4703,7 +4705,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
order.insert(insertAtIndex, s.vid.v);
}
StickerSets::iterator custom = sets.find(CustomStickerSetId);
auto custom = sets.find(Stickers::CustomSetId);
if (custom != sets.cend()) {
for (int32 i = 0, l = it->stickers.size(); i < l; ++i) {
int32 removeIndex = custom->stickers.indexOf(it->stickers.at(i));
@ -4722,26 +4724,26 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
case mtpc_updateStickerSetsOrder: {
const MTPDupdateStickerSetsOrder &d(update.c_updateStickerSetsOrder());
const QVector<MTPlong> &order(d.vorder.c_vector().v);
const StickerSets &sets(cStickerSets());
StickerSetsOrder result;
const Stickers::Sets &sets(Global::StickerSets());
Stickers::Order result;
for (int32 i = 0, l = order.size(); i < l; ++i) {
if (sets.constFind(order.at(i).v) == sets.cend()) {
break;
}
result.push_back(order.at(i).v);
}
if (result.size() != cStickerSetsOrder().size() || result.size() != order.size()) {
cSetLastStickersUpdate(0);
if (result.size() != Global::StickerSetsOrder().size() || result.size() != order.size()) {
Global::SetLastStickersUpdate(0);
App::main()->updateStickers();
} else {
cSetStickerSetsOrder(result);
Global::SetStickerSetsOrder(result);
Local::writeStickers();
emit stickersUpdated();
}
} break;
case mtpc_updateStickerSets: {
cSetLastStickersUpdate(0);
Global::SetLastStickersUpdate(0);
App::main()->updateStickers();
} break;

View file

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

View file

@ -21,6 +21,28 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
import glob
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
types = 0;
consts = 0
@ -35,6 +57,7 @@ boxed = {};
funcsText = '';
typesText = '';
dataTexts = '';
creatorProxyText = '';
inlineMethods = '';
textSerializeInit = '';
textSerializeMethods = '';
@ -150,7 +173,10 @@ with open('scheme.tl') as f:
continue;
elif (ptypewide == '#'):
hasFlags = pname;
ptype = 'int';
if funcsNow:
ptype = 'flags<MTP' + name + '::Flags>';
else:
ptype = 'flags<MTPD' + name + '::Flags>';
else:
ptype = ptypewide;
if (ptype.find('?') >= 0):
@ -195,6 +221,27 @@ with open('scheme.tl') as f:
prmsStr = [];
prmsInit = [];
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)):
for paramName in prmsList:
if (paramName in trivialConditions):
@ -207,7 +254,7 @@ with open('scheme.tl') as f:
else:
ptypeFull = 'MTP' + paramType;
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);
else:
prmsStr.append('const ' + ptypeFull + ' &_' + paramName);
@ -218,19 +265,6 @@ with open('scheme.tl') as f:
if (len(prms) > len(trivialConditions)):
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 += '\tuint32 innerLength() const {\n'; # count size
size = [];
@ -274,6 +308,8 @@ with open('scheme.tl') as f:
funcsText += '\n\ttypedef MTP' + resType + ' ResponseType;\n'; # method return type
funcsText += '};\n'; # class ending
if (len(conditionsList)):
funcsText += 'Q_DECLARE_OPERATORS_FOR_FLAGS(MTP' + name + '::Flags)\n\n';
if (isTemplate != ''):
funcsText += 'template <typename TQueryType>\n';
funcsText += 'class MTP' + Name + ' : public MTPBoxed<MTP' + name + '<TQueryType> > {\n';
@ -325,7 +361,9 @@ def addTextSerialize(lst, dct, dataLetter):
conditions = data[6];
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)):
result += '\tif (stage) {\n';
result += '\t\tto.add(",\\n").addSpaces(lev);\n';
@ -341,12 +379,12 @@ def addTextSerialize(lst, dct, dataLetter):
if (k == hasFlags):
result += 'if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; ';
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 += '} else { to.add("[ SKIPPED BY BIT ' + conditions[k] + ' IN FIELD ' + hasFlags + ' ]"); } ';
else:
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(';
vtypeget = re.match(r'^[Vv]ector<MTP([A-Za-z0-9\._]+)>', v);
if (vtypeget):
@ -383,7 +421,10 @@ def addTextSerialize(lst, dct, dataLetter):
except KeyError:
if (vtypeget):
result += '); vtypes.push_back(';
result += 'mtpc_' + restype;
if (re.match(r'^flags<', restype)):
result += 'mtpc_flags';
else:
result += 'mtpc_' + restype + '+0';
if (not vtypeget):
result += '); vtypes.push_back(0';
else:
@ -455,6 +496,28 @@ for restype in typesList:
creatorParamsList = [];
readText = '';
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
switchLines += '\t\tcase mtpc_' + name + ': '; # for by-type-id type constructor
if (len(prms) > len(trivialConditions)):
@ -530,33 +593,25 @@ for restype in typesList:
sizeFast = '\treturn 0;\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
if (len(prms) > len(trivialConditions)):
dataTexts += dataText; # add data class
friendDecl += '\tfriend MTP' + restype + ' MTP_' + name + '(' + ', '.join(creatorParams) + ');\n';
creatorsText += 'inline MTP' + restype + ' MTP_' + name + '(' + ', '.join(creatorParams) + ') {\n';
friendDecl += '\tfriend class MTP::internal::TypeCreator;\n';
creatorProxyText += '\t\tinline static MTP' + restype + ' new_' + name + '(' + ', '.join(creatorParams) + ') {\n';
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:
if (withType): # creator by type
creatorsText += '\treturn MTP' + restype + '(mtpc_' + name + ');\n';
creatorProxyText += '\t\t\treturn MTP' + restype + '(mtpc_' + name + ');\n';
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';
if (withType):
@ -705,8 +760,19 @@ for restype in typesList:
inlineMethods += creatorsText;
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
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 += '\t\tto.add(",\\n").addSpaces(lev);\n';
textSerializeMethods += '\t} else {\n';
@ -721,7 +787,7 @@ textSerializeMethods += '\t}\n';
textSerializeMethods += '}\n\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 += '\t\tto.add(",\\n").addSpaces(lev);\n';
textSerializeMethods += '\t} else {\n';
@ -735,7 +801,7 @@ textSerializeMethods += '\t}\n';
textSerializeMethods += '}\n\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 += '\t\tto.add(",\\n").addSpaces(lev);\n';
textSerializeMethods += '\t} else {\n';
@ -786,12 +852,14 @@ textSerializeFull += '\t\t}\n';
textSerializeFull += '\t}\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 forward declarations\n' + forwards);
out.write('\n// Boxed types definitions\n' + forwTypedefs);
out.write('\n// Type classes definitions\n' + typesText);
out.write('\n// Type constructors with data\n' + dataTexts);
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// 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(textSerializeMethods);
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('\tvoid initTextSerializers() {\n');
outCpp.write(textSerializeInit);

View file

@ -158,6 +158,17 @@ namespace MTP {
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"

View file

@ -660,7 +660,7 @@ MTPautoConnection::MTPautoConnection(QThread *thread) : MTPabstractTcpConnection
void MTPautoConnection::onHttpStart() {
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;
sock.disconnectFromHost();
emit connected();
@ -671,7 +671,7 @@ void MTPautoConnection::onSocketConnected() {
if (status == HttpReady || status == WaitingBoth || status == WaitingTcp) {
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;
tcpTimeoutTimer.start(_tcpTimeout);
@ -709,7 +709,7 @@ void MTPautoConnection::onSocketDisconnected() {
} else if (status == WaitingTcp || status == UsingTcp) {
emit disconnected();
} 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;
emit connected();
}
@ -801,7 +801,7 @@ void MTPautoConnection::disconnectFromServer() {
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;
_portTcp = port;
_flagsTcp = flags;
@ -810,8 +810,8 @@ void MTPautoConnection::connectTcp(const QString &addr, int32 port, int32 flags)
sock.connectToHost(QHostAddress(_addrTcp), _portTcp);
}
void MTPautoConnection::connectHttp(const QString &addr, int32 port, int32 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
void MTPautoConnection::connectHttp(const QString &addr, int32 port, MTPDdcOption::Flags flags) {
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()));
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));
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);
}
@ -857,7 +857,7 @@ void MTPautoConnection::requestFinished(QNetworkReply *reply) {
status = HttpReady;
httpStartTimer.start(MTPTcpConnectionWaitTimeout);
} 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;
sock.disconnectFromHost();
emit connected();
@ -900,7 +900,7 @@ void MTPautoConnection::socketPacket(const char *packet, uint32 length) {
status = WaitingHttp;
sock.disconnectFromHost();
} 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;
sock.disconnectFromHost();
emit connected();
@ -919,7 +919,7 @@ void MTPautoConnection::socketPacket(const char *packet, uint32 length) {
MTPResPQ res_pq = _readPQFakeReply(data);
const MTPDresPQ &res_pq_data(res_pq.c_resPQ());
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;
emit connected();
}
@ -929,7 +929,7 @@ void MTPautoConnection::socketPacket(const char *packet, uint32 length) {
status = WaitingHttp;
sock.disconnectFromHost();
} 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;
sock.disconnectFromHost();
emit connected();
@ -969,7 +969,7 @@ void MTPautoConnection::socketError(QAbstractSocket::SocketError e) {
if (status == WaitingBoth) {
status = WaitingHttp;
} 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;
emit connected();
} else if (status == WaitingTcp || status == UsingTcp) {
@ -998,7 +998,7 @@ void MTPtcpConnection::onSocketConnected() {
if (status == WaitingTcp) {
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;
tcpTimeoutTimer.start(_tcpTimeout);
@ -1083,7 +1083,7 @@ void MTPtcpConnection::disconnectFromServer() {
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;
_port = port;
_flags = flags;
@ -1108,7 +1108,7 @@ void MTPtcpConnection::socketPacket(const char *packet, uint32 length) {
MTPResPQ res_pq = _readPQFakeReply(data);
const MTPDresPQ &res_pq_data(res_pq.c_resPQ());
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;
emit connected();
}
@ -1180,8 +1180,8 @@ void MTPhttpConnection::disconnectFromServer() {
address = QUrl();
}
void MTPhttpConnection::connectHttp(const QString &addr, int32 p, int32 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
void MTPhttpConnection::connectHttp(const QString &addr, int32 p, MTPDdcOption::Flags flags) {
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()));
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));
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);
}
@ -1217,7 +1217,7 @@ void MTPhttpConnection::requestFinished(QNetworkReply *reply) {
MTPResPQ res_pq = _readPQFakeReply(data);
const MTPDresPQ &res_pq_data(res_pq.c_resPQ());
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;
emit connected();
}
@ -1354,7 +1354,7 @@ MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConne
if (!dc) {
QReadLocker lock(mtpDcOptionsMutex());
const mtpDcOptions &options(cDcOptions());
const MTP::DcOptions &options(Global::DcOptions());
if (options.isEmpty()) {
LOG(("MTP Error: connect failed, no DCs"));
dc = 0;
@ -1994,36 +1994,36 @@ void MTProtoConnectionPrivate::socketStart(bool afterConfig) {
static const int IPv4address = 0, IPv6address = 1;
static const int TcpProtocol = 0, HttpProtocol = 1;
int32 flags[2][2] = { { 0 } };
MTPDdcOption::Flags flags[2][2] = { { 0 } };
string ip[2][2];
uint32 port[2][2] = { { 0 } };
{
QReadLocker lock(mtpDcOptionsMutex());
const mtpDcOptions &options(cDcOptions());
const MTP::DcOptions &options(Global::DcOptions());
int32 shifts[2][2][4] = {
{ // IPv4
{ // TCP IPv4
isDldDc ? (MTPDdcOption::flag_media_only | MTPDdcOption::flag_tcpo_only) : -1,
MTPDdcOption::flag_tcpo_only,
isDldDc ? (MTPDdcOption::flag_media_only) : -1,
isDldDc ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_tcpo_only) : -1,
qFlags(MTPDdcOption::Flag::f_tcpo_only),
isDldDc ? qFlags(MTPDdcOption::Flag::f_media_only) : -1,
0
}, { // HTTP IPv4
-1,
-1,
isDldDc ? (MTPDdcOption::flag_media_only) : -1,
isDldDc ? qFlags(MTPDdcOption::Flag::f_media_only) : -1,
0
},
}, { // IPv6
{ // TCP IPv6
isDldDc ? (MTPDdcOption::flag_media_only | MTPDdcOption::flag_tcpo_only | MTPDdcOption::flag_ipv6) : -1,
MTPDdcOption::flag_tcpo_only | MTPDdcOption::flag_ipv6,
isDldDc ? (MTPDdcOption::flag_media_only | MTPDdcOption::flag_ipv6) : -1,
MTPDdcOption::flag_ipv6
isDldDc ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6) : -1,
MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6,
isDldDc ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6) : -1,
qFlags(MTPDdcOption::Flag::f_ipv6)
}, { // HTTP IPv6
-1,
-1,
isDldDc ? (MTPDdcOption::flag_media_only | MTPDdcOption::flag_ipv6) : -1,
MTPDdcOption::flag_ipv6
isDldDc ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6) : -1,
qFlags(MTPDdcOption::Flag::f_ipv6)
},
},
};
@ -2033,7 +2033,7 @@ void MTProtoConnectionPrivate::socketStart(bool afterConfig) {
int32 mask = shifts[address][protocol][shift];
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()) {
ip[address][protocol] = index->ip;
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 disconnectFromServer() = 0;
virtual void connectTcp(const QString &addr, int32 port, int32 flags) = 0;
virtual void connectHttp(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, MTPDdcOption::Flags flags) = 0;
virtual bool isConnected() const = 0;
virtual bool usingHttpWait() {
return false;
@ -182,17 +182,17 @@ public:
MTPautoConnection(QThread *thread);
void sendData(mtpBuffer &buffer);
void disconnectFromServer();
void connectTcp(const QString &addr, int32 port, int32 flags);
void connectHttp(const QString &addr, int32 port, int32 flags);
bool isConnected() const;
bool usingHttpWait();
bool needHttpWait();
void sendData(mtpBuffer &buffer) override;
void disconnectFromServer() override;
void connectTcp(const QString &addr, int32 port, MTPDdcOption::Flags flags) override;
void connectHttp(const QString &addr, int32 port, MTPDdcOption::Flags flags) override;
bool isConnected() const override;
bool usingHttpWait() override;
bool needHttpWait() override;
int32 debugState() const;
int32 debugState() const override;
QString transport() const;
QString transport() const override;
public slots:
@ -233,7 +233,8 @@ private:
Requests requests;
QString _addrTcp, _addrHttp;
int32 _portTcp, _portHttp, _flagsTcp, _flagsHttp;
int32 _portTcp, _portHttp;
MTPDdcOption::Flags _flagsTcp, _flagsHttp;
int32 _tcpTimeout;
QTimer tcpTimeoutTimer;
@ -246,16 +247,16 @@ public:
MTPtcpConnection(QThread *thread);
void sendData(mtpBuffer &buffer);
void disconnectFromServer();
void connectTcp(const QString &addr, int32 port, int32 flags);
void connectHttp(const QString &addr, int32 port, int32 flags) { // not supported
void sendData(mtpBuffer &buffer) override;
void disconnectFromServer() override;
void connectTcp(const QString &addr, int32 port, MTPDdcOption::Flags flags) override;
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:
@ -281,7 +282,8 @@ private:
MTPint128 tcpNonce;
QString _addr;
int32 _port, _tcpTimeout, _flags;
int32 _port, _tcpTimeout;
MTPDdcOption::Flags _flags;
QTimer tcpTimeoutTimer;
};
@ -293,18 +295,18 @@ public:
MTPhttpConnection(QThread *thread);
void sendData(mtpBuffer &buffer);
void disconnectFromServer();
void connectTcp(const QString &addr, int32 port, int32 flags) { // not supported
void sendData(mtpBuffer &buffer) override;
void disconnectFromServer() override;
void connectTcp(const QString &addr, int32 port, MTPDdcOption::Flags flags) override { // not supported
}
void connectHttp(const QString &addr, int32 port, int32 flags);
bool isConnected() const;
bool usingHttpWait();
bool needHttpWait();
void connectHttp(const QString &addr, int32 port, MTPDdcOption::Flags flags) override;
bool isConnected() const override;
bool usingHttpWait() override;
bool needHttpWait() override;
int32 debugState() const;
int32 debugState() const override;
QString transport() const;
QString transport() const override;
public slots:
@ -319,7 +321,7 @@ private:
};
Status status;
MTPint128 httpNonce;
int32 _flags;
MTPDdcOption::Flags _flags;
QNetworkAccessManager manager;
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 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 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 title;

View file

@ -346,6 +346,7 @@ enum {
mtpc_gzip_packed = 0x3072cfa1
};
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 mtpLayers[] = {
mtpTypeId(mtpc_invokeWithLayer1),
@ -446,6 +447,49 @@ inline MTPint MTP_int(int32 v) {
}
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) {
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));
}
template <typename T>
class MTPVector : public 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) {
}
};
using MTPVector = MTPBoxed<MTPvector<T>>;
template <typename T>
inline bool operator==(const MTPvector<T> &a, const MTPvector<T> &b) {
@ -977,13 +1009,71 @@ inline bool mtpIsFalse(const MTPBool &v) {
return !mtpIsTrue(v);
}
enum { // client side flags
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
MTPDreplyKeyboardMarkup_flag_FORCE_REPLY = (1 << 30), // markup just wants a text reply
MTPDreplyKeyboardMarkup_flag_ZERO = (1 << 31), // none (zero) markup
MTPDstickerSet_flag_NOT_LOADED = (1 << 31), // sticker set is not yet loaded
#define CHECK_MTP_SCHEME_AND_CLIENT_FLAGS_CONFLICT(Type) \
// we must validate that MTProto scheme flags don't intersect with client side flags
// and define common bit operators which allow use Type_ClientFlag together with Type::Flag
#define DEFINE_MTP_CLIENT_FLAGS(Type) \
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 MTPVector<MTPMessageEntity> MTPnullEntities;

View file

@ -185,28 +185,28 @@ namespace {
void mtpUpdateDcOptions(const QVector<MTPDcOption> &options) {
QSet<int32> already, restart;
{
mtpDcOptions opts;
MTP::DcOptions opts;
{
QReadLocker lock(mtpDcOptionsMutex());
opts = cDcOptions();
opts = Global::DcOptions();
}
for (QVector<MTPDcOption>::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) {
const MTPDdcOption &optData(i->c_dcOption());
int32 id = optData.vid.v, idWithShift = id + (optData.vflags.v * _mtp_internal::dcShift);
if (already.constFind(idWithShift) == already.cend()) {
already.insert(idWithShift);
mtpDcOptions::const_iterator a = opts.constFind(idWithShift);
auto a = opts.constFind(idWithShift);
if (a != opts.cend()) {
if (a.value().ip != optData.vip_address.c_string().v || a.value().port != optData.vport.v) {
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());
cSetDcOptions(opts);
Global::SetDcOptions(opts);
}
}
for (QSet<int32>::const_iterator i = restart.cbegin(), e = restart.cend(); i != e; ++i) {
@ -261,8 +261,8 @@ void MTProtoConfigLoader::enumDC() {
OrderedSet<int32> dcs;
{
QReadLocker lock(mtpDcOptionsMutex());
const mtpDcOptions &options(cDcOptions());
for (mtpDcOptions::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) {
const MTP::DcOptions &options(Global::DcOptions());
for (auto i = options.cbegin(), e = options.cend(); i != e; ++i) {
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) {
MTPmessagesFilter filter = (_type == OverviewLinks) ? MTP_inputMessagesFilterUrl() : MTP_inputMessagesFilterDocument();
if (!_searchFull) {
int32 flags = (_history->peer->isChannel() && !_history->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 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));
MTPmessages_Search::Flags flags = 0;
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) {
_searchQueries.insert(_searchRequest, _searchQuery);
}
} else if (_migrated && !_searchFullMigrated) {
int32 flags = (_migrated->peer->isChannel() && !_migrated->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 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));
MTPmessages_Search::Flags flags = 0;
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()) {
@ -1530,9 +1536,12 @@ bool OverviewInner::onSearchMessages(bool searchCache) {
} else if (_searchQuery != q) {
_searchQuery = q;
_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();
_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);
}
return false;
@ -2386,7 +2395,6 @@ void OverviewWidget::onDeleteSelectedSure() {
for (SelectedItemSet::const_iterator i = sel.cbegin(), e = sel.cend(); i != e; ++i) {
i.value()->destroy();
}
Notify::historyItemsResized();
Ui::hideLayer();
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);
}
Notify::historyItemsResized();
Ui::hideLayer();
if (wasOnServer) {

View file

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

View file

@ -55,18 +55,6 @@ inline bool rtl() {
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(uint64, BetaVersion);
DeclareSetting(uint64, RealBetaVersion);
@ -215,24 +203,6 @@ RecentStickerPack &cGetRecentStickers();
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;
DeclareRefSetting(SavedGifs, SavedGifs);
DeclareSetting(uint64, LastSavedGifsUpdate);

View file

@ -1355,8 +1355,8 @@ void SettingsInner::onPasswordOff() {
_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_email;
MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_int(flags), MTP_string(QByteArray()), MTP_string(QByteArray()), MTP_string(QString()), MTP_string(QString())));
MTPDaccount_passwordInputSettings::Flags flags = MTPDaccount_passwordInputSettings::Flag::f_email;
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));
} else {
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) {
asChannel()->username = newUsername;
if (newUsername.isEmpty()) {
asChannel()->flags &= ~MTPDchannel::flag_username;
asChannel()->flags &= ~MTPDchannel::Flag::f_username;
} else {
asChannel()->flags |= MTPDchannel::flag_username;
asChannel()->flags |= MTPDchannel::Flag::f_username;
}
if (App::main()) {
App::main()->peerUsernameChanged(this);
@ -802,14 +802,14 @@ QString saveFileName(const QString &title, const QString &filter, const QString
bool StickerData::setInstalled() const {
switch (set.type()) {
case mtpc_inputStickerSetID: {
StickerSets::const_iterator it = cStickerSets().constFind(set.c_inputStickerSetID().vid.v);
return (it != cStickerSets().cend()) && !(it->flags & MTPDstickerSet::flag_disabled);
auto it = Global::StickerSets().constFind(set.c_inputStickerSetID().vid.v);
return (it != Global::StickerSets().cend()) && !(it->flags & MTPDstickerSet::Flag::f_disabled);
} break;
case mtpc_inputStickerSetShortName: {
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) {
return !(it->flags & MTPDstickerSet::flag_disabled);
return !(it->flags & MTPDstickerSet::Flag::f_disabled);
}
}
} 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;
}
inline int32 flagsFromMessage(const MTPmessage &msg) {
inline MTPDmessage::Flags flagsFromMessage(const MTPmessage &msg) {
switch (msg.type()) {
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;
}
@ -163,15 +165,16 @@ static const MsgId ServerMaxMsgId = 0x3FFFFFFF;
static const MsgId ShowAtUnreadMsgId = 0;
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;
bool previews() const {
return flags & MTPDinputPeerNotifySettings::flag_show_previews;
return flags & MTPDpeerNotifySettings::Flag::f_show_previews;
}
bool silent() const {
return flags & MTPDinputPeerNotifySettings::flag_silent;
return flags & MTPDpeerNotifySettings::Flag::f_silent;
}
};
typedef NotifySettings *NotifySettingsPtr;
@ -386,9 +389,9 @@ public:
uint64 access;
int32 flags;
MTPDuser::Flags flags;
bool isVerified() const {
return flags & MTPDuser::flag_verified;
return flags & MTPDuser::Flag::f_verified;
}
bool canWrite() const {
return access != UserNoAccess;
@ -434,7 +437,7 @@ public:
void invalidateParticipants() {
participants = ChatData::Participants();
admins = ChatData::Admins();
flags &= ~MTPDchat::flag_admin;
flags &= ~MTPDchat::Flag::f_admin;
invitedByMe = ChatData::InvitedByMe();
botStatus = 0;
}
@ -451,7 +454,7 @@ public:
int32 version;
int32 creator;
int32 flags;
MTPDchat::Flags flags;
bool isForbidden;
bool amIn() const {
return !isForbidden && !haveLeft() && !wasKicked();
@ -463,25 +466,25 @@ public:
return !isDeactivated() && amIn();
}
bool haveLeft() const {
return flags & MTPDchat::flag_left;
return flags & MTPDchat::Flag::f_left;
}
bool wasKicked() const {
return flags & MTPDchat::flag_kicked;
return flags & MTPDchat::Flag::f_kicked;
}
bool adminsEnabled() const {
return flags & MTPDchat::flag_admins_enabled;
return flags & MTPDchat::Flag::f_admins_enabled;
}
bool amCreator() const {
return flags & MTPDchat::flag_creator;
return flags & MTPDchat::Flag::f_creator;
}
bool amAdmin() const {
return flags & MTPDchat::flag_admin;
return flags & MTPDchat::Flag::f_admin;
}
bool isDeactivated() const {
return flags & MTPDchat::flag_deactivated;
return flags & MTPDchat::Flag::f_deactivated;
}
bool isMigrated() const {
return flags & MTPDchat::flag_migrated_to;
return flags & MTPDchat::Flag::f_migrated_to;
}
typedef QMap<UserData*, int32> Participants;
Participants participants;
@ -625,7 +628,8 @@ public:
int32 count, adminsCount;
int32 date;
int32 version;
int32 flags, flagsFull;
MTPDchannel::Flags flags;
MTPDchannelFull::Flags flagsFull;
MegagroupInfo *mgInfo;
bool lastParticipantsCountOutdated() const {
if (!mgInfo || !(mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsCountOutdated)) {
@ -639,31 +643,31 @@ public:
}
void flagsUpdated();
bool isMegagroup() const {
return flags & MTPDchannel::flag_megagroup;
return flags & MTPDchannel::Flag::f_megagroup;
}
bool isBroadcast() const {
return flags & MTPDchannel::flag_broadcast;
return flags & MTPDchannel::Flag::f_broadcast;
}
bool isPublic() const {
return flags & MTPDchannel::flag_username;
return flags & MTPDchannel::Flag::f_username;
}
bool canEditUsername() const {
return amCreator() && (flagsFull & MTPDchannelFull::flag_can_set_username);
return amCreator() && (flagsFull & MTPDchannelFull::Flag::f_can_set_username);
}
bool amCreator() const {
return flags & MTPDchannel::flag_creator;
return flags & MTPDchannel::Flag::f_creator;
}
bool amEditor() const {
return flags & MTPDchannel::flag_editor;
return flags & MTPDchannel::Flag::f_editor;
}
bool amModerator() const {
return flags & MTPDchannel::flag_moderator;
return flags & MTPDchannel::Flag::f_moderator;
}
bool haveLeft() const {
return flags & MTPDchannel::flag_left;
return flags & MTPDchannel::Flag::f_left;
}
bool wasKicked() const {
return flags & MTPDchannel::flag_kicked;
return flags & MTPDchannel::Flag::f_kicked;
}
bool amIn() const {
return !isForbidden && !haveLeft() && !wasKicked();
@ -675,17 +679,17 @@ public:
return amIn() && (canPublish() || !isBroadcast());
}
bool canViewParticipants() const {
return flagsFull & MTPDchannelFull::flag_can_view_participants;
return flagsFull & MTPDchannelFull::Flag::f_can_view_participants;
}
bool addsSignature() const {
return flags & MTPDchannel::flag_signatures;
return flags & MTPDchannel::Flag::f_signatures;
}
bool isForbidden;
bool isVerified() const {
return flags & MTPDchannel::flag_verified;
return flags & MTPDchannel::Flag::f_verified;
}
bool canAddParticipants() const {
return amCreator() || amEditor() || (flags & MTPDchannel::flag_democracy);
return amCreator() || amEditor() || (flags & MTPDchannel::Flag::f_democracy);
}
// ImagePtr photoFull;
@ -1220,7 +1224,7 @@ public:
int32 width, height, duration;
QString message; // botContextMessageText
bool noWebPage;
bool noWebPage; //currently not used
EntitiesInText entities;
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))
template <typename Enum>
inline QFlags<Enum> qFlags(Enum v) {
return QFlags<Enum>(v);
}
//typedef unsigned char uchar; // Qt has uchar
typedef qint16 int16;
typedef quint16 uint16;

View file

@ -661,8 +661,8 @@ void Window::sendServiceHistoryRequest() {
UserData *user = App::userLoaded(ServiceUserId);
if (!user) {
int32 userFlags = MTPDuser::flag_first_name | MTPDuser::flag_phone | MTPDuser::flag_status | MTPDuser::flag_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())));
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_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));
}
@ -1037,7 +1037,6 @@ bool Window::eventFilter(QObject *obj, QEvent *e) {
break;
case QEvent::ShortcutOverride: // handle shortcuts ourselves
DEBUG_LOG(("Shortcut override declined: %1").arg(static_cast<QKeyEvent*>(e)->key()));
return true;
case QEvent::Shortcut: