Skip to content

Commit

Permalink
feature: frontend for database showing page
Browse files Browse the repository at this point in the history
basic frontend for submit & edit page
  • Loading branch information
alikia2x committed Jul 11, 2024
1 parent a306438 commit a9b1a3f
Show file tree
Hide file tree
Showing 13 changed files with 352 additions and 32 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ node_modules
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
data/pending
86 changes: 85 additions & 1 deletion data/song/BV1Xp421o7hr.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,89 @@
{
"id": "BV1Xp421o7hr",
"name": "大哉乾元",
"singer": "洛天依",
"url": "https://www.bilibili.com/video/BV1Xp421o7hr",
"singer": [
"洛天依"
],
"producer": "哈米伦的弄笛者",
"tuning": [
"Creuzer"
],
"lyricist": [
"非桥段"
],
"composer": [
"胡多多"
],
"arranger": [
"胡多多"
],
"mixing": [
"明宣May"
],
"pv": [
"宇言DX",
"顺-其自然",
"Kensei",
"残垣留梦",
"Bung Kon",
"XiroKyo",
"学渣的本愿",
"La pazienza",
"妮可",
"高米迪战士",
"蓉蓉",
"妖孽"
],
"illustrator": [
"Clay菌",
"吃咖喱的poi",
"彩虹咸鱼YA",
"鵺心NUECO",
"知木绕林",
"长耳朵喵舔毛狂魔",
"龙川川川子",
"洛橘",
"脑子",
"依枕云屏",
"鷁-",
"一只勺子spoon",
"腥红",
"叹云洲",
"顾奔波",
"辚古",
"Small小_小小白",
"晓溪",
"羽虫",
"千山白",
"火锅加番茄",
"大写的TY"
],
"harmony": [
"言和",
"乐正绫",
"乐正龙牙",
"墨清弦",
"徵羽摩柯"
],
"instruments": [
"墨韵",
"浑元",
"王佳男",
"李乐",
"李弦月",
"小陈同学"
],
"songURL": [
"https://assets.aquavox.app/public/BV1Xp421o7hr.mp3"
],
"coverURL": [
"https://assets.aquavox.app/public/BV1Xp421o7hr.jpg",
"https://ipfs.a2x.pub/ipfs/QmY76zgNJEerm75tiwoWaFg4Uq2NrJQiTjHiTWK6X2VLyb?filename=BV1Xp421o7hr.jpg"
],
"duration": 259.54,
"views": 2733456,
"publishTime": "2024-02-09 20:31:23",
"updateTime": "2024-07-12 00:23:22",
"lyric": "[ti: 大哉乾元]\n[ar: 洛天依]\n[al: 2024哔哩哔哩拜年纪]\n[tool: 歌词滚动姬 https://lrc-maker.github.io]\n[length: 04:19.536]\n[00:05.630] 经起幽明 悟处通玄\n[00:09.680] 首窥龙堑 见岳见渊\n[00:13.640] 道不善宣 义不善绻\n[00:17.270] 源流万世 大哉乾元!\n[00:21.837]\n[00:36.390] 不曾闻日月争辉\n[00:38.170] 坎离复往 立下恒规\n[00:40.330] 照东南 有坤徇乾 承西北\n[00:43.680] 天道自昆仑巍巍\n[00:45.590] 翻起华夏巽震艮兑\n[00:47.810] 万象予万灵得见 两相盈岁\n[00:51.210] 潜龙长生应紫微\n[00:53.000] 惟向四方五气寻遂\n[00:55.200] 燧火旁八卦百草揆经纬\n[00:58.220] 正位 纪天下一归\n[01:00.370] 不消祈天退水\n[01:02.590] 初难知一念一决生龙髓\n[01:05.930] 百家注龙慧 千军起龙威 砥淬\n[01:10.260] 妙笔生文穗 罡风抚长麾\n[01:13.030] 始见龙形汇 以天田冲腾直向九陲\n[01:20.490] 龙震于疆 万里宁壤 天地皆可往\n[01:24.140] 龙秀于象 引仙来访 诗蜀道河江\n[01:27.940] 龙明于章 执笔成鉴 映五千煌煌\n[01:31.820] 不独九州五岳 帝王将相见苍茫\n[01:35.340] 龙泽于汤 唤水筑乡 单舟见京杭\n[01:39.040] 龙健于常 百音同讲 道一种炎黄\n[01:42.740] 龙景于康 见之庙堂 亦显于曲坊\n[01:46.580] 不劳此间祥云瑞兽频频诰春长!\n[01:57.280] 干支移晷又几回\n[01:59.500] 揽尽天骄襄助一醉\n[02:01.790] 虽万言竟道不尽无字碑\n[02:04.680] 临渊乾乾 君子催\n[02:06.600] 或跃 无咎相随\n[02:09.130] 同为龙 却与往昔不连讳\n[02:12.390] 且待飞龙归 簸却沧溟水 如沸\n[02:16.700] 有龙掸风雷 见首不见尾\n[02:19.540] 苏苏万物蜕 证元亨利贞变易轮回\n[02:27.080] 龙华于旸 红旗漫卷 新水濯旧隍\n[02:30.740] 龙泰于霜 烽烟消长 更赳赳昂昂\n[02:34.430] 龙温于壮 留待潺潺 驰涌成泱泱\n[02:38.260] 好教流光紫极 鹊渡银潢伴流觞\n[02:41.660] 龙韧于刚 龙吟激荡 云止聆佳响\n[02:45.490] 龙德于昌 喜见船马 纵横间丰仓\n[02:49.150] 龙眷于邦 情习众广 仍化为一方\n[02:52.930] 其妙错综复杂 不孤兵车付一匡!\n[02:56.602]\n[03:40.980] 此去向东 瀚海游龙 滔滔几万重\n[03:44.620] 一跃破空 乘风逐虹 猎猎青云中\n[03:48.250] 天音入梦 扶摇上穹 矫矫游星宫\n[03:52.080] 犹念神州谷稻耕耘收藏守时无?\n[03:55.670] 一息一动 似异似同 无之以为用\n[03:59.240] 天地辰龙 龙生九种 但两爻合共\n[04:03.130] 假逢童蒙 欲解懵懂 何处有真龙\n[04:06.830] 只道「大哉乾元」秩秩幽幽必然中\n[04:10.350] 也道「大哉乾元」切切实实一言中!\n[04:14.693]"
}
10 changes: 0 additions & 10 deletions src/lib/components/interactiveBox.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -168,16 +168,6 @@
</div>
<div class="relative top-52 h-6 flex">
<img class="scale-75" src="/volumeDown.svg" alt="最小音量" />
<!-- <input
class="mx-2 progress-bar shadow-md !translate-y-[-50%] !top-1/2"
bind:this={volumeBar}
on:input={volumeBarOnChange}
type="range"
min="0"
max="1"
step="0.01"
value={$userAdjustingProgress ? volumeBar.value : volume}
/> -->
<div
class="progress-bar shadow-md !top-1/2 !translate-y-[-50%]"
on:click={(e) => volumeBarOnChange(e)}
Expand Down
8 changes: 8 additions & 0 deletions src/lib/formatViews.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function formatViews(num: number): string {
if (num >= 10000) {
const formattedNum = Math.floor(num / 1000) / 10; // 向下保留1位小数
return `${formattedNum} 万`;
} else {
return num.toString();
}
}
35 changes: 20 additions & 15 deletions src/lib/server/database/musicInfo.d.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
interface MusicMetadata {
id: string;
name: string;
signer?: string | string[];
producer?: string;
lyric?: string;
tuning?: string | string[];
lyricist?: string | string[];
composer?: string | string[];
arranger?: string | string[];
mixing?: string | string[];
video?: string | string[];
illustrator?: string | string[];
songURL?: string;
duration?: number;
publishTime?: string;
views?: number;
updateTime?: string;
url: string;
singer: string[];
producer: string | null;
tuning: string[];
lyricist: string[];
composer: string[];
arranger: string[];
mixing: string[];
pv: string[];
illustrator: string[];
harmony: string[];
instruments: string[];
songURL: string[];
coverURL: string[];
duration: number | null;
views: number | null;
publishTime: string | null;
updateTime: string | null;
lyric: string | null;
}
13 changes: 13 additions & 0 deletions src/lib/songUpdateTime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function getCurrentFormattedDateTime() {
const now = new Date();

const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // getMonth() is zero-based
const day = String(now.getDate()).padStart(2, '0');

const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');

return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
1 change: 0 additions & 1 deletion src/routes/+page.server.js

This file was deleted.

11 changes: 8 additions & 3 deletions src/routes/api/database/song/[id]/+server.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getCurrentFormattedDateTime } from '$lib/songUpdateTime';
import { json, error } from '@sveltejs/kit';
import fs from 'fs';

