From fc85b09e883b136d2feff0ba6a0fde736831024f Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 13 Apr 2026 16:42:15 +0300 Subject: [PATCH] Switched existing sticker pick to inline dropdown that excludes self. --- Telegram/CMakeLists.txt | 2 - Telegram/Resources/langs/lang.strings | 2 + .../SourceFiles/boxes/sticker_creator_box.cpp | 7 +- .../SourceFiles/boxes/sticker_picker_box.cpp | 74 ------------------- .../SourceFiles/boxes/sticker_picker_box.h | 36 --------- .../SourceFiles/boxes/sticker_set_box.cpp | 51 +++++++++++-- .../chat_helpers/stickers_list_widget.cpp | 4 + .../chat_helpers/stickers_list_widget.h | 2 + 8 files changed, 58 insertions(+), 120 deletions(-) delete mode 100644 Telegram/SourceFiles/boxes/sticker_picker_box.cpp delete mode 100644 Telegram/SourceFiles/boxes/sticker_picker_box.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index d29a4281ee..a7ca2c4d00 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -378,8 +378,6 @@ PRIVATE boxes/star_gift_resale_box.h boxes/sticker_creator_box.cpp boxes/sticker_creator_box.h - boxes/sticker_picker_box.cpp - boxes/sticker_picker_box.h boxes/sticker_set_box.cpp boxes/sticker_set_box.h boxes/stickers_box.cpp diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 5431fdefeb..55fd289d4b 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -4509,6 +4509,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_stickers_create_new" = "Create a New Sticker"; "lng_stickers_add_existing" = "Add an Existing Sticker"; +"lng_stickers_pack_choose_emoji_title" = "Choose Emoji"; +"lng_stickers_pack_choose_emoji_about" = "Pick an emoji that corresponds to this sticker."; "lng_stickers_pick_existing_title" = "Choose Sticker"; "lng_stickers_pick_existing_about" = "Pick a sticker from your library to add it to this set."; "lng_stickers_pick_existing_empty" = "You don't have any stickers yet."; diff --git a/Telegram/SourceFiles/boxes/sticker_creator_box.cpp b/Telegram/SourceFiles/boxes/sticker_creator_box.cpp index c390506d27..0c28b19cd1 100644 --- a/Telegram/SourceFiles/boxes/sticker_creator_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_creator_box.cpp @@ -447,10 +447,11 @@ void StickerCreatorBox::prepare() { st::boxLabel), st::boxRowPadding); - _emojiRow = inner->add( + const auto emojiRow = inner->add( object_ptr(inner, _show), QMargins(0, 0, 0, st::boxRowPadding.left())); - _emojiRow->resize(st::boxWideWidth, st::stickersCreatorRowHeight); + emojiRow->resize(st::boxWideWidth, st::stickersCreatorRowHeight); + _emojiValue = [=] { return emojiRow->value(); }; const auto addButton = this->addButton( rpl::conditional( @@ -501,7 +502,7 @@ void StickerCreatorBox::startUpload() { if (_uploading.current()) { return; } - const auto emoji = _emojiRow->value(); + const auto emoji = _emojiValue ? _emojiValue() : QString(); if (emoji.isEmpty()) { _show->showToast(tr::lng_stickers_create_emoji_required(tr::now)); return; diff --git a/Telegram/SourceFiles/boxes/sticker_picker_box.cpp b/Telegram/SourceFiles/boxes/sticker_picker_box.cpp deleted file mode 100644 index 6bfe7e2e1e..0000000000 --- a/Telegram/SourceFiles/boxes/sticker_picker_box.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* -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 "boxes/sticker_picker_box.h" - -#include "chat_helpers/compose/compose_show.h" -#include "chat_helpers/stickers_list_widget.h" -#include "data/data_document.h" -#include "data/data_session.h" -#include "data/stickers/data_stickers.h" -#include "lang/lang_keys.h" -#include "main/main_session.h" -#include "styles/style_chat_helpers.h" -#include "styles/style_layers.h" - -StickerPickerBox::StickerPickerBox( - QWidget*, - std::shared_ptr show, - Fn)> chosen) -: _show(std::move(show)) -, _chosen(std::move(chosen)) { -} - -void StickerPickerBox::prepare() { - setTitle(tr::lng_stickers_pick_existing_title()); - - auto descriptor = ChatHelpers::StickersListDescriptor{ - .show = _show, - .mode = ChatHelpers::StickersListMode::UserpicBuilder, - .paused = [] { return false; }, - }; - auto list = object_ptr( - this, - std::move(descriptor)); - _list = list.data(); - - _list->refreshRecent(); - _list->refreshStickers(); - - _list->chosen( - ) | rpl::on_next([=](const ChatHelpers::FileChosen &chosen) { - const auto document = chosen.document; - if (_chosen) { - _chosen(document); - } - closeBox(); - }, _list->lifetime()); - - setInnerWidget(std::move(list)); - setDimensions(st::boxWideWidth, st::stickersMaxHeight); - - scrolls( - ) | rpl::on_next([=, this] { - if (_list) { - const auto top = scrollTop(); - _list->setVisibleTopBottom(top, top + scrollHeight()); - } - }, lifetime()); - - addButton(tr::lng_cancel(), [=] { closeBox(); }); -} - -void StickerPickerBox::resizeEvent(QResizeEvent *e) { - BoxContent::resizeEvent(e); - if (_list) { - const auto width = this->width(); - _list->resizeToWidth(width); - _list->setMinimalHeight(width, st::stickersMaxHeight); - } -} diff --git a/Telegram/SourceFiles/boxes/sticker_picker_box.h b/Telegram/SourceFiles/boxes/sticker_picker_box.h deleted file mode 100644 index 0b43b25149..0000000000 --- a/Telegram/SourceFiles/boxes/sticker_picker_box.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -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/layers/box_content.h" - -class DocumentData; - -namespace ChatHelpers { -class Show; -class StickersListWidget; -} // namespace ChatHelpers - -class StickerPickerBox final : public Ui::BoxContent { -public: - StickerPickerBox( - QWidget*, - std::shared_ptr show, - Fn)> chosen); - -protected: - void prepare() override; - void resizeEvent(QResizeEvent *e) override; - -private: - const std::shared_ptr _show; - Fn)> _chosen; - - QPointer _list; - -}; diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index 0ea2e41d6c..8b74f0bb41 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/unixtime.h" #include "boxes/premium_preview_box.h" #include "boxes/sticker_creator_box.h" -#include "boxes/sticker_picker_box.h" #include "chat_helpers/compose/compose_show.h" #include "chat_helpers/stickers_list_widget.h" #include "chat_helpers/stickers_lottie.h" @@ -57,6 +56,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/gradient_round_button.h" #include "ui/widgets/menu/menu_add_action_callback.h" #include "ui/widgets/menu/menu_add_action_callback_factory.h" +#include "ui/widgets/inner_dropdown.h" #include "ui/widgets/popup_menu.h" #include "ui/widgets/scroll_area.h" #include "window/window_session_controller.h" @@ -488,6 +488,7 @@ private: bool _previewLocked = false; base::unique_qptr _menu; + base::unique_qptr _pickerDropdown; rpl::event_stream _setInstalled; rpl::event_stream _setArchived; @@ -2353,6 +2354,16 @@ void StickerSetBox::Inner::startAddExistingStickerFlow() { if (!hasAddCell()) { return; } + auto box = (Ui::BoxContent*)nullptr; + for (auto p = parentWidget(); p; p = p->parentWidget()) { + if (const auto candidate = dynamic_cast(p)) { + box = candidate; + break; + } + } + if (!box) { + return; + } const auto identifier = StickerSetIdentifier{ .id = _setId, .accessHash = _setAccessHash, @@ -2360,8 +2371,31 @@ void StickerSetBox::Inner::startAddExistingStickerFlow() { }; const auto session = _session; const auto show = _show; - const auto onChosen = crl::guard(this, [=, this]( - not_null document) { + + _pickerDropdown = base::make_unique_q(box); + const auto dropdown = _pickerDropdown.get(); + dropdown->setAutoHiding(false); + dropdown->setMaxHeight(st::stickersMaxHeight); + + auto descriptor = ChatHelpers::StickersListDescriptor{ + .show = _show, + .mode = ChatHelpers::StickersListMode::UserpicBuilder, + .paused = [] { return false; }, + .excludeSetId = _setId, + }; + const auto list = dropdown->setOwnedWidget( + object_ptr( + dropdown, + std::move(descriptor))); + list->refreshRecent(); + list->refreshStickers(); + + list->chosen( + ) | rpl::on_next([=, this](const ChatHelpers::FileChosen &chosen) { + const auto document = chosen.document; + if (_pickerDropdown) { + _pickerDropdown->hideAnimated(); + } const auto sticker = document->sticker(); const auto fallback = QString::fromUtf8("\xF0\x9F\x99\x82"); const auto emoji = (sticker && !sticker->alt.isEmpty()) @@ -2382,8 +2416,15 @@ void StickerSetBox::Inner::startAddExistingStickerFlow() { ? tr::lng_attach_failed(tr::now) : err); })); - }); - _show->showBox(Box(_show, onChosen)); + }, list->lifetime()); + + const auto desiredWidth = box->width(); + list->resizeToWidth(desiredWidth); + + dropdown->resize(desiredWidth, st::stickersMaxHeight); + dropdown->move(0, 0); + dropdown->setOrigin(Ui::PanelAnimation::Origin::TopLeft); + dropdown->showAnimated(); } void StickerSetBox::Inner::startCreateNewStickerFlow() { diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index 79172d23ad..0843ed7ccd 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -213,6 +213,7 @@ StickersListWidget::StickersListWidget( , _section(Section::Stickers) , _isMasks(_mode == Mode::Masks) , _isEffects(_mode == Mode::MessageEffects) +, _excludeSetId(descriptor.excludeSetId) , _updateItemsTimer([=] { updateItems(); }) , _updateSetsTimer([=] { updateSets(); }) , _trendingAddBgOver( @@ -2578,6 +2579,9 @@ bool StickersListWidget::appendSet( uint64 setId, bool externalLayout, AppendSkip skip) { + if (_excludeSetId && setId == _excludeSetId) { + return false; + } const auto &sets = session().data().stickers().sets(); auto it = sets.find(setId); if (it == sets.cend() diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h index ad9f514c24..f28369fcf9 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h @@ -84,6 +84,7 @@ struct StickersListDescriptor { std::vector customRecentList; const style::EmojiPan *st = nullptr; ComposeFeatures features; + uint64 excludeSetId = 0; }; class StickersListWidget final : public TabbedSelector::Inner { @@ -419,6 +420,7 @@ private: Section _section = Section::Stickers; const bool _isMasks; const bool _isEffects; + const uint64 _excludeSetId = 0; base::Timer _updateItemsTimer; base::Timer _updateSetsTimer;