diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 73ebae0e1..a65c1fd91 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -2619,7 +2619,7 @@ void Session::checkSelfDestructItems() { auto nextDestructIn = crl::time(0); for (auto i = _selfDestructItems.begin(); i != _selfDestructItems.cend();) { if (const auto item = message(*i)) { - if (auto destructIn = item->getSelfDestructIn(now)) { + if (const auto destructIn = item->getSelfDestructIn(now)) { if (nextDestructIn > 0) { accumulate_min(nextDestructIn, destructIn); } else { diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 03129e338..448254a42 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -1212,9 +1212,15 @@ void HistoryItem::markMediaAndMentionRead() { } if (const auto selfdestruct = Get()) { - if (!selfdestruct->destructAt) { - selfdestruct->destructAt = crl::now() + selfdestruct->timeToLive; - _history->owner().selfDestructIn(this, selfdestruct->timeToLive); + if (selfdestruct->destructAt == crl::time()) { + const auto ttl = selfdestruct->timeToLive; + if (const auto maybeTime = std::get_if(&ttl)) { + const auto time = *maybeTime; + selfdestruct->destructAt = crl::now() + time; + _history->owner().selfDestructIn(this, time); + } else { + selfdestruct->destructAt = TimeToLiveSingleView(); + } } } } @@ -3430,7 +3436,7 @@ void HistoryItem::createServiceFromMtp(const MTPDmessage &message) { const auto ttl = data.vttl_seconds(); Assert(ttl != nullptr); - setSelfDestruct(HistoryServiceSelfDestruct::Type::Photo, ttl->v); + setSelfDestruct(HistoryServiceSelfDestruct::Type::Photo, *ttl); if (out()) { setServiceText({ tr::lng_ttl_photo_sent(tr::now, Ui::Text::WithEntities) @@ -3455,7 +3461,7 @@ void HistoryItem::createServiceFromMtp(const MTPDmessage &message) { const auto ttl = data.vttl_seconds(); Assert(ttl != nullptr); - setSelfDestruct(HistoryServiceSelfDestruct::Type::Video, ttl->v); + setSelfDestruct(HistoryServiceSelfDestruct::Type::Video, *ttl); if (out()) { setServiceText({ tr::lng_ttl_video_sent(tr::now, Ui::Text::WithEntities) @@ -4558,10 +4564,16 @@ void HistoryItem::applyAction(const MTPMessageAction &action) { }); } -void HistoryItem::setSelfDestruct(HistoryServiceSelfDestruct::Type type, int ttlSeconds) { +void HistoryItem::setSelfDestruct( + HistoryServiceSelfDestruct::Type type, + MTPint mtpTTLvalue) { UpdateComponents(HistoryServiceSelfDestruct::Bit()); - auto selfdestruct = Get(); - selfdestruct->timeToLive = ttlSeconds * 1000LL; + const auto selfdestruct = Get(); + if (mtpTTLvalue.v == TimeId(0x7FFFFFFF)) { + selfdestruct->timeToLive = TimeToLiveSingleView(); + } else { + selfdestruct->timeToLive = mtpTTLvalue.v * crl::time(1000); + } selfdestruct->type = type; } @@ -4949,10 +4961,12 @@ ClickHandlerPtr HistoryItem::fromLink() const { } crl::time HistoryItem::getSelfDestructIn(crl::time now) { - if (auto selfdestruct = Get()) { - if (selfdestruct->destructAt > 0) { - if (selfdestruct->destructAt <= now) { - auto text = [selfdestruct] { + if (const auto selfdestruct = Get()) { + const auto at = std::get_if(&selfdestruct->destructAt); + if (at && (*at) > 0) { + const auto destruct = *at; + if (destruct <= now) { + auto text = [&] { switch (selfdestruct->type) { case HistoryServiceSelfDestruct::Type::Photo: return tr::lng_ttl_photo_expired(tr::now); @@ -4961,10 +4975,10 @@ crl::time HistoryItem::getSelfDestructIn(crl::time now) { } Unexpected("Type in HistoryServiceSelfDestruct::Type"); }; - setServiceText({ TextWithEntities{.text = text() } }); + setServiceText({ TextWithEntities{ .text = text() } }); return 0; } - return selfdestruct->destructAt - now; + return destruct - now; } } return 0; diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 1b15d91e8..7e54081dc 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -575,7 +575,7 @@ private: void translationToggle( not_null translation, bool used); - void setSelfDestruct(HistorySelfDestructType type, int ttlSeconds); + void setSelfDestruct(HistorySelfDestructType type, MTPint mtpTTLvalue); TextWithEntities fromLinkText() const; ClickHandlerPtr fromLink() const; diff --git a/Telegram/SourceFiles/history/history_item_components.h b/Telegram/SourceFiles/history/history_item_components.h index e5c7ec37b..d5414ba14 100644 --- a/Telegram/SourceFiles/history/history_item_components.h +++ b/Telegram/SourceFiles/history/history_item_components.h @@ -599,13 +599,22 @@ enum class HistorySelfDestructType { Video, }; +struct TimeToLiveSingleView { + friend inline auto operator<=>( + TimeToLiveSingleView, + TimeToLiveSingleView) = default; + friend inline bool operator==( + TimeToLiveSingleView, + TimeToLiveSingleView) = default; +}; + struct HistoryServiceSelfDestruct : public RuntimeComponent { using Type = HistorySelfDestructType; Type type = Type::Photo; - crl::time timeToLive = 0; - crl::time destructAt = 0; + std::variant timeToLive = crl::time(); + std::variant destructAt = crl::time(); }; struct HistoryServiceOngoingCall