Expand All @@ -19,7 +20,11 @@ export async function POST({ params, request }) {
}
const filePath = `./data/pending/${params.id}-${timeStamp}.json`;
const data: MusicMetadata = await request.json();
data.updateTime = new Date().getTime().toString();
fs.writeFileSync(filePath, JSON.stringify(data));
return json({});
data.updateTime = getCurrentFormattedDateTime();
fs.writeFileSync(filePath, JSON.stringify(data, null, 4));
return json({
"message": "successfully created"
}, {
status: 201
});
}
86 changes: 84 additions & 2 deletions src/routes/database/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,3 +1,85 @@
<script lang="ts">
import formatDuration from '$lib/formatDuration';
import { formatViews } from '$lib/formatViews';
import { onMount } from 'svelte';
let songList: MusicMetadata[] = [];
onMount(async () => {
fetch('/api/database/songs')
.then((response) => response.json())
.then((data) => {
songList = data;
})
.catch((error) => {
console.log(error);
return [];
});
});
</script>

<svelte:head>
<title>AquaVox 音乐数据库</title>
</svelte:head>

<div>
<h1>AquaVox 音乐数据库</h1>
</div>
<div class="flex justify-between items-center h-20 mb-8">
<h1>AquaVox 音乐数据库</h1>
<a
href="/database/submit"
class="h-12 w-24 border-black dark:border-white border-2 flex items-center justify-center rounded-lg"
>提交新曲</a
>
</div>

