Просмотр исходного кода

Update html to use hyperx; use Component where lifecycle needed, refs;

also fix bugs here and there
Artur Paikin 7 лет назад
Родитель
Сommit
b062ba4236
36 измененных файлов с 247 добавлено и 150 удалено
  1. 10 5
      src/plugins/Dashboard/ActionBrowseTagline.js
  2. 4 2
      src/plugins/Dashboard/Dashboard.js
  3. 12 3
      src/plugins/Dashboard/FileCard.js
  4. 6 3
      src/plugins/Dashboard/FileItem.js
  5. 3 1
      src/plugins/Dashboard/FileItemProgress.js
  6. 4 1
      src/plugins/Dashboard/FileList.js
  7. 19 16
      src/plugins/Dashboard/Tabs.js
  8. 0 21
      src/plugins/Dashboard/UploadBtn.js
  9. 3 1
      src/plugins/Dashboard/icons.js
  10. 5 2
      src/plugins/Dashboard/index.js
  11. 3 1
      src/plugins/Dropbox/icons.js
  12. 4 2
      src/plugins/Dropbox/index.js
  13. 3 2
      src/plugins/Dummy.js
  14. 3 1
      src/plugins/FileInput.js
  15. 4 1
      src/plugins/GoogleDrive/index.js
  16. 4 2
      src/plugins/Informer.js
  17. 6 3
      src/plugins/Instagram/index.js
  18. 3 1
      src/plugins/ProgressBar.js
  19. 30 18
      src/plugins/Provider/view/AuthView.js
  20. 3 1
      src/plugins/Provider/view/Breadcrumb.js
  21. 3 1
      src/plugins/Provider/view/Breadcrumbs.js
  22. 4 1
      src/plugins/Provider/view/Browser.js
  23. 3 1
      src/plugins/Provider/view/Loader.js
  24. 9 5
      src/plugins/Provider/view/Table.js
  25. 31 8
      src/plugins/Provider/view/TableRow.js
  26. 2 1
      src/plugins/Provider/view/index.js
  27. 4 5
      src/plugins/StatusBar/StatusBar.js
  28. 3 1
      src/plugins/Webcam/CameraIcon.js
  29. 36 32
      src/plugins/Webcam/CameraScreen.js
  30. 3 1
      src/plugins/Webcam/PermissionsScreen.js
  31. 3 1
      src/plugins/Webcam/RecordButton.js
  32. 3 1
      src/plugins/Webcam/RecordStartIcon.js
  33. 3 1
      src/plugins/Webcam/RecordStopIcon.js
  34. 3 1
      src/plugins/Webcam/SnapshotButton.js
  35. 3 1
      src/plugins/Webcam/WebcamIcon.js
  36. 5 2
      src/plugins/Webcam/index.js

+ 10 - 5
src/plugins/Dashboard/ActionBrowseTagline.js

