refactor: 更新 eslint 和 prettier 配置 格式化代码

This commit is contained in:
alger
2025-07-23 23:54:35 +08:00
parent d1f5c8af84
commit c08c2cbf19
134 changed files with 3887 additions and 3301 deletions
-1
View File
@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ref } from 'vue';
// 定义表配置的泛型接口
+165 -129
View File
@@ -1,32 +1,59 @@
import { cloneDeep } from 'lodash';
import { createDiscreteApi } from 'naive-ui';
import { computed, nextTick, onUnmounted, ref, watch } from 'vue';
import { computed, type ComputedRef,nextTick, onUnmounted, ref, watch } from 'vue';
import { getBilibiliAudioUrl } from '@/api/bilibili';
import useIndexedDB from '@/hooks/IndexDBHook';
import { audioService } from '@/services/audioService';
import pinia, { usePlayerStore } from '@/store';
import type { usePlayerStore } from '@/store';
import { getSongUrl } from '@/store/modules/player';
import type { Artist, ILyricText, SongResult } from '@/type/music';
import { isElectron } from '@/utils';
import { getTextColors } from '@/utils/linearColor';
import { getSongUrl } from '@/store/modules/player';
const windowData = window as any;
const playerStore = usePlayerStore(pinia);
// 全局 playerStore 引用,通过 initMusicHook 函数注入
let playerStore: ReturnType<typeof usePlayerStore> | null = null;
// 初始化函数,接受 store 实例
export const initMusicHook = (store: ReturnType<typeof usePlayerStore>) => {
playerStore = store;
// 创建 computed 属性
playMusic = computed(() => getPlayerStore().playMusic as SongResult);
artistList = computed(
() => (getPlayerStore().playMusic.ar || getPlayerStore().playMusic?.song?.artists) as Artist[]
);
// 在 store 注入后初始化需要 store 的功能
setupKeyboardListeners();
initProgressAnimation();
setupMusicWatchers();
setupCorrectionTimeWatcher();
setupPlayStateWatcher();
};
// 获取 playerStore 的辅助函数
const getPlayerStore = () => {
if (!playerStore) {
throw new Error('MusicHook not initialized. Call initMusicHook first.');
}
return playerStore;
};
export const lrcArray = ref<ILyricText[]>([]); // 歌词数组
export const lrcTimeArray = ref<number[]>([]); // 歌词时间数组
export const nowTime = ref(0); // 当前播放时间
export const allTime = ref(0); // 总播放时间
export const nowIndex = ref(0); // 当前播放歌词
export const currentLrcProgress = ref(0); // 来存储当前歌词的进度
export const playMusic = computed(() => playerStore.playMusic as SongResult); // 当前播放歌曲
export const sound = ref<Howl | null>(audioService.getCurrentSound());
export const isLyricWindowOpen = ref(false); // 新增状态
export const textColors = ref<any>(getTextColors());
export const artistList = computed(
() => (playerStore.playMusic.ar || playerStore.playMusic?.song?.artists) as Artist[]
);
// 这些 computed 属性需要在初始化后创建
export let playMusic: ComputedRef<SongResult>;
export let artistList: ComputedRef<Artist[]>;
export const musicDB = await useIndexedDB('musicDB', [
{ name: 'music', keyPath: 'id' },
@@ -34,25 +61,29 @@ export const musicDB = await useIndexedDB('musicDB', [
{ name: 'api_cache', keyPath: 'id' }
]);
document.onkeyup = (e) => {
// 检查事件目标是否是输入框元素
const target = e.target as HTMLElement;
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
return;
}
// 键盘事件处理器,在初始化后设置
const setupKeyboardListeners = () => {
document.onkeyup = (e) => {
// 检查事件目标是否是输入框元素
const target = e.target as HTMLElement;
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
return;
}
switch (e.code) {
case 'Space':
if (playerStore.play) {
playerStore.setPlayMusic(false);
audioService.getCurrentSound()?.pause();
} else {
playerStore.setPlayMusic(true);
audioService.getCurrentSound()?.play();
}
break;
default:
}
const store = getPlayerStore();
switch (e.code) {
case 'Space':
if (store.play) {
store.setPlayMusic(false);
audioService.getCurrentSound()?.pause();
} else {
store.setPlayMusic(true);
audioService.getCurrentSound()?.play();
}
break;
default:
}
};
};
const { message } = createDiscreteApi(['message']);
@@ -72,7 +103,7 @@ const stopProgressAnimation = () => {
// 全局更新函数
const updateProgress = () => {
if (!playerStore.play) {
if (!getPlayerStore().play) {
stopProgressAnimation();
return;
}
@@ -120,11 +151,11 @@ const updateProgress = () => {
Math.floor(currentTime) !== Math.floor(lastSavedTime.value)
) {
lastSavedTime.value = currentTime;
if (playerStore.playMusic && playerStore.playMusic.id) {
if (getPlayerStore().playMusic && getPlayerStore().playMusic.id) {
localStorage.setItem(
'playProgress',
JSON.stringify({
songId: playerStore.playMusic.id,
songId: getPlayerStore().playMusic.id,
progress: currentTime
})
);
@@ -175,7 +206,7 @@ const initProgressAnimation = () => {
let debounceTimer: any = null;
watch(
() => playerStore.play,
() => getPlayerStore().play,
(newIsPlaying) => {
console.log('播放状态变化:', newIsPlaying);
@@ -217,7 +248,7 @@ const initProgressAnimation = () => {
// 监听当前歌词索引变化
watch(nowIndex, () => {
currentLrcProgress.value = 0;
if (playerStore.play) {
if (getPlayerStore().play) {
startProgressAnimation();
}
});
@@ -225,45 +256,45 @@ const initProgressAnimation = () => {
// 监听音频对象变化
watch(sound, (newSound) => {
console.log('sound 对象变化:', !!newSound);
if (newSound && playerStore.play) {
if (newSound && getPlayerStore().play) {
startProgressAnimation();
}
});
};
// 初始化进度动画
initProgressAnimation();
// 设置音乐相关的监听器
const setupMusicWatchers = () => {
const store = getPlayerStore();
// 移除对 playerStore.playMusicUrl 的监听,因为播放逻辑已经在 player.ts 中处理
// 保留 watch 对 playerStore.playMusic 的监听以更新歌词数据
// 监听 playerStore.playMusic 的变化以更新歌词数据
watch(
() => store.playMusic,
() => {
nextTick(async () => {
console.log('歌曲切换,更新歌词数据');
// 更新歌词数据
lrcArray.value = playMusic.value.lyric?.lrcArray || [];
lrcTimeArray.value = playMusic.value.lyric?.lrcTimeArray || [];
watch(
() => playerStore.playMusic,
() => {
nextTick(async () => {
console.log('歌曲切换,更新歌词数据');
// 更新歌词数据
lrcArray.value = playMusic.value.lyric?.lrcArray || [];
lrcTimeArray.value = playMusic.value.lyric?.lrcTimeArray || [];
// 当歌词数据更新时,如果歌词窗口打开,则发送数据
if (isElectron && isLyricWindowOpen.value) {
console.log('歌词窗口已打开,同步最新歌词数据');
// 不管歌词数组是否为空,都发送最新数据
sendLyricToWin();
// 再次延迟发送,确保歌词窗口已完全加载
setTimeout(() => {
// 当歌词数据更新时,如果歌词窗口打开,则发送数据
if (isElectron && isLyricWindowOpen.value) {
console.log('歌词窗口已打开,同步最新歌词数据');
// 不管歌词数组是否为空,都发送最新数据
sendLyricToWin();
}, 500);
}
});
},
{
deep: true,
immediate: true
}
);
// 再次延迟发送,确保歌词窗口已完全加载
setTimeout(() => {
sendLyricToWin();
}, 500);
}
});
},
{
deep: true,
immediate: true
}
);
};
const setupAudioListeners = () => {
let interval: any = null;
@@ -331,9 +362,9 @@ const setupAudioListeners = () => {
// 监听播放
audioService.on('play', () => {
playerStore.setPlayMusic(true);
getPlayerStore().setPlayMusic(true);
if (isElectron) {
window.api.sendSong(cloneDeep(playerStore.playMusic));
window.api.sendSong(cloneDeep(getPlayerStore().playMusic));
}
clearInterval();
interval = window.setInterval(() => {
@@ -383,7 +414,7 @@ const setupAudioListeners = () => {
// 监听暂停
audioService.on('pause', () => {
console.log('音频暂停事件触发');
playerStore.setPlayMusic(false);
getPlayerStore().setPlayMusic(false);
clearInterval();
if (isElectron && isLyricWindowOpen.value) {
sendLyricToWin();
@@ -400,17 +431,17 @@ const setupAudioListeners = () => {
}
// 重新播放当前歌曲
if (playerStore.playMusicUrl && playMusic.value) {
const newSound = await audioService.play(playerStore.playMusicUrl, playMusic.value);
if (getPlayerStore().playMusicUrl && playMusic.value) {
const newSound = await audioService.play(getPlayerStore().playMusicUrl, playMusic.value);
sound.value = newSound as Howl;
setupAudioListeners();
} else {
console.error('No music URL or playMusic data available');
playerStore.nextPlay();
getPlayerStore().nextPlay();
}
} catch (error) {
console.error('Error replaying song:', error);
playerStore.nextPlay();
getPlayerStore().nextPlay();
}
};
@@ -419,36 +450,36 @@ const setupAudioListeners = () => {
console.log('音频播放结束事件触发');
clearInterval();
if (playerStore.playMode === 1) {
if (getPlayerStore().playMode === 1) {
// 单曲循环模式
if (sound.value) {
replayMusic();
}
} else if (playerStore.playMode === 2) {
} else if (getPlayerStore().playMode === 2) {
// 随机播放模式
if (playerStore.playList.length <= 1) {
if (getPlayerStore().playList.length <= 1) {
replayMusic();
} else {
let randomIndex;
do {
randomIndex = Math.floor(Math.random() * playerStore.playList.length);
} while (randomIndex === playerStore.playListIndex && playerStore.playList.length > 1);
playerStore.playListIndex = randomIndex;
playerStore.setPlay(playerStore.playList[randomIndex]);
randomIndex = Math.floor(Math.random() * getPlayerStore().playList.length);
} while (randomIndex === getPlayerStore().playListIndex && getPlayerStore().playList.length > 1);
getPlayerStore().playListIndex = randomIndex;
getPlayerStore().setPlay(getPlayerStore().playList[randomIndex]);
}
} else {
// 列表循环模式
playerStore.nextPlay();
getPlayerStore().nextPlay();
}
});
audioService.on('previoustrack', () => {
playerStore.prevPlay();
getPlayerStore().prevPlay();
});
audioService.on('nexttrack', () => {
playerStore.nextPlay();
getPlayerStore().nextPlay();
});
return clearInterval;
@@ -464,11 +495,11 @@ export const pause = () => {
try {
// 保存当前播放进度
const currentTime = currentSound.seek() as number;
if (playerStore.playMusic && playerStore.playMusic.id) {
if (getPlayerStore().playMusic && getPlayerStore().playMusic.id) {
localStorage.setItem(
'playProgress',
JSON.stringify({
songId: playerStore.playMusic.id,
songId: getPlayerStore().playMusic.id,
progress: currentTime
})
);
@@ -503,15 +534,18 @@ loadCorrectionMap();
// 歌词矫正时间,当前歌曲
export const correctionTime = ref(0);
// 切歌时自动读取矫正时间
watch(
() => playMusic.value?.id,
(id) => {
if (!id) return;
correctionTime.value = correctionTimeMap.value[id] ?? 0;
},
{ immediate: true }
);
// 设置歌词矫正时间的监听器
const setupCorrectionTimeWatcher = () => {
// 切歌时自动读取矫正时间
watch(
() => playMusic.value?.id,
(id) => {
if (!id) return;
correctionTime.value = correctionTimeMap.value[id] ?? 0;
},
{ immediate: true }
);
};
/**
* 调整歌词矫正时间(每首歌独立)
@@ -557,7 +591,7 @@ const currentLrcTiming = computed(() => {
export const getLrcStyle = (index: number) => {
const currentTime = nowTime.value + correctionTime.value;
const start = lrcTimeArray.value[index];
const end = lrcTimeArray.value[index + 1] ?? (start + 1);
const end = lrcTimeArray.value[index + 1] ?? start + 1;
if (currentTime >= start && currentTime < end) {
// 当前句,显示进度
@@ -638,7 +672,7 @@ export const sendLyricToWin = () => {
nowTime: nowTime.value,
startCurrentTime: lrcTimeArray.value[nowIndex] || 0,
nextTime: lrcTimeArray.value[nowIndex + 1] || 0,
isPlay: playerStore.play,
isPlay: getPlayerStore().play,
lrcArray: lrcArray.value,
lrcTimeArray: lrcTimeArray.value,
allTime: allTime.value,
@@ -657,7 +691,7 @@ export const sendLyricToWin = () => {
nowTime: nowTime.value,
startCurrentTime: 0,
nextTime: 0,
isPlay: playerStore.play,
isPlay: getPlayerStore().play,
lrcArray: [{ text: '当前歌曲暂无歌词', trText: '' }],
lrcTimeArray: [0],
allTime: allTime.value,
@@ -682,14 +716,14 @@ const startLyricSync = () => {
// 每秒同步一次歌词数据
lyricSyncInterval = setInterval(() => {
if (isElectron && isLyricWindowOpen.value && playerStore.play && playMusic.value?.id) {
if (isElectron && isLyricWindowOpen.value && getPlayerStore().play && playMusic.value?.id) {
// 发送当前播放进度的更新
try {
const updateData = {
type: 'update',
nowIndex: getLrcIndex(nowTime.value),
nowTime: nowTime.value,
isPlay: playerStore.play
isPlay: getPlayerStore().play
};
window.api.sendLyric(JSON.stringify(updateData));
} catch (error) {
@@ -735,7 +769,7 @@ export const openLyric = () => {
nowTime: nowTime.value,
startCurrentTime: 0,
nextTime: 0,
isPlay: playerStore.play,
isPlay: getPlayerStore().play,
lrcArray: [{ text: '加载歌词中...', trText: '' }],
lrcTimeArray: [0],
allTime: allTime.value,
@@ -771,25 +805,28 @@ export const closeLyric = () => {
stopLyricSync();
};
// 在组件挂载时设置播放状态监听
watch(
() => playerStore.play,
(isPlaying) => {
// 如果歌词窗口打开,根据播放状态控制同步
if (isElectron && isLyricWindowOpen.value) {
if (isPlaying) {
startLyricSync();
} else {
// 如果暂停播放,发送一次暂停状态的更新
const pauseData = {
type: 'update',
isPlay: false
};
window.api.sendLyric(JSON.stringify(pauseData));
// 设置播放状态监听
const setupPlayStateWatcher = () => {
// 在组件挂载时设置对播放状态的监听
watch(
() => getPlayerStore().play,
(isPlaying) => {
// 如果歌词窗口打开,根据播放状态控制同步
if (isElectron && isLyricWindowOpen.value) {
if (isPlaying) {
startLyricSync();
} else {
// 如果暂停播放,发送一次暂停状态的更新
const pauseData = {
type: 'update',
isPlay: false
};
window.api.sendLyric(JSON.stringify(pauseData));
}
}
}
}
);
);
};
// 在组件卸载时清理资源
onUnmounted(() => {
@@ -801,20 +838,20 @@ if (isElectron) {
windowData.electron.ipcRenderer.on('lyric-control-back', (_, command: string) => {
switch (command) {
case 'playpause':
if (playerStore.play) {
playerStore.setPlayMusic(false);
if (getPlayerStore().play) {
getPlayerStore().setPlayMusic(false);
audioService.getCurrentSound()?.pause();
} else {
playerStore.setPlayMusic(true);
getPlayerStore().setPlayMusic(true);
audioService.getCurrentSound()?.play();
}
break;
case 'prev':
playerStore.prevPlay();
getPlayerStore().prevPlay();
break;
case 'next':
playerStore.nextPlay();
getPlayerStore().nextPlay();
break;
case 'close':
isLyricWindowOpen.value = false; // 确保状态更新
@@ -830,7 +867,7 @@ if (isElectron) {
export const initAudioListeners = async () => {
try {
// 确保有正在播放的音乐
if (!playerStore.playMusic || !playerStore.playMusic.id) {
if (!getPlayerStore().playMusic || !getPlayerStore().playMusic.id) {
console.log('没有正在播放的音乐,跳过音频监听器初始化');
return;
}
@@ -905,7 +942,7 @@ audioService.on('url_expired', async (expiredTrack) => {
// 更新存储
(expiredTrack as any).playMusicUrl = newUrl;
playerStore.playMusicUrl = newUrl;
getPlayerStore().playMusicUrl = newUrl;
// 重新播放并设置进度
const newSound = await audioService.play(newUrl, expiredTrack);
@@ -919,9 +956,9 @@ audioService.on('url_expired', async (expiredTrack) => {
}
// 如果之前是播放状态,继续播放
if (playerStore.play) {
if (getPlayerStore().play) {
newSound.play();
playerStore.setIsPlay(true);
getPlayerStore().setIsPlay(true);
}
message.success('已自动恢复播放');
@@ -933,7 +970,6 @@ audioService.on('url_expired', async (expiredTrack) => {
// 处理网易云音乐,重新获取URL
console.log('重新获取网易云音乐URL');
try {
const newUrl = await getSongUrl(expiredTrack.id, expiredTrack as any);
if (newUrl) {
@@ -941,7 +977,7 @@ audioService.on('url_expired', async (expiredTrack) => {
// 更新存储
(expiredTrack as any).playMusicUrl = newUrl;
playerStore.playMusicUrl = newUrl;
getPlayerStore().playMusicUrl = newUrl;
// 重新播放并设置进度
const newSound = await audioService.play(newUrl, expiredTrack);
@@ -955,9 +991,9 @@ audioService.on('url_expired', async (expiredTrack) => {
}
// 如果之前是播放状态,继续播放
if (playerStore.play) {
if (getPlayerStore().play) {
newSound.play();
playerStore.setIsPlay(true);
getPlayerStore().setIsPlay(true);
}
message.success('已自动恢复播放');
@@ -982,16 +1018,16 @@ window.addEventListener('audio-ready', ((event: CustomEvent) => {
if (newSound) {
// 更新本地 sound 引用
sound.value = newSound as Howl;
// 设置音频监听器
setupAudioListeners();
// 获取当前播放位置并更新显示
const currentPosition = newSound.seek() as number;
if (typeof currentPosition === 'number' && !Number.isNaN(currentPosition)) {
nowTime.value = currentPosition;
}
console.log('音频就绪,已设置监听器并更新进度显示');
}
} catch (error) {
+47 -45
View File
@@ -1,7 +1,7 @@
import { cloneDeep } from 'lodash';
import { useMessage } from 'naive-ui';
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useMessage } from 'naive-ui';
import { getSongUrl } from '@/store/modules/player';
import type { SongResult } from '@/type/music';
@@ -13,23 +13,23 @@ const ipcRenderer = isElectron ? window.electron.ipcRenderer : null;
const createDownloadManager = () => {
// 正在下载的文件集合
const activeDownloads = new Set<string>();
// 已经发送了通知的文件集合(避免重复通知)
const notifiedDownloads = new Set<string>();
// 事件监听器是否已初始化
let isInitialized = false;
// 监听器引用(用于清理)
let completeListener: ((event: any, data: any) => void) | null = null;
let errorListener: ((event: any, data: any) => void) | null = null;
return {
// 添加下载
addDownload: (filename: string) => {
activeDownloads.add(filename);
},
// 移除下载
removeDownload: (filename: string) => {
activeDownloads.delete(filename);
@@ -38,98 +38,100 @@ const createDownloadManager = () => {
notifiedDownloads.delete(filename);
}, 5000);
},
// 标记文件已通知
markNotified: (filename: string) => {
notifiedDownloads.add(filename);
},
// 检查文件是否已通知
isNotified: (filename: string) => {
return notifiedDownloads.has(filename);
},
// 清理所有下载
clearDownloads: () => {
activeDownloads.clear();
notifiedDownloads.clear();
},
// 初始化事件监听器
initEventListeners: (message: any, t: any) => {
if (isInitialized) return;
// 移除可能存在的旧监听器
if (completeListener) {
ipcRenderer?.removeListener('music-download-complete', completeListener);
}
if (errorListener) {
ipcRenderer?.removeListener('music-download-error', errorListener);
}
// 创建新的监听器
completeListener = (_event, data) => {
if (!data.filename || !activeDownloads.has(data.filename)) return;
// 如果该文件已经通知过,则跳过
if (notifiedDownloads.has(data.filename)) return;
// 标记为已通知
notifiedDownloads.add(data.filename);
// 从活动下载移除
activeDownloads.delete(data.filename);
};
errorListener = (_event, data) => {
if (!data.filename || !activeDownloads.has(data.filename)) return;
// 如果该文件已经通知过,则跳过
if (notifiedDownloads.has(data.filename)) return;
// 标记为已通知
notifiedDownloads.add(data.filename);
// 显示失败通知
message.error(t('songItem.message.downloadFailed', {
filename: data.filename,
error: data.error || '未知错误'
}));
message.error(
t('songItem.message.downloadFailed', {
filename: data.filename,
error: data.error || '未知错误'
})
);
// 从活动下载移除
activeDownloads.delete(data.filename);
};
// 添加监听器
ipcRenderer?.on('music-download-complete', completeListener);
ipcRenderer?.on('music-download-error', errorListener);
isInitialized = true;
},
// 清理事件监听器
cleanupEventListeners: () => {
if (!isInitialized) return;
if (completeListener) {
ipcRenderer?.removeListener('music-download-complete', completeListener);
completeListener = null;
}
if (errorListener) {
ipcRenderer?.removeListener('music-download-error', errorListener);
errorListener = null;
}
isInitialized = false;
},
// 获取活跃下载数量
getActiveDownloadCount: () => {
return activeDownloads.size;
},
// 检查是否有特定文件正在下载
hasDownload: (filename: string) => {
return activeDownloads.has(filename);
@@ -170,7 +172,7 @@ export const useDownload = () => {
// 构建文件名
const artistNames = (song.ar || song.song?.artists)?.map((a) => a.name).join(',');
const filename = `${song.name} - ${artistNames}`;
// 检查是否已在下载
if (downloadManager.hasDownload(filename)) {
isDownloading.value = false;
@@ -182,7 +184,7 @@ export const useDownload = () => {
const songData = cloneDeep(song);
songData.ar = songData.ar || songData.song?.artists;
// 发送下载请求
ipcRenderer?.send('download-music', {
url: typeof musicUrl === 'string' ? musicUrl : musicUrl.url,
@@ -195,7 +197,7 @@ export const useDownload = () => {
});
message.success(t('songItem.message.downloadQueued'));
// 简化的监听逻辑,基本通知由全局监听器处理
setTimeout(() => {
isDownloading.value = false;
@@ -230,7 +232,7 @@ export const useDownload = () => {
let successCount = 0;
let failCount = 0;
const totalCount = songs.length;
// 下载进度追踪
const trackProgress = () => {
if (successCount + failCount === totalCount) {
@@ -260,36 +262,36 @@ export const useDownload = () => {
trackProgress();
return;
}
const songData = cloneDeep(song);
const filename = `${song.name} - ${(song.ar || song.song?.artists)?.map((a) => a.name).join(',')}`;
// 检查是否已在下载
if (downloadManager.hasDownload(filename)) {
failCount++;
trackProgress();
return;
}
// 添加到活动下载集合
downloadManager.addDownload(filename);
const songInfo = {
...songData,
ar: songData.ar || songData.song?.artists,
downloadTime: Date.now()
};
ipcRenderer?.send('download-music', {
url,
filename,
songInfo,
type
});
successCount++;
});
// 所有下载开始后,检查进度
trackProgress();
} catch (error) {
@@ -305,4 +307,4 @@ export const useDownload = () => {
downloadMusic,
batchDownloadMusic
};
};
};
+34 -32
View File
@@ -1,30 +1,29 @@
import { useDialog, useMessage } from 'naive-ui';
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { usePlayerStore } from '@/store';
import type { SongResult } from '@/type/music';
import { computed, ref } from 'vue';
import { getImgUrl } from '@/utils';
import { getImageBackground } from '@/utils/linearColor';
import { useMessage, useDialog } from 'naive-ui';
import { useI18n } from 'vue-i18n';
import { useDownload } from './useDownload';
import { useArtist } from './useArtist';
export function useSongItem(props: {
item: SongResult;
canRemove?: boolean;
}) {
import { useArtist } from './useArtist';
import { useDownload } from './useDownload';
export function useSongItem(props: { item: SongResult; canRemove?: boolean }) {
const { t } = useI18n();
const playerStore = usePlayerStore();
const message = useMessage();
const dialog = useDialog();
const { downloadMusic } = useDownload();
const { navigateToArtist } = useArtist();
// 状态变量
const showDropdown = ref(false);
const dropdownX = ref(0);
const dropdownY = ref(0);
const isHovering = ref(false);
// 计算属性
const play = computed(() => playerStore.isPlay);
const playMusic = computed(() => playerStore.playMusic);
@@ -32,18 +31,20 @@ export function useSongItem(props: {
() => playMusic.value.id === props.item.id && playMusic.value.playLoading
);
const isPlaying = computed(() => playMusic.value.id === props.item.id);
// 收藏与不喜欢状态
const isFavorite = computed(() => {
const numericId = typeof props.item.id === 'string' ? parseInt(props.item.id, 10) : props.item.id;
const numericId =
typeof props.item.id === 'string' ? parseInt(props.item.id, 10) : props.item.id;
return playerStore.favoriteList.includes(numericId);
});
const isDislike = computed(() => {
const numericId = typeof props.item.id === 'string' ? parseInt(props.item.id, 10) : props.item.id;
const numericId =
typeof props.item.id === 'string' ? parseInt(props.item.id, 10) : props.item.id;
return playerStore.dislikeList.includes(numericId);
});
// 获取艺术家列表
const artists = computed(() => {
return (props.item.ar || props.item.song?.artists)?.slice(0, 4) || [];
@@ -52,12 +53,12 @@ export function useSongItem(props: {
// 处理图片加载
const handleImageLoad = async (imageElement: HTMLImageElement) => {
if (!imageElement) return;
const { backgroundColor, primaryColor } = await getImageBackground(imageElement);
props.item.backgroundColor = backgroundColor;
props.item.primaryColor = primaryColor;
};
// 播放音乐
const playMusicEvent = async (item: SongResult) => {
try {
@@ -71,11 +72,12 @@ export function useSongItem(props: {
return false;
}
};
// 切换收藏状态
const toggleFavorite = async (e: Event) => {
e && e.stopPropagation();
const numericId = typeof props.item.id === 'string' ? parseInt(props.item.id, 10) : props.item.id;
const numericId =
typeof props.item.id === 'string' ? parseInt(props.item.id, 10) : props.item.id;
if (isFavorite.value) {
playerStore.removeFromFavorite(numericId);
@@ -83,7 +85,7 @@ export function useSongItem(props: {
playerStore.addToFavorite(numericId);
}
};
// 切换不喜欢状态
const toggleDislike = async (e: Event) => {
e && e.stopPropagation();
@@ -91,7 +93,7 @@ export function useSongItem(props: {
playerStore.removeFromDislikeList(props.item.id);
return;
}
dialog.warning({
title: t('songItem.dialog.dislike.title'),
content: t('songItem.dialog.dislike.content'),
@@ -102,20 +104,20 @@ export function useSongItem(props: {
}
});
};
// 添加到下一首播放
const handlePlayNext = () => {
playerStore.addToNextPlay(props.item);
message.success(t('songItem.message.addedToNextPlay'));
};
// 获取歌曲时长
const getDuration = (item: SongResult): number => {
if (item.duration) return item.duration;
if (typeof item.dt === 'number') return item.dt;
return 0;
};
// 格式化时长
const formatDuration = (ms: number): string => {
if (!ms) return '--:--';
@@ -124,7 +126,7 @@ export function useSongItem(props: {
const seconds = totalSeconds % 60;
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
};
// 处理右键菜单
const handleContextMenu = (e: MouseEvent) => {
e.preventDefault();
@@ -132,7 +134,7 @@ export function useSongItem(props: {
dropdownX.value = e.clientX;
dropdownY.value = e.clientY;
};
// 处理菜单点击
const handleMenuClick = (e: MouseEvent) => {
e.preventDefault();
@@ -140,17 +142,17 @@ export function useSongItem(props: {
dropdownX.value = e.clientX;
dropdownY.value = e.clientY;
};
// 处理艺术家点击
const handleArtistClick = (id: number) => {
navigateToArtist(id);
};
// 鼠标悬停处理
const handleMouseEnter = () => {
isHovering.value = true;
};
const handleMouseLeave = () => {
isHovering.value = false;
};
@@ -165,7 +167,7 @@ export function useSongItem(props: {
isDislike,
artists,
showDropdown,
dropdownX,
dropdownX,
dropdownY,
isHovering,
playerStore,
@@ -185,4 +187,4 @@ export function useSongItem(props: {
handleMouseLeave,
downloadMusic
};
}
}
+13 -13
View File
@@ -9,10 +9,10 @@ export function useZoom() {
const MIN_ZOOM = 0.5;
const MAX_ZOOM = 1.5;
const ZOOM_STEP = 0.05; // 5%的步长
// 当前缩放因子
const zoomFactor = ref(1);
// 初始化获取当前缩放比例
const initZoomFactor = async () => {
try {
@@ -22,35 +22,35 @@ export function useZoom() {
console.error('获取缩放比例失败:', error);
}
};
// 增加缩放比例,保证100%为节点
const increaseZoom = () => {
let newZoom;
// 如果当前缩放低于100%并且增加后会超过100%,则直接设为100%
if (zoomFactor.value < 1.0 && zoomFactor.value + ZOOM_STEP > 1.0) {
newZoom = 1.0; // 精确设置为100%
} else {
newZoom = Math.min(MAX_ZOOM, Math.round((zoomFactor.value + ZOOM_STEP) * 20) / 20);
}
setZoomFactor(newZoom);
};
// 减少缩放比例,保证100%为节点
const decreaseZoom = () => {
let newZoom;
// 如果当前缩放大于100%并且减少后会低于100%,则直接设为100%
if (zoomFactor.value > 1.0 && zoomFactor.value - ZOOM_STEP < 1.0) {
newZoom = 1.0; // 精确设置为100%
} else {
newZoom = Math.max(MIN_ZOOM, Math.round((zoomFactor.value - ZOOM_STEP) * 20) / 20);
}
setZoomFactor(newZoom);
};
// 重置缩放比例到系统建议值
const resetZoom = async () => {
try {
@@ -59,18 +59,18 @@ export function useZoom() {
console.error('重置缩放比例失败:', error);
}
};
// 设置为100%标准缩放
const setZoom100 = () => {
setZoomFactor(1.0);
};
// 设置缩放比例
const setZoomFactor = (zoom: number) => {
window.ipcRenderer.send('set-content-zoom', zoom);
zoomFactor.value = zoom;
};
// 检查是否为100%缩放
const isZoom100 = () => {
return Math.abs(zoomFactor.value - 1.0) < 0.001;
@@ -89,4 +89,4 @@ export function useZoom() {
MAX_ZOOM,
ZOOM_STEP
};
}
}