mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
fix: add play mode toggle, wire play history API, add back navigation buttons
- Add play mode cycle button (seq/loop/random/rloop) to Player bar - Wire GET /api/player/:botId/history to query database instead of returning empty array - Pass database instance from server.ts to createPlayerRouter - Add back navigation button to Playlist, Lyrics, History, Search, and Settings views - SongCard already had dblclick-to-play (no change needed) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
9dce883384
commit
ee5a75ab5e
8 files changed
+141
-4
No files matched your search
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<div class="history-page">
|
||||
<button class="back-btn" @click="$router.back()">
|
||||
<Icon icon="mdi:arrow-left" />
|
||||
返回
|
||||
</button>
|
||||
<h1 class="page-title">播放历史</h1>
|
||||
|
||||
<div v-if="loading" class="loading">加载中...</div>
|
||||
@@ -24,6 +28,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { Icon } from '@iconify/vue';
|
||||
import axios from 'axios';
|
||||
import { usePlayerStore } from '../stores/player.js';
|
||||
import SongCard from '../components/SongCard.vue';
|
||||
@@ -52,6 +57,17 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.back-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
opacity: 0.7;
|
||||
margin-bottom: 16px;
|
||||
transition: opacity var(--transition-fast);
|
||||
&:hover { opacity: 1; }
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 28px;
|
||||
font-weight: 800;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<template>
|
||||
<div class="lyrics-page" :style="bgStyle">
|
||||
<div class="lyrics-overlay" />
|
||||
<button class="back-btn" @click="$router.back()">
|
||||
<Icon icon="mdi:arrow-left" />
|
||||
返回
|
||||
</button>
|
||||
|
||||
<div v-if="currentSong" class="lyrics-content">
|
||||
<div class="lyrics-left">
|
||||
@@ -40,6 +44,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
|
||||
import { Icon } from '@iconify/vue';
|
||||
import axios from 'axios';
|
||||
import { usePlayerStore } from '../stores/player.js';
|
||||
import CoverArt from '../components/CoverArt.vue';
|
||||
@@ -175,6 +180,20 @@ onUnmounted(() => {
|
||||
-webkit-backdrop-filter: blur(60px);
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
position: absolute;
|
||||
top: 24px;
|
||||
left: 24px;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
transition: color var(--transition-fast);
|
||||
&:hover { color: white; }
|
||||
}
|
||||
|
||||
.lyrics-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<div class="playlist-page">
|
||||
<button class="back-btn" @click="$router.back()">
|
||||
<Icon icon="mdi:arrow-left" />
|
||||
返回
|
||||
</button>
|
||||
<div v-if="loading" class="loading">加载中...</div>
|
||||
|
||||
<template v-else-if="playlist">
|
||||
@@ -101,6 +105,17 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.back-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
opacity: 0.7;
|
||||
margin-bottom: 16px;
|
||||
transition: opacity var(--transition-fast);
|
||||
&:hover { opacity: 1; }
|
||||
}
|
||||
|
||||
.playlist-hero {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<div class="search-page">
|
||||
<button class="back-btn" @click="$router.back()">
|
||||
<Icon icon="mdi:arrow-left" />
|
||||
返回
|
||||
</button>
|
||||
<div class="search-header">
|
||||
<div class="search-input-wrap">
|
||||
<Icon icon="mdi:magnify" class="search-icon" />
|
||||
@@ -89,6 +93,17 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.back-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
opacity: 0.7;
|
||||
margin-bottom: 16px;
|
||||
transition: opacity var(--transition-fast);
|
||||
&:hover { opacity: 1; }
|
||||
}
|
||||
|
||||
.search-header {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<div class="settings-page">
|
||||
<button class="back-btn" @click="$router.back()">
|
||||
<Icon icon="mdi:arrow-left" />
|
||||
返回
|
||||
</button>
|
||||
<h1 class="page-title">设置</h1>
|
||||
|
||||
<!-- Theme Toggle -->
|
||||
@@ -385,6 +389,17 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.back-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
opacity: 0.7;
|
||||
margin-bottom: 16px;
|
||||
transition: opacity var(--transition-fast);
|
||||
&:hover { opacity: 1; }
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 28px;
|
||||
font-weight: 800;
|
||||
|
||||
Reference in new issue
Block a user