From c0b8752fdc3167c447115dabd28c737e674e4e9f Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Mon, 7 Jan 2019 15:17:28 -0800 Subject: [PATCH 1/3] Override 'will-download' event to use native save window --- src/main/index.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/main/index.js b/src/main/index.js index 4e9f415..d89411d 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -10,6 +10,13 @@ telemetry.appWasOpened(); // const defaultSize = {width: 1096, height: 715}; // minimum const defaultSize = {width: 1280, height: 800}; // good for MAS screenshots +const fileFilters = { + '.sb3': { + name: 'Scratch 3 Project', + extensions: ['sb3'] + } +}; + const isDevelopment = process.env.NODE_ENV !== 'production'; const createMainWindow = () => { @@ -54,6 +61,30 @@ const createMainWindow = () => { })); } + webContents.session.on('will-download', (ev, item) => { + const itemPath = item.getFilename(); + const baseName = path.basename(itemPath); + const extName = path.extname(baseName); + if (extName) { + const extNameNoDot = extName.replace(/^\./, ''); + const options = { + defaultPath: path.join(app.getPath('documents'), baseName), + filters: [ + fileFilters[extName] || { + name: `${extNameNoDot.toUpperCase()} Files`, + extensions: [extNameNoDot] + } + ] + }; + const userChosenPath = dialog.showSaveDialog(window, options); + if (userChosenPath) { + item.setSavePath(userChosenPath); + } else { + item.cancel(); + } + } + }); + webContents.on('will-prevent-unload', ev => { const choice = dialog.showMessageBox(window, { type: 'question', From 1113ba0c18182943252c83a80f3a7d32edb9ee0b Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Tue, 8 Jan 2019 11:23:55 -0800 Subject: [PATCH 2/3] Support more file types in save dialog override --- src/main/FileFilters.js | 102 ++++++++++++++++++++++++++++++++++++++++ src/main/index.js | 15 +----- 2 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 src/main/FileFilters.js diff --git a/src/main/FileFilters.js b/src/main/FileFilters.js new file mode 100644 index 0000000..1d3cde8 --- /dev/null +++ b/src/main/FileFilters.js @@ -0,0 +1,102 @@ +const saveFilters = { + JPEG: { + name: 'JPEG Image', + extensions: ['jpg', 'jpeg'] + }, + MP3: { + name: 'MP3 Sound', + extensions: ['mp3'] + }, + PNG: { + name: 'PNG Image', + extensions: ['png'] + }, + SB: { + name: 'Scratch 1 Project', + extensions: ['sb'] + }, + SB2: { + name: 'Scratch 2 Project', + extensions: ['sb2'] + }, + SB3: { + name: 'Scratch 3 Project', + extensions: ['sb3'] + }, + Sprite2: { + name: 'Scratch 2 Sprite', + extensions: ['sprite2'] + }, + Sprite3: { + name: 'Scratch 3 Sprite', + extensions: ['sprite3'] + }, + SVG: { + name: 'SVG Image', + extensions: ['svg'] + }, + WAV: { + name: 'WAV Sound', + extensions: ['wav'] + } +}; + +const loadFilters = { + ...saveFilters, + AllBitmaps: { + name: 'All Bitmaps', + extensions: [ + ...saveFilters.JPEG.extensions, + ...saveFilters.PNG.extensions + ] + }, + AllImages: { + name: 'All Images', + extensions: [ + ...saveFilters.JPEG.extensions, + ...saveFilters.PNG.extensions, + ...saveFilters.SVG.extensions + ] + }, + AllProjects: { + name: 'All Scratch Projects', + extensions: [ + ...saveFilters.SB3.extensions, + ...saveFilters.SB2.extensions, + ...saveFilters.SB.extensions + ] + }, + AllSounds: { + name: 'All Sounds', + extensions: [ + ...saveFilters.MP3.extensions, + ...saveFilters.WAV.extensions + ] + }, + AllSprites: { + name: 'All Sprites', + extensions: [ + ...saveFilters.Sprite3.extensions, + ...saveFilters.Sprite2.extensions + ] + } +}; + +const filtersByExtension = Object.values(saveFilters).reduce((result, filter) => { + for (const extension of filter.extensions) { + result[extension] = filter; + } + return result; +}, {}); + +const getFilterForExtension = extNameNoDot => + filtersByExtension[extNameNoDot] || { + name: `${extNameNoDot.toUpperCase()} Files`, + extensions: [extNameNoDot] + }; + +export { + saveFilters, + loadFilters, + getFilterForExtension +}; diff --git a/src/main/index.js b/src/main/index.js index d89411d..8a3e4aa 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,6 +1,7 @@ import {BrowserWindow, Menu, app, dialog} from 'electron'; import * as path from 'path'; import {format as formatUrl} from 'url'; +import {getFilterForExtension} from './FileFilters'; import telemetry from './ScratchDesktopTelemetry'; import MacOSMenu from './MacOSMenu'; @@ -10,13 +11,6 @@ telemetry.appWasOpened(); // const defaultSize = {width: 1096, height: 715}; // minimum const defaultSize = {width: 1280, height: 800}; // good for MAS screenshots -const fileFilters = { - '.sb3': { - name: 'Scratch 3 Project', - extensions: ['sb3'] - } -}; - const isDevelopment = process.env.NODE_ENV !== 'production'; const createMainWindow = () => { @@ -69,12 +63,7 @@ const createMainWindow = () => { const extNameNoDot = extName.replace(/^\./, ''); const options = { defaultPath: path.join(app.getPath('documents'), baseName), - filters: [ - fileFilters[extName] || { - name: `${extNameNoDot.toUpperCase()} Files`, - extensions: [extNameNoDot] - } - ] + filters: [getFilterForExtension(extNameNoDot)] }; const userChosenPath = dialog.showSaveDialog(window, options); if (userChosenPath) { From d93cd7ae33935a3e1e6d88f1e13cf3d4011fe736 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Tue, 8 Jan 2019 15:37:37 -0800 Subject: [PATCH 3/3] Remember last save location --- src/main/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/index.js b/src/main/index.js index 8a3e4aa..a00c2c7 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -62,7 +62,6 @@ const createMainWindow = () => { if (extName) { const extNameNoDot = extName.replace(/^\./, ''); const options = { - defaultPath: path.join(app.getPath('documents'), baseName), filters: [getFilterForExtension(extNameNoDot)] }; const userChosenPath = dialog.showSaveDialog(window, options);