mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Several working accounts together.
This commit is contained in:
parent
6fc5e22882
commit
ab5796c117
14 changed files with 97 additions and 60 deletions
|
@ -148,19 +148,18 @@ Application::~Application() {
|
||||||
_mediaView = nullptr;
|
_mediaView = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeAccount().sessionExists()) {
|
unlockTerms();
|
||||||
activeAccount().session().saveSettingsNowIfNeeded();
|
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();
|
Local::finish();
|
||||||
|
|
||||||
// Some MTP requests can be cancelled from data clearing.
|
|
||||||
unlockTerms();
|
|
||||||
activeAccount().destroySession();
|
|
||||||
activeAccount().clearMtp();
|
|
||||||
|
|
||||||
Shortcuts::Finish();
|
Shortcuts::Finish();
|
||||||
|
|
||||||
Ui::Emoji::Clear();
|
Ui::Emoji::Clear();
|
||||||
|
@ -230,6 +229,10 @@ void Application::run() {
|
||||||
QMimeDatabase().mimeTypeForName(qsl("text/plain"));
|
QMimeDatabase().mimeTypeForName(qsl("text/plain"));
|
||||||
|
|
||||||
_window = std::make_unique<Window::Controller>();
|
_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);
|
QCoreApplication::instance()->installEventFilter(this);
|
||||||
connect(
|
connect(
|
||||||
|
@ -251,8 +254,6 @@ void Application::run() {
|
||||||
Global::RefLocalPasscodeChanged().notify();
|
Global::RefLocalPasscodeChanged().notify();
|
||||||
lockByPasscode();
|
lockByPasscode();
|
||||||
DEBUG_LOG(("Application Info: passcode needed..."));
|
DEBUG_LOG(("Application Info: passcode needed..."));
|
||||||
} else {
|
|
||||||
_window->showAccount(&activeAccount());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_window->widget()->show();
|
_window->widget()->show();
|
||||||
|
|
|
@ -151,22 +151,16 @@ void Step::finish(const MTPUser &user, QImage &&photo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto account = _account;
|
const auto account = _account;
|
||||||
const auto weak = base::make_weak(account.get());
|
|
||||||
account->createSession(user);
|
account->createSession(user);
|
||||||
if (weak) {
|
|
||||||
account->local().writeMtpData();
|
|
||||||
}
|
|
||||||
App::wnd()->controller().setupMain();
|
|
||||||
|
|
||||||
// "this" is already deleted here by creating the main widget.
|
// "this" is already deleted here by creating the main widget.
|
||||||
if (weak && account->sessionExists()) {
|
account->local().writeMtpData();
|
||||||
auto &session = account->session();
|
auto &session = account->session();
|
||||||
if (!photo.isNull()) {
|
if (!photo.isNull()) {
|
||||||
session.api().uploadPeerPhoto(session.user(), std::move(photo));
|
session.api().uploadPeerPhoto(session.user(), std::move(photo));
|
||||||
}
|
}
|
||||||
if (session.supportMode()) {
|
if (session.supportMode()) {
|
||||||
PrepareSupportMode(&session);
|
PrepareSupportMode(&session);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,11 @@ void Account::start(std::shared_ptr<MTP::AuthKey> localKey) {
|
||||||
finishStarting();
|
finishStarting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Account::startAdded(std::shared_ptr<MTP::AuthKey> localKey) {
|
||||||
|
_local->startAdded(std::move(localKey));
|
||||||
|
finishStarting();
|
||||||
|
}
|
||||||
|
|
||||||
void Account::finishStarting() {
|
void Account::finishStarting() {
|
||||||
_appConfig = std::make_unique<AppConfig>(this);
|
_appConfig = std::make_unique<AppConfig>(this);
|
||||||
watchProxyChanges();
|
watchProxyChanges();
|
||||||
|
@ -151,10 +156,11 @@ void Account::createSession(
|
||||||
|
|
||||||
_session = std::make_unique<Session>(this, user, std::move(settings));
|
_session = std::make_unique<Session>(this, user, std::move(settings));
|
||||||
if (!serialized.isEmpty()) {
|
if (!serialized.isEmpty()) {
|
||||||
// For now it depends on Auth() which depends on _sessionValue.
|
|
||||||
local().readSelf(_session.get(), serialized, streamVersion);
|
local().readSelf(_session.get(), serialized, streamVersion);
|
||||||
}
|
}
|
||||||
_sessionValue = _session.get();
|
_sessionValue = _session.get();
|
||||||
|
|
||||||
|
Ensures(_session != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::destroySession() {
|
void Account::destroySession() {
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
[[nodiscard]] Storage::StartResult legacyStart(
|
[[nodiscard]] Storage::StartResult legacyStart(
|
||||||
const QByteArray &passcode);
|
const QByteArray &passcode);
|
||||||
void start(std::shared_ptr<MTP::AuthKey> localKey);
|
void start(std::shared_ptr<MTP::AuthKey> localKey);
|
||||||
|
void startAdded(std::shared_ptr<MTP::AuthKey> localKey);
|
||||||
|
|
||||||
[[nodiscard]] UserId willHaveUserId() const;
|
[[nodiscard]] UserId willHaveUserId() const;
|
||||||
void createSession(const MTPUser &user);
|
void createSession(const MTPUser &user);
|
||||||
|
|
|
@ -66,6 +66,12 @@ rpl::producer<Account*> Accounts::activeValue() const {
|
||||||
return _active.value();
|
return _active.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Accounts::activeIndex() const {
|
||||||
|
Expects(_accounts.contains(_activeIndex));
|
||||||
|
|
||||||
|
return _activeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
Account &Accounts::active() const {
|
Account &Accounts::active() const {
|
||||||
Expects(!_accounts.empty());
|
Expects(!_accounts.empty());
|
||||||
|
|
||||||
|
@ -91,11 +97,18 @@ rpl::producer<Session*> Accounts::activeSessionValue() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Accounts::add() {
|
int Accounts::add() {
|
||||||
|
Expects(!Core::App().locked());
|
||||||
|
|
||||||
auto index = 0;
|
auto index = 0;
|
||||||
while (_accounts.contains(index)) {
|
while (_accounts.contains(index)) {
|
||||||
++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;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +120,10 @@ void Accounts::activate(int index) {
|
||||||
_active = _accounts.find(index)->second.get();
|
_active = _accounts.find(index)->second.get();
|
||||||
_active.current()->sessionValue(
|
_active.current()->sessionValue(
|
||||||
) | rpl::start_to_stream(_activeSessions, _activeLifetime);
|
) | rpl::start_to_stream(_activeSessions, _activeLifetime);
|
||||||
|
|
||||||
|
crl::on_main(&Core::App(), [=] {
|
||||||
|
_local->writeAccounts();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
|
|
@ -34,6 +34,7 @@ public:
|
||||||
[[nodiscard]] rpl::producer<Account*> activeValue() const;
|
[[nodiscard]] rpl::producer<Account*> activeValue() const;
|
||||||
|
|
||||||
// Expects(started());
|
// Expects(started());
|
||||||
|
[[nodiscard]] int activeIndex() const;
|
||||||
[[nodiscard]] Account &active() const;
|
[[nodiscard]] Account &active() const;
|
||||||
[[nodiscard]] rpl::producer<not_null<Account*>> activeChanges() const;
|
[[nodiscard]] rpl::producer<not_null<Account*>> activeChanges() const;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
#include "main/main_accounts.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "lang/lang_cloud_manager.h"
|
#include "lang/lang_cloud_manager.h"
|
||||||
#include "lang/lang_instance.h"
|
#include "lang/lang_instance.h"
|
||||||
|
@ -124,6 +125,31 @@ auto GenerateCodes() {
|
||||||
window->showSettings(Settings::Type::Folders);
|
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
|
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
||||||
codes.emplace(qsl("registertg"), [](SessionController *window) {
|
codes.emplace(qsl("registertg"), [](SessionController *window) {
|
||||||
Platform::RegisterCustomScheme(true);
|
Platform::RegisterCustomScheme(true);
|
||||||
|
|
|
@ -50,11 +50,10 @@ using Database = Storage::Cache::Database;
|
||||||
QString _basePath, _userBasePath, _userDbPath;
|
QString _basePath, _userBasePath, _userDbPath;
|
||||||
|
|
||||||
bool _started = false;
|
bool _started = false;
|
||||||
internal::Manager *_manager = nullptr;
|
|
||||||
TaskQueue *_localLoader = nullptr;
|
TaskQueue *_localLoader = nullptr;
|
||||||
|
|
||||||
bool _working() {
|
bool _working() {
|
||||||
return _manager && !_basePath.isEmpty();
|
return !_basePath.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckStreamStatus(QDataStream &stream) {
|
bool CheckStreamStatus(QDataStream &stream) {
|
||||||
|
@ -290,12 +289,7 @@ bool _readOldMtpData(bool remove, ReadSettingsContext &context) {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void finish() {
|
void finish() {
|
||||||
if (_manager) {
|
delete base::take(_localLoader);
|
||||||
_manager->finish();
|
|
||||||
_manager->deleteLater();
|
|
||||||
_manager = nullptr;
|
|
||||||
delete base::take(_localLoader);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitialLoadTheme();
|
void InitialLoadTheme();
|
||||||
|
@ -303,9 +297,8 @@ bool ApplyDefaultNightMode();
|
||||||
void readLangPack();
|
void readLangPack();
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
Expects(!_manager);
|
Expects(_basePath.isEmpty());
|
||||||
|
|
||||||
_manager = new internal::Manager();
|
|
||||||
_localLoader = new TaskQueue(kFileLoaderQueueStopTimeout);
|
_localLoader = new TaskQueue(kFileLoaderQueueStopTimeout);
|
||||||
|
|
||||||
_basePath = cWorkingDir() + qsl("tdata/");
|
_basePath = cWorkingDir() + qsl("tdata/");
|
||||||
|
@ -1081,13 +1074,4 @@ void ClearManager::onStart() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
Manager::Manager() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::finish() {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace Local
|
} // namespace Local
|
||||||
|
|
|
@ -110,15 +110,4 @@ bool readOldUserSettings(
|
||||||
bool remove,
|
bool remove,
|
||||||
Storage::details::ReadSettingsContext &context);
|
Storage::details::ReadSettingsContext &context);
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
class Manager final : public QObject {
|
|
||||||
public:
|
|
||||||
Manager();
|
|
||||||
|
|
||||||
void finish();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace Local
|
} // namespace Local
|
||||||
|
|
|
@ -124,8 +124,6 @@ StartResult Account::legacyStart(const QByteArray &passcode) {
|
||||||
const auto result = readMapWith(MTP::AuthKeyPtr(), passcode);
|
const auto result = readMapWith(MTP::AuthKeyPtr(), passcode);
|
||||||
if (result == ReadMapResult::Failed) {
|
if (result == ReadMapResult::Failed) {
|
||||||
Assert(_localKey == nullptr);
|
Assert(_localKey == nullptr);
|
||||||
//_mapChanged = true;
|
|
||||||
//writeMap();
|
|
||||||
} else if (result == ReadMapResult::IncorrectPasscode) {
|
} else if (result == ReadMapResult::IncorrectPasscode) {
|
||||||
return StartResult::IncorrectPasscode;
|
return StartResult::IncorrectPasscode;
|
||||||
}
|
}
|
||||||
|
@ -141,6 +139,13 @@ void Account::start(MTP::AuthKeyPtr localKey) {
|
||||||
clearLegacyFiles();
|
clearLegacyFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Account::startAdded(MTP::AuthKeyPtr localKey) {
|
||||||
|
Expects(localKey != nullptr);
|
||||||
|
|
||||||
|
_localKey = std::move(localKey);
|
||||||
|
clearLegacyFiles();
|
||||||
|
}
|
||||||
|
|
||||||
void Account::clearLegacyFiles() {
|
void Account::clearLegacyFiles() {
|
||||||
const auto weak = base::make_weak(_owner.get());
|
const auto weak = base::make_weak(_owner.get());
|
||||||
ClearLegacyFiles(_basePath, [weak, this](
|
ClearLegacyFiles(_basePath, [weak, this](
|
||||||
|
|
|
@ -54,8 +54,9 @@ public:
|
||||||
Account(not_null<Main::Account*> owner, const QString &dataName);
|
Account(not_null<Main::Account*> owner, const QString &dataName);
|
||||||
~Account();
|
~Account();
|
||||||
|
|
||||||
[[nodiscard]] void start(MTP::AuthKeyPtr localKey);
|
|
||||||
[[nodiscard]] StartResult legacyStart(const QByteArray &passcode);
|
[[nodiscard]] StartResult legacyStart(const QByteArray &passcode);
|
||||||
|
[[nodiscard]] void start(MTP::AuthKeyPtr localKey);
|
||||||
|
[[nodiscard]] void startAdded(MTP::AuthKeyPtr localKey);
|
||||||
[[nodiscard]] int oldMapVersion() const {
|
[[nodiscard]] int oldMapVersion() const {
|
||||||
return _oldMapVersion;
|
return _oldMapVersion;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,12 @@ StartResult Accounts::start(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Accounts::startAdded(not_null<Main::Account*> account) {
|
||||||
|
Expects(_localKey != nullptr);
|
||||||
|
|
||||||
|
account->startAdded(_localKey);
|
||||||
|
}
|
||||||
|
|
||||||
void Accounts::startWithSingleAccount(
|
void Accounts::startWithSingleAccount(
|
||||||
const QByteArray &passcode,
|
const QByteArray &passcode,
|
||||||
Fn<void(int, std::unique_ptr<Main::Account>)> callback,
|
Fn<void(int, std::unique_ptr<Main::Account>)> callback,
|
||||||
|
@ -202,13 +208,17 @@ void Accounts::writeAccounts() {
|
||||||
key.writeData(_passcodeKeyEncrypted);
|
key.writeData(_passcodeKeyEncrypted);
|
||||||
|
|
||||||
const auto &list = _owner->list();
|
const auto &list = _owner->list();
|
||||||
|
const auto active = _owner->activeIndex();
|
||||||
|
|
||||||
auto keySize = sizeof(qint32) + sizeof(qint32) * list.size();
|
auto keySize = sizeof(qint32) + sizeof(qint32) * list.size();
|
||||||
|
|
||||||
EncryptedDescriptor keyData(keySize);
|
EncryptedDescriptor keyData(keySize);
|
||||||
keyData.stream << qint32(list.size());
|
keyData.stream << qint32(list.size());
|
||||||
|
keyData.stream << qint32(active);
|
||||||
for (const auto &[index, account] : list) {
|
for (const auto &[index, account] : list) {
|
||||||
keyData.stream << qint32(index);
|
if (index != active) {
|
||||||
|
keyData.stream << qint32(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
key.writeEncrypted(keyData, _localKey);
|
key.writeEncrypted(keyData, _localKey);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
[[nodiscard]] StartResult start(
|
[[nodiscard]] StartResult start(
|
||||||
const QByteArray &passcode,
|
const QByteArray &passcode,
|
||||||
Fn<void(int, std::unique_ptr<Main::Account>)> callback);
|
Fn<void(int, std::unique_ptr<Main::Account>)> callback);
|
||||||
|
void startAdded(not_null<Main::Account*> account);
|
||||||
void writeAccounts();
|
void writeAccounts();
|
||||||
|
|
||||||
[[nodiscard]] bool checkPasscode(const QByteArray &passcode) const;
|
[[nodiscard]] bool checkPasscode(const QByteArray &passcode) const;
|
||||||
|
|
|
@ -44,6 +44,7 @@ void Controller::showAccount(not_null<Main::Account*> account) {
|
||||||
|
|
||||||
_account->sessionValue(
|
_account->sessionValue(
|
||||||
) | rpl::start_with_next([=](Main::Session *session) {
|
) | rpl::start_with_next([=](Main::Session *session) {
|
||||||
|
const auto was = base::take(_sessionController);
|
||||||
_sessionController = session
|
_sessionController = session
|
||||||
? std::make_unique<SessionController>(session, this)
|
? std::make_unique<SessionController>(session, this)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
|
Loading…
Add table
Reference in a new issue