Browse Source

example: showcase migration out of Robodog (#4021)

* example: showcase migration out of Robodog

Co-authored-by: Artur Paikin <artur@arturpaikin.com>

* Fix server, apply what was done in #3946

* Do weird things with input[type=file]

* fix last example

* Improve completion logging

* Fix lint

Co-authored-by: Artur Paikin <artur@arturpaikin.com>
Antoine du Hamel 2 years ago
parent
commit
089aaed615

+ 1 - 0
.eslintrc.js

@@ -199,6 +199,7 @@ module.exports = {
         'examples/node-xhr/*.js',
         'examples/php-xhr/*.js',
         'examples/python-xhr/*.js',
+        'examples/transloadit/*.js',
         'examples/transloadit-markdown-bin/*.js',
         'examples/xhr-bundle/*.js',
         'private/dev/*.js',

+ 2 - 0
examples/transloadit/.gitignore

@@ -1 +1,3 @@
 uppy.min.css
+bundle.js
+bundle.js.map

+ 24 - 0
examples/transloadit/README.md

@@ -0,0 +1,24 @@
+# Robodog
+
+This example shows all the different Robodog APIs in action on a single page.
+Robodog has been deprecated, so this example shows how to replicate Robodog
+features without using it. If you are new with Uppy, this example is probably
+not for you, as it is specifically aimed for Robodog users looking to migrate
+out of it.
+
+## Run it
+
+To run this example, make sure you've correctly installed the **repository root**:
+
+```sh
+corepack yarn install
+corepack yarn build
+```
+
+That will also install the dependencies for this example.
+
+Then, again in the **repository root**, start this example by doing:
+
+```sh
+corepack yarn workspace @uppy-example/transloadit start
+```

+ 156 - 53
examples/transloadit/main.js

@@ -1,5 +1,16 @@
-const { inspect } = require('node:util')
-const robodog = require('@uppy/robodog')
+import Transloadit, { COMPANION_URL } from '@uppy/transloadit'
+import Uppy from '@uppy/core'
+import Form from '@uppy/form'
+import Dashboard from '@uppy/dashboard'
+import RemoteSources from '@uppy/remote-sources'
+import ImageEditor from '@uppy/image-editor'
+import Webcam from '@uppy/webcam'
+import ProgressBar from '@uppy/progress-bar'
+
+import '@uppy/core/dist/style.css'
+import '@uppy/dashboard/dist/style.css'
+import '@uppy/image-editor/dist/style.css'
+import '@uppy/progress-bar/dist/style.css'
 
 const TRANSLOADIT_KEY = '35c1aed03f5011e982b6afe82599b6a0'
 // A trivial template that resizes images, just for example purposes.
@@ -17,23 +28,43 @@ const TRANSLOADIT_KEY = '35c1aed03f5011e982b6afe82599b6a0'
 const TEMPLATE_ID = 'bbc273f69e0c4694a5a9d1b587abc1bc'
 
 /**
- * robodog.form
+ * Form
  */
 
-const formUppy = robodog.form('#test-form', {
+// Robodog supported automatically replacing <input type="file"> elements
+// Now we do it manually:
+const button = document.createElement('button')
+button.type = 'button'
+button.innerText = 'Select files'
+button.id = 'select-files'
+const fileInput = document.querySelector('#test-form input[type=file]')
+fileInput.replaceWith(button)
+
+const formUppy = new Uppy({
   debug: true,
-  fields: ['message'],
+  autoProceed: true,
   restrictions: {
     allowedFileTypes: ['.png'],
   },
-  waitForEncoding: true,
-  params: {
-    auth: { key: TRANSLOADIT_KEY },
-    template_id: TEMPLATE_ID,
-  },
-  modal: true,
-  progressBar: '#test-form .progress',
 })
+  .use(Dashboard, {
+    trigger: '#select-files',
+    closeAfterFinish: true,
+    note: 'Only PNG files please!',
+  })
+  .use(RemoteSources, { companionUrl: COMPANION_URL })
+  .use(Form, {
+    target: '#test-form',
+    fields: ['message'],
+    addResultToForm: true,
+  })
+  .use(Transloadit, {
+    waitForEncoding: true,
+    params: {
+      auth: { key: TRANSLOADIT_KEY },
+      template_id: TEMPLATE_ID,
+    },
+  })
 
 formUppy.on('error', (err) => {
   document.querySelector('#test-form .error')
@@ -45,81 +76,153 @@ formUppy.on('upload-error', (file, err) => {
     .textContent = err.message
 })
 
+formUppy.on('complete', ({ transloadit }) => {
+  const btn = document.getElementById('select-files')
+  const form = document.getElementById('test-form')
+  btn.hidden = true
+  const selectedFiles = document.createElement('uppy-form-selected-files')
+  selectedFiles.textContent = `selected files: ${Object.keys(transloadit[0].results).length}`
+  form.appendChild(selectedFiles)
+})
+
 window.formUppy = formUppy
 
-const formUppyWithDashboard = robodog.form('#dashboard-form', {
+/**
+ * Form with Dashboard
+ */
+
+const formUppyWithDashboard = new Uppy({
   debug: true,
-  fields: ['message'],
+  autoProceed: false,
   restrictions: {
     allowedFileTypes: ['.png'],
   },
-  waitForEncoding: true,
-  note: 'Only PNG files please!',
-  params: {
-    auth: { key: TRANSLOADIT_KEY },
-    template_id: TEMPLATE_ID,
-  },
-  dashboard: '#dashboard-form .dashboard',
 })
+  .use(Dashboard, {
+    inline: true,
+    target: '#dashboard-form .dashboard',
+    note: 'Only PNG files please!',
+    hideUploadButton: true,
+  })
+  .use(RemoteSources, { companionUrl: COMPANION_URL })
+  .use(Form, {
+    target: '#dashboard-form',
+    fields: ['message'],
+    triggerUploadOnSubmit: true,
+    submitOnSuccess: true,
+    addResultToForm: true,
+  })
+  .use(Transloadit, {
+    waitForEncoding: true,
+    params: {
+      auth: { key: TRANSLOADIT_KEY },
+      template_id: TEMPLATE_ID,
+    },
+  })
 
 window.formUppyWithDashboard = formUppyWithDashboard
 
-const dashboard = robodog.dashboard('#dashboard', {
+/**
+ * Dashboard
+ */
+
+const dashboard = new Uppy({
   debug: true,
-  waitForEncoding: true,
-  note: 'Images will be resized with Transloadit',
-  params: {
-    auth: { key: TRANSLOADIT_KEY },
-    template_id: TEMPLATE_ID,
+  autoProceed: false,
+  restrictions: {
+    allowedFileTypes: ['.png'],
   },
 })
+  .use(Dashboard, {
+    inline: true,
+    target: '#dashboard',
+    note: 'Only PNG files please!',
+  })
+  .use(RemoteSources, { companionUrl: COMPANION_URL })
+  .use(Webcam, { target: Dashboard })
+  .use(ImageEditor, { target: Dashboard })
+  .use(Transloadit, {
+    waitForEncoding: true,
+    params: {
+      auth: { key: TRANSLOADIT_KEY },
+      template_id: TEMPLATE_ID,
+    },
+  })
 
 window.dashboard = dashboard
 
-/**
- * robodog.modal
- */
+// /**
+//  * Dashboard Modal
+//  */
 
-function openModal () {
-  robodog.pick({
-    restrictions: {
-      allowedFileTypes: ['.png'],
-    },
+const dashboardModal = new Uppy({
+  debug: true,
+  autoProceed: false,
+})
+  .use(Dashboard, { closeAfterFinish: true })
+  .use(RemoteSources, { companionUrl: COMPANION_URL })
+  .use(Webcam, { target: Dashboard })
+  .use(ImageEditor, { target: Dashboard })
+  .use(Transloadit, {
     waitForEncoding: true,
     params: {
       auth: { key: TRANSLOADIT_KEY },
       template_id: TEMPLATE_ID,
     },
-    providers: [
-      'webcam',
-    ],
-    // if providers need custom config
-    // webcam: {
-    //   option: 'whatever'
-    // }
-  }).then(console.log, console.error)
+  })
+
+dashboardModal.on('complete', ({ transloadit, successful, failed }) => {
+  if (failed?.length !== 0) {
+    console.error('it failed', failed)
+  } else {
+    console.log('success', { transloadit, successful })
+  }
+})
+
+function openModal () {
+  dashboardModal.getPlugin('Dashboard').openModal()
 }
 
 window.openModal = openModal
 
-/**
- * robodog.upload
- */
+// /**
+//  * uppy.upload (files come from input[type=file])
+//  */
 
-window.doUpload = (event) => {
-  const resultEl = document.querySelector('#upload-result')
-  const errorEl = document.querySelector('#upload-error')
-  robodog.upload(event.target.files, {
+const uppyWithoutUI = new Uppy({
+  debug: true,
+  restrictions: {
+    allowedFileTypes: ['.png'],
+  },
+})
+  .use(Transloadit, {
     waitForEncoding: true,
     params: {
       auth: { key: TRANSLOADIT_KEY },
       template_id: TEMPLATE_ID,
     },
-  }).then((result) => {
+  })
+  .use(ProgressBar, { target: '#upload-result' })
+
+window.doUpload = (event) => {
+  const resultEl = document.querySelector('#upload-result')
+  const errorEl = document.querySelector('#upload-error')
+
+  uppyWithoutUI.addFiles(event.target.files)
+  uppyWithoutUI.upload()
+
+  uppyWithoutUI.on('complete', ({ transloadit }) => {
+    const resizedUrl = transloadit[0].results['resize'][0]['ssl_url']
+    const img = document.createElement('img')
+    img.src = resizedUrl
+    document.getElementById('upload-result').appendChild(img)
+
     resultEl.classList.remove('hidden')
     errorEl.classList.add('hidden')
-    resultEl.textContent = inspect(result.results)
-  }, (err) => {
+    resultEl.textContent = JSON.stringify(transloadit[0].results, null, 2)
+  })
+
+  uppyWithoutUI.on('error', (err) => {
     resultEl.classList.add('hidden')
     errorEl.classList.remove('hidden')
     errorEl.textContent = err.message

+ 22 - 6
examples/transloadit/package.json

@@ -2,16 +2,32 @@
   "name": "@uppy-example/transloadit",
   "version": "0.0.0",
   "dependencies": {
-    "@babel/core": "^7.4.4",
-    "@uppy/robodog": "workspace:*",
-    "babelify": "^10.0.0",
-    "budo": "^11.3.2",
+    "@uppy/core": "workspace:*",
+    "@uppy/dashboard": "workspace:*",
+    "@uppy/drop-target": "workspace:*",
+    "@uppy/form": "workspace:*",
+    "@uppy/image-editor": "workspace:*",
+    "@uppy/progress-bar": "workspace:*",
+    "@uppy/remote-sources": "workspace:*",
+    "@uppy/transloadit": "workspace:*",
+    "@uppy/webcam": "workspace:*",
     "express": "^4.16.4",
     "he": "^1.2.0"
   },
+  "devDependencies": {
+    "@rollup/plugin-commonjs": "^22.0.0",
+    "@rollup/plugin-node-resolve": "^13.0.0",
+    "npm-run-all": "^4.1.5",
+    "rollup": "^2.60.2",
+    "rollup-plugin-css-only": "^3.0.0",
+    "rollup-plugin-livereload": "^2.0.0",
+    "rollup-plugin-terser": "^7.0.0"
+  },
   "private": true,
   "scripts": {
-    "css": "cp ../../packages/uppy/dist/uppy.min.css .",
-    "start": "yarn run css && (node server & budo main.js:bundle.js -- -t babelify & wait)"
+    "serve": "sirv .",
+    "start:server": "node server.cjs",
+    "start:client": "rollup -c -w",
+    "start": "npm-run-all --parallel start:server start:client"
   }
 }

+ 0 - 20
examples/transloadit/readme.md

@@ -1,20 +0,0 @@
-# Robodog
-
-This example shows all the different Robodog APIs in action on a single page.
-
-## Run it
-
-To run this example, make sure you've correctly installed the **repository root**:
-
-```bash
-npm install
-npm run build
-```
-
-That will also install the dependencies for this example.
-
-Then, again in the **repository root**, start this example by doing:
-
-```bash
-npm run example transloadit
-```

+ 70 - 0
examples/transloadit/rollup.config.js

@@ -0,0 +1,70 @@
+import { spawn } from 'node:child_process'
+
+import commonjs from '@rollup/plugin-commonjs'
+import resolve from '@rollup/plugin-node-resolve'
+import livereload from 'rollup-plugin-livereload'
+import { terser } from 'rollup-plugin-terser'
+import css from 'rollup-plugin-css-only'
+
+const production = !process.env.ROLLUP_WATCH
+
+function serve () {
+  let server
+
+  function toExit () {
+    if (server) server.kill(0)
+  }
+
+  return {
+    writeBundle () {
+      if (server) return
+      server = spawn('npm', ['run', 'serve', '--', '--dev'], {
+        stdio: ['ignore', 'inherit', 'inherit'],
+        shell: true,
+      })
+
+      process.on('SIGTERM', toExit)
+      process.on('exit', toExit)
+    },
+  }
+}
+
+export default {
+  input: 'main.js',
+  output: {
+    sourcemap: true,
+    format: 'iife',
+    name: 'app',
+    file: 'bundle.js',
+  },
+  plugins: [
+    // we'll extract any component CSS out into
+    // a separate file - better for performance
+    css({ output: 'uppy.min.css' }),
+
+    // If you have external dependencies installed from
+    // npm, you'll most likely need these plugins. In
+    // some cases you'll need additional configuration -
+    // consult the documentation for details:
+    // https://github.com/rollup/plugins/tree/master/packages/commonjs
+    resolve({
+      browser: true,
+    }),
+    commonjs(),
+
+    // In dev mode, call `npm run start` once
+    // the bundle has been generated
+    !production && serve(),
+
+    // Watch the `public` directory and refresh the
+    // browser on changes when not in production
+    !production && livereload('public'),
+
+    // If we're building for production (npm run build
+    // instead of npm run dev), minify
+    production && terser(),
+  ],
+  watch: {
+    clearScreen: false,
+  },
+}

+ 27 - 2
examples/transloadit/server.js → examples/transloadit/server.cjs

@@ -25,7 +25,8 @@ function onrequest (req, res) {
 
   function onbody (body) {
     const fields = qs.parse(body)
-    const assemblies = JSON.parse(fields.transloadit)
+    const result = JSON.parse(fields.uppyResult)
+    const assemblies = result[0].transloadit
 
     res.setHeader('content-type', 'text/html')
     res.write(Header())
@@ -76,9 +77,33 @@ function FormFields (fields) {
 
   function Field ([name, value]) {
     if (name === 'transloadit') return ''
+    let isValueJSON = false
+    if (value.startsWith('{') || value.startsWith('[')) {
+      try {
+        value = JSON.stringify(
+          JSON.parse(value),
+          null,
+          2,
+        )
+        isValueJSON = true
+      } catch {
+        // Nothing
+      }
+    }
+
+    const prettyValue = isValueJSON ? `
+        <details open>
+          <code>
+            <pre style="max-width: 100%; max-height: 400px; white-space: pre-wrap; overflow: auto;">${e(value)}</pre>
+          </code>
+        </details>
+      ` : e(value)
+
     return `
       <dt>${e(name)}</dt>
-      <dd>${e(value)}</dd>
+      <dd>
+        ${prettyValue}
+      </dd>
     `
   }
 }

+ 19 - 7
yarn.lock

@@ -8285,12 +8285,24 @@ __metadata:
   version: 0.0.0-use.local
   resolution: "@uppy-example/transloadit@workspace:examples/transloadit"
   dependencies:
-    "@babel/core": ^7.4.4
-    "@uppy/robodog": "workspace:*"
-    babelify: ^10.0.0
-    budo: ^11.3.2
+    "@rollup/plugin-commonjs": ^22.0.0
+    "@rollup/plugin-node-resolve": ^13.0.0
+    "@uppy/core": "workspace:*"
+    "@uppy/dashboard": "workspace:*"
+    "@uppy/drop-target": "workspace:*"
+    "@uppy/form": "workspace:*"
+    "@uppy/image-editor": "workspace:*"
+    "@uppy/progress-bar": "workspace:*"
+    "@uppy/remote-sources": "workspace:*"
+    "@uppy/transloadit": "workspace:*"
+    "@uppy/webcam": "workspace:*"
     express: ^4.16.4
     he: ^1.2.0
+    npm-run-all: ^4.1.5
+    rollup: ^2.60.2
+    rollup-plugin-css-only: ^3.0.0
+    rollup-plugin-livereload: ^2.0.0
+    rollup-plugin-terser: ^7.0.0
   languageName: unknown
   linkType: soft
 
@@ -8613,7 +8625,7 @@ __metadata:
   languageName: unknown
   linkType: soft
 
-"@uppy/form@workspace:^, @uppy/form@workspace:packages/@uppy/form":
+"@uppy/form@workspace:*, @uppy/form@workspace:^, @uppy/form@workspace:packages/@uppy/form":
   version: 0.0.0-use.local
   resolution: "@uppy/form@workspace:packages/@uppy/form"
   dependencies:
@@ -8803,7 +8815,7 @@ __metadata:
   languageName: unknown
   linkType: soft
 
-"@uppy/robodog@workspace:*, @uppy/robodog@workspace:packages/@uppy/robodog":
+"@uppy/robodog@workspace:packages/@uppy/robodog":
   version: 0.0.0-use.local
   resolution: "@uppy/robodog@workspace:packages/@uppy/robodog"
   dependencies:
@@ -12031,7 +12043,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"budo@npm:^11.3.2, budo@npm:^11.6.1, budo@npm:^11.6.2":
+"budo@npm:^11.6.1, budo@npm:^11.6.2":
   version: 11.7.0
   resolution: "budo@npm:11.7.0"
   dependencies: