Trace Viewer uses Service Workers to show traces. To view trace:
diff --git a/packages/web/src/components/splitView.tsx b/packages/web/src/components/splitView.tsx
index a252996e73..2db241dfc4 100644
--- a/packages/web/src/components/splitView.tsx
+++ b/packages/web/src/components/splitView.tsx
@@ -38,8 +38,14 @@ export const SplitView: React.FC> = ({
settingName,
children
}) => {
- const [hSize, setHSize] = useSetting(settingName ? settingName + '.' + orientation + ':size' : undefined, Math.max(minSidebarSize, sidebarSize) * window.devicePixelRatio);
- const [vSize, setVSize] = useSetting(settingName ? settingName + '.' + orientation + ':size' : undefined, Math.max(minSidebarSize, sidebarSize) * window.devicePixelRatio);
+ const defaultSize = Math.max(minSidebarSize, sidebarSize) * window.devicePixelRatio;
+ const hSetting = useSetting((settingName ?? 'unused') + '.' + orientation + ':size', defaultSize);
+ const vSetting = useSetting((settingName ?? 'unused') + '.' + orientation + ':size', defaultSize);
+ const hState = React.useState(defaultSize);
+ const vState = React.useState(defaultSize);
+ const [hSize, setHSize] = settingName ? hSetting : hState;
+ const [vSize, setVSize] = settingName ? vSetting : vState;
+
const [resizing, setResizing] = React.useState<{ offset: number, size: number } | null>(null);
const [measure, ref] = useMeasure();
diff --git a/packages/web/src/uiUtils.ts b/packages/web/src/uiUtils.ts
index 9901a24bde..4499ed81f5 100644
--- a/packages/web/src/uiUtils.ts
+++ b/packages/web/src/uiUtils.ts
@@ -141,26 +141,32 @@ export function copy(text: string) {
export type Setting = readonly [T, (value: T) => void, string];
-export function useSetting(name: string | undefined, defaultValue: S, title?: string): [S, React.Dispatch>, Setting] {
- if (name)
- defaultValue = settings.getObject(name, defaultValue);
- const [value, setValue] = React.useState(defaultValue);
- const setValueWrapper = React.useCallback((value: React.SetStateAction) => {
- if (name)
- settings.setObject(name, value);
- setValue(value);
- }, [name, setValue]);
+export function useSetting(name: string, defaultValue: S, title?: string): [S, (v: S) => void, Setting] {
+ const subscribe = React.useCallback((onStoreChange: () => void) => {
+ settings.onChangeEmitter.addEventListener(name, onStoreChange);
+ return () => settings.onChangeEmitter.removeEventListener(name, onStoreChange);
+ }, [name]);
+
+ const value = React.useSyncExternalStore(subscribe, () => settings.getObject(name, defaultValue));
+
+ const setValueWrapper = React.useCallback((value: S) => {
+ settings.setObject(name, value);
+ }, [name]);
+
const setting = [value, setValueWrapper, title || name || ''] as Setting;
return [value, setValueWrapper, setting];
}
export class Settings {
+ onChangeEmitter = new EventTarget();
+
getString(name: string, defaultValue: string): string {
return localStorage[name] || defaultValue;
}
setString(name: string, value: string) {
localStorage[name] = value;
+ this.onChangeEmitter.dispatchEvent(new Event(name));
if ((window as any).saveSettings)
(window as any).saveSettings();
}
@@ -177,6 +183,8 @@ export class Settings {
setObject(name: string, value: T) {
localStorage[name] = JSON.stringify(value);
+ this.onChangeEmitter.dispatchEvent(new Event(name));
+
if ((window as any).saveSettings)
(window as any).saveSettings();
}