Skip to content

Commit db31dc3

Browse files
committed
fix(App): Fix "save image as"
1 parent 7fdf915 commit db31dc3

File tree

4 files changed

+81
-57
lines changed

4 files changed

+81
-57
lines changed

src/electron/ipc-api/download.js

Lines changed: 0 additions & 55 deletions
This file was deleted.

src/electron/ipc-api/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import autoUpdate from './autoUpdate';
33
import browserViewManager from './browserViewManager';
44
import cld from './cld';
55
import desktopCapturer from './desktopCapturer';
6-
import download from './download';
76
import focusState from './focusState';
87
import fullscreenStatus from './fullscreen';
98
import macOSPermissions from './macOSPermissions';
@@ -16,7 +15,6 @@ export default (params) => {
1615
settings(params);
1716
autoUpdate(params);
1817
appIndicator(params);
19-
download(params);
2018
cld(params);
2119
desktopCapturer();
2220
focusState(params);

src/electron/serviceContextMenuTemplate.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { DEFAULT_WEB_CONTENTS_ID } from '../config';
1111
import { isDevMode, isMac } from '../environment';
1212
import { IPC } from '../features/todos/constants';
1313
import { SPELLCHECKER_LOCALES } from '../i18n/languages';
14+
import { downloadFile } from '../lib/download';
1415

1516
const debug = require('debug')('Franz:feature:serviceContextMenu');
1617

@@ -211,6 +212,14 @@ export const buildMenuTpl = ({
211212
reader.onloadend = () => {
212213
const base64data = reader.result;
213214

215+
downloadFile({
216+
content: base64data,
217+
webContents: contents,
218+
fileOptions: {
219+
name: fileName,
220+
mime: blob.type,
221+
},
222+
});
214223
contents.send('download-file', {
215224
content: base64data,
216225
fileOptions: {
@@ -222,6 +231,10 @@ export const buildMenuTpl = ({
222231
debug('binary string', blob);
223232
} else {
224233
contents.send('download-file', { url: props.srcURL });
234+
downloadFile({
235+
url: props.srcURL,
236+
webContents: contents,
237+
});
225238
}
226239
},
227240
}, {

src/lib/download.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { dialog, WebContents } from 'electron';
2+
import { download } from 'electron-dl';
3+
import fs from 'fs-extra';
4+
import mime from 'mime-types';
5+
6+
const debug = require('debug')('Franz:ipcApi:download');
7+
8+
function decodeBase64Image(dataString) {
9+
const matches = dataString.match(/^data:([A-Za-z-+/]+);base64,(.+)$/);
10+
11+
if (matches.length !== 3) {
12+
return new Error('Invalid input string');
13+
}
14+
15+
return Buffer.from(matches[2], 'base64');
16+
}
17+
18+
type Params = {
19+
url?: string;
20+
content?: string | ArrayBuffer;
21+
webContents: WebContents;
22+
fileOptions?: {
23+
mime: string;
24+
name: string;
25+
};
26+
}
27+
// export default (params) => {
28+
export async function downloadFile({
29+
url,
30+
content,
31+
webContents,
32+
fileOptions,
33+
}: Params) {
34+
// We're passing a fake browserWindow to `electron-dl` in order to access the
35+
// webContents of the webview that has initiated the download
36+
const fakeWindow = {
37+
webContents,
38+
};
39+
40+
try {
41+
if (!content) {
42+
const dl = await download(fakeWindow, url, {
43+
saveAs: true,
44+
});
45+
debug('File saved to', dl.savePath);
46+
} else {
47+
const extension = mime.extension(fileOptions.mime);
48+
const filename = `${fileOptions.name}.${extension}`;
49+
50+
try {
51+
const saveDialog = await dialog.showSaveDialog(null, {
52+
defaultPath: filename,
53+
});
54+
55+
if (saveDialog.canceled) return;
56+
57+
const binaryImage = decodeBase64Image(content);
58+
fs.writeFileSync(saveDialog.filePath, binaryImage, 'binary');
59+
60+
debug('File blob saved to', saveDialog.filePath);
61+
} catch (err) {
62+
console.log(err);
63+
}
64+
}
65+
} catch (e) {
66+
console.error(e);
67+
}
68+
}

0 commit comments

Comments
 (0)