Options ui (#222)

* wip

* Commenting stuff to keep the build happy

* Revealing sections

* Custom select elements & more form work

* Range input styles

* Text fields with inputs do the right thing

* Safari & Firefox fixes

* Large compress select

* oops

* MozJPEG options updated

* OptPNG options

* These asserts weren't true

* Generic options

* WebP options

* Hiding "edit" when "original image"

* Download icon

* Copy setting button - still not happy with this

* Progress indicator

* Loading icon enter/exit anim

* Preventing controls going under options

* Ahh so that's what was causing scrolling

* Ahh so that's what was causing outlines

* Simplifying range styles and fixing cross-browser

* Processing custom element styles

* Get precision from step by default

* I don't know how or when this happened.

* Don't need that many steps

* Avoid having an element that covers the pinch zoom

* Preventing overlap with zoom controls

* Prevent ts warning

* Fixing spinner position

* Simplifying FileSize
This commit is contained in:
Jake Archibald
2018-11-06 13:36:23 +00:00
committed by GitHub
parent 0cec90c7ca
commit bdd3c11f1a
37 changed files with 1291 additions and 948 deletions

View File

@@ -65,7 +65,9 @@ interface Props {
interface State {
source?: SourceImage;
images: [EncodedImage, EncodedImage];
/** Source image load */
loading: boolean;
loadingCounter: number;
error?: string;
orientation: Orientation;
}
@@ -159,6 +161,7 @@ export default class Compress extends Component<Props, State> {
state: State = {
source: undefined,
loading: false,
loadingCounter: 0,
images: [
{
preprocessorState: defaultPreprocessorState,
@@ -252,7 +255,9 @@ export default class Compress extends Component<Props, State> {
@bind
private async updateFile(file: File | Fileish) {
this.setState({ loading: true });
const loadingCounter = this.state.loadingCounter + 1;
this.setState({ loadingCounter, loading: true });
// Abort any current encode jobs, as they're redundant now.
this.leftProcessor.abortCurrent();
@@ -273,6 +278,9 @@ export default class Compress extends Component<Props, State> {
data = await decodeImage(file, this.leftProcessor);
}
// Another file has been opened before this one processed.
if (this.state.loadingCounter !== loadingCounter) return;
let newState: State = {
...this.state,
source: { data, file, vectorImage },
@@ -303,6 +311,8 @@ export default class Compress extends Component<Props, State> {
} catch (err) {
if (err.name === 'AbortError') return;
console.error(err);
// Another file has been opened before this one processed.
if (this.state.loadingCounter !== loadingCounter) return;
this.props.onError('Invalid image');
this.setState({ loading: false });
}
@@ -388,10 +398,9 @@ export default class Compress extends Component<Props, State> {
render({ }: Props, { loading, images, source, orientation }: State) {
const [leftImage, rightImage] = images;
const [leftImageData, rightImageData] = images.map(i => i.data);
const anyLoading = loading || images.some(image => image.loading);
return (
<div class={style.compress}>
<div class={`${style.compress} ${style[orientation]}`}>
<Output
originalImage={source && source.data}
orientation={orientation}
@@ -400,24 +409,22 @@ export default class Compress extends Component<Props, State> {
leftImgContain={leftImage.preprocessorState.resize.fitMethod === 'cover'}
rightImgContain={rightImage.preprocessorState.resize.fitMethod === 'cover'}
/>
<div class={`${style.optionPair} ${style[orientation]}`}>
{images.map((image, index) => (
<Options
source={source}
orientation={orientation}
imageIndex={index}
imageFile={image.file}
downloadUrl={image.downloadUrl}
preprocessorState={image.preprocessorState}
encoderState={image.encoderState}
onEncoderTypeChange={this.onEncoderTypeChange.bind(this, index)}
onEncoderOptionsChange={this.onEncoderOptionsChange.bind(this, index)}
onPreprocessorOptionsChange={this.onPreprocessorOptionsChange.bind(this, index)}
onCopyToOtherClick={this.onCopyToOtherClick.bind(this, index)}
/>
))}
</div>
{anyLoading && <span style={{ position: 'fixed', top: 0, left: 0 }}>Loading...</span>}
{images.map((image, index) => (
<Options
loading={loading || image.loading}
source={source}
orientation={orientation}
imageIndex={index}
imageFile={image.file}
downloadUrl={image.downloadUrl}
preprocessorState={image.preprocessorState}
encoderState={image.encoderState}
onEncoderTypeChange={this.onEncoderTypeChange.bind(this, index)}
onEncoderOptionsChange={this.onEncoderOptionsChange.bind(this, index)}
onPreprocessorOptionsChange={this.onPreprocessorOptionsChange.bind(this, index)}
onCopyToOtherClick={this.onCopyToOtherClick.bind(this, index)}
/>
))}
</div>
);
}