mirror of
https://github.com/sct/overseerr.git
synced 2025-09-28 13:04:23 +02:00
refactor(frontend): titlecard behavior changed to allow clicking anywhere to go through to title
mobile behavior remains mostly the same, except after the first click, a second click anywhere else will go through to the title.
This commit is contained in:
78
src/hooks/useInteraction.ts
Normal file
78
src/hooks/useInteraction.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
export const INTERACTION_TYPE = {
|
||||
MOUSE: 'mouse',
|
||||
PEN: 'pen',
|
||||
TOUCH: 'touch',
|
||||
};
|
||||
|
||||
const UPDATE_INTERVAL = 1000; // Throttle updates to the type to prevent flip flopping
|
||||
|
||||
const useInteraction = (): boolean => {
|
||||
const [isTouch, setIsTouch] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const hasTapEvent = 'ontouchstart' in window;
|
||||
setIsTouch(hasTapEvent);
|
||||
|
||||
let localTouch = hasTapEvent;
|
||||
let lastTouchUpdate = Date.now();
|
||||
|
||||
const shouldUpdate = (): boolean =>
|
||||
lastTouchUpdate + UPDATE_INTERVAL < Date.now();
|
||||
|
||||
const onMouseMove = (): void => {
|
||||
if (localTouch && shouldUpdate()) {
|
||||
setTimeout(() => {
|
||||
if (shouldUpdate()) {
|
||||
setIsTouch(false);
|
||||
localTouch = false;
|
||||
}
|
||||
}, UPDATE_INTERVAL);
|
||||
}
|
||||
};
|
||||
|
||||
const onTouchStart = (): void => {
|
||||
lastTouchUpdate = Date.now();
|
||||
|
||||
if (!localTouch) {
|
||||
setIsTouch(true);
|
||||
localTouch = true;
|
||||
}
|
||||
};
|
||||
|
||||
const onPointerMove = (e: PointerEvent): void => {
|
||||
const { pointerType } = e;
|
||||
|
||||
switch (pointerType) {
|
||||
case INTERACTION_TYPE.TOUCH:
|
||||
case INTERACTION_TYPE.PEN:
|
||||
return onTouchStart();
|
||||
default:
|
||||
return onMouseMove();
|
||||
}
|
||||
};
|
||||
|
||||
if (hasTapEvent) {
|
||||
window.addEventListener('mousemove', onMouseMove);
|
||||
window.addEventListener('touchstart', onTouchStart);
|
||||
} else {
|
||||
window.addEventListener('pointerdown', onPointerMove);
|
||||
window.addEventListener('pointermove', onPointerMove);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (hasTapEvent) {
|
||||
window.removeEventListener('mousemove', onMouseMove);
|
||||
window.removeEventListener('touchstart', onTouchStart);
|
||||
} else {
|
||||
window.removeEventListener('pointerdown', onPointerMove);
|
||||
window.removeEventListener('pointermove', onPointerMove);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return isTouch;
|
||||
};
|
||||
|
||||
export default useInteraction;
|
7
src/hooks/useIsTouch.ts
Normal file
7
src/hooks/useIsTouch.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { useContext } from 'react';
|
||||
import { InteractionContext } from '../context/InteractionContext';
|
||||
|
||||
export const useIsTouch = (): boolean => {
|
||||
const { isTouch } = useContext(InteractionContext);
|
||||
return isTouch;
|
||||
};
|
Reference in New Issue
Block a user