[+] Options
This commit is contained in:
@@ -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>
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import AppBar from "../../../components/appbar/AppBar.svelte";
|
import AppBar from "../../../components/appbar/AppBar.svelte";
|
||||||
import type { PageProps } from "./$types"
|
import type { PageProps } from "./$types"
|
||||||
import { LinearProgress, MenuItem } from "m3-svelte";
|
import { LinearProgress } from "m3-svelte";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import type { LyricSegment } from "../../../shared/types.ts";
|
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 { composeList, fuzzyEquals } from "./IMEHelper.ts";
|
||||||
|
import MenuItem from "../../../components/material3/MenuItem.svelte";
|
||||||
|
|
||||||
let { data }: PageProps = $props()
|
let { data }: PageProps = $props()
|
||||||
|
|
||||||
@@ -15,6 +16,12 @@
|
|||||||
|
|
||||||
let hiddenInput: HTMLInputElement
|
let hiddenInput: HTMLInputElement
|
||||||
let inp = $state("")
|
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
|
// Process each line into segments with swi (start word index) and kanji/kana
|
||||||
type ProcLrcSeg = { swi: number, kanji?: string, kana: string }
|
type ProcLrcSeg = { swi: number, kanji?: string, kana: string }
|
||||||
@@ -45,10 +52,8 @@
|
|||||||
let now = $state(Date.now())
|
let now = $state(Date.now())
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
hiddenInput.focus()
|
hiddenInput.focus() // TODO: auto focus when focus lost
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => { if (startTime) now = Date.now() }, 1000)
|
||||||
if (startTime) now = Date.now()
|
|
||||||
}, 1000)
|
|
||||||
return () => clearInterval(interval)
|
return () => clearInterval(interval)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -87,6 +92,7 @@
|
|||||||
|
|
||||||
$effect(() => inputChanged(inp, false))
|
$effect(() => inputChanged(inp, false))
|
||||||
|
|
||||||
|
// Computed stats
|
||||||
let flat = $derived(states.flat())
|
let flat = $derived(states.flat())
|
||||||
let progress = $derived(Math.min(100, Math.floor((flat.filter(s => s !== 'unseen').length / flat.length) * 100)))
|
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)
|
let totalTyped = $derived(flat.filter(s => s !== 'unseen').length)
|
||||||
@@ -94,7 +100,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<AppBar title={data.brief.name} sub={data.brief.artists.map(a => a.name).join(", ") + " - " + data.brief.album}>
|
<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>
|
</AppBar>
|
||||||
|
|
||||||
<LinearProgress percent={progress} />
|
<LinearProgress percent={progress} />
|
||||||
@@ -126,15 +133,15 @@
|
|||||||
{#each line.parts as seg}
|
{#each line.parts as seg}
|
||||||
{#if !seg.kanji}
|
{#if !seg.kanji}
|
||||||
{#each seg.kana as char, c}
|
{#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}
|
{/each}
|
||||||
{:else}
|
{:else}
|
||||||
<ruby>
|
<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}
|
{#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}
|
{/each}
|
||||||
</rt>
|
</rt>{/if}
|
||||||
</ruby>
|
</ruby>
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
Reference in New Issue
Block a user