diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index ee7a2907d8..bb658108cf 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -457,6 +457,8 @@ PRIVATE dialogs/dialogs_search_from_controllers.h dialogs/dialogs_widget.cpp dialogs/dialogs_widget.h + export/export_manager.cpp + export/export_manager.h export/view/export_view_content.cpp export/view/export_view_content.h export/view/export_view_panel_controller.cpp diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index cd129d88dc..d87aca158e 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -60,6 +60,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/storage_domain.h" #include "storage/storage_databases.h" #include "storage/localstorage.h" +#include "export/export_manager.h" #include "window/window_session_controller.h" #include "window/window_controller.h" #include "base/qthelp_regex.h" @@ -102,6 +103,7 @@ Application::Application(not_null launcher) , _fallbackProductionConfig( std::make_unique(MTP::Environment::Production)) , _domain(std::make_unique(cDataFile())) +, _exportManager(std::make_unique()) , _langpack(std::make_unique()) , _langCloudManager(std::make_unique(langpack())) , _emojiKeywords(std::make_unique()) @@ -617,13 +619,11 @@ Main::Session *Application::maybeActiveSession() const { } bool Application::exportPreventsQuit() { - if (const auto session = maybeActiveSession()) { - if (session->data().exportInProgress()) { - session->data().stopExportWithConfirmation([] { - App::quit(); - }); - return true; - } + if (_exportManager->inProgress()) { + _exportManager->stopWithConfirmation([] { + App::quit(); + }); + return true; } return false; } diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index f352b1a481..44aecddde8 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -87,6 +87,10 @@ namespace Stickers { class EmojiImageLoader; } // namespace Stickers +namespace Export { +class Manager; +} // namespace Export + namespace Core { class Launcher; @@ -176,6 +180,9 @@ public: } [[nodiscard]] Main::Account &activeAccount() const; [[nodiscard]] bool someSessionExists() const; + [[nodiscard]] Export::Manager &exportManager() const { + return *_exportManager; + } [[nodiscard]] bool exportPreventsQuit(); // Main::Session component. @@ -301,6 +308,7 @@ private: base::Timer _clearEmojiImageLoaderTimer; mutable std::unique_ptr _fallbackProductionConfig; const std::unique_ptr _domain; + const std::unique_ptr _exportManager; std::unique_ptr _window; std::unique_ptr _mediaView; const std::unique_ptr _langpack; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 70f8ea2603..2c4979df26 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -18,7 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/crash_reports.h" // CrashReports::SetAnnotation #include "ui/image/image.h" #include "ui/image/image_location_factory.h" // Images::FromPhotoSize -#include "export/export_controller.h" +#include "export/export_manager.h" #include "export/view/export_view_panel_controller.h" #include "mtproto/mtproto_config.h" #include "window/notifications_manager.h" @@ -926,31 +926,6 @@ Storage::Cache::Database &Session::cacheBigFile() { return *_bigFileCache; } -void Session::startExport(PeerData *peer) { - startExport(peer ? peer->input : MTP_inputPeerEmpty()); -} - -void Session::startExport(const MTPInputPeer &singlePeer) { - if (_exportPanel) { - _exportPanel->activatePanel(); - return; - } - _export = std::make_unique( - &session().mtp(), - singlePeer); - _exportPanel = std::make_unique( - &session(), - _export.get()); - - _exportViewChanges.fire(_exportPanel.get()); - - _exportPanel->stopRequests( - ) | rpl::start_with_next([=] { - LOG(("Export Info: Stop requested.")); - stopExport(); - }, _export->lifetime()); -} - void Session::suggestStartExport(TimeId availableAt) { _exportAvailableAt = availableAt; suggestStartExport(); @@ -977,47 +952,13 @@ void Session::suggestStartExport() { std::min(left + 5, 3600) * crl::time(1000), _session, [=] { suggestStartExport(); }); - } else if (_export) { + } else if (Core::App().exportManager().inProgress()) { Export::View::ClearSuggestStart(&session()); } else { _exportSuggestion = Export::View::SuggestStart(&session()); } } -rpl::producer Session::currentExportView( -) const { - return _exportViewChanges.events_starting_with(_exportPanel.get()); -} - -bool Session::exportInProgress() const { - return _export != nullptr; -} - -void Session::stopExportWithConfirmation(FnMut callback) { - if (!_exportPanel) { - callback(); - return; - } - auto closeAndCall = [=, callback = std::move(callback)]() mutable { - auto saved = std::move(callback); - LOG(("Export Info: Stop With Confirmation.")); - stopExport(); - if (saved) { - saved(); - } - }; - _exportPanel->stopWithConfirmation(std::move(closeAndCall)); -} - -void Session::stopExport() { - if (_exportPanel) { - LOG(("Export Info: Destroying.")); - _exportPanel = nullptr; - _exportViewChanges.fire(nullptr); - } - _export = nullptr; -} - const Passport::SavedCredentials *Session::passportCredentials() const { return _passportCredentials ? &_passportCredentials->first : nullptr; } diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index a024b3c516..02061e1388 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -37,13 +37,6 @@ namespace Main { class Session; } // namespace Main -namespace Export { -class Controller; -namespace View { -class PanelController; -} // namespace View -} // namespace Export - namespace Ui { class BoxContent; } // namespace Ui @@ -119,15 +112,8 @@ public: void keepAlive(std::shared_ptr media); void keepAlive(std::shared_ptr media); - void startExport(PeerData *peer = nullptr); - void startExport(const MTPInputPeer &singlePeer); void suggestStartExport(TimeId availableAt); void clearExportSuggestion(); - [[nodiscard]] auto currentExportView() const - -> rpl::producer; - bool exportInProgress() const; - void stopExportWithConfirmation(FnMut callback); - void stopExport(); [[nodiscard]] auto passportCredentials() const -> const Passport::SavedCredentials*; @@ -773,14 +759,11 @@ private: void checkPollsClosings(); - not_null _session; + const not_null _session; Storage::DatabasePointer _cache; Storage::DatabasePointer _bigFileCache; - std::unique_ptr _export; - std::unique_ptr _exportPanel; - rpl::event_stream _exportViewChanges; TimeId _exportAvailableAt = 0; QPointer _exportSuggestion; diff --git a/Telegram/SourceFiles/export/export_manager.cpp b/Telegram/SourceFiles/export/export_manager.cpp new file mode 100644 index 0000000000..214fa8d889 --- /dev/null +++ b/Telegram/SourceFiles/export/export_manager.cpp @@ -0,0 +1,95 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "export/export_manager.h" + +#include "export/export_controller.h" +#include "export/view/export_view_panel_controller.h" +#include "data/data_peer.h" +#include "main/main_session.h" +#include "main/main_account.h" +#include "ui/layers/box_content.h" +#include "base/unixtime.h" + +namespace Export { + +Manager::Manager() = default; + +Manager::~Manager() = default; + +void Manager::start(not_null peer) { + start(&peer->session(), peer->input); +} + +void Manager::start( + not_null session, + const MTPInputPeer &singlePeer) { + if (_panel) { + _panel->activatePanel(); + return; + } + _controller = std::make_unique( + &session->mtp(), + singlePeer); + _panel = std::make_unique( + session, + _controller.get()); + session->account().sessionChanges( + ) | rpl::filter([=](Main::Session *value) { + return (value != session); + }) | rpl::start_with_next([=] { + stop(); + }, _panel->lifetime()); + + _viewChanges.fire(_panel.get()); + + _panel->stopRequests( + ) | rpl::start_with_next([=] { + LOG(("Export Info: Stop requested.")); + stop(); + }, _controller->lifetime()); +} + +rpl::producer Manager::currentView( +) const { + return _viewChanges.events_starting_with(_panel.get()); +} + +bool Manager::inProgress() const { + return _controller != nullptr; +} + +bool Manager::inProgress(not_null session) const { + return _panel && (&_panel->session() == session); +} + +void Manager::stopWithConfirmation(FnMut callback) { + if (!_panel) { + callback(); + return; + } + auto closeAndCall = [=, callback = std::move(callback)]() mutable { + auto saved = std::move(callback); + LOG(("Export Info: Stop With Confirmation.")); + stop(); + if (saved) { + saved(); + } + }; + _panel->stopWithConfirmation(std::move(closeAndCall)); +} + +void Manager::stop() { + if (_panel) { + LOG(("Export Info: Destroying.")); + _panel = nullptr; + _viewChanges.fire(nullptr); + } + _controller = nullptr; +} + +} // namespace Export diff --git a/Telegram/SourceFiles/export/export_manager.h b/Telegram/SourceFiles/export/export_manager.h new file mode 100644 index 0000000000..3879d10ee4 --- /dev/null +++ b/Telegram/SourceFiles/export/export_manager.h @@ -0,0 +1,51 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +class PeerData; + +namespace Ui { +class BoxContent; +} // namespace Ui + +namespace Main { +class Session; +} // namespace Main + +namespace Export { + +class Controller; + +namespace View { +class PanelController; +} // namespace View + +class Manager final { +public: + Manager(); + ~Manager(); + + void start(not_null peer); + void start( + not_null session, + const MTPInputPeer &singlePeer = MTP_inputPeerEmpty()); + + [[nodiscard]] rpl::producer currentView() const; + [[nodiscard]] bool inProgress() const; + [[nodiscard]] bool inProgress(not_null session) const; + void stopWithConfirmation(FnMut callback); + void stop(); + +private: + std::unique_ptr _controller; + std::unique_ptr _panel; + rpl::event_stream _viewChanges; + +}; + +} // namespace Export diff --git a/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp b/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp index c8435ce5c4..30a337242e 100644 --- a/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp +++ b/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "export/view/export_view_settings.h" #include "export/view/export_view_progress.h" +#include "export/export_manager.h" #include "ui/widgets/labels.h" #include "ui/widgets/separate_panel.h" #include "ui/wrap/padding_wrap.h" @@ -16,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/confirm_box.h" #include "lang/lang_keys.h" #include "storage/storage_account.h" +#include "core/application.h" #include "core/file_utilities.h" #include "main/main_session.h" #include "data/data_session.h" @@ -51,7 +53,8 @@ void SuggestBox::prepare() { addButton(tr::lng_box_ok(), [=] { closeBox(); - _session->data().startExport( + Core::App().exportManager().start( + _session, _session->local().readExportSettings().singlePeer); }); addButton(tr::lng_export_suggest_cancel(), [=] { closeBox(); }); diff --git a/Telegram/SourceFiles/export/view/export_view_panel_controller.h b/Telegram/SourceFiles/export/view/export_view_panel_controller.h index afed15f1b1..d13d033a64 100644 --- a/Telegram/SourceFiles/export/view/export_view_panel_controller.h +++ b/Telegram/SourceFiles/export/view/export_view_panel_controller.h @@ -38,12 +38,16 @@ public: not_null process); ~PanelController(); + [[nodiscard]] Main::Session &session() const { + return *_session; + } + void activatePanel(); void stopWithConfirmation(FnMut callback = nullptr); - rpl::producer<> stopRequests() const; + [[nodiscard]] rpl::producer<> stopRequests() const; - rpl::lifetime &lifetime() { + [[nodiscard]] rpl::lifetime &lifetime() { return _lifetime; } diff --git a/Telegram/SourceFiles/main/main_domain.cpp b/Telegram/SourceFiles/main/main_domain.cpp index 7ca6b64edb..d4e2945fee 100644 --- a/Telegram/SourceFiles/main/main_domain.cpp +++ b/Telegram/SourceFiles/main/main_domain.cpp @@ -15,7 +15,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mtproto/mtproto_config.h" #include "mtproto/mtproto_dc_options.h" #include "storage/storage_domain.h" +#include "storage/storage_account.h" #include "storage/localstorage.h" +#include "export/export_settings.h" #include "facades.h" namespace Main { @@ -93,6 +95,15 @@ void Domain::activateAfterStarting() { activate(toActivate); removePasscodeIfEmpty(); + + for (const auto &[index, account] : _accounts) { + if (const auto session = account->maybeSession()) { + const auto settings = session->local().readExportSettings(); + if (const auto availableAt = settings.availableAt) { + session->data().suggestStartExport(availableAt); + } + } + } } const std::vector &Domain::accounts() const { diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 0fc30b3c41..3b0d53b85a 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -96,6 +96,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "calls/calls_instance.h" #include "calls/calls_top_bar.h" #include "export/export_settings.h" +#include "export/export_manager.h" #include "export/view/export_view_top_bar.h" #include "export/view/export_view_panel_controller.h" #include "main/main_session.h" @@ -255,12 +256,17 @@ MainWidget::MainWidget( handleAudioUpdate(state); }, lifetime()); - subscribe(session().calls().currentCallChanged(), [this](Calls::Call *call) { setCurrentCall(call); }); + subscribe(session().calls().currentCallChanged(), [=](Calls::Call *call) { + setCurrentCall(call); + }); - session().data().currentExportView( + Core::App().exportManager().currentView( ) | rpl::start_with_next([=](Export::View::PanelController *view) { setCurrentExportView(view); }, lifetime()); + if (_exportTopBar) { + _exportTopBar->finishAnimating(); + } subscribe(_controller->dialogsListFocused(), [this](bool) { updateDialogsWidthAnimated(); @@ -354,10 +360,6 @@ MainWidget::MainWidget( cSetOtherOnline(0); - if (const auto availableAt = session().local().readExportSettings().availableAt) { - session().data().suggestStartExport(availableAt); - } - _history->start(); Core::App().checkStartUrl(); @@ -1007,8 +1009,10 @@ void MainWidget::setCurrentExportView(Export::View::PanelController *view) { } else { _exportTopBar->entity()->updateData(std::move(data)); } - }, _currentExportView->lifetime()); + }, _exportViewLifetime); } else { + _exportViewLifetime.destroy(); + LOG(("Export Info: Destroy top bar by controller removal.")); destroyExportTopBar(); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 21b3f16ce5..622cdbf2a1 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -376,6 +376,7 @@ private: Export::View::PanelController *_currentExportView = nullptr; object_ptr> _exportTopBar = { nullptr }; + rpl::lifetime _exportViewLifetime; object_ptr> _player = { nullptr }; diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 2f046daffd..17c2f77cee 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -25,8 +25,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/shortcuts.h" #include "core/sandbox.h" #include "core/application.h" -#include "main/main_session.h" +#include "export/export_manager.h" #include "intro/intro_widget.h" +#include "main/main_session.h" #include "main/main_account.h" // Account::sessionValue. #include "mainwidget.h" #include "boxes/confirm_box.h" @@ -675,9 +676,9 @@ void MainWindow::showLogoutConfirmation() { } if (account && account->sessionExists() - && account->session().data().exportInProgress()) { + && Core::App().exportManager().inProgress(&account->session())) { Ui::hideLayer(); - account->session().data().stopExportWithConfirmation([=] { + Core::App().exportManager().stopWithConfirmation([=] { Core::App().logout(account); }); } else { diff --git a/Telegram/SourceFiles/settings/settings_chat.cpp b/Telegram/SourceFiles/settings/settings_chat.cpp index 1fa2a6049f..d7eecc043f 100644 --- a/Telegram/SourceFiles/settings/settings_chat.cpp +++ b/Telegram/SourceFiles/settings/settings_chat.cpp @@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/toast/toast.h" #include "ui/image/image.h" #include "lang/lang_keys.h" +#include "export/export_manager.h" #include "window/themes/window_theme.h" #include "window/themes/window_themes_embedded.h" #include "window/themes/window_theme_editor_box.h" @@ -803,7 +804,7 @@ void SetupExport( base::call_delayed( st::boxDuration, session, - [=] { session->data().startExport(); }); + [=] { Core::App().exportManager().start(session); }); }); } diff --git a/Telegram/SourceFiles/settings/settings_codes.cpp b/Telegram/SourceFiles/settings/settings_codes.cpp index eea48db355..dd0243472f 100644 --- a/Telegram/SourceFiles/settings/settings_codes.cpp +++ b/Telegram/SourceFiles/settings/settings_codes.cpp @@ -127,9 +127,7 @@ auto GenerateCodes() { Ui::Toast::Show("Forced custom scheme register."); }); #endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME - codes.emplace(qsl("export"), [](SessionController *window) { - window->session().data().startExport(); - }); + #if defined Q_OS_WIN || defined Q_OS_MAC codes.emplace(qsl("freetype"), [](SessionController *window) { auto text = cUseFreeType() diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 855b01aa4c..2eefb268a4 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -50,6 +50,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_histories.h" #include "data/data_chat_filters.h" #include "dialogs/dialogs_key.h" +#include "core/application.h" +#include "export/export_manager.h" #include "boxes/peers/edit_peer_info_box.h" #include "facades.h" // Adaptive::ThreeColumn #include "styles/style_layers.h" @@ -719,7 +721,7 @@ void FolderFiller::addTogglesForArchive() { } // namespace void PeerMenuExportChat(not_null peer) { - peer->owner().startExport(peer); + Core::App().exportManager().start(peer); } void PeerMenuDeleteContact(not_null user) {