@@ -1,4 +1,8 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
+let inputEl
 
 
 module.exports = (props) => {
 module.exports = (props) => {
   const input = html`
   const input = html`
@@ -9,7 +13,10 @@ module.exports = (props) => {
            type="file" 
            type="file" 
            name="files[]" 
            name="files[]" 
            multiple="true"
            multiple="true"
-           onchange=${props.handleInputChange} />`
+           onchange=${props.handleInputChange} 
+           ref=${(input) => {
+             inputEl = input
+           }} />`
 
 
   return html`
   return html`
     <span>
     <span>
@@ -19,9 +26,7 @@ module.exports = (props) => {
       }
       }
       <button type="button"
       <button type="button"
               class="UppyDashboard-browse"
               class="UppyDashboard-browse"
-              onclick=${(ev) => {
-                input.click()
-              }}>${props.i18n('browse')}</button>
+              onclick=${(ev) => inputEl.click()}>${props.i18n('browse')}</button>
       ${input}
       ${input}
     </span>
     </span>
   `
   `

+ 4 - 2
src/plugins/Dashboard/Dashboard.js

@@ -1,11 +1,13 @@
-const html = require('yo-yo')
 const FileList = require('./FileList')
 const FileList = require('./FileList')
 const Tabs = require('./Tabs')
 const Tabs = require('./Tabs')
 const FileCard = require('./FileCard')
 const FileCard = require('./FileCard')
-// const UploadBtn = require('./UploadBtn')
 const { isTouchDevice, toArray } = require('../../core/Utils')
 const { isTouchDevice, toArray } = require('../../core/Utils')
 const { closeIcon } = require('./icons')
 const { closeIcon } = require('./icons')
 
 
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
 // http://dev.edenspiekermann.com/2016/02/11/introducing-accessible-modal-dialog
 // http://dev.edenspiekermann.com/2016/02/11/introducing-accessible-modal-dialog
 // https://github.com/ghosh/micromodal
 // https://github.com/ghosh/micromodal
 
 

+ 12 - 3
src/plugins/Dashboard/FileCard.js

@@ -1,7 +1,10 @@
-const html = require('yo-yo')
 const getFileTypeIcon = require('./getFileTypeIcon')
 const getFileTypeIcon = require('./getFileTypeIcon')
 const { checkIcon } = require('./icons')
 const { checkIcon } = require('./icons')
 
 
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
 module.exports = function fileCard (props) {
 module.exports = function fileCard (props) {
   const file = props.fileCardFor ? props.files[props.fileCardFor] : false
   const file = props.fileCardFor ? props.files[props.fileCardFor] : false
   const meta = {}
   const meta = {}
@@ -57,8 +60,14 @@ module.exports = function fileCard (props) {
             <div class="UppyDashboardFileCard-info">
             <div class="UppyDashboardFileCard-info">
               <fieldset class="UppyDashboardFileCard-fieldset">
               <fieldset class="UppyDashboardFileCard-fieldset">
                 <label class="UppyDashboardFileCard-label">Name</label>
                 <label class="UppyDashboardFileCard-label">Name</label>
-                <input class="UppyDashboardFileCard-input" data-name="name" type="text" value="${file.meta.name}"
-                       onkeyup=${tempStoreMetaOrSubmit} />
+                <input class="UppyDashboardFileCard-input" 
+                       type="text"
+                       data-name="name"
+                       value="${file.meta.name || ''}"
+                       placeholder="name"
+                       onkeyup=${tempStoreMetaOrSubmit}
+                       onkeydown=${tempStoreMetaOrSubmit}
+                       onkeypress=${tempStoreMetaOrSubmit} />
               </fieldset>
               </fieldset>
               ${renderMetaFields(file)}
               ${renderMetaFields(file)}
             </div>
             </div>

+ 6 - 3
src/plugins/Dashboard/FileItem.js

@@ -1,4 +1,3 @@
-const html = require('yo-yo')
 const { getETA,
 const { getETA,
          getSpeed,
          getSpeed,
          prettyETA,
          prettyETA,
@@ -10,6 +9,10 @@ const FileItemProgress = require('./FileItemProgress')
 const getFileTypeIcon = require('./getFileTypeIcon')
 const getFileTypeIcon = require('./getFileTypeIcon')
 const { iconEdit, iconCopy, iconRetry } = require('./icons')
 const { iconEdit, iconCopy, iconRetry } = require('./icons')
 
 
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
 module.exports = function fileItem (props) {
 module.exports = function fileItem (props) {
   const file = props.file
   const file = props.file
   const acquirers = props.acquirers
   const acquirers = props.acquirers
@@ -22,7 +25,7 @@ module.exports = function fileItem (props) {
   const error = file.error || false
   const error = file.error || false
 
 
   const fileName = getFileNameAndExtension(file.meta.name).name
   const fileName = getFileNameAndExtension(file.meta.name).name
-  const truncatedFileName = props.isWide ? truncateString(fileName, 16) : fileName
+  const truncatedFileName = props.isWide ? truncateString(fileName, 14) : fileName
 
 
   const onPauseResumeCancelRetry = (ev) => {
   const onPauseResumeCancelRetry = (ev) => {
     if (isUploaded) return
     if (isUploaded) return
@@ -148,7 +151,7 @@ module.exports = function fileItem (props) {
                        title="Remove file"
                        title="Remove file"
                        onclick=${() => props.removeFile(file.id)}>
                        onclick=${() => props.removeFile(file.id)}>
                  <svg aria-hidden="true" class="UppyIcon" width="60" height="60" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg">
                  <svg aria-hidden="true" class="UppyIcon" width="60" height="60" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg">
-                    <path stroke="#FFF" stroke-width="0.8px" fill-rule="nonzero" vector-effect="non-scaling-stroke" d="M30 1C14 1 1 14 1 30s13 29 29 29 29-13 29-29S46 1 30 1z" />
+                    <path stroke="#FFF" stroke-width="1" fill-rule="nonzero" vector-effect="non-scaling-stroke" d="M30 1C14 1 1 14 1 30s13 29 29 29 29-13 29-29S46 1 30 1z" />
                     <path fill="#FFF" vector-effect="non-scaling-stroke" d="M42 39.667L39.667 42 30 32.333 20.333 42 18 39.667 27.667 30 18 20.333 20.333 18 30 27.667 39.667 18 42 20.333 32.333 30z"/>
                     <path fill="#FFF" vector-effect="non-scaling-stroke" d="M42 39.667L39.667 42 30 32.333 20.333 42 18 39.667 27.667 30 18 20.333 20.333 18 30 27.667 39.667 18 42 20.333 32.333 30z"/>
                  </svg>
                  </svg>
                </button>`
                </button>`

+ 3 - 1
src/plugins/Dashboard/FileItemProgress.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 // http://codepen.io/Harkko/pen/rVxvNM
 // http://codepen.io/Harkko/pen/rVxvNM
 // https://css-tricks.com/svg-line-animation-works/
 // https://css-tricks.com/svg-line-animation-works/

+ 4 - 1
src/plugins/Dashboard/FileList.js

@@ -1,8 +1,11 @@
-const html = require('yo-yo')
 const FileItem = require('./FileItem')
 const FileItem = require('./FileItem')
 const ActionBrowseTagline = require('./ActionBrowseTagline')
 const ActionBrowseTagline = require('./ActionBrowseTagline')
 const { dashboardBgIcon } = require('./icons')
 const { dashboardBgIcon } = require('./icons')
 
 
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
 module.exports = (props) => {
 module.exports = (props) => {
   return html`<ul class="UppyDashboard-files
   return html`<ul class="UppyDashboard-files
                          ${props.totalFileCount === 0 ? 'UppyDashboard-files--noFiles' : ''}">
                          ${props.totalFileCount === 0 ? 'UppyDashboard-files--noFiles' : ''}">

+ 19 - 16
src/plugins/Dashboard/Tabs.js

@@ -1,6 +1,10 @@
-const html = require('yo-yo')
 const ActionBrowseTagline = require('./ActionBrowseTagline')
 const ActionBrowseTagline = require('./ActionBrowseTagline')
 const { localIcon } = require('./icons')
 const { localIcon } = require('./icons')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
+let inputEl
 
 
 module.exports = (props) => {
 module.exports = (props) => {
   const isHidden = Object.keys(props.files).length === 0
   const isHidden = Object.keys(props.files).length === 0
@@ -19,29 +23,28 @@ module.exports = (props) => {
     `
     `
   }
   }
 
 
-  const input = html`
-    <input class="UppyDashboard-input"
-          hidden="true"
-          aria-hidden="true" 
-          tabindex="-1" 
-          type="file" 
-          name="files[]" 
-          multiple="true"
-          onchange=${props.handleInputChange} />`
-
   return html`<div class="UppyDashboardTabs">
   return html`<div class="UppyDashboardTabs">
       <ul class="UppyDashboardTabs-list" role="tablist">
       <ul class="UppyDashboardTabs-list" role="tablist">
         <li class="UppyDashboardTab" role="presentation">
         <li class="UppyDashboardTab" role="presentation">
-          <button type="button" class="UppyDashboardTab-btn"
+          <button type="button" 
+                  class="UppyDashboardTab-btn"
                   role="tab"
                   role="tab"
                   tabindex="0"
                   tabindex="0"
-                  onclick=${(ev) => {
-                    input.click()
-                  }}>
+                  onclick=${ev => inputEl.click()}>
             ${localIcon()}
             ${localIcon()}
             <h5 class="UppyDashboardTab-name">${props.i18n('myDevice')}</h5>
             <h5 class="UppyDashboardTab-name">${props.i18n('myDevice')}</h5>
           </button>
           </button>
-          ${input}
+          <input class="UppyDashboard-input"
+                 hidden="true"
+                 aria-hidden="true" 
+                 tabindex="-1" 
+                 type="file" 
+                 name="files[]" 
+                 multiple="true"
+                 onchange=${props.handleInputChange} 
+                 ref=${(input) => {
+                   inputEl = input
+                 }} />
         </li>
         </li>
         ${props.acquirers.map((target) => {
         ${props.acquirers.map((target) => {
           return html`<li class="UppyDashboardTab" role="presentation">
           return html`<li class="UppyDashboardTab" role="presentation">

+ 0 - 21
src/plugins/Dashboard/UploadBtn.js

@@ -1,21 +0,0 @@
-const html = require('yo-yo')
-const { uploadIcon } = require('./icons')
-
-module.exports = (props) => {
-  props = props || {}
-
-  return html`<button class="UppyButton--circular
-                   UppyButton--blue
-                   UppyDashboard-upload"
-                 type="button"
-                 title="${props.i18n('uploadAllNewFiles')}"
-                 aria-label="${props.i18n('uploadAllNewFiles')}"
-                 onclick=${props.startUpload}>
-            ${uploadIcon()}
-            <sup class="UppyDashboard-uploadCount"
-                 title="${props.i18n('numberOfSelectedFiles')}"
-                 aria-label="${props.i18n('numberOfSelectedFiles')}">
-                  ${props.newFileCount}</sup>
-    </button>
-  `
-}

+ 3 - 1
src/plugins/Dashboard/icons.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 // https://css-tricks.com/creating-svg-icon-system-react/
 // https://css-tricks.com/creating-svg-icon-system-react/
 
 

+ 5 - 2
src/plugins/Dashboard/index.js

@@ -210,9 +210,12 @@ module.exports = class DashboardUI extends Plugin {
     document.body.classList.add('is-UppyDashboard-open')
     document.body.classList.add('is-UppyDashboard-open')
     document.body.style.top = `-${this.savedDocumentScrollPosition}px`
     document.body.style.top = `-${this.savedDocumentScrollPosition}px`
 
 
+    this.updateDashboardElWidth()
+    this.setFocusToFirstNode()
+
     // timeout is needed because yo-yo/morphdom/nanoraf; not needed without nanoraf
     // timeout is needed because yo-yo/morphdom/nanoraf; not needed without nanoraf
-    setTimeout(this.setFocusToFirstNode, 100)
-    setTimeout(this.updateDashboardElWidth, 100)
+    // setTimeout(this.setFocusToFirstNode, 100)
+    // setTimeout(this.updateDashboardElWidth, 100)
   }
   }
 
 
   closeModal () {
   closeModal () {

+ 3 - 1
src/plugins/Dropbox/icons.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 module.exports = {
 module.exports = {
   folder: () =>
   folder: () =>

+ 4 - 2
src/plugins/Dropbox/index.js

@@ -1,9 +1,12 @@
-const html = require('yo-yo')
 const Plugin = require('../../core/Plugin')
 const Plugin = require('../../core/Plugin')
 const Provider = require('../Provider')
 const Provider = require('../Provider')
 const View = require('../Provider/view')
 const View = require('../Provider/view')
 const icons = require('./icons')
 const icons = require('./icons')
 
 
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
 module.exports = class Dropbox extends Plugin {
 module.exports = class Dropbox extends Plugin {
   constructor (uppy, opts) {
   constructor (uppy, opts) {
     super(uppy, opts)
     super(uppy, opts)
@@ -28,7 +31,6 @@ module.exports = class Dropbox extends Plugin {
     this.files = []
     this.files = []
 
 
     this.onAuth = this.onAuth.bind(this)
     this.onAuth = this.onAuth.bind(this)
-
     this.render = this.render.bind(this)
     this.render = this.render.bind(this)
 
 
     // set default options
     // set default options

+ 3 - 2
src/plugins/Dummy.js

@@ -1,6 +1,7 @@
 const Plugin = require('../core/Plugin')
 const Plugin = require('../core/Plugin')
-const html = require('yo-yo')
-// const yo = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 /**
 /**
  * Dummy
  * Dummy

+ 3 - 1
src/plugins/FileInput.js

@@ -1,7 +1,9 @@
 const Plugin = require('../core/Plugin')
 const Plugin = require('../core/Plugin')
 const { toArray } = require('../core/Utils')
 const { toArray } = require('../core/Utils')
 const Translator = require('../core/Translator')
 const Translator = require('../core/Translator')
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 module.exports = class FileInput extends Plugin {
 module.exports = class FileInput extends Plugin {
   constructor (uppy, opts) {
   constructor (uppy, opts) {

+ 4 - 1
src/plugins/GoogleDrive/index.js

@@ -1,8 +1,11 @@
-const html = require('yo-yo')
 const Plugin = require('../../core/Plugin')
 const Plugin = require('../../core/Plugin')
 const Provider = require('../Provider')
 const Provider = require('../Provider')
 const View = require('../Provider/view')
 const View = require('../Provider/view')
 
 
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
 module.exports = class GoogleDrive extends Plugin {
 module.exports = class GoogleDrive extends Plugin {
   constructor (uppy, opts) {
   constructor (uppy, opts) {
     super(uppy, opts)
     super(uppy, opts)

+ 4 - 2
src/plugins/Informer.js

@@ -1,5 +1,8 @@
 const Plugin = require('../core/Plugin')
 const Plugin = require('../core/Plugin')
-const html = require('yo-yo')
+
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 /**
 /**
  * Informer
  * Informer
@@ -14,7 +17,6 @@ module.exports = class Informer extends Plugin {
     this.type = 'progressindicator'
     this.type = 'progressindicator'
     this.id = this.opts.id || 'Informer'
     this.id = this.opts.id || 'Informer'
     this.title = 'Informer'
     this.title = 'Informer'
-    // this.timeoutID = undefined
 
 
     // set default options
     // set default options
     const defaultOptions = {
     const defaultOptions = {

+ 6 - 3
src/plugins/Instagram/index.js

@@ -1,8 +1,11 @@
-const html = require('yo-yo')
 const Plugin = require('../../core/Plugin')
 const Plugin = require('../../core/Plugin')
 const Provider = require('../Provider')
 const Provider = require('../Provider')
 const View = require('../Provider/view')
 const View = require('../Provider/view')
 
 
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
 module.exports = class Instagram extends Plugin {
 module.exports = class Instagram extends Plugin {
   constructor (uppy, opts) {
   constructor (uppy, opts) {
     super(uppy, opts)
     super(uppy, opts)
@@ -80,7 +83,7 @@ module.exports = class Instagram extends Plugin {
   }
   }
 
 
   getItemIcon (item) {
   getItemIcon (item) {
-    return html`<img width="100px" src=${item.images.thumbnail.url}/>`
+    return html`<img width="100" src=${item.images.thumbnail.url}/>`
   }
   }
 
 
   getItemSubList (item) {
   getItemSubList (item) {
@@ -126,7 +129,7 @@ module.exports = class Instagram extends Plugin {
   }
   }
 
 
   getNextPagePath () {
   getNextPagePath () {
-    const { files } = this.uppy.getState()[this.stateId]
+    const { files } = this.getPluginState()
     return `recent?max_id=${this.getItemId(files[files.length - 1])}`
     return `recent?max_id=${this.getItemId(files[files.length - 1])}`
   }
   }
 
 

+ 3 - 1
src/plugins/ProgressBar.js

@@ -1,5 +1,7 @@
 const Plugin = require('../core/Plugin')
 const Plugin = require('../core/Plugin')
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 /**
 /**
  * Progress bar
  * Progress bar

+ 30 - 18
src/plugins/Provider/view/AuthView.js

@@ -1,21 +1,33 @@
-const html = require('yo-yo')
-const onload = require('on-load')
 const LoaderView = require('./Loader')
 const LoaderView = require('./Loader')
 
 
-module.exports = (props) => {
-  const demoLink = props.demo ? html`<button class="UppyProvider-authBtnDemo" onclick=${props.handleDemoAuth}>Proceed with Demo Account</button>` : null
-  const AuthBlock = () => html`
-    <div class="UppyProvider-auth">
-      <h1 class="UppyProvider-authTitle">Please connect your ${props.pluginName}<br> account to select files</h1>
-      <button type="button" class="UppyProvider-authBtn" onclick=${props.handleAuth}>Connect to ${props.pluginName}</button>
-      ${demoLink}
-    </div>
-  `
-  return onload(html`
-    <div style="height: 100%;">
-      ${props.checkAuthInProgress
-        ? LoaderView()
-        : AuthBlock()
-      }
-    </div>`, props.checkAuth, null, `auth${props.pluginName}`)
+const { h, Component } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
+class AuthView extends Component {
+  componentDidMount () {
+    this.props.checkAuth()
+  }
+
+  render () {
+    const demoLink = this.props.demo ? html`<button class="UppyProvider-authBtnDemo" onclick=${this.props.handleDemoAuth}>Proceed with Demo Account</button>` : null
+    const AuthBlock = () => html`
+      <div class="UppyProvider-auth">
+        <h1 class="UppyProvider-authTitle">Please authenticate with <span class="UppyProvider-authTitleName">${this.props.pluginName}</span><br> to select files</h1>
+        <button type="button" class="UppyProvider-authBtn" onclick=${this.props.handleAuth}>Connect to ${this.props.pluginName}</button>
+        ${demoLink}
+      </div>
+    `
+
+    return html`
+      <div style="height: 100%;">
+        ${this.props.checkAuthInProgress
+          ? LoaderView()
+          : AuthBlock()
+        }
+      </div>
+    `
+  }
 }
 }
+
+module.exports = AuthView

+ 3 - 1
src/plugins/Provider/view/Breadcrumb.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 module.exports = (props) => {
 module.exports = (props) => {
   return html`
   return html`

+ 3 - 1
src/plugins/Provider/view/Breadcrumbs.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 const Breadcrumb = require('./Breadcrumb')
 const Breadcrumb = require('./Breadcrumb')
 
 
 module.exports = (props) => {
 module.exports = (props) => {

+ 4 - 1
src/plugins/Provider/view/Browser.js

@@ -1,7 +1,10 @@
-const html = require('yo-yo')
 const Breadcrumbs = require('./Breadcrumbs')
 const Breadcrumbs = require('./Breadcrumbs')
 const Table = require('./Table')
 const Table = require('./Table')
 
 
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
 module.exports = (props) => {
 module.exports = (props) => {
   let filteredFolders = props.folders
   let filteredFolders = props.folders
   let filteredFiles = props.files
   let filteredFiles = props.files

+ 3 - 1
src/plugins/Provider/view/Loader.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 module.exports = (props) => {
 module.exports = (props) => {
   return html`
   return html`

+ 9 - 5
src/plugins/Provider/view/Table.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 const Row = require('./TableRow')
 const Row = require('./TableRow')
 
 
 module.exports = (props) => {
 module.exports = (props) => {
@@ -17,7 +19,7 @@ module.exports = (props) => {
   return html`
   return html`
     <table class="BrowserTable" onscroll=${props.handleScroll}>
     <table class="BrowserTable" onscroll=${props.handleScroll}>
       <tbody role="listbox" aria-label="List of files from ${props.title}">
       <tbody role="listbox" aria-label="List of files from ${props.title}">
-        ${props.folders.map((folder) => {
+        ${props.folders.map(folder => {
           let isDisabled = false
           let isDisabled = false
           let isChecked = props.isChecked(folder)
           let isChecked = props.isChecked(folder)
           if (isChecked) {
           if (isChecked) {
@@ -25,7 +27,8 @@ module.exports = (props) => {
           }
           }
           return Row({
           return Row({
             title: props.getItemName(folder),
             title: props.getItemName(folder),
-            active: props.activeRow(folder),
+            type: 'folder',
+            // active: props.activeRow(folder),
             getItemIcon: () => props.getItemIcon(folder),
             getItemIcon: () => props.getItemIcon(folder),
             handleClick: () => props.handleFolderClick(folder),
             handleClick: () => props.handleFolderClick(folder),
             isDisabled: isDisabled,
             isDisabled: isDisabled,
@@ -34,10 +37,11 @@ module.exports = (props) => {
             columns: props.columns
             columns: props.columns
           })
           })
         })}
         })}
-        ${props.files.map((file) => {
+        ${props.files.map(file => {
           return Row({
           return Row({
             title: props.getItemName(file),
             title: props.getItemName(file),
-            active: props.activeRow(file),
+            type: 'file',
+            // active: props.activeRow(file),
             getItemIcon: () => props.getItemIcon(file),
             getItemIcon: () => props.getItemIcon(file),
             handleClick: () => props.handleFileClick(file),
             handleClick: () => props.handleFileClick(file),
             isDisabled: false,
             isDisabled: false,

+ 31 - 8
src/plugins/Provider/view/TableRow.js

@@ -1,25 +1,48 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 const cuid = require('cuid')
 const cuid = require('cuid')
 
 
 module.exports = (props) => {
 module.exports = (props) => {
-  // const classes = props.active ? 'BrowserTable-row is-active' : 'BrowserTable-row'
   const uniqueId = cuid()
   const uniqueId = cuid()
 
 
+  const checkboxSelect = (ev) => {
+    if (ev.keyCode === 13) {
+      ev.stopPropagation()
+      ev.preventDefault()
+    }
+  }
+
+  const handleItemClick = (ev) => {
+    // when file is clicked, select it, but when folder is clicked, open it
+    if (props.type === 'folder') {
+      return props.handleClick()
+    }
+    props.handleCheckboxClick(ev)
+  }
+
   return html`
   return html`
-    <tr class="BrowserTable-row">
+    <tr class="BrowserTable-row" onclick=${handleItemClick}>
       <td class="BrowserTable-column">
       <td class="BrowserTable-column">
         <div class="BrowserTable-checkbox">
         <div class="BrowserTable-checkbox">
           <input type="checkbox"
           <input type="checkbox"
                  role="option" 
                  role="option" 
                  tabindex="0"
                  tabindex="0"
-                 aria-label="Select file: ${props.title}"
+                 aria-label="Select ${props.title}"
                  id=${uniqueId}
                  id=${uniqueId}
-                 checked=${props.isChecked}
-                 disabled=${props.isDisabled}
-                 onchange=${props.handleCheckboxClick} />
+                 ${props.isChecked
+                  ? { 'checked': true }
+                 : {}}
+                 ${props.isDisabled
+                  ? { 'disabled': true }
+                 : {}}
+                 onchange=${props.handleCheckboxClick}
+                 onkeyup=${checkboxSelect}
+                 onkeydown=${checkboxSelect}
+                 onkeypress=${checkboxSelect} />
           <label for=${uniqueId}></label>
           <label for=${uniqueId}></label>
         </div>
         </div>
-        <button type="button" class="BrowserTable-item" aria-label="Select file: ${props.title}" tabindex="0" onclick=${props.handleClick}>
+        <button type="button" class="BrowserTable-item" aria-label="Select ${props.title}" tabindex="0" onclick=${handleItemClick}>
           ${props.getItemIcon()} ${props.title}
           ${props.getItemIcon()} ${props.title}
         </button>
         </button>
       </td>
       </td>

+ 2 - 1
src/plugins/Provider/view/index.js

@@ -2,6 +2,7 @@ const AuthView = require('./AuthView')
 const Browser = require('./Browser')
 const Browser = require('./Browser')
 const LoaderView = require('./Loader')
 const LoaderView = require('./Loader')
 const Utils = require('../../../core/Utils')
 const Utils = require('../../../core/Utils')
+const { h } = require('preact')
 
 
 /**
 /**
  * Class to easily generate generic views for plugins
  * Class to easily generate generic views for plugins
@@ -555,7 +556,7 @@ module.exports = class View {
     }
     }
 
 
     if (!authenticated) {
     if (!authenticated) {
-      return AuthView({
+      return h(AuthView, {
         pluginName: this.plugin.title,
         pluginName: this.plugin.title,
         demo: this.plugin.opts.demo,
         demo: this.plugin.opts.demo,
         checkAuth: this.checkAuth,
         checkAuth: this.checkAuth,

+ 4 - 5
src/plugins/StatusBar/StatusBar.js

@@ -1,6 +1,9 @@
-const html = require('yo-yo')
 const throttle = require('lodash.throttle')
 const throttle = require('lodash.throttle')
 
 
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
+
 function progressDetails (props) {
 function progressDetails (props) {
   return html`<span>${props.totalProgress || 0}%・${props.complete} / ${props.inProgress}・${props.totalUploadedSize} / ${props.totalSize}・↑ ${props.totalSpeed}/s・${props.totalETA}</span>`
   return html`<span>${props.totalProgress || 0}%・${props.complete} / ${props.inProgress}・${props.totalUploadedSize} / ${props.totalSize}・↑ ${props.totalSpeed}/s・${props.totalETA}</span>`
 }
 }
@@ -15,10 +18,6 @@ const STATE_POSTPROCESSING = 'postprocessing'
 const STATE_COMPLETE = 'complete'
 const STATE_COMPLETE = 'complete'
 
 
 function getUploadingState (props, files) {
 function getUploadingState (props, files) {
-  // if (props.error) {
-  //   return STATE_ERROR
-  // }
-
   if (props.isAllErrored) {
   if (props.isAllErrored) {
     return STATE_ERROR
     return STATE_ERROR
   }
   }

+ 3 - 1
src/plugins/Webcam/CameraIcon.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 module.exports = (props) => {
 module.exports = (props) => {
   return html`<svg aria-hidden="true" class="UppyIcon" width="100" height="77" viewBox="0 0 100 77">
   return html`<svg aria-hidden="true" class="UppyIcon" width="100" height="77" viewBox="0 0 100 77">

+ 36 - 32
src/plugins/Webcam/CameraScreen.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h, Component } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 const SnapshotButton = require('./SnapshotButton')
 const SnapshotButton = require('./SnapshotButton')
 const RecordButton = require('./RecordButton')
 const RecordButton = require('./RecordButton')
 
 
@@ -6,40 +8,42 @@ function isModeAvailable (modes, mode) {
   return modes.indexOf(mode) !== -1
   return modes.indexOf(mode) !== -1
 }
 }
 
 
-module.exports = (props) => {
-  const src = props.src || ''
-  let video
-
-  if (props.useTheFlash) {
-    video = props.getSWFHTML()
-  } else {
-    video = html`<video class="UppyWebcam-video" autoplay muted src="${src}"></video>`
+class CameraScreen extends Component {
+  constructor (props) {
+    super(props)
+    this.src = this.props.src || ''
+    this.shouldShowRecordButton = this.props.supportsRecording && (
+      isModeAvailable(this.props.modes, 'video-only') ||
+      isModeAvailable(this.props.modes, 'audio-only') ||
+      isModeAvailable(this.props.modes, 'video-audio')
+    )
+    this.shouldShowSnapshotButton = isModeAvailable(this.props.modes, 'picture')
   }
   }
 
 
-  const shouldShowRecordButton = props.supportsRecording && (
-    isModeAvailable(props.modes, 'video-only') ||
-    isModeAvailable(props.modes, 'audio-only') ||
-    isModeAvailable(props.modes, 'video-audio')
-  )
+  componentDidMount () {
+    this.props.onFocus()
+    // const recordButton = el.querySelector('.UppyWebcam-recordButton')
+    // if (recordButton) recordButton.focus()
+  }
 
 
-  const shouldShowSnapshotButton = isModeAvailable(props.modes, 'picture')
+  componentWillUnmount () {
+    this.props.onStop()
+  }
 
 
-  return html`
-    <div class="UppyWebcam-container" onload=${(el) => {
-      props.onFocus()
-      const recordButton = el.querySelector('.UppyWebcam-recordButton')
-      if (recordButton) recordButton.focus()
-    }} onunload=${(el) => {
-      props.onStop()
-    }}>
-      <div class='UppyWebcam-videoContainer'>
-        ${video}
+  render () {
+    return html`
+      <div class="UppyWebcam-container">
+        <div class="UppyWebcam-videoContainer">
+          <video class="UppyWebcam-video" autoplay muted src="${this.src}"></video>
+        </div>
+        <div class="UppyWebcam-buttonContainer">
+          ${this.shouldShowSnapshotButton ? SnapshotButton(this.props) : null}
+          ${this.shouldShowRecordButton ? RecordButton(this.props) : null}
+        </div>
+        <canvas class="UppyWebcam-canvas" style="display: none;"></canvas>
       </div>
       </div>
-      <div class='UppyWebcam-buttonContainer'>
-        ${shouldShowRecordButton ? RecordButton(props) : null}
-        ${shouldShowSnapshotButton ? SnapshotButton(props) : null}
-      </div>
-      <canvas class="UppyWebcam-canvas" style="display: none;"></canvas>
-    </div>
-  `
+    `
+  }
 }
 }
+
+module.exports = CameraScreen

+ 3 - 1
src/plugins/Webcam/PermissionsScreen.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 module.exports = (props) => {
 module.exports = (props) => {
   return html`
   return html`

+ 3 - 1
src/plugins/Webcam/RecordButton.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 const RecordStartIcon = require('./RecordStartIcon')
 const RecordStartIcon = require('./RecordStartIcon')
 const RecordStopIcon = require('./RecordStopIcon')
 const RecordStopIcon = require('./RecordStopIcon')
 
 

+ 3 - 1
src/plugins/Webcam/RecordStartIcon.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 module.exports = (props) => {
 module.exports = (props) => {
   return html`<svg aria-hidden="true" class="UppyIcon" width="100" height="100" viewBox="0 0 100 100">
   return html`<svg aria-hidden="true" class="UppyIcon" width="100" height="100" viewBox="0 0 100 100">

+ 3 - 1
src/plugins/Webcam/RecordStopIcon.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 module.exports = (props) => {
 module.exports = (props) => {
   return html`<svg aria-hidden="true" class="UppyIcon" width="100" height="100" viewBox="0 0 100 100">
   return html`<svg aria-hidden="true" class="UppyIcon" width="100" height="100" viewBox="0 0 100 100">

+ 3 - 1
src/plugins/Webcam/SnapshotButton.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 const CameraIcon = require('./CameraIcon')
 const CameraIcon = require('./CameraIcon')
 
 
 module.exports = function SnapshotButton ({ onSnapshot }) {
 module.exports = function SnapshotButton ({ onSnapshot }) {

+ 3 - 1
src/plugins/Webcam/WebcamIcon.js

@@ -1,4 +1,6 @@
-const html = require('yo-yo')
+const { h } = require('preact')
+const hyperx = require('hyperx')
+const html = hyperx(h)
 
 
 module.exports = (props) => {
 module.exports = (props) => {
   return html`
   return html`

+ 5 - 2
src/plugins/Webcam/index.js

@@ -1,3 +1,4 @@
+const { h } = require('preact')
 const Plugin = require('../../core/Plugin')
 const Plugin = require('../../core/Plugin')
 const Translator = require('../../core/Translator')
 const Translator = require('../../core/Translator')
 const {
 const {
@@ -168,7 +169,9 @@ module.exports = class Webcam extends Plugin {
       })
       })
       return this.getVideo()
       return this.getVideo()
     }).then((file) => {
     }).then((file) => {
-      return this.uppy.addFile(file)
+      this.uppy.addFile(file)
+      const dashboard = this.uppy.getPlugin('Dashboard')
+      if (dashboard) dashboard.hideAllPanels()
     }).then(() => {
     }).then(() => {
       this.recordingChunks = null
       this.recordingChunks = null
       this.recorder = null
       this.recorder = null
@@ -301,7 +304,7 @@ module.exports = class Webcam extends Plugin {
       return PermissionsScreen(webcamState)
       return PermissionsScreen(webcamState)
     }
     }
 
 
-    return CameraScreen(Object.assign({}, webcamState, {
+    return h(CameraScreen, Object.assign({}, webcamState, {
       onSnapshot: this.takeSnapshot,
       onSnapshot: this.takeSnapshot,
       onStartRecording: this.startRecording,
       onStartRecording: this.startRecording,
       onStopRecording: this.stopRecording,
       onStopRecording: this.stopRecording,