Integrate supported ops into the UI
This commit is contained in:
@@ -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 })
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -8,7 +8,7 @@ const Stats = isDebug
|
||||
)
|
||||
: null;
|
||||
|
||||
/** @extends Component<{ getPreview: () => Promise<Blob> }, { error?: string }> */
|
||||
/** @extends Component<{ getPreview?: () => Promise<Blob> }, { 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 })
|
||||
)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user