diff --git a/interface/app/$libraryId/Explorer/QuickPreview/index.tsx b/interface/app/$libraryId/Explorer/QuickPreview/index.tsx
index 7527d1ac6..8de1afc4b 100644
--- a/interface/app/$libraryId/Explorer/QuickPreview/index.tsx
+++ b/interface/app/$libraryId/Explorer/QuickPreview/index.tsx
@@ -93,6 +93,9 @@ export const QuickPreview = () => {
const [thumbnailLoading, setThumbnailLoading] = useState<'notLoaded' | 'loaded' | 'error'>(
'notLoaded'
);
+ // the purpose of these refs is to prevent "jittering" when zooming with trackpads, as the deltaY value can be very high
+ const deltaYRef = useRef(0);
+ const lastZoomTimeRef = useRef(0);
const { t } = useLocale();
@@ -198,6 +201,55 @@ export const QuickPreview = () => {
getQuickPreviewStore().itemIndex = 0;
};
+ const handleZoomIn = useCallback(() => {
+ setMagnification((currentMagnification) =>
+ currentMagnification < 2
+ ? currentMagnification + currentMagnification * 0.1
+ : currentMagnification
+ );
+ }, []);
+
+ const handleZoomOut = useCallback(() => {
+ setMagnification((currentMagnification) =>
+ currentMagnification > 0.5 ? currentMagnification / (1 + 0.1) : currentMagnification
+ );
+ }, []);
+
+ // pinch support for trackpads
+ const applyZoom = useCallback(() => {
+ if (deltaYRef.current < 0) {
+ handleZoomIn();
+ } else if (deltaYRef.current > 0) {
+ handleZoomOut();
+ }
+ deltaYRef.current = 0;
+ }, [handleZoomIn, handleZoomOut]);
+
+ const handleWheel = useCallback(
+ (event: WheelEvent) => {
+ if (event.ctrlKey) {
+ event.preventDefault();
+ deltaYRef.current += event.deltaY;
+ const now = Date.now();
+ if (now - lastZoomTimeRef.current > 50) {
+ applyZoom();
+ lastZoomTimeRef.current = now;
+ }
+ }
+ },
+ [applyZoom]
+ );
+
+ useEffect(() => {
+ window.addEventListener('wheel', handleWheel, { passive: false });
+ return () => {
+ window.removeEventListener('wheel', handleWheel);
+ };
+ }, [handleWheel]);
+
+ useShortcut('zoomIn', handleZoomIn);
+ useShortcut('zoomOut', handleZoomOut);
+
useShortcut('quickPreviewMoveBack', () => {
if (isContextMenuOpen || isRenaming) return;
handleMoveBetweenItems(-1);
@@ -455,14 +507,7 @@ export const QuickPreview = () => {
{
- magnification < 2 &&
- setMagnification(
- (currentMagnification) =>
- currentMagnification +
- currentMagnification * 0.2
- );
- }}
+ onClick={handleZoomIn}
// this is same formula as interest calculation
>
@@ -471,13 +516,7 @@ export const QuickPreview = () => {
{
- magnification > 0.5 &&
- setMagnification(
- (currentMagnification) =>
- currentMagnification / (1 + 0.2)
- );
- }}
+ onClick={handleZoomOut}
// this is same formula as interest calculation
>
diff --git a/interface/hooks/useShortcut.ts b/interface/hooks/useShortcut.ts
index 1bd51fd90..76a3f7194 100644
--- a/interface/hooks/useShortcut.ts
+++ b/interface/hooks/useShortcut.ts
@@ -155,6 +155,14 @@ const shortcuts = {
toggleSidebar: {
all: ['Control', 'KeyS'],
macOS: ['Meta', 'KeyS']
+ },
+ zoomIn: {
+ macOS: ['Meta', '='],
+ all: ['Control', '=']
+ },
+ zoomOut: {
+ macOS: ['Meta', '-'],
+ all: ['Control', '-']
}
} satisfies Record;
diff --git a/patches/@oscartbeaumont-sd__rspc-tauri@0.0.0-main-dc31e5b2.patch b/patches/@oscartbeaumont-sd__rspc-tauri@0.0.0-main-dc31e5b2.patch
index ce63311a2..b21e28f95 100644
--- a/patches/@oscartbeaumont-sd__rspc-tauri@0.0.0-main-dc31e5b2.patch
+++ b/patches/@oscartbeaumont-sd__rspc-tauri@0.0.0-main-dc31e5b2.patch
@@ -7,7 +7,7 @@ index df70b20e9381e7bf44f9a35b11174e40ede80376..bc06927b7290891717c48999f79d0705
// @ts-ignore
this.requestMap.set(id, resolve);
- await window.appWindow.emit("plugin:rspc:transport", {
-+ await window.getCurrent().emit("plugin:rspc:transport", {
++ await window.getCurrentWindow().emit("plugin:rspc:transport", {
id,
method: operation,
params: {
@@ -19,8 +19,8 @@ index a80ac6155a4a920173c442b4d7b458a46ab63624..03b3d9ee6d3691980584c1fd58c17f7c
import { randomId, RSPCError } from '@oscartbeaumont-sd/rspc-client';
import { listen } from '@tauri-apps/api/event';
-import { appWindow } from '@tauri-apps/api/window';
-+import { getCurrent } from '@tauri-apps/api/window';
-
++import { getCurrentWindow } from '@tauri-apps/api/window';
+
// @ts-nocheck No one asked
class TauriTransport {
@@ -15,7 +15,7 @@ class TauriTransport {
@@ -28,7 +28,7 @@ index a80ac6155a4a920173c442b4d7b458a46ab63624..03b3d9ee6d3691980584c1fd58c17f7c
// @ts-ignore
this.requestMap.set(id, resolve);
- await appWindow.emit("plugin:rspc:transport", {
-+ await getCurrent().emit("plugin:rspc:transport", {
++ await getCurrentWindow().emit("plugin:rspc:transport", {
id,
method: operation,
params: {
@@ -41,7 +41,7 @@ index e597db7bf00a7e62f32266814345b257b8f8d0da..fa683640a0c0c9f1796ed1af1fd0d04c
await listener;
}
- await window.appWindow.emit("plugin:rspc:transport", currentBatch);
-+ await window.getCurrent().emit("plugin:rspc:transport", currentBatch);
++ await window.getCurrentWindow().emit("plugin:rspc:transport", currentBatch);
})();
});
}
@@ -53,8 +53,8 @@ index bd7ceb6927d187dd2ff7cf9a9364d7c312a75b88..844495e36aef0c1337e7393685c1a33f
import { AlphaRSPCError } from '@oscartbeaumont-sd/rspc-client/v2';
import { listen } from '@tauri-apps/api/event';
-import { appWindow } from '@tauri-apps/api/window';
-+import { getCurrent } from '@tauri-apps/api/window';
-
++import { getCurrentWindow } from '@tauri-apps/api/window';
+
// @ts-nocheck No one asked
/**
@@ -42,7 +42,7 @@ import { appWindow } from '@tauri-apps/api/window';
@@ -62,7 +62,7 @@ index bd7ceb6927d187dd2ff7cf9a9364d7c312a75b88..844495e36aef0c1337e7393685c1a33f
await listener;
}
- await appWindow.emit("plugin:rspc:transport", currentBatch);
-+ await getCurrent().emit("plugin:rspc:transport", currentBatch);
++ await getCurrentWindow().emit("plugin:rspc:transport", currentBatch);
})();
});
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 014be1add..4ead2ad2c 100644
Binary files a/pnpm-lock.yaml and b/pnpm-lock.yaml differ
diff --git a/scripts/setup.sh b/scripts/setup.sh
index d746d5c24..eb942b4b4 100755
--- a/scripts/setup.sh
+++ b/scripts/setup.sh
@@ -185,7 +185,7 @@ case "$(uname)" in
fi
# Tauri dependencies
- set -- openssl webkit2gtk4.1-devel openssl-dev curl wget file libappindicator-gtk3-devel librsvg2-devel libxdo-devel dbus-devel
+ set -- openssl webkit2gtk4.1-devel openssl-devel curl wget file libappindicator-gtk3-devel librsvg2-devel libxdo-devel dbus-devel
# Webkit2gtk requires gstreamer plugins for video playback to work
set -- "$@" gstreamer1-devel gstreamer1-plugins-base-devel gstreamer1-plugins-good \