mirror of https://github.com/procxx/kepka.git
Strictly match message / media types.
This commit is contained in:
parent
6d9f40db30
commit
eb7201a55b
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue