Add "Save image as..." button to context menu on images

Fixes https://github.com/vector-im/riot-web/issues/9324
Requires https://github.com/matrix-org/matrix-react-sdk/pull/2848
pull/9327/head
Travis Ralston 2019-03-29 14:57:02 -06:00
parent d1a5b79bc3
commit 7a9cea4baa
1 changed files with 37 additions and 1 deletions

View File

@ -1,5 +1,7 @@
const {clipboard, nativeImage, Menu, MenuItem, shell} = require('electron'); const {clipboard, nativeImage, Menu, MenuItem, shell, dialog} = require('electron');
const url = require('url'); const url = require('url');
const fs = require('fs');
const request = require('request');
const MAILTO_PREFIX = "mailto:"; const MAILTO_PREFIX = "mailto:";
@ -47,6 +49,7 @@ function onLinkContextMenu(ev, params) {
})); }));
} }
let addSaveAs = false;
if (params.mediaType && params.mediaType === 'image' && !url.startsWith('file://')) { if (params.mediaType && params.mediaType === 'image' && !url.startsWith('file://')) {
popupMenu.append(new MenuItem({ popupMenu.append(new MenuItem({
label: 'Copy image', label: 'Copy image',
@ -58,6 +61,10 @@ function onLinkContextMenu(ev, params) {
} }
}, },
})); }));
// We want the link to be ordered below the copy stuff, but don't want to duplicate
// the `if` statement, so use a flag.
addSaveAs = true;
} }
// No point offering to copy a blob: URL either // No point offering to copy a blob: URL either
@ -79,6 +86,35 @@ function onLinkContextMenu(ev, params) {
})); }));
} }
} }
if (addSaveAs) {
popupMenu.append(new MenuItem({
label: 'Save image as...',
click() {
const targetFileName = params.titleText || "image.png";
const filePath = dialog.showSaveDialog({
defaultPath: targetFileName,
});
try {
if (url.startsWith("data:")) {
fs.writeFileSync(filePath, nativeImage.createFromDataURL(url));
} else {
request.get(url).pipe(fs.createWriteStream(filePath));
}
} catch (err) {
console.error(err);
dialog.showMessageBox({
type: "error",
title: "Failed to save image",
message: "The image failed to save",
});
}
},
}));
}
// popup() requires an options object even for no options // popup() requires an options object even for no options
popupMenu.popup({}); popupMenu.popup({});
ev.preventDefault(); ev.preventDefault();