feat: use Taptic Engine & preview media on force click

This commit is contained in:
AlexeyZavar 2024-08-18 13:39:54 +03:00
parent 95b3df10b2
commit 9dbc9e59e5
19 changed files with 208 additions and 15 deletions

View file

@ -114,6 +114,12 @@ set(ayugram_files
ayu/utils/telegram_helpers.h ayu/utils/telegram_helpers.h
ayu/utils/windows_utils.cpp ayu/utils/windows_utils.cpp
ayu/utils/windows_utils.h 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.cpp
ayu/ui/ayu_logo.h ayu/ui/ayu_logo.h
ayu/ui/utils/ayu_profile_values.cpp ayu/ui/utils/ayu_profile_values.cpp

View file

@ -6,12 +6,13 @@
// Copyright @Radolyn, 2024 // Copyright @Radolyn, 2024
#include "ayu_infra.h" #include "ayu_infra.h"
#include "ayu_lang.h" #include "ayu/ayu_lang.h"
#include "ayu_worker.h" #include "ayu/ayu_worker.h"
#include "ayu/ayu_fonts.h" #include "ayu/ayu_fonts.h"
#include "ayu/ayu_settings.h" #include "ayu/ayu_settings.h"
#include "ayu/data/ayu_database.h" #include "ayu/data/ayu_database.h"
#include "lang/lang_instance.h" #include "lang/lang_instance.h"
#include "utils/taptic_engine/taptic_engine.h"
namespace AyuInfra { namespace AyuInfra {
@ -45,6 +46,8 @@ void init() {
initDatabase(); initDatabase();
initFonts(); initFonts();
initWorker(); initWorker();
TapticEngine::init();
} }
} }

View file

@ -227,7 +227,7 @@ AyuGramSettings::AyuGramSettings() {
// ~ Customization // ~ Customization
appIcon = appIcon =
#ifdef Q_OS_DARWIN #ifdef Q_OS_MAC
AyuAssets::DEFAULT_MACOS_ICON AyuAssets::DEFAULT_MACOS_ICON
#else #else
AyuAssets::DEFAULT_ICON AyuAssets::DEFAULT_ICON

View file

@ -34,7 +34,7 @@ void loadIcons() {
if (LAST_LOADED_NAME != settings->appIcon) { if (LAST_LOADED_NAME != settings->appIcon) {
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)); LAST_LOADED = QImage(qsl(":/gui/art/ayu/%1/app_macos.png").arg(settings->appIcon));
#else #else
LAST_LOADED = QImage(qsl(":/gui/art/ayu/%1/app.png").arg(settings->appIcon)); LAST_LOADED = QImage(qsl(":/gui/art/ayu/%1/app.png").arg(settings->appIcon));

View file

@ -170,7 +170,6 @@ private:
QString _chosen; QString _chosen;
QStringList _query; QStringList _query;
bool _areOfficial = false;
bool _mouseSelection = false; bool _mouseSelection = false;
QPoint _globalMousePosition; QPoint _globalMousePosition;

View file

@ -34,7 +34,7 @@
namespace AyuUi { namespace AyuUi {
bool needToShowItem(int state) { bool needToShowItem(int state) {
return state == 1 || state == 2 && base::IsExtendedContextMenuModifierPressed(); return state == 1 || (state == 2 && base::IsExtendedContextMenuModifierPressed());
} }
void AddHistoryAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item) { void AddHistoryAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item) {
@ -120,7 +120,7 @@ void AddMessageDetailsAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item) {
if (!containsSingleCustomEmojiPack && emojiPacks.size() > 1) { if (!containsSingleCustomEmojiPack && emojiPacks.size() > 1) {
const auto author = emojiPacks.front().id >> 32; const auto author = emojiPacks.front().id >> 32;
auto sameAuthor = true; auto sameAuthor = true;
for (const auto pack : emojiPacks) { for (const auto &pack : emojiPacks) {
if (pack.id >> 32 != author) { if (pack.id >> 32 != author) {
sameAuthor = false; sameAuthor = false;
break; break;

View file

@ -21,7 +21,7 @@
#endif #endif
const QVector<QString> icons{ const QVector<QString> icons{
#ifdef Q_OS_DARWIN #ifdef Q_OS_MAC
AyuAssets::DEFAULT_MACOS_ICON, AyuAssets::DEFAULT_MACOS_ICON,
#endif #endif
AyuAssets::DEFAULT_ICON, AyuAssets::DEFAULT_ICON,

View file

@ -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

View file

@ -0,0 +1,12 @@
#pragma once
namespace TapticEngine {
namespace Impl {
void init();
void generateGeneric();
void generateAlignment();
void generateLevelChange();
}
}

View file

@ -0,0 +1,12 @@
#pragma once
namespace TapticEngine {
namespace Impl {
void init();
void generateGeneric();
void generateAlignment();
void generateLevelChange();
}
}

View file

@ -0,0 +1,41 @@
#include "taptic_engine_mac.h"
#ifdef Q_OS_MAC
#import <AppKit/AppKit.h>
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

View file

@ -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();
}
}

View file

@ -0,0 +1,11 @@
#pragma once
namespace TapticEngine {
void init();
void generateGeneric();
void generateAlignment();
void generateLevelChange();
// void deinit();
}

View file

@ -93,6 +93,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
// AyuGram includes // AyuGram includes
#include "ayu/ayu_settings.h" #include "ayu/ayu_settings.h"
#include "ayu/utils/taptic_engine/taptic_engine.h"
namespace Dialogs { namespace Dialogs {
@ -1025,6 +1026,7 @@ void Widget::setupStories() {
storiesToggleExplicitExpand(true); storiesToggleExplicitExpand(true);
_scroll->setOverscrollDefaults(0, 0); _scroll->setOverscrollDefaults(0, 0);
} else { } else {
TapticEngine::generateLevelChange();
_scroll->setOverscrollDefaults( _scroll->setOverscrollDefaults(
-st::dialogsStoriesFull.height, -st::dialogsStoriesFull.height,
0); 0);

View file

@ -99,6 +99,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
// AyuGram includes // AyuGram includes
#include "ayu/ui/context_menu/context_menu.h" #include "ayu/ui/context_menu/context_menu.h"
#include "ayu/utils/telegram_helpers.h" #include "ayu/utils/telegram_helpers.h"
#include "data/data_document_media.h"
namespace { namespace {
@ -488,6 +489,51 @@ HistoryInner::HistoryInner(
_scroll->scrollToY(_scroll->scrollTop() + d); _scroll->scrollToY(_scroll->scrollTop() + d);
}, _scroll->lifetime()); }, _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(); setupSharingDisallowed();
} }
@ -1976,6 +2022,11 @@ void HistoryInner::mouseActionFinish(
} }
void HistoryInner::mouseReleaseEvent(QMouseEvent *e) { void HistoryInner::mouseReleaseEvent(QMouseEvent *e) {
if (_wasForceClickPreview) {
_wasForceClickPreview = false;
return;
}
mouseActionFinish(e->globalPos(), e->button()); mouseActionFinish(e->globalPos(), e->button());
if (!rect().contains(e->pos())) { if (!rect().contains(e->pos())) {
leaveEvent(e); leaveEvent(e);

View file

@ -538,4 +538,6 @@ private:
int _scrollDateLastItemTop = 0; int _scrollDateLastItemTop = 0;
ClickHandlerPtr _scrollDateLink; ClickHandlerPtr _scrollDateLink;
bool _wasForceClickPreview = false;
}; };

View file

@ -464,14 +464,7 @@ void Step::paintCover(QPainter &p, int top) {
st::introCoverLeft.paint(p, left, coverHeight - st::introCoverLeft.height(), width()); st::introCoverLeft.paint(p, left, coverHeight - st::introCoverLeft.height(), width());
st::introCoverRight.paint(p, width() - right - st::introCoverRight.width(), coverHeight - st::introCoverRight.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; 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()); const auto ayuGramIcon = Ui::PixmapFromImage(AyuAssets::currentAppLogo());
QIcon(ayuGramIcon).paint(&p, QRect(width() / 2 - ayuGramIcon.width() / 2, planeTop - 16, ayuGramIcon.width(), st::introCoverIcon.height())); QIcon(ayuGramIcon).paint(&p, QRect(width() / 2 - ayuGramIcon.width() / 2, planeTop - 16, ayuGramIcon.width(), st::introCoverIcon.height()));
} }

View file

@ -17,6 +17,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/random.h" #include "base/random.h"
#include "styles/style_chat.h" #include "styles/style_chat.h"
// AyuGram includes
#include "ayu/utils/taptic_engine/taptic_engine.h"
namespace Ui { namespace Ui {
namespace { namespace {
@ -55,6 +59,11 @@ auto ReactionFlyAnimation::callback() {
return [=] { return [=] {
if (_repaint) { if (_repaint) {
_repaint(); _repaint();
if (_minis.animating() && !_hapticExecuted) {
TapticEngine::generateGeneric();
_hapticExecuted = true;
}
} }
}; };
} }

View file

@ -127,6 +127,8 @@ private:
bool _effectOnly = false; bool _effectOnly = false;
bool _valid = false; bool _valid = false;
bool _hapticExecuted = false;
mutable Parabolic _cached; mutable Parabolic _cached;
}; };