Explorar el Código

Experimental refactor of Dashboard. Added classnames package for dynamic class string building.

Harry Hedger hace 8 años
padre
commit
d8211ae111

+ 1 - 0
package.json

@@ -70,6 +70,7 @@
     "watchify": "3.7.0"
   },
   "dependencies": {
+    "classnames": "^2.2.5",
     "deep-freeze-strict": "1.1.1",
     "drag-drop": "2.11.0",
     "es6-promise": "3.2.1",

+ 0 - 69
src/experimental/ui/Dashboard/FileCard.js

@@ -1,69 +0,0 @@
-import html from '../../core/html'
-import { iconText, iconFile, iconAudio, checkIcon } from './icons'
-
-function getIconByMime (fileTypeGeneral) {
-  switch (fileTypeGeneral) {
-    case 'text':
-      return iconText()
-    case 'audio':
-      return iconAudio()
-    default:
-      return iconFile()
-  }
-}
-
-export default function fileCard (props) {
-  // const { bus } = props
-
-  const file = props.fileCardFor ? props.files[props.fileCardFor] : false
-  const meta = {}
-
-  function tempStoreMeta (ev) {
-    const value = ev.target.value
-    const name = ev.target.attributes.name.value
-    meta[name] = value
-  }
-
-  function renderMetaFields (file) {
-    const metaFields = props.metaFields || []
-    return metaFields.map((field) => {
-      return html`<fieldset class="UppyDashboardFileCard-fieldset">
-        <label class="UppyDashboardFileCard-label">${field.name}</label>
-        <input class="UppyDashboardFileCard-input"
-                         name="${field.id}"
-                         type="text"
-                         value="${file.meta[field.id]}"
-                         placeholder="${field.placeholder || ''}"
-                         onkeyup=${tempStoreMeta} /></fieldset>`
-    })
-  }
-
-  return html`<div class="UppyDashboardFileCard" aria-hidden="${props.fileCardFor ? 'false' : 'true'}">
-    <div class="UppyDashboardContent-bar">
-      <h2 class="UppyDashboardContent-title">Editing <span class="UppyDashboardContent-titleFile">${file.meta ? file.meta.name : file.name}</span></h2>
-      <button class="UppyDashboardContent-back" title="Finish editing file"
-              onclick=${() => props.done(meta, file.id)}>Done</button>
-    </div>
-    ${props.fileCardFor
-      ? html`<div class="UppyDashboardFileCard-inner">
-          <div class="UppyDashboardFileCard-preview">
-            ${file.preview
-              ? html`<img alt="${file.name}" src="${file.preview}">`
-              : html`<div class="UppyDashboardItem-previewIcon">${getIconByMime(file.type.general)}</div>`
-            }
-          </div>
-          <div class="UppyDashboardFileCard-info">
-            <fieldset class="UppyDashboardFileCard-fieldset">
-              <label class="UppyDashboardFileCard-label">Name</label>
-              <input class="UppyDashboardFileCard-input" name="name" type="text" value="${file.meta.name}"
-                     onkeyup=${tempStoreMeta} />
-            </fieldset>
-            ${renderMetaFields(file)}
-          </div>
-        </div>`
-      : null
-    }
-    <button class="UppyButton--circular UppyButton--blue UppyButton--sizeM UppyDashboardFileCard-done" type="button"
-            title="Finish editing file" onclick=${() => props.done(meta, file.id)}>${checkIcon()}</button>
-    </div>`
-}

+ 79 - 62
src/experimental/ui/Dashboard/FileItem.js

@@ -1,4 +1,5 @@
 import html from '../../core/html'
+import cx from 'classnames'
 import { getETA,
          getSpeed,
          prettyETA,
@@ -31,89 +32,105 @@ export default function fileItem (props) {
   const fileName = getFileNameAndExtension(file.meta.name)[0]
   const truncatedFileName = truncateString(fileName, 15)
 
-  return html`<li class="UppyDashboardItem
-                        ${uploadInProgress ? 'is-inprogress' : ''}
-                        ${isUploaded ? 'is-complete' : ''}
-                        ${isPaused ? 'is-paused' : ''}"
-                  id="uppy_${file.id}"
-                  title="${file.meta.name}">
+  const itemClasses = cx({
+    'UppyDashboardItem': true,
+    'is-inprogress': uploadInProgress,
+    'is-complete': isUploaded,
+    'is-paused': isPaused
+  })
+
+  // TODO:
+  // maybe pull button onclick to own function
+  // declutter showProgressDetails ternary
+
+  return html`
+    <li
+      class=${itemClasses}
+      id="uppy_${file.id}"
+      title="${file.meta.name}">
       <div class="UppyDashboardItem-preview">
         ${file.preview
           ? html`<img alt="${file.name}" src="${file.preview}">`
           : getIconByMime(file.type.general)
         }
         <div class="UppyDashboardItem-progress">
-          <button class="UppyDashboardItem-progressBtn"
-                  title="${isUploaded
-                          ? 'upload complete'
-                          : file.isPaused ? 'resume upload' : 'pause upload'}"
-                  onclick=${(ev) => {
-                    if (isUploaded) return
-                    props.pauseUpload(file.id)
-                  }}>
+          <button
+            class="UppyDashboardItem-progressBtn"
+            title="${isUploaded ? 'upload complete' : file.isPaused ? 'resume upload' : 'pause upload'}"
+            onclick=${() => {
+              if (isUploaded) return
+              props.pauseUpload(file.id)
+            }}>
             ${FileItemProgress({
               progress: file.progress.percentage,
               fileID: file.id
             })}
           </button>
           ${props.showProgressDetails
-            ? html`<div class="UppyDashboardItem-progressInfo"
-                   title="${props.i18n('localDisk')}"
-                   aria-label="${props.i18n('localDisk')}">
+            ? html`
+              <div class="UppyDashboardItem-progressInfo"
+                title="${props.i18n('localDisk')}"
+                aria-label="${props.i18n('localDisk')}">
                 ${!file.isPaused && !isUploaded
                   ? html`<span>${prettyETA(getETA(file.progress))} ・ ↑ ${prettyBytes(getSpeed(file.progress))}/s</span>`
                   : null
                 }
-              </div>`
+              </div>
+            `
             : null
           }
         </div>
       </div>
-    <div class="UppyDashboardItem-info">
-      <h4 class="UppyDashboardItem-name" title="${fileName}">
-        ${file.uploadURL
-          ? html`<a href="${file.uploadURL}" target="_blank">
-              ${file.extension ? truncatedFileName + '.' + file.extension : truncatedFileName}
-            </a>`
-          : file.extension ? truncatedFileName + '.' + file.extension : truncatedFileName
+      <div class="UppyDashboardItem-info">
+        <h4 class="UppyDashboardItem-name" title="${fileName}">
+          ${file.uploadURL
+            ? html`<a href="${file.uploadURL}" target="_blank">
+                ${file.extension ? truncatedFileName + '.' + file.extension : truncatedFileName}
+              </a>`
+            : file.extension ? truncatedFileName + '.' + file.extension : truncatedFileName
+          }
+        </h4>
+        <div class="UppyDashboardItem-status">
+          <span class="UppyDashboardItem-statusSize">${file.data.size ? prettyBytes(file.data.size) : '?'}</span>
+        </div>
+        ${!uploadInProgressOrComplete
+          ? html`
+            <button class="UppyDashboardItem-edit"
+              aria-label="Edit file"
+              title="Edit file"
+              onclick=${(e) => props.showFileCard(file.id)}>
+              ${iconEdit()}
+            </button>
+          `
+          : null
         }
-      </h4>
-      <div class="UppyDashboardItem-status">
-        <span class="UppyDashboardItem-statusSize">${file.data.size ? prettyBytes(file.data.size) : '?'}</span>
-      </div>
-      ${!uploadInProgressOrComplete
-        ? html`<button class="UppyDashboardItem-edit"
-                       aria-label="Edit file"
-                       title="Edit file"
-                       onclick=${(e) => props.showFileCard(file.id)}>
-                        ${iconEdit()}</button>`
-        : null
-      }
-      ${file.uploadURL
-        ? html`<button class="UppyDashboardItem-copyLink"
-                       aria-label="Copy link"
-                       title="Copy link"
-                       onclick=${() => {
-                         copyToClipboard(file.uploadURL, props.i18n('copyLinkToClipboardFallback'))
-                          .then(() => {
-                            props.log('Link copied to clipboard.')
-                            props.info(props.i18n('copyLinkToClipboardSuccess'), 'info', 3000)
-                          })
-                          .catch(props.log)
-                       }}>${iconCopy()}</button>`
+        ${file.uploadURL ? html`
+          <button class="UppyDashboardItem-copyLink"
+            aria-label="Copy link"
+            title="Copy link"
+            onclick=${() => {
+              copyToClipboard(file.uploadURL, props.i18n('copyLinkToClipboardFallback'))
+              .then(() => {
+                props.log('Link copied to clipboard.')
+                props.info(props.i18n('copyLinkToClipboardSuccess'), 'info', 3000)
+              })
+              .catch(props.log)
+            }}>${iconCopy()}</button>`
         : null
-      }
-    </div>
-    <div class="UppyDashboardItem-action">
-      ${!isUploaded
-        ? html`<button class="UppyDashboardItem-remove"
-                       aria-label="Remove file"
-                       title="Remove file"
-                       onclick=${() => props.removeFile(file.id)}>
-                  ${removeIcon()}
-               </button>`
+        }
+      </div>
+      <div class="UppyDashboardItem-action">
+        ${!isUploaded ? html`
+          <button class="UppyDashboardItem-remove"
+            aria-label="Remove file"
+            title="Remove file"
+            onclick=${() => props.removeFile(file.id)}>
+            ${removeIcon()}
+          </button>
+        `
         : null
-      }
-    </div>
-  </li>`
+        }
+      </div>
+    </li>
+  `
 }

+ 2 - 1
src/experimental/ui/Dashboard/FileItemProgress.js

@@ -16,5 +16,6 @@ export default function (props) {
         <rect x="5" y="0" width="2" height="10" rx="0" />
       </g>
       <polygon transform="translate(2, 3)" points="14 22.5 7 15.2457065 8.99985857 13.1732815 14 18.3547104 22.9729883 9 25 11.1005634" class="check"/>
-  </svg>`
+    </svg>
+  `
 }

+ 0 - 39
src/experimental/ui/Dashboard/Tabs.js

@@ -1,39 +0,0 @@
-import html from '../../core/html'
-import { localIcon } from './icons'
-
-export default (props) => {
-  return html`<div class="UppyDashboardTabs">
-    <h3 class="UppyDashboardTabs-title">${props.i18n('dropPasteImport')}</h3>
-    <nav>
-      <ul class="UppyDashboardTabs-list" role="tablist">
-        <li class="UppyDashboardTab">
-          <button class="UppyDashboardTab-btn UppyDashboard-focus"
-                  role="tab"
-                  tabindex="0"
-                  onclick=${(ev) => {
-                    const input = document.querySelector(`${props.container} .UppyDashboard-input`)
-                    input.click()
-                  }}>
-            ${localIcon()}
-            <h5 class="UppyDashboardTab-name">${props.i18n('localDisk')}</h5>
-          </button>
-          <input class="UppyDashboard-input" type="file" name="files[]" multiple="true"
-                 onchange=${props.localInputChange} />
-        </li>
-        ${props.acquirers.map((target) => {
-          return html`<li class="UppyDashboardTab">
-            <button class="UppyDashboardTab-btn"
-                    role="tab"
-                    tabindex="0"
-                    aria-controls="${props.panelSelectorPrefix}--${target.id}"
-                    aria-selected="${target.isHidden ? 'false' : 'true'}"
-                    onclick=${() => props.showPanel(target.id)}>
-              ${target.icon}
-              <h5 class="UppyDashboardTab-name">${target.name}</h5>
-            </button>
-          </li>`
-        })}
-      </ul>
-    </nav>
-  </div>`
-}

+ 0 - 0
src/experimental/ui/Dashboard/StatusBar.js → src/experimental/ui/Dashboard/doneui/StatusBar.js


+ 126 - 0
src/experimental/ui/Dashboard/newu/Dashboard.js

@@ -0,0 +1,126 @@
+import html from '../../../../core/html'
+import cx from 'classnames'
+import Tabs from './Tabs'
+import FileCard from './FileCard'
+
+export default (props) => {
+  const {
+    container,
+    hideAllPanels,
+    hideModal,
+    i18n,
+    inline,
+    log,
+    onPaste,
+    panelSelectorPrefix,
+    pauseAll,
+    resumeAll,
+    showPanel,
+    showProgressDetails,
+    removeFile,
+    pauseUpload,
+    startUpload
+  } = props
+
+  // temporary to pass linting
+  const state = {}
+  const modal = false
+  const closeIcon = false
+  const localInputChange = false
+  const acquirers = []
+  const files = []
+  const fileCardDone = false
+  const showFileCard = false
+  const totalProgress = 0
+  const info = ''
+  const progressindicators = []
+
+  const dashboardClasses = cx({
+    'Uppy': true,
+    'UppyDashboard': true,
+    'UppyTheme--default': true,
+    // 'Uppy--isTouchDevice': isTouchDevice(),
+    'UppyDashboard--modal': !inline
+  })
+
+  return html`
+    <div class=${dashboardClasses}
+      aria-hidden="${inline ? 'false' : modal.isHidden}"
+      aria-label="${!inline ? i18n('dashboardWindowTitle') : i18n('dashboardTitle')}"
+      role="dialog"
+      onpaste=${onPaste}>
+
+      <div class="UppyDashboard-overlay"
+           onclick=${hideModal}>
+      </div>
+
+      <button class="UppyDashboard-close"
+              aria-label="${i18n('closeModal')}"
+              title="${i18n('closeModal')}"
+              onclick=${hideModal}>
+        ${closeIcon()}
+      </button>
+
+      <div class="UppyDashboard-inner" tabindex="0">
+        <div class="UppyDashboard-innerWrap">
+
+          ${Tabs({
+            localInputChange: localInputChange,
+            acquirers: acquirers,
+            container: container,
+            panelSelectorPrefix: panelSelectorPrefix,
+            showPanel: showPanel,
+            i18n: i18n
+          })}
+
+          ${FileCard({
+            files: files,
+            fileCardFor: modal.fileCardFor,
+            done: fileCardDone,
+            metaFields: state.metaFields,
+            log: log,
+            i18n: i18n
+          })}
+
+          ${FileList({
+            files: files,
+            showFileCard: showFileCard,
+            showProgressDetails: showProgressDetails,
+            totalProgress: totalProgress,
+            info: info,
+            i18n: i18n,
+            log: log,
+            removeFile: removeFile,
+            pauseAll: pauseAll,
+            resumeAll: resumeAll,
+            pauseUpload: pauseUpload,
+            startUpload: startUpload
+          })}
+
+          ${acquirers.map((target) => {
+            return html`
+              <div class="UppyDashboardContent-panel"
+                   id="${panelSelectorPrefix}--${target.id}"
+                   role="tabpanel"
+                   aria-hidden="${target.isHidden}">
+                <div class="UppyDashboardContent-bar">
+                  <h2 class="UppyDashboardContent-title">${i18n('importFrom')} ${target.name}</h2>
+                  <button
+                    class="UppyDashboardContent-back"
+                    onclick=${hideAllPanels}>${i18n('done')}</button>
+                </div>
+                ${target.render(state)}
+              </div>
+            `
+          })}
+
+          <div class="UppyDashboard-progressindicators">
+            ${progressindicators.map((target) => {
+              return target.render(state)
+            })}
+          </div>
+        </div>
+      </div>
+    </div>
+  `
+}

+ 112 - 0
src/experimental/ui/Dashboard/newu/FileCard.js

@@ -0,0 +1,112 @@
+import html from '../../../../core/html'
+import { iconText, iconFile, iconAudio, checkIcon } from './icons'
+
+function getIconByMime (fileTypeGeneral) {
+  switch (fileTypeGeneral) {
+    case 'text':
+      return iconText()
+    case 'audio':
+      return iconAudio()
+    default:
+      return iconFile()
+  }
+}
+
+export default function fileCard (props) {
+  const {
+    done,
+    fileCardFor,
+    files,
+    metaFields
+  } = props
+
+  // const { bus } = props
+
+  // Notes:
+  // what is this? can a filecard be generated with no file in files?
+  // why not just pass down the individual file?
+  const file = fileCardFor ? files[fileCardFor] : false
+  const meta = {}
+
+  function tempStoreMeta (ev) {
+    const value = ev.target.value
+    const name = ev.target.attributes.name.value
+    meta[name] = value
+  }
+
+  function renderMetaFields (file) {
+    // not sure if this is going to break shit
+    if (!metaFields || !metaFields.map) {
+      return []
+    }
+
+    return metaFields.map((field) => {
+      return html`
+        <fieldset class="UppyDashboardFileCard-fieldset">
+          <label class="UppyDashboardFileCard-label">
+            ${field.name}
+          </label>
+          <input
+            class="UppyDashboardFileCard-input"
+            name="${field.id}"
+            type="text"
+            value="${file.meta[field.id]}"
+            placeholder="${field.placeholder || ''}"
+            onkeyup=${tempStoreMeta}/>
+        </fieldset>
+      `
+    })
+  }
+
+  return html`
+    <div class="UppyDashboardFileCard" aria-hidden="${fileCardFor ? 'false' : 'true'}">
+      <div class="UppyDashboardContent-bar">
+        <h2 class="UppyDashboardContent-title">
+          Editing
+          <span class="UppyDashboardContent-titleFile">
+            ${file.meta ? file.meta.name : file.name}
+          </span>
+        </h2>
+        <button
+          class="UppyDashboardContent-back"
+          title="Finish editing file"
+          onclick=${() => done(meta, file.id)}>
+          Done
+        </button>
+      </div>
+
+      ${fileCardFor
+        ? html`
+          <div class="UppyDashboardFileCard-inner">
+            <div class="UppyDashboardFileCard-preview">
+              ${file.preview
+                ? html`<img alt="${file.name}" src="${file.preview}">`
+                : html`<div class="UppyDashboardItem-previewIcon">${getIconByMime(file.type.general)}</div>`
+              }
+            </div>
+            <div class="UppyDashboardFileCard-info">
+              <fieldset class="UppyDashboardFileCard-fieldset">
+                <label class="UppyDashboardFileCard-label">Name</label>
+                <input
+                  class="UppyDashboardFileCard-input"
+                  name="name"
+                  type="text"
+                  value="${file.meta.name}"
+                  onkeyup=${tempStoreMeta}/>
+              </fieldset>
+              ${renderMetaFields(file)}
+            </div>
+          </div>
+        `
+        : null
+      }
+      <button
+        class="UppyButton--circular UppyButton--blue UppyButton--sizeM UppyDashboardFileCard-done"
+        type="button"
+        title="Finish editing file"
+        onclick=${() => done(meta, file.id)}>
+        ${checkIcon()}
+      </button>
+    </div>
+  `
+}

+ 66 - 0
src/experimental/ui/Dashboard/newu/Tabs.js

@@ -0,0 +1,66 @@
+import html from '../../core/html'
+import { localIcon } from './icons'
+
+export default (props) => {
+  const {
+    acquirers,
+    container,
+    i18n,
+    localInputChange,
+    panelSelectorPrefix,
+    showPanel
+  } = props
+
+  return html`
+    <div class="UppyDashboardTabs">
+      <h3 class="UppyDashboardTabs-title">
+        ${i18n('dropPasteImport')}
+      </h3>
+      <nav>
+        <ul class="UppyDashboardTabs-list" role="tablist">
+          <li class="UppyDashboardTab">
+            <button
+              class="UppyDashboardTab-btn UppyDashboard-focus"
+              role="tab"
+              tabindex="0"
+              onclick=${(ev) => {
+                const input = document.querySelector(`${container} .UppyDashboard-input`)
+                input.click()
+              }}>
+              ${localIcon()}
+              <h5 class="UppyDashboardTab-name">
+                ${i18n('localDisk')}
+              </h5>
+            </button>
+            <input
+              class="UppyDashboard-input"
+              type="file"
+              name="files[]"
+              multiple="true"
+              onchange=${localInputChange}/>
+          </li>
+
+          ${acquirers.map((target) => {
+            return html`
+              <li class="UppyDashboardTab">
+                <button
+                  class="UppyDashboardTab-btn"
+                  role="tab"
+                  tabindex="0"
+                  aria-controls="${panelSelectorPrefix}--${target.id}"
+                  aria-selected="${target.isHidden ? 'false' : 'true'}"
+                  onclick=${() => showPanel(target.id)}>
+                  ${target.icon}
+                  <h5 class="UppyDashboardTab-name">
+                    ${target.name}
+                  </h5>
+                </button>
+              </li>
+            `
+          })}
+
+        </ul>
+      </nav>
+    </div>
+  `
+}

+ 0 - 0
src/experimental/ui/Dashboard/ui/Dashboard.js