Skip to content

Commit

Permalink
refactor: settings
Browse files Browse the repository at this point in the history
  • Loading branch information
j4k0xb committed May 22, 2024
1 parent b9ad0db commit 329c9a4
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 53 deletions.
15 changes: 9 additions & 6 deletions apps/playground/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ import ProgressBar from './components/ProgressBar';
import Sidebar from './components/Sidebar';
import Tab from './components/Tab';
import { DeobfuscateContextProvider } from './context/DeobfuscateContext';
import { settings } from './hooks/useSettings';
import { useSessions, type SavedModel } from './indexeddb';
import { debounce } from './utils/debounce';
import type { DeobfuscateResult } from './webcrack.worker';

export const [settings, setSettings] = createStore({
export const [config, setConfig] = createStore({
deobfuscate: true,
unminify: true,
unpack: true,
Expand Down Expand Up @@ -52,15 +53,17 @@ function App() {
const filePaths = createMemo(() =>
fileModels().map((model) => model.uri.path),
);
const hasNonEmptyModels = () => models().some((m) => m.getValueLength() > 0);

window.onbeforeunload = () =>
models().some((m) => m.getValueLength() > 0) || undefined;
(settings.confirmOnLeave && hasNonEmptyModels()) || undefined;

// eslint-disable-next-line @typescript-eslint/no-misused-promises
const saveModelsDebounced = debounce(() => saveModels(models()), 1000);
const saveModelsDebounced = debounce(() => {
settings.workspaceHistory && saveModels(models()).catch(console.error);
}, 1000);

createEffect(() => {
if (models().some((m) => m.getValueLength() > 0)) {
if (hasNonEmptyModels()) {
saveModelsDebounced();
}
});
Expand Down Expand Up @@ -182,7 +185,7 @@ function App() {
return (
<DeobfuscateContextProvider
code={activeTab()?.getValue()}
options={{ ...settings }}
options={{ ...config }}
onResult={onDeobfuscateResult}
onError={onDeobfuscateError}
>
Expand Down
43 changes: 27 additions & 16 deletions apps/playground/src/components/Menu.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { For } from 'solid-js';
import { useTheme } from '../hooks/useTheme';
import { setSettings, settings, type Settings } from '../hooks/useSettings';
import { useSessions, type SavedModel } from '../indexeddb';

interface Props {
Expand All @@ -9,7 +9,6 @@ interface Props {

export default function Menu(props: Props) {
const { sessions } = useSessions();
const [theme, setTheme] = useTheme();

function openFile() {
const input = document.createElement('input');
Expand Down Expand Up @@ -69,34 +68,46 @@ export default function Menu(props: Props) {
<ul class="min-w-52 z-10">
<li>
<label class="h-10 flex items-center">
Dark Mode
<input
type="checkbox"
class="toggle toggle-sm ml-auto"
checked={theme() === 'dark'}
onClick={(e) =>
setTheme(e.currentTarget.checked ? 'dark' : 'light')
Theme
<select
class="select select-sm ml-auto"
value={settings.theme}
onChange={(e) =>
setSettings(
'theme',
e.currentTarget.value as Settings['theme'],
)
}
/>
>
<option value="dark">Dark</option>
<option value="light">Light</option>
<option value="system">System</option>
</select>
</label>
</li>
<li class="disabled">
<li>
<label class="h-10 flex items-center">
Prompt on leave
Confirm on Leave
<input
type="checkbox"
class="checkbox checkbox-sm ml-auto"
disabled
checked={settings.confirmOnLeave}
onChange={(e) =>
setSettings('confirmOnLeave', e.currentTarget.checked)
}
/>
</label>
</li>
<li class="disabled">
<li>
<label class="h-10 flex items-center">
File History
Workspace History
<input
type="checkbox"
class="checkbox checkbox-sm ml-auto"
disabled
checked={settings.workspaceHistory}
onChange={(e) =>
setSettings('workspaceHistory', e.currentTarget.checked)
}
/>
</label>
</li>
Expand Down
3 changes: 1 addition & 2 deletions apps/playground/src/components/MonacoEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as monaco from 'monaco-editor';
import { createEffect, onCleanup, onMount } from 'solid-js';
import { useDeobfuscateContext } from '../context/DeobfuscateContext';
import { useTheme } from '../hooks/useTheme';
import { theme } from '../hooks/useTheme';
import { registerEvalSelection } from '../monaco/eval-selection';
import { PlaceholderContentWidget } from '../monaco/placeholder-widget';

Expand All @@ -21,7 +21,6 @@ monaco.editor.defineTheme('dark', {

export default function MonacoEditor(props: Props) {
const { deobfuscate } = useDeobfuscateContext();
const [theme] = useTheme();
const viewStates = new WeakMap<
monaco.editor.ITextModel,
monaco.editor.ICodeEditorViewState
Expand Down
22 changes: 11 additions & 11 deletions apps/playground/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Show } from 'solid-js';
import { setSettings, settings } from '../App';
import { config, setConfig } from '../App';
import { useDeobfuscateContext } from '../context/DeobfuscateContext';
import FileTree from './FileTree';

Expand Down Expand Up @@ -75,8 +75,8 @@ export default function Sidebar(props: Props) {
<input
type="checkbox"
class="checkbox checkbox-sm hidden sm:inline"
checked={settings.deobfuscate}
onClick={(e) => setSettings('deobfuscate', e.currentTarget.checked)}
checked={config.deobfuscate}
onClick={(e) => setConfig('deobfuscate', e.currentTarget.checked)}
/>
</label>
<label class="label cursor-pointer px-4 hover:bg-base-100 group">
Expand Down Expand Up @@ -112,8 +112,8 @@ export default function Sidebar(props: Props) {
<input
type="checkbox"
class="checkbox checkbox-sm hidden sm:inline"
checked={settings.unminify}
onClick={(e) => setSettings('unminify', e.currentTarget.checked)}
checked={config.unminify}
onClick={(e) => setConfig('unminify', e.currentTarget.checked)}
/>
</label>
<label class="label cursor-pointer px-4 hover:bg-base-100 group">
Expand Down Expand Up @@ -147,8 +147,8 @@ export default function Sidebar(props: Props) {
<input
type="checkbox"
class="checkbox checkbox-sm hidden sm:inline"
checked={settings.unpack}
onClick={(e) => setSettings('unpack', e.currentTarget.checked)}
checked={config.unpack}
onClick={(e) => setConfig('unpack', e.currentTarget.checked)}
/>
</label>
<label class="label cursor-pointer px-4 hover:bg-base-100 group">
Expand Down Expand Up @@ -184,8 +184,8 @@ export default function Sidebar(props: Props) {
<input
type="checkbox"
class="checkbox checkbox-sm hidden sm:inline"
checked={settings.jsx}
onClick={(e) => setSettings('jsx', e.currentTarget.checked)}
checked={config.jsx}
onClick={(e) => setConfig('jsx', e.currentTarget.checked)}
/>
</label>
<label class="label cursor-pointer px-4 hover:bg-base-100">
Expand All @@ -211,8 +211,8 @@ export default function Sidebar(props: Props) {
<input
type="checkbox"
class="checkbox checkbox-sm hidden sm:inline"
checked={settings.mangle}
onClick={(e) => setSettings('mangle', e.currentTarget.checked)}
checked={config.mangle}
onClick={(e) => setConfig('mangle', e.currentTarget.checked)}
/>
</label>

Expand Down
27 changes: 27 additions & 0 deletions apps/playground/src/hooks/useSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { createEffect, createRoot } from 'solid-js';
import { createStore } from 'solid-js/store';

const defaultSettings = {
theme: 'system' as 'dark' | 'light' | 'system',
confirmOnLeave: false,
workspaceHistory: true,
};

export type Settings = typeof defaultSettings;

const savedSettings = JSON.parse(
localStorage.getItem('settings') ?? '{}',
) as Settings;

const [settings, setSettings] = createStore({
...defaultSettings,
...savedSettings,
});

createRoot(() => {
createEffect(() => {
localStorage.setItem('settings', JSON.stringify(settings));
});
});

export { setSettings, settings };
26 changes: 8 additions & 18 deletions apps/playground/src/hooks/useTheme.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,21 @@
import { createEffect, createRoot, createSignal } from 'solid-js';

type Theme = 'dark' | 'light';
import { settings } from './useSettings';

const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const preferredTheme = darkMediaQuery.matches ? 'dark' : 'light';
const savedTheme = localStorage.getItem('theme') as Theme | null;
const [preferredTheme, setPreferredTheme] = createSignal(
darkMediaQuery.matches ? 'dark' : 'light',
);

const [theme, setTheme] = createSignal<Theme>(savedTheme ?? preferredTheme);
export function theme() {
return settings.theme === 'system' ? preferredTheme() : settings.theme;
}

createRoot(() => {
createEffect(() => {
document.documentElement.dataset.theme = theme();
});

darkMediaQuery.addEventListener('change', (event) => {
if (savedTheme === null) {
setTheme(event.matches ? 'dark' : 'light');
}
setPreferredTheme(event.matches ? 'dark' : 'light');
});
});

export function useTheme() {
return [
theme,
(theme: Theme) => {
setTheme(theme);
localStorage.setItem('theme', theme);
},
] as const;
}

0 comments on commit 329c9a4

Please sign in to comment.