Files
AlgerMusicPlayer/src/renderer/App.vue
T
alger 8f0a959d44 fix(window): 修复迷你模式相关的两处状态污染
- 展开播放列表后的 340x400 迷你窗口被误判为普通窗口并持久化到
  windowState,导致下次启动主窗口尺寸异常
- 迷你/主界面切换时复位 musicFull,避免残留 true 使返回后第一次点击
  歌曲信息被取反关闭、全屏播放页'打不开'

Closes #242
2026-07-05 15:16:56 +08:00

205 lines
6.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="app-container h-full w-full" :class="{ mobile: isMobile, noElectron: !isElectron }">
<n-config-provider :theme="theme === 'dark' ? darkTheme : lightTheme">
<n-dialog-provider>
<n-message-provider>
<router-view></router-view>
<traffic-warning-drawer v-if="!isElectron"></traffic-warning-drawer>
<disclaimer-modal></disclaimer-modal>
</n-message-provider>
</n-dialog-provider>
</n-config-provider>
</div>
</template>
<script setup lang="ts">
import { cloneDeep } from 'lodash';
import { darkTheme, lightTheme } from 'naive-ui';
import { computed, nextTick, onMounted, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import DisclaimerModal from '@/components/common/DisclaimerModal.vue';
import TrafficWarningDrawer from '@/components/TrafficWarningDrawer.vue';
import { usePlayerStore } from '@/store/modules/player';
import { usePlayerCoreStore } from '@/store/modules/playerCore';
import { useSettingsStore } from '@/store/modules/settings';
import { useUserStore } from '@/store/modules/user';
import { isElectron, isLyricWindow } from '@/utils';
import { checkLoginStatus } from '@/utils/auth';
import { initAudioListeners, initMusicHook } from './hooks/MusicHook';
import { audioService } from './services/audioService';
import { initLxMusicRunner } from './services/LxMusicSourceRunner';
import { isMobile } from './utils';
import { useAppShortcuts } from './utils/appShortcuts';
const { locale } = useI18n();
const settingsStore = useSettingsStore();
const playerStore = usePlayerStore();
const playerCoreStore = usePlayerCoreStore();
const userStore = useUserStore();
const router = useRouter();
// 监听语言变化
watch(
() => settingsStore.setData.language,
(newLanguage) => {
if (newLanguage && newLanguage !== locale.value) {
locale.value = newLanguage;
}
},
{ immediate: true }
);
const theme = computed(() => {
return settingsStore.theme;
});
// 监听字体变化并应用
watch(
() => [settingsStore.setData.fontFamily, settingsStore.setData.fontScope],
([newFont, fontScope]) => {
const appElement = document.body;
if (newFont && fontScope === 'global') {
appElement.style.fontFamily = newFont;
} else {
appElement.style.fontFamily = '';
}
}
);
const handleSetLanguage = (value: string) => {
console.log('应用语言变更:', value);
if (value) {
locale.value = value;
}
};
if (!isLyricWindow.value) {
settingsStore.initializeSettings();
settingsStore.initializeTheme();
settingsStore.initializeSystemFonts();
// 初始化登录状态 - 从 localStorage 恢复用户信息和登录类型
const loginInfo = checkLoginStatus();
if (loginInfo.isLoggedIn) {
if (loginInfo.user && !userStore.user) {
userStore.setUser(loginInfo.user);
}
if (loginInfo.loginType && !userStore.loginType) {
userStore.setLoginType(loginInfo.loginType);
}
}
}
handleSetLanguage(settingsStore.setData.language);
// 监听迷你模式状态
if (isElectron) {
window.api.onLanguageChanged(handleSetLanguage);
window.electron.ipcRenderer.on('mini-mode', (_, value) => {
settingsStore.setMiniMode(value);
// 切换迷你/主界面时复位全屏播放页状态:
// musicFull 残留为 true 会让返回主界面后第一次点击歌曲信息被"取反"关闭,
// 表现为全屏页打不开(#242
playerStore.setMusicFull(false);
if (value) {
// 存储当前路由
localStorage.setItem('currentRoute', router.currentRoute.value.path);
router.push('/mini');
} else {
// 清理迷你模式下设置的 body 样式
document.body.style.height = '';
document.body.style.overflow = '';
// 恢复当前路由
const currentRoute = localStorage.getItem('currentRoute');
if (currentRoute) {
router.push(currentRoute);
localStorage.removeItem('currentRoute');
} else {
router.push('/');
}
}
});
}
// 使用应用内快捷键
useAppShortcuts();
onMounted(async () => {
playerStore.setIsPlay(false);
if (isLyricWindow.value) {
return;
}
// 检查网络状态,离线时自动跳转到本地音乐页面
if (!navigator.onLine) {
router.push('/local-music');
}
// 监听网络状态变化,断网时跳转到本地音乐页面
const handleOffline = () => {
router.push('/local-music');
};
window.addEventListener('offline', handleOffline);
onUnmounted(() => {
window.removeEventListener('offline', handleOffline);
});
// 初始化 MusicHook,注入 playerStore
initMusicHook(playerStore);
// 设置 URL 过期自动续播处理器
const { setupUrlExpiredHandler } = await import('@/services/playbackController');
setupUrlExpiredHandler();
// 初始化播放状态
await playerStore.initializePlayState();
// 初始化音频设备变化监听器
playerCoreStore.initAudioDeviceListener();
// 初始化落雪音源(如果有激活的音源)
const activeLxApiId = settingsStore.setData?.activeLxMusicApiId;
if (activeLxApiId) {
const lxMusicScripts = settingsStore.setData?.lxMusicScripts || [];
const activeScript = lxMusicScripts.find((script: any) => script.id === activeLxApiId);
if (activeScript && activeScript.script) {
try {
console.log('[App] 初始化激活的落雪音源:', activeScript.name);
await initLxMusicRunner(activeScript.script);
} catch (error) {
console.error('[App] 初始化落雪音源失败:', error);
}
}
}
// 如果有正在播放的音乐,则初始化音频监听器
if (playerStore.playMusic && playerStore.playMusic.id) {
// 使用 nextTick 确保 DOM 更新后再初始化
await nextTick();
initAudioListeners();
if (isElectron) {
window.api.sendSong(cloneDeep(playerStore.playMusic));
}
}
audioService.releaseOperationLock();
});
</script>
<style lang="scss" scoped>
.app-container {
user-select: none;
}
.mobile {
.text-base {
font-size: 14px !important;
}
}
.html:has(.mobile) {
font-size: 14px;
}
</style>