[+] Resume last
This commit is contained in:
@@ -2,6 +2,6 @@
|
||||
let { icon, ...rest } = $props();
|
||||
</script>
|
||||
|
||||
<button class="cbox w-48px h-48px" {...rest}>
|
||||
<span class="h-24px w-24px {icon}"></span>
|
||||
<button class="cbox size-48px" {...rest}>
|
||||
<span class="size-24px {icon}"></span>
|
||||
</button>
|
||||
@@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
import type { NeteaseSongBrief } from "../shared/songs";
|
||||
|
||||
let { info }: { info: NeteaseSongBrief } = $props();
|
||||
</script>
|
||||
|
||||
<div class="hbox gap-16px">
|
||||
<img class="rounded-16px size-68px" src={info.albumPic} alt="Album Art" />
|
||||
<div class="vbox">
|
||||
<div class="m3-font-title-large">{info.name}</div>
|
||||
<div class="hbox w-full">
|
||||
<div class="m3-font-body-medium m3-color-on-surface-variant">{info.artists.map(a => a.name).join(", ")} - {info.album}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<script lang="ts">
|
||||
import IconButton from "./IconButton.svelte";
|
||||
|
||||
let { title, ...rest } = $props()
|
||||
</script>
|
||||
|
||||
<div class="hbox h-full px-16px" {...rest}>
|
||||
<div class="m3-font-title-large">{title}</div>
|
||||
<IconButton icon="i-material-symbols:arrow-forward" />
|
||||
</div>
|
||||
@@ -19,4 +19,4 @@
|
||||
{#if settings}
|
||||
<IconButton icon="i-material-symbols:settings-rounded" onclick={settings} aria-label="Settings" />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
// import { log } from 'console';
|
||||
import { getSongMeta, parseBrief } from '../shared/songs';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ params }) => {
|
||||
let last = parseBrief(await getSongMeta(25723366))
|
||||
return { last }
|
||||
}
|
||||
+24
-2
@@ -1,7 +1,29 @@
|
||||
<script>
|
||||
import { Button } from "m3-svelte"
|
||||
<script lang="ts">
|
||||
import AppBar from "../components/appbar/AppBar.svelte";
|
||||
import TitleHeader from "../components/TitleHeader.svelte";
|
||||
import SongInfo from "../components/SongInfo.svelte";
|
||||
import type { PageProps } from "./$types";
|
||||
|
||||
let { data }: PageProps = $props()
|
||||
</script>
|
||||
|
||||
|
||||
<AppBar account={() => alert('Account clicked')} settings={() => alert('Settings clicked')} />
|
||||
|
||||
<div class="vbox gap-16px">
|
||||
{#if data.last}
|
||||
<div>
|
||||
<TitleHeader title="从暂停的位置继续"/>
|
||||
<div class="p-content">
|
||||
<SongInfo info={data.last}></SongInfo>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div>
|
||||
<TitleHeader title="最近播放"/>
|
||||
<div class="p-content">
|
||||
最近播放的列表
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+22
-1
@@ -4,4 +4,25 @@
|
||||
|
||||
body
|
||||
margin: 0
|
||||
background: rgb(var(--m3-scheme-background))
|
||||
background: rgb(var(--m3-scheme-background))
|
||||
|
||||
.hbox
|
||||
display: flex
|
||||
flex-direction: row
|
||||
align-items: center
|
||||
|
||||
.vbox
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
.vcbox
|
||||
@extend .vbox
|
||||
align-items: center
|
||||
|
||||
.cbox
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
.p-content
|
||||
padding: 0 16px
|
||||
+19
-11
@@ -54,8 +54,14 @@ const getPlaylistRaw = cached(
|
||||
await fs.writeFile(p, JSON.stringify(track), 'utf-8')
|
||||
}
|
||||
return pl
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
export const getSongMeta = cached(
|
||||
async (songId: number) => path.join('data', 'songs', `${songId}`, 'meta.json'),
|
||||
async (songId: number) => {
|
||||
const detail = await ne.song_detail({ ids: songId.toString() })
|
||||
return detail.body.songs[0]
|
||||
})
|
||||
|
||||
export interface NeteaseSongBrief {
|
||||
id: number
|
||||
@@ -66,20 +72,22 @@ export interface NeteaseSongBrief {
|
||||
artists: { id: number, name: string }[]
|
||||
}
|
||||
|
||||
export const parseBrief = (songData: any): NeteaseSongBrief => ({
|
||||
id: songData.id,
|
||||
name: songData.name,
|
||||
album: songData.al.name,
|
||||
albumId: songData.al.id,
|
||||
albumPic: songData.al.picUrl,
|
||||
artists: songData.ar.map((ar: any) => ({ id: ar.id, name: ar.name }))
|
||||
})
|
||||
|
||||
/**
|
||||
* Get a list of songs from a playlist reference.
|
||||
*/
|
||||
export async function getSongsFromPlaylist(ref: string): Promise<any[]> {
|
||||
const playlistId = parsePlaylistRef(ref)
|
||||
const plData = await getPlaylistRaw({ id: playlistId })
|
||||
return plData.playlist.tracks.map((track: any) => ({
|
||||
id: track.id,
|
||||
name: track.name,
|
||||
album: track.al.name,
|
||||
albumId: track.al.id,
|
||||
albumPic: track.al.picUrl,
|
||||
artists: track.ar.map((ar: any) => ({ id: ar.id, name: ar.name }))
|
||||
}))
|
||||
return plData.playlist.tracks.map(parseBrief)
|
||||
}
|
||||
|
||||
interface NeteaseLyricsResponse { lrc: { lyric: string } }
|
||||
@@ -98,4 +106,4 @@ export const getLyricsProcessed = cached(
|
||||
)
|
||||
|
||||
// console.log((await getSongsFromPlaylist('580208139')).length)
|
||||
console.log(await getLyricsProcessed(25723366))
|
||||
// console.log(await getLyricsProcessed(25723366))
|
||||
@@ -105,11 +105,6 @@ export default defineConfig({
|
||||
})]
|
||||
],
|
||||
shortcuts: {
|
||||
// Azalea's shortcuts
|
||||
'hbox': 'flex flex-row items-center',
|
||||
'vbox': 'flex flex-col items-center',
|
||||
'cbox': 'flex justify-center items-center',
|
||||
|
||||
// Marina
|
||||
'form-error': 'text-3.5 font-medium text-destructive',
|
||||
'form-warning': 'text-3.5 font-medium text-warning',
|
||||
|
||||
Reference in New Issue
Block a user