Skip to content

Commit

Permalink
feat(front): add experimental customJS system
Browse files Browse the repository at this point in the history
  • Loading branch information
SARDONYX-sard committed Oct 10, 2023
1 parent 349e0c9 commit 2f5620f
Show file tree
Hide file tree
Showing 11 changed files with 215 additions and 50 deletions.
1 change: 1 addition & 0 deletions cspell.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"icns",
"jwalk",
"multispace",
"noconflict",
"rfind",
"Rustup",
"Skyrim",
Expand Down
30 changes: 30 additions & 0 deletions frontend/src/components/editor_list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Tooltip } from "@mui/material";
import MenuItem from "@mui/material/MenuItem";
import Select from "@mui/material/Select";
import { selectEditorMode } from "../utils/editor";
import type { EditorMode } from "@/utils/editor";

type Props = {
setEditorMode: (value: EditorMode) => void;
editorMode: EditorMode;
};

export const SelectEditorMode = ({ editorMode, setEditorMode }: Props) => {
return (
<Tooltip title="Editor Mode" placement="top">
<Select
name={editorMode ?? "default"}
onChange={(e) => {
const presetEditor = selectEditorMode(e.target.value);
setEditorMode(presetEditor);
}}
labelId="editor-select-label"
id="editor-select"
value={editorMode ?? "default"}
>
<MenuItem value={"default"}>Default</MenuItem>
<MenuItem value={"vim"}>Vim</MenuItem>
</Select>
</Tooltip>
);
};
43 changes: 18 additions & 25 deletions frontend/src/components/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,18 +134,14 @@ export function ConvertForm() {
error={Boolean(error)}
helperText={
<>
<p>
[Required] Path of dir containing
&quot;DynamicAnimationReplacer&quot;.{" "}
</p>
<p>
&quot;C:\\[...]/Mod Name/&quot; -&gt; Convert 1st & 3rd
person
</p>
<p>
&quot;[...]/animations/DynamicAnimationReplacer/&quot;
-&gt; Convert only 3rd person
</p>
[Required] Path of dir containing
&quot;DynamicAnimationReplacer&quot;.
<br />
&quot;C:\\[...]/Mod Name/&quot; -&gt; Convert 1st & 3rd
person
<br />
&quot;[...]/animations/DynamicAnimationReplacer/&quot;
-&gt; Convert only 3rd person
</>
}
/>
Expand Down Expand Up @@ -374,19 +370,16 @@ function MappingHelpBtn() {

return (
<>
<p>
[Optional] File path that helps map priority number to a section name.
</p>
<p>
See {" "}
<a
style={{ cursor: "pointer", color: "#00c2ff" }}
onClick={handleMappingClick}
>
[What is the mapping file?]
</a>
(Jump to wiki)
</p>
[Optional] File path that helps map priority number to a section name.
<br />
See{" "}
<a
style={{ cursor: "pointer", color: "#00c2ff" }}
onClick={handleMappingClick}
>
[What is the mapping file?]
</a>
(Jump to wiki)
</>
);
}
95 changes: 78 additions & 17 deletions frontend/src/components/pages/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,67 @@
"use client";

import { Box, TextField } from "@mui/material";
import { useDynStyle, useStorageState } from "@/hooks";
import { SelectStyleList } from "./../style_list";
import AceEditor from "react-ace";
import type { EditorMode } from "@/utils/editor";
import { Box } from "@mui/material";
import { SelectEditorMode } from "@/components/editor_list";
import { SelectStyleList } from "@/components/style_list";
import { Toaster } from "react-hot-toast";
import { selectEditorMode } from "@/utils/editor";
import { useDynStyle, useInjectScript, useStorageState } from "@/hooks";

import "ace-builds/src-noconflict/ext-language_tools";
import "ace-builds/src-noconflict/keybinding-vim";
import "ace-builds/src-noconflict/mode-css";
import "ace-builds/src-noconflict/mode-javascript";
import "ace-builds/src-noconflict/theme-one_dark";
import InputLabel from "@mui/material/InputLabel";

export default function Settings() {
const [style, setStyle] = useDynStyle();
const [script, setScript] = useInjectScript();
const [preset, setPreset] = useStorageState("presetNumber", "0");
const [editorMode, setEditorMode] = useStorageState("editorMode", "default");

const setEditorKeyMode = (editorMode: EditorMode) => {
setEditorMode(editorMode ?? "");
};

return (
<Box
component="main"
sx={{
display: "flex",
marginBottom: "20px",
flexDirection: "column",
alignItems: "center",
width: "100%",
}}
>
<TextField
sx={{
marginTop: "20px",
width: "80%",
maxHeight: "30%",
<Toaster position="bottom-right" reverseOrder={false} />
<InputLabel sx={{ marginTop: "20px" }}>Custom CSS</InputLabel>
<AceEditor
style={{
width: "95%",
backgroundColor: "#2424248c",
}}
rows={10}
label="Custom CSS"
margin="dense"
multiline
onChange={(e) => {
setStyle(e.target.value);
localStorage.setItem("customCSS", e.target.value);
height="300px"
mode="css"
theme="one_dark"
value={style}
debounceChangePeriod={500}
onChange={(value) => {
setStyle(value);
localStorage.setItem("customCSS", value);
setPreset("0");
}}
placeholder="{ body: url('https://localhost' }"
value={style}
name="Custom CSS"
enableBasicAutocompletion
enableLiveAutocompletion
enableSnippets
keyboardHandler={selectEditorMode(editorMode)}
highlightActiveLine
editorProps={{ $blockScrolling: true }}
/>

<Box
Expand All @@ -43,15 +70,49 @@ export default function Settings() {
justifyContent: "space-around",
width: "80%",
marginTop: "20px",
maxHeight: "30%",
maxHeight: "20%",
}}
>
<SelectStyleList
preset={preset}
setPreset={setPreset}
setStyle={setStyle}
/>
<SelectEditorMode
editorMode={selectEditorMode(editorMode)}
setEditorMode={setEditorKeyMode}
/>
</Box>

<InputLabel error sx={{ marginTop: "20px" }}>
Custom JavaScript(Please do not execute untrusted scripts)
</InputLabel>
<AceEditor
style={{
width: "95%",
backgroundColor: "#2424248c",
}}
height="200px"
mode="javascript"
theme="one_dark"
value={script}
onChange={(value) => {
localStorage.setItem("customJS", value);
setScript(value);
}}
placeholder="(()=> {
const p = document.createElement('p');
p.innerText = 'Hello';
document.body.appendChild(p);
)()"
name="Custom JavaScript"
enableBasicAutocompletion
enableLiveAutocompletion
enableSnippets
keyboardHandler={selectEditorMode(editorMode)}
highlightActiveLine
editorProps={{ $blockScrolling: true }}
/>
</Box>
);
}
3 changes: 2 additions & 1 deletion frontend/src/components/style_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ export const SelectStyleList = ({ preset, setPreset, setStyle }: Props) => {
return (
<Tooltip
title="You can choose a CSS preset. NOTE: The moment you edit the preset, Yourself CSS will be overwritten."
placement="top"
placement="right"
>
<Select
sx={{ marginLeft: "50px" }}
name={preset}
onChange={(e) => {
const presetNumber = selectPreset(e.target.value);
Expand Down
33 changes: 32 additions & 1 deletion frontend/src/hooks/dyn_style.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useInsertionEffect, useState } from "react";
import { useEffect, useInsertionEffect, useState } from "react";
import { selectPreset, presetStyles } from "../utils/styles";
import toast from "react-hot-toast";

const getStyle = () => {
const presetNumber = selectPreset(localStorage.getItem("presetNumber") ?? "");
Expand Down Expand Up @@ -31,3 +32,33 @@ export function useDynStyle(initialState = getStyle()) {

return [style, setStyle] as const;
}

export function useInjectScript(
initialState = (() => localStorage.getItem("customJS") ?? "")()
) {
const [script, setScript] = useState(initialState);
const [pathname, setPathname] = useState<string | null>(null);

useEffect(() => {
const scriptElement = document.createElement("script");
if (pathname !== window.location.pathname) {
try {
scriptElement.innerText = script;
scriptElement.id = "custom-script";
if (!document.getElementById("custom-script")) {
document.body.appendChild(scriptElement);
}
} catch (e) {
toast.error(`${e}`);
}
setPathname(window.location.pathname);
}
return () => {
if (document.getElementById("custom-script")) {
document.body.removeChild(scriptElement);
}
};
}, [script, pathname]);

return [script, setScript] as const;
}
2 changes: 1 addition & 1 deletion frontend/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { useStorageState } from "./storage_state";
export { useDynStyle } from "./dyn_style";
export { useInjectScript, useDynStyle } from "./dyn_style";
export { useToastLimit } from "./toasts_limit";
7 changes: 7 additions & 0 deletions frontend/src/utils/editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type EditorMode = "vim" | undefined;

export function selectEditorMode(select: string): EditorMode {
if (select === "vim") {
return select;
}
}
6 changes: 3 additions & 3 deletions frontend/src/utils/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ const preset1 = `body {
background-color: #000;
}
div:has(textarea),
.ace_gutter,
.MuiOutlinedInput-root {
background-color: #2424248c;
background-color: #2424248c !important;
}
.Mui-error {
Expand Down Expand Up @@ -56,7 +56,7 @@ const preset2 = `body {
background-color: #000;
}
div:has(textarea),
.ace_gutter,
.MuiButton-outlined,
.MuiOutlinedInput-root {
background-color: #2424248c;
Expand Down
Loading

0 comments on commit 2f5620f

Please sign in to comment.