diff --git a/api.cpp b/api.cpp index 4dc10ba..330f9d5 100644 --- a/api.cpp +++ b/api.cpp @@ -185,12 +185,6 @@ class Context { }); } - void triggerCapture() { - gpp_rethrow([=]() { - gpp_try(gp_camera_trigger_capture(camera.get(), context.get())); - }); - } - private: gpp_unique_ptr camera; gpp_unique_ptr context; diff --git a/libapi.mjs.d.ts b/libapi.mjs.d.ts index eda796f..d330313 100644 --- a/libapi.mjs.d.ts +++ b/libapi.mjs.d.ts @@ -13,6 +13,15 @@ export type Config = { | { type: 'datetime'; value: number } ); +declare interface SupportedOps { + captureImage: boolean; + captureVideo: boolean; + captureAudio: boolean; + capturePreview: boolean; + config: boolean; + triggerCapture: boolean; +} + declare class Context { configToJS(): Promise; setConfigValue( @@ -22,6 +31,7 @@ declare class Context { capturePreviewAsBlob(): Promise; captureImageAsFile(): Promise; hasPendingEvent(): Promise; + supportedOps(): SupportedOps; delete(): void; isDeleted(): boolean; diff --git a/ui/index.js b/ui/index.js index 4979ff6..c167c7e 100644 --- a/ui/index.js +++ b/ui/index.js @@ -143,7 +143,9 @@ class App extends Component { 'div', { class: 'pure-u-2-3' }, h(Preview, { - getPreview: this.capturePreview + getPreview: this.connection.supportedOps.capturePreview + ? this.capturePreview + : undefined }) ), h( @@ -152,7 +154,9 @@ class App extends Component { h( 'form', { class: 'pure-form pure-form-aligned' }, - h(CaptureButton, { getFile: this.captureImage }), + this.connection.supportedOps.triggerCapture + ? h(CaptureButton, { getFile: this.captureImage }) + : undefined, h(Widget, { config: state.config, setValue: this.setValue }) ) ) diff --git a/ui/ops.js b/ui/ops.js index fc07455..4a026bd 100644 --- a/ui/ops.js +++ b/ui/ops.js @@ -2,12 +2,13 @@ import initModule from '../libapi.mjs'; /** @typedef {import('../libapi.mjs').Context} Context */ -const ContextPromise = initModule().then(Module => Module.Context); +const ModulePromise = initModule(); export async function connect() { - let Context = await ContextPromise; + const Module = await ModulePromise; - let context = await new Context(); + let context = await new Module.Context(); + let supportedOps = await context.supportedOps(); let queue = Promise.resolve(); @@ -30,6 +31,7 @@ export async function connect() { } return { + supportedOps, schedule, disconnect() { context.delete(); diff --git a/ui/preview.js b/ui/preview.js index 7e7f21e..de1f403 100644 --- a/ui/preview.js +++ b/ui/preview.js @@ -8,7 +8,7 @@ const Stats = isDebug ) : null; -/** @extends Component<{ getPreview: () => Promise }, { error?: string }> */ +/** @extends Component<{ getPreview?: () => Promise }, { error?: string }> */ export class Preview extends Component { canvasHolderRef = createRef(); canvasRef = createRef(); @@ -20,17 +20,15 @@ export class Preview extends Component { return h( 'div', { class: 'center-parent', ref: this.canvasHolderRef }, - this.state.error - ? h( - 'div', - { class: 'center' }, - `Could not retrieve preview: ${this.state.error}` - ) + !this.props.getPreview + ? h('div', { class: 'center' }, `Preview is unsupported`) : h('canvas', { class: 'center', ref: this.canvasRef }) ); } async componentDidMount() { + if (!this.props.getPreview) return; + let canvas = /** @type {HTMLCanvasElement} */ (this.canvasRef.current); let canvasHolder = this.canvasHolderRef.current; @@ -70,39 +68,34 @@ export class Preview extends Component { await new Promise(resolve => setTimeout(resolve, 1000)); while (this.canvasRef.current) { - let blob; try { - blob = await this.props.getPreview(); - } catch (error) { - this.setState({ error: error.message }); - return; - } + let blob = await this.props.getPreview(); - // If ratio is known; decode resized image right away - it's a bit faster. - // If it isn't known, retrieve entire image to calculate ratio from its dimensions. - let img = await createImageBitmap( - blob, - ratio - ? { - resizeWidth: canvas.width, - resizeHeight: canvas.height - } - : {} - ); - if (!ratio) { - ratio = img.width / img.height; - updateCanvasSize(); + // If ratio is known; decode resized image right away - it's a bit faster. + // If it isn't known, retrieve entire image to calculate ratio from its dimensions. + let img = await createImageBitmap( + blob, + ratio + ? { + resizeWidth: canvas.width, + resizeHeight: canvas.height + } + : {} + ); + if (!ratio) { + ratio = img.width / img.height; + updateCanvasSize(); + } + canvasCtx.transferFromImageBitmap(img); + } catch (error) { + console.error(error); } - canvasCtx.transferFromImageBitmap(img); await new Promise(resolve => requestAnimationFrame(resolve)); this.stats?.update(); } } componentWillUnmount() { - this.resizeObserver.disconnect(); - if (isDebug) { - this.canvasHolderRef.current.removeChild(this.stats.dom); - } + this.resizeObserver?.disconnect(); } } diff --git a/ui/widget.js b/ui/widget.js index f2722bd..ea8be9f 100644 --- a/ui/widget.js +++ b/ui/widget.js @@ -68,11 +68,13 @@ export class Widget extends Component { let { label, name } = config; let id = `config-${name}`; if (config.type === 'window' || config.type === 'section') { + let children = Object.values(config.children); + if (!children.length) return; return h( 'fieldset', { id }, h('legend', {}, label), - Object.values(config.children).map(config => + children.map(config => h(Widget, { key: config.name, config, setValue }) ) );