mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-01 20:42:50 +08:00
fix #37
This commit is contained in:
1 parent
1bd6ab9975
commit
47514f57aa
9 files changed
+88
-101
No files matched your search
+22
-6
@@ -42,7 +42,7 @@ export class QQMusicProvider implements MusicProvider {
|
|||||||
|
|
||||||
const songs: Song[] = (res.data?.response?.data?.song?.list ?? []).map(
|
const songs: Song[] = (res.data?.response?.data?.song?.list ?? []).map(
|
||||||
(s: any) => ({
|
(s: any) => ({
|
||||||
id: String(s.songmid ?? s.songid),
|
id: String(s.mid ?? s.songmid ?? s.songid),
|
||||||
name: s.songname ?? "",
|
name: s.songname ?? "",
|
||||||
artist: (s.singer ?? []).map((a: any) => a.name).join(" / "),
|
artist: (s.singer ?? []).map((a: any) => a.name).join(" / "),
|
||||||
album: s.albumname ?? "",
|
album: s.albumname ?? "",
|
||||||
@@ -57,12 +57,26 @@ export class QQMusicProvider implements MusicProvider {
|
|||||||
return { songs, playlists: [], albums: [] };
|
return { songs, playlists: [], albums: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSongUrl(songId: string, _quality?: string): Promise<string | null> {
|
async getSongUrl(songId: string, quality?: string): Promise<string | null> {
|
||||||
|
try {
|
||||||
const res = await this.api.get("/getMusicPlay", {
|
const res = await this.api.get("/getMusicPlay", {
|
||||||
params: { songmid: songId, ...this.cookieParams },
|
params: { songmid: songId, quality: quality ?? this.quality, ...this.cookieParams },
|
||||||
});
|
});
|
||||||
const playUrl = res.data?.data?.playUrl?.[songId];
|
const playUrl = res.data?.data?.playUrl?.[songId];
|
||||||
return playUrl?.url || null;
|
if (playUrl?.url) return playUrl.url;
|
||||||
|
} catch {
|
||||||
|
// try with songid
|
||||||
|
try {
|
||||||
|
const res = await this.api.get("/getMusicPlay", {
|
||||||
|
params: { songid: songId, quality: quality ?? this.quality, ...this.cookieParams },
|
||||||
|
});
|
||||||
|
const playUrl = res.data?.data?.playUrl?.[songId];
|
||||||
|
if (playUrl?.url) return playUrl.url;
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSongDetail(songId: string): Promise<Song | null> {
|
async getSongDetail(songId: string): Promise<Song | null> {
|
||||||
@@ -115,12 +129,14 @@ export class QQMusicProvider implements MusicProvider {
|
|||||||
const cdlist = res.data?.response?.cdlist ?? [];
|
const cdlist = res.data?.response?.cdlist ?? [];
|
||||||
if (cdlist.length === 0) return [];
|
if (cdlist.length === 0) return [];
|
||||||
return (cdlist[0].songlist ?? []).map((s: any) => ({
|
return (cdlist[0].songlist ?? []).map((s: any) => ({
|
||||||
id: String(s.songmid ?? s.songid),
|
id: String(s.mid ?? s.songmid ?? s.songid),
|
||||||
name: s.songname ?? s.name ?? "",
|
name: s.songname ?? s.name ?? "",
|
||||||
artist: (s.singer ?? []).map((a: any) => a.name).join(" / "),
|
artist: (s.singer ?? []).map((a: any) => a.name).join(" / "),
|
||||||
album: s.albumname ?? "",
|
album: s.albumname ?? "",
|
||||||
duration: s.interval ?? 0,
|
duration: s.interval ?? 0,
|
||||||
coverUrl: s.albummid
|
coverUrl: s.album?.mid
|
||||||
|
? `https://y.gtimg.cn/music/photo_new/T002R300x300M000${s.album.mid}.jpg`
|
||||||
|
: s.albummid
|
||||||
? `https://y.gtimg.cn/music/photo_new/T002R300x300M000${s.albummid}.jpg`
|
? `https://y.gtimg.cn/music/photo_new/T002R300x300M000${s.albummid}.jpg`
|
||||||
: "",
|
: "",
|
||||||
platform: "qq",
|
platform: "qq",
|
||||||
|
|||||||
+34
-15
@@ -277,35 +277,54 @@ export function createPlayerRouter(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Play a single song by ID — resolves URL on demand
|
// Play a single song by ID — resolves URL on demand
|
||||||
router.post("/:botId/play-by-id", async (req, res) => {
|
router.post("/:botId/play-song", async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const bot = (req as any).bot;
|
const bot = (req as any).bot;
|
||||||
const { songId, platform } = req.body;
|
const { song } = req.body;
|
||||||
const provider = bot.getProviderFor(
|
if (!song || !song.id || !song.platform) {
|
||||||
platform === "bilibili" || platform === "qq" || platform === "youtube"
|
res.status(400).json({ error: "song object with id and platform is required" });
|
||||||
? platform
|
|
||||||
: "netease"
|
|
||||||
);
|
|
||||||
|
|
||||||
const song = await provider.getSongDetail(songId);
|
|
||||||
if (!song) {
|
|
||||||
res.json({ message: "Song not found" });
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const queue = bot.getQueueManager();
|
const queue = bot.getQueueManager();
|
||||||
queue.clear();
|
queue.clear();
|
||||||
queue.add({ ...song, platform: provider.platform });
|
queue.add(song);
|
||||||
queue.play();
|
queue.play();
|
||||||
|
|
||||||
bot.getPlayer().resetFailures();
|
bot.getPlayer().resetFailures();
|
||||||
const ok = await bot.resolveAndPlay(queue.current()!);
|
const ok = await bot.resolveAndPlay(queue.current()!);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
res.json({ message: `Cannot play: ${song.name}` });
|
res.json({ message: `Cannot play: ${song.name || song.id}` });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({ message: `Now playing: ${song.name} - ${song.artist}` });
|
res.json({ message: `Now playing: ${song.name || 'Unknown'} - ${song.artist || 'Unknown'}` });
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({ error: (err as Error).message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post("/:botId/add-song", async (req, res) => {
|
||||||
|
try {
|
||||||
|
const bot = (req as any).bot;
|
||||||
|
const { song } = req.body;
|
||||||
|
if (!song || !song.id || !song.platform) {
|
||||||
|
res.status(400).json({ error: "song object with id and platform is required" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const queue = bot.getQueueManager();
|
||||||
|
const wasIdle = bot.getPlayer().getState() === "idle";
|
||||||
|
queue.add(song);
|
||||||
|
|
||||||
|
// If nothing was playing, start this newly-added song immediately.
|
||||||
|
if (wasIdle) {
|
||||||
|
queue.playAt(queue.size() - 1);
|
||||||
|
bot.getPlayer().resetFailures();
|
||||||
|
await bot.resolveAndPlay(queue.current()!);
|
||||||
|
res.json({ message: `Now playing: ${song.name || 'Unknown'} - ${song.artist || 'Unknown'}` });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({ message: `Added to queue: ${song.name || 'Unknown'} - ${song.artist || 'Unknown'} (position ${queue.size()})` });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
res.status(500).json({ error: (err as Error).message });
|
res.status(500).json({ error: (err as Error).message });
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
-57
@@ -797,9 +797,6 @@
|
|||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -821,9 +818,6 @@
|
|||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -845,9 +839,6 @@
|
|||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -869,9 +860,6 @@
|
|||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -893,9 +881,6 @@
|
|||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -917,9 +902,6 @@
|
|||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1088,9 +1070,6 @@
|
|||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1105,9 +1084,6 @@
|
|||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1122,9 +1098,6 @@
|
|||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1139,9 +1112,6 @@
|
|||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1156,9 +1126,6 @@
|
|||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1173,9 +1140,6 @@
|
|||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1190,9 +1154,6 @@
|
|||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1207,9 +1168,6 @@
|
|||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1224,9 +1182,6 @@
|
|||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1241,9 +1196,6 @@
|
|||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1258,9 +1210,6 @@
|
|||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1275,9 +1224,6 @@
|
|||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -1292,9 +1238,6 @@
|
|||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
|
|||||||
@@ -28,9 +28,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Icon } from '@iconify/vue';
|
import { Icon } from '@iconify/vue';
|
||||||
import CoverArt from './CoverArt.vue';
|
import CoverArt from './CoverArt.vue';
|
||||||
|
import { Song } from '../stores/player.js';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
song: { id: string; name: string; artist: string; album: string; duration: number; coverUrl: string; platform: string };
|
song: Song;
|
||||||
index: number;
|
index: number;
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export interface Song {
|
|||||||
album: string;
|
album: string;
|
||||||
duration: number;
|
duration: number;
|
||||||
coverUrl: string;
|
coverUrl: string;
|
||||||
platform: 'netease' | 'qq';
|
platform: 'netease' | 'qq' | 'bilibili' | 'youtube';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BotStatus {
|
export interface BotStatus {
|
||||||
@@ -259,6 +259,13 @@ export const usePlayerStore = defineStore('player', {
|
|||||||
this._syncAfterAction();
|
this._syncAfterAction();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async playSong(song: Song) {
|
||||||
|
if (!this.activeBotId) return;
|
||||||
|
await axios.post(`/api/player/${this.activeBotId}/play-song`, { song });
|
||||||
|
this._setTiming(this.activeBotId, { serverElapsed: 0 });
|
||||||
|
this._syncAfterAction();
|
||||||
|
},
|
||||||
|
|
||||||
async addToQueue(query: string, platform = 'netease') {
|
async addToQueue(query: string, platform = 'netease') {
|
||||||
if (!this.activeBotId) return;
|
if (!this.activeBotId) return;
|
||||||
await axios.post(`/api/player/${this.activeBotId}/add`, { query, platform });
|
await axios.post(`/api/player/${this.activeBotId}/add`, { query, platform });
|
||||||
@@ -269,6 +276,11 @@ export const usePlayerStore = defineStore('player', {
|
|||||||
await axios.post(`/api/player/${this.activeBotId}/add-by-id`, { songId, platform });
|
await axios.post(`/api/player/${this.activeBotId}/add-by-id`, { songId, platform });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async addSong(song: Song) {
|
||||||
|
if (!this.activeBotId) return;
|
||||||
|
await axios.post(`/api/player/${this.activeBotId}/add-song`, { song });
|
||||||
|
},
|
||||||
|
|
||||||
async playPlaylist(playlistId: string, platform = 'netease') {
|
async playPlaylist(playlistId: string, platform = 'netease') {
|
||||||
if (!this.activeBotId) return;
|
if (!this.activeBotId) return;
|
||||||
await axios.post(`/api/player/${this.activeBotId}/play-playlist`, { playlistId, platform });
|
await axios.post(`/api/player/${this.activeBotId}/play-playlist`, { playlistId, platform });
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
:song="song"
|
:song="song"
|
||||||
:index="i + 1"
|
:index="i + 1"
|
||||||
:active="store.currentSong?.id === song.id"
|
:active="store.currentSong?.id === song.id"
|
||||||
@play="store.play(song.name, song.platform)"
|
@play="store.playSong(song)"
|
||||||
@add="store.addToQueue(song.name, song.platform)"
|
@add="store.addSong(song)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -35,7 +35,9 @@ import SongCard from '../components/SongCard.vue';
|
|||||||
|
|
||||||
const store = usePlayerStore();
|
const store = usePlayerStore();
|
||||||
|
|
||||||
const history = ref<Array<{ id: string; name: string; artist: string; album: string; duration: number; coverUrl: string; platform: string }>>([]);
|
import { Song } from '../stores/player.js';
|
||||||
|
|
||||||
|
const history = ref<Song[]>([]);
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
v-for="song in store.dailySongs.slice(0, 12)"
|
v-for="song in store.dailySongs.slice(0, 12)"
|
||||||
:key="song.id"
|
:key="song.id"
|
||||||
class="daily-card hover-scale"
|
class="daily-card hover-scale"
|
||||||
@click="store.playById(song.id, song.platform)"
|
@click="store.playSong(song)"
|
||||||
>
|
>
|
||||||
<CoverArt :url="song.coverUrl" :size="120" :radius="10" :show-shadow="true" />
|
<CoverArt :url="song.coverUrl" :size="120" :radius="10" :show-shadow="true" />
|
||||||
<div class="daily-name">{{ song.name }}</div>
|
<div class="daily-name">{{ song.name }}</div>
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
v-for="song in store.bilibiliPopular.slice(0, 12)"
|
v-for="song in store.bilibiliPopular.slice(0, 12)"
|
||||||
:key="song.id"
|
:key="song.id"
|
||||||
class="daily-card hover-scale"
|
class="daily-card hover-scale"
|
||||||
@click="store.playById(song.id, song.platform)"
|
@click="store.playSong(song)"
|
||||||
>
|
>
|
||||||
<CoverArt :url="song.coverUrl" :size="120" :radius="10" :show-shadow="true" />
|
<CoverArt :url="song.coverUrl" :size="120" :radius="10" :show-shadow="true" />
|
||||||
<div class="daily-name">{{ song.name }}</div>
|
<div class="daily-name">{{ song.name }}</div>
|
||||||
|
|||||||
@@ -31,8 +31,8 @@
|
|||||||
:song="song"
|
:song="song"
|
||||||
:index="i + 1"
|
:index="i + 1"
|
||||||
:active="store.currentSong?.id === song.id"
|
:active="store.currentSong?.id === song.id"
|
||||||
@play="store.playById(song.id, song.platform)"
|
@play="store.playSong(song)"
|
||||||
@add="store.addToQueueById(song.id, song.platform)"
|
@add="store.addSong(song)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -53,6 +53,8 @@ import SongCard from '../components/SongCard.vue';
|
|||||||
const store = usePlayerStore();
|
const store = usePlayerStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
import { Song } from '../stores/player.js';
|
||||||
|
|
||||||
interface PlaylistDetail {
|
interface PlaylistDetail {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -61,18 +63,8 @@ interface PlaylistDetail {
|
|||||||
songCount: number;
|
songCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SongItem {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
artist: string;
|
|
||||||
album: string;
|
|
||||||
duration: number;
|
|
||||||
coverUrl: string;
|
|
||||||
platform: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const playlist = ref<PlaylistDetail | null>(null);
|
const playlist = ref<PlaylistDetail | null>(null);
|
||||||
const songs = ref<SongItem[]>([]);
|
const songs = ref<Song[]>([]);
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
|
|
||||||
async function playAll() {
|
async function playAll() {
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
:song="song"
|
:song="song"
|
||||||
:index="i + 1"
|
:index="i + 1"
|
||||||
:active="store.currentSong?.id === song.id"
|
:active="store.currentSong?.id === song.id"
|
||||||
@play="store.playById(song.id, song.platform)"
|
@play="store.playSong(song)"
|
||||||
@add="store.addToQueueById(song.id, song.platform)"
|
@add="store.addSong(song)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -50,7 +50,9 @@ const store = usePlayerStore();
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
const query = ref((route.query.q as string) || '');
|
const query = ref((route.query.q as string) || '');
|
||||||
const results = ref<Array<{ id: string; name: string; artist: string; album: string; duration: number; coverUrl: string; platform: string }>>([]);
|
import { Song } from '../stores/player.js';
|
||||||
|
|
||||||
|
const results = ref<Song[]>([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const searched = ref(false);
|
const searched = ref(false);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user