Jake code review

This commit is contained in:
Surma
2019-02-11 15:48:31 +00:00
parent efad4f612f
commit 3315188bb3
2 changed files with 73 additions and 40 deletions

View File

@@ -1,5 +1,5 @@
import App from './index'; import App from './index';
import { SideEvent, SideEventType } from '../compress/index'; import { SquooshStartEventType, SquooshSideEventType } from '../compress/index';
import { expose } from 'comlink'; import { expose } from 'comlink';
@@ -15,21 +15,26 @@ export function exposeAPI(app: App) {
expose(new API(app), self.parent); expose(new API(app), self.parent);
} }
class API { function addRemovableGlobalListener<
constructor(private _app: App) { } K extends keyof GlobalEventHandlersEventMap
>(name: K, listener: (ev: GlobalEventHandlersEventMap[K]) => void): () => void {
document.addEventListener(name, listener);
return () => document.removeEventListener(name, listener);
}
setFile(blob: Blob, name: string) { class API {
constructor(private _app: App) {}
async setFile(blob: Blob, name: string) {
return new Promise((resolve) => { return new Promise((resolve) => {
document.addEventListener( document.addEventListener(SquooshStartEventType.START, () => resolve(), {
SideEventType.START, once: true,
() => resolve(), });
{ once: true },
);
this._app.openFile(new File([blob], name)); this._app.openFile(new File([blob], name));
}); });
} }
getBlob(side: 0 | 1) { async getBlob(side: 0 | 1) {
if (!this._app.state.file || !this._app.compressInstance) { if (!this._app.state.file || !this._app.compressInstance) {
throw new Error('No file has been loaded'); throw new Error('No file has been loaded');
} }
@@ -40,34 +45,35 @@ class API {
return this._app.compressInstance!.state.sides[side].file; return this._app.compressInstance!.state.sides[side].file;
} }
return new Promise((resolve, reject) => { const listeners: ReturnType<typeof addRemovableGlobalListener>[] = [];
document.addEventListener(
SideEventType.DONE, const r = new Promise((resolve, reject) => {
(event: Event) => { listeners.push(
if ((event as SideEvent).side !== side) { addRemovableGlobalListener(SquooshSideEventType.DONE, (event) => {
if (event.side !== side) {
return; return;
} }
resolve(this._app.compressInstance!.state.sides[side].file); resolve(this._app.compressInstance!.state.sides[side].file);
}, }),
); );
document.addEventListener( listeners.push(
SideEventType.ABORT, addRemovableGlobalListener(SquooshSideEventType.ABORT, (event) => {
(event) => { if (event.side !== side) {
if ((event as SideEvent).side !== side) {
return; return;
} }
reject(new DOMException('Aborted', 'AbortError')); reject(new DOMException('Aborted', 'AbortError'));
}, }),
); );
document.addEventListener( listeners.push(
SideEventType.ERROR, addRemovableGlobalListener(SquooshSideEventType.ERROR, (event) => {
(event) => { if (event.side !== side) {
if ((event as SideEvent).side !== side) {
return; return;
} }
reject((event as SideEvent).error); reject(event.error);
}, }),
); );
}); });
r.then(() => listeners.forEach(remove => remove()));
return r;
} }
} }

View File

@@ -32,26 +32,51 @@ import { ExpandIcon, CopyAcrossIconProps } from '../../lib/icons';
import SnackBarElement from '../../lib/SnackBar'; import SnackBarElement from '../../lib/SnackBar';
import { InputProcessorState, defaultInputProcessorState } from '../../codecs/input-processors'; import { InputProcessorState, defaultInputProcessorState } from '../../codecs/input-processors';
export enum SideEventType { // Safari and Edge don't quite support extending Event, this works around it.
START = 'squoosh:START', function fixExtendedEvent(instance: Event, type: Function) {
if (!(instance instanceof type)) {
Object.setPrototypeOf(instance, type.prototype);
}
}
export enum SquooshStartEventType {
START = 'squoosh:start',
}
export class SquooshStartEvent extends Event {
constructor(init?: EventInit) {
super(SquooshStartEventType.START, init);
fixExtendedEvent(this, SquooshStartEvent);
}
}
export enum SquooshSideEventType {
DONE = 'squoosh:done', DONE = 'squoosh:done',
ABORT = 'squoosh:abort', ABORT = 'squoosh:abort',
ERROR = 'squoosh:error', ERROR = 'squoosh:error',
} }
export interface SideEventInit extends EventInit { export interface SquooshSideEventInit extends EventInit {
side?: 0|1; side: 0|1;
error?: Error; error?: Error;
} }
export class SideEvent extends Event { export class SquooshSideEvent extends Event {
public side?: 0|1; public side: 0|1;
public error?: Error; public error?: Error;
constructor(name: SideEventType, init: SideEventInit) { constructor(name: SquooshSideEventType, init: SquooshSideEventInit) {
super(name, init); super(name, init);
fixExtendedEvent(this, SquooshSideEvent);
this.side = init.side; this.side = init.side;
this.error = init.error; this.error = init.error;
} }
} }
declare global {
interface GlobalEventHandlersEventMap {
[SquooshStartEventType.START]: SquooshStartEvent;
[SquooshSideEventType.DONE]: SquooshSideEvent;
[SquooshSideEventType.ABORT]: SquooshSideEvent;
[SquooshSideEventType.ERROR]: SquooshSideEvent;
}
}
export interface SourceImage { export interface SourceImage {
file: File | Fileish; file: File | Fileish;
decoded: ImageData; decoded: ImageData;
@@ -494,30 +519,32 @@ export default class Compress extends Component<Props, State> {
} }
@bind @bind
private dispatchSideEvent(type: SideEventType, init: SideEventInit = {}) { private dispatchSideEvent(type: SquooshSideEventType, init: SquooshSideEventInit) {
document.dispatchEvent( document.dispatchEvent(
new SideEvent(type, init), new SquooshSideEvent(type, init),
); );
} }
@bind @bind
private signalProcessingStart() { private signalProcessingStart() {
this.dispatchSideEvent(SideEventType.START); document.dispatchEvent(
new SquooshStartEvent(),
);
} }
@bind @bind
private signalProcessingDone(side: 0|1) { private signalProcessingDone(side: 0|1) {
this.dispatchSideEvent(SideEventType.DONE, { side }); this.dispatchSideEvent(SquooshSideEventType.DONE, { side });
} }
@bind @bind
private signalProcessingAbort(side: 0|1) { private signalProcessingAbort(side: 0|1) {
this.dispatchSideEvent(SideEventType.ABORT, { side }); this.dispatchSideEvent(SquooshSideEventType.ABORT, { side });
} }
@bind @bind
private signalProcessingError(side: 0|1, msg: string) { private signalProcessingError(side: 0|1, msg: string) {
this.dispatchSideEvent(SideEventType.ERROR, { side, error: new Error(msg) }); this.dispatchSideEvent(SquooshSideEventType.ERROR, { side, error: new Error(msg) });
} }
private async updateImage(index: number, options: UpdateImageOptions = {}): Promise<void> { private async updateImage(index: number, options: UpdateImageOptions = {}): Promise<void> {