d86fc93ed6
Why Phone and PC need a single capture flow that ends at inventory PNG and board-foot numbers with no backend, inference, or Woo create. Scope Add frontend/ Vite+Svelte capture UI with Resume, Add photo, Mask, Length axis, and Measure. Mask runs in a worker with Auto/Green/Black and a 2.0s sensitivity debounce. Measure computes scale, widths, sqft, bdft, and a 3:4 alpha inventory PNG. Persist one device draft in IndexedDB. Serve the static build from frontend/Dockerfile via nginx (deploy/nginx-m1.conf). No FastAPI. Verification sudo docker build -f frontend/Dockerfile -t slabuploader-m1 . sudo docker run -d --name slabuploader-m1 -p 0.0.0.0:18080:80 slabuploader-m1 curl http://127.0.0.1:18080/ returns 200 Playwright: synthetic green-sheet photo through Calculate shows sqft/bdft
27 lines
1.4 KiB
TypeScript
27 lines
1.4 KiB
TypeScript
// Supported clients: iOS Safari, Android Chrome, PC Chrome/Edge/Firefox.
|
|
// Gated on required API presence; anything missing → hard stop.
|
|
export function supported(): string | null {
|
|
if (typeof window === 'undefined') return 'window unavailable';
|
|
if (typeof createImageBitmap !== 'function') return 'createImageBitmap';
|
|
if (typeof Worker === 'undefined') return 'Worker';
|
|
if (typeof indexedDB === 'undefined') return 'IndexedDB';
|
|
const hasOffscreen =
|
|
typeof OffscreenCanvas !== 'undefined' &&
|
|
typeof OffscreenCanvas.prototype.convertToBlob === 'function';
|
|
const hasCanvasBlob =
|
|
typeof HTMLCanvasElement !== 'undefined' &&
|
|
typeof HTMLCanvasElement.prototype.toBlob === 'function';
|
|
if (!hasOffscreen && !hasCanvasBlob) return 'canvas PNG encode';
|
|
const ua = navigator.userAgent;
|
|
const isIOS = /iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
|
const isAndroid = /Android/i.test(ua);
|
|
const isSafari = /Safari/i.test(ua) && !/Chrome|CriOS|Edg|Firefox|FxiOS/i.test(ua);
|
|
const isChrome = /Chrome|CriOS/i.test(ua) && !/Edg/i.test(ua);
|
|
const isEdge = /Edg/i.test(ua);
|
|
const isFirefox = /Firefox|FxiOS/i.test(ua);
|
|
if (isIOS && isSafari) return null;
|
|
if (isAndroid && isChrome) return null;
|
|
if (!isIOS && !isAndroid && (isChrome || isEdge || isFirefox)) return null;
|
|
return 'unsupported browser';
|
|
}
|