From ab5796c1179c4ec067801f5d4fb0dee5f67044d2 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 16 Jun 2020 10:42:47 +0400 Subject: [PATCH] Several working accounts together. --- Telegram/SourceFiles/core/application.cpp | 23 ++++++++-------- Telegram/SourceFiles/intro/intro_step.cpp | 20 +++++--------- Telegram/SourceFiles/main/main_account.cpp | 8 +++++- Telegram/SourceFiles/main/main_account.h | 1 + Telegram/SourceFiles/main/main_accounts.cpp | 19 +++++++++++++- Telegram/SourceFiles/main/main_accounts.h | 1 + .../SourceFiles/settings/settings_codes.cpp | 26 +++++++++++++++++++ Telegram/SourceFiles/storage/localstorage.cpp | 22 +++------------- Telegram/SourceFiles/storage/localstorage.h | 11 -------- .../SourceFiles/storage/storage_account.cpp | 9 +++++-- .../SourceFiles/storage/storage_account.h | 3 ++- .../SourceFiles/storage/storage_accounts.cpp | 12 ++++++++- .../SourceFiles/storage/storage_accounts.h | 1 + .../SourceFiles/window/window_controller.cpp | 1 + 14 files changed, 97 insertions(+), 60 deletions(-) diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 1389b56a7..09d5d5e94 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -148,19 +148,18 @@ Application::~Application() { _mediaView = nullptr; } - if (activeAccount().sessionExists()) { - activeAccount().session().saveSettingsNowIfNeeded(); + unlockTerms(); + for (const auto &[index, account] : accounts().list()) { + if (account->sessionExists()) { + account->session().saveSettingsNowIfNeeded(); + } + // Some MTP requests can be cancelled from data clearing. + account->destroySession(); + account->clearMtp(); } - // This can call writeMap() that serializes Main::Session. - // In case it gets called after destroySession() we get missing data. Local::finish(); - // Some MTP requests can be cancelled from data clearing. - unlockTerms(); - activeAccount().destroySession(); - activeAccount().clearMtp(); - Shortcuts::Finish(); Ui::Emoji::Clear(); @@ -230,6 +229,10 @@ void Application::run() { QMimeDatabase().mimeTypeForName(qsl("text/plain")); _window = std::make_unique(); + accounts().activeChanges( + ) | rpl::start_with_next([=](not_null account) { + _window->showAccount(account); + }, _window->widget()->lifetime()); QCoreApplication::instance()->installEventFilter(this); connect( @@ -251,8 +254,6 @@ void Application::run() { Global::RefLocalPasscodeChanged().notify(); lockByPasscode(); DEBUG_LOG(("Application Info: passcode needed...")); - } else { - _window->showAccount(&activeAccount()); } _window->widget()->show(); diff --git a/Telegram/SourceFiles/intro/intro_step.cpp b/Telegram/SourceFiles/intro/intro_step.cpp index 1a2c1e9fc..1010b0beb 100644 --- a/Telegram/SourceFiles/intro/intro_step.cpp +++ b/Telegram/SourceFiles/intro/intro_step.cpp @@ -151,22 +151,16 @@ void Step::finish(const MTPUser &user, QImage &&photo) { } const auto account = _account; - const auto weak = base::make_weak(account.get()); account->createSession(user); - if (weak) { - account->local().writeMtpData(); - } - App::wnd()->controller().setupMain(); // "this" is already deleted here by creating the main widget. - if (weak && account->sessionExists()) { - auto &session = account->session(); - if (!photo.isNull()) { - session.api().uploadPeerPhoto(session.user(), std::move(photo)); - } - if (session.supportMode()) { - PrepareSupportMode(&session); - } + account->local().writeMtpData(); + auto &session = account->session(); + if (!photo.isNull()) { + session.api().uploadPeerPhoto(session.user(), std::move(photo)); + } + if (session.supportMode()) { + PrepareSupportMode(&session); } } diff --git a/Telegram/SourceFiles/main/main_account.cpp b/Telegram/SourceFiles/main/main_account.cpp index 7e182343b..dfc7a231a 100644 --- a/Telegram/SourceFiles/main/main_account.cpp +++ b/Telegram/SourceFiles/main/main_account.cpp @@ -64,6 +64,11 @@ void Account::start(std::shared_ptr localKey) { finishStarting(); } +void Account::startAdded(std::shared_ptr localKey) { + _local->startAdded(std::move(localKey)); + finishStarting(); +} + void Account::finishStarting() { _appConfig = std::make_unique(this); watchProxyChanges(); @@ -151,10 +156,11 @@ void Account::createSession( _session = std::make_unique(this, user, std::move(settings)); if (!serialized.isEmpty()) { - // For now it depends on Auth() which depends on _sessionValue. local().readSelf(_session.get(), serialized, streamVersion); } _sessionValue = _session.get(); + + Ensures(_session != nullptr); } void Account::destroySession() { diff --git a/Telegram/SourceFiles/main/main_account.h b/Telegram/SourceFiles/main/main_account.h index f4676ee92..3ababab33 100644 --- a/Telegram/SourceFiles/main/main_account.h +++ b/Telegram/SourceFiles/main/main_account.h @@ -37,6 +37,7 @@ public: [[nodiscard]] Storage::StartResult legacyStart( const QByteArray &passcode); void start(std::shared_ptr localKey); + void startAdded(std::shared_ptr localKey); [[nodiscard]] UserId willHaveUserId() const; void createSession(const MTPUser &user); diff --git a/Telegram/SourceFiles/main/main_accounts.cpp b/Telegram/SourceFiles/main/main_accounts.cpp index 4528cc529..f1124eece 100644 --- a/Telegram/SourceFiles/main/main_accounts.cpp +++ b/Telegram/SourceFiles/main/main_accounts.cpp @@ -66,6 +66,12 @@ rpl::producer Accounts::activeValue() const { return _active.value(); } +int Accounts::activeIndex() const { + Expects(_accounts.contains(_activeIndex)); + + return _activeIndex; +} + Account &Accounts::active() const { Expects(!_accounts.empty()); @@ -91,11 +97,18 @@ rpl::producer Accounts::activeSessionValue() const { } int Accounts::add() { + Expects(!Core::App().locked()); + auto index = 0; while (_accounts.contains(index)) { ++index; } - _accounts.emplace(index, std::make_unique(_dataName, index)); + const auto account = _accounts.emplace( + index, + std::make_unique(_dataName, index) + ).first->second.get(); + _local->startAdded(account); + account->startMtp(); return index; } @@ -107,6 +120,10 @@ void Accounts::activate(int index) { _active = _accounts.find(index)->second.get(); _active.current()->sessionValue( ) | rpl::start_to_stream(_activeSessions, _activeLifetime); + + crl::on_main(&Core::App(), [=] { + _local->writeAccounts(); + }); } } // namespace Main diff --git a/Telegram/SourceFiles/main/main_accounts.h b/Telegram/SourceFiles/main/main_accounts.h index f976153c1..e5039c97b 100644 --- a/Telegram/SourceFiles/main/main_accounts.h +++ b/Telegram/SourceFiles/main/main_accounts.h @@ -34,6 +34,7 @@ public: [[nodiscard]] rpl::producer activeValue() const; // Expects(started()); + [[nodiscard]] int activeIndex() const; [[nodiscard]] Account &active() const; [[nodiscard]] rpl::producer> activeChanges() const; diff --git a/Telegram/SourceFiles/settings/settings_codes.cpp b/Telegram/SourceFiles/settings/settings_codes.cpp index 18dcee73f..930df4a17 100644 --- a/Telegram/SourceFiles/settings/settings_codes.cpp +++ b/Telegram/SourceFiles/settings/settings_codes.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwindow.h" #include "data/data_session.h" #include "main/main_session.h" +#include "main/main_accounts.h" #include "boxes/confirm_box.h" #include "lang/lang_cloud_manager.h" #include "lang/lang_instance.h" @@ -124,6 +125,31 @@ auto GenerateCodes() { window->showSettings(Settings::Type::Folders); } }); + + codes.emplace(qsl("accadd"), [](SessionController *window) { + crl::on_main(&Core::App(), [=] { + if (window + && !Core::App().locked() + && Core::App().accounts().list().size() < 3) { + Core::App().accounts().activate(Core::App().accounts().add()); + } + }); + }); + for (auto i = 0; i != 3; ++i) { + codes.emplace(qsl("account%1").arg(i + 1), [=]( + SessionController *window) { + crl::on_main(&Core::App(), [=] { + const auto &list = Core::App().accounts().list(); + const auto j = list.find(i); + if (j != list.end() && !Core::App().locked()) { + if (&Core::App().activeAccount() != j->second.get()) { + Core::App().accounts().activate(i); + } + } + }); + }); + } + #ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME codes.emplace(qsl("registertg"), [](SessionController *window) { Platform::RegisterCustomScheme(true); diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index 317e46e98..9af3578de 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -50,11 +50,10 @@ using Database = Storage::Cache::Database; QString _basePath, _userBasePath, _userDbPath; bool _started = false; -internal::Manager *_manager = nullptr; TaskQueue *_localLoader = nullptr; bool _working() { - return _manager && !_basePath.isEmpty(); + return !_basePath.isEmpty(); } bool CheckStreamStatus(QDataStream &stream) { @@ -290,12 +289,7 @@ bool _readOldMtpData(bool remove, ReadSettingsContext &context) { } // namespace void finish() { - if (_manager) { - _manager->finish(); - _manager->deleteLater(); - _manager = nullptr; - delete base::take(_localLoader); - } + delete base::take(_localLoader); } void InitialLoadTheme(); @@ -303,9 +297,8 @@ bool ApplyDefaultNightMode(); void readLangPack(); void start() { - Expects(!_manager); + Expects(_basePath.isEmpty()); - _manager = new internal::Manager(); _localLoader = new TaskQueue(kFileLoaderQueueStopTimeout); _basePath = cWorkingDir() + qsl("tdata/"); @@ -1081,13 +1074,4 @@ void ClearManager::onStart() { } } -namespace internal { - -Manager::Manager() { -} - -void Manager::finish() { -} - -} // namespace internal } // namespace Local diff --git a/Telegram/SourceFiles/storage/localstorage.h b/Telegram/SourceFiles/storage/localstorage.h index bf23d8ff1..0ac8396d1 100644 --- a/Telegram/SourceFiles/storage/localstorage.h +++ b/Telegram/SourceFiles/storage/localstorage.h @@ -110,15 +110,4 @@ bool readOldUserSettings( bool remove, Storage::details::ReadSettingsContext &context); -namespace internal { - -class Manager final : public QObject { -public: - Manager(); - - void finish(); - -}; - -} // namespace internal } // namespace Local diff --git a/Telegram/SourceFiles/storage/storage_account.cpp b/Telegram/SourceFiles/storage/storage_account.cpp index 189f9ccca..5a3987b0c 100644 --- a/Telegram/SourceFiles/storage/storage_account.cpp +++ b/Telegram/SourceFiles/storage/storage_account.cpp @@ -124,8 +124,6 @@ StartResult Account::legacyStart(const QByteArray &passcode) { const auto result = readMapWith(MTP::AuthKeyPtr(), passcode); if (result == ReadMapResult::Failed) { Assert(_localKey == nullptr); - //_mapChanged = true; - //writeMap(); } else if (result == ReadMapResult::IncorrectPasscode) { return StartResult::IncorrectPasscode; } @@ -141,6 +139,13 @@ void Account::start(MTP::AuthKeyPtr localKey) { clearLegacyFiles(); } +void Account::startAdded(MTP::AuthKeyPtr localKey) { + Expects(localKey != nullptr); + + _localKey = std::move(localKey); + clearLegacyFiles(); +} + void Account::clearLegacyFiles() { const auto weak = base::make_weak(_owner.get()); ClearLegacyFiles(_basePath, [weak, this]( diff --git a/Telegram/SourceFiles/storage/storage_account.h b/Telegram/SourceFiles/storage/storage_account.h index d6f91da25..c46afa0e1 100644 --- a/Telegram/SourceFiles/storage/storage_account.h +++ b/Telegram/SourceFiles/storage/storage_account.h @@ -54,8 +54,9 @@ public: Account(not_null owner, const QString &dataName); ~Account(); - [[nodiscard]] void start(MTP::AuthKeyPtr localKey); [[nodiscard]] StartResult legacyStart(const QByteArray &passcode); + [[nodiscard]] void start(MTP::AuthKeyPtr localKey); + [[nodiscard]] void startAdded(MTP::AuthKeyPtr localKey); [[nodiscard]] int oldMapVersion() const { return _oldMapVersion; } diff --git a/Telegram/SourceFiles/storage/storage_accounts.cpp b/Telegram/SourceFiles/storage/storage_accounts.cpp index 53621fb92..8407fb589 100644 --- a/Telegram/SourceFiles/storage/storage_accounts.cpp +++ b/Telegram/SourceFiles/storage/storage_accounts.cpp @@ -71,6 +71,12 @@ StartResult Accounts::start( return result; } +void Accounts::startAdded(not_null account) { + Expects(_localKey != nullptr); + + account->startAdded(_localKey); +} + void Accounts::startWithSingleAccount( const QByteArray &passcode, Fn)> callback, @@ -202,13 +208,17 @@ void Accounts::writeAccounts() { key.writeData(_passcodeKeyEncrypted); const auto &list = _owner->list(); + const auto active = _owner->activeIndex(); auto keySize = sizeof(qint32) + sizeof(qint32) * list.size(); EncryptedDescriptor keyData(keySize); keyData.stream << qint32(list.size()); + keyData.stream << qint32(active); for (const auto &[index, account] : list) { - keyData.stream << qint32(index); + if (index != active) { + keyData.stream << qint32(index); + } } key.writeEncrypted(keyData, _localKey); } diff --git a/Telegram/SourceFiles/storage/storage_accounts.h b/Telegram/SourceFiles/storage/storage_accounts.h index a9dfe350e..02d14d33c 100644 --- a/Telegram/SourceFiles/storage/storage_accounts.h +++ b/Telegram/SourceFiles/storage/storage_accounts.h @@ -32,6 +32,7 @@ public: [[nodiscard]] StartResult start( const QByteArray &passcode, Fn)> callback); + void startAdded(not_null account); void writeAccounts(); [[nodiscard]] bool checkPasscode(const QByteArray &passcode) const; diff --git a/Telegram/SourceFiles/window/window_controller.cpp b/Telegram/SourceFiles/window/window_controller.cpp index 3b8a01bf9..310e63074 100644 --- a/Telegram/SourceFiles/window/window_controller.cpp +++ b/Telegram/SourceFiles/window/window_controller.cpp @@ -44,6 +44,7 @@ void Controller::showAccount(not_null account) { _account->sessionValue( ) | rpl::start_with_next([=](Main::Session *session) { + const auto was = base::take(_sessionController); _sessionController = session ? std::make_unique(session, this) : nullptr;