mirror of https://github.com/procxx/kepka.git
First working auth by QR code.
This commit is contained in:
parent
95ba12e3cb
commit
d5718f96b8
.gitmodules
Telegram
|
@ -52,3 +52,9 @@
|
|||
[submodule "Telegram/ThirdParty/expected"]
|
||||
path = Telegram/ThirdParty/expected
|
||||
url = https://github.com/TartanLlama/expected
|
||||
[submodule "Telegram/ThirdParty/QR"]
|
||||
path = Telegram/ThirdParty/QR
|
||||
url = https://github.com/nayuki/QR-Code-generator
|
||||
[submodule "Telegram/lib_qr"]
|
||||
path = Telegram/lib_qr
|
||||
url = https://github.com/desktop-app/lib_qr.git
|
||||
|
|
|
@ -178,6 +178,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_photo_caption" = "Caption";
|
||||
"lng_photos_comment" = "Comment";
|
||||
|
||||
"lng_intro_qr_title" = "Scan From Mobile Telegram";
|
||||
"lng_intro_qr_description" = "Please scan this code from your Telegram on iOS or Android.";
|
||||
"lng_intro_qr_skip" = "Log in using phone";
|
||||
|
||||
"lng_phone_title" = "Your Phone Number";
|
||||
"lng_phone_desc" = "Please confirm your country code and\nenter your mobile phone number.";
|
||||
"lng_country_code" = "Country Code";
|
||||
|
|
|
@ -160,3 +160,6 @@ introBackButton: IconButton(defaultIconButton) {
|
|||
}
|
||||
}
|
||||
|
||||
introQrTop: 90px;
|
||||
introQrPixel: 50px; // large enough
|
||||
introQrMaxSize: 170px;
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
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 "intro/intro_qr.h"
|
||||
|
||||
#include "lang/lang_keys.h"
|
||||
#include "intro/introphone.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "main/main_account.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "core/application.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "qr/qr_generate.h"
|
||||
#include "styles/style_intro.h"
|
||||
|
||||
namespace Intro {
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] QImage TelegramLogoImage(int size) {
|
||||
return Core::App().logo().scaled(
|
||||
size,
|
||||
size,
|
||||
Qt::KeepAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
[[nodiscard]] QImage TelegramQrExact(const Qr::Data &data, int pixel) {
|
||||
return Qr::ReplaceCenter(
|
||||
Qr::Generate(data, pixel),
|
||||
TelegramLogoImage(Qr::ReplaceSize(data, pixel)));
|
||||
}
|
||||
|
||||
[[nodiscard]] QImage TelegramQr(const Qr::Data &data, int pixel, int max = 0) {
|
||||
Expects(data.size > 0);
|
||||
|
||||
if (max > 0 && data.size * pixel > max) {
|
||||
pixel = std::max(max / data.size, 1);
|
||||
}
|
||||
return TelegramQrExact(data, pixel * style::DevicePixelRatio());
|
||||
}
|
||||
|
||||
[[nodiscard]] QImage TelegramQr(const QString &text, int pixel, int max) {
|
||||
return TelegramQr(Qr::Encode(text), pixel, max);
|
||||
}
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> PrepareQrWidget(
|
||||
not_null<QWidget*> parent,
|
||||
rpl::producer<QImage> images) {
|
||||
auto result = Ui::CreateChild<Ui::RpWidget>(parent.get());
|
||||
auto current = result->lifetime().make_state<QImage>();
|
||||
std::move(
|
||||
images
|
||||
) | rpl::start_with_next([=](QImage &&image) {
|
||||
result->resize(image.size() / cIntRetinaFactor());
|
||||
*current = std::move(image);
|
||||
result->update();
|
||||
}, result->lifetime());
|
||||
result->paintRequest(
|
||||
) | rpl::filter([=] {
|
||||
return !current->isNull();
|
||||
}) | rpl::start_with_next([=](QRect clip) {
|
||||
QPainter(result).drawImage(
|
||||
QRect(QPoint(), current->size() / cIntRetinaFactor()),
|
||||
*current);
|
||||
}, result->lifetime());
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
QrWidget::QrWidget(
|
||||
QWidget *parent,
|
||||
not_null<Main::Account*> account,
|
||||
not_null<Widget::Data*> data)
|
||||
: Step(parent, account, data)
|
||||
, _code(PrepareQrWidget(this, _qrImages.events()))
|
||||
, _refreshTimer([=] { refreshCode(); }) {
|
||||
setTitleText(tr::lng_intro_qr_title());
|
||||
setDescriptionText(tr::lng_intro_qr_description());
|
||||
setErrorCentered(true);
|
||||
|
||||
account->destroyStaleAuthorizationKeys();
|
||||
account->mtpUpdates(
|
||||
) | rpl::start_with_next([=](const MTPUpdates &updates) {
|
||||
checkForTokenUpdate(updates);
|
||||
}, lifetime());
|
||||
|
||||
_code->widthValue(
|
||||
) | rpl::start_with_next([=] {
|
||||
updateCodeGeometry();
|
||||
}, _code->lifetime());
|
||||
_code->show();
|
||||
|
||||
refreshCode();
|
||||
}
|
||||
|
||||
void QrWidget::resizeEvent(QResizeEvent *e) {
|
||||
Step::resizeEvent(e);
|
||||
updateCodeGeometry();
|
||||
}
|
||||
|
||||
void QrWidget::checkForTokenUpdate(const MTPUpdates &updates) {
|
||||
updates.match([&](const MTPDupdateShort &data) {
|
||||
checkForTokenUpdate(data.vupdate());
|
||||
}, [&](const MTPDupdates &data) {
|
||||
for (const auto &update : data.vupdates().v) {
|
||||
checkForTokenUpdate(update);
|
||||
}
|
||||
}, [&](const MTPDupdatesCombined &data) {
|
||||
for (const auto &update : data.vupdates().v) {
|
||||
checkForTokenUpdate(update);
|
||||
}
|
||||
}, [](const auto &) {});
|
||||
}
|
||||
|
||||
void QrWidget::checkForTokenUpdate(const MTPUpdate &update) {
|
||||
update.match([&](const MTPDupdateLoginToken &data) {
|
||||
if (_requestId) {
|
||||
_forceRefresh = true;
|
||||
} else {
|
||||
_refreshTimer.cancel();
|
||||
refreshCode();
|
||||
}
|
||||
}, [](const auto &) {});
|
||||
}
|
||||
|
||||
void QrWidget::updateCodeGeometry() {
|
||||
_code->moveToLeft(
|
||||
(width() - _code->width()) / 2,
|
||||
contentTop() + st::introQrTop);
|
||||
}
|
||||
|
||||
void QrWidget::submit() {
|
||||
goReplace<PhoneWidget>();
|
||||
}
|
||||
|
||||
rpl::producer<QString> QrWidget::nextButtonText() const {
|
||||
return tr::lng_intro_qr_skip();
|
||||
}
|
||||
|
||||
void QrWidget::refreshCode() {
|
||||
if (_requestId) {
|
||||
return;
|
||||
}
|
||||
_requestId = _api.request(MTPauth_ExportLoginToken(
|
||||
MTP_int(ApiId),
|
||||
MTP_string(ApiHash),
|
||||
MTP_vector<MTPint>(0)
|
||||
)).done([=](const MTPauth_LoginToken &result) {
|
||||
handleTokenResult(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
showTokenError(error);
|
||||
}).send();
|
||||
}
|
||||
|
||||
void QrWidget::handleTokenResult(const MTPauth_LoginToken &result) {
|
||||
result.match([&](const MTPDauth_loginToken &data) {
|
||||
_requestId = 0;
|
||||
showToken(data.vtoken().v);
|
||||
|
||||
if (base::take(_forceRefresh)) {
|
||||
refreshCode();
|
||||
} else {
|
||||
const auto left = data.vexpires().v - base::unixtime::now();
|
||||
_refreshTimer.callOnce(std::max(left, 1) * crl::time(1000));
|
||||
}
|
||||
}, [&](const MTPDauth_loginTokenMigrateTo &data) {
|
||||
importTo(data.vdc_id().v, data.vtoken().v);
|
||||
}, [&](const MTPDauth_loginTokenSuccess &data) {
|
||||
done(data.vauthorization());
|
||||
});
|
||||
}
|
||||
|
||||
void QrWidget::showTokenError(const RPCError &error) {
|
||||
_requestId = 0;
|
||||
if (base::take(_forceRefresh)) {
|
||||
refreshCode();
|
||||
} else {
|
||||
showError(rpl::single(error.type()));
|
||||
}
|
||||
}
|
||||
|
||||
void QrWidget::showToken(const QByteArray &token) {
|
||||
const auto encoded = token.toBase64(QByteArray::Base64UrlEncoding);
|
||||
const auto text = "tg_login/" + encoded;
|
||||
_qrImages.fire(TelegramQr(text, st::introQrPixel, st::introQrMaxSize));
|
||||
}
|
||||
|
||||
void QrWidget::importTo(MTP::DcId dcId, const QByteArray &token) {
|
||||
Expects(_requestId != 0);
|
||||
|
||||
_requestId = _api.request(MTPauth_ImportLoginToken(
|
||||
MTP_bytes(token)
|
||||
)).done([=](const MTPauth_LoginToken &result) {
|
||||
handleTokenResult(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
showTokenError(error);
|
||||
}).toDC(dcId).send();
|
||||
}
|
||||
|
||||
void QrWidget::done(const MTPauth_Authorization &authorization) {
|
||||
authorization.match([&](const MTPDauth_authorization &data) {
|
||||
if (data.vuser().type() != mtpc_user
|
||||
|| !data.vuser().c_user().is_self()) {
|
||||
showError(rpl::single(Lang::Hard::ServerError()));
|
||||
return;
|
||||
}
|
||||
const auto phone = data.vuser().c_user().vphone().value_or_empty();
|
||||
cSetLoggedPhoneNumber(phone);
|
||||
finish(data.vuser());
|
||||
}, [&](const MTPDauth_authorizationSignUpRequired &data) {
|
||||
_requestId = 0;
|
||||
LOG(("API Error: Unexpected auth.authorizationSignUpRequired."));
|
||||
showError(rpl::single(Lang::Hard::ServerError()));
|
||||
});
|
||||
}
|
||||
|
||||
void QrWidget::activate() {
|
||||
Step::activate();
|
||||
_code->show();
|
||||
}
|
||||
|
||||
void QrWidget::finished() {
|
||||
Step::finished();
|
||||
_refreshTimer.cancel();
|
||||
rpcInvalidate();
|
||||
cancelled();
|
||||
}
|
||||
|
||||
void QrWidget::cancelled() {
|
||||
_api.request(base::take(_requestId)).cancel();
|
||||
}
|
||||
|
||||
} // namespace Intro
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
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
|
||||
|
||||
#include "ui/countryinput.h"
|
||||
#include "intro/introwidget.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace Ui {
|
||||
class PhonePartInput;
|
||||
class CountryCodeInput;
|
||||
class RoundButton;
|
||||
class FlatLabel;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Intro {
|
||||
|
||||
class QrWidget : public Widget::Step {
|
||||
public:
|
||||
QrWidget(
|
||||
QWidget *parent,
|
||||
not_null<Main::Account*> account,
|
||||
not_null<Widget::Data*> data);
|
||||
|
||||
void activate() override;
|
||||
void finished() override;
|
||||
void cancelled() override;
|
||||
void submit() override;
|
||||
rpl::producer<QString> nextButtonText() const override;
|
||||
|
||||
bool hasBack() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
||||
private:
|
||||
void refreshCode();
|
||||
void updateCodeGeometry();
|
||||
void checkForTokenUpdate(const MTPUpdates &updates);
|
||||
void checkForTokenUpdate(const MTPUpdate &update);
|
||||
void handleTokenResult(const MTPauth_LoginToken &result);
|
||||
void showTokenError(const RPCError &error);
|
||||
void importTo(MTP::DcId dcId, const QByteArray &token);
|
||||
void showToken(const QByteArray &token);
|
||||
void done(const MTPauth_Authorization &authorization);
|
||||
|
||||
rpl::event_stream<QImage> _qrImages;
|
||||
not_null<Ui::RpWidget*> _code;
|
||||
base::Timer _refreshTimer;
|
||||
MTP::Sender _api;
|
||||
mtpRequestId _requestId = 0;
|
||||
bool _forceRefresh = false;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Intro
|
|
@ -236,7 +236,7 @@ void CodeWidget::codeSubmitDone(const MTPauth_Authorization &result) {
|
|||
result.match([&](const MTPDauth_authorization &data) {
|
||||
if (data.vuser().type() != mtpc_user
|
||||
|| !data.vuser().c_user().is_self()) {
|
||||
showCodeError(rpl::single(Lang::Hard::ServerError()));
|
||||
showError(rpl::single(Lang::Hard::ServerError()));
|
||||
return;
|
||||
}
|
||||
cSetLoggedPhoneNumber(getData()->phone);
|
||||
|
|
|
@ -69,13 +69,6 @@ void PhoneWidget::resizeEvent(QResizeEvent *e) {
|
|||
auto phoneTop = _country->y() + _country->height() + st::introPhoneTop;
|
||||
_code->moveToLeft(contentLeft(), phoneTop);
|
||||
_phone->moveToLeft(contentLeft() + _country->width() - st::introPhone.width, phoneTop);
|
||||
updateSignupGeometry();
|
||||
}
|
||||
|
||||
void PhoneWidget::updateSignupGeometry() {
|
||||
if (_signup) {
|
||||
_signup->moveToLeft(contentLeft() + st::buttonRadius, contentTop() + st::introDescriptionTop);
|
||||
}
|
||||
}
|
||||
|
||||
void PhoneWidget::showPhoneError(rpl::producer<QString> text) {
|
||||
|
@ -85,10 +78,6 @@ void PhoneWidget::showPhoneError(rpl::producer<QString> text) {
|
|||
|
||||
void PhoneWidget::hidePhoneError() {
|
||||
hideError();
|
||||
if (_signup) {
|
||||
_signup->hide(anim::type::instant);
|
||||
showDescription();
|
||||
}
|
||||
}
|
||||
|
||||
void PhoneWidget::countryChanged() {
|
||||
|
|
|
@ -48,7 +48,6 @@ private slots:
|
|||
void onCheckRequest();
|
||||
|
||||
private:
|
||||
void updateSignupGeometry();
|
||||
void countryChanged();
|
||||
|
||||
void phoneSubmitDone(const MTPauth_SentCode &result);
|
||||
|
@ -66,8 +65,6 @@ private:
|
|||
object_ptr<Ui::CountryCodeInput> _code;
|
||||
object_ptr<Ui::PhonePartInput> _phone;
|
||||
|
||||
object_ptr<Ui::FadeWrap<Ui::FlatLabel>> _signup = { nullptr };
|
||||
|
||||
QString _sentPhone;
|
||||
mtpRequestId _sentRequest = 0;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "intro/introstart.h"
|
||||
|
||||
#include "lang/lang_keys.h"
|
||||
#include "intro/introphone.h"
|
||||
#include "intro/intro_qr.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
|
||||
|
@ -26,7 +26,7 @@ StartWidget::StartWidget(
|
|||
}
|
||||
|
||||
void StartWidget::submit() {
|
||||
goNext<PhoneWidget>();
|
||||
goNext<QrWidget>();
|
||||
}
|
||||
|
||||
rpl::producer<QString> StartWidget::nextButtonText() const {
|
||||
|
|
|
@ -120,21 +120,6 @@ void Account::createSession(
|
|||
Expects(_session == nullptr);
|
||||
Expects(_sessionValue.current() == nullptr);
|
||||
|
||||
_mtp->setUpdatesHandler(::rpcDone([](
|
||||
const mtpPrime *from,
|
||||
const mtpPrime *end) {
|
||||
if (const auto main = App::main()) {
|
||||
return main->updateReceived(from, end);
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
_mtp->setGlobalFailHandler(::rpcFail([=](const RPCError &error) {
|
||||
if (sessionExists()) {
|
||||
crl::on_main(&session(), [=] { logOut(); });
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
||||
_session = std::make_unique<Session>(this, user, std::move(settings));
|
||||
_sessionValue = _session.get();
|
||||
|
||||
|
@ -152,7 +137,6 @@ void Account::destroySession() {
|
|||
return;
|
||||
}
|
||||
session().data().clear();
|
||||
_mtp->clearGlobalHandlers();
|
||||
|
||||
_sessionValue = nullptr;
|
||||
_session = nullptr;
|
||||
|
@ -192,6 +176,14 @@ rpl::producer<MTP::Instance*> Account::mtpChanges() const {
|
|||
return _mtpValue.changes();
|
||||
}
|
||||
|
||||
rpl::producer<MTPUpdates> Account::mtpUpdates() const {
|
||||
return _mtpUpdates.events();
|
||||
}
|
||||
|
||||
rpl::producer<> Account::mtpNewSessionCreated() const {
|
||||
return _mtpNewSessionCreated.events();
|
||||
}
|
||||
|
||||
void Account::setMtpMainDcId(MTP::DcId mainDcId) {
|
||||
Expects(!_mtp);
|
||||
|
||||
|
@ -344,6 +336,26 @@ void Account::startMtp() {
|
|||
_mtp->setUserPhone(cLoggedPhoneNumber());
|
||||
_mtpConfig.mainDcId = _mtp->mainDcId();
|
||||
|
||||
_mtp->setUpdatesHandler(::rpcDone([=](
|
||||
const mtpPrime *from,
|
||||
const mtpPrime *end) {
|
||||
auto newSession = MTPNewSession();
|
||||
auto updates = MTPUpdates();
|
||||
if (updates.read(from, end)) {
|
||||
_mtpUpdates.fire(std::move(updates));
|
||||
} else if (newSession.read(from, end)) {
|
||||
_mtpNewSessionCreated.fire({});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
_mtp->setGlobalFailHandler(::rpcFail([=](const RPCError &error) {
|
||||
if (sessionExists()) {
|
||||
crl::on_main(&session(), [=] { logOut(); });
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
_mtp->setStateChangedHandler([](MTP::ShiftedDcId dc, int32 state) {
|
||||
if (dc == MTP::maindc()) {
|
||||
Global::RefConnectionTypeChanged().notify();
|
||||
|
|
|
@ -56,6 +56,8 @@ public:
|
|||
QByteArray &&selfSerialized,
|
||||
int32 selfStreamVersion);
|
||||
[[nodiscard]] Settings *getSessionSettings();
|
||||
[[nodiscard]] rpl::producer<> mtpNewSessionCreated() const;
|
||||
[[nodiscard]] rpl::producer<MTPUpdates> mtpUpdates() const;
|
||||
|
||||
// Serialization.
|
||||
[[nodiscard]] QByteArray serializeMtpAuthorization() const;
|
||||
|
@ -86,6 +88,8 @@ private:
|
|||
std::unique_ptr<MTP::Instance> _mtp;
|
||||
rpl::variable<MTP::Instance*> _mtpValue;
|
||||
std::unique_ptr<MTP::Instance> _mtpForKeysDestroy;
|
||||
rpl::event_stream<MTPUpdates> _mtpUpdates;
|
||||
rpl::event_stream<> _mtpNewSessionCreated;
|
||||
rpl::event_stream<> _configUpdates;
|
||||
|
||||
std::unique_ptr<Session> _session;
|
||||
|
|
|
@ -93,6 +93,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "export/view/export_view_top_bar.h"
|
||||
#include "export/view/export_view_panel_controller.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_account.h"
|
||||
#include "support/support_helper.h"
|
||||
#include "storage/storage_facade.h"
|
||||
#include "storage/storage_shared_media.h"
|
||||
|
@ -430,6 +431,16 @@ MainWidget::MainWidget(
|
|||
[this] { updateControlsGeometry(); },
|
||||
lifetime());
|
||||
|
||||
session().account().mtpUpdates(
|
||||
) | rpl::start_with_next([=](const MTPUpdates &updates) {
|
||||
mtpUpdateReceived(updates);
|
||||
}, lifetime());
|
||||
|
||||
session().account().mtpNewSessionCreated(
|
||||
) | rpl::start_with_next([=] {
|
||||
mtpNewSessionCreated();
|
||||
}, lifetime());
|
||||
|
||||
// MSVC BUG + REGRESSION rpl::mappers::tuple :(
|
||||
using namespace rpl::mappers;
|
||||
_controller->activeChatValue(
|
||||
|
@ -3673,35 +3684,22 @@ void MainWidget::checkIdleFinish() {
|
|||
}
|
||||
}
|
||||
|
||||
bool MainWidget::updateReceived(const mtpPrime *from, const mtpPrime *end) {
|
||||
if (end <= from) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void MainWidget::mtpNewSessionCreated() {
|
||||
session().checkAutoLock();
|
||||
updSeq = 0;
|
||||
MTP_LOG(0, ("getDifference { after new_session_created }%1"
|
||||
).arg(cTestMode() ? " TESTMODE" : ""));
|
||||
getDifference();
|
||||
}
|
||||
|
||||
if (mtpTypeId(*from) == mtpc_new_session_created) {
|
||||
MTPNewSession newSession;
|
||||
if (!newSession.read(from, end)) {
|
||||
return false;
|
||||
}
|
||||
updSeq = 0;
|
||||
MTP_LOG(0, ("getDifference { after new_session_created }%1").arg(cTestMode() ? " TESTMODE" : ""));
|
||||
getDifference();
|
||||
return true;
|
||||
}
|
||||
MTPUpdates updates;
|
||||
if (!updates.read(from, end)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void MainWidget::mtpUpdateReceived(const MTPUpdates &updates) {
|
||||
session().checkAutoLock();
|
||||
_lastUpdateTime = crl::now();
|
||||
_noUpdatesTimer.callOnce(kNoUpdatesTimeout);
|
||||
if (!requestingDifference()
|
||||
|| HasForceLogoutNotification(updates)) {
|
||||
feedUpdates(updates);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
|
||||
|
|
|
@ -133,7 +133,6 @@ public:
|
|||
void incrementSticker(DocumentData *sticker);
|
||||
|
||||
void activate();
|
||||
[[nodiscard]] bool updateReceived(const mtpPrime *from, const mtpPrime *end);
|
||||
|
||||
void refreshDialog(Dialogs::Key key);
|
||||
void removeDialog(Dialogs::Key key);
|
||||
|
@ -394,6 +393,8 @@ private:
|
|||
bool failChannelDifference(ChannelData *channel, const RPCError &err);
|
||||
void failDifferenceStartTimerFor(ChannelData *channel);
|
||||
|
||||
void mtpUpdateReceived(const MTPUpdates &updates);
|
||||
void mtpNewSessionCreated();
|
||||
void feedUpdateVector(
|
||||
const MTPVector<MTPUpdate> &updates,
|
||||
bool skipMessageIds = false);
|
||||
|
|
|
@ -60,7 +60,7 @@ void Downloader::requestedAmountIncrement(MTP::DcId dcId, int index, int amount)
|
|||
using namespace rpl::mappers;
|
||||
|
||||
auto it = _requestedBytesAmount.find(dcId);
|
||||
if (it == _requestedBytesAmount.cend()) {
|
||||
if (it == _requestedBytesAmount.end()) {
|
||||
it = _requestedBytesAmount.emplace(dcId, RequestedInDc { { 0 } }).first;
|
||||
}
|
||||
it->second[index] += amount;
|
||||
|
|
|
@ -79,7 +79,7 @@ private:
|
|||
int _priority = 1;
|
||||
|
||||
using RequestedInDc = std::array<int64, MTP::kDownloadSessionsCount>;
|
||||
std::map<MTP::DcId, RequestedInDc> _requestedBytesAmount;
|
||||
base::flat_map<MTP::DcId, RequestedInDc> _requestedBytesAmount;
|
||||
|
||||
base::flat_map<MTP::DcId, crl::time> _killDownloadSessionTimes;
|
||||
base::Timer _killDownloadSessionsTimer;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 67c62461d380352500fc39557fd9f046b7fe1d18
|
|
@ -75,6 +75,7 @@
|
|||
'<(submodules_loc)/codegen/codegen.gyp:codegen_style',
|
||||
'<(submodules_loc)/lib_base/lib_base.gyp:lib_base',
|
||||
'<(submodules_loc)/lib_ui/lib_ui.gyp:lib_ui',
|
||||
'<(submodules_loc)/lib_qr/lib_qr.gyp:lib_qr',
|
||||
'<(third_party_loc)/libtgvoip/libtgvoip.gyp:libtgvoip',
|
||||
'<(submodules_loc)/lib_lottie/lib_lottie.gyp:lib_lottie',
|
||||
'tests/tests.gyp:tests',
|
||||
|
|
|
@ -444,6 +444,8 @@
|
|||
<(src_loc)/intro/introsignup.h
|
||||
<(src_loc)/intro/introstart.cpp
|
||||
<(src_loc)/intro/introstart.h
|
||||
<(src_loc)/intro/intro_qr.cpp
|
||||
<(src_loc)/intro/intro_qr.h
|
||||
<(src_loc)/lang/lang_cloud_manager.cpp
|
||||
<(src_loc)/lang/lang_cloud_manager.h
|
||||
<(src_loc)/lang/lang_file_parser.cpp
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 6111aa3cef49d481d6450f463cfc4fe482755db7
|
Loading…
Reference in New Issue