forked from external-repos/squoosh
* Class for file drop * OCD * We don't need the invalid state, as we'll accept all types. * Flattening CSS * Fixing zoom input in Firefox * Fixing 'container' scaleTo * two-up closer design match & smaller line * Fixing edge bug
90 lines
2.3 KiB
TypeScript
90 lines
2.3 KiB
TypeScript
import { h, Component } from 'preact';
|
|
|
|
import { bind, linkRef, Fileish } from '../../lib/initial-util';
|
|
import * as style from './style.scss';
|
|
import { FileDropEvent } from './custom-els/FileDrop';
|
|
import './custom-els/FileDrop';
|
|
import SnackBarElement from '../../lib/SnackBar';
|
|
import '../../lib/SnackBar';
|
|
import Intro from '../intro';
|
|
import '../custom-els/LoadingSpinner';
|
|
|
|
// This is imported for TypeScript only. It isn't used.
|
|
import Compress from '../compress';
|
|
|
|
export interface SourceImage {
|
|
file: File | Fileish;
|
|
data: ImageData;
|
|
vectorImage?: HTMLImageElement;
|
|
}
|
|
|
|
interface Props {}
|
|
|
|
interface State {
|
|
file?: File | Fileish;
|
|
Compress?: typeof Compress;
|
|
}
|
|
|
|
export default class App extends Component<Props, State> {
|
|
state: State = {
|
|
file: undefined,
|
|
Compress: undefined,
|
|
};
|
|
|
|
snackbar?: SnackBarElement;
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
import('../compress').then((module) => {
|
|
this.setState({ Compress: module.default });
|
|
}).catch(() => {
|
|
this.showError('Failed to load app');
|
|
});
|
|
|
|
// In development, persist application state across hot reloads:
|
|
if (process.env.NODE_ENV === 'development') {
|
|
this.setState(window.STATE);
|
|
const oldCDU = this.componentDidUpdate;
|
|
this.componentDidUpdate = (props, state) => {
|
|
if (oldCDU) oldCDU.call(this, props, state);
|
|
window.STATE = this.state;
|
|
};
|
|
}
|
|
}
|
|
|
|
@bind
|
|
private onFileDrop(event: FileDropEvent) {
|
|
const { file } = event;
|
|
if (!file) return;
|
|
this.setState({ file });
|
|
}
|
|
|
|
@bind
|
|
private onIntroPickFile(file: File | Fileish) {
|
|
this.setState({ file });
|
|
}
|
|
|
|
@bind
|
|
private showError(error: string) {
|
|
if (!this.snackbar) throw Error('Snackbar missing');
|
|
this.snackbar.showSnackbar({ message: error });
|
|
}
|
|
|
|
render({}: Props, { file, Compress }: State) {
|
|
return (
|
|
<div id="app" class={style.app}>
|
|
<file-drop accept="image/*" onfiledrop={this.onFileDrop} class={style.drop}>
|
|
{(!file)
|
|
? <Intro onFile={this.onIntroPickFile} onError={this.showError} />
|
|
: (Compress)
|
|
? <Compress file={file} onError={this.showError} />
|
|
: <loading-spinner class={style.appLoader}/>
|
|
}
|
|
<snack-bar ref={linkRef(this, 'snackbar')} />
|
|
</file-drop>
|
|
</div>
|
|
);
|
|
}
|
|
}
|