This commit is contained in:
@@ -36,6 +36,7 @@ import { getBookDirFromLanguage, getBookDirFromWritingMode } from '@/utils/book'
|
||||
import { useUICSS } from '@/hooks/useUICSS';
|
||||
import {
|
||||
handleKeydown,
|
||||
handleKeyup,
|
||||
handleMousedown,
|
||||
handleMouseup,
|
||||
handleClick,
|
||||
@@ -224,6 +225,7 @@ const FoliateViewer: React.FC<{
|
||||
// and more gesture events can be detected in the iframeEventHandlers
|
||||
detail.doc.isEventListenersAdded = true;
|
||||
detail.doc.addEventListener('keydown', handleKeydown.bind(null, bookKey));
|
||||
detail.doc.addEventListener('keyup', handleKeyup.bind(null, bookKey));
|
||||
detail.doc.addEventListener('mousedown', handleMousedown.bind(null, bookKey));
|
||||
detail.doc.addEventListener('mouseup', handleMouseup.bind(null, bookKey));
|
||||
detail.doc.addEventListener('click', handleClick.bind(null, bookKey, doubleClickDisabled));
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useReaderStore } from '@/store/readerStore';
|
||||
import { useNotebookStore } from '@/store/notebookStore';
|
||||
import { isTauriAppPlatform } from '@/services/environment';
|
||||
@@ -171,20 +172,38 @@ const useBookShortcuts = ({ sideBarBookKey, bookKeys }: UseBookShortcutsProps) =
|
||||
}
|
||||
};
|
||||
|
||||
const zoomIn = () => {
|
||||
const zoomInFactor = (factor = 1.0) => {
|
||||
if (!sideBarBookKey) return;
|
||||
const viewSettings = getViewSettings(sideBarBookKey)!;
|
||||
const zoomLevel = viewSettings!.zoomLevel + ZOOM_STEP;
|
||||
const zoomLevel = viewSettings!.zoomLevel + ZOOM_STEP * factor;
|
||||
applyZoomLevel(Math.min(zoomLevel, MAX_ZOOM_LEVEL));
|
||||
};
|
||||
|
||||
const zoomOut = () => {
|
||||
const zoomOutFactor = (factor = 1.0) => {
|
||||
if (!sideBarBookKey) return;
|
||||
const viewSettings = getViewSettings(sideBarBookKey)!;
|
||||
const zoomLevel = viewSettings!.zoomLevel - ZOOM_STEP;
|
||||
const zoomLevel = viewSettings!.zoomLevel - ZOOM_STEP * factor;
|
||||
applyZoomLevel(Math.max(zoomLevel, MIN_ZOOM_LEVEL));
|
||||
};
|
||||
|
||||
const zoomIn = () => {
|
||||
zoomInFactor();
|
||||
};
|
||||
|
||||
const zoomOut = () => {
|
||||
zoomOutFactor();
|
||||
};
|
||||
|
||||
const handleZoomIn = (event: CustomEvent) => {
|
||||
const factor = event.detail?.factor || 1.0;
|
||||
zoomInFactor(factor);
|
||||
};
|
||||
|
||||
const handleZoomOut = (event: CustomEvent) => {
|
||||
const factor = event.detail?.factor || 1.0;
|
||||
zoomOutFactor(factor);
|
||||
};
|
||||
|
||||
const resetZoom = () => {
|
||||
if (!sideBarBookKey) return;
|
||||
applyZoomLevel(100);
|
||||
@@ -202,6 +221,18 @@ const useBookShortcuts = ({ sideBarBookKey, bookKeys }: UseBookShortcutsProps) =
|
||||
eventDispatcher.dispatch('toggle-bookmark', { bookKey: sideBarBookKey });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
eventDispatcher.on('zoom-in', handleZoomIn);
|
||||
eventDispatcher.on('zoom-out', handleZoomOut);
|
||||
eventDispatcher.on('reset-zoom', resetZoom);
|
||||
return () => {
|
||||
eventDispatcher.off('zoom-in', handleZoomIn);
|
||||
eventDispatcher.off('zoom-out', handleZoomOut);
|
||||
eventDispatcher.off('reset-zoom', resetZoom);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [sideBarBookKey]);
|
||||
|
||||
useShortcuts(
|
||||
{
|
||||
onSwitchSideBar: switchSideBar,
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useReaderStore } from '@/store/readerStore';
|
||||
import { useBookDataStore } from '@/store/bookDataStore';
|
||||
import { debounce } from '@/utils/debounce';
|
||||
import { ScrollSource } from './usePagination';
|
||||
import { eventDispatcher } from '@/utils/event';
|
||||
|
||||
export const useMouseEvent = (
|
||||
bookKey: string,
|
||||
@@ -19,7 +20,15 @@ export const useMouseEvent = (
|
||||
debounceScroll('mouse', -msg.data.deltaY, 0);
|
||||
}
|
||||
if (msg.data.type === 'iframe-wheel') {
|
||||
debounceFlip(msg);
|
||||
if (msg.data.ctrlKey) {
|
||||
if (msg.data.deltaY > 0) {
|
||||
eventDispatcher.dispatch('zoom-out', { factor: Math.abs(msg.data.deltaY) / 100 });
|
||||
} else if (msg.data.deltaY < 0) {
|
||||
eventDispatcher.dispatch('zoom-in', { factor: Math.abs(msg.data.deltaY) / 100 });
|
||||
}
|
||||
} else {
|
||||
debounceFlip(msg);
|
||||
}
|
||||
} else {
|
||||
handlePageFlip(msg);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,41 @@ import { eventDispatcher } from '@/utils/event';
|
||||
let lastClickTime = 0;
|
||||
let longHoldTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
let keyboardState = {
|
||||
key: '',
|
||||
code: '',
|
||||
ctrlKey: false,
|
||||
shiftKey: false,
|
||||
altKey: false,
|
||||
metaKey: false,
|
||||
};
|
||||
|
||||
const getKeyStatus = (event?: MouseEvent | WheelEvent | TouchEvent) => {
|
||||
if (event && 'ctrlKey' in event) {
|
||||
return {
|
||||
key: keyboardState.key,
|
||||
code: keyboardState.code,
|
||||
ctrlKey: event.ctrlKey,
|
||||
shiftKey: event.shiftKey,
|
||||
altKey: event.altKey,
|
||||
metaKey: event.metaKey,
|
||||
};
|
||||
}
|
||||
return {
|
||||
...keyboardState,
|
||||
};
|
||||
};
|
||||
|
||||
export const handleKeydown = (bookKey: string, event: KeyboardEvent) => {
|
||||
keyboardState = {
|
||||
key: event.key,
|
||||
code: event.code,
|
||||
ctrlKey: event.ctrlKey,
|
||||
shiftKey: event.shiftKey,
|
||||
altKey: event.altKey,
|
||||
metaKey: event.metaKey,
|
||||
};
|
||||
|
||||
if (['Backspace'].includes(event.key)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
@@ -23,6 +57,31 @@ export const handleKeydown = (bookKey: string, event: KeyboardEvent) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const handleKeyup = (bookKey: string, event: KeyboardEvent) => {
|
||||
keyboardState = {
|
||||
key: '',
|
||||
code: '',
|
||||
ctrlKey: event.ctrlKey,
|
||||
shiftKey: event.shiftKey,
|
||||
altKey: event.altKey,
|
||||
metaKey: event.metaKey,
|
||||
};
|
||||
|
||||
window.postMessage(
|
||||
{
|
||||
type: 'iframe-keyup',
|
||||
bookKey,
|
||||
key: event.key,
|
||||
code: event.code,
|
||||
ctrlKey: event.ctrlKey,
|
||||
shiftKey: event.shiftKey,
|
||||
altKey: event.altKey,
|
||||
metaKey: event.metaKey,
|
||||
},
|
||||
'*',
|
||||
);
|
||||
};
|
||||
|
||||
export const handleMousedown = (bookKey: string, event: MouseEvent) => {
|
||||
longHoldTimeout = setTimeout(() => {
|
||||
longHoldTimeout = null;
|
||||
@@ -39,6 +98,7 @@ export const handleMousedown = (bookKey: string, event: MouseEvent) => {
|
||||
clientY: event.clientY,
|
||||
offsetX: event.offsetX,
|
||||
offsetY: event.offsetY,
|
||||
...getKeyStatus(event),
|
||||
},
|
||||
'*',
|
||||
);
|
||||
@@ -60,6 +120,7 @@ export const handleMouseup = (bookKey: string, event: MouseEvent) => {
|
||||
clientY: event.clientY,
|
||||
offsetX: event.offsetX,
|
||||
offsetY: event.offsetY,
|
||||
...getKeyStatus(event),
|
||||
},
|
||||
'*',
|
||||
);
|
||||
@@ -80,6 +141,7 @@ export const handleWheel = (bookKey: string, event: WheelEvent) => {
|
||||
clientY: event.clientY,
|
||||
offsetX: event.offsetX,
|
||||
offsetY: event.offsetY,
|
||||
...getKeyStatus(event),
|
||||
},
|
||||
'*',
|
||||
);
|
||||
@@ -104,6 +166,7 @@ export const handleClick = (
|
||||
clientY: event.clientY,
|
||||
offsetX: event.offsetX,
|
||||
offsetY: event.offsetY,
|
||||
...getKeyStatus(event),
|
||||
},
|
||||
'*',
|
||||
);
|
||||
@@ -151,6 +214,7 @@ export const handleClick = (
|
||||
clientY: event.clientY,
|
||||
offsetX: event.offsetX,
|
||||
offsetY: event.offsetY,
|
||||
...getKeyStatus(event),
|
||||
},
|
||||
'*',
|
||||
);
|
||||
@@ -183,6 +247,7 @@ const handleTouchEv = (bookKey: string, event: TouchEvent, type: string) => {
|
||||
bookKey,
|
||||
timeStamp: Date.now(),
|
||||
targetTouches: touches,
|
||||
...getKeyStatus(event),
|
||||
},
|
||||
'*',
|
||||
);
|
||||
|
||||
+1
-1
Submodule packages/foliate-js updated: 1b601ae548...a97db3e9cf
Reference in New Issue
Block a user