添加保存全部按钮

This commit is contained in:
Weiqi Gao 2023-12-30 14:40:06 +08:00
parent 95a914b6bf
commit 5dbdebce75
3 changed files with 172 additions and 83 deletions

55
package-lock.json generated
View File

@ -19,9 +19,6 @@
"electron-builder": "^24.6.3",
"eslint": "^8.47.0",
"prettier": "^3.0.2"
},
"optionalDependencies": {
"dmg-license": "^1.0.11"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@ -691,6 +688,7 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz",
"integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==",
"dev": true,
"optional": true,
"dependencies": {
"@types/node": "*",
@ -709,6 +707,7 @@
"version": "1.10.6",
"resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz",
"integrity": "sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==",
"dev": true,
"optional": true
},
"node_modules/@types/yauzl": {
@ -724,7 +723,7 @@
"version": "0.8.10",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
"integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
"devOptional": true,
"dev": true,
"engines": {
"node": ">=10.0.0"
}
@ -772,7 +771,7 @@
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"devOptional": true,
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@ -797,7 +796,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"devOptional": true,
"dev": true,
"engines": {
"node": ">=8"
}
@ -806,7 +805,7 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"devOptional": true,
"dev": true,
"dependencies": {
"color-convert": "^2.0.1"
},
@ -922,6 +921,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
"dev": true,
"optional": true,
"engines": {
"node": ">=0.8"
@ -931,6 +931,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
"dev": true,
"optional": true,
"engines": {
"node": ">=8"
@ -976,7 +977,7 @@
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"devOptional": true,
"dev": true,
"funding": [
{
"type": "github",
@ -1059,6 +1060,7 @@
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"dev": true,
"funding": [
{
"type": "github",
@ -1276,6 +1278,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
"integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
"dev": true,
"optional": true,
"dependencies": {
"slice-ansi": "^3.0.0",
@ -1317,7 +1320,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"devOptional": true,
"dev": true,
"dependencies": {
"color-name": "~1.1.4"
},
@ -1329,7 +1332,7 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"devOptional": true
"dev": true
},
"node_modules/combined-stream": {
"version": "1.0.8",
@ -1381,12 +1384,14 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
"dev": true,
"optional": true
},
"node_modules/crc": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
"integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
"dev": true,
"optional": true,
"dependencies": {
"buffer": "^5.1.0"
@ -1626,6 +1631,7 @@
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz",
"integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==",
"dev": true,
"optional": true,
"os": [
"darwin"
@ -1821,7 +1827,7 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"devOptional": true
"dev": true
},
"node_modules/end-of-stream": {
"version": "1.4.4",
@ -2128,6 +2134,7 @@
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz",
"integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==",
"dev": true,
"engines": [
"node >=0.6.0"
],
@ -2137,7 +2144,7 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"devOptional": true
"dev": true
},
"node_modules/fast-diff": {
"version": "1.3.0",
@ -2177,7 +2184,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"devOptional": true
"dev": true
},
"node_modules/fast-levenshtein": {
"version": "2.0.6",
@ -2649,6 +2656,7 @@
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz",
"integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==",
"dev": true,
"optional": true,
"os": [
"darwin"
@ -2677,6 +2685,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"funding": [
{
"type": "github",
@ -2783,7 +2792,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"devOptional": true,
"dev": true,
"engines": {
"node": ">=8"
}
@ -2954,7 +2963,7 @@
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"devOptional": true
"dev": true
},
"node_modules/json-stable-stringify-without-jsonify": {
"version": "1.0.1",
@ -3237,6 +3246,7 @@
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
"integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
"dev": true,
"optional": true
},
"node_modules/normalize-url": {
@ -3448,7 +3458,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
"integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
"devOptional": true,
"dev": true,
"dependencies": {
"@xmldom/xmldom": "^0.8.8",
"base64-js": "^1.5.1",
@ -3515,7 +3525,7 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
"devOptional": true,
"dev": true,
"engines": {
"node": ">=6"
}
@ -3903,6 +3913,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
"integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
"dev": true,
"optional": true,
"dependencies": {
"ansi-styles": "^4.0.0",
@ -3917,6 +3928,7 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
"dev": true,
"optional": true,
"engines": {
"node": ">= 6.0.0",
@ -3961,7 +3973,7 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"devOptional": true,
"dev": true,
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@ -3975,7 +3987,7 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"devOptional": true,
"dev": true,
"dependencies": {
"ansi-regex": "^5.0.1"
},
@ -4232,7 +4244,7 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"devOptional": true,
"dev": true,
"dependencies": {
"punycode": "^2.1.0"
}
@ -4247,6 +4259,7 @@
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz",
"integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==",
"dev": true,
"optional": true,
"dependencies": {
"assert-plus": "^1.0.0",
@ -4298,7 +4311,7 @@
"version": "15.1.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
"integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
"devOptional": true,
"dev": true,
"engines": {
"node": ">=8.0"
}

View File

@ -1,6 +1,6 @@
{
"name": "um-react-electron",
"version": "1.0.0",
"version": "1.0.1",
"description": "Unlock Music 音乐解锁 (React) Electron App",
"main": "./src/main.js",
"author": "dreamfly",

View File

@ -1,26 +1,66 @@
// Modules to control application life and create native browser window
const { app, shell, BrowserWindow } = require('electron')
const { app, shell, BrowserWindow, Menu, dialog } = require('electron')
const path = require('path')
const { electronApp, optimizer } = require('@electron-toolkit/utils')
let name, mainWindow;
function downloadURL(url, filepath) {
return new Promise((resolve, reject) => {
name = filepath;
mainWindow.webContents.downloadURL(url);
mainWindow.webContents.session.once('will-download', (event, item) => {
item.once('done', (event, state) => {
if (state === 'completed') {
resolve();
} else {
reject(new Error(`Download failed: ${state}`));
}
});
});
});
}
async function downloadAll() {
console.log('保存全部')
const links = await mainWindow.webContents.executeJavaScript(`
Array.from(document.querySelectorAll('a[href^="blob"]')).map(a => ({
href: a.href,
download: a.download
}))
`);
console.log(links);
// Ask for a directory to save all files
const { filePaths } = await dialog.showOpenDialog({
properties: ['openDirectory']
});
if (!filePaths || !filePaths.length) {
return;
}
for (const link of links) {
try {
await downloadURL(link.href, path.join(filePaths[0], link.download));
console.log(`Downloaded ${link.download}`);
} catch (error) {
console.log(`Failed to download ${link.download}: ${error.message}`);
}
}
}
function createWindow() {
// Create the browser window.
const mainWindow = new BrowserWindow({
mainWindow = new BrowserWindow({
width: 900,
height: 670,
show: false,
autoHideMenuBar: true,
// autoHideMenuBar: true,
// frame: false, // 隐藏标题栏
...(process.platform === 'linux' || process.platform === 'win32'
? {
...(process.platform === 'linux' || process.platform === 'win32' ? {
icon: path.join(__dirname, '../resources/icon.png')
}
: {}),
...(process.platform === 'darwin'
? {
} : {}),
...(process.platform === 'darwin' ? {
titleBarStyle: 'hidden' // 隐藏 macOS 的默认标题栏
}
: {}),
} : {}),
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
sandbox: false,
@ -37,6 +77,33 @@ function createWindow() {
return { action: 'deny' }
})
mainWindow.webContents.session.on('will-download', (event, item) => {
if (name) {
item.setSavePath(name);
name = null;
}
item.on('updated', (event, state) => {
if (state === 'interrupted') {
console.log('Download is interrupted but can be resumed')
} else if (state === 'progressing') {
if (item.isPaused()) {
console.log('Download is paused')
} else {
console.log(`Received bytes: ${item.getReceivedBytes()}`)
}
}
});
item.once('done', (event, state) => {
if (state === 'completed') {
console.log('Download successfully')
} else {
console.log(`Download failed: ${state}`)
}
});
});
// and load the index.html of the app.
// console.log(app.isPackaged)
// if (!app.isPackaged) {
@ -67,9 +134,18 @@ app.whenReady().then(() => {
app.on('NSApplicationDelegate.applicationSupportsSecureRestorableState', () => true)
const menu = Menu.buildFromTemplate([{
label: '文件',
submenu: [{
label: '保存全部',
click: downloadAll
}]
}]);
Menu.setApplicationMenu(menu);
createWindow()
app.on('activate', function () {
app.on('activate', function() {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
@ -80,7 +156,7 @@ app.whenReady().then(() => {
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
app.on('window-all-closed', function() {
if (process.platform !== 'darwin') {
app.quit()
}