forked from miao-moe/QZMusic_PC
feat: 迁移架构&实现功能
- 持久化音量设置 - 搜索页支持自定义每页显示数量(持久化) - vite-electron-plugin迁移electron-vite
This commit is contained in:
44
src/preload/index.ts
Normal file
44
src/preload/index.ts
Normal 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)
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -190,6 +190,7 @@ const formatTime = (seconds2: number) => {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.player-bar {
|
.player-bar {
|
||||||
|
box-sizing: border-box;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ const togglePlaylists = () => {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.sidebar {
|
.sidebar {
|
||||||
|
box-sizing: border-box;
|
||||||
width: var(--sidebar-width);
|
width: var(--sidebar-width);
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background-color: var(--color-bg-secondary);
|
background-color: var(--color-bg-secondary);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { computed } from 'vue';
|
|||||||
import Sidebar from '../components/Sidebar.vue';
|
import Sidebar from '../components/Sidebar.vue';
|
||||||
import TopBar from '../components/TopBar.vue';
|
import TopBar from '../components/TopBar.vue';
|
||||||
import PlayerBar from '../components/PlayerBar.vue';
|
import PlayerBar from '../components/PlayerBar.vue';
|
||||||
import { usePlayerStore } from '../stores/player.ts';
|
import { usePlayerStore } from '../stores/player';
|
||||||
|
|
||||||
const playerStore = usePlayerStore();
|
const playerStore = usePlayerStore();
|
||||||
const hasSongs = computed(() => playerStore.playlist.length > 0);
|
const hasSongs = computed(() => playerStore.playlist.length > 0);
|
||||||
@@ -29,7 +29,6 @@ const hasSongs = computed(() => playerStore.playlist.length > 0);
|
|||||||
<style>
|
<style>
|
||||||
/* 这确保 width: 100% + padding 不会撑破容器 */
|
/* 这确保 width: 100% + padding 不会撑破容器 */
|
||||||
*, *::before, *::after {
|
*, *::before, *::after {
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { defineStore } from 'pinia';
|
|||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import { MessagePlugin } from 'tdesign-vue-next';
|
import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
import type { Song } from '../types/song';
|
import type { Song } from '../types/song';
|
||||||
import { parseLyric } from '../utils/lyricParser';
|
|
||||||
|
|
||||||
export enum PlayMode {
|
export enum PlayMode {
|
||||||
List = 'list',
|
List = 'list',
|
||||||
@@ -147,13 +146,7 @@ export const usePlayerStore = defineStore('player', () => {
|
|||||||
// Check if plugin API exists
|
// Check if plugin API exists
|
||||||
if (window.electronAPI?.plugin?.getLyric) {
|
if (window.electronAPI?.plugin?.getLyric) {
|
||||||
const rawLyric = await window.electronAPI.plugin.getLyric(song.source || 'kw', song.id.toString());
|
const rawLyric = await window.electronAPI.plugin.getLyric(song.source || 'kw', song.id.toString());
|
||||||
if (rawLyric) {
|
console.log(rawLyric)
|
||||||
const parsedLines = parseLyric(rawLyric);
|
|
||||||
if (parsedLines) {
|
|
||||||
lyrics.value = { lines: parsedLines };
|
|
||||||
}
|
|
||||||
console.log(lyrics)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
MessagePlugin.warning("当前插件不支持歌词获取").then()
|
MessagePlugin.warning("当前插件不支持歌词获取").then()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ const currentDate = computed(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content-wrapper {
|
.content-wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
max-width: 1400px;
|
max-width: 1400px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
@@ -116,6 +117,7 @@ const currentDate = computed(() => {
|
|||||||
border-radius: var(--radius-2xl);
|
border-radius: var(--radius-2xl);
|
||||||
-electron-corner-smoothing: 65%;
|
-electron-corner-smoothing: 65%;
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 32px;
|
gap: 32px;
|
||||||
@@ -362,6 +364,7 @@ const currentDate = computed(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.song-item {
|
.song-item {
|
||||||
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
|
|||||||
@@ -74,10 +74,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, onMounted } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { Icon } from '@iconify/vue';
|
import { Icon } from '@iconify/vue';
|
||||||
import { usePlayerStore } from '../stores/player.ts';
|
import { usePlayerStore } from '../stores/player';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const playerStore = usePlayerStore();
|
const playerStore = usePlayerStore();
|
||||||
@@ -140,6 +140,7 @@ const handlePlaySong = (index: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content-wrapper {
|
.content-wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
max-width: 1400px;
|
max-width: 1400px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
@@ -155,6 +156,7 @@ const handlePlaySong = (index: number) => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 40px;
|
padding: 0 40px;
|
||||||
|
box-sizing: border-box;
|
||||||
box-shadow: var(--shadow-lg);
|
box-shadow: var(--shadow-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,8 +362,7 @@ const handlePlaySong = (index: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* List Styles */
|
/* List Styles */
|
||||||
.song-list-container {
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-header {
|
.list-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -376,10 +377,10 @@ const handlePlaySong = (index: number) => {
|
|||||||
.col-album { width: 200px; }
|
.col-album { width: 200px; }
|
||||||
.col-time { width: 60px; text-align: right; }
|
.col-time { width: 60px; text-align: right; }
|
||||||
|
|
||||||
.song-list {
|
|
||||||
}
|
|
||||||
|
|
||||||
.song-item {
|
.song-item {
|
||||||
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 10px 16px;
|
padding: 10px 16px;
|
||||||
|
|||||||
@@ -227,6 +227,7 @@ watch(limit, (newLimit) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content-wrapper {
|
.content-wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
padding: 20px 30px; /* Reduced vertical padding, kept horizontal for spacing but flexible */
|
padding: 20px 30px; /* Reduced vertical padding, kept horizontal for spacing but flexible */
|
||||||
width: 100%;
|
width: 100%;
|
||||||
/* Removed max-width to allow full width usage as requested */
|
/* Removed max-width to allow full width usage as requested */
|
||||||
@@ -403,12 +404,12 @@ watch(limit, (newLimit) => {
|
|||||||
.col-time { text-align: right; }
|
.col-time { text-align: right; }
|
||||||
|
|
||||||
.song-item {
|
.song-item {
|
||||||
|
box-sizing: border-box;
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
transition: background-color 0.2s;
|
transition: background-color 0.2s;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--color-text-secondary);
|
color: var(--color-text-secondary);
|
||||||
width: 100%; /* Fill width */
|
width: 100%; /* Fill width */
|
||||||
box-sizing: border-box; /* Include padding in width */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.song-item:hover {
|
.song-item:hover {
|
||||||
|
|||||||
Reference in New Issue
Block a user