diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 3866d85b8d..59334123dc 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -3652,10 +3652,22 @@ void ApiWrap::applyUpdateNoPtsCheck(const MTPUpdate &update) { auto &d = update.c_updateNewMessage(); auto needToAdd = true; if (d.vmessage().type() == mtpc_message) { // index forwarded messages to links _overview - if (_session->data().checkEntitiesAndViewsUpdate(d.vmessage().c_message())) { // already in blocks + const auto &data = d.vmessage().c_message(); + if (_session->data().checkEntitiesAndViewsUpdate(data)) { // already in blocks LOG(("Skipping message, because it is already in blocks!")); needToAdd = false; } + if (needToAdd && !data.is_from_scheduled()) { + // If we still need to add a new message, + // we should first check if this message is in + // the list of scheduled messages. + // This is necessary to correctly update the file reference. + // Note that when a message is scheduled until online + // while the recipient is already online, the server sends + // an ordinary new message with skipped "from_scheduled" flag. + _session->data().scheduledMessages().checkEntitiesAndUpdate( + data); + } } if (needToAdd) { _session->data().addNewMessage( diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.cpp b/Telegram/SourceFiles/data/data_scheduled_messages.cpp index 288359feee..042bbcb443 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.cpp +++ b/Telegram/SourceFiles/data/data_scheduled_messages.cpp @@ -132,6 +132,45 @@ void ScheduledMessages::apply(const MTPDupdateNewScheduledMessage &update) { _updates.fire_copy(history); } +void ScheduledMessages::checkEntitiesAndUpdate(const MTPDmessage &data) { + // When the user sends a message with a media scheduled until online + // while the recipient is already online, the server sends + // updateNewMessage to the client and the client calls this method. + + const auto peer = peerFromMTP(data.vto_id()); + if (!peerIsUser(peer)) { + return; + } + + const auto history = _session->data().historyLoaded(peer); + if (!history) { + return; + } + + const auto i = _data.find(history); + if (i == end(_data)) { + return; + } + + const auto &itemMap = i->second.itemById; + const auto j = itemMap.find(data.vid().v); + if (j == end(itemMap)) { + return; + } + + const auto existing = j->second; + Assert(existing->date() == kScheduledUntilOnlineTimestamp); + existing->updateSentContent({ + qs(data.vmessage()), + Api::EntitiesFromMTP(data.ventities().value_or_empty()) + }, data.vmedia()); + existing->updateReplyMarkup(data.vreply_markup()); + existing->updateForwardedInfo(data.vfwd_from()); + _session->data().requestItemTextRefresh(existing); + + existing->destroy(); +} + void ScheduledMessages::apply( const MTPDupdateDeleteScheduledMessages &update) { const auto peer = peerFromMTP(update.vpeer()); diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.h b/Telegram/SourceFiles/data/data_scheduled_messages.h index 68c586f424..09a2c3eb4b 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.h +++ b/Telegram/SourceFiles/data/data_scheduled_messages.h @@ -31,6 +31,7 @@ public: [[nodiscard]] MsgId lookupId(not_null item) const; [[nodiscard]] int count(not_null history) const; + void checkEntitiesAndUpdate(const MTPDmessage &data); void apply(const MTPDupdateNewScheduledMessage &update); void apply(const MTPDupdateDeleteScheduledMessages &update); void apply(