Skip to content

Commit b203077

Browse files
committed
feat: 添加下载设置功能,支持自定义文件名格式和下载路径配置
- 新增下载设置抽屉,允许用户设置下载路径和文件名格式 - 支持多种文件名格式预设和自定义格式 - 实现下载项的显示名称格式化 - 优化下载管理逻辑,避免重复通知
1 parent a08fbf1 commit b203077

File tree

5 files changed

+784
-101
lines changed

5 files changed

+784
-101
lines changed

src/i18n/lang/en-US/download.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@ export default {
33
localMusic: 'Local Music',
44
count: '{count} songs in total',
55
clearAll: 'Clear All',
6+
settings: 'Settings',
67
tabs: {
78
downloading: 'Downloading',
89
downloaded: 'Downloaded'
910
},
1011
empty: {
1112
noTasks: 'No download tasks',
12-
noDownloaded: 'No downloaded songs'
13+
noDownloaded: 'No downloaded songs',
14+
noDownloadedHint: 'Download your favorite songs to listen offline'
1315
},
1416
progress: {
1517
total: 'Total Progress: {progress}%'
1618
},
19+
items: 'items',
1720
status: {
1821
downloading: 'Downloading',
1922
completed: 'Completed',
@@ -43,13 +46,46 @@ export default {
4346
},
4447
message: {
4548
downloadComplete: '{filename} download completed',
46-
downloadFailed: '{filename} download failed: {error}'
49+
downloadFailed: '{filename} download failed: {error}',
50+
alreadyDownloading: '{filename} is already downloading'
4751
},
4852
loading: 'Loading...',
4953
playStarted: 'Play started: {name}',
5054
playFailed: 'Play failed: {name}',
5155
path: {
5256
copied: 'Path copied to clipboard',
5357
copyFailed: 'Failed to copy path'
58+
},
59+
settingsPanel: {
60+
title: 'Download Settings',
61+
path: 'Download Location',
62+
pathDesc: 'Set where your music files will be saved',
63+
pathPlaceholder: 'Please select download path',
64+
noPathSelected: 'Please select download path first',
65+
select: 'Select Folder',
66+
open: 'Open Folder',
67+
fileFormat: 'Filename Format',
68+
fileFormatDesc: 'Set how downloaded music files will be named',
69+
customFormat: 'Custom Format',
70+
separator: 'Separator',
71+
separators: {
72+
dash: 'Space-dash-space',
73+
underscore: 'Underscore',
74+
space: 'Space'
75+
},
76+
dragToArrange: 'Sort or use arrow buttons to arrange:',
77+
formatVariables: 'Available variables',
78+
preview: 'Preview:',
79+
saveSuccess: 'Download settings saved',
80+
presets: {
81+
songArtist: 'Song - Artist',
82+
artistSong: 'Artist - Song',
83+
songOnly: 'Song only'
84+
},
85+
components: {
86+
songName: 'Song name',
87+
artistName: 'Artist name',
88+
albumName: 'Album name'
89+
}
5490
}
5591
};

src/i18n/lang/zh-CN/download.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export default {
33
localMusic: '本地音乐',
44
count: '共 {count} 首歌曲',
55
clearAll: '清空记录',
6+
settings: '设置',
67
tabs: {
78
downloading: '下载中',
89
downloaded: '已下载'
@@ -50,5 +51,37 @@ export default {
5051
path: {
5152
copied: '路径已复制到剪贴板',
5253
copyFailed: '复制路径失败'
54+
},
55+
settingsPanel: {
56+
title: '下载设置',
57+
path: '下载位置',
58+
pathDesc: '设置音乐文件下载保存的位置',
59+
pathPlaceholder: '请选择下载路径',
60+
noPathSelected: '请先选择下载路径',
61+
select: '选择文件夹',
62+
open: '打开文件夹',
63+
fileFormat: '文件名格式',
64+
fileFormatDesc: '设置下载音乐时的文件命名格式',
65+
customFormat: '自定义格式',
66+
separator: '分隔符',
67+
separators: {
68+
dash: '空格-空格',
69+
underscore: '下划线',
70+
space: '空格'
71+
},
72+
dragToArrange: '拖动排序或使用箭头按钮调整顺序:',
73+
formatVariables: '可用变量',
74+
preview: '预览效果:',
75+
saveSuccess: '下载设置已保存',
76+
presets: {
77+
songArtist: '歌曲名 - 歌手名',
78+
artistSong: '歌手名 - 歌曲名',
79+
songOnly: '仅歌曲名'
80+
},
81+
components: {
82+
songName: '歌曲名',
83+
artistName: '歌手名',
84+
albumName: '专辑名'
85+
}
5386
}
5487
};

src/main/modules/fileManager.ts

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ const audioCacheStore = new Store({
3434
}
3535
});
3636

37+
// 保存已发送通知的文件,避免重复通知
38+
const sentNotifications = new Map();
39+
3740
/**
3841
* 初始化文件管理相关的IPC监听
3942
*/
@@ -123,6 +126,23 @@ export function initializeFileManager() {
123126
}
124127
});
125128

