You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Desktop: Add message box to ask confirmation when resizing image
This commit is contained in:
		| @@ -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), | ||||
|   | ||||
| @@ -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)); | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 }; | ||||
|   | ||||
| @@ -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); | ||||
| }); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user