mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-14 08:11:03 +00:00
d859e23879
WebKit's swipe from the left edge slid away a screenshot of the whole page, closed no sheet and took every drag near the edge from the UI. Binaries from this one turn it off and report an edgeBack feature, and the UI draws its own: the page follows the finger, a release past a third or a flick slides it off and goes back, anything else springs it home, with a light detent. Open sheets now register in one overlay stack, so a way back closes the one on top first, through its own close path (unsaved changes still ask): the edge swipe on iOS and Android's back gesture alike.
44 lines
1.3 KiB
TypeScript
44 lines
1.3 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
|
|
/**
|
|
* The overlays open on screen, newest last, so a way back closes the one on
|
|
* top before it leaves the page: the iOS edge swipe (MEdgeBack) and Android's
|
|
* back gesture (native/nativeApp.ts) both ask here first. Each entry is the
|
|
* overlay's own close path, so an unsaved-changes question still asks.
|
|
*/
|
|
type Close = () => void;
|
|
const stack: { id: number; close: () => void }[] = [];
|
|
let nextId = 1;
|
|
|
|
/** Closes the overlay on top. False when none is open, so the caller goes back instead. */
|
|
export function closeTopOverlay(): boolean {
|
|
const top = stack[stack.length - 1];
|
|
if (!top) return false;
|
|
top.close();
|
|
return true;
|
|
}
|
|
|
|
export function hasOpenOverlay(): boolean {
|
|
return stack.length > 0;
|
|
}
|
|
|
|
/** Registers an overlay while `open`, with the way it closes. */
|
|
export function useOverlay(open: boolean, close: Close): void {
|
|
const closeRef = useRef(close);
|
|
closeRef.current = close;
|
|
useEffect(() => {
|
|
if (!open) return;
|
|
const entry = { id: nextId++, close: () => closeRef.current() };
|
|
stack.push(entry);
|
|
return () => {
|
|
const i = stack.findIndex((e) => e.id === entry.id);
|
|
if (i >= 0) stack.splice(i, 1);
|
|
};
|
|
}, [open]);
|
|
}
|
|
|
|
/** Test helper. */
|
|
export function _resetOverlayStack(): void {
|
|
stack.length = 0;
|
|
}
|