Browse Source

docs: update custom plugin example

thanks @kiloreux
Artur Paikin 5 years ago
parent
commit
ee39e7c967
1 changed files with 64 additions and 12 deletions
  1. 64 12
      website/src/docs/writing-plugins.md

+ 64 - 12
website/src/docs/writing-plugins.md

@@ -224,30 +224,60 @@ this.i18nArray = this.translator.translateArray.bind(this.translator)
 
 ## 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.
+Below is a full example of a [simple plugin](https://github.com/arturi/uppy-plugin-image-compressor) that compresses images before uploading them. You can replace `compressorjs` 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')
+const { Plugin } = require('@uppy/core')
+const Translator = require('@uppy/utils/lib/Translator')
+const Compressor = require('compressorjs/dist/compressor.common.js')
 
-class UppyCompressor extends Plugin {
-  constructor (uppy, options) {
-    super(uppy, options)
-    this.id = options.id || 'Compressor'
+class UppyImageCompressor extends Plugin {
+  constructor (uppy, opts) {
+    super(uppy, opts)
+    this.id = this.opts.id || 'ImageCompressor'
     this.type = 'modifier'
 
+    this.defaultLocale = {
+      strings: {
+        compressingImages: 'Compressing images...'
+      }
+    }
+
+    const defaultOptions = {
+      quality: 0.6
+    }
+
+    this.opts = Object.assign({}, defaultOptions, opts)
+
+    // we use those internally in `this.compress`, so they
+    // should not be overriden
+    delete this.opts.success
+    delete this.opts.error
+
+    this.i18nInit()
+
     this.prepareUpload = this.prepareUpload.bind(this)
     this.compress = this.compress.bind(this)
   }
 
+  setOptions (newOpts) {
+    super.setOptions(newOpts)
+    this.i18nInit()
+  }
+
+  i18nInit () {
+    this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
+    this.i18n = this.translator.translate.bind(this.translator)
+    this.setPluginState() // so that UI re-renders and we see the updated locale
+  }
+
   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) => {
@@ -261,27 +291,49 @@ class UppyCompressor extends Plugin {
   prepareUpload (fileIDs) {
     const promises = fileIDs.map((fileID) => {
       const file = this.uppy.getFile(fileID)
+      this.uppy.emit('preprocess-progress', file, {
+        mode: 'indeterminate',
+        message: this.i18n('compressingImages')
+      })
+
       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)
+        this.uppy.log(`[Image Compressor] Image ${file.id} size before/after compression: ${file.data.size} / ${compressedBlob.size}`)
+        this.uppy.setFileState(fileID, { data: compressedBlob })
+      }).catch((err) => {
+        this.uppy.log(`[Image Compressor] Failed to compress ${file.id}:`, 'warning')
+        this.uppy.log(err, 'warning')
       })
     })
+
+    const emitPreprocessCompleteForAll = () => {
+      fileIDs.forEach((fileID) => {
+        const file = this.uppy.getFile(fileID)
+        this.uppy.emit('preprocess-complete', file)
+      })
+    }
+
+    // Why emit `preprocess-complete` for all files at once, instead of
+    // above when each is processed?
+    // Because it leads to StatusBar showing a weird “upload 6 files” button,
+    // while waiting for all the files to complete pre-processing.
     return Promise.all(promises)
+      .then(emitPreprocessCompleteForAll)
   }
 
   install () {
     this.uppy.addPreProcessor(this.prepareUpload)
   }
-
+  
   uninstall () {
     this.uppy.removePreProcessor(this.prepareUpload)
   }
 }
 
-module.exports = UppyCompressor
+module.exports = UppyImageCompressor
 ```
 
 [core.setfilestate]: /docs/uppy#uppy-setFileState-fileID-state