mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 06:26:26 +00:00
73237ffedb
The tour type is a dropdown; a bike tour picks its profile, routes for it, says when a point lies off every way, and shows what it runs on: surfaces, kinds of way and, for a mountain bike, the trail grades, each pointed at on the map. A type's own map (OpenHikingMap for a hike, CyclOSM for a bike tour) is offered while a tour of that type is open, with an admin switch each. From the planned cards: a hike avoids steep climbs, steps or ferries, nothing else; a saved tour can be shared where the platform takes GPX files; and the tours rail adds a tour from one menu: plan new, import GPX, or take one over from another trip.
38 lines
1.6 KiB
TypeScript
38 lines
1.6 KiB
TypeScript
/**
|
|
* Handing a file to the system's share sheet (the Web Share API), where the
|
|
* platform takes files of that kind. Chrome takes only an allow-list of file
|
|
* types, Safari and the phones most, so whether a share is offered is asked
|
|
* per file name and type, never assumed from `navigator.share` alone.
|
|
*/
|
|
|
|
/** Whether this browser would hand a file of this name and type to the share sheet. */
|
|
export function canShareFile(name: string, type: string): boolean {
|
|
if (typeof navigator === 'undefined' || typeof navigator.share !== 'function') return false;
|
|
if (typeof navigator.canShare !== 'function') return false;
|
|
try {
|
|
return navigator.canShare({ files: [new File([''], name, { type })] });
|
|
} catch {
|
|
// A browser that cannot even build the question cannot share the file either.
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* How a share ended: `cancelled` when the sheet was closed without a target,
|
|
* `needs-gesture` when the browser refused because the tap that asked lies too
|
|
* far back (Safari, after the file had to be fetched first), `failed` otherwise.
|
|
*/
|
|
export type FileShareOutcome = 'shared' | 'cancelled' | 'needs-gesture' | 'failed';
|
|
|
|
/** Opens the share sheet with the file; call it straight from the tap that asks for it. */
|
|
export async function shareFile(file: File, title: string): Promise<FileShareOutcome> {
|
|
try {
|
|
await navigator.share({ files: [file], title });
|
|
return 'shared';
|
|
} catch (error: unknown) {
|
|
if (error instanceof DOMException && error.name === 'AbortError') return 'cancelled';
|
|
if (error instanceof DOMException && error.name === 'NotAllowedError') return 'needs-gesture';
|
|
return 'failed';
|
|
}
|
|
}
|