From 3dffcfac5f12de66933cc4e3e4efcf4c1210ad6f Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Wed, 12 Jun 2019 11:30:19 +0300 Subject: [PATCH] docs: add custom plugin example (#1623) * Add custom plugin full example * Mention that a custom plugin is needed for async work in onBeforeFileAdded and onBeforeUpload * fix demo not working in IE 11 (es5), add Dropbox too --- website/src/docs/uppy.md | 8 +++- website/src/docs/writing-plugins.md | 67 ++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/website/src/docs/uppy.md b/website/src/docs/uppy.md index 59acd8397..67ad1ab57 100644 --- a/website/src/docs/uppy.md +++ b/website/src/docs/uppy.md @@ -120,6 +120,8 @@ A function run before a file is added to Uppy. It gets passed `(currentFile, fil Use this function to run any number of custom checks on the selected file, or manipulate it, for instance, by optimizing a file name. +> ⚠️ Note that this method is intended for quick synchronous checks/modifications only. If you need to do an async API call, or heavy work on a file (like compression or encryption), you should utilize a [custom plugin](/docs/writing-plugins/#Example-of-a-custom-plugin) instead. + Return true/nothing or a modified file object to proceed with adding the file: ```js @@ -155,7 +157,7 @@ onBeforeFileAdded: (currentFile, files) => { } ``` -**Note:** it is up to you to show a notification to the user about a file not passing validation. We recommend showing a message using [uppy.info()](#uppy-info) and logging to console for debugging purposes. +**Note:** it is up to you to show a notification to the user about a file not passing validation. We recommend showing a message using [uppy.info()](#uppy-info) and logging to console for debugging purposes via [uppy.log()](#uppy-log). @@ -165,6 +167,8 @@ A function run before an upload begins. Gets passed `files` object with all the Use this to check if all files or their total number match your requirements, or manipulate all the files at once before upload. +> ⚠️ Note that this method is intended for quick synchronous checks/modifications only. If you need to do an async API call, or heavy work on a file (like compression or encryption), you should utilize a [custom plugin](/docs/writing-plugins/#Example-of-a-custom-plugin) instead. + Return true or modified `files` object to proceed: ```js @@ -191,7 +195,7 @@ onBeforeUpload: (files) => { } ``` -**Note:** it is up to you to show a notification to the user about a file not passing validation. We recommend showing a message using [uppy.info()](#uppy-info) and logging to console for debugging purposes. +**Note:** it is up to you to show a notification to the user about a file not passing validation. We recommend showing a message using [uppy.info()](#uppy-info) and logging to console for debugging purposes via [uppy.log()](#uppy-log). ### `locale: {}` diff --git a/website/src/docs/writing-plugins.md b/website/src/docs/writing-plugins.md index ca102d5e6..e900179e8 100644 --- a/website/src/docs/writing-plugins.md +++ b/website/src/docs/writing-plugins.md @@ -10,8 +10,11 @@ There are already a few useful Uppy plugins out there, but there might come a ti - Render some custom UI element, e.g., [StatusBar](/docs/statusbar) or [Dashboard](/docs/dashboard). - Do the actual uploading, e.g., [XHRUpload](/docs/xhrupload) or [Tus](/docs/tus). + - Do work before the upload, like compressing an image or calling external API. - Interact with a third-party service to process uploads correctly, e.g., [Transloadit](/docs/transloadit) or [AwsS3](/docs/aws-s3). +See a [full example of a plugin](#Example-of-a-custom-plugin) below. + ## Creating A Plugin Plugins are classes that extend from Uppy's `Plugin` class. Each plugin has an `id` and a `type`. `id`s are used to uniquely identify plugins. A `type` can be anything—some plugins use `type`s to determine whether to do something to some other plugin. For example, when targeting plugins at the built-in `Dashboard` plugin, the Dashboard uses the `type` to figure out where to mount different UI elements. `'acquirer'`-type plugins are mounted into the tab bar, while `'progressindicator'`-type plugins are mounted into the progress bar area. @@ -219,4 +222,66 @@ this.i18nArray = this.translator.translateArray.bind(this.translator) // ^-- Only if you're using i18nArray, which allows you to pass in JSX Components as well. ``` -[core.setfilestate]: /docs/uppy#uppy-setFileState-fileID-state \ No newline at end of file +## Example of a custom plugin + +Below is a full example of a simple plugin that compresses images before uploading them. You can replace `compress` method with any other work you need to do. This works especially well for async stuff, like calling an external API. + +```js +const Compressor = require('compressorjs') + +class UppyCompressor extends Plugin { + constructor (uppy, options) { + super(uppy, options) + this.id = options.id || 'Compressor' + this.type = 'modifier' + + this.prepareUpload = this.prepareUpload.bind(this) + this.compress = this.compress.bind(this) + } + + compress (blob) { + this.uppy.log(`[Compressor] Image size before compression: ${blob.size}`) + return new Promise((resolve, reject) => { + new Compressor(blob, Object.assign( + {}, + this.opts, + { + success: (result) => { + this.uppy.log(`[Compressor] Image size after compression: ${result.size}`) + return resolve(result) + }, + error: (err) => { + return reject(err) + } + } + )) + }) + } + + prepareUpload (fileIDs) { + const promises = fileIDs.map((fileID) => { + const file = this.uppy.getFile(fileID) + if (file.type.split('/')[0] !== 'image') { + return + } + return this.compress(file.data).then((compressedBlob) => { + const compressedFile = Object.assign({}, file, { data: compressedBlob }) + this.uppy.setFileState(fileID, compressedFile) + }) + }) + return Promise.all(promises) + } + + install () { + this.uppy.addPreProcessor(this.prepareUpload) + } + + uninstall () { + this.uppy.removePreProcessor(this.prepareUpload) + } +} + +module.exports = UppyCompressor +``` + +[core.setfilestate]: /docs/uppy#uppy-setFileState-fileID-state