Files
squoosh/src/components/options/index.tsx
Jason Miller 3035a68b90 Options UI (#39)
* Initial work to add Options config

* Use a single encoder instance and retry up to 10 times on failure.

* Switch both sides to allow encoding from the source image, add options configuration for each.

* Styling for options (and a few tweaks for the app)

* Dep updates.

* Remove commented out code.

* Fix Encoder typing

* Fix lint issues

* Apparently I didnt have tslint autofix enabled on the chromebook

* Attempt to fix layout/panning issues

* Fix missing custom element import!

* Fix variable naming, remove dynamic encoder names, remove retry, allow encoders to return ImageData.

* Refactor state management to use an Array of objects and immutable updates instead of relying on explicit update notifications.

* Add Identity encoder, which is a passthrough encoder that handles the "original" view.

* Drop comlink-loader into the project and add ".worker" to the jpeg encoder filename so it runs in a worker (🦄)

* lint fixes.

* cleanup

* smaller PR feedback fixes

* rename "jpeg" codec to "MozJpeg"

* Formatting fixes for Options

* Colocate codecs and their options UIs in src/codecs, and standardize the namings

* Handle canvas errors

* Throw if quality is undefined, add default quality

* add note about temp styles

* add note about temp styles [2]

* Renaming updateOption

* Clarify option input bindings

* Move updateCanvas() to util and rename to drawBitmapToCanvas

* use generics to pass through encoder options

* Remove unused dependencies

* fix options type

* const

* Use `Array.prototype.some()` for image loading check

* Display encoding errors in the UI.

* I fought typescript and I think I won

* This doesn't need to be optional

* Quality isn't optional

* Simplifying comlink casting

* Splitting counters into loading and displaying

* Still loading if the loading counter isn't equal.
2018-06-29 16:29:18 +01:00

64 lines
2.0 KiB
TypeScript

import { h, Component } from 'preact';
import * as style from './style.scss';
import { bind } from '../../lib/util';
import MozJpegEncoderOptions from '../../codecs/mozjpeg/options';
import { type as mozJPEGType } from '../../codecs/mozjpeg/encoder';
import { type as identityType } from '../../codecs/identity/encoder';
import { EncoderState, EncoderType, EncoderOptions, encoders } from '../../codecs/encoders';
const encoderOptionsComponentMap = {
[mozJPEGType]: MozJpegEncoderOptions,
[identityType]: undefined
};
interface Props {
class?: string;
encoderState: EncoderState;
onTypeChange(newType: EncoderType): void;
onOptionsChange(newOptions: EncoderOptions): void;
}
interface State {}
export default class Options extends Component<Props, State> {
typeSelect?: HTMLSelectElement;
@bind
onTypeChange(event: Event) {
const el = event.currentTarget as HTMLSelectElement;
// The select element only has values matching encoder types,
// so 'as' is safe here.
const type = el.value as EncoderType;
this.props.onTypeChange(type);
}
render({ class: className, encoderState, onOptionsChange }: Props) {
const EncoderOptionComponent = encoderOptionsComponentMap[encoderState.type];
return (
<div class={`${style.options}${className ? (' ' + className) : ''}`}>
<label>
Mode:
<select value={encoderState.type} onChange={this.onTypeChange}>
{encoders.map(encoder => (
<option value={encoder.type}>{encoder.label}</option>
))}
</select>
</label>
{EncoderOptionComponent &&
<EncoderOptionComponent
options={
// Casting options, as encoderOptionsComponentMap[encodeData.type] ensures the correct type,
// but typescript isn't smart enough.
encoderState.options as typeof EncoderOptionComponent['prototype']['props']['options']
}
onChange={onOptionsChange}
/>
}
</div>
);
}
}