[+] Options

This commit is contained in:
2025-11-19 14:52:13 +08:00
parent c55fb17498
commit c5abffc734
2 changed files with 78 additions and 11 deletions
+60
View File
@@ -0,0 +1,60 @@
<script lang="ts">
import { Layer } from "m3-svelte";
import type { Snippet } from "svelte";
let {
icon,
textIcon,
disabled = false,
onclick,
children,
}: {
icon?: string;
textIcon?: string;
disabled?: boolean;
onclick: () => void;
children: Snippet;
} = $props();
</script>
<button type="button" class="item focus-inset m3-font-label-large" {disabled} {onclick}>
<Layer />
{#if icon == "space"}
<span class="icon"></span>
{:else if icon || textIcon}
<span class="icon cbox {icon}">
{textIcon}
</span>
{/if}
{@render children()}
</button>
<style lang="scss">
.item {
display: flex;
align-items: center;
height: calc(3rem + var(--m3-util-density-term));
padding: 0 0.75rem;
gap: 0.75rem;
white-space: nowrap;
border: none;
position: relative;
background-color: transparent;
color: rgb(var(--m3-scheme-on-surface));
cursor: pointer;
}
.icon {
width: 1.5rem;
height: 1.5rem;
font-size: 1.3rem;
}
.item:disabled {
color: rgb(var(--m3-scheme-on-surface) / 0.38);
cursor: auto;
}
.item:disabled > .icon > :global(svg) {
color: rgb(var(--m3-scheme-on-surface) / 0.38);
}
</style>
+18 -11
View File
@@ -1,11 +1,12 @@
<script lang="ts">
import AppBar from "../../../components/appbar/AppBar.svelte";
import type { PageProps } from "./$types"
import { LinearProgress, MenuItem } from "m3-svelte";
import { LinearProgress } from "m3-svelte";
import { onMount } from "svelte";
import type { LyricSegment } from "../../../shared/types.ts";
import { isKana, isKanji, toHiragana } from "wanakana";
import { isKana, isKanji, toHiragana, toKatakana } from "wanakana";
import { composeList, fuzzyEquals } from "./IMEHelper.ts";
import MenuItem from "../../../components/material3/MenuItem.svelte";
let { data }: PageProps = $props()
@@ -15,6 +16,12 @@
let hiddenInput: HTMLInputElement
let inp = $state("")
// TODO: Persist settings
let settings = $state({
isFuri: true,
allKata: false
})
const preprocessKana = (kana: string) => settings.allKata ? toKatakana(kana) : kana
// Process each line into segments with swi (start word index) and kanji/kana
type ProcLrcSeg = { swi: number, kanji?: string, kana: string }
@@ -45,10 +52,8 @@
let now = $state(Date.now())
onMount(() => {
hiddenInput.focus()
const interval = setInterval(() => {
if (startTime) now = Date.now()
}, 1000)
hiddenInput.focus() // TODO: auto focus when focus lost
const interval = setInterval(() => { if (startTime) now = Date.now() }, 1000)
return () => clearInterval(interval)
})
@@ -87,6 +92,7 @@
$effect(() => inputChanged(inp, false))
// Computed stats
let flat = $derived(states.flat())
let progress = $derived(Math.min(100, Math.floor((flat.filter(s => s !== 'unseen').length / flat.length) * 100)))
let totalTyped = $derived(flat.filter(s => s !== 'unseen').length)
@@ -94,7 +100,8 @@
</script>
<AppBar title={data.brief.name} sub={data.brief.artists.map(a => a.name).join(", ") + " - " + data.brief.album}>
<MenuItem onclick={() => console.log("clicked")}>Mewo</MenuItem>
<MenuItem textIcon="あ" onclick={() => settings.isFuri = !settings.isFuri}>{settings.isFuri ? "隐藏" : "显示"}假名标注</MenuItem>
<MenuItem textIcon="カ" onclick={() => settings.allKata = !settings.allKata}>{settings.allKata ? "恢复平假名" : "全部转换为片假名"}</MenuItem>
</AppBar>
<LinearProgress percent={progress} />
@@ -126,15 +133,15 @@
{#each line.parts as seg}
{#if !seg.kanji}
{#each seg.kana as char, c}
<span class="{states[l][seg.swi + c]}">{char}</span>
<span class="{states[l][seg.swi + c]}">{preprocessKana(char)}</span>
{/each}
{:else}
<ruby>
<span class="{getKanjiState(l, seg)}">{seg.kanji}</span><rt>
<span class="{getKanjiState(l, seg)}">{seg.kanji}</span>{#if settings.isFuri}<rt>
{#each seg.kana as char, c}
<span class="{states[l][seg.swi + c]}">{char}</span>
<span class="{states[l][seg.swi + c]}">{preprocessKana(char)}</span>
{/each}
</rt>
</rt>{/if}
</ruby>
{/if}
{/each}