Show progress in theme saving.

This commit is contained in:
John Preston 2019-09-08 14:52:42 +03:00
parent a773ad7b02
commit f9b2a8d6ac
4 changed files with 105 additions and 12 deletions

View File

@ -11,15 +11,32 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_profile.h"
#include "storage/localstorage.h"
#include "lang/lang_keys.h"
#include "ui/effects/radial_animation.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/shadow.h"
#include "ui/wrap/fade_wrap.h"
#include "ui/text/text_utilities.h"
#include "base/timer.h"
#include "mainwidget.h"
#include "mainwindow.h"
struct AbstractBox::LoadingProgress {
LoadingProgress(
Fn<void()> &&callback,
const style::InfiniteRadialAnimation &st);
Ui::InfiniteRadialAnimation animation;
base::Timer removeTimer;
};
AbstractBox::LoadingProgress::LoadingProgress(
Fn<void()> &&callback,
const style::InfiniteRadialAnimation &st)
: animation(std::move(callback), st) {
}
void BoxContent::setTitle(rpl::producer<QString> title) {
getDelegate()->setTitle(std::move(title) | Ui::Text::ToWithEntities());
}
@ -279,15 +296,35 @@ int AbstractBox::titleHeight() const {
}
int AbstractBox::buttonsHeight() const {
auto padding = _layerType ? st::boxLayerButtonPadding : st::boxButtonPadding;
const auto padding = _layerType
? st::boxLayerButtonPadding
: st::boxButtonPadding;
return padding.top() + st::defaultBoxButton.height + padding.bottom();
}
int AbstractBox::buttonsTop() const {
auto padding = _layerType ? st::boxLayerButtonPadding : st::boxButtonPadding;
const auto padding = _layerType
? st::boxLayerButtonPadding
: st::boxButtonPadding;
return height() - padding.bottom() - st::defaultBoxButton.height;
}
QRect AbstractBox::loadingRect() const {
const auto padding = _layerType
? st::boxLayerButtonPadding
: st::boxButtonPadding;
const auto size = st::boxLoadingSize;
const auto skipx = _layerType
? st::boxLayerTitlePosition.x()
: st::boxTitlePosition.x();
const auto skipy = (st::defaultBoxButton.height - size) / 2;
return QRect(
skipx,
height() - padding.bottom() - skipy - size,
size,
size);
}
void AbstractBox::paintEvent(QPaintEvent *e) {
Painter p(this);
auto clip = e->rect();
@ -309,6 +346,14 @@ void AbstractBox::paintEvent(QPaintEvent *e) {
&& clip.intersects(QRect(0, 0, width(), titleHeight()))) {
paintAdditionalTitle(p);
}
if (_loadingProgress) {
const auto rect = loadingRect();
_loadingProgress->animation.draw(
p,
rect.topLeft(),
rect.size(),
width());
}
}
void AbstractBox::paintAdditionalTitle(Painter &p) {
@ -441,6 +486,36 @@ QPointer<Ui::IconButton> AbstractBox::addTopButton(const style::IconButton &st,
return result;
}
void AbstractBox::showLoading(bool show) {
const auto &st = st::boxLoadingAnimation;
if (!show) {
if (_loadingProgress && !_loadingProgress->removeTimer.isActive()) {
_loadingProgress->removeTimer.callOnce(
st.sineDuration + st.sinePeriod);
_loadingProgress->animation.stop();
}
return;
}
if (!_loadingProgress) {
const auto callback = [=] {
if (!anim::Disabled()) {
const auto t = st::boxLoadingAnimation.thickness;
update(loadingRect().marginsAdded({ t, t, t, t }));
}
};
_loadingProgress = std::make_unique<LoadingProgress>(
callback,
st::boxLoadingAnimation);
_loadingProgress->removeTimer.setCallback([=] {
_loadingProgress = nullptr;
});
} else {
_loadingProgress->removeTimer.cancel();
}
_loadingProgress->animation.start();
}
void AbstractBox::setDimensions(int newWidth, int maxHeight, bool forceCenterPosition) {
_maxContentHeight = maxHeight;

View File

@ -46,6 +46,7 @@ public:
virtual QPointer<Ui::IconButton> addTopButton(
const style::IconButton &st,
Fn<void()> clickCallback) = 0;
virtual void showLoading(bool show) = 0;
virtual void updateButtonsPositions() = 0;
virtual void showBox(
@ -133,6 +134,9 @@ public:
std::move(clickCallback),
st);
}
void showLoading(bool show) {
getDelegate()->showLoading(show);
}
void updateButtonsGeometry() {
getDelegate()->updateButtonsPositions();
}
@ -294,6 +298,7 @@ public:
QPointer<Ui::IconButton> addTopButton(
const style::IconButton &st,
Fn<void()> clickCallback) override;
void showLoading(bool show) override;
void updateButtonsPositions() override;
QPointer<QWidget> outerContainer() override;
@ -332,17 +337,20 @@ protected:
}
private:
struct LoadingProgress;
void paintAdditionalTitle(Painter &p);
void updateTitlePosition();
void refreshLang();
bool hasTitle() const;
int titleHeight() const;
int buttonsHeight() const;
int buttonsTop() const;
int contentTop() const;
int countFullHeight() const;
int countRealHeight() const;
[[nodiscard]] bool hasTitle() const;
[[nodiscard]] int titleHeight() const;
[[nodiscard]] int buttonsHeight() const;
[[nodiscard]] int buttonsTop() const;
[[nodiscard]] int contentTop() const;
[[nodiscard]] int countFullHeight() const;
[[nodiscard]] int countRealHeight() const;
[[nodiscard]] QRect loadingRect() const;
void updateSize();
not_null<Window::LayerStackWidget*> _layer;
@ -363,6 +371,7 @@ private:
std::vector<object_ptr<Ui::RoundButton>> _buttons;
object_ptr<Ui::RoundButton> _leftButton = { nullptr };
base::unique_qptr<Ui::IconButton> _topButton = { nullptr };
std::unique_ptr<LoadingProgress> _loadingProgress;
};

