Fix custom emoji in edit caption / send files box.

This commit is contained in:
John Preston 2022-07-25 13:34:18 +03:00
parent 075ced2742
commit 2d6008f6ca
17 changed files with 83 additions and 40 deletions

View file

@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_premium_limits.h" #include "data/data_premium_limits.h"
#include "data/stickers/data_custom_emoji.h"
#include "editor/photo_editor_layer_widget.h" #include "editor/photo_editor_layer_widget.h"
#include "history/history_drag_area.h" #include "history/history_drag_area.h"
#include "history/history_item.h" #include "history/history_item.h"
@ -473,13 +474,15 @@ void EditCaptionBox::setupDragArea() {
void EditCaptionBox::setupEmojiPanel() { void EditCaptionBox::setupEmojiPanel() {
const auto container = getDelegate()->outerContainer(); const auto container = getDelegate()->outerContainer();
using Selector = ChatHelpers::TabbedSelector;
_emojiPanel = base::make_unique_q<ChatHelpers::TabbedPanel>( _emojiPanel = base::make_unique_q<ChatHelpers::TabbedPanel>(
container, container,
_controller, _controller,
object_ptr<ChatHelpers::TabbedSelector>( object_ptr<Selector>(
nullptr, nullptr,
_controller, _controller,
ChatHelpers::TabbedSelector::Mode::EmojiOnly)); Window::GifPauseReason::Layer,
Selector::Mode::EmojiOnly));
_emojiPanel->setDesiredHeightValues( _emojiPanel->setDesiredHeightValues(
1., 1.,
st::emojiPanMinHeight / 2, st::emojiPanMinHeight / 2,
@ -489,6 +492,10 @@ void EditCaptionBox::setupEmojiPanel() {
) | rpl::start_with_next([=](EmojiPtr emoji) { ) | rpl::start_with_next([=](EmojiPtr emoji) {
Ui::InsertEmojiAtCursor(_field->textCursor(), emoji); Ui::InsertEmojiAtCursor(_field->textCursor(), emoji);
}, lifetime()); }, lifetime());
_emojiPanel->selector()->customEmojiChosen(
) | rpl::start_with_next([=](Selector::FileChosen data) {
Data::InsertCustomEmoji(_field.get(), data.document);
}, lifetime());
const auto filterCallback = [=](not_null<QEvent*> event) { const auto filterCallback = [=](not_null<QEvent*> event) {
emojiFilterForGeometry(event); emojiFilterForGeometry(event);

View file

@ -48,6 +48,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_premium_limits.h" #include "data/data_premium_limits.h"
#include "data/stickers/data_custom_emoji.h"
#include "media/clip/media_clip_reader.h" #include "media/clip/media_clip_reader.h"
#include "api/api_common.h" #include "api/api_common.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
@ -715,13 +716,15 @@ void SendFilesBox::setupEmojiPanel() {
Expects(_caption != nullptr); Expects(_caption != nullptr);
const auto container = getDelegate()->outerContainer(); const auto container = getDelegate()->outerContainer();
using Selector = ChatHelpers::TabbedSelector;
_emojiPanel = base::make_unique_q<ChatHelpers::TabbedPanel>( _emojiPanel = base::make_unique_q<ChatHelpers::TabbedPanel>(
container, container,
_controller, _controller,
object_ptr<ChatHelpers::TabbedSelector>( object_ptr<Selector>(
nullptr, nullptr,
_controller, _controller,
ChatHelpers::TabbedSelector::Mode::EmojiOnly)); Window::GifPauseReason::Layer,
Selector::Mode::EmojiOnly));
_emojiPanel->setDesiredHeightValues( _emojiPanel->setDesiredHeightValues(
1., 1.,
st::emojiPanMinHeight / 2, st::emojiPanMinHeight / 2,
@ -731,6 +734,10 @@ void SendFilesBox::setupEmojiPanel() {
) | rpl::start_with_next([=](EmojiPtr emoji) { ) | rpl::start_with_next([=](EmojiPtr emoji) {
Ui::InsertEmojiAtCursor(_caption->textCursor(), emoji); Ui::InsertEmojiAtCursor(_caption->textCursor(), emoji);
}, lifetime()); }, lifetime());
_emojiPanel->selector()->customEmojiChosen(
) | rpl::start_with_next([=](Selector::FileChosen data) {
Data::InsertCustomEmoji(_caption.data(), data.document);
}, lifetime());
const auto filterCallback = [=](not_null<QEvent*> event) { const auto filterCallback = [=](not_null<QEvent*> event) {
emojiFilterForGeometry(event); emojiFilterForGeometry(event);

View file

@ -364,8 +364,9 @@ void EmojiColorPicker::drawVariant(Painter &p, int variant) {
EmojiListWidget::EmojiListWidget( EmojiListWidget::EmojiListWidget(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller) not_null<Window::SessionController*> controller,
: Inner(parent, controller) Window::GifPauseReason level)
: Inner(parent, controller, level)
, _localSetsManager( , _localSetsManager(
std::make_unique<LocalStickersManager>(&controller->session())) std::make_unique<LocalStickersManager>(&controller->session()))
, _collapsedBg(st::emojiPanExpand.height / 2, st::emojiPanHeaderFg) , _collapsedBg(st::emojiPanExpand.height / 2, st::emojiPanHeaderFg)
@ -509,6 +510,7 @@ object_ptr<TabbedSelector::InnerFooter> EmojiListWidget::createFooter() {
using FooterDescriptor = StickersListFooter::Descriptor; using FooterDescriptor = StickersListFooter::Descriptor;
auto result = object_ptr<StickersListFooter>(FooterDescriptor{ auto result = object_ptr<StickersListFooter>(FooterDescriptor{
.controller = controller(), .controller = controller(),
.level = level(),
.parent = this, .parent = this,
}); });
_footer = result; _footer = result;
@ -703,8 +705,7 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
toColumn = _columnCount - toColumn; toColumn = _columnCount - toColumn;
} }
const auto paused = controller()->isGifPausedAtLeastFor( const auto paused = controller()->isGifPausedAtLeastFor(level());
Window::GifPauseReason::SavedGifs);
const auto now = crl::now(); const auto now = crl::now();
auto selectedButton = std::get_if<OverButton>(!v::is_null(_pressed) auto selectedButton = std::get_if<OverButton>(!v::is_null(_pressed)
? &_pressed ? &_pressed

View file

@ -58,7 +58,8 @@ class EmojiListWidget
public: public:
EmojiListWidget( EmojiListWidget(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller); not_null<Window::SessionController*> controller,
Window::GifPauseReason level);
~EmojiListWidget(); ~EmojiListWidget();
using Section = Ui::Emoji::Section; using Section = Ui::Emoji::Section;

View file

@ -861,7 +861,7 @@ void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) {
media->checkStickerSmall(); media->checkStickerSmall();
const auto paused = _controller->isGifPausedAtLeastFor( const auto paused = _controller->isGifPausedAtLeastFor(
Window::GifPauseReason::SavedGifs); Window::GifPauseReason::TabbedPanel);
const auto size = ChatHelpers::ComputeStickerSize( const auto size = ChatHelpers::ComputeStickerSize(
document, document,
stickerBoundingBox()); stickerBoundingBox());

View file

@ -168,8 +168,9 @@ void GifsListWidget::Footer::processPanelHideFinished() {
GifsListWidget::GifsListWidget( GifsListWidget::GifsListWidget(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller) not_null<Window::SessionController*> controller,
: Inner(parent, controller) Window::GifPauseReason level)
: Inner(parent, controller, level)
, _api(&controller->session().mtp()) , _api(&controller->session().mtp())
, _section(Section::Gifs) , _section(Section::Gifs)
, _updateInlineItems([=] { updateInlineItems(); }) , _updateInlineItems([=] { updateInlineItems(); })
@ -197,8 +198,7 @@ GifsListWidget::GifsListWidget(
controller->gifPauseLevelChanged( controller->gifPauseLevelChanged(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
if (!controller->isGifPausedAtLeastFor( if (!controller->isGifPausedAtLeastFor(level)) {
Window::GifPauseReason::SavedGifs)) {
updateInlineItems(); updateInlineItems();
} }
}, lifetime()); }, lifetime());
@ -343,8 +343,7 @@ void GifsListWidget::paintInlineItems(Painter &p, QRect clip) {
p.drawText(QRect(0, 0, width(), (height() / 3) * 2 + st::normalFont->height), text, style::al_center); p.drawText(QRect(0, 0, width(), (height() / 3) * 2 + st::normalFont->height), text, style::al_center);
return; return;
} }
const auto gifPaused = controller()->isGifPausedAtLeastFor( const auto gifPaused = controller()->isGifPausedAtLeastFor(level());
Window::GifPauseReason::SavedGifs);
using namespace InlineBots::Layout; using namespace InlineBots::Layout;
PaintContext context(crl::now(), false, gifPaused, false); PaintContext context(crl::now(), false, gifPaused, false);

View file

@ -51,7 +51,10 @@ class GifsListWidget
public: public:
using InlineChosen = TabbedSelector::InlineChosen; using InlineChosen = TabbedSelector::InlineChosen;
GifsListWidget(QWidget *parent, not_null<Window::SessionController*> controller); GifsListWidget(
QWidget *parent,
not_null<Window::SessionController*> controller,
Window::GifPauseReason level);
rpl::producer<TabbedSelector::FileChosen> fileChosen() const; rpl::producer<TabbedSelector::FileChosen> fileChosen() const;
rpl::producer<TabbedSelector::PhotoChosen> photoChosen() const; rpl::producer<TabbedSelector::PhotoChosen> photoChosen() const;

View file

@ -147,6 +147,7 @@ bool StickersListFooter::ScrollState::animationCallback(crl::time now) {
StickersListFooter::StickersListFooter(Descriptor &&descriptor) StickersListFooter::StickersListFooter(Descriptor &&descriptor)
: InnerFooter(descriptor.parent) : InnerFooter(descriptor.parent)
, _controller(descriptor.controller) , _controller(descriptor.controller)
, _level(descriptor.level)
, _searchButtonVisible(descriptor.searchButtonVisible) , _searchButtonVisible(descriptor.searchButtonVisible)
, _settingsButtonVisible(descriptor.settingsButtonVisible) , _settingsButtonVisible(descriptor.settingsButtonVisible)
, _iconState([=] { update(); }) , _iconState([=] { update(); })
@ -559,8 +560,7 @@ void StickersListFooter::paintEvent(QPaintEvent *e) {
} }
const auto now = crl::now(); const auto now = crl::now();
const auto paused = _controller->isGifPausedAtLeastFor( const auto paused = _controller->isGifPausedAtLeastFor(_level);
Window::GifPauseReason::SavedGifs);
enumerateVisibleIcons([&](const IconInfo &info) { enumerateVisibleIcons([&](const IconInfo &info) {
paintSetIcon(p, info, now, paused); paintSetIcon(p, info, now, paused);
}); });

View file

@ -78,6 +78,7 @@ class StickersListFooter final : public TabbedSelector::InnerFooter {
public: public:
struct Descriptor { struct Descriptor {
not_null<Window::SessionController*> controller; not_null<Window::SessionController*> controller;
Window::GifPauseReason level = {};
not_null<RpWidget*> parent; not_null<RpWidget*> parent;
bool searchButtonVisible = false; bool searchButtonVisible = false;
bool settingsButtonVisible = false; bool settingsButtonVisible = false;
@ -210,6 +211,7 @@ private:
void clipCallback(Media::Clip::Notification notification, uint64 setId); void clipCallback(Media::Clip::Notification notification, uint64 setId);
const not_null<Window::SessionController*> _controller; const not_null<Window::SessionController*> _controller;
const Window::GifPauseReason _level = {};
const bool _searchButtonVisible = false; const bool _searchButtonVisible = false;
const bool _settingsButtonVisible = false; const bool _settingsButtonVisible = false;

View file

@ -162,8 +162,9 @@ void StickersListWidget::Sticker::ensureMediaCreated() {
StickersListWidget::StickersListWidget( StickersListWidget::StickersListWidget(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
Window::GifPauseReason level,
bool masks) bool masks)
: Inner(parent, controller) : Inner(parent, controller, level)
, _api(&controller->session().mtp()) , _api(&controller->session().mtp())
, _localSetsManager( , _localSetsManager(
std::make_unique<LocalStickersManager>(&controller->session())) std::make_unique<LocalStickersManager>(&controller->session()))
@ -252,6 +253,7 @@ object_ptr<TabbedSelector::InnerFooter> StickersListWidget::createFooter() {
using FooterDescriptor = StickersListFooter::Descriptor; using FooterDescriptor = StickersListFooter::Descriptor;
auto result = object_ptr<StickersListFooter>(FooterDescriptor{ auto result = object_ptr<StickersListFooter>(FooterDescriptor{
.controller = controller(), .controller = controller(),
.level = level(),
.parent = this, .parent = this,
.searchButtonVisible = !_isMasks, .searchButtonVisible = !_isMasks,
.settingsButtonVisible = true, .settingsButtonVisible = true,
@ -818,8 +820,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
: &_selected); : &_selected);
const auto now = crl::now(); const auto now = crl::now();
const auto paused = controller()->isGifPausedAtLeastFor( const auto paused = controller()->isGifPausedAtLeastFor(level());
Window::GifPauseReason::SavedGifs);
if (sets.empty() && _section == Section::Search) { if (sets.empty() && _section == Section::Search) {
paintEmptySearchResults(p); paintEmptySearchResults(p);
} }

View file

@ -56,6 +56,7 @@ public:
StickersListWidget( StickersListWidget(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
Window::GifPauseReason level,
bool masks = false); bool masks = false);
rpl::producer<TabbedSelector::FileChosen> chosen() const; rpl::producer<TabbedSelector::FileChosen> chosen() const;

View file

@ -64,16 +64,10 @@ TabbedPanel::TabbedPanel(
_selector->setParent(this); _selector->setParent(this);
_selector->setRoundRadius(st::roundRadiusSmall); _selector->setRoundRadius(st::roundRadiusSmall);
_selector->setAfterShownCallback([=](SelectorTab tab) { _selector->setAfterShownCallback([=](SelectorTab tab) {
if (tab == SelectorTab::Gifs || tab == SelectorTab::Stickers) { _controller->enableGifPauseReason(_selector->level());
_controller->enableGifPauseReason(
Window::GifPauseReason::SavedGifs);
}
}); });
_selector->setBeforeHidingCallback([=](SelectorTab tab) { _selector->setBeforeHidingCallback([=](SelectorTab tab) {
if (tab == SelectorTab::Gifs || tab == SelectorTab::Stickers) { _controller->disableGifPauseReason(_selector->level());
_controller->disableGifPauseReason(
Window::GifPauseReason::SavedGifs);
}
}); });
_selector->showRequests( _selector->showRequests(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {

View file

@ -289,9 +289,11 @@ void TabbedSelector::Tab::saveScrollTop() {
TabbedSelector::TabbedSelector( TabbedSelector::TabbedSelector(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
Window::GifPauseReason level,
Mode mode) Mode mode)
: RpWidget(parent) : RpWidget(parent)
, _controller(controller) , _controller(controller)
, _level(level)
, _mode(mode) , _mode(mode)
, _topShadow(full() ? object_ptr<Ui::PlainShadow>(this) : nullptr) , _topShadow(full() ? object_ptr<Ui::PlainShadow>(this) : nullptr)
, _bottomShadow(this) , _bottomShadow(this)
@ -425,17 +427,25 @@ Main::Session &TabbedSelector::session() const {
return _controller->session(); return _controller->session();
} }
Window::GifPauseReason TabbedSelector::level() const {
return _level;
}
TabbedSelector::Tab TabbedSelector::createTab(SelectorTab type, int index) { TabbedSelector::Tab TabbedSelector::createTab(SelectorTab type, int index) {
auto createWidget = [&]() -> object_ptr<Inner> { auto createWidget = [&]() -> object_ptr<Inner> {
switch (type) { switch (type) {
case SelectorTab::Emoji: case SelectorTab::Emoji:
return object_ptr<EmojiListWidget>(this, _controller); return object_ptr<EmojiListWidget>(this, _controller, _level);
case SelectorTab::Stickers: case SelectorTab::Stickers:
return object_ptr<StickersListWidget>(this, _controller); return object_ptr<StickersListWidget>(this, _controller, _level);
case SelectorTab::Gifs: case SelectorTab::Gifs:
return object_ptr<GifsListWidget>(this, _controller); return object_ptr<GifsListWidget>(this, _controller, _level);
case SelectorTab::Masks: case SelectorTab::Masks:
return object_ptr<StickersListWidget>(this, _controller, true); return object_ptr<StickersListWidget>(
this,
_controller,
_level,
true);
} }
Unexpected("Type in TabbedSelector::createTab."); Unexpected("Type in TabbedSelector::createTab.");
}; };
@ -1133,9 +1143,11 @@ not_null<const TabbedSelector::Tab*> TabbedSelector::currentTab() const {
TabbedSelector::Inner::Inner( TabbedSelector::Inner::Inner(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller) not_null<Window::SessionController*> controller,
Window::GifPauseReason level)
: RpWidget(parent) : RpWidget(parent)
, _controller(controller) { , _controller(controller)
, _level(level) {
} }
Main::Session &TabbedSelector::Inner::session() const { Main::Session &TabbedSelector::Inner::session() const {

View file

@ -34,6 +34,7 @@ class BoxContent;
namespace Window { namespace Window {
class SessionController; class SessionController;
enum class GifPauseReason;
} // namespace Window } // namespace Window
namespace SendMenu { namespace SendMenu {
@ -78,10 +79,12 @@ public:
TabbedSelector( TabbedSelector(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
Window::GifPauseReason level,
Mode mode = Mode::Full); Mode mode = Mode::Full);
~TabbedSelector(); ~TabbedSelector();
Main::Session &session() const; Main::Session &session() const;
Window::GifPauseReason level() const;
rpl::producer<EmojiPtr> emojiChosen() const; rpl::producer<EmojiPtr> emojiChosen() const;
rpl::producer<FileChosen> customEmojiChosen() const; rpl::producer<FileChosen> customEmojiChosen() const;
@ -222,6 +225,7 @@ private:
not_null<StickersListWidget*> masks() const; not_null<StickersListWidget*> masks() const;
const not_null<Window::SessionController*> _controller; const not_null<Window::SessionController*> _controller;
const Window::GifPauseReason _level = {};
Mode _mode = Mode::Full; Mode _mode = Mode::Full;
int _roundRadius = 0; int _roundRadius = 0;
@ -258,11 +262,17 @@ private:
class TabbedSelector::Inner : public Ui::RpWidget { class TabbedSelector::Inner : public Ui::RpWidget {
public: public:
Inner(QWidget *parent, not_null<Window::SessionController*> controller); Inner(
QWidget *parent,
not_null<Window::SessionController*> controller,
Window::GifPauseReason level);
[[nodiscard]] not_null<Window::SessionController*> controller() const { [[nodiscard]] not_null<Window::SessionController*> controller() const {
return _controller; return _controller;
} }
[[nodiscard]] Window::GifPauseReason level() const {
return _level;
}
[[nodiscard]] Main::Session &session() const; [[nodiscard]] Main::Session &session() const;
[[nodiscard]] int getVisibleTop() const { [[nodiscard]] int getVisibleTop() const {
@ -321,7 +331,8 @@ protected:
void checkHideWithBox(QPointer<Ui::BoxContent> box); void checkHideWithBox(QPointer<Ui::BoxContent> box);
private: private:
not_null<Window::SessionController*> _controller; const not_null<Window::SessionController*> _controller;
const Window::GifPauseReason _level = {};
int _visibleTop = 0; int _visibleTop = 0;
int _visibleBottom = 0; int _visibleBottom = 0;

View file

@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "chat_helpers/tabbed_panel.h" #include "chat_helpers/tabbed_panel.h"
#include "chat_helpers/tabbed_selector.h" #include "chat_helpers/tabbed_selector.h"
#include "window/window_session_controller.h" // Window::GifPauseReason
#include "styles/style_chat_helpers.h" #include "styles/style_chat_helpers.h"
namespace Editor { namespace Editor {
@ -23,6 +25,7 @@ StickersPanelController::StickersPanelController(
object_ptr<ChatHelpers::TabbedSelector>( object_ptr<ChatHelpers::TabbedSelector>(
nullptr, nullptr,
controller, controller,
Window::GifPauseReason::Layer,
ChatHelpers::TabbedSelector::Mode::MediaEditor))) { ChatHelpers::TabbedSelector::Mode::MediaEditor))) {
_stickersPanel->setDesiredHeightValues( _stickersPanel->setDesiredHeightValues(
1., 1.,

View file

@ -620,7 +620,8 @@ SessionController::SessionController(
, _tabbedSelector( , _tabbedSelector(
std::make_unique<ChatHelpers::TabbedSelector>( std::make_unique<ChatHelpers::TabbedSelector>(
_window->widget(), _window->widget(),
this)) this,
GifPauseReason::TabbedPanel))
, _invitePeekTimer([=] { checkInvitePeek(); }) , _invitePeekTimer([=] { checkInvitePeek(); })
, _activeChatsFilter(session->data().chatsFilters().defaultId()) , _activeChatsFilter(session->data().chatsFilters().defaultId())
, _defaultChatTheme(std::make_shared<Ui::ChatTheme>()) , _defaultChatTheme(std::make_shared<Ui::ChatTheme>())

View file

@ -84,7 +84,7 @@ class FiltersMenu;
enum class GifPauseReason { enum class GifPauseReason {
Any = 0, Any = 0,
InlineResults = (1 << 0), InlineResults = (1 << 0),
SavedGifs = (1 << 1), TabbedPanel = (1 << 1),
Layer = (1 << 2), Layer = (1 << 2),
RoundPlaying = (1 << 3), RoundPlaying = (1 << 3),
MediaPreview = (1 << 4), MediaPreview = (1 << 4),