Strictly match message / media types.

This commit is contained in:
John Preston 2018-12-17 12:16:06 +04:00
parent 6d9f40db30
commit eb7201a55b
13 changed files with 292 additions and 303 deletions

View File

@ -2773,7 +2773,7 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs
auto indices = base::flat_map<uint64, int>(); // copied from feedMsgs auto indices = base::flat_map<uint64, int>(); // copied from feedMsgs
for (auto i = 0, l = v->size(); i != l; ++i) { for (auto i = 0, l = v->size(); i != l; ++i) {
const auto msgId = idFromMessage(v->at(i)); const auto msgId = IdFromMessage(v->at(i));
indices.emplace((uint64(uint32(msgId)) << 32) | uint64(i), i); indices.emplace((uint64(uint32(msgId)) << 32) | uint64(i), i);
} }
@ -3434,8 +3434,8 @@ void ApiWrap::requestMessageAfterDate(
if (auto list = getMessagesList()) { if (auto list = getMessagesList()) {
App::feedMsgs(*list, NewMessageExisting); App::feedMsgs(*list, NewMessageExisting);
for (auto &message : *list) { for (auto &message : *list) {
if (dateFromMessage(message) >= offsetDate) { if (DateFromMessage(message) >= offsetDate) {
callback(idFromMessage(message)); callback(IdFromMessage(message));
return; return;
} }
} }

View File

@ -874,22 +874,20 @@ namespace App {
return false; return false;
} }
void updateEditedMessage(const MTPMessage &m) { void updateEditedMessage(const MTPMessage &message) {
auto apply = [](const auto &data) { message.match([](const MTPDmessageEmpty &) {
auto peerId = peerFromMTP(data.vto_id); }, [](const auto &message) {
if (data.has_from_id() && peerId == Auth().userPeerId()) { auto peerId = peerFromMTP(message.vto_id);
peerId = peerFromUser(data.vfrom_id); if (message.has_from_id() && peerId == Auth().userPeerId()) {
peerId = peerFromUser(message.vfrom_id);
} }
if (auto existing = App::histItemById(peerToChannel(peerId), data.vid.v)) { const auto existing = App::histItemById(
existing->applyEdition(data); peerToChannel(peerId),
message.vid.v);
if (existing) {
existing->applyEdition(message);
} }
}; });
if (m.type() == mtpc_message) { // apply message edit
apply(m.c_message());
} else if (m.type() == mtpc_messageService) {
apply(m.c_messageService());
}
} }
void addSavedGif(DocumentData *doc) { void addSavedGif(DocumentData *doc) {
@ -932,7 +930,7 @@ namespace App {
} }
} }
} }
const auto msgId = idFromMessage(msg); const auto msgId = IdFromMessage(msg);
indices.emplace((uint64(uint32(msgId)) << 32) | uint64(i), i); indices.emplace((uint64(uint32(msgId)) << 32) | uint64(i), i);
} }
for (const auto [position, index] : indices) { for (const auto [position, index] : indices) {

View File

@ -303,8 +303,8 @@ void BoxController::receivedCalls(const QVector<MTPMessage> &result) {
} }
for_const (auto &message, result) { for_const (auto &message, result) {
auto msgId = idFromMessage(message); auto msgId = IdFromMessage(message);
auto peerId = peerFromMessage(message); auto peerId = PeerFromMessage(message);
if (auto peer = App::peerLoaded(peerId)) { if (auto peer = App::peerLoaded(peerId)) {
auto item = App::histories().addNewMessage(message, NewMessageExisting); auto item = App::histories().addNewMessage(message, NewMessageExisting);
insertRow(item, InsertWay::Append); insertRow(item, InsertWay::Append);

View File

@ -133,3 +133,38 @@ HistoryItem *FileClickHandler::getActionItem() const {
? App::histItemById(context()) ? App::histItemById(context())
: nullptr; : nullptr;
} }
PeerId PeerFromMessage(const MTPmessage &message) {
return message.match([](const MTPDmessageEmpty &) {
return PeerId(0);
}, [](const auto &message) {
auto from_id = message.has_from_id() ? peerFromUser(message.vfrom_id) : 0;
auto to_id = peerFromMTP(message.vto_id);
auto out = message.is_out();
return (out || !peerIsUser(to_id)) ? to_id : from_id;
});
}
MTPDmessage::Flags FlagsFromMessage(const MTPmessage &message) {
return message.match([](const MTPDmessageEmpty &) {
return MTPDmessage::Flags(0);
}, [](const MTPDmessage &message) {
return message.vflags.v;
}, [](const MTPDmessageService &message) {
return mtpCastFlags(message.vflags.v);
});
}
MsgId IdFromMessage(const MTPmessage &message) {
return message.match([](const auto &message) {
return message.vid.v;
});
}
TimeId DateFromMessage(const MTPmessage &message) {
return message.match([](const MTPDmessageEmpty &) {
return TimeId(0);
}, [](const auto &message) {
return message.vdate.v;
});
}

View File

@ -234,41 +234,10 @@ Q_DECLARE_METATYPE(FullMsgId);
using MessageIdsList = std::vector<FullMsgId>; using MessageIdsList = std::vector<FullMsgId>;
inline PeerId peerFromMessage(const MTPmessage &msg) { PeerId PeerFromMessage(const MTPmessage &message);
auto compute = [](auto &message) { MTPDmessage::Flags FlagsFromMessage(const MTPmessage &message);
auto from_id = message.has_from_id() ? peerFromUser(message.vfrom_id) : 0; MsgId IdFromMessage(const MTPmessage &message);
auto to_id = peerFromMTP(message.vto_id); TimeId DateFromMessage(const MTPmessage &message);
auto out = message.is_out();
return (out || !peerIsUser(to_id)) ? to_id : from_id;
};
switch (msg.type()) {
case mtpc_message: return compute(msg.c_message());
case mtpc_messageService: return compute(msg.c_messageService());
}
return 0;
}
inline MTPDmessage::Flags flagsFromMessage(const MTPmessage &msg) {
switch (msg.type()) {
case mtpc_message: return msg.c_message().vflags.v;
case mtpc_messageService: return mtpCastFlags(msg.c_messageService().vflags.v);
}
return 0;
}
inline MsgId idFromMessage(const MTPmessage &msg) {
switch (msg.type()) {
case mtpc_messageEmpty: return msg.c_messageEmpty().vid.v;
case mtpc_message: return msg.c_message().vid.v;
case mtpc_messageService: return msg.c_messageService().vid.v;
}
Unexpected("Type in idFromMessage()");
}
inline TimeId dateFromMessage(const MTPmessage &msg) {
switch (msg.type()) {
case mtpc_message: return msg.c_message().vdate.v;
case mtpc_messageService: return msg.c_messageService().vdate.v;
}
return 0;
}
class DocumentData; class DocumentData;
class PhotoData; class PhotoData;

View File

@ -1885,9 +1885,9 @@ bool DialogsInner::searchReceived(
auto unknownUnreadCounts = std::vector<not_null<History*>>(); auto unknownUnreadCounts = std::vector<not_null<History*>>();
TimeId lastDateFound = 0; TimeId lastDateFound = 0;
for_const (auto message, messages) { for_const (auto message, messages) {
auto msgId = idFromMessage(message); auto msgId = IdFromMessage(message);
auto peerId = peerFromMessage(message); auto peerId = PeerFromMessage(message);
auto lastDate = dateFromMessage(message); auto lastDate = DateFromMessage(message);
if (const auto peer = App::peerLoaded(peerId)) { if (const auto peer = App::peerLoaded(peerId)) {
if (lastDate) { if (lastDate) {
const auto item = App::histories().addNewMessage( const auto item = App::histories().addNewMessage(

View File

@ -470,9 +470,9 @@ void DialogsWidget::updateDialogsOffset(
} }
for (auto j = messages.size(); j != 0;) { for (auto j = messages.size(); j != 0;) {
const auto &message = messages[--j]; const auto &message = messages[--j];
if (idFromMessage(message) == msgId if (IdFromMessage(message) == msgId
&& peerFromMessage(message) == peer) { && PeerFromMessage(message) == peer) {
if (const auto date = dateFromMessage(message)) { if (const auto date = DateFromMessage(message)) {
lastDate = date; lastDate = date;
} }
return; return;

View File

@ -36,52 +36,50 @@ TextWithEntities PrepareText(const QString &value, const QString &emptyValue) {
return result; return result;
} }
MTPMessage PrepareLogMessage(const MTPMessage &message, MsgId newId, int32 newDate) { MTPMessage PrepareLogMessage(
switch (message.type()) { const MTPMessage &message,
case mtpc_messageEmpty: return MTP_messageEmpty(MTP_int(newId)); MsgId newId,
case mtpc_messageService: { TimeId newDate) {
auto &data = message.c_messageService(); return message.match([&](const MTPDmessageEmpty &) {
auto removeFlags = MTPDmessageService::Flag::f_out return MTP_messageEmpty(MTP_int(newId));
}, [&](const MTPDmessageService &message) {
const auto removeFlags = MTPDmessageService::Flag::f_out
| MTPDmessageService::Flag::f_post | MTPDmessageService::Flag::f_post
/* | MTPDmessageService::Flag::f_reply_to_msg_id*/; /* | MTPDmessageService::Flag::f_reply_to_msg_id*/;
auto flags = data.vflags.v & ~removeFlags; const auto flags = message.vflags.v & ~removeFlags;
return MTP_messageService( return MTP_messageService(
MTP_flags(flags), MTP_flags(flags),
MTP_int(newId), MTP_int(newId),
data.vfrom_id, message.vfrom_id,
data.vto_id, message.vto_id,
data.vreply_to_msg_id, message.vreply_to_msg_id,
MTP_int(newDate), MTP_int(newDate),
data.vaction); message.vaction);
} break; }, [&](const MTPDmessage &message) {
case mtpc_message: { const auto removeFlags = MTPDmessage::Flag::f_out
auto &data = message.c_message();
auto removeFlags = MTPDmessage::Flag::f_out
| MTPDmessage::Flag::f_post | MTPDmessage::Flag::f_post
| MTPDmessage::Flag::f_reply_to_msg_id | MTPDmessage::Flag::f_reply_to_msg_id
| MTPDmessage::Flag::f_edit_date | MTPDmessage::Flag::f_edit_date
| MTPDmessage::Flag::f_grouped_id; | MTPDmessage::Flag::f_grouped_id;
auto flags = data.vflags.v & ~removeFlags; const auto flags = message.vflags.v & ~removeFlags;
return MTP_message( return MTP_message(
MTP_flags(flags), MTP_flags(flags),
MTP_int(newId), MTP_int(newId),
data.vfrom_id, message.vfrom_id,
data.vto_id, message.vto_id,
data.vfwd_from, message.vfwd_from,
data.vvia_bot_id, message.vvia_bot_id,
data.vreply_to_msg_id, message.vreply_to_msg_id,
MTP_int(newDate), MTP_int(newDate),
data.vmessage, message.vmessage,
data.vmedia, message.vmedia,
data.vreply_markup, message.vreply_markup,
data.ventities, message.ventities,
data.vviews, message.vviews,
data.vedit_date, message.vedit_date,
MTP_string(""), MTP_string(""),
data.vgrouped_id); message.vgrouped_id);
} break; });
}
Unexpected("Type in PrepareLogMessage()");
} }
bool MediaCanHaveCaption(const MTPMessage &message) { bool MediaCanHaveCaption(const MTPMessage &message) {

View File

@ -154,7 +154,7 @@ void Histories::remove(const PeerId &peer) {
HistoryItem *Histories::addNewMessage( HistoryItem *Histories::addNewMessage(
const MTPMessage &msg, const MTPMessage &msg,
NewMessageType type) { NewMessageType type) {
auto peer = peerFromMessage(msg); auto peer = PeerFromMessage(msg);
if (!peer) return nullptr; if (!peer) return nullptr;
auto result = App::history(peer)->addNewMessage(msg, type); auto result = App::history(peer)->addNewMessage(msg, type);
@ -750,7 +750,7 @@ bool History::updateSendActionNeedsAnimating(TimeMs ms, bool force) {
HistoryItem *History::createItem( HistoryItem *History::createItem(
const MTPMessage &message, const MTPMessage &message,
bool detachExistingItem) { bool detachExistingItem) {
const auto messageId = idFromMessage(message); const auto messageId = IdFromMessage(message);
if (!messageId) { if (!messageId) {
return nullptr; return nullptr;
} }

View File

@ -41,6 +41,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace { namespace {
enum class MediaCheckResult {
Good,
Unsupported,
Empty,
HasTimeToLive,
};
not_null<HistoryItem*> CreateUnsupportedMessage( not_null<HistoryItem*> CreateUnsupportedMessage(
not_null<History*> history, not_null<History*> history,
MsgId msgId, MsgId msgId,
@ -69,6 +76,75 @@ not_null<HistoryItem*> CreateUnsupportedMessage(
text); text);
} }
MediaCheckResult CheckMessageMedia(const MTPMessageMedia &media) {
using Result = MediaCheckResult;
return media.match([](const MTPDmessageMediaEmpty &) {
return Result::Good;
}, [](const MTPDmessageMediaContact &) {
return Result::Good;
}, [](const MTPDmessageMediaGeo &data) {
return data.vgeo.match([](const MTPDgeoPoint &) {
return Result::Good;
}, [](const MTPDgeoPointEmpty &) {
return Result::Empty;
});
}, [](const MTPDmessageMediaVenue &data) {
return data.vgeo.match([](const MTPDgeoPoint &) {
return Result::Good;
}, [](const MTPDgeoPointEmpty &) {
return Result::Empty;
});
}, [](const MTPDmessageMediaGeoLive &data) {
return data.vgeo.match([](const MTPDgeoPoint &) {
return Result::Good;
}, [](const MTPDgeoPointEmpty &) {
return Result::Empty;
});
}, [](const MTPDmessageMediaPhoto &data) {
if (data.has_ttl_seconds()) {
return Result::HasTimeToLive;
} else if (!data.has_photo()) {
return Result::Empty;
}
return data.vphoto.match([](const MTPDphoto &) {
return Result::Good;
}, [](const MTPDphotoEmpty &) {
return Result::Empty;
});
}, [](const MTPDmessageMediaDocument &data) {
if (data.has_ttl_seconds()) {
return Result::HasTimeToLive;
} else if (!data.has_document()) {
return Result::Empty;
}
return data.vdocument.match([](const MTPDdocument &) {
return Result::Good;
}, [](const MTPDdocumentEmpty &) {
return Result::Empty;
});
}, [](const MTPDmessageMediaWebPage &data) {
return data.vwebpage.match([](const MTPDwebPage &) {
return Result::Good;
}, [](const MTPDwebPageEmpty &) {
return Result::Good;
}, [](const MTPDwebPagePending &) {
return Result::Good;
}, [](const MTPDwebPageNotModified &) {
return Result::Unsupported;
});
}, [](const MTPDmessageMediaGame &data) {
return data.vgame.match([](const MTPDgame &) {
return Result::Good;
});
}, [](const MTPDmessageMediaInvoice &) {
return Result::Good;
}, [](const MTPDmessageMediaPoll &) { // #TODO polls
return Result::Unsupported;
}, [](const MTPDmessageMediaUnsupported &) {
return Result::Unsupported;
});
}
} // namespace } // namespace
void HistoryItem::HistoryItem::Destroyer::operator()(HistoryItem *value) { void HistoryItem::HistoryItem::Destroyer::operator()(HistoryItem *value) {
@ -676,98 +752,11 @@ ClickHandlerPtr goToMessageClickHandler(
not_null<HistoryItem*> HistoryItem::Create( not_null<HistoryItem*> HistoryItem::Create(
not_null<History*> history, not_null<History*> history,
const MTPMessage &message) { const MTPMessage &message) {
switch (message.type()) { return message.match([&](const MTPDmessage &data) -> HistoryItem* {
case mtpc_messageEmpty: { const auto checked = data.has_media()
const auto &data = message.c_messageEmpty(); ? CheckMessageMedia(data.vmedia)
const auto text = HistoryService::PreparedText { : MediaCheckResult::Good;
lang(lng_message_empty) if (checked == MediaCheckResult::Unsupported) {
};
return new HistoryService(history, data.vid.v, TimeId(0), text);
} break;
case mtpc_message: {
const auto &data = message.c_message();
enum class MediaCheckResult {
Good,
Unsupported,
Empty,
HasTimeToLive,
};
auto badMedia = MediaCheckResult::Good;
const auto &media = data.vmedia;
if (data.has_media()) switch (media.type()) {
case mtpc_messageMediaEmpty:
case mtpc_messageMediaContact: break;
case mtpc_messageMediaGeo:
switch (media.c_messageMediaGeo().vgeo.type()) {
case mtpc_geoPoint: break;
case mtpc_geoPointEmpty: badMedia = MediaCheckResult::Empty; break;
default: badMedia = MediaCheckResult::Unsupported; break;
}
break;
case mtpc_messageMediaVenue:
switch (media.c_messageMediaVenue().vgeo.type()) {
case mtpc_geoPoint: break;
case mtpc_geoPointEmpty: badMedia = MediaCheckResult::Empty; break;
default: badMedia = MediaCheckResult::Unsupported; break;
}
break;
case mtpc_messageMediaGeoLive:
switch (media.c_messageMediaGeoLive().vgeo.type()) {
case mtpc_geoPoint: break;
case mtpc_geoPointEmpty: badMedia = MediaCheckResult::Empty; break;
default: badMedia = MediaCheckResult::Unsupported; break;
}
break;
case mtpc_messageMediaPhoto: {
auto &photo = media.c_messageMediaPhoto();
if (photo.has_ttl_seconds()) {
badMedia = MediaCheckResult::HasTimeToLive;
} else if (!photo.has_photo()) {
badMedia = MediaCheckResult::Empty;
} else {
switch (photo.vphoto.type()) {
case mtpc_photo: break;
case mtpc_photoEmpty: badMedia = MediaCheckResult::Empty; break;
default: badMedia = MediaCheckResult::Unsupported; break;
}
}
} break;
case mtpc_messageMediaDocument: {
auto &document = media.c_messageMediaDocument();
if (document.has_ttl_seconds()) {
badMedia = MediaCheckResult::HasTimeToLive;
} else if (!document.has_document()) {
badMedia = MediaCheckResult::Empty;
} else {
switch (document.vdocument.type()) {
case mtpc_document: break;
case mtpc_documentEmpty: badMedia = MediaCheckResult::Empty; break;
default: badMedia = MediaCheckResult::Unsupported; break;
}
}
} break;
case mtpc_messageMediaWebPage:
switch (media.c_messageMediaWebPage().vwebpage.type()) {
case mtpc_webPage:
case mtpc_webPageEmpty:
case mtpc_webPagePending: break;
case mtpc_webPageNotModified:
default: badMedia = MediaCheckResult::Unsupported; break;
}
break;
case mtpc_messageMediaGame:
switch (media.c_messageMediaGame().vgame.type()) {
case mtpc_game: break;
default: badMedia = MediaCheckResult::Unsupported; break;
}
break;
case mtpc_messageMediaInvoice:
break;
case mtpc_messageMediaUnsupported:
default: badMedia = MediaCheckResult::Unsupported; break;
}
if (badMedia == MediaCheckResult::Unsupported) {
return CreateUnsupportedMessage( return CreateUnsupportedMessage(
history, history,
data.vid.v, data.vid.v,
@ -776,7 +765,7 @@ not_null<HistoryItem*> HistoryItem::Create(
data.vvia_bot_id.v, data.vvia_bot_id.v,
data.vdate.v, data.vdate.v,
data.vfrom_id.v); data.vfrom_id.v);
} else if (badMedia == MediaCheckResult::Empty) { } else if (checked == MediaCheckResult::Empty) {
const auto text = HistoryService::PreparedText { const auto text = HistoryService::PreparedText {
lang(lng_message_empty) lang(lng_message_empty)
}; };
@ -787,20 +776,19 @@ not_null<HistoryItem*> HistoryItem::Create(
text, text,
data.vflags.v, data.vflags.v,
data.has_from_id() ? data.vfrom_id.v : UserId(0)); data.has_from_id() ? data.vfrom_id.v : UserId(0));
} else if (badMedia == MediaCheckResult::HasTimeToLive) { } else if (checked == MediaCheckResult::HasTimeToLive) {
return new HistoryService(history, data); return new HistoryService(history, data);
} }
return new HistoryMessage(history, data); return new HistoryMessage(history, data);
} break; }, [&](const MTPDmessageService &data) -> HistoryItem* {
case mtpc_messageService: {
auto &data = message.c_messageService();
if (data.vaction.type() == mtpc_messageActionPhoneCall) { if (data.vaction.type() == mtpc_messageActionPhoneCall) {
return new HistoryMessage(history, data); return new HistoryMessage(history, data);
} }
return new HistoryService(history, data); return new HistoryService(history, data);
} break; }, [&](const MTPDmessageEmpty &data) -> HistoryItem* {
} const auto text = HistoryService::PreparedText{
lang(lng_message_empty)
Unexpected("Type in HistoryItem::Create()."); };
return new HistoryService(history, data.vid.v, TimeId(0), text);
});
} }

View File

@ -758,110 +758,110 @@ void HistoryMessage::setMedia(const MTPMessageMedia &media) {
std::unique_ptr<Data::Media> HistoryMessage::CreateMedia( std::unique_ptr<Data::Media> HistoryMessage::CreateMedia(
not_null<HistoryMessage*> item, not_null<HistoryMessage*> item,
const MTPMessageMedia &media) { const MTPMessageMedia &media) {
switch (media.type()) { using Result = std::unique_ptr<Data::Media>;
case mtpc_messageMediaContact: { return media.match([&](const MTPDmessageMediaContact &media) -> Result {
const auto &data = media.c_messageMediaContact();
return std::make_unique<Data::MediaContact>( return std::make_unique<Data::MediaContact>(
item, item,
data.vuser_id.v, media.vuser_id.v,
qs(data.vfirst_name), qs(media.vfirst_name),
qs(data.vlast_name), qs(media.vlast_name),
qs(data.vphone_number)); qs(media.vphone_number));
} break; }, [&](const MTPDmessageMediaGeo &media) -> Result {
case mtpc_messageMediaGeo: { return media.vgeo.match([&](const MTPDgeoPoint &point) -> Result {
const auto &data = media.c_messageMediaGeo().vgeo;
if (data.type() == mtpc_geoPoint) {
return std::make_unique<Data::MediaLocation>( return std::make_unique<Data::MediaLocation>(
item, item,
LocationCoords(data.c_geoPoint())); LocationCoords(point));
} }, [](const MTPDgeoPointEmpty &) -> Result {
} break; return nullptr;
case mtpc_messageMediaGeoLive: { });
const auto &data = media.c_messageMediaGeoLive().vgeo; }, [&](const MTPDmessageMediaGeoLive &media) -> Result {
if (data.type() == mtpc_geoPoint) { return media.vgeo.match([&](const MTPDgeoPoint &point) -> Result {
return std::make_unique<Data::MediaLocation>( return std::make_unique<Data::MediaLocation>(
item, item,
LocationCoords(data.c_geoPoint())); LocationCoords(point));
} }, [](const MTPDgeoPointEmpty &) -> Result {
} break; return nullptr;
case mtpc_messageMediaVenue: { });
const auto &data = media.c_messageMediaVenue(); }, [&](const MTPDmessageMediaVenue &media) -> Result {
if (data.vgeo.type() == mtpc_geoPoint) { return media.vgeo.match([&](const MTPDgeoPoint &point) -> Result {
return std::make_unique<Data::MediaLocation>( return std::make_unique<Data::MediaLocation>(
item, item,
LocationCoords(data.vgeo.c_geoPoint()), LocationCoords(point),
qs(data.vtitle), qs(media.vtitle),
qs(data.vaddress)); qs(media.vaddress));
} }, [](const MTPDgeoPointEmpty &data) -> Result {
} break; return nullptr;
case mtpc_messageMediaPhoto: { });
const auto &data = media.c_messageMediaPhoto(); }, [&](const MTPDmessageMediaPhoto &media) -> Result {
if (data.has_ttl_seconds()) { if (media.has_ttl_seconds()) {
LOG(("App Error: " LOG(("App Error: "
"Unexpected MTPMessageMediaPhoto " "Unexpected MTPMessageMediaPhoto "
"with ttl_seconds in HistoryMessage.")); "with ttl_seconds in HistoryMessage."));
} else if (data.has_photo() && data.vphoto.type() == mtpc_photo) { return nullptr;
return std::make_unique<Data::MediaPhoto>( } else if (!media.has_photo()) {
item,
Auth().data().photo(data.vphoto.c_photo()));
} else {
LOG(("API Error: " LOG(("API Error: "
"Got MTPMessageMediaPhoto " "Got MTPMessageMediaPhoto "
"without photo and without ttl_seconds.")); "without photo and without ttl_seconds."));
return nullptr;
} }
} break; return media.vphoto.match([&](const MTPDphoto &photo) -> Result {
case mtpc_messageMediaDocument: { return std::make_unique<Data::MediaPhoto>(
const auto &data = media.c_messageMediaDocument(); item,
if (data.has_ttl_seconds()) { Auth().data().photo(photo));
}, [](const MTPDphotoEmpty &) -> Result {
return nullptr;
});
}, [&](const MTPDmessageMediaDocument &media) -> Result {
if (media.has_ttl_seconds()) {
LOG(("App Error: " LOG(("App Error: "
"Unexpected MTPMessageMediaDocument " "Unexpected MTPMessageMediaDocument "
"with ttl_seconds in HistoryMessage.")); "with ttl_seconds in HistoryMessage."));
} else if (data.has_document() return nullptr;
&& data.vdocument.type() == mtpc_document) { } else if (!media.has_document()) {
return std::make_unique<Data::MediaFile>(
item,
Auth().data().document(data.vdocument.c_document()));
} else {
LOG(("API Error: " LOG(("API Error: "
"Got MTPMessageMediaDocument " "Got MTPMessageMediaDocument "
"without document and without ttl_seconds.")); "without document and without ttl_seconds."));
return nullptr;
} }
} break; const auto &document = media.vdocument;
case mtpc_messageMediaWebPage: { return document.match([&](const MTPDdocument &document) -> Result {
const auto &data = media.c_messageMediaWebPage().vwebpage; return std::make_unique<Data::MediaFile>(
switch (data.type()) { item,
case mtpc_webPageEmpty: break; Auth().data().document(document));
case mtpc_webPagePending: }, [](const MTPDdocumentEmpty &) -> Result {
return nullptr;
});
}, [&](const MTPDmessageMediaWebPage &media) {
return media.vwebpage.match([](const MTPDwebPageEmpty &) -> Result {
return nullptr;
}, [&](const MTPDwebPagePending &webpage) -> Result {
return std::make_unique<Data::MediaWebPage>( return std::make_unique<Data::MediaWebPage>(
item, item,
Auth().data().webpage(data.c_webPagePending())); Auth().data().webpage(webpage));
break; }, [&](const MTPDwebPage &webpage) -> Result {
case mtpc_webPage:
return std::make_unique<Data::MediaWebPage>( return std::make_unique<Data::MediaWebPage>(
item, item,
Auth().data().webpage(data.c_webPage())); Auth().data().webpage(webpage));
break; }, [](const MTPDwebPageNotModified &) -> Result {
case mtpc_webPageNotModified:
LOG(("API Error: " LOG(("API Error: "
"webPageNotModified is unexpected in message media.")); "webPageNotModified is unexpected in message media."));
break; return nullptr;
} });
} break; }, [&](const MTPDmessageMediaGame &media) -> Result {
case mtpc_messageMediaGame: { return media.vgame.match([&](const MTPDgame &game) {
const auto &data = media.c_messageMediaGame().vgame;
if (data.type() == mtpc_game) {
return std::make_unique<Data::MediaGame>( return std::make_unique<Data::MediaGame>(
item, item,
Auth().data().game(data.c_game())); Auth().data().game(game));
} });
} break; }, [&](const MTPDmessageMediaInvoice &media) -> Result {
case mtpc_messageMediaInvoice: { return std::make_unique<Data::MediaInvoice>(item, media);
return std::make_unique<Data::MediaInvoice>( }, [&](const MTPDmessageMediaPoll &media) -> Result { // #TODO polls
item, return nullptr;
media.c_messageMediaInvoice()); }, [](const MTPDmessageMediaEmpty &) -> Result {
} break; return nullptr;
}; }, [](const MTPDmessageMediaUnsupported &) -> Result {
return nullptr;
});
return nullptr; return nullptr;
} }

View File

@ -2285,10 +2285,10 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
} }
const auto ExtractFirstId = [&] { const auto ExtractFirstId = [&] {
return histList->empty() ? -1 : idFromMessage(histList->front()); return histList->empty() ? -1 : IdFromMessage(histList->front());
}; };
const auto ExtractLastId = [&] { const auto ExtractLastId = [&] {
return histList->empty() ? -1 : idFromMessage(histList->back()); return histList->empty() ? -1 : IdFromMessage(histList->back());
}; };
const auto PeerString = [](PeerId peerId) { const auto PeerString = [](PeerId peerId) {
if (peerIsUser(peerId)) { if (peerIsUser(peerId)) {

View File

@ -3846,56 +3846,57 @@ enum class DataIsLoadedResult {
MentionNotLoaded = 2, MentionNotLoaded = 2,
Ok = 3, Ok = 3,
}; };
DataIsLoadedResult allDataLoadedForMessage(const MTPMessage &msg) { DataIsLoadedResult allDataLoadedForMessage(const MTPMessage &message) {
switch (msg.type()) { return message.match([](const MTPDmessage &message) {
case mtpc_message: { if (!message.is_post() && message.has_from_id()) {
const MTPDmessage &d(msg.c_message()); if (!App::userLoaded(peerFromUser(message.vfrom_id))) {
if (!d.is_post() && d.has_from_id()) {
if (!App::userLoaded(peerFromUser(d.vfrom_id))) {
return DataIsLoadedResult::FromNotLoaded; return DataIsLoadedResult::FromNotLoaded;
} }
} }
if (d.has_via_bot_id()) { if (message.has_via_bot_id()) {
if (!App::userLoaded(peerFromUser(d.vvia_bot_id))) { if (!App::userLoaded(peerFromUser(message.vvia_bot_id))) {
return DataIsLoadedResult::NotLoaded; return DataIsLoadedResult::NotLoaded;
} }
} }
if (d.has_fwd_from() && !fwdInfoDataLoaded(d.vfwd_from)) { if (message.has_fwd_from()
&& !fwdInfoDataLoaded(message.vfwd_from)) {
return DataIsLoadedResult::NotLoaded; return DataIsLoadedResult::NotLoaded;
} }
if (d.has_entities() && !mentionUsersLoaded(d.ventities)) { if (message.has_entities()
&& !mentionUsersLoaded(message.ventities)) {
return DataIsLoadedResult::MentionNotLoaded; return DataIsLoadedResult::MentionNotLoaded;
} }
} break; return DataIsLoadedResult::Ok;
case mtpc_messageService: { }, [](const MTPDmessageService &message) {
const MTPDmessageService &d(msg.c_messageService()); if (!message.is_post() && message.has_from_id()) {
if (!d.is_post() && d.has_from_id()) { if (!App::userLoaded(peerFromUser(message.vfrom_id))) {
if (!App::userLoaded(peerFromUser(d.vfrom_id))) {
return DataIsLoadedResult::FromNotLoaded; return DataIsLoadedResult::FromNotLoaded;
} }
} }
switch (d.vaction.type()) { return message.vaction.match(
case mtpc_messageActionChatAddUser: { [](const MTPDmessageActionChatAddUser &action) {
for_const (const MTPint &userId, d.vaction.c_messageActionChatAddUser().vusers.v) { for (const MTPint &userId : action.vusers.v) {
if (!App::userLoaded(peerFromUser(userId))) { if (!App::userLoaded(peerFromUser(userId))) {
return DataIsLoadedResult::NotLoaded; return DataIsLoadedResult::NotLoaded;
} }
} }
} break; return DataIsLoadedResult::Ok;
case mtpc_messageActionChatJoinedByLink: { }, [](const MTPDmessageActionChatJoinedByLink &action) {
if (!App::userLoaded(peerFromUser(d.vaction.c_messageActionChatJoinedByLink().vinviter_id))) { if (!App::userLoaded(peerFromUser(action.vinviter_id))) {
return DataIsLoadedResult::NotLoaded; return DataIsLoadedResult::NotLoaded;
} }
} break; return DataIsLoadedResult::Ok;
case mtpc_messageActionChatDeleteUser: { }, [](const MTPDmessageActionChatDeleteUser &action) {
if (!App::userLoaded(peerFromUser(d.vaction.c_messageActionChatDeleteUser().vuser_id))) { if (!App::userLoaded(peerFromUser(action.vuser_id))) {
return DataIsLoadedResult::NotLoaded; return DataIsLoadedResult::NotLoaded;
} }
} break; return DataIsLoadedResult::Ok;
} }, [](const auto &) {
} break; return DataIsLoadedResult::Ok;
} });
return DataIsLoadedResult::Ok; }, [](const MTPDmessageEmpty &message) {
return DataIsLoadedResult::Ok;
});
} }
} // namespace } // namespace
@ -4052,7 +4053,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
case mtpc_updateNewChannelMessage: { case mtpc_updateNewChannelMessage: {
auto &d = update.c_updateNewChannelMessage(); auto &d = update.c_updateNewChannelMessage();
auto channel = App::channelLoaded(peerToChannel(peerFromMessage(d.vmessage))); auto channel = App::channelLoaded(peerToChannel(PeerFromMessage(d.vmessage)));
auto isDataLoaded = allDataLoadedForMessage(d.vmessage); auto isDataLoaded = allDataLoadedForMessage(d.vmessage);
if (!requestingDifference() && (!channel || isDataLoaded != DataIsLoadedResult::Ok)) { if (!requestingDifference() && (!channel || isDataLoaded != DataIsLoadedResult::Ok)) {
MTP_LOG(0, ("getDifference { good - " MTP_LOG(0, ("getDifference { good - "
@ -4146,7 +4147,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
case mtpc_updateEditChannelMessage: { case mtpc_updateEditChannelMessage: {
auto &d = update.c_updateEditChannelMessage(); auto &d = update.c_updateEditChannelMessage();
auto channel = App::channelLoaded(peerToChannel(peerFromMessage(d.vmessage))); auto channel = App::channelLoaded(peerToChannel(PeerFromMessage(d.vmessage)));
if (channel && !_handlingChannelDifference) { if (channel && !_handlingChannelDifference) {
if (channel->ptsRequesting()) { // skip global updates while getting channel difference if (channel->ptsRequesting()) { // skip global updates while getting channel difference