playground: Persist source and panel (#6071)

This commit is contained in:
Micha Reiser 2023-07-26 07:55:59 +02:00 committed by GitHub
parent c8ee357613
commit 1fdadee59c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 97 additions and 32 deletions

View file

@ -10,7 +10,7 @@ import init, { Diagnostic, Workspace } from "../pkg";
import { ErrorMessage } from "./ErrorMessage";
import Header from "./Header";
import { useTheme } from "./theme";
import { persist, restore, stringify } from "./settings";
import { persist, persistLocal, restore, stringify } from "./settings";
import SettingsEditor from "./SettingsEditor";
import SourceEditor from "./SourceEditor";
import { Panel, PanelGroup } from "react-resizable-panels";
@ -50,17 +50,45 @@ export default function Editor() {
});
const [tab, setTab] = useState<Tab>("Source");
const [theme, setTheme] = useTheme();
const [secondaryTool, setSecondaryTool] = useState<SecondaryTool | null>(
null,
() => {
const secondaryValue = new URLSearchParams(location.search).get(
"secondary",
);
if (secondaryValue == null) {
return null;
} else {
return parseSecondaryTool(secondaryValue);
}
},
);
const [theme, setTheme] = useTheme();
const initialized = ruffVersion != null;
// Ideally this would be retrieved right from the URl... but routing without a proper
// router is hard (there's no location changed event) and pulling in a router
// feels overkill.
const handleSecondaryToolSelected = (tool: SecondaryTool | null) => {
if (tool === secondaryTool) {
tool = null;
}
const url = new URL(location.href);
if (tool == null) {
url.searchParams.delete("secondary");
} else {
url.searchParams.set("secondary", tool);
}
history.replaceState(null, "", url);
setSecondaryTool(tool);
};
useEffect(() => {
init().then(() => {
setRuffVersion(Workspace.version());
const [settingsSource, pythonSource] = restore() ?? [
stringify(Workspace.defaultSettings()),
DEFAULT_PYTHON_SOURCE,
@ -71,6 +99,7 @@ export default function Editor() {
revision: 0,
settingsSource,
});
setRuffVersion(Workspace.version());
});
}, []);
@ -141,6 +170,12 @@ export default function Editor() {
}
}, [initialized, deferredSource, secondaryTool]);
useEffect(() => {
if (initialized) {
persistLocal(source);
}
}, [initialized, source]);
const handleShare = useMemo(() => {
if (!initialized) {
return undefined;
@ -215,13 +250,7 @@ export default function Editor() {
)}
<SecondarySideBar
selected={secondaryTool}
onSelected={(tool) => {
if (secondaryTool === tool) {
setSecondaryTool(null);
} else {
setSecondaryTool(tool);
}
}}
onSelected={handleSecondaryToolSelected}
/>
</PanelGroup>
) : null}
@ -241,3 +270,11 @@ export default function Editor() {
</main>
);
}
function parseSecondaryTool(tool: string): SecondaryTool | null {
if (Object.hasOwn(SecondaryTool, tool)) {
return tool as any;
}
return null;
}

View file

@ -1,7 +1,12 @@
import Editor from "@monaco-editor/react";
import { Theme } from "./theme";
export type SecondaryTool = "Format" | "AST" | "Tokens" | "FIR";
export enum SecondaryTool {
"Format" = "Format",
"AST" = "AST",
"Tokens" = "Tokens",
"FIR" = "FIR",
}
export type SecondaryPanelResult =
| null

View file

@ -15,32 +15,32 @@ export default function SecondarySideBar({
<SideBar position="right">
<SideBarEntry
title="Format (alpha)"
selected={selected === "Format"}
onClick={() => onSelected("Format")}
selected={selected === SecondaryTool.Format}
onClick={() => onSelected(SecondaryTool.Format)}
>
<FormatIcon />
</SideBarEntry>
<SideBarEntry
title="AST"
selected={selected === "AST"}
onClick={() => onSelected("AST")}
selected={selected === SecondaryTool.AST}
onClick={() => onSelected(SecondaryTool.AST)}
>
<StructureIcon />
</SideBarEntry>
<SideBarEntry
title="Tokens"
selected={selected === "Tokens"}
onClick={() => onSelected("Tokens")}
selected={selected === SecondaryTool.Tokens}
onClick={() => onSelected(SecondaryTool.Tokens)}
>
<TokensIcon />
</SideBarEntry>
<SideBarEntry
title="Formatter IR"
selected={selected === "FIR"}
onClick={() => onSelected("FIR")}
selected={selected === SecondaryTool.FIR}
onClick={() => onSelected(SecondaryTool.FIR)}
>
FIR
</SideBarEntry>

View file

@ -39,10 +39,33 @@ export function restore(): [string, string] | null {
window.location.hash.slice(1),
);
if (value != null) {
if (value == null) {
return restoreLocal();
} else {
const [settingsSource, pythonSource] = value.split("$$$");
return [settingsSource.replaceAll("$$$$$$", "$$$"), pythonSource];
} else {
return null;
}
}
function restoreLocal(): [string, string] | null {
const source = localStorage.getItem("source");
if (source == null) {
return null;
} else {
return JSON.parse(source);
}
}
export function persistLocal({
settingsSource,
pythonSource,
}: {
settingsSource: string;
pythonSource: string;
}) {
localStorage.setItem(
"source",
JSON.stringify([settingsSource, pythonSource]),
);
}

View file

@ -29,8 +29,8 @@ html,
@font-face {
font-family: "Alliance Text";
src:
url("../public/fonts/Alliance-TextRegular.woff2") format("woff2"),
url("../public/fonts/Alliance-TextRegular.woff") format("woff");
url("../fonts/Alliance-TextRegular.woff2") format("woff2"),
url("../fonts/Alliance-TextRegular.woff") format("woff");
font-weight: normal;
font-style: normal;
font-display: block;
@ -39,8 +39,8 @@ html,
@font-face {
font-family: "Alliance Text";
src:
url("../public/fonts/Alliance-TextMedium.woff2") format("woff2"),
url("../public/fonts/Alliance-TextMedium.woff") format("woff");
url("../fonts/Alliance-TextMedium.woff2") format("woff2"),
url("../fonts/Alliance-TextMedium.woff") format("woff");
font-weight: 500;
font-style: normal;
font-display: block;
@ -49,8 +49,8 @@ html,
@font-face {
font-family: "Alliance Platt";
src:
url("../public/fonts/Alliance-PlattMedium.woff2") format("woff2"),
url("../public/fonts/Alliance-PlattMedium.woff") format("woff");
url("../fonts/Alliance-PlattMedium.woff2") format("woff2"),
url("../fonts/Alliance-PlattMedium.woff") format("woff");
font-weight: 500;
font-style: normal;
font-display: block;
@ -59,8 +59,8 @@ html,
@font-face {
font-family: "Alliance Platt";
src:
url("../public/fonts/Alliance-PlattRegular.woff2") format("woff2"),
url("../public/fonts/Alliance-PlattRegular.woff") format("woff");
url("../fonts/Alliance-PlattRegular.woff2") format("woff2"),
url("../fonts/Alliance-PlattRegular.woff") format("woff");
font-weight: normal;
font-style: normal;
font-display: block;