Allow returning from new account setup.

This commit is contained in:
John Preston 2020-06-23 18:55:08 +04:00
parent c92c15883d
commit 55ec4ebf86
13 changed files with 146 additions and 61 deletions

View file

@ -259,7 +259,7 @@ void CodeWidget::codeSubmitDone(const MTPauth_Authorization &result) {
} else {
getData()->termsLock = Window::TermsLock();
}
goReplace<SignupWidget>();
goReplace<SignupWidget>(Animate::Forward);
});
}
@ -358,7 +358,7 @@ void CodeWidget::gotPassword(const MTPaccount_Password &result) {
getData()->hasRecovery = d.is_has_recovery();
getData()->pwdHint = qs(d.vhint().value_or_empty());
getData()->pwdNotEmptyPassport = d.is_has_secure_values();
goReplace<PasswordCheckWidget>();
goReplace<PasswordCheckWidget>(Animate::Forward);
}
void CodeWidget::submit() {

View file

@ -94,7 +94,9 @@ void PhoneWidget::setupQrLogin() {
contentTop() + st::introQrLoginLinkTop);
}, qrLogin->lifetime());
qrLogin->setClickedCallback([=] { goReplace<QrWidget>(); });
qrLogin->setClickedCallback([=] {
goReplace<QrWidget>(Animate::Forward);
});
}, lifetime());
}

View file

