mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
Merge remote-tracking branch 'origin/main' into feature/design-implementation
This commit is contained in:
commit
877c431b13
19 files changed
+1353
-389
No files matched your search
@@ -3,6 +3,14 @@
|
||||
<div class="queue-header">
|
||||
<h3 class="queue-title">播放队列</h3>
|
||||
<span class="queue-count">{{ botQueue.length }} 首</span>
|
||||
<button
|
||||
v-if="botQueue.length > 0"
|
||||
class="clear-btn"
|
||||
@click="clearAndStop"
|
||||
title="清空队列并停止播放"
|
||||
>
|
||||
<Icon icon="mdi:stop-circle-outline" />
|
||||
</button>
|
||||
<button class="close-btn" @click="$emit('close')">
|
||||
<Icon icon="mdi:close" />
|
||||
</button>
|
||||
@@ -70,6 +78,15 @@ async function removeSong(index: number) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
async function clearAndStop() {
|
||||
try {
|
||||
await store.stop();
|
||||
await store.fetchQueue();
|
||||
} catch {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -117,6 +134,14 @@ async function removeSong(index: number) {
|
||||
&:hover { opacity: 1; }
|
||||
}
|
||||
|
||||
.clear-btn {
|
||||
font-size: 18px;
|
||||
opacity: 0.6;
|
||||
transition: opacity var(--transition-fast);
|
||||
color: var(--text-primary);
|
||||
&:hover { opacity: 1; }
|
||||
}
|
||||
|
||||
.queue-empty {
|
||||
padding: 40px 20px;
|
||||
text-align: center;
|
||||
|
||||
@@ -28,9 +28,10 @@
|
||||
<script setup lang="ts">
|
||||
import { Icon } from '@iconify/vue';
|
||||
import CoverArt from './CoverArt.vue';
|
||||
import { Song } from '../stores/player.js';
|
||||
|
||||
defineProps<{
|
||||
song: { id: string; name: string; artist: string; album: string; duration: number; coverUrl: string; platform: string };
|
||||
song: Song;
|
||||
index: number;
|
||||
active?: boolean;
|
||||
}>();
|
||||
|
||||
@@ -8,7 +8,7 @@ export interface Song {
|
||||
album: string;
|
||||
duration: number;
|
||||
coverUrl: string;
|
||||
platform: 'netease' | 'qq';
|
||||
platform: 'netease' | 'qq' | 'bilibili' | 'youtube';
|
||||
}
|
||||
|
||||
export interface BotStatus {
|
||||
@@ -259,6 +259,13 @@ export const usePlayerStore = defineStore('player', {
|
||||
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') {
|
||||
if (!this.activeBotId) return;
|
||||
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 });
|
||||
},
|
||||
|
||||
async addSong(song: Song) {
|
||||
if (!this.activeBotId) return;
|
||||
await axios.post(`/api/player/${this.activeBotId}/add-song`, { song });
|
||||
},
|
||||
|
||||
async playPlaylist(playlistId: string, platform = 'netease') {
|
||||
if (!this.activeBotId) return;
|
||||
await axios.post(`/api/player/${this.activeBotId}/play-playlist`, { playlistId, platform });
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
:song="song"
|
||||
:index="i + 1"
|
||||
:active="store.currentSong?.id === song.id"
|
||||
@play="store.play(song.name, song.platform)"
|
||||
@add="store.addToQueue(song.name, song.platform)"
|
||||
@play="store.playSong(song)"
|
||||
@add="store.addSong(song)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -35,7 +35,9 @@ import SongCard from '../components/SongCard.vue';
|
||||
|
||||
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);
|
||||
|
||||
onMounted(async () => {
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
v-for="song in store.dailySongs.slice(0, 12)"
|
||||
:key="song.id"
|
||||
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" />
|
||||
<div class="daily-name">{{ song.name }}</div>
|
||||
@@ -105,7 +105,7 @@
|
||||
v-for="song in store.bilibiliPopular.slice(0, 12)"
|
||||
:key="song.id"
|
||||
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" />
|
||||
<div class="daily-name">{{ song.name }}</div>
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
:song="song"
|
||||
:index="i + 1"
|
||||
:active="store.currentSong?.id === song.id"
|
||||
@play="store.playById(song.id, song.platform)"
|
||||
@add="store.addToQueueById(song.id, song.platform)"
|
||||
@play="store.playSong(song)"
|
||||
@add="store.addSong(song)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -53,6 +53,8 @@ import SongCard from '../components/SongCard.vue';
|
||||
const store = usePlayerStore();
|
||||
const route = useRoute();
|
||||
|
||||
import { Song } from '../stores/player.js';
|
||||
|
||||
interface PlaylistDetail {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -61,18 +63,8 @@ interface PlaylistDetail {
|
||||
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 songs = ref<SongItem[]>([]);
|
||||
const songs = ref<Song[]>([]);
|
||||
const loading = ref(true);
|
||||
|
||||
async function playAll() {
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
:song="song"
|
||||
:index="i + 1"
|
||||
:active="store.currentSong?.id === song.id"
|
||||
@play="store.playById(song.id, song.platform)"
|
||||
@add="store.addToQueueById(song.id, song.platform)"
|
||||
@play="store.playSong(song)"
|
||||
@add="store.addSong(song)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -50,7 +50,9 @@ const store = usePlayerStore();
|
||||
const route = useRoute();
|
||||
|
||||
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 searched = ref(false);
|
||||
|
||||
|
||||
Reference in new issue
Block a user