Skip to content

Commit

Permalink
Improve export progress / finished design.
Browse files Browse the repository at this point in the history
  • Loading branch information
john-preston committed Jun 20, 2018
1 parent 329db0d commit e8dd277
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 41 deletions.
8 changes: 8 additions & 0 deletions Telegram/Resources/langs/lang.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1687,6 +1687,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_export_state_video_message" = "Round video message";
"lng_export_state_sticker" = "Sticker";
"lng_export_state_gif" = "Animated GIF";
"lng_export_progress" = "Note: Please don't close Telegram while exporting files and personal data.";
"lng_export_stop" = "Stop";
"lng_export_sure_stop" = "Are you sure you want to stop exporting your data?\n\nThis action cannot be undone.";
"lng_export_about_done" = "Your data is successfully exported.";
"lng_export_done" = "Show my data";
"lng_export_finished" = "Export is finished.";
"lng_export_total_files" = "Total files: {count}";
"lng_export_total_size" = "Total size: {size}";

// Wnd specific

Expand Down
7 changes: 2 additions & 5 deletions Telegram/SourceFiles/export/export_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ struct PasswordCheckState {
bool requesting = true;
bool hasPassword = false;
bool checked = false;

};

struct ProcessingState {
Expand Down Expand Up @@ -65,22 +64,20 @@ struct ProcessingState {
QString bytesName;
int bytesLoaded = 0;
int bytesCount = 0;

};

struct ApiErrorState {
RPCError data;

};

struct OutputErrorState {
QString path;

};

struct FinishedState {
QString path;

int filesCount = 0;
int64 bytesCount = 0;
};

using State = base::optional_variant<
Expand Down
2 changes: 1 addition & 1 deletion Telegram/SourceFiles/export/output/export_output_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ QString TextWriter::mainFilePath() {
}

QString TextWriter::mainFileRelativePath() const {
return "result.txt";
return "overview.txt";
}

QString TextWriter::pathWithRelativePath(const QString &path) const {
Expand Down
20 changes: 20 additions & 0 deletions Telegram/SourceFiles/export/view/export.style
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,31 @@ exportProgressLabel: FlatLabel(boxLabel) {
exportProgressInfoLabel: FlatLabel(boxLabel) {
textFg: windowSubTextFg;
maxHeight: 20px;
style: boxTextStyle;
}
exportProgressWidth: 3px;
exportProgressFg: mediaPlayerActiveFg;
exportProgressBg: mediaPlayerInactiveFg;

exportCancelButton: RoundButton(attentionBoxButton) {
width: 200px;
height: 44px;
textTop: 12px;
font: font(semibold 15px);
}
exportCancelBottom: 30px;
exportDoneButton: RoundButton(defaultActiveButton) {
width: 200px;
height: 44px;
textTop: 12px;
font: font(semibold 15px);
}

exportAboutLabel: FlatLabel(boxLabel) {
textFg: windowSubTextFg;
}
exportAboutPadding: margins(22px, 10px, 22px, 0px);

exportTopBarLabel: FlatLabel(defaultFlatLabel) {
maxHeight: 20px;
palette: TextPalette(defaultTextPalette) {
Expand Down
25 changes: 25 additions & 0 deletions Telegram/SourceFiles/export/view/export_view_content.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ For license and copyright information please follow this link:
namespace Export {
namespace View {

const QString Content::kDoneId = "done";

Content ContentFromState(const ProcessingState &state) {
using Step = ProcessingState::Step;

Expand Down Expand Up @@ -101,6 +103,29 @@ Content ContentFromState(const ProcessingState &state) {
break;
default: Unexpected("Step in ContentFromState.");
}
while (result.rows.size() < 3) {
result.rows.push_back(Content::Row());
}
return result;
}

Content ContentFromState(const FinishedState &state) {
auto result = Content();
result.rows.push_back({
Content::kDoneId,
lang(lng_export_finished),
QString(),
1. });
result.rows.push_back({
Content::kDoneId,
lng_export_total_files(lt_count, QString::number(state.filesCount)),
QString(),
1. });
result.rows.push_back({
Content::kDoneId,
lng_export_total_size(lt_size, formatSizeText(state.bytesCount)),
QString(),
1. });
return result;
}

Expand Down
7 changes: 6 additions & 1 deletion Telegram/SourceFiles/export/view/export_view_content.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ struct Content {

std::vector<Row> rows;

static const QString kDoneId;

};

Content ContentFromState(const ProcessingState &state);
Content ContentFromState(const FinishedState &state);

inline auto ContentFromState(rpl::producer<State> state) {
return std::move(
Expand All @@ -34,8 +37,10 @@ inline auto ContentFromState(rpl::producer<State> state) {
}) | rpl::map([](const State &state) {
if (const auto process = base::get_if<ProcessingState>(&state)) {
return ContentFromState(*process);
} else if (const auto done = base::get_if<FinishedState>(&state)) {
return ContentFromState(*done);
}
return Content();
Unexpected("State type in ContentFromState.");
});
}

Expand Down
35 changes: 32 additions & 3 deletions Telegram/SourceFiles/export/view/export_view_panel_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ For license and copyright information please follow this link:
#include "ui/widgets/labels.h"
#include "ui/widgets/separate_panel.h"
#include "ui/wrap/padding_wrap.h"
#include "boxes/confirm_box.h"
#include "lang/lang_keys.h"
#include "core/file_utilities.h"
#include "styles/style_export.h"
#include "styles/style_boxes.h"

namespace Export {
namespace View {
Expand Down Expand Up @@ -102,13 +104,39 @@ void PanelController::showProgress() {

progress->cancelClicks(
) | rpl::start_with_next([=] {
_panel->hideGetDuration();
stopWithConfirmation();
}, progress->lifetime());

progress->doneClicks(
) | rpl::start_with_next([=] {
if (const auto finished = base::get_if<FinishedState>(&_state)) {
File::ShowInFolder(finished->path);
_panel->hideGetDuration();
}
}, progress->lifetime());

_panel->showInner(std::move(progress));
_panel->setHideOnDeactivate(true);
}

void PanelController::stopWithConfirmation() {
auto box = Box<ConfirmBox>(
lang(lng_export_sure_stop),
lang(lng_export_stop),
st::attentionBoxButton,
[=] { stopExport(); });
_panel->showBox(
std::move(box),
LayerOption::KeepOther,
anim::type::normal);
}

void PanelController::stopExport() {
_stopRequested = true;
_panel->showAndActivate();
_panel->hideGetDuration();
}

void PanelController::showDone(const QString &path) {
_panel->setTitle(Lang::Viewer(lng_export_title));

Expand All @@ -133,7 +161,7 @@ rpl::producer<> PanelController::closed() const {
return _panelCloseEvents.events(
) | rpl::flatten_latest(
) | rpl::filter([=] {
return !_state.is<ProcessingState>();
return !_state.is<ProcessingState>() || _stopRequested;
});
}

Expand All @@ -147,7 +175,8 @@ void PanelController::updateState(State &&state) {
} else if (const auto error = base::get_if<OutputErrorState>(&_state)) {
showError(*error);
} else if (const auto finished = base::get_if<FinishedState>(&_state)) {
showDone(finished->path);
_panel->setHideOnDeactivate(false);
// showDone(finished->path);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class PanelController {
PanelController(not_null<ControllerWrap*> process);

void activatePanel();
void stopWithConfirmation();

rpl::producer<> closed() const;

Expand All @@ -39,6 +40,7 @@ class PanelController {
~PanelController();

private:
void stopExport();
void createPanel();
void updateState(State &&state);
void showSettings();
Expand All @@ -54,6 +56,7 @@ class PanelController {

State _state;
rpl::event_stream<rpl::producer<>> _panelCloseEvents;
bool _stopRequested = false;
rpl::lifetime _lifetime;

};
Expand Down
70 changes: 42 additions & 28 deletions Telegram/SourceFiles/export/view/export_view_progress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,61 +237,64 @@ ProgressWidget::ProgressWidget(
rpl::producer<Content> content)
: RpWidget(parent)
, _body(this) {
initFooter();

widthValue(
) | rpl::start_with_next([=](int width) {
_body->resizeToWidth(width);
_body->moveToLeft(0, 0);
}, _body->lifetime());

_about = _body->add(
object_ptr<Ui::FlatLabel>(
this,
lang(lng_export_progress),
Ui::FlatLabel::InitType::Simple,
st::exportAboutLabel),
st::exportAboutPadding);

std::move(
content
) | rpl::start_with_next([=](Content &&content) {
updateState(std::move(content));
}, lifetime());

_cancel = base::make_unique_q<Ui::RoundButton>(
this,
langFactory(lng_export_stop),
st::exportCancelButton);
setupBottomButton(_cancel.get());
}

rpl::producer<> ProgressWidget::cancelClicks() const {
return _cancel->clicks();
return _cancel ? _cancel->clicks() : rpl::never<>();
}

void ProgressWidget::initFooter() {
const auto buttonsPadding = st::boxButtonPadding;
const auto buttonsHeight = buttonsPadding.top()
+ st::defaultBoxButton.height
+ buttonsPadding.bottom();
const auto buttons = Ui::CreateChild<Ui::FixedHeightWidget>(
this,
buttonsHeight);
rpl::producer<> ProgressWidget::doneClicks() const {
return _doneClicks.events();
}

void ProgressWidget::setupBottomButton(not_null<Ui::RoundButton*> button) {
button->show();

sizeValue(
) | rpl::start_with_next([=](QSize size) {
buttons->resizeToWidth(size.width());
buttons->moveToLeft(0, size.height() - buttons->height());
}, lifetime());

_cancel = Ui::CreateChild<Ui::RoundButton>(
buttons,
langFactory(lng_cancel),
st::defaultBoxButton);
_cancel->show();

buttons->widthValue(
) | rpl::start_with_next([=] {
const auto right = st::boxButtonPadding.right();
const auto top = st::boxButtonPadding.top();
_cancel->moveToRight(right, top);
}, _cancel->lifetime());
button->move(
(size.width() - button->width()) / 2,
(size.height() - st::exportCancelBottom - button->height()));
}, button->lifetime());
}

void ProgressWidget::updateState(Content &&content) {
if (!content.rows.empty() && content.rows[0].id == Content::kDoneId) {
showDone();
}

auto index = 0;
for (auto &row : content.rows) {
if (index < _rows.size()) {
_rows[index]->updateData(std::move(row));
} else {
_rows.push_back(_body->add(
_rows.push_back(_body->insert(
index,
object_ptr<Row>(this, std::move(row)),
st::exportProgressRowPadding));
}
Expand All @@ -302,6 +305,17 @@ void ProgressWidget::updateState(Content &&content) {
}
}

void ProgressWidget::showDone() {
_cancel = nullptr;
_about->setText(lang(lng_export_about_done));
_done = base::make_unique_q<Ui::RoundButton>(
this,
langFactory(lng_export_done),
st::exportDoneButton);
_done->clicks() | rpl::start_to_stream(_doneClicks, _done->lifetime());
setupBottomButton(_done.get());
}

ProgressWidget::~ProgressWidget() = default;

} // namespace View
Expand Down
10 changes: 8 additions & 2 deletions Telegram/SourceFiles/export/view/export_view_progress.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ For license and copyright information please follow this link:
namespace Ui {
class VerticalLayout;
class RoundButton;
class FlatLabel;
} // namespace Ui

namespace Export {
Expand All @@ -25,20 +26,25 @@ class ProgressWidget : public Ui::RpWidget {
rpl::producer<Content> content);

rpl::producer<> cancelClicks() const;
rpl::producer<> doneClicks() const;

~ProgressWidget();

private:
void initFooter();
void setupBottomButton(not_null<Ui::RoundButton*> button);
void updateState(Content &&content);
void showDone();

Content _content;

class Row;
object_ptr<Ui::VerticalLayout> _body;
std::vector<not_null<Row*>> _rows;

QPointer<Ui::RoundButton> _cancel;
QPointer<Ui::FlatLabel> _about;
base::unique_qptr<Ui::RoundButton> _cancel;
base::unique_qptr<Ui::RoundButton> _done;
rpl::event_stream<> _doneClicks;

};

Expand Down
Loading

0 comments on commit e8dd277

Please sign in to comment.