[F] Fix settings persistence
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import { API } from "$lib/client"
|
||||
import { typingSettingsDefault, type TypingSettings, type UserData } from "$lib/types"
|
||||
|
||||
export class UserDataSync {
|
||||
settings = $state<TypingSettings>(typingSettingsDefault)
|
||||
loc = $state<UserData['loc']>(undefined)
|
||||
|
||||
constructor(data: any) {
|
||||
this.settings = data.user.data?.typingSettings ?? typingSettingsDefault
|
||||
this.loc = data.user.data.loc
|
||||
|
||||
$effect(() => {
|
||||
data.user.data = data.user.data || {}
|
||||
data.user.data.typingSettings = this.settings
|
||||
API.saveUserData({ typingSettings: this.settings })
|
||||
})
|
||||
|
||||
$effect(() => {
|
||||
data.user.data = data.user.data || {}
|
||||
data.user.data.loc = this.loc
|
||||
API.saveUserData({ loc: this.loc })
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -6,19 +6,15 @@
|
||||
import ProgressList from "$lib/ui/ProgressList.svelte"
|
||||
import { goto } from "$app/navigation"
|
||||
import { getI18n, useMsg } from "$lib/i18n"
|
||||
import { typingSettingsDefault } from "$lib/types"
|
||||
import { getNextSong } from "$lib/ui/player/SongSwitching.js"
|
||||
import { UserDataSync } from "$lib/ui/player/state.svelte"
|
||||
|
||||
const t = getI18n().song.mode
|
||||
const getMsg = useMsg()
|
||||
|
||||
let { data } = $props()
|
||||
|
||||
let settings = $state(data.user.data?.typingSettings ?? typingSettingsDefault)
|
||||
$effect(() => { API.saveUserData({ typingSettings: settings }) })
|
||||
|
||||
let loc = $state(data.user.data.loc)
|
||||
$effect(() => { API.saveUserData({ loc }) })
|
||||
const ud = new UserDataSync(data)
|
||||
|
||||
let taskStatus = $state({
|
||||
lyrics: false,
|
||||
@@ -89,7 +85,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<PlayerAppBar song={data.song} bind:settings bind:loc playlist={data.playlist} />
|
||||
<PlayerAppBar song={data.song} bind:settings={ud.settings} bind:loc={ud.loc} playlist={data.playlist} />
|
||||
|
||||
<ProgressList percentage={progressPercentage} items={progressItems} />
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script lang="ts">
|
||||
import type { PageProps } from "./$types"
|
||||
import { onMount } from "svelte"
|
||||
import { typingSettingsDefault } from "$lib/types"
|
||||
import { processLrcLine, dedupLines, type ProcLrcLine } from "$lib/ui/player/IMEHelper"
|
||||
import "$lib/ext.ts"
|
||||
import { API } from "$lib/client"
|
||||
import { MusicControl } from "$lib/ui/player/MusicControl"
|
||||
import Lyrics from "$lib/ui/player/Lyrics.svelte"
|
||||
import PlayerAppBar from "$lib/ui/player/PlayerAppBar.svelte"
|
||||
import { UserDataSync } from "$lib/ui/player/state.svelte"
|
||||
import { getI18n } from "$lib/i18n"
|
||||
import { Layer } from "m3-svelte";
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
let { data }: PageProps = $props()
|
||||
|
||||
let li = $state(0)
|
||||
let settings = $state(data.user.data?.typingSettings ?? typingSettingsDefault)
|
||||
$effect(() => { API.saveUserData({ typingSettings: settings }) })
|
||||
|
||||
let loc = $state(data.user.data.loc)
|
||||
$effect(() => { API.saveUserData({ loc }) })
|
||||
const ud = new UserDataSync(data)
|
||||
|
||||
let vocalsVolume = $state(data.user.data.vocalsVolume ?? 100)
|
||||
$effect(() => {
|
||||
@@ -31,7 +27,7 @@
|
||||
let isPlaying = $state(false)
|
||||
|
||||
// Process lyrics
|
||||
const isHideRepeated = $derived(settings.hideRepeated)
|
||||
const isHideRepeated = $derived(ud.settings.hideRepeated)
|
||||
let deduplicatedLyrics = $derived(dedupLines(data.lrc, isHideRepeated))
|
||||
let processedLrc: ProcLrcLine[] = $derived(deduplicatedLyrics.map(line => processLrcLine(line.lyric)))
|
||||
|
||||
@@ -91,7 +87,7 @@
|
||||
|
||||
<svelte:window onclick={() => musicControl?.ready()} onkeydown={() => musicControl?.ready()}/>
|
||||
|
||||
<PlayerAppBar song={data.song} bind:settings bind:loc showRomajiOnError={false} isKaraoke={true} disableHideRepeated playlist={data.playlist} />
|
||||
<PlayerAppBar song={data.song} bind:settings={ud.settings} bind:loc={ud.loc} showRomajiOnError={false} isKaraoke={true} disableHideRepeated playlist={data.playlist} />
|
||||
|
||||
<div class="vbox p-content py-4 gap-2 mfg-on-surface-variant">
|
||||
{#if data.audioData.vocalsUrl}
|
||||
@@ -113,7 +109,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Lyrics lines={processedLrc} currentLineIndex={li} {settings} {states} />
|
||||
<Lyrics lines={processedLrc} currentLineIndex={li} settings={ud.settings} {states} />
|
||||
|
||||
<button
|
||||
class="fixed bottom-6 right-6 z-5 size-64px cbox rounded-full surface-variant mbg-surface-container mfg-on-surface-variant shadow-lg hover:shadow-xl transition-all active:scale-90"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
import Lyrics from "$lib/ui/player/Lyrics.svelte"
|
||||
import PlayerAppBar from "$lib/ui/player/PlayerAppBar.svelte"
|
||||
import { getI18n } from "$lib/i18n"
|
||||
import { UserDataSync } from "$lib/ui/player/state.svelte"
|
||||
|
||||
const t = getI18n().song.play
|
||||
|
||||
@@ -25,15 +26,10 @@
|
||||
let inp = $state("")
|
||||
|
||||
// Settings stored in user data
|
||||
let settings = $state(data.user.data?.typingSettings ?? typingSettingsDefault)
|
||||
$effect(() => { API.saveUserData({ typingSettings: settings }) })
|
||||
|
||||
// Playlist location state
|
||||
let loc = $state(data.user.data.loc)
|
||||
$effect(() => { API.saveUserData({ loc }) })
|
||||
const ud = new UserDataSync(data)
|
||||
|
||||
// Process each line into segments with swi (start word index) and kanji/kana
|
||||
const isHideRepeated = $derived(settings.hideRepeated && !data.audioUrl)
|
||||
const isHideRepeated = $derived(ud.settings.hideRepeated && !data.audioUrl)
|
||||
let deduplicatedLyrics = $derived(dedupLines(data.lrc, isHideRepeated))
|
||||
let processedLrc: ProcLrcLine[] = $derived(deduplicatedLyrics.map(line => processLrcLine(line.lyric)))
|
||||
// State tracking for each kana character: UNSEEN, RIGHT, WRONG
|
||||
@@ -146,10 +142,10 @@
|
||||
totalTyped, totalRight, startTime, statsHistory
|
||||
})
|
||||
|
||||
if (loc?.currentPlaylistId) {
|
||||
loc.isFinished = true
|
||||
loc.lastResultId = res.id
|
||||
await API.saveUserData({ loc })
|
||||
if (ud.loc) {
|
||||
ud.loc.isFinished = true
|
||||
ud.loc.lastResultId = res.id
|
||||
await API.saveUserData({ loc: ud.loc })
|
||||
}
|
||||
|
||||
goto(`/results/${res.id}`, { replaceState: true })
|
||||
@@ -158,7 +154,7 @@
|
||||
|
||||
<svelte:window onclick={() => musicControl?.ready()} onkeydown={() => musicControl?.ready()}/>
|
||||
|
||||
<PlayerAppBar song={data.song} bind:settings bind:loc disableHideRepeated={!!data.audioUrl} playlist={data.playlist} />
|
||||
<PlayerAppBar song={data.song} bind:settings={ud.settings} bind:loc={ud.loc} disableHideRepeated={!!data.audioUrl} playlist={data.playlist} />
|
||||
|
||||
<LinearProgress percent={progress} />
|
||||
|
||||
@@ -180,4 +176,4 @@
|
||||
</div>
|
||||
|
||||
<!-- Lines -->
|
||||
<Lyrics lines={processedLrc} currentLineIndex={li} currentWordIndex={wi} {states} {settings} showCaret={true} onLineClick={() => hiddenInput.focus()} />
|
||||
<Lyrics lines={processedLrc} currentLineIndex={li} currentWordIndex={wi} {states} settings={ud.settings} showCaret={true} onLineClick={() => hiddenInput.focus()} />
|
||||
Reference in New Issue
Block a user