[+] Scroll-here
This commit is contained in:
@@ -38,17 +38,12 @@
|
||||
songs = []
|
||||
|
||||
API.netease.startImport(link)
|
||||
.catch(e => error = e.message)
|
||||
.then(data => {
|
||||
id = data.playlistId
|
||||
songs = data.songs
|
||||
|
||||
const interval = setInterval(() => {
|
||||
API.netease.checkProgress(data.id)
|
||||
.catch(e => {
|
||||
error = e.message
|
||||
clearInterval(interval)
|
||||
})
|
||||
.then(data => {
|
||||
songs = data.songs
|
||||
if (data.done) {
|
||||
@@ -56,8 +51,13 @@
|
||||
status = 'success'
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
error = e.message
|
||||
clearInterval(interval)
|
||||
})
|
||||
}, 1000)
|
||||
})
|
||||
.catch(e => error = e.message)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
<LinearProgress percent={progress.total ? progress.done / progress.total * 100 : 0}/>
|
||||
{/if}
|
||||
|
||||
<div class="vbox self-stretch flex-1 overflow-y-auto p-content min-h-0 gap-8px">
|
||||
<div class="vbox p-content scroll-here gap-8px">
|
||||
{#if status !== 'idle'}
|
||||
{#each songs as song}
|
||||
<div class="hbox gap-12px items-center">
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
<div class="m3-font-headline-small">歌曲列表</div>
|
||||
<div class="m3-font-label-small pb-3px">{songs.length} 首歌曲</div>
|
||||
</div>
|
||||
<div class="vbox gap-12px mt-12px pb-12px min-h-0 flex-shrink-1 overflow-y-auto">
|
||||
<div class="vbox gap-12px mt-12px pb-12px scroll-here">
|
||||
{#each songs as song, index}
|
||||
<a href="/song/{song.id}" class="p-content">
|
||||
<SongInfo info={song} />
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<MenuItem icon="i-material-symbols:download" onclick={() => goto("/import/netease")}>从网易云导入</MenuItem>
|
||||
</AppBar>
|
||||
|
||||
<div class="vbox p-content gap-12px">
|
||||
<div class="vbox p-content gap-12px scroll-here">
|
||||
{#each data.playlists as pl}
|
||||
<a href="/playlist/{pl.id}">
|
||||
<ImageListItem photoUrl={pl.coverImgUrl} title={pl.name} text={`${pl.creator.nickname} 创建`} right={`${pl.trackCount} 首歌`} />
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
|
||||
<AppBar title={data.song.name} sub={artistAndAlbum(data.song)} />
|
||||
|
||||
<div class="vbox gap-16px p-content flex-1 overflow-y-auto">
|
||||
<div class="vbox gap-16px p-content scroll-here">
|
||||
<div class="hbox gap-12px items-end! h-48px">
|
||||
<div class="m3-font-headline-small">练习结果</div>
|
||||
</div>
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
<script lang="ts">
|
||||
import AppBar from "../../../../components/appbar/AppBar.svelte";
|
||||
import type { PageProps } from "../$types"
|
||||
import { LinearProgress } from "m3-svelte";
|
||||
import { onMount, tick } from "svelte";
|
||||
import { typingSettingsDefault, type LyricSegment } from "../../../../shared/types.ts";
|
||||
import { isKana, isKanji, toHiragana, toKatakana, toRomaji } from "wanakana";
|
||||
import { composeList, fuzzyEquals, processLrcLine, dedupLines, type ProcLrcLine, type ProcLrcSeg } from "./IMEHelper.ts";
|
||||
import MenuItem from "../../../../components/material3/MenuItem.svelte";
|
||||
import AppBar from "../../../../components/appbar/AppBar.svelte"
|
||||
import type { PageProps } from "./$types"
|
||||
import { LinearProgress } from "m3-svelte"
|
||||
import { onMount, tick } from "svelte"
|
||||
import { typingSettingsDefault, type LyricSegment } from "../../../../shared/types.ts"
|
||||
import { isKana, isKanji, toHiragana, toKatakana, toRomaji } from "wanakana"
|
||||
import { composeList, fuzzyEquals, processLrcLine, dedupLines, type ProcLrcLine, type ProcLrcSeg } from "./IMEHelper.ts"
|
||||
import MenuItem from "../../../../components/material3/MenuItem.svelte"
|
||||
import "../../../../shared/ext.ts"
|
||||
import { API } from "$lib/client.ts";
|
||||
import { animateCaret } from "./animation.ts";
|
||||
import { goto } from '$app/navigation';
|
||||
import { artistAndAlbum } from "../../../../shared/tools.ts";
|
||||
import Button from "../../../../components/Button.svelte";
|
||||
import { API } from "$lib/client.ts"
|
||||
import { animateCaret } from "./animation.ts"
|
||||
import { goto } from '$app/navigation'
|
||||
import { artistAndAlbum } from "../../../../shared/tools.ts"
|
||||
|
||||
let { data }: PageProps = $props()
|
||||
|
||||
@@ -83,7 +82,7 @@
|
||||
|
||||
// On input changed: Convert to hiragana, compare with current position, update states
|
||||
function inputChanged(input: string, isComposed: boolean) {
|
||||
if (!processedLrc[li] || !states[li]) return;
|
||||
if (!processedLrc[li] || !states[li]) return
|
||||
if (!startTime && input) startTime = Date.now()
|
||||
console.log(`input changed: ${input}`)
|
||||
// Convert to hiragana
|
||||
@@ -129,7 +128,7 @@
|
||||
}
|
||||
|
||||
// Check next expected character, if it's neither kana nor kanji, skip it
|
||||
while (findLoc().let(({ exp, cLine }) => !isKana(exp) && !isKanji(exp) && incr(cLine)));
|
||||
while (findLoc().let(({ exp, cLine }) => !isKana(exp) && !isKanji(exp) && incr(cLine)))
|
||||
|
||||
// Prevent IME stuck
|
||||
if (imeUsed && inp && !isKana(inp[0]) && inp.split('').some(c => isKana(c)) ) {
|
||||
@@ -169,9 +168,9 @@
|
||||
})
|
||||
|
||||
if (loc?.currentPlaylistId) {
|
||||
loc.isFinished = true;
|
||||
loc.lastResultId = res.id;
|
||||
await API.saveUserData({ loc });
|
||||
loc.isFinished = true
|
||||
loc.lastResultId = res.id
|
||||
await API.saveUserData({ loc })
|
||||
}
|
||||
|
||||
goto(`/results/${res.id}`, { replaceState: true })
|
||||
@@ -213,13 +212,13 @@
|
||||
</div>
|
||||
|
||||
<!-- Lines -->
|
||||
<div bind:this={lrcWrapper} class="lrc-wrapper flex-1 overflow-y-auto" lang="ja-JP">
|
||||
<div bind:this={lrcWrapper} class="lrc-wrapper scroll-here" lang="ja-JP">
|
||||
<div class="vbox gap-12px py-32px relative min-h-full lrc-content">
|
||||
<div bind:this={caret} class="absolute bg-amber w-2px h-24px transition-all duration-75 z-10"></div>
|
||||
{#each processedLrc as line, l}
|
||||
<div class="lrc p-content text-center m3-font-body-large" class:active={l === li} role="button" tabindex="0"
|
||||
onclick={() => hiddenInput.focus()}
|
||||
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); hiddenInput.focus(); } }}>
|
||||
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); hiddenInput.focus() } }}>
|
||||
{#each line.parts as seg}
|
||||
{#if !seg.kanji}
|
||||
{#each seg.kana as char, c}
|
||||
|
||||
+7
-1
@@ -31,4 +31,10 @@ body
|
||||
.p-content
|
||||
// padding: 0 16px
|
||||
padding-left: 16px
|
||||
padding-right: 16px
|
||||
padding-right: 16px
|
||||
|
||||
.scroll-here
|
||||
align-self: stretch
|
||||
overflow-y: auto
|
||||
min-height: 0
|
||||
flex: 1
|
||||
Reference in New Issue
Block a user