forked from external-repos/squoosh
Improving image open time (#185)
* Moving intro into its own component * Tidying JSX, and allowing image to render before first compression. Fixes #164.
This commit is contained in:
@@ -38,6 +38,7 @@ import {
|
||||
|
||||
import { decodeImage } from '../../codecs/decoders';
|
||||
import { cleanMerge, cleanSet } from '../../lib/clean-modify';
|
||||
import Intro from '../intro';
|
||||
|
||||
type Orientation = 'horizontal' | 'vertical';
|
||||
|
||||
@@ -209,14 +210,6 @@ export default class App extends Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
@bind
|
||||
async onFileChange(event: Event): Promise<void> {
|
||||
const fileInput = event.target as HTMLInputElement;
|
||||
const file = fileInput.files && fileInput.files[0];
|
||||
if (!file) return;
|
||||
await this.updateFile(file);
|
||||
}
|
||||
|
||||
@bind
|
||||
async onFileDrop(event: FileDropEvent) {
|
||||
const { file } = event;
|
||||
@@ -342,38 +335,38 @@ export default class App extends Component<Props, State> {
|
||||
return (
|
||||
<file-drop accept="image/*" onfiledrop={this.onFileDrop}>
|
||||
<div id="app" class={`${style.app} ${style[orientation]}`}>
|
||||
{(leftImageData && rightImageData && source) ? (
|
||||
<Output
|
||||
orientation={orientation}
|
||||
imgWidth={source.data.width}
|
||||
imgHeight={source.data.height}
|
||||
leftImg={leftImageData}
|
||||
rightImg={rightImageData}
|
||||
leftImgContain={leftImage.preprocessorState.resize.fitMethod === 'cover'}
|
||||
rightImgContain={rightImage.preprocessorState.resize.fitMethod === 'cover'}
|
||||
/>
|
||||
) : (
|
||||
<div class={style.welcome}>
|
||||
<h1>Drop, paste or select an image</h1>
|
||||
<input type="file" onChange={this.onFileChange} />
|
||||
</div>
|
||||
)}
|
||||
{(leftImageData && rightImageData && source) && images.map((image, index) => (
|
||||
<Options
|
||||
orientation={orientation}
|
||||
sourceAspect={source.data.width / source.data.height}
|
||||
imageIndex={index}
|
||||
imageFile={image.file}
|
||||
sourceImageFile={source && source.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)}
|
||||
/>
|
||||
))}
|
||||
{source
|
||||
?
|
||||
<div class={`${style.optionPair} ${style[orientation]}`}>
|
||||
<Output
|
||||
orientation={orientation}
|
||||
imgWidth={source.data.width}
|
||||
imgHeight={source.data.height}
|
||||
leftImg={leftImageData || source.data}
|
||||
rightImg={rightImageData || source.data}
|
||||
leftImgContain={leftImage.preprocessorState.resize.fitMethod === 'cover'}
|
||||
rightImgContain={rightImage.preprocessorState.resize.fitMethod === 'cover'}
|
||||
/>
|
||||
{images.map((image, index) => (
|
||||
<Options
|
||||
orientation={orientation}
|
||||
sourceAspect={source.data.width / source.data.height}
|
||||
imageIndex={index}
|
||||
imageFile={image.file}
|
||||
sourceImageFile={source && source.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>
|
||||
:
|
||||
<Intro onFile={this.updateFile} />
|
||||
}
|
||||
{anyLoading && <span style={{ position: 'fixed', top: 0, left: 0 }}>Loading...</span>}
|
||||
<snack-bar ref={linkRef(this, 'snackbar')} />
|
||||
</div>
|
||||
|
||||
@@ -11,39 +11,6 @@ Note: These styles are temporary. They will be replaced before going live.
|
||||
overflow: hidden;
|
||||
contain: strict;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
&.horizontal {
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.welcome {
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
|
||||
h1 {
|
||||
font-weight: inherit;
|
||||
font-size: 150%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input {
|
||||
display: inline-block;
|
||||
width: 16em;
|
||||
padding: 10px;
|
||||
margin: 0 auto;
|
||||
-webkit-appearance: none;
|
||||
border: 1px solid var(--button-fg);
|
||||
background: rgba(var(--button-fg-color), 0.1);
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
:global {
|
||||
@@ -87,3 +54,18 @@ Note: These styles are temporary. They will be replaced before going live.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.option-pair {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
|
||||
&.horizontal {
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
27
src/components/intro/index.tsx
Normal file
27
src/components/intro/index.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { h, Component } from 'preact';
|
||||
import * as style from './style.scss';
|
||||
import { bind } from '../../lib/util';
|
||||
|
||||
interface Props {
|
||||
onFile: (file: File) => void;
|
||||
}
|
||||
interface State {}
|
||||
|
||||
export default class Intro extends Component<Props, State> {
|
||||
@bind
|
||||
onFileChange(event: Event): void {
|
||||
const fileInput = event.target as HTMLInputElement;
|
||||
const file = fileInput.files && fileInput.files[0];
|
||||
if (!file) return;
|
||||
this.props.onFile(file);
|
||||
}
|
||||
|
||||
render({ }: Props, { }: State) {
|
||||
return (
|
||||
<div class={style.welcome}>
|
||||
<h1>Drop, paste or select an image</h1>
|
||||
<input type="file" onChange={this.onFileChange} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
22
src/components/intro/style.scss
Normal file
22
src/components/intro/style.scss
Normal file
@@ -0,0 +1,22 @@
|
||||
.welcome {
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
|
||||
h1 {
|
||||
font-weight: inherit;
|
||||
font-size: 150%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input {
|
||||
display: inline-block;
|
||||
width: 16em;
|
||||
padding: 10px;
|
||||
margin: 0 auto;
|
||||
-webkit-appearance: none;
|
||||
border: 1px solid var(--button-fg);
|
||||
background: rgba(var(--button-fg-color), 0.1);
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user