-
+
{name}
progressBarOnClick(e)}
+ aria-valuemax={duration}
+ aria-valuemin="0"
+ aria-valuenow={progress}
bind:this={progressBar}
+ class="progress-bar shadow-md"
+ on:keydown
+ on:keyup
on:mousedown={() => {
userAdjustingProgress.set(true);
}}
on:mousemove={(e) => {
if ($userAdjustingProgress) {
+ console.log(e.offsetX )
adjustDisplayProgress(e.offsetX / progressBar.getBoundingClientRect().width);
}
}}
- on:touchstart={(e) => {
- if (e.cancelable) {
- e.preventDefault();
- }
- userAdjustingProgress.set(true);
- }}
- on:touchmove={(e) => {
- e.preventDefault();
- userAdjustingProgress.set(true);
- if ($userAdjustingProgress) {
- lastTouchProgress =
- turncate(
- e.touches[0].clientX - progressBar.getBoundingClientRect().x,
- 0,
- progressBar.getBoundingClientRect().width
- ) / progressBar.getBoundingClientRect().width;
- adjustDisplayProgress(lastTouchProgress);
- }
- }}
- on:touchend={(e) => {
- e.preventDefault();
- userAdjustingProgress.set(false);
- adjustProgress(lastTouchProgress);
- }}
- on:mouseup={() => {
- userAdjustingProgress.set(false);
+ on:mouseup={(e) => {
+ const offsetX = e.offsetX;
+ progressBarOnClick(e);
+ // Q: why it needs delay?
+ // A: I do not know.
+ setTimeout(()=> {
+ userAdjustingProgress.set(false);
+ progressBarMouseUp(offsetX);
+ }, 50);
}}
role="slider"
- aria-valuemin="0"
- aria-valuemax={duration}
- aria-valuenow={progress}
tabindex="0"
- on:keydown
- on:keyup
>
@@ -152,26 +136,49 @@
{formatDuration(duration)}
-

+
volumeBarOnChange(e)}
- bind:this={volumeBar}
+ on:keydown
+ on:keyup
on:mousedown={() => {
userAdjustingVolume = true;
}}
@@ -180,11 +187,12 @@
volumeBarOnChange(e);
}
}}
- on:touchstart={(e) => {
- if (e.cancelable) {
- e.preventDefault();
- }
- userAdjustingVolume = true;
+ on:mouseup={() => {
+ userAdjustingVolume = false;
+ }}
+ on:touchend={(e) => {
+ e.preventDefault();
+ userAdjustingVolume = false;
}}
on:touchmove={(e) => {
e.preventDefault();
@@ -193,24 +201,18 @@
volumeBarChangeTouch(e);
}
}}
- on:touchend={(e) => {
- e.preventDefault();
- userAdjustingVolume = false;
- }}
- on:mouseup={() => {
- userAdjustingVolume = false;
+ on:touchstart={(e) => {
+ if (e.cancelable) {
+ e.preventDefault();
+ }
+ userAdjustingVolume = true;
}}
role="slider"
- aria-valuemin="0"
- aria-valuemax="1"
- aria-valuenow={volume}
tabindex="0"
- on:keydown
- on:keyup
>
-

+
@@ -221,6 +223,7 @@
left: 50%;
transform: translate(-50%, 0);
}
+
.control-btn {
display: inline-block;
height: 3.7rem;
@@ -228,11 +231,10 @@
cursor: pointer;
margin: 0 0.5rem;
border-radius: 0.5rem;
- transition: 0.1s;
- }
- .control-btn:hover {
- background-color: rgba(0, 0, 0, 0.1);
+ transition: 0.45s;
+ scale: 1;
}
+
.control-img {
height: 2rem;
width: 2rem;
@@ -240,6 +242,7 @@
left: 50%;
transform: translateX(-50%);
}
+
.switch-song-img {
width: auto !important;
height: 1.7rem !important;
@@ -256,19 +259,21 @@
font-family: sans-serif;
text-align: center;
}
- .song-info-top {
+
+ .song-info-regular {
white-space: nowrap;
overflow: hidden;
position: relative;
+ height: 2.375rem;
}
- .song-info-top.animate {
+ .song-info-regular.animate {
mask-image: linear-gradient(
- 90deg,
- rgba(0, 0, 0, 0) 0%,
- rgba(0, 0, 0, 1) 2rem,
- rgba(0, 0, 0, 1) calc(100% - 5rem),
- rgba(0, 0, 0, 0) 100%
+ 90deg,
+ rgba(0, 0, 0, 0) 0%,
+ rgba(0, 0, 0, 1) 2rem,
+ rgba(0, 0, 0, 1) calc(100% - 5rem),
+ rgba(0, 0, 0, 0) 100%
);
}
@@ -283,12 +288,15 @@
height: 2.5rem;
display: inline-block;
}
+
.song-name.animate {
animation: scroll 10s linear infinite;
}
+
.song-name::-webkit-scrollbar {
display: none;
}
+
@keyframes scroll {
0% {
transform: translateX(100%);
@@ -300,10 +308,12 @@
transform: translateX(-100%);
}
}
+
.song-author {
font-size: 1.2rem;
color: rgba(255, 255, 255, 0.8);
}
+
.progress {
position: absolute;
width: 100%;
@@ -311,6 +321,7 @@
transform: translate(-50%, 0);
height: 2.4rem;
}
+
.progress-bar {
-webkit-appearance: none;
appearance: none;
@@ -325,9 +336,11 @@
cursor: pointer;
transition: 0.3s;
}
+
.progress-bar:hover {
height: 0.7rem;
}
+
.bar {
background-color: white;
position: absolute;
@@ -351,10 +364,18 @@
display: inline-block;
top: 0.2rem;
}
+
.time-current {
left: 0;
}
+
.time-total {
right: 0;
}
+
+ @media (min-width: 768px) {
+ .control-btn {
+ transition: 0.1s
+ }
+ }
diff --git a/src/lib/components/lyrics.svelte b/src/lib/components/lyrics.svelte
index 03a744e..59135ca 100644
--- a/src/lib/components/lyrics.svelte
+++ b/src/lib/components/lyrics.svelte
@@ -4,6 +4,8 @@
import progressBarRaw from '$lib/state/progressBarRaw';
import type { LrcJsonData } from 'lrc-parser-ts';
import progressBarSlideValue from '$lib/state/progressBarSlideValue';
+ import nextUpdate from '$lib/state/nextUpdate';
+ import truncate from '$lib/truncate';
// Component input properties
export let lyrics: string[];
@@ -12,24 +14,47 @@
// Local state and variables
let getLyricIndex: Function;
- const debugMode = false;
+ let debugMode = false;
+ if (localStorage.getItem('debugMode') == null) {
+ localStorage.setItem('debugMode', 'false');
+ }
+ else {
+ debugMode = localStorage.getItem('debugMode')!.toLowerCase() === "true";
+ }
let currentLyricIndex = -1;
let currentPositionIndex = -1;
let currentAnimationIndex = -1;
- let lyricsContainer: HTMLDivElement;
- let nextUpdate = -1;
+ let lyricsContainer: HTMLDivElement | null;
let lastAdjustProgress = 0;
let localProgress = 0;
let lastScroll = 0;
let scrolling = false;
let scriptScrolling = false;
+ let currentLyricTopMargin = 288;
+
// References to lyric elements
let refs: HTMLParagraphElement[] = [];
let _refs: any[] = [];
$: refs = _refs.filter(Boolean);
$: getLyricIndex = createLyricsSearcher(originalLyrics);
+
+ // handle KeyDown event
+ function onKeyDown(e: KeyboardEvent) {
+ if (e.altKey && e.shiftKey && (e.metaKey || e.key === 'OS') && e.key === 'Enter') {
+ debugMode = !debugMode;
+ localStorage.setItem('debugMode', debugMode ? 'true' : 'false');
+ }
+ }
+
+ // using for debug mode
+ function extractTranslateValue(s: string): string | null {
+ const regex = /translateY\((-?\d*px)\)/;
+ let arr = regex.exec(s);
+ return arr==null ? null : arr[1];
+ }
+
// Helper function to get CSS class for a lyric based on its index and progress
function getClass(lyricIndex: number, progress: number) {
if (!originalLyrics.scripts) return 'previous-lyric';
@@ -38,6 +63,100 @@
else return 'previous-lyric';
}
+ // Function to move the lyrics up smoothly
+ async function moveToNextLine(h: number) {
+ console.debug(new Date().getTime() , 'moveToNextLine', h);
+ // the line that's going to process (like a pointer)
+ // by default, it's "the next line" after the lift
+ let processingLineIndex = currentPositionIndex + 2;
+
+ // modify translateY of all lines in viewport one by one to lift them up
+ for (let i = processingLineIndex; i < refs.length; i++) {
+ const lyric = refs[i];
+ lyric.style.transition =
+ `transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease, opacity 200ms ease,
+ font-size 200ms ease, scale 250ms ease`;
+ lyric.style.transform = `translateY(${-h}px)`;
+ processingLineIndex = i;
+ await sleep(75);
+ const twoLinesAhead = refs[i - 2];
+ if (lyricsContainer && twoLinesAhead.getBoundingClientRect().top > lyricsContainer.getBoundingClientRect().height) break;
+ }
+
+ if (refs.length - processingLineIndex < 3) {
+ for (let i = processingLineIndex; i < refs.length; i++) {
+ const lyric = refs[i];
+ lyric.style.transition =
+ 'transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
+ lyric.style.transform = `translateY(${-h}px)`;
+ processingLineIndex = i;
+ await sleep(75);
+ }
+ } else {
+ for (let i = processingLineIndex; i < refs.length; i++) {
+ refs[i].style.transition =
+ 'transform 0s, filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
+ const height = refs[i].getBoundingClientRect().height;
+ refs[i].style.transform = `translateY(${-height}px)`;
+ }
+ }
+
+ // wait until the animation end
+ await sleep(650);
+
+ // clear the transition to let the following style changes could be done without animation
+ for (let i = 0; i < refs.length; i++) {
+ refs[i].style.transition =
+ 'transform 0s, filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
+ }
+ // reset the translateY, and immediately scroll down to provide visual stability
+ for (let i = 0; i < refs.length; i++) {
+ refs[i].style.transform = `translateY(0px)`;
+ }
+ scriptScrolling = true;
+ if (lyricsContainer !== null) {
+ lyricsContainer.scrollTop += h;
+ }
+ await sleep(500);
+ scriptScrolling = false;
+ }
+
+ // Scroll the lyrics container to the given lyric
+ async function scrollToLyric(currentLyric: HTMLParagraphElement) {
+ if (!originalLyrics || !originalLyrics.scripts || !lyricsContainer) return;
+ scriptScrolling = true;
+ lyricsContainer.scrollTop += currentLyric.getBoundingClientRect().top - currentLyricTopMargin;
+ for (let i = 0; i < refs.length; i++) {
+ refs[i].style.transform = 'translateY(0px)';
+ }
+ setTimeout(() => {
+ scriptScrolling = false;
+ }, 500);
+ }
+
+ // Handle scroll events in the lyrics container
+ function scrollHandler() {
+ scrolling = !scriptScrolling;
+ if (scrolling && originalLyrics.scripts) {
+ lastScroll = new Date().getTime();
+ for (let i = 0; i < originalLyrics.scripts.length; i++) {
+ if (refs[i]) {
+ refs[i].style.filter = 'blur(0px)';
+ }
+ }
+ }
+ setTimeout(() => {
+ if (new Date().getTime() - lastScroll > 5000) {
+ scrolling = false;
+ }
+ }, 5500);
+ }
+
+ // Utility function to create a sleep/delay
+ function sleep(ms: number) {
+ return new Promise((resolve) => setTimeout(resolve, ms));
+ }
+
// Scroll to corresponding lyric while adjusting progress
$: {
if ($userAdjustingProgress == true) {
@@ -47,6 +166,7 @@
}
// Update the current lyric and apply blur effect based on the progress
+ // worked in real-time.
$: {
(() => {
if (!lyricsContainer || !originalLyrics.scripts) return;
@@ -57,10 +177,10 @@
if (cl.start <= progress && progress <= cl.end) {
currentLyricIndex = currentPositionIndex;
- nextUpdate = cl.end;
+ nextUpdate.set(cl.end);
} else {
currentLyricIndex = -1;
- nextUpdate = cl.start;
+ nextUpdate.set(cl.start);
}
const currentLyric = refs[currentPositionIndex];
@@ -68,7 +188,7 @@
for (let i = 0; i < scripts.length; i++) {
const offset = Math.abs(i - currentPositionIndex);
- const blurRadius = Math.min(offset * 1, 16);
+ const blurRadius = Math.min(offset * 0.96, 16);
if (refs[i]) {
refs[i].style.filter = `blur(${blurRadius}px)`;
}
@@ -76,73 +196,53 @@
})();
}
- // Utility function to create a sleep/delay
- function sleep(ms: number) {
- return new Promise((resolve) => setTimeout(resolve, ms));
+ // Main function that control's lyrics update during playing
+ // triggered by nextUpdate's update
+ async function lyricsUpdate(){
+ if (
+ currentPositionIndex < 0 ||
+ currentPositionIndex === currentAnimationIndex ||
+ currentPositionIndex === lastAdjustProgress ||
+ $userAdjustingProgress === true ||
+ scrolling
+ ) return;
+
+ const currentLyric = refs[currentPositionIndex];
+ const currentLyricRect = currentLyric.getBoundingClientRect();
+
+ if (originalLyrics.scripts && currentLyricRect.top < 0) return;
+
+ const offsetHeight = truncate(currentLyricRect.top - currentLyricTopMargin, 0, Infinity);
+
+ // prepare current line
+ currentLyric.style.transition = `transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease,
+ opacity 200ms ease, font-size 200ms ease, scale 250ms ease`;
+ currentLyric.style.transform = `translateY(${-offsetHeight}px)`;
+
+ for (let i = currentPositionIndex - 1; i >= 0; i--) {
+ refs[i].style.transition = `transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease,
+ opacity 200ms ease, font-size 200ms ease, scale 250ms ease`;
+ refs[i].style.transform = `translateY(${-offsetHeight}px)`;
+ }
+ if (currentPositionIndex + 1 < refs.length) {
+ const nextLyric = refs[currentPositionIndex + 1];
+ nextLyric.style.transition = `transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease,
+ opacity 200ms ease, font-size 200ms ease, scale 250ms ease`;
+ nextLyric.style.transform = `translateY(${-offsetHeight}px)`;
+ await moveToNextLine(offsetHeight);
+ }
+ currentAnimationIndex = currentPositionIndex;
}
- // Function to move the lyrics up smoothly
- async function moveToNextLine(h: number) {
- let pos = currentPositionIndex + 2;
- for (let i = currentPositionIndex + 2; i < refs.length; i++) {
- const lyric = refs[i];
- lyric.style.transition =
- 'transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
- lyric.style.transform = `translateY(${-h}px)`;
- pos = i;
- await sleep(75);
- if (refs[i - 2].getBoundingClientRect().top > lyricsContainer.getBoundingClientRect().height) break;
- }
- if (refs.length - pos < 3) {
- for (let i = pos; i < refs.length; i++) {
- const lyric = refs[i];
- lyric.style.transition =
- 'transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
- lyric.style.transform = `translateY(${-h}px)`;
- pos = i;
- await sleep(75);
- }
- } else {
- for (let i = pos; i < refs.length; i++) {
- refs[i].style.transition =
- 'transform 0s, filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
- const height = refs[i].getBoundingClientRect().height;
- refs[i].style.transform = `translateY(${-height}px)`;
- }
- }
+ nextUpdate.subscribe(lyricsUpdate)
- await sleep(650);
- for (let i = 0; i < refs.length; i++) {
- refs[i].style.transition =
- 'transform 0s, filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
- }
- for (let i = 0; i < refs.length; i++) {
- refs[i].style.transform = `translateY(0px)`;
- }
- scriptScrolling = true;
- lyricsContainer.scrollTop += h;
- setTimeout(() => {
- scriptScrolling = false;
- }, 500);
- }
-
- // Scroll the lyrics container to the given lyric
- async function scrollToLyric(currentLyric: HTMLParagraphElement) {
- if (!originalLyrics || !originalLyrics.scripts || !lyricsContainer) return;
- scriptScrolling = true;
- lyricsContainer.scrollTop += currentLyric.getBoundingClientRect().top - 144;
- setTimeout(() => {
- scriptScrolling = false;
- }, 500);
- }
-
- // Handle user adjusting progress state changes
- userAdjustingProgress.subscribe((v) => {
+ // Process while user is adjusting progress
+ userAdjustingProgress.subscribe((adjusting) => {
if (!originalLyrics) return;
const scripts = originalLyrics.scripts;
if (!scripts) return;
- if (v) {
+ if (adjusting) {
for (let i = 0; i < scripts.length; i++) {
refs[i].style.filter = `blur(0px)`;
}
@@ -175,91 +275,40 @@
}
});
- // Handle scroll events in the lyrics container
- function scrollHandler() {
- scrolling = !scriptScrolling;
- if (scrolling && originalLyrics.scripts) {
- lastScroll = new Date().getTime();
- for (let i = 0; i < originalLyrics.scripts.length; i++) {
- if (refs[i]) {
- refs[i].style.filter = 'blur(0px)';
- }
- }
- }
- setTimeout(() => {
- if (new Date().getTime() - lastScroll > 5000) {
- scrolling = false;
- }
- }, 5500);
- }
-
- // Update lyrics position based on progress
- $: {
- (() => {
- if ($userAdjustingProgress) {
- nextUpdate = progress;
- return;
- }
-
- if (nextUpdate - progress >= 0.05) return;
- if (
- currentPositionIndex < 0 ||
- currentPositionIndex === currentAnimationIndex ||
- currentPositionIndex === lastAdjustProgress ||
- scrolling
- )
- return;
-
- const currentLyric = refs[currentPositionIndex];
-
- if (originalLyrics.scripts && currentLyric.getBoundingClientRect().top < 0) return;
-
- const offsetHeight =
- refs[currentPositionIndex].getBoundingClientRect().height +
- refs[currentPositionIndex].getBoundingClientRect().top -
- 144;
-
- currentLyric.style.transition =
- 'transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
- currentLyric.style.transform = `translateY(${-offsetHeight}px)`;
-
- for (let i = currentPositionIndex - 1; i >= 0; i--) {
- refs[i].style.transition =
- 'transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
- const height = refs[i].getBoundingClientRect().height;
- refs[i].style.transform = `translateY(${-offsetHeight}px)`;
- }
- if (currentPositionIndex + 1 < refs.length) {
- const nextLyric = refs[currentPositionIndex + 1];
- nextLyric.style.transition =
- 'transform .6s cubic-bezier(.28,.01,.29,.99), filter 200ms ease, opacity 200ms ease, font-size 200ms ease, scale 250ms ease';
- nextLyric.style.transform = `translateY(${-offsetHeight}px)`;
- moveToNextLine(offsetHeight);
- }
- currentAnimationIndex = currentPositionIndex;
- })();
- }
-{#if lyrics && originalLyrics}
+
+
+{#if debugMode && lyricsContainer}
+
+
+ LyricIndex: {currentLyricIndex} PositionIndex: {currentPositionIndex}
+ AnimationIndex:{currentAnimationIndex}
+ NextUpdate: {$nextUpdate}
+ Progress: {progress.toFixed(2)}
+ lastAdjustProgress: {lastAdjustProgress}
+ scrollPosition: {lyricsContainer.scrollTop}
+
+
+{/if}
+
+
+{#if lyrics && originalLyrics && originalLyrics.scripts}
- {#if debugMode}
-
- LyricIndex: {currentLyricIndex} PositionIndex: {currentPositionIndex} AnimationIndex:{currentAnimationIndex}
- NextUpdate: {nextUpdate}
- Progress: {progress.toFixed(2)}
- lastAdjustProgress: {lastAdjustProgress}
-
- {/if}
{#each lyrics as lyric, i}
- {#if debugMode}
- {i}
+ {#if debugMode && refs[i] && refs[i].style !== undefined}
+ {i}
+ {originalLyrics.scripts[i].start} ~ {originalLyrics.scripts[i].end}
+ tY: {extractTranslateValue(refs[i].style.transform)}
+ top: {Math.round(refs[i].getBoundingClientRect().top)}px
+
{/if}
{lyric}
@@ -268,82 +317,103 @@
{/if}
+
diff --git a/src/lib/state/nextUpdate.ts b/src/lib/state/nextUpdate.ts
new file mode 100644
index 0000000..1ef1ac9
--- /dev/null
+++ b/src/lib/state/nextUpdate.ts
@@ -0,0 +1,3 @@
+import { writable } from 'svelte/store';
+const nextUpdate = writable(-1);
+export default nextUpdate;
\ No newline at end of file
diff --git a/src/lib/truncate.ts b/src/lib/truncate.ts
new file mode 100644
index 0000000..c10b4a4
--- /dev/null
+++ b/src/lib/truncate.ts
@@ -0,0 +1,3 @@
+export default function truncate(value: number, min: number, max: number) {
+ return Math.min(Math.max(value, min), max);
+}
\ No newline at end of file
diff --git a/src/routes/api/database/search/+server.ts b/src/routes/api/database/search/+server.ts
index ea4400a..52fa9c7 100644
--- a/src/routes/api/database/search/+server.ts
+++ b/src/routes/api/database/search/+server.ts
@@ -1,27 +1,28 @@
import { songNameCache } from '$lib/server/cache.js';
import { loadData } from '$lib/server/database/loadData';
-import { json, error } from '@sveltejs/kit';
+import { error, json } from '@sveltejs/kit';
+import type { RequestHandler } from './$types';
-export async function GET({ url }) {
- const keyword = url.searchParams.get("keyword");
+export const GET: RequestHandler = async ({ url }) => {
+ const keyword = url.searchParams.get('keyword');
- loadData();
+ await loadData();
if (keyword === null) {
return error(400, {
- "message": "Miss parameter: keyword"
- })
+ 'message': 'Miss parameter: keyword'
+ });
}
const resultList: MusicMetadata[] = [];
- for (const songName of songNameCache.keys()){
+ for (const songName of songNameCache.keys()) {
if (songName.toLocaleLowerCase().includes(keyword.toLocaleLowerCase())) {
resultList.push(songNameCache.get(songName)!);
}
}
- return json({
- "result": resultList
+ return json({
+ 'result': resultList
});
-}
\ No newline at end of file
+};
\ No newline at end of file
diff --git a/src/routes/api/database/song/[id]/+server.ts b/src/routes/api/database/song/[id]/+server.ts
index a6ba77a..7b03ee5 100644
--- a/src/routes/api/database/song/[id]/+server.ts
+++ b/src/routes/api/database/song/[id]/+server.ts
@@ -2,8 +2,9 @@ import { safePath } from '$lib/server/safePath';
import { getCurrentFormattedDateTime } from '$lib/songUpdateTime';
import { json, error } from '@sveltejs/kit';
import fs from 'fs';
+import type { RequestHandler } from './$types';
-export async function GET({ params }) {
+export const GET: RequestHandler = async ({ params }) => {
const filePath = safePath(`${params.id}.json`, { base: './data/song' });
if (!filePath) {
return error(404, {
@@ -13,13 +14,13 @@ export async function GET({ params }) {
let data;
try { data = fs.readFileSync(filePath); } catch (e) {
return error(404, {
- message: "No correspoding song."
+ message: "No corresponding song."
});
}
return json(JSON.parse(data.toString()));
}
-export async function POST({ params, request }) {
+export const POST: RequestHandler = async ({ request, params }) => {
const timeStamp = new Date().getTime();
try {
if (!fs.existsSync("./data/pending/")) {
diff --git a/src/routes/api/database/songs/+server.ts b/src/routes/api/database/songs/+server.ts
index 4daa7b3..101b9c7 100644
--- a/src/routes/api/database/songs/+server.ts
+++ b/src/routes/api/database/songs/+server.ts
@@ -1,8 +1,9 @@
import { songData } from '$lib/server/cache.js';
import { loadData } from '$lib/server/database/loadData.js';
import { json } from '@sveltejs/kit';
+import type { RequestHandler } from './$types';
-export async function GET({ url }) {
+export const GET: RequestHandler = async ({ url }) => {
const limit = parseInt(url.searchParams.get("limit") ?? "20");
const offset = parseInt(url.searchParams.get("offset") ?? "0");
loadData();
diff --git a/src/routes/database/edit/[id]/+page.server.ts b/src/routes/database/edit/[id]/+page.server.ts
index c274947..ce0f590 100644
--- a/src/routes/database/edit/[id]/+page.server.ts
+++ b/src/routes/database/edit/[id]/+page.server.ts
@@ -1,9 +1,8 @@
-/** @type {import('./$types').PageLoad} */
-import { safePath } from '$lib/server/safePath';
import fs from 'fs';
+import type { PageServerLoad } from './$types';
+import { safePath } from '$lib/server/safePath';
-
-export function load({ params }) {
+export const load: PageServerLoad = ({ params }) => {
const filePath = safePath(`${params.id}.json`, { base: './data/song' });
if (!filePath) {
return {
diff --git a/src/routes/play/[id]/+page.svelte b/src/routes/play/[id]/+page.svelte
index 9c2c853..a68d275 100644
--- a/src/routes/play/[id]/+page.svelte
+++ b/src/routes/play/[id]/+page.svelte
@@ -11,6 +11,8 @@
import lrcParser, { type LrcJsonData } from 'lrc-parser-ts';
import userAdjustingProgress from '$lib/state/userAdjustingProgress';
import type { IAudioMetadata } from 'music-metadata-browser';
+ import { onMount } from 'svelte';
+ import progressBarRaw from '$lib/state/progressBarRaw';
const audioId = $page.params.id;
let audioPlayer: HTMLAudioElement;
@@ -150,20 +152,12 @@
$: {
clearInterval(mainInterval);
mainInterval = setInterval(() => {
- if (
- audioPlayer !== null &&
- audioPlayer.currentTime !== undefined
- ) {
- if ($userAdjustingProgress === false)
- currentProgress = audioPlayer.currentTime;
- progressBarRaw.set(audioPlayer.currentTime);
- }
+ if ($userAdjustingProgress === false)
+ currentProgress = audioPlayer.currentTime;
+ progressBarRaw.set(audioPlayer.currentTime);
}, 50);
}
- import { onMount } from 'svelte';
- import progressBarRaw from '$lib/state/progressBarRaw';
-
onMount(() => {
audioPlayer.volume = localStorage.getItem('volume') ? Number(localStorage.getItem('volume')) : 1;
});
@@ -175,13 +169,7 @@
}
}
- $: {
- if (originalLyrics) {
- hasLyrics = true;
- } else {
- hasLyrics = false;
- }
- }
+ $: hasLyrics = !!originalLyrics;
readDB();