diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index c4603bca8..4244b1adf 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1166,6 +1166,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_mute_box_title" = "Mute notifications for..."; "lng_preview_loading" = "Getting Link Info..."; +"lng_preview_cant" = "Could not generate preview for this link."; "lng_profile_settings_section" = "Settings"; "lng_profile_bot_settings" = "Bot Settings"; diff --git a/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp b/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp index 931aeef55..ea09d9b14 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/controls/history_view_draft_options.h" +#include "base/timer_rpl.h" #include "base/unixtime.h" #include "boxes/peer_list_box.h" #include "boxes/peer_list_controllers.h" @@ -589,6 +590,9 @@ void DraftOptionsBox( QString link; Ui::SettingsSlider *tabs = nullptr; PreviewWrap *wrap = nullptr; + + Fn performSwitch; + Fn requestAndSwitch; rpl::lifetime resolveLifetime; }; const auto state = box->lifetime().make_state(); @@ -740,35 +744,54 @@ void DraftOptionsBox( }; const auto &resolver = args.resolver; - const auto performSwitch = [=](const QString &link, WebPageData *page) { - if (page) { + state->performSwitch = [=](const QString &link, WebPageData *page) { + const auto now = base::unixtime::now(); + if (!page || page->pendingTill > 0 && page->pendingTill < now) { + show->showToast(tr::lng_preview_cant(tr::now)); + } else if (page->pendingTill > 0) { + const auto delay = std::max(page->pendingTill - now, TimeId()); + base::timer_once( + (delay + 1) * crl::time(1000) + ) | rpl::start_with_next([=] { + state->requestAndSwitch(link, true); + }, state->resolveLifetime); + + page->owner().webPageUpdates( + ) | rpl::start_with_next([=](not_null updated) { + if (updated == page && !updated->pendingTill) { + state->resolveLifetime.destroy(); + state->performSwitch(link, page); + } + }, state->resolveLifetime); + } else { state->preview = page; state->webpage.id = page->id; state->webpage.url = page->url; state->webpage.manual = true; state->link = link; state->shown.force_assign(Section::Link); - } else { - show->showToast(u"Could not generate preview for this link."_q); } }; + state->requestAndSwitch = [=](const QString &link, bool force) { + resolver->request(link, force); + + state->resolveLifetime = resolver->resolved( + ) | rpl::start_with_next([=](const QString &resolved) { + if (resolved == link) { + state->resolveLifetime.destroy(); + state->performSwitch( + link, + resolver->lookup(link).value_or(nullptr)); + } + }); + }; const auto switchTo = [=](const QString &link) { if (link == state->link) { return; - } - if (const auto value = resolver->lookup(link)) { - performSwitch(link, *value); + } else if (const auto value = resolver->lookup(link)) { + state->performSwitch(link, *value); } else { - resolver->request(link); - state->resolveLifetime = resolver->resolved( - ) | rpl::start_with_next([=](const QString &resolved) { - if (resolved == link) { - state->resolveLifetime.destroy(); - performSwitch( - link, - resolver->lookup(link).value_or(nullptr)); - } - }); + state->requestAndSwitch(link, false); } }; diff --git a/Telegram/SourceFiles/history/view/controls/history_view_webpage_processor.cpp b/Telegram/SourceFiles/history/view/controls/history_view_webpage_processor.cpp index 50abe57bd..ca5fb31c0 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_webpage_processor.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_webpage_processor.cpp @@ -134,8 +134,8 @@ QString WebpageResolver::find(not_null page) const { return QString(); } -void WebpageResolver::request(const QString &link) { - if (_requestLink == link) { +void WebpageResolver::request(const QString &link, bool force) { + if (_requestLink == link && !force) { return; } const auto done = [=](const MTPDmessageMediaWebPage &data) { @@ -191,7 +191,7 @@ WebpageProcessor::WebpageProcessor( if (!ShowWebPagePreview(_data) || _link.isEmpty()) { return; } - _resolver->request(_link); + _resolver->request(_link, true); }) { _history->session().downloaderTaskFinished( ) | rpl::filter([=] { diff --git a/Telegram/SourceFiles/history/view/controls/history_view_webpage_processor.h b/Telegram/SourceFiles/history/view/controls/history_view_webpage_processor.h index f27d1ad6c..5aac1fd6e 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_webpage_processor.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_webpage_processor.h @@ -62,7 +62,7 @@ public: [[nodiscard]] QString find(not_null page) const; - void request(const QString &link); + void request(const QString &link, bool force = false); void cancel(const QString &link); private: