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
+41 -38
View File
@@ -1,14 +1,14 @@
import axios from 'axios';
import { app, dialog, ipcMain, Notification, protocol, shell } from 'electron';
import Store from 'electron-store';
import { fileTypeFromFile } from 'file-type';
import * as fs from 'fs';
import * as http from 'http';
import * as https from 'https';
import * as NodeID3 from 'node-id3';
import * as path from 'path';
import * as os from 'os';
import * as mm from 'music-metadata';
import { fileTypeFromFile } from 'file-type';
import * as NodeID3 from 'node-id3';
import * as os from 'os';
import * as path from 'path';
import { getStore } from './config';
@@ -42,18 +42,18 @@ export function initializeFileManager() {
// 注册本地文件协议
protocol.registerFileProtocol('local', (request, callback) => {
try {
let url = request.url;
const url = request.url;
// local://C:/Users/xxx.mp3
let filePath = decodeURIComponent(url.replace('local:///', ''));
// 兼容 local:///C:/Users/xxx.mp3 这种情况
if (/^\/[a-zA-Z]:\//.test(filePath)) {
filePath = filePath.slice(1);
}
// 还原为系统路径格式
filePath = path.normalize(filePath);
// 检查文件是否存在
if (!fs.existsSync(filePath)) {
console.error('File not found:', filePath);
@@ -128,13 +128,13 @@ export function initializeFileManager() {
ipcMain.handle('get-downloads-path', () => {
return app.getPath('downloads');
});
// 获取存储的配置值
ipcMain.handle('get-store-value', (_, key) => {
const store = new Store();
return store.get(key);
});
// 设置存储的配置值
ipcMain.on('set-store-value', (_, key, value) => {
const store = new Store();
@@ -189,7 +189,8 @@ export function initializeFileManager() {
const validEntriesPromises = await Promise.all(
entriesArray.map(async ([path, info]) => {
try {
const exists = await fs.promises.access(path)
const exists = await fs.promises
.access(path)
.then(() => true)
.catch(() => false);
return exists ? info : null;
@@ -202,7 +203,7 @@ export function initializeFileManager() {
// 过滤有效的歌曲并排序
const validSongs = validEntriesPromises
.filter(song => song !== null)
.filter((song) => song !== null)
.sort((a, b) => (b.downloadTime || 0) - (a.downloadTime || 0));
// 更新存储,移除不存在的文件记录
@@ -376,9 +377,9 @@ async function downloadMusic(
const downloadPath =
(configStore.get('set.downloadPath') as string) || app.getPath('downloads');
const apiPort = configStore.get('set.musicApiPort') || 30488;
// 获取文件名格式设置
const nameFormat =
const nameFormat =
(configStore.get('set.downloadNameFormat') as string) || '{songName} - {artistName}';
// 根据格式创建文件名
@@ -388,7 +389,7 @@ async function downloadMusic(
const artistName = songInfo.ar?.map((a: any) => a.name).join('/') || '未知艺术家';
const songName = songInfo.name || filename;
const albumName = songInfo.al?.name || '未知专辑';
// 应用自定义格式
formattedFilename = nameFormat
.replace(/\{songName\}/g, songName)
@@ -401,12 +402,12 @@ async function downloadMusic(
// 创建临时文件路径 (在系统临时目录中创建)
const tempDir = path.join(os.tmpdir(), 'AlgerMusicPlayerTemp');
// 确保临时目录存在
if (!fs.existsSync(tempDir)) {
fs.mkdirSync(tempDir, { recursive: true });
}
tempFilePath = path.join(tempDir, `${Date.now()}_${sanitizedFilename}.tmp`);
// 先获取文件大小
@@ -460,7 +461,7 @@ async function downloadMusic(
// 检测文件类型
let fileExtension = '';
try {
// 首先尝试使用file-type库检测
const fileType = await fileTypeFromFile(tempFilePath);
@@ -475,26 +476,28 @@ async function downloadMusic(
const formatInfo = metadata.format;
const container = formatInfo.container || '';
const codec = formatInfo.codec || '';
// 音频格式映射表
const formatMap = {
'mp3': ['MPEG', 'MP3', 'mp3'],
'aac': ['AAC'],
'flac': ['FLAC'],
'ogg': ['Ogg', 'Vorbis'],
'wav': ['WAV', 'PCM'],
'm4a': ['M4A', 'MP4']
mp3: ['MPEG', 'MP3', 'mp3'],
aac: ['AAC'],
flac: ['FLAC'],
ogg: ['Ogg', 'Vorbis'],
wav: ['WAV', 'PCM'],
m4a: ['M4A', 'MP4']
};
// 查找匹配的格式
const format = Object.entries(formatMap).find(([_, keywords]) =>
keywords.some(keyword => container.includes(keyword) || codec.includes(keyword))
const format = Object.entries(formatMap).find(([_, keywords]) =>
keywords.some((keyword) => container.includes(keyword) || codec.includes(keyword))
);
// 设置文件扩展名,如果没找到则默认为mp3
fileExtension = format ? `.${format[0]}` : '.mp3';
console.log(`music-metadata检测结果: 容器:${container}, 编码:${codec}, 扩展名: ${fileExtension}`);
console.log(
`music-metadata检测结果: 容器:${container}, 编码:${codec}, 扩展名: ${fileExtension}`
);
} else {
// 两种方法都失败,使用传入的type或默认mp3
fileExtension = type ? `.${type}` : '.mp3';
@@ -593,7 +596,7 @@ async function downloadMusic(
try {
// 在写入ID3标签前,先移除可能存在的旧标签
NodeID3.removeTags(finalFilePath);
const tags = {
title: filename,
artist: artistNames,
@@ -676,7 +679,7 @@ async function downloadMusic(
const notificationId = `download-${finalFilePath}`;
if (!sentNotifications.has(notificationId)) {
sentNotifications.set(notificationId, true);
// 发送桌面通知
try {
const artistNames =
@@ -687,13 +690,13 @@ async function downloadMusic(
body: `${songInfo?.name || filename} - ${artistNames}`,
silent: false
});
notification.on('click', () => {
shell.showItemInFolder(finalFilePath);
});
notification.show();
// 60秒后清理通知记录,释放内存
setTimeout(() => {
sentNotifications.delete(notificationId);
@@ -722,7 +725,7 @@ async function downloadMusic(
if (writer) {
writer.end();
}
// 清理临时文件
if (tempFilePath && fs.existsSync(tempFilePath)) {
try {
@@ -731,7 +734,7 @@ async function downloadMusic(
console.error('Failed to delete temporary file:', e);
}
}
// 清理未完成的最终文件
if (finalFilePath && fs.existsSync(finalFilePath)) {
try {
+12 -11
View File
@@ -1,10 +1,11 @@
import cors from 'cors';
import { ipcMain } from 'electron';
import express from 'express';
import cors from 'cors';
import os from 'os';
import { getStore } from './config';
import path from 'path';
import fs from 'fs';
import os from 'os';
import path from 'path';
import { getStore } from './config';
// 定义远程控制相关接口
export interface RemoteControlConfig {
@@ -72,9 +73,9 @@ export function initializeRemoteControl(mainWindow: Electron.BrowserWindow) {
if (server) {
stopServer();
}
store.set('remoteControl', newConfig);
if (newConfig.enabled) {
startServer(newConfig);
}
@@ -105,16 +106,16 @@ function startServer(config: RemoteControlConfig) {
}
app = express();
// 跨域配置
app.use(cors());
app.use(express.json());
// IP 过滤中间件
app.use((req, res, next) => {
const clientIp = req.ip || req.socket.remoteAddress || '';
const cleanIp = clientIp.replace(/^::ffff:/, ''); // 移除IPv6前缀
console.log('config',config)
console.log('config', config);
if (config.allowedIps.length === 0 || config.allowedIps.includes(cleanIp)) {
next();
} else {
@@ -216,7 +217,7 @@ function setupRoutes(app: express.Application) {
const isDev = process.env.NODE_ENV === 'development';
const htmlPath = path.join(process.cwd(), 'resources', 'html', 'remote-control.html');
const finalPath = isDev ? htmlPath : path.join(resourcesPath, 'html', 'remote-control.html');
if (fs.existsSync(finalPath)) {
res.sendFile(finalPath);
} else {
@@ -228,4 +229,4 @@ function setupRoutes(app: express.Application) {
res.status(500).send('加载远程控制界面失败');
}
});
}
}
+1 -1
View File
@@ -329,7 +329,7 @@ export function updateTrayMenu(mainWindow: BrowserWindow) {
// 初始化状态栏Tray
function initializeStatusBarTray(mainWindow: BrowserWindow) {
const store = getStore()
const store = getStore();
if (process.platform !== 'darwin' || !store.get('set.showTopAction')) return;
const iconSize = getProperIconSize();
+141 -132
View File
@@ -31,8 +31,6 @@ export interface WindowState {
isMaximized: boolean;
}
/**
* 窗口大小管理器
* 负责保存、恢复和维护窗口大小状态
@@ -42,12 +40,12 @@ class WindowSizeManager {
private mainWindow: BrowserWindow | null = null;
private savedState: WindowState | null = null;
private isInitialized: boolean = false;
constructor() {
this.store = store;
// 初始化时不做与screen相关的操作,等app ready后再初始化
}
/**
* 初始化窗口大小管理器
* 必须在app ready后调用
@@ -57,17 +55,17 @@ class WindowSizeManager {
console.warn('WindowSizeManager.initialize() 必须在 app ready 之后调用!');
return;
}
if (this.isInitialized) {
return;
}
this.initMinimumWindowSize();
this.setupIPCHandlers();
this.isInitialized = true;
console.log('窗口大小管理器初始化完成');
}
/**
* 设置主窗口引用
*/
@@ -75,19 +73,19 @@ class WindowSizeManager {
if (!this.isInitialized) {
this.initialize();
}
this.mainWindow = win;
// 读取保存的状态
this.savedState = this.getWindowState();
// 监听重要事件
this.setupEventListeners(win);
// 立即保存初始状态
this.saveWindowState(win);
}
/**
* 初始化最小窗口尺寸
*/
@@ -96,14 +94,17 @@ class WindowSizeManager {
console.warn('不能在 app ready 之前访问 screen 模块');
return;
}
try {
const { width: workAreaWidth, height: workAreaHeight } = screen.getPrimaryDisplay().workArea;
// 根据工作区大小设置合理的最小尺寸
MIN_WIDTH = Math.min(Math.round(DEFAULT_MAIN_WIDTH * 0.5), Math.round(workAreaWidth * 0.3));
MIN_HEIGHT = Math.min(Math.round(DEFAULT_MAIN_HEIGHT * 0.5), Math.round(workAreaHeight * 0.3));
MIN_HEIGHT = Math.min(
Math.round(DEFAULT_MAIN_HEIGHT * 0.5),
Math.round(workAreaHeight * 0.3)
);
console.log(`设置最小窗口尺寸: ${MIN_WIDTH}x${MIN_HEIGHT}`);
} catch (error) {
console.error('初始化最小窗口尺寸失败:', error);
@@ -112,7 +113,7 @@ class WindowSizeManager {
MIN_HEIGHT = Math.round(DEFAULT_MAIN_HEIGHT * 0.5);
}
}
/**
* 设置事件监听器
*/
@@ -123,46 +124,46 @@ class WindowSizeManager {
this.saveWindowState(win);
}
});
// 监听窗口移动事件
win.on('move', () => {
if (!win.isDestroyed() && !win.isMinimized()) {
this.saveWindowState(win);
}
});
// 监听窗口最大化事件
win.on('maximize', () => {
if (!win.isDestroyed()) {
this.saveWindowState(win);
}
});
// 监听窗口从最大化恢复事件
win.on('unmaximize', () => {
if (!win.isDestroyed()) {
this.saveWindowState(win);
}
});
// 监听窗口关闭事件,确保保存最终状态
win.on('close', () => {
if (!win.isDestroyed()) {
this.saveWindowState(win);
}
});
// 在页面加载完成后确保窗口大小正确
win.webContents.on('did-finish-load', () => {
this.enforceCorrectSize(win);
});
// 在窗口准备好显示时确保尺寸正确
win.on('ready-to-show', () => {
this.enforceCorrectSize(win);
});
}
/**
* 强制应用正确的窗口大小
*/
@@ -170,30 +171,36 @@ class WindowSizeManager {
if (!this.savedState || win.isMaximized() || win.isMinimized() || win.isDestroyed()) {
return;
}
const [currentWidth, currentHeight] = win.getSize();
if (Math.abs(currentWidth - this.savedState.width) > 2 ||
Math.abs(currentHeight - this.savedState.height) > 2) {
console.log(`强制调整窗口大小: 当前=${currentWidth}x${currentHeight}, 目标=${this.savedState.width}x${this.savedState.height}`);
if (
Math.abs(currentWidth - this.savedState.width) > 2 ||
Math.abs(currentHeight - this.savedState.height) > 2
) {
console.log(
`强制调整窗口大小: 当前=${currentWidth}x${currentHeight}, 目标=${this.savedState.width}x${this.savedState.height}`
);
// 临时禁用minimum size限制
const [minWidth, minHeight] = win.getMinimumSize();
win.setMinimumSize(1, 1);
// 强制设置正确大小
win.setSize(this.savedState.width, this.savedState.height, false);
// 恢复原始minimum size
win.setMinimumSize(minWidth, minHeight);
// 验证尺寸设置是否成功
const [newWidth, newHeight] = win.getSize();
console.log(`调整后窗口大小: ${newWidth}x${newHeight}`);
// 如果调整后的大小仍然与目标不一致,尝试再次调整
if (Math.abs(newWidth - this.savedState.width) > 1 ||
Math.abs(newHeight - this.savedState.height) > 1) {
if (
Math.abs(newWidth - this.savedState.width) > 1 ||
Math.abs(newHeight - this.savedState.height) > 1
) {
console.log(`窗口大小调整后仍不一致,将再次尝试调整`);
setTimeout(() => {
if (!win.isDestroyed() && !win.isMaximized() && !win.isMinimized()) {
@@ -201,12 +208,12 @@ class WindowSizeManager {
}
}, 50);
}
// // 开始尺寸强制执行
// this.startSizeEnforcement(win);
}
}
/**
* 开启尺寸强制执行定时器
*/
@@ -216,15 +223,15 @@ class WindowSizeManager {
// clearInterval(this.enforceTimer);
// this.enforceTimer = null;
// }
// this.enforceCount = 0;
// // 创建新的定时器,每50ms检查一次窗口大小
// this.enforceTimer = setInterval(() => {
// if (this.enforceCount >= this.MAX_ENFORCE_COUNT ||
// !this.savedState ||
// win.isDestroyed() ||
// win.isMaximized() ||
// if (this.enforceCount >= this.MAX_ENFORCE_COUNT ||
// !this.savedState ||
// win.isDestroyed() ||
// win.isMaximized() ||
// win.isMinimized()) {
// // 达到最大检查次数或不需要检查,清除定时器
// if (this.enforceTimer) {
@@ -233,35 +240,35 @@ class WindowSizeManager {
// }
// return;
// }
// const [currentWidth, currentHeight] = win.getSize();
// if (Math.abs(currentWidth - this.savedState.width) > 2 ||
// if (Math.abs(currentWidth - this.savedState.width) > 2 ||
// Math.abs(currentHeight - this.savedState.height) > 2) {
// console.log(`[定时检查] 强制调整窗口大小: 当前=${currentWidth}x${currentHeight}, 目标=${this.savedState.width}x${this.savedState.height}`);
// // 临时禁用minimum size限制
// const [minWidth, minHeight] = win.getMinimumSize();
// win.setMinimumSize(1, 1);
// // 强制设置正确大小
// win.setSize(this.savedState.width, this.savedState.height, false);
// // 恢复原始minimum size
// win.setMinimumSize(minWidth, minHeight);
// // 验证尺寸设置是否成功
// const [newWidth, newHeight] = win.getSize();
// if (Math.abs(newWidth - this.savedState.width) <= 1 &&
// if (Math.abs(newWidth - this.savedState.width) <= 1 &&
// Math.abs(newHeight - this.savedState.height) <= 1) {
// console.log(`窗口大小已成功调整为目标尺寸: ${newWidth}x${newHeight}`);
// }
// }
// this.enforceCount++;
// }, 50);
// }
/**
* 获取窗口创建选项
*/
@@ -270,10 +277,10 @@ class WindowSizeManager {
if (!this.isInitialized && app.isReady()) {
this.initialize();
}
// 读取保存的状态
const savedState = this.getWindowState();
// 准备选项
const options: Electron.BrowserWindowConstructorOptions = {
width: savedState?.width || DEFAULT_MAIN_WIDTH,
@@ -287,7 +294,7 @@ class WindowSizeManager {
contextIsolation: true
}
};
// 如果有保存的位置,且位置有效,则使用该位置
if (savedState?.x !== undefined && savedState?.y !== undefined && app.isReady()) {
if (this.isPositionVisible(savedState.x, savedState.y)) {
@@ -295,49 +302,57 @@ class WindowSizeManager {
options.y = savedState.y;
}
}
console.log(`窗口创建选项: 大小=${options.width}x${options.height}, 位置=(${options.x}, ${options.y})`);
console.log(
`窗口创建选项: 大小=${options.width}x${options.height}, 位置=(${options.x}, ${options.y})`
);
return options;
}
/**
* 应用窗口初始状态
* 在窗口创建后调用
*/
applyInitialState(win: BrowserWindow): void {
const savedState = this.getWindowState();
if (!savedState) {
win.center();
return;
}
// 如果需要最大化,直接最大化
if (savedState.isMaximized) {
console.log('应用已保存的最大化状态');
win.maximize();
}
}
// 如果位置无效,则居中显示
else if (!app.isReady() || savedState.x === undefined || savedState.y === undefined ||
!this.isPositionVisible(savedState.x, savedState.y)) {
else if (
!app.isReady() ||
savedState.x === undefined ||
savedState.y === undefined ||
!this.isPositionVisible(savedState.x, savedState.y)
) {
console.log('保存的位置无效,窗口居中显示');
win.center();
}
}
/**
* 保存窗口状态
*/
saveWindowState(win: BrowserWindow): WindowState {
// 如果窗口已销毁,则返回之前的状态或默认状态
console.log('win.isDestroyed()',win.isDestroyed())
console.log('win.isDestroyed()', win.isDestroyed());
if (win.isDestroyed()) {
return this.savedState || {
width: DEFAULT_MAIN_WIDTH,
height: DEFAULT_MAIN_HEIGHT,
isMaximized: false
};
return (
this.savedState || {
width: DEFAULT_MAIN_WIDTH,
height: DEFAULT_MAIN_HEIGHT,
isMaximized: false
}
);
}
// 检查是否是mini模式窗口(根据窗口大小判断)
@@ -352,9 +367,10 @@ class WindowSizeManager {
// 由于 Electron 的限制,最大化状态下 getBounds() 可能不准确
// 所以我们尽量保留之前保存的非最大化时的大小
const currentBounds = win.getBounds();
const previousSize = this.savedState && !this.savedState.isMaximized
? { width: this.savedState.width, height: this.savedState.height }
: { width: currentBounds.width, height: currentBounds.height };
const previousSize =
this.savedState && !this.savedState.isMaximized
? { width: this.savedState.width, height: this.savedState.height }
: { width: currentBounds.width, height: currentBounds.height };
state = {
width: previousSize.width,
@@ -363,19 +379,18 @@ class WindowSizeManager {
y: currentBounds.y,
isMaximized: true
};
console.log('state IsMaximized',state)
}
else if (win.isMinimized()) {
console.log('state IsMaximized', state);
} else if (win.isMinimized()) {
// 最小化状态下不保存窗口大小,因为可能不准确
console.log('state IsMinimized',this.savedState)
return this.savedState || {
width: DEFAULT_MAIN_WIDTH,
height: DEFAULT_MAIN_HEIGHT,
isMaximized: false
};
}
else {
console.log('state IsMinimized', this.savedState);
return (
this.savedState || {
width: DEFAULT_MAIN_WIDTH,
height: DEFAULT_MAIN_HEIGHT,
isMaximized: false
}
);
} else {
// 正常状态下保存当前大小和位置
const [width, height] = win.getSize();
const [x, y] = win.getPosition();
@@ -387,7 +402,7 @@ class WindowSizeManager {
y,
isMaximized: false
};
console.log('state IsNormal',state)
console.log('state IsNormal', state);
}
// 如果是mini模式,不保存到持久化存储,只返回状态用于内存中的恢复
@@ -402,11 +417,11 @@ class WindowSizeManager {
// 更新内部状态
this.savedState = state;
console.log('state',state)
console.log('state', state);
return state;
}
/**
* 获取保存的窗口状态
*/
@@ -432,8 +447,6 @@ class WindowSizeManager {
return validatedState;
}
/**
* 检查位置是否在可见屏幕范围内
*/
@@ -441,18 +454,13 @@ class WindowSizeManager {
if (!app.isReady()) {
return false;
}
try {
const displays = screen.getAllDisplays();
for (const display of displays) {
const { x: screenX, y: screenY, width, height } = display.workArea;
if (
x >= screenX &&
x < screenX + width &&
y >= screenY &&
y < screenY + height
) {
if (x >= screenX && x < screenX + width && y >= screenY && y < screenY + height) {
return true;
}
}
@@ -460,10 +468,10 @@ class WindowSizeManager {
console.error('检查位置可见性失败:', error);
return false;
}
return false;
}
/**
* 计算适合当前缩放比的缩放因子
*/
@@ -472,14 +480,14 @@ class WindowSizeManager {
if (!app.isReady()) {
return 1;
}
try {
// 获取系统的缩放因子
const { scaleFactor } = screen.getPrimaryDisplay();
// 缩放因子默认为1
let zoomFactor = 1;
// 只在高DPI情况下调整
if (scaleFactor > 1) {
// 自定义逻辑来根据不同的缩放比例进行调整
@@ -500,38 +508,40 @@ class WindowSizeManager {
zoomFactor = 1;
}
}
// 获取用户的自定义缩放设置(如果有)
const userZoomFactor = this.store.get('set.contentZoomFactor') as number | undefined;
if (userZoomFactor) {
zoomFactor = userZoomFactor;
}
return zoomFactor;
} catch (error) {
console.error('计算内容缩放因子失败:', error);
return 1;
}
}
/**
* 应用页面内容缩放
*/
applyContentZoom(win: BrowserWindow): void {
const zoomFactor = this.calculateContentZoomFactor();
win.webContents.setZoomFactor(zoomFactor);
if (app.isReady()) {
try {
console.log(`应用页面缩放因子: ${zoomFactor}, 系统缩放比: ${screen.getPrimaryDisplay().scaleFactor}`);
console.log(
`应用页面缩放因子: ${zoomFactor}, 系统缩放比: ${screen.getPrimaryDisplay().scaleFactor}`
);
} catch (error) {
console.log(`应用页面缩放因子: ${zoomFactor}`);
console.error('获取系统缩放比失败:', error);
}
} else {
console.log(`应用页面缩放因子: ${zoomFactor}`);
}
}
/**
* 初始化IPC消息处理程序
*/
@@ -541,25 +551,25 @@ class WindowSizeManager {
console.log('IPC处理程序已注册,跳过重复注册');
return;
}
console.log('注册窗口大小相关的IPC处理程序');
// 标记为已注册
ipcHandlersRegistered = true;
// 安全地移除已存在的处理程序(如果有)
const removeHandlerSafely = (channel: string) => {
try {
ipcMain.removeHandler(channel);
} catch (error) {
// 忽略错误,处理程序可能不存在
console.warn(`移除IPC处理程序 ${channel} 时出错:`, error);
}
};
// 为需要使用handle方法的通道先移除已有处理程序
removeHandlerSafely('get-content-zoom');
removeHandlerSafely('get-system-scale-factor');
// 注册新的处理程序
ipcMain.on('set-content-zoom', (event, zoomFactor) => {
const win = BrowserWindow.fromWebContents(event.sender);
@@ -568,7 +578,7 @@ class WindowSizeManager {
this.store.set('set.contentZoomFactor', zoomFactor);
}
});
ipcMain.handle('get-content-zoom', (event) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win && !win.isDestroyed()) {
@@ -576,12 +586,12 @@ class WindowSizeManager {
}
return 1;
});
ipcMain.handle('get-system-scale-factor', () => {
if (!app.isReady()) {
return 1;
}
try {
return screen.getPrimaryDisplay().scaleFactor;
} catch (error) {
@@ -589,7 +599,7 @@ class WindowSizeManager {
return 1;
}
});
ipcMain.on('reset-content-zoom', (event) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win && !win.isDestroyed()) {
@@ -597,25 +607,25 @@ class WindowSizeManager {
this.applyContentZoom(win);
}
});
ipcMain.on('resize-window', (event, width, height) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win && !win.isDestroyed()) {
console.log(`接收到调整窗口大小请求: ${width}x${height}`);
// 确保尺寸不小于最小值
const adjustedWidth = Math.max(width, MIN_WIDTH);
const adjustedHeight = Math.max(height, MIN_HEIGHT);
// 设置窗口的大小
win.setSize(adjustedWidth, adjustedHeight);
console.log(`窗口大小已调整为: ${adjustedWidth}x${adjustedHeight}`);
// 保存窗口状态
this.saveWindowState(win);
}
});
ipcMain.on('resize-mini-window', (event, showPlaylist) => {
const win = BrowserWindow.fromWebContents(event.sender);
if (win && !win.isDestroyed()) {
@@ -632,7 +642,7 @@ class WindowSizeManager {
}
}
});
// 只在app ready后设置显示器变化监听
if (app.isReady()) {
// 监听显示器变化事件
@@ -642,13 +652,13 @@ class WindowSizeManager {
if (changedMetrics.includes('scaleFactor')) {
this.applyContentZoom(this.mainWindow);
}
// 重新初始化最小尺寸
this.initMinimumWindowSize();
}
});
}
// 监听 store 中的缩放设置变化
this.store.onDidChange('set.contentZoomFactor', () => {
if (this.mainWindow && !this.mainWindow.isDestroyed()) {
@@ -712,4 +722,3 @@ export const initWindowSizeHandlers = (mainWindow: BrowserWindow | null): void =
export const calculateMinimumWindowSize = (): { minWidth: number; minHeight: number } => {
return { minWidth: MIN_WIDTH, minHeight: MIN_HEIGHT };
};
+58 -35
View File
@@ -1,18 +1,28 @@
import { is } from '@electron-toolkit/utils';
import { app, BrowserWindow, nativeImage, globalShortcut, ipcMain, screen, session, shell } from 'electron';
import {
app,
BrowserWindow,
globalShortcut,
ipcMain,
nativeImage,
screen,
session,
shell
} from 'electron';
import Store from 'electron-store';
import { join } from 'path';
import {
DEFAULT_MAIN_WIDTH,
DEFAULT_MAIN_HEIGHT,
DEFAULT_MINI_WIDTH,
DEFAULT_MINI_HEIGHT,
applyContentZoom,
saveWindowState,
applyInitialState,
initWindowSizeHandlers,
DEFAULT_MAIN_HEIGHT,
DEFAULT_MAIN_WIDTH,
DEFAULT_MINI_HEIGHT,
DEFAULT_MINI_WIDTH,
getWindowOptions,
getWindowState,
initWindowSizeHandlers,
saveWindowState,
WindowState
} from './window-size';
@@ -68,34 +78,32 @@ function setThumbarButtons(window: BrowserWindow) {
window.setThumbarButtons([
{
tooltip: 'prev',
icon: nativeImage
.createFromPath(join(app.getAppPath(), 'resources/icons', 'prev.png')),
icon: nativeImage.createFromPath(join(app.getAppPath(), 'resources/icons', 'prev.png')),
click() {
window.webContents.send('global-shortcut', 'prevPlay');
},
}
},
{
tooltip: isPlaying ? 'pause' : 'play',
icon: nativeImage
.createFromPath(join(app.getAppPath(), 'resources/icons', isPlaying ? 'pause.png' : 'play.png')),
icon: nativeImage.createFromPath(
join(app.getAppPath(), 'resources/icons', isPlaying ? 'pause.png' : 'play.png')
),
click() {
window.webContents.send('global-shortcut', 'togglePlay');
},
}
},
{
tooltip: 'next',
icon: nativeImage
.createFromPath(join(app.getAppPath(), 'resources/icons', 'next.png')),
icon: nativeImage.createFromPath(join(app.getAppPath(), 'resources/icons', 'next.png')),
click() {
window.webContents.send('global-shortcut', 'nextPlay');
},
}
}
]);
}
/**
* 初始化窗口管理相关的IPC监听
*/
@@ -159,7 +167,11 @@ export function initializeWindowManager() {
win.setMaximumSize(DEFAULT_MINI_WIDTH, DEFAULT_MINI_HEIGHT);
win.setSize(DEFAULT_MINI_WIDTH, DEFAULT_MINI_HEIGHT, false); // 禁用动画
// 将迷你窗口放在工作区的右上角,留出一些边距
win.setPosition(screenX + screenWidth - DEFAULT_MINI_WIDTH - 20, display.workArea.y + 20, false);
win.setPosition(
screenX + screenWidth - DEFAULT_MINI_WIDTH - 20,
display.workArea.y + 20,
false
);
win.setAlwaysOnTop(true);
win.setSkipTaskbar(false);
win.setResizable(false);
@@ -186,7 +198,10 @@ export function initializeWindowManager() {
console.log('从迷你模式恢复,使用保存的状态:', JSON.stringify(preMiniModeState));
// 设置适当的最小尺寸
win.setMinimumSize(Math.max(DEFAULT_MAIN_WIDTH * 0.5, 600), Math.max(DEFAULT_MAIN_HEIGHT * 0.5, 400));
win.setMinimumSize(
Math.max(DEFAULT_MAIN_WIDTH * 0.5, 600),
Math.max(DEFAULT_MAIN_HEIGHT * 0.5, 400)
);
// 恢复窗口状态
win.setAlwaysOnTop(false);
@@ -223,9 +238,13 @@ export function initializeWindowManager() {
if (!win.isDestroyed() && !win.isMaximized() && !win.isMinimized()) {
// 再次验证窗口大小
const [width, height] = win.getSize();
if (Math.abs(width - preMiniModeState.width) > 2 ||
Math.abs(height - preMiniModeState.height) > 2) {
console.log(`恢复后窗口大小不一致,再次调整: 当前=${width}x${height}, 目标=${preMiniModeState.width}x${preMiniModeState.height}`);
if (
Math.abs(width - preMiniModeState.width) > 2 ||
Math.abs(height - preMiniModeState.height) > 2
) {
console.log(
`恢复后窗口大小不一致,再次调整: 当前=${width}x${height}, 目标=${preMiniModeState.width}x${preMiniModeState.height}`
);
win.setSize(preMiniModeState.width, preMiniModeState.height, false);
}
}
@@ -234,7 +253,6 @@ export function initializeWindowManager() {
}
});
ipcMain.on('update-play-state', (_, playing: boolean) => {
isPlaying = playing;
if (mainWindowInstance) {
@@ -279,14 +297,16 @@ export function createMainWindow(icon: Electron.NativeImage): BrowserWindow {
webSecurity: false
};
console.log(`创建窗口,使用选项: ${JSON.stringify({
width: options.width,
height: options.height,
x: options.x,
y: options.y,
minWidth: options.minWidth,
minHeight: options.minHeight
})}`);
console.log(
`创建窗口,使用选项: ${JSON.stringify({
width: options.width,
height: options.height,
x: options.x,
y: options.y,
minWidth: options.minWidth,
minHeight: options.minHeight
})}`
);
// 创建窗口
const mainWindow = new BrowserWindow(options);
@@ -340,9 +360,13 @@ export function createMainWindow(icon: Electron.NativeImage): BrowserWindow {
if (!mainWindow.isDestroyed() && !mainWindow.isMaximized()) {
const [currentWidth, currentHeight] = mainWindow.getSize();
if (savedState && !savedState.isMaximized) {
if (Math.abs(currentWidth - savedState.width) > 2 ||
Math.abs(currentHeight - savedState.height) > 2) {
console.log(`窗口大小不匹配,再次调整: 当前=${currentWidth}x${currentHeight}, 目标=${savedState.width}x${savedState.height}`);
if (
Math.abs(currentWidth - savedState.width) > 2 ||
Math.abs(currentHeight - savedState.height) > 2
) {
console.log(
`窗口大小不匹配,再次调整: 当前=${currentWidth}x${currentHeight}, 目标=${savedState.width}x${savedState.height}`
);
mainWindow.setSize(savedState.width, savedState.height, false);
}
}
@@ -371,7 +395,6 @@ export function createMainWindow(icon: Electron.NativeImage): BrowserWindow {
initWindowSizeHandlers(mainWindow);
// 保存主窗口引用
mainWindowInstance = mainWindow;