mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
331 lines
12 KiB
Svelte
331 lines
12 KiB
Svelte
<script lang="ts">
|
|
import { mdiContentSave, mdiDatabaseSync, mdiDelete, mdiHelpCircle, mdiReload } from '@mdi/js';
|
|
import { createEventDispatcher, tick } from 'svelte';
|
|
import {
|
|
adjustTimerOnAfk$,
|
|
afkTimer$,
|
|
allowNewLineDuringPause$,
|
|
allowPasteDuringPause$,
|
|
autoStartTimerDuringPause$,
|
|
autoStartTimerDuringPausePaste$,
|
|
blockCopyOnPage$,
|
|
blurStats$,
|
|
characterMilestone$,
|
|
continuousReconnect$,
|
|
customCSS$,
|
|
defaultSettings,
|
|
displayVertical$,
|
|
enableAfkBlur$,
|
|
enableAfkBlurRestart$,
|
|
enableExternalClipboardMonitor$,
|
|
enableLineAnimation$,
|
|
enablePaste$,
|
|
filterNonCJKLines$,
|
|
flashOnMissedLine$,
|
|
fontSize$,
|
|
lastSettingPreset$,
|
|
maxLines$,
|
|
maxPipLines$,
|
|
mergeEqualLineStarts$,
|
|
milestoneLines$,
|
|
onlineFont$,
|
|
openDialog$,
|
|
persistActionHistory$,
|
|
persistLines$,
|
|
persistNotes$,
|
|
persistStats$,
|
|
preserveWhitespace$,
|
|
preventGlobalDuplicate$,
|
|
preventLastDuplicate$,
|
|
reconnectSecondarySocket$,
|
|
reconnectSocket$,
|
|
removeAllWhitespace$,
|
|
replacements$,
|
|
reverseLineOrder$,
|
|
secondarySocketState$,
|
|
secondaryWebsocketUrl$,
|
|
settingPresets$,
|
|
showCharacterCount$,
|
|
showConnectionErrors$,
|
|
showConnectionIcon$,
|
|
showLineCount$,
|
|
showPresetQuickSwitch$,
|
|
showSpeed$,
|
|
showTimer$,
|
|
skipResetConfirmations$,
|
|
socketState$,
|
|
theme$,
|
|
websocketUrl$,
|
|
windowTitle$,
|
|
} from '../stores/stores';
|
|
import type { DialogResult, SettingPreset, Settings } from '../types';
|
|
import { dummyFn } from '../util';
|
|
import Icon from './Icon.svelte';
|
|
|
|
export let isQuickSwitch = false;
|
|
|
|
export function getCurrentSettings(): Settings {
|
|
return {
|
|
theme$: $theme$,
|
|
replacements$: $replacements$,
|
|
windowTitle$: $windowTitle$,
|
|
websocketUrl$: $websocketUrl$,
|
|
secondaryWebsocketUrl$: $secondaryWebsocketUrl$,
|
|
fontSize$: $fontSize$,
|
|
characterMilestone$: $characterMilestone$,
|
|
onlineFont$: $onlineFont$,
|
|
preventLastDuplicate$: $preventLastDuplicate$,
|
|
maxLines$: $maxLines$,
|
|
maxPipLines$: $maxPipLines$,
|
|
afkTimer$: $afkTimer$,
|
|
adjustTimerOnAfk$: $adjustTimerOnAfk$,
|
|
enableExternalClipboardMonitor$: $enableExternalClipboardMonitor$,
|
|
showPresetQuickSwitch$: $showPresetQuickSwitch$,
|
|
skipResetConfirmations$: $skipResetConfirmations$,
|
|
persistStats$: $persistStats$,
|
|
persistNotes$: $persistNotes$,
|
|
persistLines$: $persistLines$,
|
|
persistActionHistory$: $persistActionHistory$,
|
|
enablePaste$: $enablePaste$,
|
|
blockCopyOnPage$: $blockCopyOnPage$,
|
|
allowPasteDuringPause$: $allowPasteDuringPause$,
|
|
allowNewLineDuringPause$: $allowNewLineDuringPause$,
|
|
autoStartTimerDuringPausePaste$: $autoStartTimerDuringPausePaste$,
|
|
autoStartTimerDuringPause$: $autoStartTimerDuringPause$,
|
|
preventGlobalDuplicate$: $preventGlobalDuplicate$,
|
|
mergeEqualLineStarts$: $mergeEqualLineStarts$,
|
|
filterNonCJKLines: $filterNonCJKLines$,
|
|
flashOnMissedLine$: $flashOnMissedLine$,
|
|
displayVertical$: $displayVertical$,
|
|
reverseLineOrder$: $reverseLineOrder$,
|
|
preserveWhitespace$: $preserveWhitespace$,
|
|
removeAllWhitespace$: $removeAllWhitespace$,
|
|
showTimer$: $showTimer$,
|
|
showSpeed$: $showSpeed$,
|
|
showCharacterCount$: $showCharacterCount$,
|
|
showLineCount$: $showLineCount$,
|
|
blurStats$: $blurStats$,
|
|
enableLineAnimation$: $enableLineAnimation$,
|
|
enableAfkBlur$: $enableAfkBlur$,
|
|
enableAfkBlurRestart$: $enableAfkBlurRestart$,
|
|
continuousReconnect$: $continuousReconnect$,
|
|
showConnectionErrors$: $showConnectionErrors$,
|
|
showConnectionIcon$: $showConnectionIcon$,
|
|
customCSS$: $customCSS$,
|
|
};
|
|
}
|
|
|
|
export function updateSettingsWithPreset(preset: SettingPreset, updateLastPreset = true) {
|
|
theme$.next(preset.settings.theme$ ?? defaultSettings.theme$);
|
|
replacements$.next(preset.settings.replacements$ ?? defaultSettings.replacements$);
|
|
windowTitle$.next(preset.settings.windowTitle$ ?? defaultSettings.windowTitle$);
|
|
websocketUrl$.next(preset.settings.websocketUrl$ ?? defaultSettings.websocketUrl$);
|
|
secondaryWebsocketUrl$.next(preset.settings.secondaryWebsocketUrl$ ?? '');
|
|
fontSize$.next(preset.settings.fontSize$ ?? defaultSettings.fontSize$);
|
|
characterMilestone$.next(preset.settings.characterMilestone$ ?? defaultSettings.characterMilestone$);
|
|
onlineFont$.next(preset.settings.onlineFont$ ?? defaultSettings.onlineFont$);
|
|
preventLastDuplicate$.next(preset.settings.preventLastDuplicate$ ?? defaultSettings.preventLastDuplicate$);
|
|
maxLines$.next(preset.settings.maxLines$ ?? defaultSettings.maxLines$);
|
|
maxPipLines$.next(preset.settings.maxPipLines$ ?? defaultSettings.maxPipLines$);
|
|
afkTimer$.next(preset.settings.afkTimer$ ?? defaultSettings.afkTimer$);
|
|
adjustTimerOnAfk$.next(preset.settings.adjustTimerOnAfk$ ?? defaultSettings.adjustTimerOnAfk$);
|
|
enableExternalClipboardMonitor$.next(
|
|
preset.settings.enableExternalClipboardMonitor$ ?? defaultSettings.enableExternalClipboardMonitor$,
|
|
);
|
|
showPresetQuickSwitch$.next(preset.settings.showPresetQuickSwitch$ ?? defaultSettings.showPresetQuickSwitch$);
|
|
skipResetConfirmations$.next(
|
|
preset.settings.skipResetConfirmations$ ?? defaultSettings.skipResetConfirmations$,
|
|
);
|
|
persistStats$.next(preset.settings.persistStats$ ?? defaultSettings.persistStats$);
|
|
persistNotes$.next(preset.settings.persistNotes$ ?? defaultSettings.persistNotes$);
|
|
persistLines$.next(preset.settings.persistLines$ ?? defaultSettings.persistLines$);
|
|
persistActionHistory$.next(preset.settings.persistActionHistory$ ?? defaultSettings.persistActionHistory$);
|
|
enablePaste$.next(preset.settings.enablePaste$ ?? defaultSettings.enablePaste$);
|
|
blockCopyOnPage$.next(preset.settings.blockCopyOnPage$ ?? defaultSettings.blockCopyOnPage$);
|
|
allowPasteDuringPause$.next(preset.settings.allowPasteDuringPause$ ?? defaultSettings.allowPasteDuringPause$);
|
|
allowNewLineDuringPause$.next(
|
|
preset.settings.allowNewLineDuringPause$ ?? defaultSettings.allowNewLineDuringPause$,
|
|
);
|
|
autoStartTimerDuringPausePaste$.next(
|
|
preset.settings.autoStartTimerDuringPausePaste$ ?? defaultSettings.autoStartTimerDuringPausePaste$,
|
|
);
|
|
autoStartTimerDuringPause$.next(
|
|
preset.settings.autoStartTimerDuringPause$ ?? defaultSettings.autoStartTimerDuringPause$,
|
|
);
|
|
preventGlobalDuplicate$.next(
|
|
preset.settings.preventGlobalDuplicate$ ?? defaultSettings.preventGlobalDuplicate$,
|
|
);
|
|
mergeEqualLineStarts$.next(preset.settings.mergeEqualLineStarts$ ?? defaultSettings.mergeEqualLineStarts$);
|
|
filterNonCJKLines$.next(preset.settings.filterNonCJKLines ?? defaultSettings.filterNonCJKLines);
|
|
flashOnMissedLine$.next(preset.settings.flashOnMissedLine$ ?? defaultSettings.flashOnMissedLine$);
|
|
displayVertical$.next(preset.settings.displayVertical$ ?? defaultSettings.displayVertical$);
|
|
reverseLineOrder$.next(preset.settings.reverseLineOrder$ ?? defaultSettings.reverseLineOrder$);
|
|
preserveWhitespace$.next(preset.settings.preserveWhitespace$ ?? defaultSettings.preserveWhitespace$);
|
|
removeAllWhitespace$.next(preset.settings.removeAllWhitespace$ ?? defaultSettings.removeAllWhitespace$);
|
|
showTimer$.next(preset.settings.showTimer$ ?? defaultSettings.showTimer$);
|
|
showSpeed$.next(preset.settings.showSpeed$ ?? defaultSettings.showSpeed$);
|
|
showCharacterCount$.next(preset.settings.showCharacterCount$ ?? defaultSettings.showCharacterCount$);
|
|
showLineCount$.next(preset.settings.showLineCount$ ?? defaultSettings.showLineCount$);
|
|
blurStats$.next(preset.settings.blurStats$ ?? defaultSettings.blurStats$);
|
|
enableLineAnimation$.next(preset.settings.enableLineAnimation$ ?? defaultSettings.enableLineAnimation$);
|
|
enableAfkBlur$.next(preset.settings.enableAfkBlur$ ?? defaultSettings.enableAfkBlur$);
|
|
enableAfkBlurRestart$.next(preset.settings.enableAfkBlurRestart$ ?? defaultSettings.enableAfkBlurRestart$);
|
|
continuousReconnect$.next(preset.settings.continuousReconnect$ ?? defaultSettings.continuousReconnect$);
|
|
showConnectionErrors$.next(preset.settings.showConnectionErrors$ ?? defaultSettings.showConnectionErrors$);
|
|
showConnectionIcon$.next(preset.settings.showConnectionIcon$ ?? defaultSettings.showConnectionIcon$);
|
|
customCSS$.next(preset.settings.customCSS$ ?? defaultSettings.customCSS$);
|
|
|
|
if (updateLastPreset) {
|
|
$lastSettingPreset$ = preset.name;
|
|
}
|
|
|
|
if ($characterMilestone$ === 0) {
|
|
$milestoneLines$ = new Map<string, string>();
|
|
}
|
|
|
|
tick().then(() => {
|
|
dispatch('layoutChange');
|
|
|
|
if ($socketState$ !== 1 && $continuousReconnect$) {
|
|
reconnectSocket$.next();
|
|
}
|
|
|
|
if ($secondarySocketState$ !== 1 && $continuousReconnect$) {
|
|
reconnectSecondarySocket$.next();
|
|
}
|
|
});
|
|
}
|
|
|
|
const fallbackPresetEntry = [{ name: '' }];
|
|
const dispatch = createEventDispatcher<{ layoutChange: void; exportImportPreset: MouseEvent }>();
|
|
|
|
function selectPreset(event: Event) {
|
|
const target = event.target as HTMLSelectElement;
|
|
|
|
changePreset(target.selectedOptions[0].value);
|
|
}
|
|
|
|
function changePreset(presetName: string) {
|
|
const existingEntry = $settingPresets$.find((entry) => entry.name === presetName);
|
|
|
|
if (existingEntry) {
|
|
updateSettingsWithPreset(existingEntry);
|
|
}
|
|
}
|
|
|
|
async function savePreset() {
|
|
const { canceled, data } = await new Promise<DialogResult<string>>((resolve) => {
|
|
$openDialog$ = {
|
|
icon: mdiHelpCircle,
|
|
askForData: 'text',
|
|
dataValue: $lastSettingPreset$ || 'Preset Name',
|
|
message: '',
|
|
callback: resolve,
|
|
};
|
|
});
|
|
|
|
if (canceled || !data) {
|
|
return;
|
|
}
|
|
|
|
const existingEntryIndex = $settingPresets$.findIndex((entry) => entry.name === data);
|
|
const entry: SettingPreset = {
|
|
name: data,
|
|
settings: getCurrentSettings(),
|
|
};
|
|
|
|
if (existingEntryIndex > -1) {
|
|
$settingPresets$[existingEntryIndex] = entry;
|
|
} else {
|
|
$settingPresets$ = [...$settingPresets$, entry];
|
|
}
|
|
|
|
$lastSettingPreset$ = data;
|
|
}
|
|
|
|
async function deletePreset() {
|
|
if (!$skipResetConfirmations$) {
|
|
const { canceled } = await new Promise<DialogResult>((resolve) => {
|
|
$openDialog$ = {
|
|
icon: mdiHelpCircle,
|
|
message: 'Preset will be deleted',
|
|
callback: resolve,
|
|
};
|
|
});
|
|
|
|
if (canceled) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
$settingPresets$ = $settingPresets$.filter((entry) => entry.name !== $lastSettingPreset$);
|
|
$lastSettingPreset$ = '';
|
|
}
|
|
</script>
|
|
|
|
{#if isQuickSwitch}
|
|
<select
|
|
class="w-48 hidden sm:block"
|
|
class:sm:hidden={!$showPresetQuickSwitch$ || $settingPresets$.length < 2}
|
|
value={$lastSettingPreset$}
|
|
on:change={selectPreset}
|
|
>
|
|
{#each $settingPresets$.length ? $settingPresets$ : fallbackPresetEntry as preset (preset.name)}
|
|
<option value={preset.name}>
|
|
{preset.name}
|
|
</option>
|
|
{/each}
|
|
</select>
|
|
{:else}
|
|
<details role="button" class="col-span-4 mb-2">
|
|
<summary>Presets</summary>
|
|
<div class="flex items-center justify-between mt-2">
|
|
<select class="select flex-1 max-w-md" value={$lastSettingPreset$} on:change={selectPreset}>
|
|
{#each $settingPresets$.length ? $settingPresets$ : fallbackPresetEntry as preset (preset.name)}
|
|
<option value={preset.name}>
|
|
{preset.name || 'No Presets stored'}
|
|
</option>
|
|
{/each}
|
|
</select>
|
|
<div
|
|
role="button"
|
|
class="flex flex-col items-center hover:text-primary ml-3"
|
|
on:click={savePreset}
|
|
on:keyup={dummyFn}
|
|
>
|
|
<Icon path={mdiContentSave} />
|
|
<span class="label-text">Save</span>
|
|
</div>
|
|
<div
|
|
role="button"
|
|
class="flex flex-col items-center hover:text-primary ml-3"
|
|
on:click={(event) => dispatch('exportImportPreset', event)}
|
|
on:keyup={dummyFn}
|
|
>
|
|
<Icon path={mdiDatabaseSync} />
|
|
<span class="label-text">Export/Import</span>
|
|
</div>
|
|
<div
|
|
role="button"
|
|
class="flex flex-col items-center hover:text-primary ml-3"
|
|
class:invisible={!$lastSettingPreset$}
|
|
on:click={() => changePreset($lastSettingPreset$)}
|
|
on:keyup={dummyFn}
|
|
>
|
|
<Icon path={mdiReload} />
|
|
<span class="label-text">Reload</span>
|
|
</div>
|
|
<div
|
|
role="button"
|
|
class="flex flex-col items-center hover:text-primary ml-3"
|
|
class:invisible={!$lastSettingPreset$}
|
|
on:click={deletePreset}
|
|
on:keyup={dummyFn}
|
|
>
|
|
<Icon path={mdiDelete} />
|
|
<span class="label-text">Delete</span>
|
|
</div>
|
|
</div>
|
|
</details>
|
|
{/if}
|