From 170ebb57c6e6717bff087d041da3f578a3ebc137 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 9 Apr 2024 12:10:55 +0400 Subject: [PATCH] Preview custom emoji on long press from the panel. --- .../chat_helpers/emoji_list_widget.cpp | 49 ++++++++++++++++--- .../chat_helpers/emoji_list_widget.h | 6 +++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp index 42513a6ed399fa..ac8b6f1171f4aa 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp @@ -34,6 +34,7 @@ For license and copyright information please follow this link: #include "data/data_changes.h" #include "data/data_channel.h" #include "data/data_document.h" +#include "data/data_file_origin.h" #include "data/data_peer_values.h" #include "data/stickers/data_stickers.h" #include "data/stickers/data_custom_emoji.h" @@ -51,12 +52,15 @@ For license and copyright information please follow this link: #include "styles/style_chat_helpers.h" #include "styles/style_menu_icons.h" +#include + namespace ChatHelpers { namespace { constexpr auto kCollapsedRows = 3; constexpr auto kAppearDuration = 0.3; constexpr auto kCustomSearchLimit = 256; +constexpr auto kColorPickerDelay = crl::time(500); using Core::RecentEmojiId; using Core::RecentEmojiDocument; @@ -477,7 +481,8 @@ EmojiListWidget::EmojiListWidget( , _overBg(st::emojiPanRadius, st().overBg) , _collapsedBg(st::emojiPanExpand.height / 2, st().headerFg) , _picker(this, st()) -, _showPickerTimer([=] { showPicker(); }) { +, _showPickerTimer([=] { showPicker(); }) +, _previewTimer([=] { showPreview(); }) { setMouseTracking(true); if (st().bg->c.alpha() > 0) { setAttribute(Qt::WA_OpaquePaintEvent); @@ -624,6 +629,15 @@ void EmojiListWidget::applyNextSearchQuery() { } } +void EmojiListWidget::showPreview() { + if (const auto over = std::get_if(&_pressed)) { + if (const auto custom = lookupCustomEmoji(over)) { + _show->showMediaPreview(custom->stickerSetOrigin(), custom); + _previewShown = true; + } + } +} + std::vector EmojiListWidget::collectPlainSearchResults() { return SearchEmoji(_searchQuery, _searchEmoji); } @@ -1119,7 +1133,7 @@ void EmojiListWidget::fillRecentMenu( const auto addAction = Ui::Menu::CreateAddActionCallback(menu); const auto over = OverEmoji{ section, index }; const auto emoji = lookupOverEmoji(&over); - const auto custom = lookupCustomEmoji(index, section); + const auto custom = lookupCustomEmoji(&over); if (custom && custom->sticker()) { const auto sticker = custom->sticker(); const auto emoji = sticker->alt; @@ -1492,6 +1506,11 @@ bool EmojiListWidget::checkPickerHide() { return false; } +DocumentData *EmojiListWidget::lookupCustomEmoji( + const OverEmoji *over) const { + return over ? lookupCustomEmoji(over->index, over->section) : nullptr; +} + DocumentData *EmojiListWidget::lookupCustomEmoji( int index, int section) const { @@ -1594,13 +1613,19 @@ void EmojiListWidget::mousePressEvent(QMouseEvent *e) { if (!Core::App().settings().hasChosenEmojiVariant(emoji)) { showPicker(); } else { - _showPickerTimer.callOnce(500); + _previewTimer.cancel(); + _showPickerTimer.callOnce(kColorPickerDelay); } + } else if (lookupCustomEmoji(over)) { + _showPickerTimer.cancel(); + _previewTimer.callOnce(QApplication::startDragTime()); } } } void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) { + _previewTimer.cancel(); + auto pressed = _pressed; setPressed(v::null); _lastMousePos = e->globalPos(); @@ -1625,7 +1650,10 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) { _picker->hide(); } - if (v::is_null(_selected) || _selected != pressed) { + if (_previewShown) { + _previewShown = false; + return; + } else if (v::is_null(_selected) || _selected != pressed) { return; } @@ -1644,7 +1672,7 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) { return; } selectEmoji(lookupChosen(emoji, over)); - } else if (const auto custom = lookupCustomEmoji(index, section)) { + } else if (const auto custom = lookupCustomEmoji(over)) { selectCustom(lookupChosen(custom, over)); } } else if (const auto set = std::get_if(&pressed)) { @@ -2478,7 +2506,9 @@ bool EmojiListWidget::eventHook(QEvent *e) { void EmojiListWidget::updateSelected() { if (!v::is_null(_pressed) || !v::is_null(_pickerSelected)) { - return; + if (!_previewShown) { + return; + } } auto newSelected = OverState{ v::null }; @@ -2537,6 +2567,13 @@ void EmojiListWidget::setSelected(OverState newSelected) { } else { _picker->showAnimated(); } + } else if (_previewShown && _pressed != _selected) { + if (const auto over = std::get_if(&_selected)) { + if (const auto custom = lookupCustomEmoji(over)) { + _pressed = _selected; + _show->showMediaPreview(custom->stickerSetOrigin(), custom); + } + } } } diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h index 0f1c897a639aa9..d3fba5c7235a91 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h @@ -287,6 +287,8 @@ class EmojiListWidget final int index); [[nodiscard]] EmojiPtr lookupOverEmoji(const OverEmoji *over) const; + [[nodiscard]] DocumentData *lookupCustomEmoji( + const OverEmoji *over) const; [[nodiscard]] DocumentData *lookupCustomEmoji( int index, int section) const; @@ -371,6 +373,8 @@ class EmojiListWidget final DocumentId documentId, uint64 setId); + void showPreview(); + void applyNextSearchQuery(); const std::shared_ptr _show; @@ -440,6 +444,8 @@ class EmojiListWidget final object_ptr _picker; base::Timer _showPickerTimer; + base::Timer _previewTimer; + bool _previewShown = false; rpl::event_stream _chosen; rpl::event_stream _customChosen;