View File

@ -161,6 +161,12 @@ boxPhotoCompressedSkip: 20px;
boxPhotoCaptionSkip: 8px;
boxPhotoTextFg: windowSubTextFg;
boxLoadingAnimation: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) {
color: windowSubTextFg;
thickness: 2px;
}
boxLoadingSize: 20px;
cropPointSize: 10px;
cropSkip: 13px;
cropMinSize: 20px;

View File

@ -481,8 +481,8 @@ Fn<void()> SavePreparedTheme(
|| (fields.createdBy != session->userId());
const auto finish = [=](const MTPTheme &result) {
done();
Background()->clearEditingTheme(ClearEditing::KeepChanges);
done();
const auto cloud = result.match([&](const MTPDtheme &data) {
const auto result = Data::CloudTheme::Parse(session, data);
@ -807,11 +807,12 @@ void SaveThemeBox(
const auto saving = box->lifetime().make_state<bool>();
const auto cancel = std::make_shared<Fn<void()>>(nullptr);
box->lifetime().add([=] { if (*cancel) (*cancel)(); });
box->addButton(tr::lng_settings_save(), [=] {
const auto save = [=] {
if (*saving) {
return;
}
*saving = true;
box->showLoading(true);
const auto done = crl::guard(box, [=] {
box->closeBox();
window->showRightColumn(nullptr);
@ -820,6 +821,7 @@ void SaveThemeBox(
SaveErrorType type,
const QString &error) {
*saving = false;
box->showLoading(false);
if (error == qstr("THEME_TITLE_INVALID")) {
type = SaveErrorType::Name;
} else if (error == qstr("THEME_SLUG_INVALID")) {
@ -847,7 +849,8 @@ void SaveThemeBox(
fields,
done,
fail);
});
};
box->addButton(tr::lng_settings_save(), save);
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
}