@ -218,7 +218,7 @@ void QrWidget::checkForTokenUpdate(const MTPUpdate &update) {
}
void QrWidget::submit() {
goReplace<PhoneWidget>();
goReplace<PhoneWidget>(Animate::Forward);
}
rpl::producer<QString> QrWidget::nextButtonText() const {
@ -389,7 +389,7 @@ void QrWidget::sendCheckPasswordRequest() {
data);
if (!data.vcurrent_algo() || !data.vsrp_id() || !data.vsrp_B()) {
LOG(("API Error: No current password received on login."));
goReplace<QrWidget>();
goReplace<QrWidget>(Animate::Forward);
return;
} else if (!getData()->pwdRequest) {
const auto box = std::make_shared<QPointer<Ui::BoxContent>>();
@ -406,7 +406,7 @@ void QrWidget::sendCheckPasswordRequest() {
getData()->hasRecovery = data.is_has_recovery();
getData()->pwdHint = qs(data.vhint().value_or_empty());
getData()->pwdNotEmptyPassport = data.is_has_secure_values();
goReplace<PasswordCheckWidget>();
goReplace<PasswordCheckWidget>(Animate::Forward);
});
}).fail([=](const RPCError &error) {
showTokenError(error);

View file

@ -118,19 +118,19 @@ rpl::producer<QString> Step::nextButtonText() const {
void Step::goBack() {
if (_goCallback) {
_goCallback(nullptr, Direction::Back);
_goCallback(nullptr, StackAction::Back, Animate::Back);
}
}
void Step::goNext(Step *step) {
if (_goCallback) {
_goCallback(step, Direction::Forward);
_goCallback(step, StackAction::Forward, Animate::Forward);
}
}
void Step::goReplace(Step *step) {
void Step::goReplace(Step *step, Animate animate) {
if (_goCallback) {
_goCallback(step, Direction::Replace);
_goCallback(step, StackAction::Replace, animate);
}
}
@ -455,12 +455,12 @@ QPixmap Step::prepareSlideAnimation() {
QRect(grabLeft, grabTop, st::introStepWidth, st::introStepHeight));
}
void Step::showAnimated(Direction direction) {
void Step::showAnimated(Animate animate) {
setFocus();
show();
hideChildren();
if (_slideAnimation) {
auto slideLeft = (direction == Direction::Back);
auto slideLeft = (animate == Animate::Back);
_slideAnimation->start(
slideLeft,
[=] { update(0, contentTop(), width(), st::introStepHeight); },
@ -474,7 +474,8 @@ void Step::setShowAnimationClipping(QRect clipping) {
_coverAnimation.clipping = clipping;
}
void Step::setGoCallback(Fn<void(Step *step, Direction direction)> callback) {
void Step::setGoCallback(
Fn<void(Step *step, StackAction action, Animate animate)> callback) {
_goCallback = std::move(callback);
}

View file

@ -28,7 +28,8 @@ namespace Intro {
namespace details {
struct Data;
enum class Direction;
enum class StackAction;
enum class Animate;
class Step : public Ui::RpWidget, protected base::Subscriber {
public:
@ -55,7 +56,7 @@ public:
}
void setGoCallback(
Fn<void(Step *step, Direction direction)> callback);
Fn<void(Step *step, StackAction action, Animate animate)> callback);
void setShowResetCallback(Fn<void()> callback);
void setShowTermsCallback(
Fn<void()> callback);
@ -63,7 +64,7 @@ public:
Fn<void(Fn<void()> callback)> callback);
void prepareShowAnimated(Step *after);
void showAnimated(Direction direction);
void showAnimated(Animate animate);
void showFast();
[[nodiscard]] bool animating() const;
void setShowAnimationClipping(QRect clipping);
@ -114,8 +115,8 @@ protected:
}
template <typename StepType>
void goReplace() {
goReplace(new StepType(parentWidget(), _account, _data));
void goReplace(Animate animate) {
goReplace(new StepType(parentWidget(), _account, _data), animate);
}
void showResetButton() {
@ -157,7 +158,7 @@ private:
void refreshError(const QString &text);
void goNext(Step *step);
void goReplace(Step *step);
void goReplace(Step *step, Animate animate);
[[nodiscard]] CoverAnimation prepareCoverAnimation(Step *step);
[[nodiscard]] QPixmap prepareContentSnapshot();
@ -172,7 +173,7 @@ private:
mutable std::optional<MTP::Sender> _api;
bool _hasCover = false;
Fn<void(Step *step, Direction direction)> _goCallback;
Fn<void(Step *step, StackAction action, Animate animate)> _goCallback;
Fn<void()> _showResetCallback;
Fn<void()> _showTermsCallback;
Fn<void(Fn<void()> callback)> _acceptTermsCallback;

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "intro/intro_start.h"
#include "intro/intro_phone.h"
#include "intro/intro_qr.h"
#include "intro/intro_code.h"
#include "intro/intro_signup.h"
#include "intro/intro_password_check.h"
@ -16,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_cloud_manager.h"
#include "storage/localstorage.h"
#include "main/main_account.h"
#include "main/main_domain.h"
#include "mainwindow.h"
#include "boxes/confirm_box.h"
#include "ui/text/text_utilities.h"
@ -40,7 +42,10 @@ using namespace ::Intro::details;
} // namespace
Widget::Widget(QWidget *parent, not_null<Main::Account*> account)
Widget::Widget(
QWidget *parent,
not_null<Main::Account*> account,
EnterPoint point)
: RpWidget(parent)
, _account(account)
, _back(this, object_ptr<Ui::IconButton>(this, st::introBackButton))
@ -57,7 +62,19 @@ Widget::Widget(QWidget *parent, not_null<Main::Account*> account)
this,
account,
rpl::single(true))) {
appendStep(new StartWidget(this, _account, getData()));
switch (point) {
case EnterPoint::Start:
appendStep(new StartWidget(this, _account, getData()));
break;
case EnterPoint::Phone:
appendStep(new PhoneWidget(this, _account, getData()));
break;
case EnterPoint::Qr:
appendStep(new QrWidget(this, _account, getData()));
break;
default: Unexpected("Enter point in Intro::Widget::Widget.");
}
fixOrder();
getData()->country = Platform::SystemCountry();
@ -77,9 +94,7 @@ Widget::Widget(QWidget *parent, not_null<Main::Account*> account)
handleUpdates(updates);
}, lifetime());
_back->entity()->setClickedCallback([=] {
historyMove(Direction::Back);
});
_back->entity()->setClickedCallback([=] { backRequested(); });
_back->hide(anim::type::instant);
_next->entity()->setClickedCallback([=] { getStep()->submit(); });
@ -227,18 +242,18 @@ void Widget::setInnerFocus() {
}
}
void Widget::historyMove(Direction direction) {
void Widget::historyMove(StackAction action, Animate animate) {
Expects(_stepHistory.size() > 1);
if (getStep()->animating()) {
return;
}
auto wasStep = getStep((direction == Direction::Back) ? 0 : 1);
if (direction == Direction::Back) {
auto wasStep = getStep((action == StackAction::Back) ? 0 : 1);
if (action == StackAction::Back) {
_stepHistory.pop_back();
wasStep->cancelled();
} else if (direction == Direction::Replace) {
} else if (action == StackAction::Replace) {
_stepHistory.erase(_stepHistory.end() - 2);
}
@ -258,10 +273,10 @@ void Widget::historyMove(Direction direction) {
}
_stepLifetime.destroy();
if (direction == Direction::Forward || direction == Direction::Replace) {
if (action == StackAction::Forward || action == StackAction::Replace) {
wasStep->finished();
}
if (direction == Direction::Back || direction == Direction::Replace) {
if (action == StackAction::Back || action == StackAction::Replace) {
delete base::take(wasStep);
}
_back->toggle(getStep()->hasBack(), anim::type::normal);
@ -274,7 +289,7 @@ void Widget::historyMove(Direction direction) {
setupNextButton();
if (_resetAccount) _resetAccount->show(anim::type::normal);
if (_terms) _terms->show(anim::type::normal);
getStep()->showAnimated(direction);
getStep()->showAnimated(animate);
fixOrder();
}
@ -298,7 +313,7 @@ void Widget::fixOrder() {
_connecting->raise();
}
void Widget::moveToStep(Step *step, Direction direction) {
void Widget::moveToStep(Step *step, StackAction action, Animate animate) {
appendStep(step);
_back->raise();
_settings->raise();
@ -307,17 +322,17 @@ void Widget::moveToStep(Step *step, Direction direction) {
}
_connecting->raise();
historyMove(direction);
historyMove(action, animate);
}
void Widget::appendStep(Step *step) {
_stepHistory.push_back(step);
step->setGeometry(rect());
step->setGoCallback([=](Step *step, Direction direction) {
if (direction == Direction::Back) {
historyMove(direction);
step->setGoCallback([=](Step *step, StackAction action, Animate animate) {
if (action == StackAction::Back) {
historyMove(action, animate);
} else {
moveToStep(step, direction);
moveToStep(step, action, animate);
}
});
step->setShowResetCallback([=] {
@ -399,7 +414,8 @@ void Widget::resetAccount() {
Ui::hideLayer();
moveToStep(
new SignupWidget(this, _account, getData()),
Direction::Replace);
StackAction::Replace,
Animate::Forward);
}).fail([=](const RPCError &error) {
_resetRequest = 0;
@ -689,7 +705,7 @@ void Widget::keyPressEvent(QKeyEvent *e) {
if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Back) {
if (getStep()->hasBack()) {
historyMove(Direction::Back);
backRequested();
}
} else if (e->key() == Qt::Key_Enter
|| e->key() == Qt::Key_Return
@ -698,6 +714,20 @@ void Widget::keyPressEvent(QKeyEvent *e) {
}
}
void Widget::backRequested() {
if (_stepHistory.size() > 1) {
historyMove(StackAction::Back, Animate::Back);
} else if (const auto parent
= Core::App().domain().maybeLastOrSomeAuthedAccount()) {
Core::App().domain().activate(parent);
} else {
moveToStep(
new StartWidget(this, _account, getData()),
StackAction::Replace,
Animate::Back);
}
}
Widget::~Widget() {
for (auto step : base::take(_stepHistory)) {
delete step;

View file

@ -62,19 +62,33 @@ struct Data {
};
enum class Direction {
enum class StackAction {
Back,
Forward,
Replace,
};
enum class Animate {
Back,
Forward,
};
class Step;
} // namespace details
enum class EnterPoint : uchar {
Start,
Phone,
Qr,
};
class Widget : public Ui::RpWidget, private base::Subscriber {
public:
Widget(QWidget *parent, not_null<Main::Account*> account);
Widget(
QWidget *parent,
not_null<Main::Account*> account,
EnterPoint point);
void showAnimated(const QPixmap &bgAnimCache, bool back = false);
@ -95,6 +109,7 @@ private:
void setupNextButton();
void handleUpdates(const MTPUpdates &updates);
void handleUpdate(const MTPUpdate &update);
void backRequested();
void updateControlsGeometry();
[[nodiscard]] not_null<details::Data*> getData() {
@ -118,8 +133,11 @@ private:
return _stepHistory[_stepHistory.size() - skip - 1];
}
void historyMove(details::Direction direction);
void moveToStep(details::Step *step, details::Direction direction);
void historyMove(details::StackAction action, details::Animate animate);
void moveToStep(
details::Step *step,
details::StackAction action,
details::Animate animate);
void appendStep(details::Step *step);
void getNearestDC();

View file

@ -103,6 +103,20 @@ rpl::producer<> Domain::accountsChanges() const {
return _accountsChanges.events();
}
Account *Domain::maybeLastOrSomeAuthedAccount() {
auto result = (Account*)nullptr;
for (const auto &[index, account] : _accounts) {
if (!account->sessionExists()) {
continue;
} else if (index == _lastActiveIndex) {
return account.get();
} else if (!result) {
result = account.get();
}
}
return result;
}
rpl::producer<Account*> Domain::activeValue() const {
return _active.value();
}
@ -114,6 +128,8 @@ Account &Domain::active() const {
return *_active.current();
}
rpl::producer<not_null<Account*>> Domain::activeChanges() const {
return _active.changes() | rpl::map([](Account *value) {
return not_null{ value };
@ -316,6 +332,9 @@ void Domain::activate(not_null<Main::Account*> account) {
const auto changed = (_accountToActivate != i->index);
_activeLifetime.destroy();
if (_active.current()) {
_lastActiveIndex = _accountToActivate;
}
_accountToActivate = i->index;
_active = account.get();
_active.current()->sessionValue(

View file

@ -48,6 +48,7 @@ public:
-> const std::vector<AccountWithIndex> &;
[[nodiscard]] rpl::producer<Account*> activeValue() const;
[[nodiscard]] rpl::producer<> accountsChanges() const;
[[nodiscard]] Account *maybeLastOrSomeAuthedAccount();
// Expects(started());
[[nodiscard]] Account &active() const;
@ -87,6 +88,7 @@ private:
rpl::event_stream<> _accountsChanges;
rpl::variable<Account*> _active = nullptr;
int _accountToActivate = -1;
int _lastActiveIndex = -1;
bool _writeAccountsScheduled = false;
rpl::event_stream<Session*> _activeSessions;

View file

@ -257,12 +257,12 @@ void MainWindow::clearPasscodeLock() {
}
}
void MainWindow::setupIntro() {
void MainWindow::setupIntro(Intro::EnterPoint point) {
auto animated = (_main || _passcodeLock);
auto bg = animated ? grabInner() : QPixmap();
clearWidgets();
_intro.create(bodyWidget(), &account());
_intro.create(bodyWidget(), &account(), point);
if (_passcodeLock) {
_intro->hide();
} else {

View file

@ -17,6 +17,7 @@ class MainWidget;
namespace Intro {
class Widget;
enum class EnterPoint : uchar;
} // namespace Intro
namespace Local {
@ -53,7 +54,7 @@ public:
void setupPasscodeLock();
void clearPasscodeLock();
void setupIntro();
void setupIntro(Intro::EnterPoint point);
void setupMain();
MainWidget *sessionContent() const;

View file

@ -12,6 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_domain.h"
#include "main/main_session.h"
#include "main/main_session_settings.h"
#include "main/main_app_config.h"
#include "intro/intro_widget.h"
#include "mtproto/mtproto_config.h"
#include "ui/layers/box_content.h"
#include "ui/layers/layer_widget.h"
@ -100,7 +102,17 @@ void Controller::clearPasscodeLock() {
}
void Controller::setupIntro() {
_widget.setupIntro();
const auto parent = Core::App().domain().maybeLastOrSomeAuthedAccount();
if (!parent) {
_widget.setupIntro(Intro::EnterPoint::Start);
return;
}
const auto qrLogin = parent->appConfig().get<QString>(
"qr_login_code",
"[not-set]");
DEBUG_LOG(("qr_login_code in setup: %1").arg(qrLogin));
const auto qr = (qrLogin == "primary");
_widget.setupIntro(qr ? Intro::EnterPoint::Qr : Intro::EnterPoint::Phone);
}
void Controller::setupMain() {

View file

@ -115,7 +115,7 @@ private:
class MainMenu::ToggleAccountsButton final : public Ui::AbstractButton {
public:
ToggleAccountsButton(QWidget *parent, rpl::producer<bool> toggled);
explicit ToggleAccountsButton(QWidget *parent);
[[nodiscard]] int rightSkip() const {
return _rightSkip.current();
@ -274,9 +274,7 @@ void MainMenu::AccountButton::paintEvent(QPaintEvent *e) {
available);
}
MainMenu::ToggleAccountsButton::ToggleAccountsButton(
QWidget *parent,
rpl::producer<bool> toggled)
MainMenu::ToggleAccountsButton::ToggleAccountsButton(QWidget *parent)
: AbstractButton(parent) {
rpl::single(
rpl::empty_value()
@ -290,8 +288,12 @@ MainMenu::ToggleAccountsButton::ToggleAccountsButton(
}
}, lifetime());
std::move(
toggled
auto &settings = Core::App().settings();
if (Core::App().domain().accounts().size() < 2
&& settings.mainMenuAccountsShown()) {
settings.setMainMenuAccountsShown(false);
}
settings.mainMenuAccountsShownValue(
) | rpl::filter([=](bool value) {
return (_toggled != value);
}) | rpl::start_with_next([=](bool value) {
@ -481,7 +483,7 @@ MainMenu::MainMenu(
_controller->session().user(),
Ui::UserpicButton::Role::Custom,
st::mainMenuUserpic)
, _toggleAccounts(this, Core::App().settings().mainMenuAccountsShownValue())
, _toggleAccounts(this)
, _archiveButton(this, st::mainMenuCloudButton)
, _scroll(this, st::defaultSolidScroll)
, _inner(_scroll->setOwnedWidget(
@ -506,8 +508,8 @@ MainMenu::MainMenu(
setupArchiveButton();
setupUserpicButton();
setupAccounts();
setupAccountsToggle();
setupAccounts();
_nightThemeSwitch.setCallback([this] {
if (const auto action = *_nightThemeAction) {
@ -671,6 +673,7 @@ void MainMenu::setupAccounts() {
rebuildAccounts();
}, lifetime());
_accounts->toggleOn(Core::App().settings().mainMenuAccountsShownValue());
_accounts->toggleOn(Core::App().settings().mainMenuAccountsShownValue());
_accounts->finishAnimating();
@ -798,12 +801,8 @@ void MainMenu::setupAccountsToggle() {
auto &settings = Core::App().settings();
const auto shown = !settings.mainMenuAccountsShown();
settings.setMainMenuAccountsShown(shown);
Core::App().saveSettingsDelayed();
});
_toggleAccounts->paintRequest(
) | rpl::start_with_next([=] {
auto p = Painter(_toggleAccounts.data());
}, _toggleAccounts->lifetime());
}
void MainMenu::parentResized() {