mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 21:27:07 +02:00
feat: use Taptic Engine & preview media on force click
This commit is contained in:
parent
95b3df10b2
commit
9dbc9e59e5
19 changed files with 208 additions and 15 deletions
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -227,7 +227,7 @@ AyuGramSettings::AyuGramSettings() {
|
|||
|
||||
// ~ Customization
|
||||
appIcon =
|
||||
#ifdef Q_OS_DARWIN
|
||||
#ifdef Q_OS_MAC
|
||||
AyuAssets::DEFAULT_MACOS_ICON
|
||||
#else
|
||||
AyuAssets::DEFAULT_ICON
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -170,7 +170,6 @@ private:
|
|||
QString _chosen;
|
||||
QStringList _query;
|
||||
|
||||
bool _areOfficial = false;
|
||||
bool _mouseSelection = false;
|
||||
QPoint _globalMousePosition;
|
||||
|
||||
|
|
|
@ -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<Ui::PopupMenu*> menu, HistoryItem *item) {
|
||||
|
@ -120,7 +120,7 @@ void AddMessageDetailsAction(not_null<Ui::PopupMenu*> 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;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#endif
|
||||
|
||||
const QVector<QString> icons{
|
||||
#ifdef Q_OS_DARWIN
|
||||
#ifdef Q_OS_MAC
|
||||
AyuAssets::DEFAULT_MACOS_ICON,
|
||||
#endif
|
||||
AyuAssets::DEFAULT_ICON,
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
namespace TapticEngine {
|
||||
namespace Impl {
|
||||
|
||||
void init();
|
||||
void generateGeneric();
|
||||
void generateAlignment();
|
||||
void generateLevelChange();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
namespace TapticEngine {
|
||||
namespace Impl {
|
||||
|
||||
void init();
|
||||
void generateGeneric();
|
||||
void generateAlignment();
|
||||
void generateLevelChange();
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
11
Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.h
Normal file
11
Telegram/SourceFiles/ayu/utils/taptic_engine/taptic_engine.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
namespace TapticEngine {
|
||||
|
||||
void init();
|
||||
void generateGeneric();
|
||||
void generateAlignment();
|
||||
void generateLevelChange();
|
||||
// void deinit();
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -538,4 +538,6 @@ private:
|
|||
int _scrollDateLastItemTop = 0;
|
||||
ClickHandlerPtr _scrollDateLink;
|
||||
|
||||
bool _wasForceClickPreview = false;
|
||||
|
||||
};
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -127,6 +127,8 @@ private:
|
|||
bool _effectOnly = false;
|
||||
bool _valid = false;
|
||||
|
||||
bool _hapticExecuted = false;
|
||||
|
||||
mutable Parabolic _cached;
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue