feat: 迁移架构&实现功能

- 持久化音量设置
- 搜索页支持自定义每页显示数量(持久化)
- vite-electron-plugin迁移electron-vite
This commit is contained in:
lqtmcstudio
2026-02-06 14:57:32 +08:00
parent d6e1d11a52
commit 5a3ab02ee1
8 changed files with 60 additions and 17 deletions

44
src/preload/index.ts Normal file
View File

@@ -0,0 +1,44 @@
import { contextBridge, ipcRenderer } from 'electron'
contextBridge.exposeInMainWorld('electronAPI', {
// 窗口控制
minimizeWindow: () => ipcRenderer.send('window-minimize'),
maximizeWindow: () => ipcRenderer.send('window-maximize'),
closeWindow: () => ipcRenderer.send('window-close'),
isMaximized: () => ipcRenderer.invoke('window-is-maximized'),
// qzplayer Control
qzplayer: {
load: (url: string) => ipcRenderer.invoke('qzplayer-load', url),
play: () => ipcRenderer.invoke('qzplayer-play'),
pause: () => ipcRenderer.invoke('qzplayer-pause'),
togglePause: () => ipcRenderer.invoke('qzplayer-toggle-pause'),
stop: () => ipcRenderer.invoke('qzplayer-stop'),
setVolume: (vol: number) => ipcRenderer.invoke('qzplayer-set-volume', vol),
seek: (time: number) => ipcRenderer.invoke('qzplayer-seek', time),
onEvent: (callback: (event: any, data: any) => void) => ipcRenderer.on('qzplayer-event', callback)
},
// Plugin System
plugin: {
call: (pluginId: string, method: string, args: any[]) => ipcRenderer.invoke('plugin:call', pluginId, method, args),
search: (pluginId: string, query: string, page: number, limit: number) => ipcRenderer.invoke('plugin:call', pluginId, 'search', [query, page, limit]),
getLyric: (pluginId: string, id: string) => ipcRenderer.invoke('plugin:call', pluginId, 'getLyric', [id]),
},
// Cache Control
getCacheInfo: () => ipcRenderer.invoke('cache:getInfo'),
setCachePersist: (persist: boolean) => ipcRenderer.invoke('cache:setPersist', persist),
openCacheFolder: () => ipcRenderer.invoke('cache:openFolder'),
clearCache: () => ipcRenderer.invoke('cache:clear'),
// Settings
settings: {
getAll: () => ipcRenderer.invoke('settings:getAll'),
set: (settings: any) => ipcRenderer.invoke('settings:set', settings),
getTheme: () => ipcRenderer.invoke('settings:getTheme'),
setTheme: (theme: 'dark' | 'light') => ipcRenderer.invoke('settings:setTheme', theme),
getAccentColor: () => ipcRenderer.invoke('settings:getAccentColor'),
setAccentColor: (color: string) => ipcRenderer.invoke('settings:setAccentColor', color)
}
})

View File

@@ -190,6 +190,7 @@ const formatTime = (seconds2: number) => {
<style scoped>
.player-bar {
box-sizing: border-box;
position: fixed;
bottom: 0;
left: 0;

View File

@@ -93,6 +93,7 @@ const togglePlaylists = () => {
<style scoped>
.sidebar {
box-sizing: border-box;
width: var(--sidebar-width);
height: 100vh;
background-color: var(--color-bg-secondary);

View File

@@ -20,7 +20,7 @@ import { computed } from 'vue';
import Sidebar from '../components/Sidebar.vue';
import TopBar from '../components/TopBar.vue';
import PlayerBar from '../components/PlayerBar.vue';
import { usePlayerStore } from '../stores/player.ts';
import { usePlayerStore } from '../stores/player';
const playerStore = usePlayerStore();
const hasSongs = computed(() => playerStore.playlist.length > 0);
@@ -29,7 +29,6 @@ const hasSongs = computed(() => playerStore.playlist.length > 0);
<style>
/* 这确保 width: 100% + padding 不会撑破容器 */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}

View File

@@ -2,7 +2,6 @@ import { defineStore } from 'pinia';
import { ref, watch } from 'vue';
import { MessagePlugin } from 'tdesign-vue-next';
import type { Song } from '../types/song';
import { parseLyric } from '../utils/lyricParser';
export enum PlayMode {
List = 'list',
@@ -147,13 +146,7 @@ export const usePlayerStore = defineStore('player', () => {
// Check if plugin API exists
if (window.electronAPI?.plugin?.getLyric) {
const rawLyric = await window.electronAPI.plugin.getLyric(song.source || 'kw', song.id.toString());
if (rawLyric) {
const parsedLines = parseLyric(rawLyric);
if (parsedLines) {
lyrics.value = { lines: parsedLines };
}
console.log(lyrics)
}
console.log(rawLyric)
} else {
MessagePlugin.warning("当前插件不支持歌词获取").then()
}

View File

@@ -101,6 +101,7 @@ const currentDate = computed(() => {
}
.content-wrapper {
box-sizing: border-box;
padding: 24px;
max-width: 1400px;
margin: 0 auto;
@@ -116,6 +117,7 @@ const currentDate = computed(() => {
border-radius: var(--radius-2xl);
-electron-corner-smoothing: 65%;
padding: 40px;
box-sizing: border-box;
display: flex;
align-items: center;
gap: 32px;
@@ -362,6 +364,7 @@ const currentDate = computed(() => {
}
.song-item {
box-sizing: border-box;
display: flex;
align-items: center;
padding: 12px 16px;

View File

@@ -74,10 +74,10 @@
</template>
<script setup lang="ts">
import { computed, ref, onMounted } from 'vue';
import { computed, ref } from 'vue';
import { useRoute } from 'vue-router';
import { Icon } from '@iconify/vue';
import { usePlayerStore } from '../stores/player.ts';
import { usePlayerStore } from '../stores/player';
const route = useRoute();
const playerStore = usePlayerStore();
@@ -140,6 +140,7 @@ const handlePlaySong = (index: number) => {
}
.content-wrapper {
box-sizing: border-box;
padding: 30px;
max-width: 1400px;
margin: 0 auto;
@@ -155,6 +156,7 @@ const handlePlaySong = (index: number) => {
display: flex;
align-items: center;
padding: 0 40px;
box-sizing: border-box;
box-shadow: var(--shadow-lg);
}
@@ -360,8 +362,7 @@ const handlePlaySong = (index: number) => {
}
/* List Styles */
.song-list-container {
}
.list-header {
display: flex;
@@ -376,10 +377,10 @@ const handlePlaySong = (index: number) => {
.col-album { width: 200px; }
.col-time { width: 60px; text-align: right; }
.song-list {
}
.song-item {
box-sizing: border-box;
display: flex;
align-items: center;
padding: 10px 16px;

View File

@@ -227,6 +227,7 @@ watch(limit, (newLimit) => {
}
.content-wrapper {
box-sizing: border-box;
padding: 20px 30px; /* Reduced vertical padding, kept horizontal for spacing but flexible */
width: 100%;
/* Removed max-width to allow full width usage as requested */
@@ -403,12 +404,12 @@ watch(limit, (newLimit) => {
.col-time { text-align: right; }
.song-item {
box-sizing: border-box;
border-radius: var(--radius-lg);
transition: background-color 0.2s;
cursor: pointer;
color: var(--color-text-secondary);
width: 100%; /* Fill width */
box-sizing: border-box; /* Include padding in width */
}
.song-item:hover {