From 602e7a71641513413190c5ecb8692a90ffb8a257 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 9 Mar 2022 15:30:22 +0400 Subject: [PATCH] Warn on quit if downloading files. --- Telegram/Resources/langs/lang.strings | 1 + Telegram/SourceFiles/core/application.cpp | 16 +++- Telegram/SourceFiles/core/application.h | 1 + .../data/data_download_manager.cpp | 91 +++++++++++++++++++ .../SourceFiles/data/data_download_manager.h | 10 ++ 5 files changed, 118 insertions(+), 1 deletion(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 4f21582e7..1ff74a943 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1953,6 +1953,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_box_leave" = "Leave"; "lng_upload_sure_stop" = "Are you sure you want to stop uploading your files?\n\nIf you do, you'll need to start over."; +"lng_download_sure_stop" = "Are you sure you want to stop downloading your files?\n\nIf you do, you'll need to start over."; "lng_upload_show_file" = "Show file"; "lng_about_version" = "version {version}"; diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 3dadb44b3..e54d196a2 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -661,6 +661,10 @@ void Application::logoutWithChecks(Main::Account *account) { _exportManager->stopWithConfirmation(retry); } else if (account->session().uploadsInProgress()) { account->session().uploadsStopWithConfirmation(retry); + } else if (_downloadManager->loadingInProgress(&account->session())) { + _downloadManager->loadingStopWithConfirmation( + retry, + &account->session()); } else { logout(account); } @@ -801,8 +805,18 @@ bool Application::uploadPreventsQuit() { return false; } +bool Application::downloadPreventsQuit() { + if (_downloadManager->loadingInProgress()) { + _downloadManager->loadingStopWithConfirmation([=] { Quit(); }); + return true; + } + return false; +} + bool Application::preventsQuit(QuitReason reason) { - if (exportPreventsQuit() || uploadPreventsQuit()) { + if (exportPreventsQuit() + || uploadPreventsQuit() + || downloadPreventsQuit()) { return true; } else if (const auto window = activeWindow()) { if (window->widget()->isActive()) { diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index 2f73ab518..3200e8b87 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -255,6 +255,7 @@ public: not_null account, const TextWithEntities &explanation); [[nodiscard]] bool uploadPreventsQuit(); + [[nodiscard]] bool downloadPreventsQuit(); void checkLocalTime(); void lockByPasscode(); void unlockPasscode(); diff --git a/Telegram/SourceFiles/data/data_download_manager.cpp b/Telegram/SourceFiles/data/data_download_manager.cpp index 6a1579c0f..86c0f8f4b 100644 --- a/Telegram/SourceFiles/data/data_download_manager.cpp +++ b/Telegram/SourceFiles/data/data_download_manager.cpp @@ -27,8 +27,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/mime_type.h" #include "ui/controls/download_bar.h" #include "ui/text/format_song_document_name.h" +#include "ui/layers/generic_box.h" #include "storage/serialize_common.h" +#include "window/window_controller.h" +#include "window/window_session_controller.h" #include "apiwrap.h" +#include "styles/style_layers.h" namespace Data { namespace { @@ -396,6 +400,93 @@ auto DownloadManager::loadingProgressValue() const return _loadingProgress.value(); } +bool DownloadManager::loadingInProgress(Main::Session *onlyInSession) const { + return lookupLoadingItem(onlyInSession) != nullptr; +} + +HistoryItem *DownloadManager::lookupLoadingItem( + Main::Session *onlyInSession) const { + constexpr auto find = [](const SessionData &data) { + constexpr auto proj = &DownloadingId::done; + const auto i = ranges::find(data.downloading, false, proj); + return (i != end(data.downloading)) ? i->object.item.get() : nullptr; + }; + if (onlyInSession) { + const auto i = _sessions.find(onlyInSession); + return (i != end(_sessions)) ? find(i->second) : nullptr; + } else { + for (const auto &[session, data] : _sessions) { + if (const auto result = find(data)) { + return result; + } + } + } + return nullptr; +} + +void DownloadManager::loadingStopWithConfirmation( + Fn callback, + Main::Session *onlyInSession) { + const auto window = Core::App().primaryWindow(); + const auto item = lookupLoadingItem(onlyInSession); + if (!window || !item) { + return; + } + const auto weak = base::make_weak(&item->history()->session()); + const auto id = item->fullId(); + auto box = Box([=](not_null box) { + box->addRow( + object_ptr( + box.get(), + tr::lng_download_sure_stop(), + st::boxLabel), + st::boxPadding + QMargins(0, 0, 0, st::boxPadding.bottom())); + box->setStyle(st::defaultBox); + box->addButton(tr::lng_selected_upload_stop(), [=] { + box->closeBox(); + + if (!onlyInSession || weak.get()) { + loadingStop(onlyInSession); + } + if (callback) { + callback(); + } + }, st::attentionBoxButton); + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); + box->addLeftButton(tr::lng_upload_show_file(), [=] { + box->closeBox(); + + if (const auto strong = weak.get()) { + if (const auto item = strong->data().message(id)) { + if (const auto window = strong->tryResolveWindow()) { + window->showPeerHistoryAtItem(item); + } + } + } + }); + }); + window->show(std::move(box)); + window->activate(); +} + +void DownloadManager::loadingStop(Main::Session *onlyInSession) { + const auto stopInSession = [&](SessionData &data) { + while (!data.downloading.empty()) { + cancel(data, data.downloading.end() - 1); + } + }; + if (onlyInSession) { + const auto i = _sessions.find(onlyInSession); + if (i != end(_sessions)) { + stopInSession(i->second); + } + } else { + for (auto &[session, data] : _sessions) { + stopInSession(data); + } + } +} + void DownloadManager::clearLoading() { Expects(_loading.empty()); diff --git a/Telegram/SourceFiles/data/data_download_manager.h b/Telegram/SourceFiles/data/data_download_manager.h index 2a1fd8bc8..a6611e6a8 100644 --- a/Telegram/SourceFiles/data/data_download_manager.h +++ b/Telegram/SourceFiles/data/data_download_manager.h @@ -101,6 +101,12 @@ public: [[nodiscard]] auto loadingProgressValue() const -> rpl::producer; + [[nodiscard]] bool loadingInProgress( + Main::Session *onlyInSession = nullptr) const; + void loadingStopWithConfirmation( + Fn callback, + Main::Session *onlyInSession = nullptr); + [[nodiscard]] auto loadedList() -> ranges::any_view; [[nodiscard]] auto loadedAdded() const @@ -156,6 +162,10 @@ private: PhotoData *photo); void generateEntry(not_null session, DownloadedId &id); + [[nodiscard]] HistoryItem *lookupLoadingItem( + Main::Session *onlyInSession) const; + void loadingStop(Main::Session *onlyInSession); + void writePostponed(not_null session); [[nodiscard]] Fn()> serializator( not_null session) const;