129+
// 获取默认下载路径
130+
ipcMain.handle('get-downloads-path', () => {
131+
return app.getPath('downloads');
132+
});
133+
134+
// 获取存储的配置值
135+
ipcMain.handle('get-store-value', (_, key) => {
136+
const store = new Store();
137+
return store.get(key);
138+
});
139+
140+
// 设置存储的配置值
141+
ipcMain.on('set-store-value', (_, key, value) => {
142+
const store = new Store();
143+
store.set(key, value);
144+
});
145+
126146
// 下载音乐处理
127147
ipcMain.on('download-music', handleDownloadRequest);
128148

@@ -358,9 +378,28 @@ async function downloadMusic(
358378
const downloadPath =
359379
(configStore.get('set.downloadPath') as string) || app.getPath('downloads');
360380
const apiPort = configStore.get('set.musicApiPort') || 30488;
381+
382+
// 获取文件名格式设置
383+
const nameFormat =
384+
(configStore.get('set.downloadNameFormat') as string) || '{songName} - {artistName}';
385+
386+
// 根据格式创建文件名
387+
let formattedFilename = filename;
388+
if (songInfo) {
389+
// 准备替换变量
390+
const artistName = songInfo.ar?.map((a: any) => a.name).join('/') || '未知艺术家';
391+
const songName = songInfo.name || filename;
392+
const albumName = songInfo.al?.name || '未知专辑';
393+
394+
// 应用自定义格式
395+
formattedFilename = nameFormat
396+
.replace(/\{songName\}/g, songName)
397+
.replace(/\{artistName\}/g, artistName)
398+
.replace(/\{albumName\}/g, albumName);
399+
}
361400

362401
// 清理文件名中的非法字符
363-
const sanitizedFilename = sanitizeFilename(filename);
402+
const sanitizedFilename = sanitizeFilename(formattedFilename);
364403

365404
// 创建临时文件路径 (在系统临时目录中创建)
366405
const tempDir = path.join(os.tmpdir(), 'AlgerMusicPlayerTemp');
@@ -635,27 +674,38 @@ async function downloadMusic(
635674
history.unshift(newSongInfo);
636675
downloadStore.set('history', history);
637676

638-
// 发送桌面通知
639-
try {
640-
const artistNames =
641-
(songInfo?.ar || songInfo?.song?.artists)?.map((a: any) => a.name).join('/') ||
642-
'未知艺术家';
643-
const notification = new Notification({
644-
title: '下载完成',
645-
body: `${songInfo?.name || filename} - ${artistNames}`,
646-
silent: false
647-
});
648-
649-
notification.on('click', () => {
650-
shell.showItemInFolder(finalFilePath);
651-
});
652-
653-
notification.show();
654-
} catch (notifyError) {
655-
console.error('发送通知失败:', notifyError);
677+
// 避免重复发送通知
678+
const notificationId = `download-${finalFilePath}`;
679+
if (!sentNotifications.has(notificationId)) {
680+
sentNotifications.set(notificationId, true);
681+
682+
// 发送桌面通知
683+
try {
684+
const artistNames =
685+
(songInfo?.ar || songInfo?.song?.artists)?.map((a: any) => a.name).join('/') ||
686+
'未知艺术家';
687+
const notification = new Notification({
688+
title: '下载完成',
689+
body: `${songInfo?.name || filename} - ${artistNames}`,
690+
silent: false
691+
});
692+
693+
notification.on('click', () => {
694+
shell.showItemInFolder(finalFilePath);
695+
});
696+
697+
notification.show();
698+
699+
// 60秒后清理通知记录,释放内存
700+
setTimeout(() => {
701+
sentNotifications.delete(notificationId);
702+
}, 60000);
703+
} catch (notifyError) {
704+
console.error('发送通知失败:', notifyError);
705+
}
656706
}
657707

658-
// 发送下载完成事件
708+
// 发送下载完成事件,确保只发送一次
659709
event.reply('music-download-complete', {
660710
success: true,
661711
path: finalFilePath,

0 commit comments

Comments
 (0)