Fix yo-yo + Uppy rendering issues, add focus on the first element in Modal tab, refactor getTarget — now called mount

This commit is contained in:
Artur Paikin 2016-06-02 01:21:56 -04:00
parent 1e9d590fde
commit 5eadd138c0
9 changed files with 112 additions and 65 deletions

View file

@ -1,5 +1,6 @@
import Utils from '../core/Utils'
import Translator from '../core/Translator'
import yo from 'yo-yo'
import ee from 'events'
/**
@ -40,6 +41,14 @@ export default class Core {
// for debugging and testing
global.UppyState = this.state
global.UppyAddFile = this.addFile.bind(this)
this.updateAll = this.updateAll.bind(this)
this.setState = this.setState.bind(this)
this.getState = this.getState.bind(this)
this.use = this.use.bind(this)
this.actions = this.actions.bind(this)
this.run = this.run.bind(this)
this.getPlugin = this.getPlugin.bind(this)
}
/**
@ -60,7 +69,8 @@ export default class Core {
* @param {newState} object
*/
setState (newState) {
this.log(`Setting state to: ${newState}`)
this.log('Setting state to: ')
this.log(newState)
this.state = Object.assign({}, this.state, newState)
this.updateAll()
}
@ -80,6 +90,7 @@ export default class Core {
const imgSrc = ev.target.result
const updatedFiles = Object.assign({}, this.state.files)
updatedFiles[file.id].preview = imgSrc
updatedFiles[file.id].previewEl = yo`<img alt="${file.name}" src="${imgSrc}">`
this.setState({files: updatedFiles})
})
reader.addEventListener('error', (err) => {
@ -121,9 +132,9 @@ export default class Core {
this.setState({files: updatedFiles})
// if (fileTypeGeneral === 'image') {
// this.addImgPreviewToFile(updatedFiles[fileID])
// }
if (fileTypeGeneral === 'image') {
this.addImgPreviewToFile(updatedFiles[fileID])
}
if (this.opts.autoProceed) {
this.emitter.emit('next')
@ -260,7 +271,7 @@ export default class Core {
if (msg === `${msg}`) {
console.log(`LOG: ${msg}`)
} else {
console.log('LOG')
console.log('LOG')
console.dir(msg)
}
global.uppyLog = global.uppyLog || ''
@ -288,10 +299,7 @@ export default class Core {
* All preseters(data) --> All acquirers(data) --> All uploaders(data) --> done
*/
run () {
this.log({
class: this.constructor.name,
method: 'run'
})
this.log('Core is run, initializing actions, installing plugins...')
this.actions()

View file

@ -36,6 +36,7 @@ export default class DragDrop extends Plugin {
this.handleDrop = this.handleDrop.bind(this)
this.checkDragDropSupport = this.checkDragDropSupport.bind(this)
this.handleInputChange = this.handleInputChange.bind(this)
this.render = this.render.bind(this)
}
/**
@ -97,7 +98,13 @@ export default class DragDrop extends Plugin {
}
focus () {
this.input.focus()
const firstInput = document.querySelector(`${this.target} .UppyDragDrop-focus`)
// only works for the first time if wrapped in setTimeout for some reason
// firstInput.focus()
setTimeout(function () {
firstInput.focus()
}, 10)
}
render (state) {
@ -122,7 +129,7 @@ export default class DragDrop extends Plugin {
<div class="UppyDragDrop-container ${this.isDragDropSupported ? 'is-dragdrop-supported' : ''}">
<form class="UppyDragDrop-inner"
onsubmit=${onSubmit}>
<input class="UppyDragDrop-input"
<input class="UppyDragDrop-input UppyDragDrop-focus"
type="file"
name="files[]"
multiple="true"
@ -144,9 +151,9 @@ export default class DragDrop extends Plugin {
}
install () {
this.el = this.render(this.core.state)
this.target = this.getTarget(this.opts.target, this, this.el, this.render.bind(this))
this.input = document.querySelector(`${this.target} .UppyDragDrop-input`)
const target = this.opts.target
const plugin = this
this.target = this.mount(target, plugin)
dragDrop(`${this.target} .UppyDragDrop-container`, (files) => {
this.handleDrop(files)

View file

@ -19,13 +19,15 @@ export default class Dummy extends Plugin {
this.opts = Object.assign({}, defaultOptions, opts)
this.strange = yo`<h1>this is strange 1</h1>`
this.render = this.render.bind(this)
this.install = this.install.bind(this)
}
render () {
const bla = yo`<h1>this is strange 2</h1>`
const bla = yo`<h2>this is strange 2</h2>`
return yo`
<div class="wow-this-works">
<input type="text" value="hello">
<input class="UppyDummy-firstInput" type="text" value="hello">
${this.strange}
${bla}
</div>
@ -33,12 +35,18 @@ export default class Dummy extends Plugin {
}
focus () {
const firstInput = document.querySelector(`${this.target} *:input[type!=hidden]:first`)
firstInput.focus()
const firstInput = document.querySelector(`${this.target} .UppyDummy-firstInput`)
// only works for the first time if wrapped in setTimeout for some reason
// firstInput.focus()
setTimeout(function () {
firstInput.focus()
}, 10)
}
install () {
this.el = this.render()
this.target = this.getTarget(this.opts.target, this, this.el, this.render)
const target = this.opts.target
const plugin = this
this.target = this.mount(target, plugin)
}
}

View file

@ -26,6 +26,7 @@ export default class Google extends Plugin {
this.renderBrowser = this.renderBrowser.bind(this)
this.sortByTitle = this.sortByTitle.bind(this)
this.sortByDate = this.sortByDate.bind(this)
this.render = this.render.bind(this)
// set default options
const defaultOptions = {}
@ -34,13 +35,14 @@ export default class Google extends Plugin {
this.opts = Object.assign({}, defaultOptions, opts)
}
update (state) {
if (typeof this.el === 'undefined') {
return
}
focus () {
const firstInput = document.querySelector(`${this.target} .UppyGoogleDrive-focusInput`)
const newEl = this.render(this.core.state)
yo.update(this.el, newEl)
// only works for the first time if wrapped in setTimeout for some reason
// firstInput.focus()
setTimeout(function () {
firstInput.focus()
}, 10)
}
/**
@ -402,7 +404,7 @@ export default class Google extends Plugin {
<div class="row">
<div class="hidden-md-down col-lg-3 col-xl-3">
<ul class="UppyGoogleDrive-sidebar">
<li class="UppyGoogleDrive-filter"><input type='text' onkeyup=${this.filterQuery} placeholder="Search.." value=${state.filterInput}/></li>
<li class="UppyGoogleDrive-filter"><input class="UppyGoogleDrive-focusInput" type='text' onkeyup=${this.filterQuery} placeholder="Search.." value=${state.filterInput}/></li>
<li><button onclick=${this.getSubFolder.bind(this, 'root', 'My Drive')}><img src="https://ssl.gstatic.com/docs/doclist/images/icon_11_collection_list_3.png"/> My Drive</button></li>
<li><button><img src="https://ssl.gstatic.com/docs/doclist/images/icon_11_shared_collection_list_1.png"/> Shared with me</button></li>
<li><button onclick=${this.logout}>Logout</button></li>
@ -457,8 +459,9 @@ export default class Google extends Plugin {
}
})
this.el = this.render(this.core.state)
this.target = this.getTarget(this.opts.target, this, this.el, this.render.bind(this))
const target = this.opts.target
const plugin = this
this.target = this.mount(target, plugin)
this.checkAuthentication()
.then((authenticated) => {

View file

@ -28,13 +28,19 @@ export default class Modal extends Plugin {
this.hideModal = this.hideModal.bind(this)
this.showModal = this.showModal.bind(this)
this.addTarget = this.addTarget.bind(this)
this.showTabPanel = this.showTabPanel.bind(this)
this.events = this.events.bind(this)
this.render = this.render.bind(this)
this.install = this.install.bind(this)
}
addTarget (callerPlugin, render) {
const callerPluginId = callerPlugin.constructor.name
const callerPluginName = callerPlugin.title || callerPluginId
const callerPluginIcon = callerPlugin.icon || this.opts.defaultTabIcon
const callerPluginType = callerPlugin.type
addTarget (plugin) {
const callerPluginId = plugin.constructor.name
const callerPluginName = plugin.title || callerPluginId
const callerPluginIcon = plugin.icon || this.opts.defaultTabIcon
const callerPluginType = plugin.type
if (callerPluginType !== 'acquirer' &&
callerPluginType !== 'progressindicator' &&
@ -49,7 +55,8 @@ export default class Modal extends Plugin {
name: callerPluginName,
icon: callerPluginIcon,
type: callerPluginType,
render: render,
focus: plugin.focus,
render: plugin.render,
isHidden: true
}
@ -71,6 +78,7 @@ export default class Modal extends Plugin {
const newTargets = modal.targets.map((target) => {
if (target.type === 'acquirer') {
if (target.id === id) {
target.focus()
return Object.assign({}, target, {
isHidden: false
})
@ -118,6 +126,7 @@ export default class Modal extends Plugin {
const newTargets = modal.targets.map((target) => {
if (target.type === 'acquirer' && !found) {
found = true
target.focus()
return Object.assign({}, target, {
isHidden: false

View file

@ -15,7 +15,11 @@ export default class Plugin {
this.core = core
this.opts = opts
this.type = 'none'
// this.name = this.constructor.name
this.update = this.update.bind(this)
this.mount = this.mount.bind(this)
this.focus = this.focus.bind(this)
this.install = this.install.bind(this)
}
update () {
@ -35,8 +39,8 @@ export default class Plugin {
* @param {String|Object} target
*
*/
getTarget (target, caller, el, render) {
const callerPluginName = caller.id
mount (target, plugin) {
const callerPluginName = plugin.id
if (typeof target === 'string') {
this.core.log(`Installing ${callerPluginName} to ${target}`)
@ -45,16 +49,20 @@ export default class Plugin {
// if (replaceTargetContent) {
// document.querySelector(target).innerHTML = ''
// }
document.querySelector(target).appendChild(el)
const element = plugin.render(this.core.state)
document.querySelector(target).appendChild(element)
return target
} else {
// TODO: is this the way to roll just to get the plugin name?
// TODO: is instantiating the plugin really the way to roll
// just to get the plugin name?
const Target = target
const targetPluginName = new Target().id
this.core.log(`Installing ${callerPluginName} to ${targetPluginName}`)
let targetPlugin = this.core.getPlugin(targetPluginName)
let selectorTarget = targetPlugin.addTarget(caller, render)
const targetPlugin = this.core.getPlugin(targetPluginName)
const selectorTarget = targetPlugin.addTarget(plugin)
return selectorTarget
}

View file

@ -31,7 +31,8 @@ export default class ProgressBar extends Plugin {
}
install () {
this.el = this.render(this.core.state)
this.target = this.getTarget(this.opts.target, this, this.el, this.render.bind(this))
const target = this.opts.target
const plugin = this
this.target = this.mount(target, plugin)
}
}

View file

@ -17,6 +17,8 @@ export default class ProgressDrawer extends Plugin {
// merge default options with the ones set by user
this.opts = Object.assign({}, defaultOptions, opts)
this.render = this.render.bind(this)
}
drawerItem (file) {
@ -30,27 +32,27 @@ export default class ProgressDrawer extends Plugin {
<polygon points="2.836,14.708 5.665,11.878 13.415,19.628 26.334,6.712 29.164,9.54 13.415,25.288 "></polygon>
</svg>`
const fileIcon = yo`
<svg width="34" height="44" viewBox="0 0 21 29">
<path d="M2.473.31C1.44.31.59 1.21.59 2.307V26.31c0 1.097.85 2 1.883 2H18.71c1.03 0 1.88-.903 1.88-2V7.746a.525.525 0 0 0-.014-.108v-.015a.51.51 0 0 0-.014-.03v-.017a.51.51 0 0 0-.015-.03.482.482 0 0 0-.014-.016v-.015a.482.482 0 0 0-.015-.015.51.51 0 0 0-.014-.03.482.482 0 0 0-.014-.017.51.51 0 0 0-.015-.03.483.483 0 0 0-.03-.03L13.636.45a.47.47 0 0 0-.118-.093.448.448 0 0 0-.044-.015.448.448 0 0 0-.044-.016.448.448 0 0 0-.045-.015.44.44 0 0 0-.073 0H2.474zm0 .99h10.372v4.943c0 1.097.85 2 1.88 2h4.932V26.31c0 .56-.42 1.007-.948 1.007H2.472c-.527 0-.95-.446-.95-1.007V2.308c0-.56.423-1.008.95-1.008zm11.305.667l4.843 4.927.352.357h-4.246c-.527 0-.948-.446-.948-1.007V1.967z"
fill="#F6A623"
fill-rule="evenodd" />
<text font-family="ArialMT, Arial"
font-size="5"
font-weight="bold"
fill="#F6A623"
text-anchor="middle"
x="11"
y="22">
${file.type.specific ? file.type.specific.toUpperCase() : '?'}
</text>
</svg>
`
return yo`<li id="${file.id}" class="UppyProgressDrawer-item"
title="${file.name}">
<div class="UppyProgressDrawer-itemInfo">
<svg width="34" height="44" viewBox="0 0 21 29">
<path d="M2.473.31C1.44.31.59 1.21.59 2.307V26.31c0 1.097.85 2 1.883 2H18.71c1.03 0 1.88-.903 1.88-2V7.746a.525.525 0 0 0-.014-.108v-.015a.51.51 0 0 0-.014-.03v-.017a.51.51 0 0 0-.015-.03.482.482 0 0 0-.014-.016v-.015a.482.482 0 0 0-.015-.015.51.51 0 0 0-.014-.03.482.482 0 0 0-.014-.017.51.51 0 0 0-.015-.03.483.483 0 0 0-.03-.03L13.636.45a.47.47 0 0 0-.118-.093.448.448 0 0 0-.044-.015.448.448 0 0 0-.044-.016.448.448 0 0 0-.045-.015.44.44 0 0 0-.073 0H2.474zm0 .99h10.372v4.943c0 1.097.85 2 1.88 2h4.932V26.31c0 .56-.42 1.007-.948 1.007H2.472c-.527 0-.95-.446-.95-1.007V2.308c0-.56.423-1.008.95-1.008zm11.305.667l4.843 4.927.352.357h-4.246c-.527 0-.948-.446-.948-1.007V1.967z"
fill="#F6A623"
fill-rule="evenodd" />
<text font-family="ArialMT, Arial"
font-size="5"
font-weight="bold"
fill="#F6A623"
text-anchor="middle"
x="11"
y="22">
${file.type.specific ? file.type.specific.toUpperCase() : '?'}
</text>
</svg>
${file.type.general === 'image'
? yo`<img class="UppyProgressDrawer-itemIcon" alt="${file.name}" src="${file.preview}">`
: yo`<span class="UppyProgressDrawer-itemType">${file.type.specific}</span>`
}
${file.type.general === 'image' ? file.previewEl : fileIcon}
</div>
<div class="UppyProgressDrawer-itemInner">
<h4 class="UppyProgressDrawer-itemName">
@ -127,7 +129,8 @@ export default class ProgressDrawer extends Plugin {
}
install () {
this.el = this.render(this.core.state)
this.target = this.getTarget(this.opts.target, this, this.el, this.render.bind(this))
const target = this.opts.target
const plugin = this
this.target = this.mount(target, plugin)
}
}

View file

@ -1,4 +1,4 @@
import Uppy from 'uppy/core'
import Uppy from '../../../../src/core/Core.js'
import Dummy from '../../../../src/plugins/Dummy.js'
import Tus10 from '../../../../src/plugins/Tus10.js'
import Modal from '../../../../src/plugins/Modal.js'