mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-16 16:58:38 +01:00
Pholio - make the form maintain client side edits between file uploads
Summary: Fixes T3553. Did it by adding some code that refreshes the File object on keyup events within a given file entry. also fixes an html derp I found trying to fix this. Test Plan: added cool things like 'bbb' to every field and noted they were maintained when I added more files Reviewers: btrahan Reviewed By: btrahan CC: aran, Korvin, chad Maniphest Tasks: T3553 Differential Revision: https://secure.phabricator.com/D6488
This commit is contained in:
parent
33bc4d8841
commit
dd76143399
17 changed files with 290 additions and 452 deletions
|
@ -141,7 +141,6 @@ $package_spec = array(
|
|||
'javelin-behavior-differential-comment-jump',
|
||||
'javelin-behavior-differential-add-reviewers-and-ccs',
|
||||
'javelin-behavior-differential-keyboard-navigation',
|
||||
'javelin-behavior-aphront-drag-and-drop',
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea',
|
||||
'javelin-behavior-phabricator-object-selector',
|
||||
'javelin-behavior-repository-crossreference',
|
||||
|
@ -164,7 +163,6 @@ $package_spec = array(
|
|||
'maniphest.pkg.css' => array(
|
||||
'maniphest-task-summary-css',
|
||||
'maniphest-transaction-detail-css',
|
||||
'aphront-attached-file-view-css',
|
||||
'phabricator-project-tag-css',
|
||||
),
|
||||
'maniphest.pkg.js' => array(
|
||||
|
|
|
@ -798,15 +798,6 @@ celerity_register_resource_map(array(
|
|||
'disk' => '/rsrc/swf/aphlict.swf',
|
||||
'type' => 'swf',
|
||||
),
|
||||
'aphront-attached-file-view-css' =>
|
||||
array(
|
||||
'uri' => '/res/a6ca5487/rsrc/css/aphront/attached-file-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
),
|
||||
'disk' => '/rsrc/css/aphront/attached-file-view.css',
|
||||
),
|
||||
'aphront-bars' =>
|
||||
array(
|
||||
'uri' => '/res/95a907d6/rsrc/css/aphront/aphront-bars.css',
|
||||
|
@ -1289,19 +1280,6 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/core/behavior-crop.js',
|
||||
),
|
||||
'javelin-behavior-aphront-drag-and-drop' =>
|
||||
array(
|
||||
'uri' => '/res/fde3763f/rsrc/js/core/behavior-drag-and-drop.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-behavior',
|
||||
1 => 'javelin-dom',
|
||||
2 => 'phabricator-file-upload',
|
||||
3 => 'phabricator-drag-and-drop-file-upload',
|
||||
),
|
||||
'disk' => '/rsrc/js/core/behavior-drag-and-drop.js',
|
||||
),
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea' =>
|
||||
array(
|
||||
'uri' => '/res/a261f6e6/rsrc/js/core/behavior-drag-and-drop-textarea.js',
|
||||
|
@ -2254,6 +2232,21 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/application/phame/phame-post-preview.js',
|
||||
),
|
||||
'javelin-behavior-pholio-mock-edit' =>
|
||||
array(
|
||||
'uri' => '/res/34a066b1/rsrc/js/application/pholio/behavior-pholio-mock-edit.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-behavior',
|
||||
1 => 'javelin-stratcom',
|
||||
2 => 'javelin-dom',
|
||||
3 => 'javelin-workflow',
|
||||
4 => 'phabricator-phtize',
|
||||
5 => 'phabricator-drag-and-drop-file-upload',
|
||||
),
|
||||
'disk' => '/rsrc/js/application/pholio/behavior-pholio-mock-edit.js',
|
||||
),
|
||||
'javelin-behavior-pholio-mock-view' =>
|
||||
array(
|
||||
'uri' => '/res/415cd66a/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
|
||||
|
@ -3751,7 +3744,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'pholio-edit-css' =>
|
||||
array(
|
||||
'uri' => '/res/c4a1f392/rsrc/css/application/pholio/pholio-edit.css',
|
||||
'uri' => '/res/56034479/rsrc/css/application/pholio/pholio-edit.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -4319,7 +4312,7 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/dd27a69b/differential.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'bb59a901' =>
|
||||
'48040be9' =>
|
||||
array(
|
||||
'name' => 'differential.pkg.js',
|
||||
'symbols' =>
|
||||
|
@ -4335,17 +4328,16 @@ celerity_register_resource_map(array(
|
|||
8 => 'javelin-behavior-differential-comment-jump',
|
||||
9 => 'javelin-behavior-differential-add-reviewers-and-ccs',
|
||||
10 => 'javelin-behavior-differential-keyboard-navigation',
|
||||
11 => 'javelin-behavior-aphront-drag-and-drop',
|
||||
12 => 'javelin-behavior-aphront-drag-and-drop-textarea',
|
||||
13 => 'javelin-behavior-phabricator-object-selector',
|
||||
14 => 'javelin-behavior-repository-crossreference',
|
||||
15 => 'javelin-behavior-load-blame',
|
||||
16 => 'differential-inline-comment-editor',
|
||||
17 => 'javelin-behavior-differential-dropdown-menus',
|
||||
18 => 'javelin-behavior-differential-toggle-files',
|
||||
19 => 'javelin-behavior-differential-user-select',
|
||||
11 => 'javelin-behavior-aphront-drag-and-drop-textarea',
|
||||
12 => 'javelin-behavior-phabricator-object-selector',
|
||||
13 => 'javelin-behavior-repository-crossreference',
|
||||
14 => 'javelin-behavior-load-blame',
|
||||
15 => 'differential-inline-comment-editor',
|
||||
16 => 'javelin-behavior-differential-dropdown-menus',
|
||||
17 => 'javelin-behavior-differential-toggle-files',
|
||||
18 => 'javelin-behavior-differential-user-select',
|
||||
),
|
||||
'uri' => '/res/pkg/bb59a901/differential.pkg.js',
|
||||
'uri' => '/res/pkg/48040be9/differential.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'c8ce2d88' =>
|
||||
|
@ -4400,17 +4392,16 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/a9f14d76/javelin.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'adc3c36d' =>
|
||||
'06bacb9a' =>
|
||||
array(
|
||||
'name' => 'maniphest.pkg.css',
|
||||
'symbols' =>
|
||||
array(
|
||||
0 => 'maniphest-task-summary-css',
|
||||
1 => 'maniphest-transaction-detail-css',
|
||||
2 => 'aphront-attached-file-view-css',
|
||||
3 => 'phabricator-project-tag-css',
|
||||
2 => 'phabricator-project-tag-css',
|
||||
),
|
||||
'uri' => '/res/pkg/adc3c36d/maniphest.pkg.css',
|
||||
'uri' => '/res/pkg/06bacb9a/maniphest.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'98f64f07' =>
|
||||
|
@ -4430,7 +4421,6 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'reverse' =>
|
||||
array(
|
||||
'aphront-attached-file-view-css' => 'adc3c36d',
|
||||
'aphront-dialog-view-css' => 'f69c023f',
|
||||
'aphront-error-view-css' => 'f69c023f',
|
||||
'aphront-form-view-css' => 'f69c023f',
|
||||
|
@ -4443,7 +4433,7 @@ celerity_register_resource_map(array(
|
|||
'aphront-typeahead-control-css' => 'f69c023f',
|
||||
'differential-changeset-view-css' => 'dd27a69b',
|
||||
'differential-core-view-css' => 'dd27a69b',
|
||||
'differential-inline-comment-editor' => 'bb59a901',
|
||||
'differential-inline-comment-editor' => '48040be9',
|
||||
'differential-local-commits-view-css' => 'dd27a69b',
|
||||
'differential-results-table-css' => 'dd27a69b',
|
||||
'differential-revision-add-comment-css' => 'dd27a69b',
|
||||
|
@ -4461,24 +4451,23 @@ celerity_register_resource_map(array(
|
|||
'javelin-behavior-aphlict-dropdown' => '75ccea43',
|
||||
'javelin-behavior-aphlict-listen' => '75ccea43',
|
||||
'javelin-behavior-aphront-basic-tokenizer' => '75ccea43',
|
||||
'javelin-behavior-aphront-drag-and-drop' => 'bb59a901',
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea' => 'bb59a901',
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea' => '48040be9',
|
||||
'javelin-behavior-aphront-form-disable-on-submit' => '75ccea43',
|
||||
'javelin-behavior-audit-preview' => '96909266',
|
||||
'javelin-behavior-dark-console' => '4ccfeb47',
|
||||
'javelin-behavior-device' => '75ccea43',
|
||||
'javelin-behavior-differential-accept-with-errors' => 'bb59a901',
|
||||
'javelin-behavior-differential-add-reviewers-and-ccs' => 'bb59a901',
|
||||
'javelin-behavior-differential-comment-jump' => 'bb59a901',
|
||||
'javelin-behavior-differential-diff-radios' => 'bb59a901',
|
||||
'javelin-behavior-differential-dropdown-menus' => 'bb59a901',
|
||||
'javelin-behavior-differential-edit-inline-comments' => 'bb59a901',
|
||||
'javelin-behavior-differential-feedback-preview' => 'bb59a901',
|
||||
'javelin-behavior-differential-keyboard-navigation' => 'bb59a901',
|
||||
'javelin-behavior-differential-populate' => 'bb59a901',
|
||||
'javelin-behavior-differential-show-more' => 'bb59a901',
|
||||
'javelin-behavior-differential-toggle-files' => 'bb59a901',
|
||||
'javelin-behavior-differential-user-select' => 'bb59a901',
|
||||
'javelin-behavior-differential-accept-with-errors' => '48040be9',
|
||||
'javelin-behavior-differential-add-reviewers-and-ccs' => '48040be9',
|
||||
'javelin-behavior-differential-comment-jump' => '48040be9',
|
||||
'javelin-behavior-differential-diff-radios' => '48040be9',
|
||||
'javelin-behavior-differential-dropdown-menus' => '48040be9',
|
||||
'javelin-behavior-differential-edit-inline-comments' => '48040be9',
|
||||
'javelin-behavior-differential-feedback-preview' => '48040be9',
|
||||
'javelin-behavior-differential-keyboard-navigation' => '48040be9',
|
||||
'javelin-behavior-differential-populate' => '48040be9',
|
||||
'javelin-behavior-differential-show-more' => '48040be9',
|
||||
'javelin-behavior-differential-toggle-files' => '48040be9',
|
||||
'javelin-behavior-differential-user-select' => '48040be9',
|
||||
'javelin-behavior-diffusion-commit-graph' => '96909266',
|
||||
'javelin-behavior-diffusion-pull-lastmodified' => '96909266',
|
||||
'javelin-behavior-error-log' => '4ccfeb47',
|
||||
|
@ -4486,7 +4475,7 @@ celerity_register_resource_map(array(
|
|||
'javelin-behavior-history-install' => '75ccea43',
|
||||
'javelin-behavior-konami' => '75ccea43',
|
||||
'javelin-behavior-lightbox-attachments' => '75ccea43',
|
||||
'javelin-behavior-load-blame' => 'bb59a901',
|
||||
'javelin-behavior-load-blame' => '48040be9',
|
||||
'javelin-behavior-maniphest-batch-selector' => '98f64f07',
|
||||
'javelin-behavior-maniphest-subpriority-editor' => '98f64f07',
|
||||
'javelin-behavior-maniphest-transaction-controls' => '98f64f07',
|
||||
|
@ -4498,7 +4487,7 @@ celerity_register_resource_map(array(
|
|||
'javelin-behavior-phabricator-hovercards' => '75ccea43',
|
||||
'javelin-behavior-phabricator-keyboard-shortcuts' => '75ccea43',
|
||||
'javelin-behavior-phabricator-nav' => '75ccea43',
|
||||
'javelin-behavior-phabricator-object-selector' => 'bb59a901',
|
||||
'javelin-behavior-phabricator-object-selector' => '48040be9',
|
||||
'javelin-behavior-phabricator-oncopy' => '75ccea43',
|
||||
'javelin-behavior-phabricator-remarkup-assist' => '75ccea43',
|
||||
'javelin-behavior-phabricator-reveal-content' => '75ccea43',
|
||||
|
@ -4506,7 +4495,7 @@ celerity_register_resource_map(array(
|
|||
'javelin-behavior-phabricator-tooltips' => '75ccea43',
|
||||
'javelin-behavior-phabricator-watch-anchor' => '75ccea43',
|
||||
'javelin-behavior-refresh-csrf' => '75ccea43',
|
||||
'javelin-behavior-repository-crossreference' => 'bb59a901',
|
||||
'javelin-behavior-repository-crossreference' => '48040be9',
|
||||
'javelin-behavior-toggle-class' => '75ccea43',
|
||||
'javelin-behavior-workflow' => '75ccea43',
|
||||
'javelin-dom' => 'a9f14d76',
|
||||
|
@ -4529,15 +4518,15 @@ celerity_register_resource_map(array(
|
|||
'javelin-vector' => 'a9f14d76',
|
||||
'javelin-workflow' => 'a9f14d76',
|
||||
'lightbox-attachment-css' => 'f69c023f',
|
||||
'maniphest-task-summary-css' => 'adc3c36d',
|
||||
'maniphest-transaction-detail-css' => 'adc3c36d',
|
||||
'maniphest-task-summary-css' => '06bacb9a',
|
||||
'maniphest-transaction-detail-css' => '06bacb9a',
|
||||
'phabricator-action-list-view-css' => 'f69c023f',
|
||||
'phabricator-application-launch-view-css' => 'f69c023f',
|
||||
'phabricator-busy' => '75ccea43',
|
||||
'phabricator-content-source-view-css' => 'dd27a69b',
|
||||
'phabricator-core-css' => 'f69c023f',
|
||||
'phabricator-crumbs-view-css' => 'f69c023f',
|
||||
'phabricator-drag-and-drop-file-upload' => 'bb59a901',
|
||||
'phabricator-drag-and-drop-file-upload' => '48040be9',
|
||||
'phabricator-dropdown-menu' => '75ccea43',
|
||||
'phabricator-file-upload' => '75ccea43',
|
||||
'phabricator-filetree-view-css' => 'f69c023f',
|
||||
|
@ -4558,10 +4547,10 @@ celerity_register_resource_map(array(
|
|||
'phabricator-object-selector-css' => 'dd27a69b',
|
||||
'phabricator-phtize' => '75ccea43',
|
||||
'phabricator-prefab' => '75ccea43',
|
||||
'phabricator-project-tag-css' => 'adc3c36d',
|
||||
'phabricator-project-tag-css' => '06bacb9a',
|
||||
'phabricator-property-list-view-css' => 'f69c023f',
|
||||
'phabricator-remarkup-css' => 'f69c023f',
|
||||
'phabricator-shaped-request' => 'bb59a901',
|
||||
'phabricator-shaped-request' => '48040be9',
|
||||
'phabricator-side-menu-view-css' => 'f69c023f',
|
||||
'phabricator-standard-page-view' => 'f69c023f',
|
||||
'phabricator-tag-view-css' => 'f69c023f',
|
||||
|
|
|
@ -15,10 +15,8 @@ phutil_register_library_map(array(
|
|||
'Aphront403Response' => 'aphront/response/Aphront403Response.php',
|
||||
'Aphront404Response' => 'aphront/response/Aphront404Response.php',
|
||||
'AphrontAbstractAttachedFileView' => 'view/control/AphrontAbstractAttachedFileView.php',
|
||||
'AphrontAbstractFormDragAndDropUploadControl' => 'view/form/control/AphrontAbstractFormDragAndDropUploadControl.php',
|
||||
'AphrontAjaxResponse' => 'aphront/response/AphrontAjaxResponse.php',
|
||||
'AphrontApplicationConfiguration' => 'aphront/configuration/AphrontApplicationConfiguration.php',
|
||||
'AphrontAttachedFileView' => 'view/control/AphrontAttachedFileView.php',
|
||||
'AphrontBarView' => 'view/widget/bars/AphrontBarView.php',
|
||||
'AphrontCSRFException' => 'aphront/exception/AphrontCSRFException.php',
|
||||
'AphrontCalendarEventView' => 'applications/calendar/view/AphrontCalendarEventView.php',
|
||||
|
@ -38,7 +36,6 @@ phutil_register_library_map(array(
|
|||
'AphrontFormCropControl' => 'view/form/control/AphrontFormCropControl.php',
|
||||
'AphrontFormDateControl' => 'view/form/control/AphrontFormDateControl.php',
|
||||
'AphrontFormDividerControl' => 'view/form/control/AphrontFormDividerControl.php',
|
||||
'AphrontFormDragAndDropUploadControl' => 'view/form/control/AphrontFormDragAndDropUploadControl.php',
|
||||
'AphrontFormFileControl' => 'view/form/control/AphrontFormFileControl.php',
|
||||
'AphrontFormImageControl' => 'view/form/control/AphrontFormImageControl.php',
|
||||
'AphrontFormInsetView' => 'view/form/AphrontFormInsetView.php',
|
||||
|
@ -1715,9 +1712,8 @@ phutil_register_library_map(array(
|
|||
'PholioConstants' => 'applications/pholio/constants/PholioConstants.php',
|
||||
'PholioController' => 'applications/pholio/controller/PholioController.php',
|
||||
'PholioDAO' => 'applications/pholio/storage/PholioDAO.php',
|
||||
'PholioDragAndDropUploadControl' => 'applications/pholio/view/PholioDragAndDropUploadControl.php',
|
||||
'PholioDropUploadController' => 'applications/pholio/controller/PholioDropUploadController.php',
|
||||
'PholioImage' => 'applications/pholio/storage/PholioImage.php',
|
||||
'PholioImageUploadController' => 'applications/pholio/controller/PholioImageUploadController.php',
|
||||
'PholioInlineCommentEditView' => 'applications/pholio/view/PholioInlineCommentEditView.php',
|
||||
'PholioInlineCommentSaveView' => 'applications/pholio/view/PholioInlineCommentSaveView.php',
|
||||
'PholioInlineCommentView' => 'applications/pholio/view/PholioInlineCommentView.php',
|
||||
|
@ -1972,9 +1968,7 @@ phutil_register_library_map(array(
|
|||
'Aphront403Response' => 'AphrontHTMLResponse',
|
||||
'Aphront404Response' => 'AphrontHTMLResponse',
|
||||
'AphrontAbstractAttachedFileView' => 'AphrontView',
|
||||
'AphrontAbstractFormDragAndDropUploadControl' => 'AphrontFormControl',
|
||||
'AphrontAjaxResponse' => 'AphrontResponse',
|
||||
'AphrontAttachedFileView' => 'AphrontAbstractAttachedFileView',
|
||||
'AphrontBarView' => 'AphrontView',
|
||||
'AphrontCSRFException' => 'AphrontException',
|
||||
'AphrontCalendarEventView' => 'AphrontView',
|
||||
|
@ -1994,7 +1988,6 @@ phutil_register_library_map(array(
|
|||
'AphrontFormCropControl' => 'AphrontFormControl',
|
||||
'AphrontFormDateControl' => 'AphrontFormControl',
|
||||
'AphrontFormDividerControl' => 'AphrontFormControl',
|
||||
'AphrontFormDragAndDropUploadControl' => 'AphrontAbstractFormDragAndDropUploadControl',
|
||||
'AphrontFormFileControl' => 'AphrontFormControl',
|
||||
'AphrontFormImageControl' => 'AphrontFormControl',
|
||||
'AphrontFormInsetView' => 'AphrontView',
|
||||
|
@ -3705,13 +3698,12 @@ phutil_register_library_map(array(
|
|||
'PhluxViewController' => 'PhluxController',
|
||||
'PholioController' => 'PhabricatorController',
|
||||
'PholioDAO' => 'PhabricatorLiskDAO',
|
||||
'PholioDragAndDropUploadControl' => 'AphrontAbstractFormDragAndDropUploadControl',
|
||||
'PholioDropUploadController' => 'PholioController',
|
||||
'PholioImage' =>
|
||||
array(
|
||||
0 => 'PholioDAO',
|
||||
1 => 'PhabricatorMarkupInterface',
|
||||
),
|
||||
'PholioImageUploadController' => 'PholioController',
|
||||
'PholioInlineCommentEditView' => 'AphrontView',
|
||||
'PholioInlineCommentSaveView' => 'AphrontView',
|
||||
'PholioInlineCommentView' => 'AphrontView',
|
||||
|
@ -3747,7 +3739,7 @@ phutil_register_library_map(array(
|
|||
'PholioTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PholioTransactionType' => 'PholioConstants',
|
||||
'PholioTransactionView' => 'PhabricatorApplicationTransactionView',
|
||||
'PholioUploadedImageView' => 'AphrontAbstractAttachedFileView',
|
||||
'PholioUploadedImageView' => 'AphrontView',
|
||||
'PhortuneAccount' =>
|
||||
array(
|
||||
0 => 'PhortuneDAO',
|
||||
|
|
|
@ -3,20 +3,6 @@
|
|||
final class PhabricatorFileDropUploadController
|
||||
extends PhabricatorFileController {
|
||||
|
||||
private $viewObject;
|
||||
|
||||
public function setViewObject(AphrontAbstractAttachedFileView $view) {
|
||||
$this->viewObject = $view;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getViewObject() {
|
||||
if (!$this->viewObject) {
|
||||
$this->viewObject = new AphrontAttachedFileView();
|
||||
}
|
||||
return $this->viewObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phutil-external-symbol class PhabricatorStartup
|
||||
*/
|
||||
|
@ -38,14 +24,10 @@ final class PhabricatorFileDropUploadController
|
|||
'isExplicitUpload' => true,
|
||||
));
|
||||
|
||||
$view = $this->getViewObject();
|
||||
$view->setFile($file);
|
||||
|
||||
return id(new AphrontAjaxResponse())->setContent(
|
||||
array(
|
||||
'id' => $file->getID(),
|
||||
'phid' => $file->getPHID(),
|
||||
'html' => $view->render(),
|
||||
'uri' => $file->getBestURI(),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -57,7 +57,9 @@ final class PhabricatorApplicationPholio extends PhabricatorApplication {
|
|||
'edit/(?P<id>\d+)/' => 'PholioInlineEditController',
|
||||
'thumb/(?P<imageid>\d+)/' => 'PholioInlineThumbController'
|
||||
),
|
||||
'image/upload/' => 'PholioDropUploadController',
|
||||
'image/' => array(
|
||||
'upload/' => 'PholioImageUploadController',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @group pholio
|
||||
*/
|
||||
final class PholioDropUploadController extends PholioController {
|
||||
|
||||
public function processRequest() {
|
||||
return $this->delegateToController(
|
||||
id(new PhabricatorFileDropUploadController($this->getRequest()))
|
||||
->setViewObject(new PholioUploadedImageView()));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @group pholio
|
||||
*/
|
||||
final class PholioImageUploadController extends PholioController {
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$phid = $request->getStr('filePHID');
|
||||
$file = id(new PhabricatorFileQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($phid))
|
||||
->executeOne();
|
||||
if (!$file) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$image = id(new PholioImage())
|
||||
->attachFile($file)
|
||||
->setName($file->getName())
|
||||
->makeEphemeral();
|
||||
|
||||
$view = id(new PholioUploadedImageView())
|
||||
->setUser($viewer)
|
||||
->setImage($image);
|
||||
|
||||
$content = array(
|
||||
'markup' => $view,
|
||||
);
|
||||
|
||||
return id(new AphrontAjaxResponse())->setContent($content);
|
||||
}
|
||||
|
||||
}
|
|
@ -92,6 +92,8 @@ final class PholioMockEditController extends PholioController {
|
|||
->execute();
|
||||
$files = mpull($files, null, 'getPHID');
|
||||
$files = array_select_keys($files, $file_phids);
|
||||
} else {
|
||||
$files = array();
|
||||
}
|
||||
|
||||
if (!$files) {
|
||||
|
@ -111,8 +113,8 @@ final class PholioMockEditController extends PholioController {
|
|||
$sequence = 0;
|
||||
foreach ($files as $file_phid => $file) {
|
||||
$mock_image = idx($mock_images, $file_phid);
|
||||
$title = $request->getStr('title_'.$file_phid);
|
||||
$description = $request->getStr('description_'.$file_phid);
|
||||
$title = (string)$request->getStr('title_'.$file_phid);
|
||||
$description = (string)$request->getStr('description_'.$file_phid);
|
||||
if (!$mock_image) {
|
||||
// this is an add
|
||||
$add_image = id(new PholioImage())
|
||||
|
@ -195,15 +197,44 @@ final class PholioMockEditController extends PholioController {
|
|||
|
||||
$cc_tokens = mpull($handles, 'getFullName', 'getPHID');
|
||||
|
||||
$images_controller =
|
||||
id(new PholioDragAndDropUploadControl($request))
|
||||
->setUploadURI($this->getApplicationURI('image/upload/'))
|
||||
->setValue($files)
|
||||
->setImages($mock_images)
|
||||
->setName('file_phids')
|
||||
->setLabel(pht('Images'))
|
||||
->setActivatedClass('aphront-textarea-drag-and-drop')
|
||||
->setError($e_images);
|
||||
$image_elements = array();
|
||||
foreach ($mock_images as $mock_image) {
|
||||
$image_elements[] = id(new PholioUploadedImageView())
|
||||
->setUser($user)
|
||||
->setImage($mock_image);
|
||||
}
|
||||
|
||||
$list_id = celerity_generate_unique_node_id();
|
||||
$drop_id = celerity_generate_unique_node_id();
|
||||
|
||||
$list_control = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => $list_id,
|
||||
'class' => 'pholio-edit-list',
|
||||
),
|
||||
$image_elements);
|
||||
|
||||
$drop_control = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => $drop_id,
|
||||
'class' => 'pholio-edit-drop',
|
||||
),
|
||||
'Drag and drop images here to add them to the mock.');
|
||||
|
||||
Javelin::initBehavior(
|
||||
'pholio-mock-edit',
|
||||
array(
|
||||
'listID' => $list_id,
|
||||
'dropID' => $drop_id,
|
||||
'uploadURI' => '/file/dropupload/',
|
||||
'renderURI' => $this->getApplicationURI('image/upload/'),
|
||||
'pht' => array(
|
||||
'uploading' => pht('Uploading Image...'),
|
||||
'uploaded' => pht('Upload Complete...'),
|
||||
),
|
||||
));
|
||||
|
||||
require_celerity_resource('pholio-edit-css');
|
||||
$form = id(new AphrontFormView())
|
||||
|
@ -235,7 +266,13 @@ final class PholioMockEditController extends PholioController {
|
|||
->setPolicyObject($mock)
|
||||
->setPolicies($policies)
|
||||
->setName('can_view'))
|
||||
->appendChild($images_controller)
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setValue($list_control))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setValue($drop_control)
|
||||
->setError($e_images))
|
||||
->appendChild($submit);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs($this->buildSideNav());
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @group pholio
|
||||
*/
|
||||
final class PholioDragAndDropUploadControl
|
||||
extends AphrontAbstractFormDragAndDropUploadControl {
|
||||
|
||||
private $images;
|
||||
|
||||
public function setImages(array $images) {
|
||||
assert_instances_of($images, 'PholioImage');
|
||||
$this->images = $images;
|
||||
return $this;
|
||||
}
|
||||
public function getImages() {
|
||||
return $this->images;
|
||||
}
|
||||
|
||||
protected function getFileView() {
|
||||
return id(new PholioUploadedImageView())
|
||||
->setImages($this->getImages());
|
||||
}
|
||||
|
||||
}
|
|
@ -3,29 +3,21 @@
|
|||
/**
|
||||
* @group pholio
|
||||
*/
|
||||
final class PholioUploadedImageView extends AphrontAbstractAttachedFileView {
|
||||
final class PholioUploadedImageView extends AphrontView {
|
||||
|
||||
private $images = array();
|
||||
private $image;
|
||||
|
||||
public function setImages(array $images) {
|
||||
assert_instances_of($images, 'PholioImage');
|
||||
$this->images = $images;
|
||||
public function setImage(PholioImage $image) {
|
||||
$this->image = $image;
|
||||
return $this;
|
||||
}
|
||||
public function getImages() {
|
||||
return $this->images;
|
||||
}
|
||||
public function getImage($phid) {
|
||||
$images = $this->getImages();
|
||||
return idx($images, $phid, new PholioImage());
|
||||
}
|
||||
|
||||
public function render() {
|
||||
require_celerity_resource('pholio-edit-css');
|
||||
|
||||
$file = $this->getFile();
|
||||
$image = $this->image;
|
||||
$file = $image->getFile();
|
||||
$phid = $file->getPHID();
|
||||
$image = $this->getImage($phid);
|
||||
|
||||
$thumb = phutil_tag(
|
||||
'img',
|
||||
|
@ -35,11 +27,7 @@ final class PholioUploadedImageView extends AphrontAbstractAttachedFileView {
|
|||
'height' => 210,
|
||||
));
|
||||
|
||||
$file_link = $this->getName();
|
||||
if (!$image->getName()) {
|
||||
$image->setName($this->getFile()->getName());
|
||||
}
|
||||
$remove = $this->getRemoveElement();
|
||||
$remove = $this->renderRemoveElement();
|
||||
|
||||
$title = id(new AphrontFormTextControl())
|
||||
->setName('title_'.$phid)
|
||||
|
@ -51,25 +39,52 @@ final class PholioUploadedImageView extends AphrontAbstractAttachedFileView {
|
|||
->setValue($image->getDescription())
|
||||
->setLabel(pht('Description'));
|
||||
|
||||
return hsprintf(
|
||||
'<div class="pholio-uploaded-image">
|
||||
<div class="thumb-box">
|
||||
<div class="title">
|
||||
<div class="text">%s</div>
|
||||
<div class="remove">%s</div>
|
||||
</div>
|
||||
<div class="thumb">%s</div>
|
||||
$content = hsprintf(
|
||||
'<div class="thumb-box">
|
||||
<div class="title">
|
||||
<div class="text">%s</div>
|
||||
<div class="remove">%s</div>
|
||||
</div>
|
||||
<div class="image-data">
|
||||
<div class="title">%s</title>
|
||||
<div class="description">%s</description>
|
||||
</div>',
|
||||
$file_link,
|
||||
<div class="thumb">%s</div>
|
||||
</div>
|
||||
<div class="image-data">
|
||||
<div class="title">%s</div>
|
||||
<div class="description">%s</div>
|
||||
</div>',
|
||||
$file->getName(),
|
||||
$remove,
|
||||
$thumb,
|
||||
$title,
|
||||
$description);
|
||||
|
||||
$input = phutil_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'file_phids[]',
|
||||
'value' => $phid,
|
||||
));
|
||||
|
||||
return javelin_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'pholio-uploaded-image',
|
||||
'sigil' => 'pholio-drop-image',
|
||||
),
|
||||
array(
|
||||
$content,
|
||||
$input,
|
||||
));
|
||||
}
|
||||
|
||||
private function renderRemoveElement() {
|
||||
return javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'button grey',
|
||||
'sigil' => 'pholio-drop-remove',
|
||||
),
|
||||
'X');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class AphrontAttachedFileView extends AphrontAbstractAttachedFileView {
|
||||
|
||||
public function render() {
|
||||
require_celerity_resource('aphront-attached-file-view-css');
|
||||
|
||||
$file = $this->getFile();
|
||||
$phid = $file->getPHID();
|
||||
|
||||
$thumb = phutil_tag(
|
||||
'img',
|
||||
array(
|
||||
'src' => $file->getThumb60x45URI(),
|
||||
'width' => 60,
|
||||
'height' => 45,
|
||||
));
|
||||
|
||||
$name = $this->getName();
|
||||
$size = number_format($file->getByteSize()).' ' .pht('bytes');
|
||||
|
||||
$remove = $this->getRemoveElement();
|
||||
|
||||
return hsprintf(
|
||||
'<table class="aphront-attached-file-view">
|
||||
<tr>
|
||||
<td>%s</td>
|
||||
<th><strong>%s</strong><br />%s</th>
|
||||
<td class="aphront-attached-file-view-remove">%s</td>
|
||||
</tr>
|
||||
</table>',
|
||||
$thumb,
|
||||
$name,
|
||||
$size,
|
||||
$remove);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
<?php
|
||||
|
||||
abstract class AphrontAbstractFormDragAndDropUploadControl
|
||||
extends AphrontFormControl {
|
||||
|
||||
private $activatedClass;
|
||||
private $uploadURI = '/file/dropupload/';
|
||||
|
||||
public function __construct() {
|
||||
$this->setControlID(celerity_generate_unique_node_id());
|
||||
$this->setControlStyle('display: none;');
|
||||
}
|
||||
|
||||
protected function getCustomControlClass() {
|
||||
return 'aphront-form-drag-and-drop-upload';
|
||||
}
|
||||
|
||||
public function setUploadURI($upload_uri) {
|
||||
$this->uploadURI = $upload_uri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUploadURI() {
|
||||
return $this->uploadURI;
|
||||
}
|
||||
|
||||
public function setActivatedClass($class) {
|
||||
$this->activatedClass = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getFileView() {
|
||||
return new AphrontAttachedFileView();
|
||||
}
|
||||
|
||||
protected function renderInput() {
|
||||
require_celerity_resource('aphront-attached-file-view-css');
|
||||
$list_id = celerity_generate_unique_node_id();
|
||||
|
||||
$files = $this->getValue();
|
||||
$value = array();
|
||||
if ($files) {
|
||||
foreach ($files as $file) {
|
||||
$view = $this->getFileView();
|
||||
$view->setFile($file);
|
||||
$value[$file->getPHID()] = array(
|
||||
'phid' => $file->getPHID(),
|
||||
'html' => $view->render(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Javelin::initBehavior(
|
||||
'aphront-drag-and-drop',
|
||||
array(
|
||||
'control' => $this->getControlID(),
|
||||
'name' => $this->getName(),
|
||||
'value' => nonempty($value, null),
|
||||
'list' => $list_id,
|
||||
'uri' => $this->getUploadURI(),
|
||||
'activatedClass' => $this->activatedClass,
|
||||
));
|
||||
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => $list_id,
|
||||
'class' => 'aphront-form-drag-and-drop-file-list',
|
||||
),
|
||||
'');
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class AphrontFormDragAndDropUploadControl
|
||||
extends AphrontAbstractFormDragAndDropUploadControl {
|
||||
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/**
|
||||
* @provides aphront-attached-file-view-css
|
||||
*/
|
||||
|
||||
.aphront-attached-file-view {
|
||||
border: 1px solid #aaaaaa;
|
||||
background: #f9f9f9;
|
||||
width: 100%;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.aphront-attached-file-view td,
|
||||
.aphront-attached-file-view th {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.aphront-attached-file-view th {
|
||||
width: 100%;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.aphront-attached-file-view-remove {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.aphront-file-preview-view {
|
||||
float: left;
|
||||
margin: 4px 4px 12px;
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
color: #333333;
|
||||
overflow: hidden;
|
||||
width: 166px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.aphront-file-preview-thumb {
|
||||
padding: 2px;
|
||||
border: 1px solid #000000;
|
||||
background: #ffffff;
|
||||
margin-bottom: 2px;
|
||||
width: 160px;
|
||||
}
|
|
@ -3,8 +3,8 @@
|
|||
*/
|
||||
|
||||
.pholio-uploaded-image {
|
||||
float: left;
|
||||
margin: 0px 0px 12px 0px;
|
||||
margin: 0 0 12px 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pholio-uploaded-image .thumb-box {
|
||||
|
@ -13,6 +13,7 @@
|
|||
min-width: 280px;
|
||||
width: 48%;
|
||||
float: left;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pholio-uploaded-image .image-data {
|
||||
|
@ -30,12 +31,15 @@
|
|||
}
|
||||
|
||||
.pholio-uploaded-image .thumb-box .thumb {
|
||||
float: left;
|
||||
background: white;
|
||||
padding: 12px 0px 0px 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pholio-uploaded-image .thumb-box .thumb img {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.pholio-uploaded-image .thumb-box .title .text {
|
||||
width: 220px;
|
||||
float: left;
|
||||
|
@ -79,3 +83,25 @@
|
|||
padding: 20px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.pholio-edit-drop {
|
||||
border-width: 1px;
|
||||
border-style: dashed;
|
||||
border-color: #999999;
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.pholio-edit-drop.pholio-drop-active {
|
||||
border-color: {$green};
|
||||
background-color: {$lightgreen};
|
||||
}
|
||||
|
||||
.pholio-drop-uploading {
|
||||
padding: 24px;
|
||||
text-align: center;
|
||||
border: 1px solid #bbbbbb;
|
||||
background: #fcfcfc;
|
||||
color: #666666;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* @provides javelin-behavior-pholio-mock-edit
|
||||
* @requires javelin-behavior
|
||||
* javelin-stratcom
|
||||
* javelin-dom
|
||||
* javelin-workflow
|
||||
* phabricator-phtize
|
||||
* phabricator-drag-and-drop-file-upload
|
||||
*/
|
||||
JX.behavior('pholio-mock-edit', function(config) {
|
||||
var pht = JX.phtize(config.pht);
|
||||
|
||||
var nodes = {
|
||||
list: JX.$(config.listID),
|
||||
drop: JX.$(config.dropID)
|
||||
};
|
||||
|
||||
var uploading = [];
|
||||
|
||||
var drop = new JX.PhabricatorDragAndDropFileUpload(nodes.drop)
|
||||
.setURI(config.uploadURI);
|
||||
|
||||
drop.listen('didBeginDrag', function(e) {
|
||||
JX.DOM.alterClass(nodes.drop, 'pholio-drop-active', true);
|
||||
});
|
||||
|
||||
drop.listen('didEndDrag', function(e) {
|
||||
JX.DOM.alterClass(nodes.drop, 'pholio-drop-active', false);
|
||||
});
|
||||
|
||||
drop.listen('willUpload', function(file) {
|
||||
var node = JX.$N(
|
||||
'div',
|
||||
{className: 'pholio-drop-uploading'},
|
||||
pht('uploading'));
|
||||
uploading.push({node: node, file: file});
|
||||
nodes.list.appendChild(node);
|
||||
});
|
||||
|
||||
drop.listen('didUpload', function(file) {
|
||||
var node;
|
||||
for (var ii = 0; ii < uploading.length; ii++) {
|
||||
if (uploading[ii].file === file) {
|
||||
node = uploading[ii].node;
|
||||
uploading.splice(ii, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
JX.DOM.setContent(node, pht('uploaded'));
|
||||
|
||||
new JX.Workflow(config.renderURI, {filePHID: file.getPHID()})
|
||||
.setHandler(function(response) {
|
||||
JX.DOM.replace(node, JX.$H(response.markup));
|
||||
})
|
||||
.start();
|
||||
});
|
||||
|
||||
drop.start();
|
||||
|
||||
|
||||
/* -( Deleting Images )---------------------------------------------------- */
|
||||
|
||||
// TODO: It would be nice to replace this with an "image will be removed,
|
||||
// click to undo" kind of thing.
|
||||
JX.Stratcom.listen('click', 'pholio-drop-remove', function(e) {
|
||||
e.kill();
|
||||
JX.DOM.remove(e.getNode('pholio-drop-image'));
|
||||
});
|
||||
|
||||
});
|
|
@ -1,112 +0,0 @@
|
|||
/**
|
||||
* @provides javelin-behavior-aphront-drag-and-drop
|
||||
* @requires javelin-behavior
|
||||
* javelin-dom
|
||||
* phabricator-file-upload
|
||||
* phabricator-drag-and-drop-file-upload
|
||||
*/
|
||||
|
||||
JX.behavior('aphront-drag-and-drop', function(config) {
|
||||
|
||||
// The control renders hidden by default; if we don't have support for
|
||||
// drag-and-drop just leave it hidden.
|
||||
if (!JX.PhabricatorDragAndDropFileUpload.isSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show the control, since we have browser support.
|
||||
JX.$(config.control).style.display = '';
|
||||
|
||||
var files = {};
|
||||
if (config.value) {
|
||||
for (var k in config.value) {
|
||||
var file = config.value[k];
|
||||
files[k] = new JX.PhabricatorFileUpload()
|
||||
.setPHID(file.phid)
|
||||
.setMarkup(file.html);
|
||||
}
|
||||
}
|
||||
var pending = 0;
|
||||
|
||||
var list = JX.$(config.list);
|
||||
|
||||
var drop = new JX.PhabricatorDragAndDropFileUpload(JX.$(config.list))
|
||||
.setURI(config.uri);
|
||||
|
||||
drop.listen('didBeginDrag', function(e) {
|
||||
JX.DOM.alterClass(list, config.activatedClass, true);
|
||||
});
|
||||
|
||||
drop.listen('didEndDrag', function(e) {
|
||||
JX.DOM.alterClass(list, config.activatedClass, false);
|
||||
});
|
||||
|
||||
drop.listen('willUpload', function(f) {
|
||||
pending++;
|
||||
redraw();
|
||||
});
|
||||
|
||||
drop.listen('didUpload', function(f) {
|
||||
files[f.getPHID()] = f;
|
||||
|
||||
// This redraws "Upload complete!"
|
||||
pending--;
|
||||
redraw(true);
|
||||
|
||||
// This redraws the instructions and clears "Upload complete!"
|
||||
setTimeout(redraw, 1000);
|
||||
});
|
||||
|
||||
drop.start();
|
||||
redraw();
|
||||
|
||||
JX.DOM.listen(
|
||||
list,
|
||||
'click',
|
||||
'aphront-attached-file-view-remove',
|
||||
function(e) {
|
||||
e.kill();
|
||||
delete files[e.getTarget().getAttribute('ref')];
|
||||
redraw();
|
||||
});
|
||||
|
||||
function redraw(completed) {
|
||||
var items = [];
|
||||
for (var k in files) {
|
||||
var file = files[k];
|
||||
items.push(JX.$N('div', {}, JX.$H(file.getMarkup())));
|
||||
items.push(JX.$N(
|
||||
'input',
|
||||
{
|
||||
type: "hidden",
|
||||
name: config.name + "[" + file.getPHID() + "]",
|
||||
value: file.getPHID()
|
||||
}));
|
||||
}
|
||||
|
||||
var status;
|
||||
var extra = '';
|
||||
if (!pending) {
|
||||
if (completed) {
|
||||
status = JX.$H('<strong>Upload complete!</strong>');
|
||||
} else {
|
||||
arrow = String.fromCharCode(0x21EA);
|
||||
status = JX.$H(
|
||||
arrow + ' <strong>Drag and Drop</strong> files here to upload them.');
|
||||
extra = ' drag-and-drop-file-target';
|
||||
}
|
||||
} else {
|
||||
status = JX.$H(
|
||||
'Uploading <strong>' + parseInt(pending, 10) + '</strong> files...');
|
||||
}
|
||||
status = JX.$N(
|
||||
'div',
|
||||
{className: 'drag-and-drop-instructions' + extra},
|
||||
status);
|
||||
|
||||
items.push(status);
|
||||
JX.DOM.setContent(list, items);
|
||||
}
|
||||
|
||||
});
|
||||
|
Loading…
Add table
Reference in a new issue