1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-21 09:38:01 +02:00

Desktop: Add message box to ask confirmation when resizing image

This commit is contained in:
Laurent Cozic 2020-03-31 22:40:38 +01:00
parent 7f397a4da8
commit 693f6cbfe7
5 changed files with 98 additions and 32 deletions

View File

@ -1225,7 +1225,14 @@ class NoteTextComponent extends React.Component {
const filePath = filePaths[i];
try {
reg.logger().info(`Attaching ${filePath}`);
note = await shim.attachFileToNote(note, filePath, position, createFileURL);
note = await shim.attachFileToNote(note, filePath, position, {
createFileURL: createFileURL,
resizeLargeImages: 'ask',
});
if (!note) {
reg.logger().info('File attachment was cancelled');
continue;
}
reg.logger().info('File was attached.');
this.setState({
note: Object.assign({}, note),

View File

@ -419,27 +419,47 @@ class NoteScreenComponent extends BaseScreenComponent {
const dimensions = await this.imageDimensions(localFilePath);
reg.logger().info('Original dimensions ', dimensions);
if (dimensions.width > maxSize || dimensions.height > maxSize) {
let mustResize = dimensions.width > maxSize || dimensions.height > maxSize;
if (mustResize) {
const buttonId = await dialogs.pop(this, _('You are about to attach a large image (%dx%d pixels). Would you like to resize it down to %d pixels before attaching it?', dimensions.width, dimensions.height, maxSize), [
{ text: _('Yes'), id: 'yes' },
{ text: _('No'), id: 'no' },
{ text: _('Cancel'), id: 'cancel' },
]);
if (buttonId === 'cancel') return false;
mustResize = buttonId === 'yes';
}
if (mustResize) {
dimensions.width = maxSize;
dimensions.height = maxSize;
reg.logger().info('New dimensions ', dimensions);
const format = mimeType == 'image/png' ? 'PNG' : 'JPEG';
reg.logger().info(`Resizing image ${localFilePath}`);
const resizedImage = await ImageResizer.createResizedImage(localFilePath, dimensions.width, dimensions.height, format, 85); // , 0, targetPath);
const resizedImagePath = resizedImage.uri;
reg.logger().info('Resized image ', resizedImagePath);
reg.logger().info(`Moving ${resizedImagePath} => ${targetPath}`);
await RNFS.copyFile(resizedImagePath, targetPath);
try {
await RNFS.unlink(resizedImagePath);
} catch (error) {
reg.logger().warn('Error when unlinking cached file: ', error);
}
} else {
await RNFS.copyFile(localFilePath, targetPath);
}
reg.logger().info('New dimensions ', dimensions);
const format = mimeType == 'image/png' ? 'PNG' : 'JPEG';
reg.logger().info(`Resizing image ${localFilePath}`);
const resizedImage = await ImageResizer.createResizedImage(localFilePath, dimensions.width, dimensions.height, format, 85); // , 0, targetPath);
const resizedImagePath = resizedImage.uri;
reg.logger().info('Resized image ', resizedImagePath);
reg.logger().info(`Moving ${resizedImagePath} => ${targetPath}`);
await RNFS.copyFile(resizedImagePath, targetPath);
try {
await RNFS.unlink(resizedImagePath);
} catch (error) {
reg.logger().warn('Error when unlinking cached file: ', error);
}
return true;
}
async attachFile(pickerResponse, fileType) {
@ -494,7 +514,8 @@ class NoteScreenComponent extends BaseScreenComponent {
try {
if (mimeType == 'image/jpeg' || mimeType == 'image/jpg' || mimeType == 'image/png') {
await this.resizeImage(localFilePath, targetPath, pickerResponse.mime);
const done = await this.resizeImage(localFilePath, targetPath, pickerResponse.mime);
if (!done) return;
} else {
if (fileType === 'image') {
dialogs.error(this, _('Unsupported image type: %s', mimeType));

View File

@ -64,7 +64,16 @@ function shimInit() {
}
};
const resizeImage_ = async function(filePath, targetPath, mime) {
shim.showMessageBox = (message, options = null) => {
if (shim.isElectron()) {
const { bridge } = require('electron').remote.require('./bridge');
return bridge().showMessageBox(message, options);
} else {
throw new Error('Not implemented');
}
};
const handleResizeImage_ = async function(filePath, targetPath, mime, resizeLargeImages) {
const maxDim = Resource.IMAGE_MAX_DIMENSION;
if (shim.isElectron()) {
@ -75,9 +84,21 @@ function shimInit() {
const size = image.getSize();
if (size.width <= maxDim && size.height <= maxDim) {
let mustResize = size.width > maxDim || size.height > maxDim;
if (mustResize && resizeLargeImages === 'ask') {
const answer = shim.showMessageBox(_('You are about to attach a large image (%dx%d pixels). Would you like to resize it down to %d pixels before attaching it?', size.width, size.height, maxDim), {
buttons: [_('Yes'), _('No'), _('Cancel')],
});
if (answer === 2) return false;
mustResize = answer === 0;
}
if (!mustResize) {
shim.fsDriver().copy(filePath, targetPath);
return;
return true;
}
const options = {};
@ -99,7 +120,7 @@ function shimInit() {
if (md.width <= maxDim && md.height <= maxDim) {
shim.fsDriver().copy(filePath, targetPath);
return;
return true;
}
return new Promise((resolve, reject) => {
@ -117,9 +138,15 @@ function shimInit() {
});
});
}
return true;
};
shim.createResourceFromPath = async function(filePath, defaultProps = null) {
shim.createResourceFromPath = async function(filePath, defaultProps = null, options = null) {
options = Object.assign({
resizeLargeImages: 'always', // 'always' or 'ask'
}, options);
const readChunk = require('read-chunk');
const imageType = require('image-type');
@ -155,8 +182,9 @@ function shimInit() {
const targetPath = Resource.fullPath(resource);
if (resource.mime == 'image/jpeg' || resource.mime == 'image/jpg' || resource.mime == 'image/png') {
await resizeImage_(filePath, targetPath, resource.mime);
if (['image/jpeg', 'image/jpg', 'image/png'].includes(resource.mime)) {
const ok = await handleResizeImage_(filePath, targetPath, resource.mime, options.resizeLargeImages);
if (!ok) return null;
} else {
// const stat = await shim.fsDriver().stat(filePath);
// if (stat.size >= 10000000) throw new Error('Resources larger than 10 MB are not currently supported as they may crash the mobile applications. The issue is being investigated and will be fixed at a later time.');
@ -177,16 +205,22 @@ function shimInit() {
return Resource.save(resource, { isNew: true });
};
shim.attachFileToNote = async function(note, filePath, position = null, createFileURL = false) {
shim.attachFileToNote = async function(note, filePath, position = null, options = null) {
options = Object.assign({}, {
createFileURL: false,
}, options);
const { basename } = require('path');
const { escapeLinkText } = require('lib/markdownUtils');
const { toFileProtocolPath } = require('lib/path-utils');
let resource = [];
if (!createFileURL) {
resource = await shim.createResourceFromPath(filePath);
let resource = null;
if (!options.createFileURL) {
resource = await shim.createResourceFromPath(filePath, null, options);
}
if (!resource) return null;
const newBody = [];
if (position === null) {
@ -195,7 +229,7 @@ function shimInit() {
if (note.body && position) newBody.push(note.body.substr(0, position));
if (!createFileURL) {
if (!options.createFileURL) {
newBody.push(Resource.markdownTag(resource));
} else {
const filename = escapeLinkText(basename(filePath)); // to get same filename as standard drag and drop

View File

@ -220,4 +220,8 @@ shim.pathRelativeToCwd = (path) => {
throw new Error('Not implemented');
};
shim.showMessageBox = (message, options = null) => {
throw new Error('Not implemented');
};
module.exports = { shim };

View File

@ -44,7 +44,7 @@ gulp.task('watch', function() {
// For watching, we use the actual tsc tool because it's more robust and
// doesn't crash when there's an error
const promise = execa('node', ['node_modules/typescript/bin/tsc', '--project', 'tsconfig.json'], { cwd: `${__dirname}` });
const promise = execa('node', ['node_modules/typescript/bin/tsc', '--watch', '--project', 'tsconfig.json'], { cwd: `${__dirname}` });
promise.stdout.pipe(process.stdout);
});