diff --git a/CHANGELOG.md b/CHANGELOG.md index dda1f7715..cfaa58da7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ Ideas that will be planned and find their way into a release at one point - [ ] drive: Show a visual indication that downloading has started after double-clicking. Prevent that 6 clicks = 3 downloads - [ ] instagram: Make a barely working Instagram Plugin + example (#21) - [ ] meta: Use instead of Markdown task tracking. Some discussion [here](https://transloadit.slack.com/archives/general/p1455693654000062) (@kvz) -- [ ] modal: polish on mobile +- [ ] dashboard: polish on mobile - [ ] presets: Add basic preset that mimics Transloadit's jQuery plugin (#28) - [ ] test: Human should check http://www.webpagetest.org, use it sometimes to test our website & Uppy? Which will show response/loading times and where big delays are - [ ] test: Human should test with real screen reader to identify accessibility problems @@ -39,19 +39,26 @@ Ideas that will be planned and find their way into a release at one point ## 0.8.0 -To be released: July 29, 2016 +Theme: The Webcam Edition +To be released: July 29, 2016. Releasemaster: Artur + +- [ ] core: fix bug: no meta information from uppy-server files (@hedgerh) +- [ ] core: fix bug: uppy-server file is treated as local and directly uploaded (@hedgerh) - [ ] meta: better readme on GitHub and NPM (@arturi) - [ ] meta: release “Uppy Begins” post + minor blog polish (@arturi) +- [ ] webcam: initial version: webcam light goes on (@hedgerh) +- [ ] uppy-server: hammering out websockets/oauth (@hedgerh, @acconut) - [ ] modifier: A plugin to supply meta data (like width, tag, filename, user_id) (@arturi) - [ ] modifier: pass custom metadata with non-tus-upload. Maybe mimic meta behavior of tus here, too - [ ] modifier: pass custom metadata with tus-upload with tus-js-client (@arturi) -- [ ] progress: better icons, style, file types (mime + extension) (@arturi) -- [ ] modal: merge modal and dashboard (@arturi) -- [ ] modal: try a workflow where import from external service slides over and takes up the whole modal screen (@arturi) +- [ ] progress: better icons, style (@arturi) +- [ ] core: better mime/type detection (via mime + extension) (@arturi) +- [ ] test: add next-update https://www.npmjs.com/package/next-update to check if packages we use can be safely updated - [ ] test: Get IE4 on windows 3.11 to run Uppy and see it fall back to regular form upload (`api2.transloadit.com`) (@arturi) - [ ] test: working Uppy example on Require Bin — latest version straight from NPM (@arturi) -- [ ] test: add next-update https://www.npmjs.com/package/next-update to check if packages we use can be safely updated +- [x] dashboard: try a workflow where import from external service slides over and takes up the whole dashboard screen (@arturi) +- [x] modal: merge modal and dashboard (@arturi) ## 0.7.0 @@ -238,13 +245,13 @@ Here are the go-to folks for each individual component or area of expertise: - build (@hedgerh) - complete (@hedgerh) - core (@arturi) +- dashboard (/modal) (@hedgerh) - docs (@arturi) - dragdrop (@arturi) -- dropbox (@hedgerh) - drive (@hedgerh) +- dropbox (@hedgerh) - instagram (@hedgerh) - meta (@kvz) -- modal (@hedgerh) - presets (@arturi) - server (@hedgerh) - test (@arturi) diff --git a/README.md b/README.md index 5ffae7400..92ba12267 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,74 @@ -# uppy +# Uppy -A work in progress - you'll find nothing useful here yet. +Uppy logo — a puppy superman -But if you're here to dig in, these are some places you might find interesting: + + +Build Status +Sauce Test Status - - Our website (under construction) [http://uppy.io/](http://uppy.io/) +Uppy is (going to be) a cool JavaScript file uploader that fetches files for you from local disk, Google Drive, Dropbox, Instagram, remote URLs, cameras and other exciting locations, and then uploads them to wherever you want. Uppy is being developed by the [Transloadit](https://transloadit.com) team because we want file uploading experience to be better — both for users and developers. + +Check out [uppy.io](http://uppy.io/) for docs, API, examples and stats. + +## Features + +- Lightweight / easy on dependencies +- Usable as a bundle straight from a CDN as well as a module to import +- Resumable file uploads via the open [tus](http://tus.io/) standard +- Uppy speaks multiple languages (i18n support) +- Works great with file encoding and processing backends, such as [Transloadit](http://transloadit.com) +- Small core, modular plugin-based architecture. +- Qute as a puppy :dog:, also accepts cat pictures + +## Demo + +Uppy UI Demo: modal dialog with a few selected files and an upload button + +- [Full featured UI](http://uppy.io/examples/modal) +- [Simple Drag & Drop](http://uppy.io/examples/dragdrop) + +## Usage + +:warning: **Don’t use Uppy in production just yet, we’re working on it** + +It’s easy to start using Uppy, we recommend installing from npm with `npm install uppy` and then: + +``` javascript +import Uppy from 'uppy/core' +import { DragDrop, Tus10 } from 'uppy/plugins' + +const uppy = new Uppy({wait: false}) +const files = uppy + .use(DragDrop, {target: '#upload-target'}) + .use(Tus10, {endpoint: 'http://master.tus.io:8080/files/'}) + .run() +``` + +But if you like, you can also use a pre-built bundle, in that case `Uppy` will attach itself to the global `window` object: + +``` javascript + + +``` + +## Browser Support + + + Sauce Test Status + + +## Contributions are welcome + + - Contributor’s guide in [`website/src/guide/contributing.md`](website/src/guide/contributing.md) - Architecture in [`website/src/api/architecture.md`](website/src/api/architecture.md) - - Contributor's guide in [`website/src/guide/contributing.md`](website/src/guide/contributing.md) - - Open todos in for a minimum valuable product [`CHANGELOG.md`](CHANGELOG.md#todo) + - Changelog to track our release progress (we aim to roll out a release every month): [`CHANGELOG.md`](CHANGELOG.md) + +## License + +[The MIT License](LICENSE). diff --git a/example/main.js b/example/main.js index 2097a5745..909da4a8a 100644 --- a/example/main.js +++ b/example/main.js @@ -1,15 +1,15 @@ import Uppy from '../src/core/Core.js' -import Modal from '../src/plugins/modal' -// import Dashboard from '../src/plugins/dashboard' +import Modal from '../src/plugins/Modal' import Dummy from '../src/plugins/Dummy' import DragDrop from '../src/plugins/DragDrop' +import GoogleDrive from '../src/plugins/GoogleDrive' import ProgressBar from '../src/plugins/ProgressBar' import Tus10 from '../src/plugins/Tus10' const uppy = new Uppy({debug: true}) .use(Modal, {trigger: '#uppyModalOpener'}) - // .use(Dashboard, {target: Modal}) .use(DragDrop, {target: Modal}) + .use(GoogleDrive, {target: Modal, host: 'http://ya.ru'}) .use(Dummy, {target: Modal}) .use(ProgressBar, {target: Modal}) .use(Tus10, {endpoint: 'http://master.tus.io:8080/files/'}) diff --git a/src/plugins/modal/Dashboard.js b/src/plugins/Modal/Dashboard.js similarity index 100% rename from src/plugins/modal/Dashboard.js rename to src/plugins/Modal/Dashboard.js diff --git a/src/plugins/modal/FileItem.js b/src/plugins/Modal/FileItem.js similarity index 82% rename from src/plugins/modal/FileItem.js rename to src/plugins/Modal/FileItem.js index dbb65ac21..71e9e3464 100644 --- a/src/plugins/modal/FileItem.js +++ b/src/plugins/Modal/FileItem.js @@ -3,6 +3,7 @@ import { fileIcon, checkIcon, removeIcon } from './icons' export default function fileItem (bus, file) { const isUploaded = file.progress === 100 + const uploadInProgress = file.progress > 0 && file.progress const remove = (ev) => { bus.emit('file-remove', file.id) @@ -23,8 +24,8 @@ export default function fileItem (bus, file) {
${file.totalSize}
- ${file.progress > 0 && file.progress < 100 ? 'Uploading… ' + file.progress + '%' : ''} - ${file.progress === 100 ? 'Completed' : ''} + ${uploadInProgress ? 'Uploading… ' + file.progress + '%' : ''} + ${isUploaded ? 'Completed' : ''}
${isUploaded @@ -36,7 +37,7 @@ export default function fileItem (bus, file) { ` }
-
+
` diff --git a/src/plugins/modal/_dashboard.js b/src/plugins/Modal/_dashboard.js similarity index 100% rename from src/plugins/modal/_dashboard.js rename to src/plugins/Modal/_dashboard.js diff --git a/src/plugins/modal/icons.js b/src/plugins/Modal/icons.js similarity index 85% rename from src/plugins/modal/icons.js rename to src/plugins/Modal/icons.js index e26f45332..a4cb64805 100644 --- a/src/plugins/modal/icons.js +++ b/src/plugins/Modal/icons.js @@ -3,9 +3,6 @@ import html from 'yo-yo' // https://css-tricks.com/creating-svg-icon-system-react/ export function defaultTabIcon () { - // return html` - // - // ` return html` @@ -54,14 +51,11 @@ export function uploadIcon () { } export function fileIcon (fileType) { - return html` - + return html` + diff --git a/src/plugins/modal/index.js b/src/plugins/Modal/index.js similarity index 90% rename from src/plugins/modal/index.js rename to src/plugins/Modal/index.js index d803b86ac..99e915a6e 100644 --- a/src/plugins/modal/index.js +++ b/src/plugins/Modal/index.js @@ -28,7 +28,9 @@ export default class Modal extends Plugin { this.showModal = this.showModal.bind(this) this.addTarget = this.addTarget.bind(this) - this.toggleTabPanel = this.toggleTabPanel.bind(this) + this.actions = this.actions.bind(this) + this.hideAllPanels = this.hideAllPanels.bind(this) + this.showPanel = this.showPanel.bind(this) this.initEvents = this.initEvents.bind(this) this.render = this.render.bind(this) this.install = this.install.bind(this) @@ -69,7 +71,22 @@ export default class Modal extends Plugin { return this.opts.target } - toggleTabPanel (id) { + hideAllPanels () { + const modal = this.core.getState().modal + const newModalTargets = modal.targets.slice() + + newModalTargets.forEach((target) => { + if (target.type === 'acquirer') { + target.isHidden = true + } + }) + + this.core.setState({modal: Object.assign({}, modal, { + targets: newModalTargets + })}) + } + + showPanel (id) { const modal = this.core.getState().modal // hide all panels, except the one that matches current id @@ -78,7 +95,7 @@ export default class Modal extends Plugin { if (target.id === id) { target.focus() return Object.assign({}, target, { - isHidden: target.isHidden !== true + isHidden: false }) } return Object.assign({}, target, { @@ -168,6 +185,12 @@ export default class Modal extends Plugin { }) } + actions () { + this.core.emitter.on('file-add', () => { + this.hideAllPanels() + }) + } + handleDrop (files) { this.core.log('All right, someone dropped something...') @@ -218,7 +241,7 @@ export default class Modal extends Plugin { tabindex="0" aria-controls="${this.opts.panelSelectorPrefix}--${target.id}" aria-selected="${target.isHidden ? 'false' : 'true'}" - onclick=${this.toggleTabPanel.bind(this, target.id)}> + onclick=${this.showPanel.bind(this, target.id)}> ${target.icon}
${target.name}
@@ -234,7 +257,7 @@ export default class Modal extends Plugin {

Import From ${target.name}

+ onclick=${this.hideAllPanels}>Back
${target.render(state)}
` @@ -265,6 +288,7 @@ export default class Modal extends Plugin { this.target = this.mount(target, plugin) this.initEvents() + this.actions() dragDrop(this.opts.target, (files) => { this.handleDrop(files) diff --git a/src/plugins/index.js b/src/plugins/index.js index 598dc8f2b..9145bba66 100644 --- a/src/plugins/index.js +++ b/src/plugins/index.js @@ -2,7 +2,7 @@ import Plugin from './Plugin' // Orchestrators -import Modal from './modal' +import Modal from './Modal' // Acquirers import Dummy from './Dummy' diff --git a/src/scss/_dashboard.scss b/src/scss/_dashboard.scss index b9bca0e2c..827200b39 100644 --- a/src/scss/_dashboard.scss +++ b/src/scss/_dashboard.scss @@ -6,7 +6,7 @@ height: 100%; position: relative; padding: 0 20px; - padding-top: 40px; + padding-top: 50px; } .UppyDashboard-title { @@ -18,7 +18,7 @@ margin: 0; padding: 0; position: absolute; - top: 15px; + top: 18px; left: 0; width: 100%; text-align: center; @@ -33,18 +33,15 @@ padding: 0; overflow: scroll; height: 100%; - // position: absolute; - // top: 50px; - // bottom: 15px; - // right: 15px; - // left: 0; - // padding: 15px; + padding-top: 10px; } .UppyDashboardItem { list-style: none; margin: 0; width: 140px; + height: 200px; + overflow: hidden; float: left; padding-top: 20px; margin: 0 15px; @@ -53,13 +50,14 @@ } .UppyDashboardItem-icon { - width: 100px; - height: 100px; + width: 90px; + height: 90px; margin: auto; border-radius: 8px; overflow: hidden; - box-shadow: inset 0 0 0 1px rgba($color-black, 0.1); + // box-shadow: inset 0 0 0 1px rgba($color-black, 0.1); margin-bottom: 10px; + color: $color-orange; } .UppyDashboardItem-icon img { @@ -69,12 +67,12 @@ } .UppyDashboardItem-name { - font-size: 13px; - line-height: 1.4; + font-size: 12px; + line-height: 1.35; font-weight: bold; margin: 0; padding: 0; - margin-bottom: 8px; + margin-bottom: 3px; } .UppyDashboardItem-name a { @@ -85,16 +83,17 @@ .UppyDashboardItem-status { margin: 0; padding: 0; - font-size: 12px; + font-size: 11px; line-height: 1.45; font-weight: normal; color: $color-gray; + text-transform: uppercase; } .UppyDashboardItem-action { position: absolute; top: 10px; - right: -6px; + right: 0; } .UppyDashboardItem-remove { @@ -106,15 +105,18 @@ width: 85px; height: 4px; margin: auto; - background-color: lighten($color-cornflower-blue, 50%); position: absolute; - top: 100px; + top: 90px; left: 0; right: 0; border-radius: 8px; overflow: hidden; } +.UppyDashboardItem-progress.is-active { + background-color: lighten($color-cornflower-blue, 50%); +} + .UppyDashboardItem-progressInner { height: 4px; background-color: $color-cornflower-blue; diff --git a/src/scss/_modal.scss b/src/scss/_modal.scss index ddd3b843c..27239bcb4 100644 --- a/src/scss/_modal.scss +++ b/src/scss/_modal.scss @@ -24,8 +24,10 @@ .UppyModal-inner { @include clearfix; background-color: darken($color-white, 4%); - height: 80vh; width: 65%; + height: 80vh; + max-width: 800px; + max-height: 600px; position: fixed; top: 50%; left: 50%; @@ -39,7 +41,7 @@ .UppyModal-close { position: absolute; - top: 10px; + top: 15px; right: 15px; padding: 0; border: 0; @@ -92,7 +94,7 @@ .UppyModalTab-name { font-size: 10px; - margin: 8px 0; + margin: 6px 0; font-weight: normal; } @@ -136,14 +138,14 @@ position: absolute; top: 0; left: 0; - height: 40px; + height: 50px; width: 100%; border-bottom: 1px solid rgba($color-gray, 0.3); } .UppyModalContent-title { position: absolute; - top: 10px; + top: 15px; left: 0; right: 0; text-align: center; @@ -155,7 +157,7 @@ .UppyModalContent-back { @include reset-button; position: absolute; - top: 12px; + top: 17px; left: 15px; font-size: 14px; cursor: pointer; @@ -172,8 +174,8 @@ bottom: 0; left: 0; right: 0; - transform: translate3d(0, -105%, 0); - transition: all 0.5s; + transform: translateY(-105%); + transition: all 0.5s ease-in-out; background-color: darken($color-white, 4%); box-shadow: 0 0 10px 5px rgba($color-black, 0.15); padding: 15px; @@ -182,7 +184,7 @@ } .UppyModalContent-panel[aria-hidden=false] { - transform: translate3d(0, 0, 0); + transform: translateY(0); } // Progress bar placeholder diff --git a/src/scss/_variables.scss b/src/scss/_variables.scss index 4e31e0036..f35f375ba 100644 --- a/src/scss/_variables.scss +++ b/src/scss/_variables.scss @@ -5,6 +5,7 @@ $color-black: #000; $color-gray: #939393; $color-pink: #e02177; $color-green: #7AC824; +$color-orange: #F6A623; $color-white: #fff; $color-cornflower-blue: #4A90E2; $color-asphalt-gray: #525252; diff --git a/website/src/examples/modal/app.es6 b/website/src/examples/modal/app.es6 index c0d55ca0f..5cf60f10b 100644 --- a/website/src/examples/modal/app.es6 +++ b/website/src/examples/modal/app.es6 @@ -1,7 +1,7 @@ import Uppy from '../../../../src/core/Core.js' import Dummy from '../../../../src/plugins/Dummy' import Tus10 from '../../../../src/plugins/Tus10.js' -import Modal from '../../../../src/plugins/modal' +import Modal from '../../../../src/plugins/Modal' import DragDrop from '../../../../src/plugins/DragDrop.js' import GoogleDrive from '../../../../src/plugins/GoogleDrive.js' import ProgressBar from '../../../../src/plugins/ProgressBar.js'