From 4e526476e3d22010375ff090765a1ed2f7be3ead Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 13 Apr 2026 21:02:20 +0300 Subject: [PATCH] Replaced sticker creator box with generic box. --- .../SourceFiles/boxes/sticker_creator_box.cpp | 262 +++++++++--------- .../SourceFiles/boxes/sticker_creator_box.h | 46 +-- 2 files changed, 142 insertions(+), 166 deletions(-) diff --git a/Telegram/SourceFiles/boxes/sticker_creator_box.cpp b/Telegram/SourceFiles/boxes/sticker_creator_box.cpp index 5765a4b330..e0770b5d92 100644 --- a/Telegram/SourceFiles/boxes/sticker_creator_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_creator_box.cpp @@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/layers/layer_widget.h" #include "ui/painter.h" #include "ui/rp_widget.h" +#include "ui/vertical_list.h" #include "ui/widgets/buttons.h" #include "ui/widgets/labels.h" #include "ui/widgets/scroll_area.h" @@ -501,92 +502,7 @@ void OpenPhotoEditorForSticker( Ui::LayerOption::KeepOther); } -} // namespace - -StickerCreatorBox::StickerCreatorBox( - QWidget*, - std::shared_ptr show, - StickerSetIdentifier set, - QImage image, - Fn done) -: _show(std::move(show)) -, _session(&_show->session()) -, _set(std::move(set)) -, _image(std::move(image)) -, _done(std::move(done)) { -} - -StickerCreatorBox::~StickerCreatorBox() = default; - -void StickerCreatorBox::prepare() { - setTitle(tr::lng_stickers_create_image_title()); - - const auto inner = setInnerWidget( - object_ptr(this)); - - const auto previewHolder = inner->add( - object_ptr(inner), - QMargins(0, st::boxRowPadding.left(), 0, st::boxRowPadding.left()), - style::al_top); - previewHolder->resize(st::boxWideWidth, kPreviewSide); - const auto preview = Ui::CreateChild( - previewHolder, - _image); - previewHolder->widthValue( - ) | rpl::on_next([=](int width) { - preview->move((width - kPreviewSide) / 2, 0); - }, preview->lifetime()); - - inner->add( - object_ptr( - inner, - tr::lng_stickers_create_choose_emoji(), - st::boxLabel), - st::boxRowPadding); - inner->add( - object_ptr( - inner, - tr::lng_stickers_pack_choose_emoji_about(), - st::boxDividerLabel), - st::boxRowPadding); - - const auto emojiRow = inner->add( - object_ptr( - inner, - _show, - getDelegate()->outerContainer()), - QMargins(0, 0, 0, st::boxRowPadding.left())); - emojiRow->resize(st::boxWideWidth, st::stickersCreatorRowHeight); - _emojiValue = [=] { return emojiRow->value(); }; - - const auto addButton = this->addButton( - rpl::conditional( - _uploading.value(), - rpl::single(QString()), - tr::lng_box_done()), - [=] { startUpload(); }); - this->addButton(tr::lng_cancel(), [=] { closeBox(); }); - - { - using namespace Info::Statistics; - const auto loadingAnimation = InfiniteRadialAnimationWidget( - addButton, - addButton->height() / 2, - &st::editStickerSetNameLoading); - AddChildToWidgetCenter(addButton, loadingAnimation); - loadingAnimation->showOn(_uploading.value()); - } - - setDimensionsToContent(st::boxWideWidth, inner); - - boxClosing( - ) | rpl::on_next([=, this] { - _upload = nullptr; - }, lifetime()); -} - -QByteArray StickerCreatorBox::encodeWebp() const { - auto image = _image; +[[nodiscard]] QByteArray EncodeWebp(QImage image) { if (image.size() != QSize(kStickerSide, kStickerSide)) { image = image.scaled( kStickerSide, @@ -604,51 +520,138 @@ QByteArray StickerCreatorBox::encodeWebp() const { return bytes; } -void StickerCreatorBox::startUpload() { - if (_uploading.current()) { - return; - } - const auto emoji = _emojiValue ? _emojiValue() : QString(); - if (emoji.isEmpty()) { - _show->showToast(tr::lng_stickers_create_emoji_required(tr::now)); - return; - } - const auto bytes = encodeWebp(); - if (bytes.isEmpty()) { - _show->showToast(tr::lng_stickers_create_upload_failed(tr::now)); - return; - } - - _uploading = true; - _upload = std::make_unique( - _session, - _set, - bytes, - emoji); - - const auto show = _show; - const auto doneCallback = _done; - _upload->start( - crl::guard(this, [=, this](MTPmessages_StickerSet result) { - _upload = nullptr; - _uploading = false; - show->showToast(tr::lng_stickers_create_added(tr::now)); - if (doneCallback) { - doneCallback(result); - } - closeBox(); - }), - crl::guard(this, [=, this](QString err) { - _upload = nullptr; - _uploading = false; - show->showToast(err.isEmpty() - ? tr::lng_stickers_create_upload_failed(tr::now) - : err); - })); -} +} // namespace namespace Api { +void CreateStickerBox( + not_null box, + std::shared_ptr show, + StickerSetIdentifier set, + QImage image, + Fn done) { + struct State { + rpl::variable uploading = false; + std::unique_ptr upload; + QPointer addButton; + }; + const auto state = box->lifetime().make_state(); + const auto session = &show->session(); + + box->setTitle(tr::lng_stickers_create_image_title()); + + const auto inner = box->verticalLayout(); + + const auto previewHolder = inner->add( + object_ptr(inner), + QMargins(0, 0, 0, 0), + // QMargins(0, st::boxRowPadding.left(), 0, st::boxRowPadding.left()), + style::al_top); + previewHolder->resize(st::boxWideWidth, kPreviewSide); + const auto preview = Ui::CreateChild( + previewHolder, + image); + previewHolder->widthValue( + ) | rpl::on_next([=](int width) { + preview->move((width - kPreviewSide) / 2, 0); + }, preview->lifetime()); + + Ui::AddSkip(inner); + Ui::AddSkip(inner); + + inner->add( + object_ptr( + inner, + tr::lng_stickers_pack_choose_emoji_about(), + st::boxDividerLabel), + st::boxRowPadding); + + const auto emojiRow = inner->add( + object_ptr( + inner, + show, + box->getDelegate()->outerContainer()), + QMargins(0, 0, 0, st::boxRowPadding.left())); + emojiRow->resize(st::boxWideWidth, st::stickersCreatorRowHeight); + + const auto startUpload = [=, set = std::move(set), done = std::move(done)]( + ) mutable { + if (state->uploading.current()) { + return; + } + const auto emoji = emojiRow->value(); + if (emoji.isEmpty()) { + show->showToast( + tr::lng_stickers_create_emoji_required(tr::now)); + return; + } + const auto bytes = EncodeWebp(image); + if (bytes.isEmpty()) { + show->showToast( + tr::lng_stickers_create_upload_failed(tr::now)); + return; + } + + const auto lockedWidth = state->addButton + ? state->addButton->width() + : 0; + state->uploading = true; + if (state->addButton && lockedWidth > 0) { + state->addButton->resizeToWidth(lockedWidth); + } + state->upload = std::make_unique( + session, + set, + bytes, + emoji); + + const auto doneCallback = done; + state->upload->start( + crl::guard(box, [=](MTPmessages_StickerSet result) { + state->upload = nullptr; + state->uploading = false; + show->showToast(tr::lng_stickers_create_added(tr::now)); + if (doneCallback) { + doneCallback(result); + } + box->closeBox(); + }), + crl::guard(box, [=](QString err) { + state->upload = nullptr; + state->uploading = false; + show->showToast(err.isEmpty() + ? tr::lng_stickers_create_upload_failed(tr::now) + : err); + })); + }; + + const auto addButton = box->addButton( + rpl::conditional( + state->uploading.value(), + rpl::single(QString()), + tr::lng_box_done()), + startUpload); + state->addButton = addButton; + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); + + { + using namespace Info::Statistics; + const auto loadingAnimation = InfiniteRadialAnimationWidget( + addButton, + addButton->height() / 2, + &st::editStickerSetNameLoading); + AddChildToWidgetCenter(addButton, loadingAnimation); + loadingAnimation->showOn(state->uploading.value()); + } + + box->setWidth(st::boxWideWidth); + + box->boxClosing( + ) | rpl::on_next([=] { + state->upload = nullptr; + }, box->lifetime()); +} + void OpenCreateStickerFlow( std::shared_ptr show, StickerSetIdentifier set, @@ -671,7 +674,8 @@ void OpenCreateStickerFlow( std::move(image), [=, set = std::move(set), done = std::move(done)]( QImage &&prepared) mutable { - show->showBox(Box( + show->showBox(Box( + CreateStickerBox, show, std::move(set), std::move(prepared), diff --git a/Telegram/SourceFiles/boxes/sticker_creator_box.h b/Telegram/SourceFiles/boxes/sticker_creator_box.h index b973227fda..75c2a3648a 100644 --- a/Telegram/SourceFiles/boxes/sticker_creator_box.h +++ b/Telegram/SourceFiles/boxes/sticker_creator_box.h @@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "data/stickers/data_stickers.h" -#include "ui/layers/box_content.h" #include @@ -16,45 +15,18 @@ namespace ChatHelpers { class Show; } // namespace ChatHelpers -namespace Main { -class Session; -} // namespace Main +namespace Ui { +class GenericBox; +} // namespace Ui namespace Api { -class StickerUpload; -} // namespace Api -class StickerCreatorBox final : public Ui::BoxContent { -public: - StickerCreatorBox( - QWidget*, - std::shared_ptr show, - StickerSetIdentifier set, - QImage image, - Fn done); - ~StickerCreatorBox(); - -protected: - void prepare() override; - -private: - void startUpload(); - [[nodiscard]] QByteArray encodeWebp() const; - - const std::shared_ptr _show; - const not_null _session; - const StickerSetIdentifier _set; - const QImage _image; - const Fn _done; - - rpl::variable _uploading = false; - Fn _emojiValue; - - std::unique_ptr _upload; - -}; - -namespace Api { +void CreateStickerBox( + not_null box, + std::shared_ptr show, + StickerSetIdentifier set, + QImage image, + Fn done); void OpenCreateStickerFlow( std::shared_ptr show,