mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-11 16:26:20 +00:00
More work on compress
This commit is contained in:
@@ -14,7 +14,7 @@ import 'shared/initial-app/custom-els/loading-spinner';
|
|||||||
|
|
||||||
const ROUTE_EDITOR = '/editor';
|
const ROUTE_EDITOR = '/editor';
|
||||||
|
|
||||||
//const compressPromise = import('client/lazy-app/Compress');
|
const compressPromise = import('client/lazy-app/Compress');
|
||||||
const swBridgePromise = import('client/lazy-app/sw-bridge');
|
const swBridgePromise = import('client/lazy-app/sw-bridge');
|
||||||
|
|
||||||
function back() {
|
function back() {
|
||||||
@@ -27,7 +27,7 @@ interface State {
|
|||||||
awaitingShareTarget: boolean;
|
awaitingShareTarget: boolean;
|
||||||
file?: File;
|
file?: File;
|
||||||
isEditorOpen: Boolean;
|
isEditorOpen: Boolean;
|
||||||
Compress?: undefined; // typeof import('../compress').default;
|
Compress?: typeof import('client/lazy-app/Compress').default;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class App extends Component<Props, State> {
|
export default class App extends Component<Props, State> {
|
||||||
@@ -45,13 +45,13 @@ export default class App extends Component<Props, State> {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
/*compressPromise
|
compressPromise
|
||||||
.then((module) => {
|
.then((module) => {
|
||||||
this.setState({ Compress: module.default });
|
this.setState({ Compress: module.default });
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.showSnack('Failed to load app');
|
this.showSnack('Failed to load app');
|
||||||
});*/
|
});
|
||||||
|
|
||||||
swBridgePromise.then(async ({ offliner, getSharedImage }) => {
|
swBridgePromise.then(async ({ offliner, getSharedImage }) => {
|
||||||
offliner(this.showSnack);
|
offliner(this.showSnack);
|
||||||
@@ -123,9 +123,9 @@ export default class App extends Component<Props, State> {
|
|||||||
{showSpinner ? (
|
{showSpinner ? (
|
||||||
<loading-spinner class={style.appLoader} />
|
<loading-spinner class={style.appLoader} />
|
||||||
) : isEditorOpen ? (
|
) : isEditorOpen ? (
|
||||||
Compress &&
|
Compress && (
|
||||||
//<Compress file={file!} showSnack={this.showSnack} onBack={back} />
|
<Compress file={file!} showSnack={this.showSnack} onBack={back} />
|
||||||
'TODO: uncomment above'
|
)
|
||||||
) : (
|
) : (
|
||||||
<Intro onFile={this.onIntroPickFile} showSnack={this.showSnack} />
|
<Intro onFile={this.onIntroPickFile} showSnack={this.showSnack} />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ import {
|
|||||||
encoderMap,
|
encoderMap,
|
||||||
defaultPreprocessorState,
|
defaultPreprocessorState,
|
||||||
defaultProcessorState,
|
defaultProcessorState,
|
||||||
|
EncoderType,
|
||||||
|
EncoderOptions,
|
||||||
} from '../feature-meta';
|
} from '../feature-meta';
|
||||||
import Output from '../Output';
|
import Output from '../Output';
|
||||||
import Options from '../Options';
|
import Options from '../Options';
|
||||||
import ResultCache from './result-cache';
|
import ResultCache from './result-cache';
|
||||||
import { cleanMerge, cleanSet } from '../../lib/clean-modify';
|
import { cleanMerge, cleanSet } from '../util/clean-modify';
|
||||||
import './custom-els/MultiPanel';
|
import './custom-els/MultiPanel';
|
||||||
import Results from '../results';
|
import Results from '../results';
|
||||||
import { ExpandIcon, CopyAcrossIconProps } from '../../lib/icons';
|
import { ExpandIcon, CopyAcrossIconProps } from '../../lib/icons';
|
||||||
@@ -31,6 +33,8 @@ import SnackBarElement from '../../lib/SnackBar';
|
|||||||
import WorkerBridge from '../worker-bridge';
|
import WorkerBridge from '../worker-bridge';
|
||||||
import { resize } from 'features/processors/resize/client';
|
import { resize } from 'features/processors/resize/client';
|
||||||
|
|
||||||
|
type OutputType = EncoderType | 'identity';
|
||||||
|
|
||||||
export interface SourceImage {
|
export interface SourceImage {
|
||||||
file: File;
|
file: File;
|
||||||
decoded: ImageData;
|
decoded: ImageData;
|
||||||
@@ -248,7 +252,6 @@ export default class Compress extends Component<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private readonly encodeCache = new ResultCache();
|
private readonly encodeCache = new ResultCache();
|
||||||
// YOU ARE HERE
|
|
||||||
private readonly leftWorkerBridge = new WorkerBridge();
|
private readonly leftWorkerBridge = new WorkerBridge();
|
||||||
private readonly rightWorkerBridge = new WorkerBridge();
|
private readonly rightWorkerBridge = new WorkerBridge();
|
||||||
// For debouncing calls to updateImage for each side.
|
// For debouncing calls to updateImage for each side.
|
||||||
@@ -262,34 +265,36 @@ export default class Compress extends Component<Props, State> {
|
|||||||
this.widthQuery.addListener(this.onMobileWidthChange);
|
this.widthQuery.addListener(this.onMobileWidthChange);
|
||||||
this.updateFile(props.file);
|
this.updateFile(props.file);
|
||||||
|
|
||||||
import('../../lib/sw-bridge').then(({ mainAppLoaded }) => mainAppLoaded());
|
import('../sw-bridge').then(({ mainAppLoaded }) => mainAppLoaded());
|
||||||
}
|
}
|
||||||
|
|
||||||
private onMobileWidthChange = () => {
|
private onMobileWidthChange = () => {
|
||||||
this.setState({ mobileView: this.widthQuery.matches });
|
this.setState({ mobileView: this.widthQuery.matches });
|
||||||
};
|
};
|
||||||
|
|
||||||
private onEncoderTypeChange(index: 0 | 1, newType: EncoderType): void {
|
private onEncoderTypeChange(index: 0 | 1, newType: OutputType): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
sides: cleanSet(
|
sides: cleanSet(
|
||||||
this.state.sides,
|
this.state.sides,
|
||||||
`${index}.latestSettings.encoderState`,
|
`${index}.latestSettings.encoderState`,
|
||||||
{
|
newType === 'identity'
|
||||||
type: newType,
|
? undefined
|
||||||
options: encoderMap[newType].defaultOptions,
|
: {
|
||||||
},
|
type: newType,
|
||||||
|
options: encoderMap[newType].meta.defaultOptions,
|
||||||
|
},
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private onPreprocessorOptionsChange(
|
private onProcessorOptionsChange(
|
||||||
index: 0 | 1,
|
index: 0 | 1,
|
||||||
options: PreprocessorState,
|
options: ProcessorState,
|
||||||
): void {
|
): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
sides: cleanSet(
|
sides: cleanSet(
|
||||||
this.state.sides,
|
this.state.sides,
|
||||||
`${index}.latestSettings.preprocessorState`,
|
`${index}.latestSettings.processorState`,
|
||||||
options,
|
options,
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
@@ -654,7 +659,7 @@ export default class Compress extends Component<Props, State> {
|
|||||||
this,
|
this,
|
||||||
index as 0 | 1,
|
index as 0 | 1,
|
||||||
)}
|
)}
|
||||||
onPreprocessorOptionsChange={this.onPreprocessorOptionsChange.bind(
|
onPreprocessorOptionsChange={this.onProcessorOptionsChange.bind(
|
||||||
this,
|
this,
|
||||||
index as 0 | 1,
|
index as 0 | 1,
|
||||||
)}
|
)}
|
||||||
|
|||||||
62
src/client/lazy-app/util/clean-modify.ts
Normal file
62
src/client/lazy-app/util/clean-modify.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
function cleanSetOrMerge<A extends any[] | object>(
|
||||||
|
source: A,
|
||||||
|
keys: string | number | string[],
|
||||||
|
toSetOrMerge: any[] | object,
|
||||||
|
merge: boolean,
|
||||||
|
): A {
|
||||||
|
const splitKeys = Array.isArray(keys) ? keys : ('' + keys).split('.');
|
||||||
|
|
||||||
|
// Going off road in terms of types, otherwise TypeScript doesn't like the access-by-index.
|
||||||
|
// The assumptions in this code break if the object contains things which aren't arrays or
|
||||||
|
// plain objects.
|
||||||
|
let last = copy(source) as any;
|
||||||
|
const newObject = last;
|
||||||
|
|
||||||
|
const lastIndex = splitKeys.length - 1;
|
||||||
|
|
||||||
|
for (const [i, key] of splitKeys.entries()) {
|
||||||
|
if (i !== lastIndex) {
|
||||||
|
// Copy everything along the path.
|
||||||
|
last = last[key] = copy(last[key]);
|
||||||
|
} else {
|
||||||
|
// Merge or set.
|
||||||
|
last[key] = merge
|
||||||
|
? Object.assign(copy(last[key]), toSetOrMerge)
|
||||||
|
: toSetOrMerge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
function copy<A extends any[] | object>(source: A): A {
|
||||||
|
// Some type cheating here, as TypeScript can't infer between generic types.
|
||||||
|
if (Array.isArray(source)) return [...source] as any;
|
||||||
|
return { ...(source as any) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param source Object to copy from.
|
||||||
|
* @param keys Path to modify, eg "foo.bar.baz".
|
||||||
|
* @param toMerge A value to merge into the value at the path.
|
||||||
|
*/
|
||||||
|
export function cleanMerge<A extends any[] | object>(
|
||||||
|
source: A,
|
||||||
|
keys: string | number | string[],
|
||||||
|
toMerge: any[] | object,
|
||||||
|
): A {
|
||||||
|
return cleanSetOrMerge(source, keys, toMerge, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param source Object to copy from.
|
||||||
|
* @param keys Path to modify, eg "foo.bar.baz".
|
||||||
|
* @param newValue A value to set at the path.
|
||||||
|
*/
|
||||||
|
export function cleanSet<A extends any[] | object>(
|
||||||
|
source: A,
|
||||||
|
keys: string | number | string[],
|
||||||
|
newValue: any,
|
||||||
|
): A {
|
||||||
|
return cleanSetOrMerge(source, keys, newValue, false);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user