<div class="grid">
{#each songList as song}
<a
class="relative w-56 h-56 bg-zinc-300 dark:bg-zinc-600 rounded-lg overflow-hidden
shadow-lg cursor-pointer"
href={song.url}
>
<div
class="absolute top-0 left-0 w-full h-full duration-100
z-10 opacity-0 hover:opacity-100 bg-[rgba(0,0,0,0.15)]"
>
<a
class="brightness-125 absolute top-2 right-2 w-8 h-8 rounded-full
bg-[rgba(49,49,49,0.7)] backdrop-blur-lg z-10 hover:bg-red-500"
href={`/database/edit/${song.id}`}
>
<img class="relative w-4 h-4 top-2 left-2 scale-90" src="/edit.svg" alt="编辑" />
</a>
</div>
<img src={song.coverURL[0]} class="w-56 h-56" alt="" />
<div
class="absolute bottom-0 w-full h-28 backdrop-blur-xl"
style="mask-image: linear-gradient(to top, black 50%, transparent);"
>
<div class="absolute bottom-0 w-full h-16 pl-2">
<span
class="font-semibold text-2xl text-white"
style="text-shadow: 0px 0px 4px rgba(65, 65, 65, .6);">{song.name}</span
>
<br />
<span
class="relative inline-block whitespace-nowrap text-white w-40
overflow-hidden text-ellipsis"
style="text-shadow: 0px 0px 4px rgba(65, 65, 65, .6);"
>
{song.singer.join(', ')}
</span>
<div class="absolute right-2 bottom-2 text-right">
{#if song.duration}
<span>{formatDuration(song.duration)}</span>
{/if}
<br />
{#if song.views}
<span>{formatViews(song.views)}</span>
{/if}
</div>
</div>
</div>
</a>
{/each}
</div>
</div>
24 changes: 24 additions & 0 deletions src/routes/database/edit/[id]/+page.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/** @type {import('./$types').PageLoad} */
import fs from 'fs';


export function load({ params }) {
const filePath = `./data/song/${params.id}.json`;
if (!fs.existsSync(filePath)) {
return {
songData: null
}
}
const dataBuffer = fs.readFileSync(filePath);
try {
const data = JSON.parse(dataBuffer.toString());
return {
songData: data
};
}
catch {
return {
songData: null
}
}
}
37 changes: 37 additions & 0 deletions src/routes/database/edit/[id]/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script lang="ts">
/** @type {import('./$types').PageData} */
export let data;
import { page } from '$app/stores';
const songID = $page.params.id;
let editingData: string = JSON.stringify(data.songData, null, 8);
async function submit() {
fetch(`/api/database/song/${songID}`, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: editingData
})
.catch((error) => {
console.log(error);
return [];
});
}
</script>

<svelte:head>
<title>建议编辑: {data.songData.name} ({songID})</title>
</svelte:head>

<h1>建议编辑: {data.songData.name} ({songID})</h1>

<textarea bind:value={editingData} class="dark:bg-zinc-600 w-full min-h-[30rem] mt-6" />

<button
class="mt-4 h-12 w-24 border-black dark:border-white border-2 flex items-center justify-center rounded-lg"
on:click={() => {
submit();
}}>提交</button
>
Loading

0 comments on commit a9b1a3f

Please sign in to comment.