Several working accounts together.

This commit is contained in:
John Preston 2020-06-16 10:42:47 +04:00
parent 6fc5e22882
commit ab5796c117
14 changed files with 97 additions and 60 deletions

View file

@ -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<Window::Controller>();
accounts().activeChanges(
) | rpl::start_with_next([=](not_null<Main::Account*> 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();

View file

@ -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);
}
}

View file

@ -64,6 +64,11 @@ void Account::start(std::shared_ptr<MTP::AuthKey> localKey) {
finishStarting();
}
void Account::startAdded(std::shared_ptr<MTP::AuthKey> localKey) {
_local->startAdded(std::move(localKey));
finishStarting();
}
void Account::finishStarting() {
_appConfig = std::make_unique<AppConfig>(this);
watchProxyChanges();
@ -151,10 +156,11 @@ void Account::createSession(
_session = std::make_unique<Session>(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() {

View file

@ -37,6 +37,7 @@ public:
[[nodiscard]] Storage::StartResult legacyStart(
const QByteArray &passcode);
void start(std::shared_ptr<MTP::AuthKey> localKey);
void startAdded(std::shared_ptr<MTP::AuthKey> localKey);
[[nodiscard]] UserId willHaveUserId() const;
void createSession(const MTPUser &user);

View file

@ -66,6 +66,12 @@ rpl::producer<Account*> 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<Session*> Accounts::activeSessionValue() const {
}
int Accounts::add() {
Expects(!Core::App().locked());
auto index = 0;
while (_accounts.contains(index)) {
++index;
}
_accounts.emplace(index, std::make_unique<Account>(_dataName, index));
const auto account = _accounts.emplace(
index,
std::make_unique<Account>(_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

View file

@ -34,6 +34,7 @@ public:
[[nodiscard]] rpl::producer<Account*> activeValue() const;
// Expects(started());
[[nodiscard]] int activeIndex() const;
[[nodiscard]] Account &active() const;
[[nodiscard]] rpl::producer<not_null<Account*>> activeChanges() const;

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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](

View file

@ -54,8 +54,9 @@ public:
Account(not_null<Main::Account*> 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;
}

View file

@ -71,6 +71,12 @@ StartResult Accounts::start(
return result;
}
void Accounts::startAdded(not_null<Main::Account*> account) {
Expects(_localKey != nullptr);
account->startAdded(_localKey);
}
void Accounts::startWithSingleAccount(
const QByteArray &passcode,
Fn<void(int, std::unique_ptr<Main::Account>)> 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);
}

View file

@ -32,6 +32,7 @@ public:
[[nodiscard]] StartResult start(
const QByteArray &passcode,
Fn<void(int, std::unique_ptr<Main::Account>)> callback);
void startAdded(not_null<Main::Account*> account);
void writeAccounts();
[[nodiscard]] bool checkPasscode(const QByteArray &passcode) const;

View file

@ -44,6 +44,7 @@ void Controller::showAccount(not_null<Main::Account*> account) {
_account->sessionValue(
) | rpl::start_with_next([=](Main::Session *session) {
const auto was = base::take(_sessionController);
_sessionController = session
? std::make_unique<SessionController>(session, this)
: nullptr;