2017-02-23 09:32:28 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
2018-01-03 10:23:14 +00:00
|
|
|
the official desktop application for the Telegram messaging service.
|
2017-02-23 09:32:28 +00:00
|
|
|
|
2018-01-03 10:23:14 +00:00
|
|
|
For license and copyright information please follow this link:
|
|
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
2017-02-23 09:32:28 +00:00
|
|
|
*/
|
2019-07-24 11:45:24 +00:00
|
|
|
#include "main/main_session.h"
|
2017-02-23 09:32:28 +00:00
|
|
|
|
2017-04-06 19:02:40 +00:00
|
|
|
#include "apiwrap.h"
|
2020-06-11 09:41:03 +00:00
|
|
|
#include "api/api_updates.h"
|
2019-01-21 13:42:21 +00:00
|
|
|
#include "core/application.h"
|
2019-06-05 20:41:51 +00:00
|
|
|
#include "main/main_account.h"
|
2020-06-18 18:04:16 +00:00
|
|
|
#include "main/main_domain.h"
|
2020-06-18 12:47:09 +00:00
|
|
|
#include "main/main_session_settings.h"
|
2020-06-17 09:36:25 +00:00
|
|
|
#include "mtproto/mtproto_config.h"
|
2019-08-23 13:52:59 +00:00
|
|
|
#include "chat_helpers/stickers_emoji_pack.h"
|
2020-03-04 09:21:19 +00:00
|
|
|
#include "chat_helpers/stickers_dice_pack.h"
|
2017-03-04 19:36:59 +00:00
|
|
|
#include "storage/file_download.h"
|
2019-12-05 08:32:33 +00:00
|
|
|
#include "storage/download_manager_mtproto.h"
|
2017-08-04 14:54:32 +00:00
|
|
|
#include "storage/file_upload.h"
|
2020-06-09 16:57:05 +00:00
|
|
|
#include "storage/storage_account.h"
|
2017-09-04 11:40:02 +00:00
|
|
|
#include "storage/storage_facade.h"
|
2020-06-09 16:57:05 +00:00
|
|
|
#include "storage/storage_account.h"
|
2018-01-04 10:22:53 +00:00
|
|
|
#include "data/data_session.h"
|
2020-06-12 12:12:34 +00:00
|
|
|
#include "data/data_changes.h"
|
2019-01-04 11:09:48 +00:00
|
|
|
#include "data/data_user.h"
|
2020-06-11 09:41:03 +00:00
|
|
|
#include "window/window_session_controller.h"
|
2017-12-29 18:17:07 +00:00
|
|
|
#include "window/themes/window_theme.h"
|
2019-08-23 13:52:59 +00:00
|
|
|
//#include "platform/platform_specific.h"
|
2017-04-19 09:44:07 +00:00
|
|
|
#include "calls/calls_instance.h"
|
2018-11-15 15:36:04 +00:00
|
|
|
#include "support/support_helper.h"
|
2019-09-13 06:06:02 +00:00
|
|
|
#include "facades.h"
|
2017-04-15 18:48:54 +00:00
|
|
|
|
2020-02-07 22:42:01 +00:00
|
|
|
#ifndef TDESKTOP_DISABLE_SPELLCHECK
|
|
|
|
#include "chat_helpers/spellchecker_common.h"
|
|
|
|
#endif // TDESKTOP_DISABLE_SPELLCHECK
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
namespace Main {
|
2017-04-15 18:48:54 +00:00
|
|
|
namespace {
|
|
|
|
|
2018-11-04 16:51:59 +00:00
|
|
|
constexpr auto kLegacyCallsPeerToPeerNobody = 4;
|
2017-04-15 18:48:54 +00:00
|
|
|
|
2020-06-17 09:36:25 +00:00
|
|
|
[[nodiscard]] QString ValidatedInternalLinksDomain(
|
2020-06-18 18:04:16 +00:00
|
|
|
not_null<const Session*> session) {
|
2020-06-17 09:36:25 +00:00
|
|
|
// This domain should start with 'http[s]://' and end with '/'.
|
|
|
|
// Like 'https://telegram.me/' or 'https://t.me/'.
|
|
|
|
const auto &domain = session->serverConfig().internalLinksDomain;
|
|
|
|
const auto prefixes = {
|
|
|
|
qstr("https://"),
|
|
|
|
qstr("http://"),
|
|
|
|
};
|
|
|
|
for (const auto &prefix : prefixes) {
|
|
|
|
if (domain.startsWith(prefix, Qt::CaseInsensitive)) {
|
|
|
|
return domain.endsWith('/')
|
|
|
|
? domain
|
|
|
|
: MTP::ConfigFields().internalLinksDomain;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return MTP::ConfigFields().internalLinksDomain;
|
|
|
|
}
|
|
|
|
|
2017-04-15 18:48:54 +00:00
|
|
|
} // namespace
|
2017-02-23 09:32:28 +00:00
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
Session::Session(
|
2020-06-18 18:04:16 +00:00
|
|
|
not_null<Account*> account,
|
2019-10-02 10:46:02 +00:00
|
|
|
const MTPUser &user,
|
2020-06-18 12:47:09 +00:00
|
|
|
std::unique_ptr<SessionSettings> settings)
|
2019-06-05 20:41:51 +00:00
|
|
|
: _account(account)
|
2019-10-02 10:46:02 +00:00
|
|
|
, _settings(std::move(settings))
|
2017-06-05 13:33:45 +00:00
|
|
|
, _api(std::make_unique<ApiWrap>(this))
|
2020-06-11 09:41:03 +00:00
|
|
|
, _updates(std::make_unique<Api::Updates>(this))
|
2019-08-06 16:40:08 +00:00
|
|
|
, _calls(std::make_unique<Calls::Instance>(this))
|
2019-12-05 08:32:33 +00:00
|
|
|
, _downloader(std::make_unique<Storage::DownloadManagerMtproto>(_api.get()))
|
2019-04-12 10:50:41 +00:00
|
|
|
, _uploader(std::make_unique<Storage::Uploader>(_api.get()))
|
2017-09-04 11:40:02 +00:00
|
|
|
, _storage(std::make_unique<Storage::Facade>())
|
2020-06-12 12:12:34 +00:00
|
|
|
, _changes(std::make_unique<Data::Changes>(this))
|
2018-02-18 13:26:28 +00:00
|
|
|
, _data(std::make_unique<Data::Session>(this))
|
2019-01-18 12:27:37 +00:00
|
|
|
, _user(_data->processUser(user))
|
2019-08-01 14:13:02 +00:00
|
|
|
, _emojiStickersPack(std::make_unique<Stickers::EmojiPack>(this))
|
2020-04-06 09:07:49 +00:00
|
|
|
, _diceStickersPacks(std::make_unique<Stickers::DicePacks>(this))
|
2020-06-18 12:47:09 +00:00
|
|
|
, _supportHelper(Support::Helper::Create(this))
|
|
|
|
, _saveSettingsTimer([=] { saveSettings(); }) {
|
|
|
|
Expects(_settings != nullptr);
|
|
|
|
|
2018-05-11 14:03:53 +00:00
|
|
|
subscribe(Global::RefConnectionTypeChanged(), [=] {
|
2020-04-24 10:31:28 +00:00
|
|
|
_api->refreshTopPromotion();
|
2018-05-11 14:03:53 +00:00
|
|
|
});
|
2020-04-24 10:31:28 +00:00
|
|
|
_api->refreshTopPromotion();
|
2018-06-03 13:30:40 +00:00
|
|
|
_api->requestTermsUpdate();
|
2018-09-11 12:50:40 +00:00
|
|
|
_api->requestFullPeer(_user);
|
2018-05-15 16:38:27 +00:00
|
|
|
|
2020-06-17 09:36:25 +00:00
|
|
|
_api->instance().setUserPhone(_user->phone());
|
2020-06-15 16:25:02 +00:00
|
|
|
|
2018-09-11 14:36:09 +00:00
|
|
|
crl::on_main(this, [=] {
|
2020-06-12 12:12:34 +00:00
|
|
|
using Flag = Data::PeerUpdate::Flag;
|
|
|
|
changes().peerUpdates(
|
|
|
|
_user,
|
|
|
|
Flag::Name
|
|
|
|
| Flag::Username
|
|
|
|
| Flag::Photo
|
|
|
|
| Flag::About
|
|
|
|
| Flag::PhoneNumber
|
2020-06-15 16:25:02 +00:00
|
|
|
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
|
2020-06-12 12:12:34 +00:00
|
|
|
local().writeSelf();
|
2020-06-15 16:25:02 +00:00
|
|
|
|
|
|
|
if (update.flags & Flag::PhoneNumber) {
|
|
|
|
const auto phone = _user->phone();
|
2020-06-17 09:36:25 +00:00
|
|
|
_api->instance().setUserPhone(phone);
|
2020-06-15 16:25:02 +00:00
|
|
|
if (!phone.isEmpty()) {
|
2020-06-17 09:36:25 +00:00
|
|
|
_api->instance().requestConfig();
|
2020-06-15 16:25:02 +00:00
|
|
|
}
|
|
|
|
}
|
2020-06-12 12:12:34 +00:00
|
|
|
}, _lifetime);
|
2019-10-02 10:46:02 +00:00
|
|
|
|
2020-06-18 12:47:09 +00:00
|
|
|
if (_settings->hadLegacyCallsPeerToPeerNobody()) {
|
2019-10-02 10:46:02 +00:00
|
|
|
api().savePrivacy(
|
|
|
|
MTP_inputPrivacyKeyPhoneP2P(),
|
|
|
|
QVector<MTPInputPrivacyRule>(
|
|
|
|
1,
|
|
|
|
MTP_inputPrivacyValueDisallowAll()));
|
|
|
|
saveSettingsDelayed();
|
|
|
|
}
|
2018-09-11 14:36:09 +00:00
|
|
|
});
|
|
|
|
|
2020-02-07 22:42:01 +00:00
|
|
|
#ifndef TDESKTOP_DISABLE_SPELLCHECK
|
|
|
|
Spellchecker::Start(this);
|
|
|
|
#endif // TDESKTOP_DISABLE_SPELLCHECK
|
2017-02-23 09:32:28 +00:00
|
|
|
}
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
Session::~Session() {
|
2020-06-16 09:40:43 +00:00
|
|
|
data().clear();
|
2019-06-05 20:41:51 +00:00
|
|
|
ClickHandler::clearActive();
|
|
|
|
ClickHandler::unpressed();
|
|
|
|
}
|
|
|
|
|
2020-06-18 18:04:16 +00:00
|
|
|
Account &Session::account() const {
|
2019-06-05 20:41:51 +00:00
|
|
|
return *_account;
|
|
|
|
}
|
|
|
|
|
2020-06-09 16:57:05 +00:00
|
|
|
Storage::Account &Session::local() const {
|
|
|
|
return _account->local();
|
|
|
|
}
|
|
|
|
|
2020-06-18 18:04:16 +00:00
|
|
|
Domain &Session::domain() const {
|
|
|
|
return _account->domain();
|
|
|
|
}
|
|
|
|
|
|
|
|
Storage::Domain &Session::domainLocal() const {
|
|
|
|
return _account->domainLocal();
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
base::Observable<void> &Session::downloaderTaskFinished() {
|
2017-08-04 14:54:32 +00:00
|
|
|
return downloader().taskFinished();
|
2017-03-04 19:36:59 +00:00
|
|
|
}
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
UserId Session::userId() const {
|
2019-01-04 11:09:48 +00:00
|
|
|
return _user->bareId();
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
PeerId Session::userPeerId() const {
|
2019-01-04 11:09:48 +00:00
|
|
|
return _user->id;
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
bool Session::validateSelf(const MTPUser &user) {
|
2018-05-13 08:42:25 +00:00
|
|
|
if (user.type() != mtpc_user || !user.c_user().is_self()) {
|
|
|
|
LOG(("API Error: bad self user received."));
|
|
|
|
return false;
|
2019-07-05 13:38:38 +00:00
|
|
|
} else if (user.c_user().vid().v != userId()) {
|
2017-03-04 19:36:59 +00:00
|
|
|
LOG(("Auth Error: wrong self user received."));
|
2019-07-24 08:46:23 +00:00
|
|
|
crl::on_main(this, [=] { _account->logOut(); });
|
2017-03-04 19:36:59 +00:00
|
|
|
return false;
|
2017-02-23 09:32:28 +00:00
|
|
|
}
|
2017-03-04 19:36:59 +00:00
|
|
|
return true;
|
2017-02-23 09:32:28 +00:00
|
|
|
}
|
2017-03-04 19:36:59 +00:00
|
|
|
|
2020-06-18 18:04:16 +00:00
|
|
|
void Session::saveSettings() {
|
|
|
|
local().writeSessionSettings();
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
void Session::saveSettingsDelayed(crl::time delay) {
|
2019-08-23 13:52:59 +00:00
|
|
|
_saveSettingsTimer.callOnce(delay);
|
2017-04-09 18:06:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-18 18:04:16 +00:00
|
|
|
void Session::saveSettingsNowIfNeeded() {
|
|
|
|
if (_saveSettingsTimer.isActive()) {
|
|
|
|
_saveSettingsTimer.cancel();
|
|
|
|
saveSettings();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 16:09:46 +00:00
|
|
|
MTP::DcId Session::mainDcId() const {
|
2020-06-17 09:36:25 +00:00
|
|
|
return _account->mtp().mainDcId();
|
2020-06-11 16:09:46 +00:00
|
|
|
}
|
|
|
|
|
2020-06-17 09:36:25 +00:00
|
|
|
MTP::Instance &Session::mtp() const {
|
2019-07-24 08:46:23 +00:00
|
|
|
return _account->mtp();
|
|
|
|
}
|
|
|
|
|
2020-06-17 09:36:25 +00:00
|
|
|
const MTP::ConfigFields &Session::serverConfig() const {
|
|
|
|
return _account->mtp().configValues();
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
void Session::termsDeleteNow() {
|
2019-03-27 08:37:25 +00:00
|
|
|
api().request(MTPaccount_DeleteAccount(
|
|
|
|
MTP_string("Decline ToS update")
|
|
|
|
)).send();
|
|
|
|
}
|
|
|
|
|
2020-06-17 09:36:25 +00:00
|
|
|
QString Session::createInternalLink(const QString &query) const {
|
|
|
|
auto result = createInternalLinkFull(query);
|
|
|
|
auto prefixes = {
|
|
|
|
qstr("https://"),
|
|
|
|
qstr("http://"),
|
|
|
|
};
|
|
|
|
for (auto &prefix : prefixes) {
|
|
|
|
if (result.startsWith(prefix, Qt::CaseInsensitive)) {
|
|
|
|
return result.mid(prefix.size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
LOG(("Warning: bad internal url '%1'").arg(result));
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Session::createInternalLinkFull(const QString &query) const {
|
|
|
|
return ValidatedInternalLinksDomain(this) + query;
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
bool Session::supportMode() const {
|
2018-11-15 15:36:04 +00:00
|
|
|
return (_supportHelper != nullptr);
|
2018-10-02 20:39:54 +00:00
|
|
|
}
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
Support::Helper &Session::supportHelper() const {
|
2018-10-02 20:39:54 +00:00
|
|
|
Expects(supportMode());
|
|
|
|
|
2018-11-15 15:36:04 +00:00
|
|
|
return *_supportHelper;
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
Support::Templates& Session::supportTemplates() const {
|
2018-11-15 15:36:04 +00:00
|
|
|
return supportHelper().templates();
|
2018-09-28 11:56:21 +00:00
|
|
|
}
|
2019-07-24 11:45:24 +00:00
|
|
|
|
2020-06-11 09:41:03 +00:00
|
|
|
void Session::addWindow(not_null<Window::SessionController*> controller) {
|
|
|
|
_windows.emplace(controller);
|
|
|
|
controller->lifetime().add([=] {
|
|
|
|
_windows.remove(controller);
|
|
|
|
});
|
|
|
|
updates().addActiveChat(controller->activeChatChanges(
|
|
|
|
) | rpl::map([=](const Dialogs::Key &chat) {
|
|
|
|
return chat.peer();
|
|
|
|
}) | rpl::distinct_until_changed());
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Session::windows() const
|
|
|
|
-> const base::flat_set<not_null<Window::SessionController*>> & {
|
|
|
|
return _windows;
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:45:24 +00:00
|
|
|
} // namespace Main
|