diff --git a/resources/celerity/map.php b/resources/celerity/map.php index cc1567330c..c3c65fb46a 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -82,7 +82,7 @@ return array( 'rsrc/css/application/paste/paste.css' => '1898e534', 'rsrc/css/application/people/people-profile.css' => '2473d929', 'rsrc/css/application/phame/phame.css' => '7448a969', - 'rsrc/css/application/pholio/pholio-edit.css' => 'b15fec4a', + 'rsrc/css/application/pholio/pholio-edit.css' => '07676f51', 'rsrc/css/application/pholio/pholio-inline-comments.css' => '8e545e49', 'rsrc/css/application/pholio/pholio.css' => 'ca89d380', 'rsrc/css/application/phortune/phortune-credit-card-form.css' => '8391eb02', @@ -414,7 +414,7 @@ return array( 'rsrc/js/application/owners/OwnersPathEditor.js' => 'aa1733d0', 'rsrc/js/application/owners/owners-path-editor.js' => '7a68dda3', 'rsrc/js/application/passphrase/passphrase-credential-control.js' => '3cb0b2fc', - 'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '246dc085', + 'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => 'bee502c8', 'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => 'fbe497e7', 'rsrc/js/application/phortune/behavior-stripe-payment-form.js' => '3f5d6dbf', 'rsrc/js/application/phortune/behavior-test-payment-form.js' => 'fc91ab6c', @@ -666,7 +666,7 @@ return array( 'javelin-behavior-phabricator-transaction-comment-form' => 'b23b49e6', 'javelin-behavior-phabricator-transaction-list' => '13c739ea', 'javelin-behavior-phabricator-watch-anchor' => '9f36c42d', - 'javelin-behavior-pholio-mock-edit' => '246dc085', + 'javelin-behavior-pholio-mock-edit' => 'bee502c8', 'javelin-behavior-pholio-mock-view' => 'fbe497e7', 'javelin-behavior-phui-dropdown-menu' => '54733475', 'javelin-behavior-phui-file-upload' => 'b003d4fb', @@ -810,7 +810,7 @@ return array( 'phabricator-zindex-css' => '5b6fcf3f', 'phame-css' => '7448a969', 'pholio-css' => 'ca89d380', - 'pholio-edit-css' => 'b15fec4a', + 'pholio-edit-css' => '07676f51', 'pholio-inline-comments-css' => '8e545e49', 'phortune-credit-card-form' => '2290aeef', 'phortune-credit-card-form-css' => '8391eb02', @@ -1092,16 +1092,6 @@ return array( 'javelin-workflow', 'javelin-util', ), - '246dc085' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-dom', - 'javelin-workflow', - 'javelin-quicksand', - 'phabricator-phtize', - 'phabricator-drag-and-drop-file-upload', - 'phabricator-draggable-list', - ), '2926fff2' => array( 'javelin-behavior', 'javelin-dom', @@ -1871,6 +1861,16 @@ return array( 'javelin-util', 'javelin-request', ), + 'bee502c8' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-dom', + 'javelin-workflow', + 'javelin-quicksand', + 'phabricator-phtize', + 'phabricator-drag-and-drop-file-upload', + 'phabricator-draggable-list', + ), 'bf5374ef' => array( 'javelin-behavior', 'javelin-stratcom', diff --git a/src/applications/files/application/PhabricatorFilesApplication.php b/src/applications/files/application/PhabricatorFilesApplication.php index 4cdcd76041..a94709d400 100644 --- a/src/applications/files/application/PhabricatorFilesApplication.php +++ b/src/applications/files/application/PhabricatorFilesApplication.php @@ -81,7 +81,8 @@ final class PhabricatorFilesApplication extends PhabricatorApplication { 'proxy/' => 'PhabricatorFileProxyController', 'transforms/(?P[1-9]\d*)/' => 'PhabricatorFileTransformListController', - 'uploaddialog/' => 'PhabricatorFileUploadDialogController', + 'uploaddialog/(?Psingle/)?' + => 'PhabricatorFileUploadDialogController', 'download/(?P[^/]+)/' => 'PhabricatorFileDialogController', 'iconset/(?P[^/]+)/' => array( 'select/' => 'PhabricatorFileIconSetSelectController', diff --git a/src/applications/files/controller/PhabricatorFileUploadDialogController.php b/src/applications/files/controller/PhabricatorFileUploadDialogController.php index 77fff2561f..50af4656cb 100644 --- a/src/applications/files/controller/PhabricatorFileUploadDialogController.php +++ b/src/applications/files/controller/PhabricatorFileUploadDialogController.php @@ -37,12 +37,18 @@ final class PhabricatorFileUploadDialogController } } + if ($request->getURIData('single')) { + $allow_multiple = false; + } else { + $allow_multiple = true; + } + $form = id(new AphrontFormView()) ->appendChild( id(new PHUIFormFileControl()) ->setName('filePHIDs') ->setLabel(pht('Upload File')) - ->setAllowMultiple(true) + ->setAllowMultiple($allow_multiple) ->setError($e_file)); return $this->newDialog() diff --git a/src/applications/pholio/controller/PholioMockEditController.php b/src/applications/pholio/controller/PholioMockEditController.php index 362c5c41df..06d7e9c029 100644 --- a/src/applications/pholio/controller/PholioMockEditController.php +++ b/src/applications/pholio/controller/PholioMockEditController.php @@ -267,12 +267,12 @@ final class PholioMockEditController extends PholioController { $image_elements); $drop_control = phutil_tag( - 'div', + 'a', array( 'id' => $drop_id, 'class' => 'pholio-edit-drop', ), - pht('Drag and drop images here to add them to the mock.')); + pht('Click here, or drag and drop images to add them to the mock.')); $order_control = phutil_tag( 'input', diff --git a/src/applications/pholio/view/PholioUploadedImageView.php b/src/applications/pholio/view/PholioUploadedImageView.php index e105f4a95f..460b54c517 100644 --- a/src/applications/pholio/view/PholioUploadedImageView.php +++ b/src/applications/pholio/view/PholioUploadedImageView.php @@ -42,11 +42,12 @@ final class PholioUploadedImageView extends AphrontView { PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD); $thumbnail_uri = $file->getURIForTransform($xform); - $thumb_img = phutil_tag( + $thumb_img = javelin_tag( 'img', array( 'class' => 'pholio-thumb-img', 'src' => $thumbnail_uri, + 'sigil' => 'pholio-uploaded-thumb', )); $thumb_frame = phutil_tag( diff --git a/webroot/rsrc/css/application/pholio/pholio-edit.css b/webroot/rsrc/css/application/pholio/pholio-edit.css index 5478a6f10b..78fd16ca46 100644 --- a/webroot/rsrc/css/application/pholio/pholio-edit.css +++ b/webroot/rsrc/css/application/pholio/pholio-edit.css @@ -44,6 +44,10 @@ padding: 8px; } +.pholio-uploaded-image .pholio-thumb-img { + cursor: pointer; +} + .pholio-thumb-frame { background: url('/rsrc/image/checker_lighter.png'); } @@ -102,6 +106,7 @@ } .pholio-edit-drop { + display: block; border-width: 1px; border-style: dashed; border-color: {$lightgreytext}; @@ -110,11 +115,6 @@ color: {$greytext}; } -.device .pholio-edit-drop { - /* For now, no uploading from devices. */ - display: none; -} - .pholio-uploaded-image.pholio-drop-active, .pholio-edit-drop.pholio-drop-active { border-style: solid; diff --git a/webroot/rsrc/js/application/pholio/behavior-pholio-mock-edit.js b/webroot/rsrc/js/application/pholio/behavior-pholio-mock-edit.js index 8a62f7d0db..e5f01e1311 100644 --- a/webroot/rsrc/js/application/pholio/behavior-pholio-mock-edit.js +++ b/webroot/rsrc/js/application/pholio/behavior-pholio-mock-edit.js @@ -106,20 +106,47 @@ JX.behavior('pholio-mock-edit', function(config, statics) { } } - JX.DOM.setContent(node, pht('uploaded')); - - new JX.Workflow(config.renderURI, {filePHID: file.getPHID()}) - .setHandler(function(response) { - var new_node = JX.$H(response.markup).getFragment().firstChild; - build_update_control(new_node); - - JX.DOM.replace(node, new_node); - synchronize_order(); - }) - .start(); + render_upload(node, file); }); drop.start(); + + JX.DOM.listen(add_node, 'click', null, function(e) { + e.kill(); + + new JX.Workflow('/file/uploaddialog/') + .setHandler(function(response) { + var files = response.files; + for (var ii = 0; ii < files.length; ii++) { + var file = files[ii]; + + var upload = new JX.PhabricatorFileUpload() + .setID(file.id) + .setPHID(file.phid) + .setURI(file.uri); + + var node = render_uploading(); + statics.nodes.list.appendChild(node); + + render_upload(node, upload); + } + }) + .start(); + }); + }; + + var render_upload = function(node, file) { + JX.DOM.setContent(node, pht('uploaded')); + + new JX.Workflow(config.renderURI, {filePHID: file.getPHID()}) + .setHandler(function(response) { + var new_node = JX.$H(response.markup).getFragment().firstChild; + build_update_control(new_node); + + JX.DOM.replace(node, new_node); + synchronize_order(); + }) + .start(); }; var build_list_controls = function(list_node) { @@ -130,13 +157,7 @@ JX.behavior('pholio-mock-edit', function(config, statics) { }; var build_update_control = function(node) { - var drop = build_drop_upload(node); - - drop.listen('willUpload', function() { - JX.DOM.alterClass(node, 'pholio-replacing', true); - }); - - drop.listen('didUpload', function(file) { + var did_upload = function(node, file) { var node_data = JX.Stratcom.getData(node); var data = { @@ -156,9 +177,39 @@ JX.behavior('pholio-mock-edit', function(config, statics) { synchronize_order(); }) .start(); + }; + + var drop = build_drop_upload(node); + + drop.listen('willUpload', function() { + JX.DOM.alterClass(node, 'pholio-replacing', true); + }); + + drop.listen('didUpload', function(file) { + did_upload(node, file); }); drop.start(); + + JX.DOM.listen(node, 'click', 'pholio-uploaded-thumb', function(e) { + e.kill(); + + new JX.Workflow('/file/uploaddialog/single/') + .setHandler(function(response) { + var files = response.files; + for (var ii = 0; ii < files.length; ii++) { + var file = files[ii]; + + var upload = new JX.PhabricatorFileUpload() + .setID(file.id) + .setPHID(file.phid) + .setURI(file.uri); + + did_upload(node, upload); + } + }) + .start(); + }); };