Detach Widget from setValue impl

This commit is contained in:
Ingvar Stepanyan
2021-07-21 14:47:52 +00:00
parent 70a35d1b70
commit 686dba0812
2 changed files with 27 additions and 21 deletions

View File

@@ -119,6 +119,23 @@ class App extends Component {
}); });
} }
/**
* Set the specified config value.
* @param {string} name
* @param {*} value
*/
setValue = async (name, value) => {
/** @type {Promise<void>} */
let uiTimeout;
await scheduleOp(context => {
// This is terrible, yes... but some configs return too quickly before they're actually updated.
// We want to wait some time before updating the UI in that case, but not block subsequent ops.
uiTimeout = new Promise(resolve => setTimeout(resolve, 800));
return context.setConfigValue(name, value);
});
await uiTimeout;
};
render(/** @type {App['props']} */ props, /** @type {App['state']} */ state) { render(/** @type {App['props']} */ props, /** @type {App['state']} */ state) {
switch (state.type) { switch (state.type) {
case 'CameraPicker': case 'CameraPicker':
@@ -150,7 +167,7 @@ class App extends Component {
'form', 'form',
{ class: 'pure-form pure-form-aligned' }, { class: 'pure-form pure-form-aligned' },
h(CaptureButton, null), h(CaptureButton, null),
h(Widget, { config: state.config }) h(Widget, { config: state.config, setValue: this.setValue })
) )
) )
); );

View File

@@ -1,11 +1,10 @@
import { h, Component, createRef } from 'preact'; import { h, Component, createRef } from 'preact';
import { scheduleOp } from './ops.js';
/** @typedef {import('../libapi.mjs').Config} Config */ /** @typedef {import('../libapi.mjs').Config} Config */
/** /**
* *
* @extends Component<{ config: Config }> * @extends Component<{ config: Config, setValue: (name: string, value: any) => Promise<void> }>
*/ */
export class Widget extends Component { export class Widget extends Component {
state = { inProgress: false }; state = { inProgress: false };
@@ -34,28 +33,18 @@ export class Widget extends Component {
handleChange = async e => { handleChange = async e => {
this.setState({ inProgress: true }); this.setState({ inProgress: true });
let value = e.target[this.getValueProp(true)];
try { try {
/** @type {Promise<void>} */ await this.props.setValue(
let uiTimeout; this.props.config.name,
await scheduleOp(context => { e.target[this.getValueProp(true)]
// This is terrible, yes... but some configs return too quickly before they're actually updated. );
// We want to wait some time before updating the UI in that case, but not block subsequent ops. } finally {
uiTimeout = new Promise(resolve => setTimeout(resolve, 800)); this.setState({ inProgress: false });
return context.setConfigValue(this.props.config.name, value);
});
await uiTimeout;
} catch (e) {
console.error(e);
} }
this.setState({ inProgress: false });
}; };
render( render(
/** @type {Widget['props']} */ { config }, /** @type {Widget['props']} */ { config, setValue },
/** @type {Widget['state']} */ { inProgress } /** @type {Widget['state']} */ { inProgress }
) { ) {
let { label, name } = config; let { label, name } = config;
@@ -66,7 +55,7 @@ export class Widget extends Component {
{ id }, { id },
h('legend', {}, label), h('legend', {}, label),
Object.values(config.children).map(config => Object.values(config.children).map(config =>
h(Widget, { key: config.name, config }) h(Widget, { key: config.name, config, setValue })
) )
); );
} }