From 9dbc9e59e5219ff22c93617b57a895957e68e53c Mon Sep 17 00:00:00 2001 From: AlexeyZavar Date: Sun, 18 Aug 2024 13:39:54 +0300 Subject: [PATCH] feat: use Taptic Engine & preview media on force click --- Telegram/CMakeLists.txt | 6 +++ Telegram/SourceFiles/ayu/ayu_infra.cpp | 7 ++- Telegram/SourceFiles/ayu/ayu_settings.cpp | 2 +- Telegram/SourceFiles/ayu/ui/ayu_logo.cpp | 2 +- .../ayu/ui/boxes/font_selector.cpp | 1 - .../ayu/ui/context_menu/context_menu.cpp | 4 +- .../ayu/ui/settings/icon_picker.cpp | 2 +- .../platform/taptic_engine_dummy.cpp | 23 +++++++++ .../platform/taptic_engine_dummy.h | 12 +++++ .../platform/taptic_engine_mac.h | 12 +++++ .../platform/taptic_engine_mac.mm | 41 +++++++++++++++ .../ayu/utils/taptic_engine/taptic_engine.cpp | 27 ++++++++++ .../ayu/utils/taptic_engine/taptic_engine.h | 11 ++++ .../SourceFiles/dialogs/dialogs_widget.cpp | 2 + .../history/history_inner_widget.cpp | 51 +++++++++++++++++++ .../history/history_inner_widget.h | 2 + Telegram/SourceFiles/intro/intro_step.cpp | 7 --- .../ui/effects/reaction_fly_animation.cpp | 9 ++++ .../ui/effects/reaction_fly_animation.h | 2 + 19 files changed, 208 insertions(+), 15 deletions(-) create mode 100644 Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.cpp create mode 100644 Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.h create mode 100644 Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.h create mode 100644 Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.mm create mode 100644 Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.cpp create mode 100644 Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 178c021f0..01156117d 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -114,6 +114,12 @@ set(ayugram_files ayu/utils/telegram_helpers.h ayu/utils/windows_utils.cpp ayu/utils/windows_utils.h + ayu/utils/taptic_engine/taptic_engine.cpp + ayu/utils/taptic_engine/taptic_engine.h + ayu/utils/taptic_engine/platform/taptic_engine_dummy.cpp + ayu/utils/taptic_engine/platform/taptic_engine_dummy.h + ayu/utils/taptic_engine/platform/taptic_engine_mac.mm + ayu/utils/taptic_engine/platform/taptic_engine_mac.h ayu/ui/ayu_logo.cpp ayu/ui/ayu_logo.h ayu/ui/utils/ayu_profile_values.cpp diff --git a/Telegram/SourceFiles/ayu/ayu_infra.cpp b/Telegram/SourceFiles/ayu/ayu_infra.cpp index 03bf98792..cb92fc822 100644 --- a/Telegram/SourceFiles/ayu/ayu_infra.cpp +++ b/Telegram/SourceFiles/ayu/ayu_infra.cpp @@ -6,12 +6,13 @@ // Copyright @Radolyn, 2024 #include "ayu_infra.h" -#include "ayu_lang.h" -#include "ayu_worker.h" +#include "ayu/ayu_lang.h" +#include "ayu/ayu_worker.h" #include "ayu/ayu_fonts.h" #include "ayu/ayu_settings.h" #include "ayu/data/ayu_database.h" #include "lang/lang_instance.h" +#include "utils/taptic_engine/taptic_engine.h" namespace AyuInfra { @@ -45,6 +46,8 @@ void init() { initDatabase(); initFonts(); initWorker(); + + TapticEngine::init(); } } diff --git a/Telegram/SourceFiles/ayu/ayu_settings.cpp b/Telegram/SourceFiles/ayu/ayu_settings.cpp index b3837ec90..a40a2de83 100644 --- a/Telegram/SourceFiles/ayu/ayu_settings.cpp +++ b/Telegram/SourceFiles/ayu/ayu_settings.cpp @@ -227,7 +227,7 @@ AyuGramSettings::AyuGramSettings() { // ~ Customization appIcon = -#ifdef Q_OS_DARWIN +#ifdef Q_OS_MAC AyuAssets::DEFAULT_MACOS_ICON #else AyuAssets::DEFAULT_ICON diff --git a/Telegram/SourceFiles/ayu/ui/ayu_logo.cpp b/Telegram/SourceFiles/ayu/ui/ayu_logo.cpp index a84e0e1d7..1a51940aa 100644 --- a/Telegram/SourceFiles/ayu/ui/ayu_logo.cpp +++ b/Telegram/SourceFiles/ayu/ui/ayu_logo.cpp @@ -34,7 +34,7 @@ void loadIcons() { if (LAST_LOADED_NAME != settings->appIcon) { LAST_LOADED_NAME = settings->appIcon; -#ifdef Q_OS_DARWIN +#ifdef Q_OS_MAC LAST_LOADED = QImage(qsl(":/gui/art/ayu/%1/app_macos.png").arg(settings->appIcon)); #else LAST_LOADED = QImage(qsl(":/gui/art/ayu/%1/app.png").arg(settings->appIcon)); diff --git a/Telegram/SourceFiles/ayu/ui/boxes/font_selector.cpp b/Telegram/SourceFiles/ayu/ui/boxes/font_selector.cpp index d9e5eae32..735d66eae 100644 --- a/Telegram/SourceFiles/ayu/ui/boxes/font_selector.cpp +++ b/Telegram/SourceFiles/ayu/ui/boxes/font_selector.cpp @@ -170,7 +170,6 @@ private: QString _chosen; QStringList _query; - bool _areOfficial = false; bool _mouseSelection = false; QPoint _globalMousePosition; diff --git a/Telegram/SourceFiles/ayu/ui/context_menu/context_menu.cpp b/Telegram/SourceFiles/ayu/ui/context_menu/context_menu.cpp index 3351662ac..1ce4281c3 100644 --- a/Telegram/SourceFiles/ayu/ui/context_menu/context_menu.cpp +++ b/Telegram/SourceFiles/ayu/ui/context_menu/context_menu.cpp @@ -34,7 +34,7 @@ namespace AyuUi { bool needToShowItem(int state) { - return state == 1 || state == 2 && base::IsExtendedContextMenuModifierPressed(); + return state == 1 || (state == 2 && base::IsExtendedContextMenuModifierPressed()); } void AddHistoryAction(not_null menu, HistoryItem *item) { @@ -120,7 +120,7 @@ void AddMessageDetailsAction(not_null menu, HistoryItem *item) { if (!containsSingleCustomEmojiPack && emojiPacks.size() > 1) { const auto author = emojiPacks.front().id >> 32; auto sameAuthor = true; - for (const auto pack : emojiPacks) { + for (const auto &pack : emojiPacks) { if (pack.id >> 32 != author) { sameAuthor = false; break; diff --git a/Telegram/SourceFiles/ayu/ui/settings/icon_picker.cpp b/Telegram/SourceFiles/ayu/ui/settings/icon_picker.cpp index 8e5b566fa..6e2a2fc3f 100644 --- a/Telegram/SourceFiles/ayu/ui/settings/icon_picker.cpp +++ b/Telegram/SourceFiles/ayu/ui/settings/icon_picker.cpp @@ -21,7 +21,7 @@ #endif const QVector icons{ -#ifdef Q_OS_DARWIN +#ifdef Q_OS_MAC AyuAssets::DEFAULT_MACOS_ICON, #endif AyuAssets::DEFAULT_ICON, diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.cpp b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.cpp new file mode 100644 index 000000000..ee486e70b --- /dev/null +++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.cpp @@ -0,0 +1,23 @@ +#include "taptic_engine_dummy.h" + +#ifndef Q_OS_MAC + +namespace TapticEngine { +namespace Impl { + +void init() { +} + +void generateGeneric() { +} + +void generateAlignment() { +} + +void generateLevelChange() { +} + +} +} + +#endif diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.h b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.h new file mode 100644 index 000000000..d2a78b2a5 --- /dev/null +++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_dummy.h @@ -0,0 +1,12 @@ +#pragma once + +namespace TapticEngine { +namespace Impl { + +void init(); +void generateGeneric(); +void generateAlignment(); +void generateLevelChange(); + +} +} diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.h b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.h new file mode 100644 index 000000000..d2a78b2a5 --- /dev/null +++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.h @@ -0,0 +1,12 @@ +#pragma once + +namespace TapticEngine { +namespace Impl { + +void init(); +void generateGeneric(); +void generateAlignment(); +void generateLevelChange(); + +} +} diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.mm b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.mm new file mode 100644 index 000000000..f0c390d34 --- /dev/null +++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/platform/taptic_engine_mac.mm @@ -0,0 +1,41 @@ +#include "taptic_engine_mac.h" + +#ifdef Q_OS_MAC + +#import + +namespace TapticEngine { +namespace Impl { + +NSHapticFeedbackManager *hapticFeedbackManager = nil; + +void init() { + if (@available(macOS 10.11, *)) { + hapticFeedbackManager = [NSHapticFeedbackManager defaultPerformer]; + } +} + +void performHapticFeedback(NSHapticFeedbackPattern pattern) { + if (@available(macOS 10.11, *)) { + if (hapticFeedbackManager) { + [hapticFeedbackManager performFeedbackPattern:pattern performanceTime:NSHapticFeedbackPerformanceTimeNow]; + } + } +} + +void generateGeneric() { + performHapticFeedback(NSHapticFeedbackPatternGeneric); +} + +void generateAlignment() { + performHapticFeedback(NSHapticFeedbackPatternAlignment); +} + +void generateLevelChange() { + performHapticFeedback(NSHapticFeedbackPatternLevelChange); +} + +} +} + +#endif diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.cpp b/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.cpp new file mode 100644 index 000000000..7d4865413 --- /dev/null +++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.cpp @@ -0,0 +1,27 @@ +#include "taptic_engine.h" + +#if defined Q_OS_MAC +#include "ayu/utils/taptic_engine/platform/taptic_engine_mac.h" +#else +#include "ayu/utils/taptic_engine/platform/taptic_engine_dummy.h" +#endif + +namespace TapticEngine { + +void init() { + Impl::init(); +} + +void generateGeneric() { + Impl::generateGeneric(); +} + +void generateAlignment() { + Impl::generateAlignment(); +} + +void generateLevelChange() { + Impl::generateLevelChange(); +} + +} diff --git a/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.h b/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.h new file mode 100644 index 000000000..2534f550a --- /dev/null +++ b/Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.h @@ -0,0 +1,11 @@ +#pragma once + +namespace TapticEngine { + +void init(); +void generateGeneric(); +void generateAlignment(); +void generateLevelChange(); +// void deinit(); + +} diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 41a9ddd8d..b9522136f 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -93,6 +93,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL // AyuGram includes #include "ayu/ayu_settings.h" +#include "ayu/utils/taptic_engine/taptic_engine.h" namespace Dialogs { @@ -1025,6 +1026,7 @@ void Widget::setupStories() { storiesToggleExplicitExpand(true); _scroll->setOverscrollDefaults(0, 0); } else { + TapticEngine::generateLevelChange(); _scroll->setOverscrollDefaults( -st::dialogsStoriesFull.height, 0); diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index e77526572..217da94bb 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -99,6 +99,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL // AyuGram includes #include "ayu/ui/context_menu/context_menu.h" #include "ayu/utils/telegram_helpers.h" +#include "data/data_document_media.h" namespace { @@ -488,6 +489,51 @@ HistoryInner::HistoryInner( _scroll->scrollToY(_scroll->scrollTop() + d); }, _scroll->lifetime()); + _controller->window().widget()->globalForceClicks() | + rpl::start_with_next( + [=](QPoint globalPosition) + { + auto mousePos = mapFromGlobal(globalPosition); + auto point = _widget->clampMousePosition(mousePos); + + if (!inSelectionMode() && !_emptyPainter && rect().contains(mousePos)) { + if (const auto view = Element::Moused()) { + mouseActionCancel(); + + const auto m = mapPointToItem(point, view); + const auto inside = view->pointState(m) != PointState::Outside; + const auto media = view->data()->media(); + if (inside && media) { + if (const auto preview = media->document()) { + if (!preview->sticker()) { + if (const auto mediaView = preview->activeMediaView()) { + const auto previewState = Data::VideoPreviewState(mediaView.get()); + if (!previewState.loaded()) { + preview->loadVideoThumbnail(view->data()->fullId()); + preview->loadThumbnail(view->data()->fullId()); + return; + } + } + } + + _wasForceClickPreview = _controller->uiShow()->showMediaPreview( + preview->sticker() ? preview->stickerSetOrigin() : view->data()->fullId(), preview); + } else if (const auto previewPhoto = media->photo()) { + _wasForceClickPreview = + _controller->uiShow()->showMediaPreview(Data::FileOrigin(), previewPhoto); + } + + if (!_wasForceClickPreview) { + toggleFavoriteReaction(view); + } + } else { + toggleFavoriteReaction(view); + } + } + } + }, + lifetime()); + setupSharingDisallowed(); } @@ -1976,6 +2022,11 @@ void HistoryInner::mouseActionFinish( } void HistoryInner::mouseReleaseEvent(QMouseEvent *e) { + if (_wasForceClickPreview) { + _wasForceClickPreview = false; + return; + } + mouseActionFinish(e->globalPos(), e->button()); if (!rect().contains(e->pos())) { leaveEvent(e); diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index 5a11b2944..5edc1b61d 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -538,4 +538,6 @@ private: int _scrollDateLastItemTop = 0; ClickHandlerPtr _scrollDateLink; + bool _wasForceClickPreview = false; + }; diff --git a/Telegram/SourceFiles/intro/intro_step.cpp b/Telegram/SourceFiles/intro/intro_step.cpp index 5dfae5a65..da76463e3 100644 --- a/Telegram/SourceFiles/intro/intro_step.cpp +++ b/Telegram/SourceFiles/intro/intro_step.cpp @@ -464,14 +464,7 @@ void Step::paintCover(QPainter &p, int top) { st::introCoverLeft.paint(p, left, coverHeight - st::introCoverLeft.height(), width()); st::introCoverRight.paint(p, width() - right - st::introCoverRight.width(), coverHeight - st::introCoverRight.height(), width()); - auto planeLeft = (width() - st::introCoverIcon.width()) / 2 - st::introCoverIconLeft; auto planeTop = top + st::introCoverIconTop; - if (top < 0 && !_hasCover) { - auto deltaLeft = -qRound(float64(st::introPlaneWidth / st::introPlaneHeight) * top); -// auto deltaTop = top; - planeLeft += deltaLeft; - // planeTop += top; - } const auto ayuGramIcon = Ui::PixmapFromImage(AyuAssets::currentAppLogo()); QIcon(ayuGramIcon).paint(&p, QRect(width() / 2 - ayuGramIcon.width() / 2, planeTop - 16, ayuGramIcon.width(), st::introCoverIcon.height())); } diff --git a/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp b/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp index a193bf32d..3fcabe3eb 100644 --- a/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp +++ b/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp @@ -17,6 +17,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/random.h" #include "styles/style_chat.h" +// AyuGram includes +#include "ayu/utils/taptic_engine/taptic_engine.h" + + namespace Ui { namespace { @@ -55,6 +59,11 @@ auto ReactionFlyAnimation::callback() { return [=] { if (_repaint) { _repaint(); + + if (_minis.animating() && !_hapticExecuted) { + TapticEngine::generateGeneric(); + _hapticExecuted = true; + } } }; } diff --git a/Telegram/SourceFiles/ui/effects/reaction_fly_animation.h b/Telegram/SourceFiles/ui/effects/reaction_fly_animation.h index 0ea353f3b..48e8f0688 100644 --- a/Telegram/SourceFiles/ui/effects/reaction_fly_animation.h +++ b/Telegram/SourceFiles/ui/effects/reaction_fly_animation.h @@ -127,6 +127,8 @@ private: bool _effectOnly = false; bool _valid = false; + bool _hapticExecuted = false; + mutable Parabolic _cached; };