diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -82,7 +82,7 @@
     '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 @@
     '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 @@
     '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 @@
     '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 @@
       '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 @@
       '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
--- a/src/applications/files/application/PhabricatorFilesApplication.php
+++ b/src/applications/files/application/PhabricatorFilesApplication.php
@@ -81,7 +81,8 @@
         'proxy/' => 'PhabricatorFileProxyController',
         'transforms/(?P<id>[1-9]\d*)/' =>
           'PhabricatorFileTransformListController',
-        'uploaddialog/' => 'PhabricatorFileUploadDialogController',
+        'uploaddialog/(?P<single>single/)?'
+          => 'PhabricatorFileUploadDialogController',
         'download/(?P<phid>[^/]+)/' => 'PhabricatorFileDialogController',
         'iconset/(?P<key>[^/]+)/' => array(
           'select/' => 'PhabricatorFileIconSetSelectController',
diff --git a/src/applications/files/controller/PhabricatorFileUploadDialogController.php b/src/applications/files/controller/PhabricatorFileUploadDialogController.php
--- a/src/applications/files/controller/PhabricatorFileUploadDialogController.php
+++ b/src/applications/files/controller/PhabricatorFileUploadDialogController.php
@@ -37,12 +37,18 @@
       }
     }
 
+    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
--- a/src/applications/pholio/controller/PholioMockEditController.php
+++ b/src/applications/pholio/controller/PholioMockEditController.php
@@ -267,12 +267,12 @@
       $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
--- a/src/applications/pholio/view/PholioUploadedImageView.php
+++ b/src/applications/pholio/view/PholioUploadedImageView.php
@@ -42,11 +42,12 @@
       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
--- 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
--- 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.DOM.setContent(node, pht('uploaded'));
+      render_upload(node, file);
+    });
+
+    drop.start();
+
+    JX.DOM.listen(add_node, 'click', null, function(e) {
+      e.kill();
 
-      new JX.Workflow(config.renderURI, {filePHID: file.getPHID()})
+      new JX.Workflow('/file/uploaddialog/')
         .setHandler(function(response) {
-          var new_node = JX.$H(response.markup).getFragment().firstChild;
-          build_update_control(new_node);
+          var files = response.files;
+          for (var ii = 0; ii < files.length; ii++) {
+            var file = files[ii];
 
-          JX.DOM.replace(node, new_node);
-          synchronize_order();
+            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();
     });
+  };
 
-    drop.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 @@
   };
 
   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 @@
           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();
+    });
   };