1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +01:00

Allow Pholio mock images to be drag-reordered

Summary:
Ref T3640. JS part only, should give you a list in `imageOrder` on the server that you can read with `$request->getStrList('imageOrder')`.

NOTE: You can't drag images into the first position; this is an existing thing that I just need to fix with DraggableList.

@chad might have some design feedback.

Test Plan: Dragged images around, things seemed to work?

Reviewers: btrahan, chad

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T3640

Differential Revision: https://secure.phabricator.com/D6729
This commit is contained in:
epriestley 2013-08-12 12:08:54 -07:00
parent fe766ff683
commit a167d7463d
6 changed files with 83 additions and 6 deletions

View file

@ -2217,7 +2217,7 @@ celerity_register_resource_map(array(
), ),
'javelin-behavior-pholio-mock-edit' => 'javelin-behavior-pholio-mock-edit' =>
array( array(
'uri' => '/res/e537a994/rsrc/js/application/pholio/behavior-pholio-mock-edit.js', 'uri' => '/res/d5f4b705/rsrc/js/application/pholio/behavior-pholio-mock-edit.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -2227,6 +2227,7 @@ celerity_register_resource_map(array(
3 => 'javelin-workflow', 3 => 'javelin-workflow',
4 => 'phabricator-phtize', 4 => 'phabricator-phtize',
5 => 'phabricator-drag-and-drop-file-upload', 5 => 'phabricator-drag-and-drop-file-upload',
6 => 'phabricator-draggable-list',
), ),
'disk' => '/rsrc/js/application/pholio/behavior-pholio-mock-edit.js', 'disk' => '/rsrc/js/application/pholio/behavior-pholio-mock-edit.js',
), ),
@ -3103,7 +3104,7 @@ celerity_register_resource_map(array(
), ),
'phabricator-draggable-list' => 'phabricator-draggable-list' =>
array( array(
'uri' => '/res/76ddce56/rsrc/js/core/DraggableList.js', 'uri' => '/res/7292a1c4/rsrc/js/core/DraggableList.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -3705,7 +3706,7 @@ celerity_register_resource_map(array(
), ),
'pholio-edit-css' => 'pholio-edit-css' =>
array( array(
'uri' => '/res/1d07a294/rsrc/css/application/pholio/pholio-edit.css', 'uri' => '/res/00e3a3a8/rsrc/css/application/pholio/pholio-edit.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(

View file

@ -235,6 +235,7 @@ final class PholioMockEditController extends PholioController {
$list_id = celerity_generate_unique_node_id(); $list_id = celerity_generate_unique_node_id();
$drop_id = celerity_generate_unique_node_id(); $drop_id = celerity_generate_unique_node_id();
$order_id = celerity_generate_unique_node_id();
$list_control = phutil_tag( $list_control = phutil_tag(
'div', 'div',
@ -252,11 +253,20 @@ final class PholioMockEditController extends PholioController {
), ),
'Drag and drop images here to add them to the mock.'); 'Drag and drop images here to add them to the mock.');
$order_control = phutil_tag(
'input',
array(
'type' => 'hidden',
'name' => 'imageOrder',
'id' => $order_id,
));
Javelin::initBehavior( Javelin::initBehavior(
'pholio-mock-edit', 'pholio-mock-edit',
array( array(
'listID' => $list_id, 'listID' => $list_id,
'dropID' => $drop_id, 'dropID' => $drop_id,
'orderID' => $order_id,
'uploadURI' => '/file/dropupload/', 'uploadURI' => '/file/dropupload/',
'renderURI' => $this->getApplicationURI('image/upload/'), 'renderURI' => $this->getApplicationURI('image/upload/'),
'pht' => array( 'pht' => array(
@ -271,6 +281,7 @@ final class PholioMockEditController extends PholioController {
$form = id(new AphrontFormView()) $form = id(new AphrontFormView())
->setUser($user) ->setUser($user)
->setFlexible(true) ->setFlexible(true)
->appendChild($order_control)
->appendChild( ->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())
->setName('name') ->setName('name')

View file

@ -47,6 +47,13 @@ final class PholioUploadedImageView extends AphrontView {
'style' => 'background-image: url('.$file->getThumb280x210URI().');', 'style' => 'background-image: url('.$file->getThumb280x210URI().');',
)); ));
$handle = javelin_tag(
'div',
array(
'class' => 'pholio-drag-handle',
'sigil' => 'pholio-drag-handle',
));
$content = hsprintf( $content = hsprintf(
'<div class="pholio-thumb-box"> '<div class="pholio-thumb-box">
<div class="pholio-thumb-title"> <div class="pholio-thumb-title">
@ -92,6 +99,7 @@ final class PholioUploadedImageView extends AphrontView {
), ),
), ),
array( array(
$handle,
$content, $content,
$input, $input,
$replaces_input, $replaces_input,

View file

@ -3,6 +3,7 @@
*/ */
.pholio-uploaded-image { .pholio-uploaded-image {
position: relative;
overflow: hidden; overflow: hidden;
/* When we activate the image control to show that we're going to replace /* When we activate the image control to show that we're going to replace
@ -23,6 +24,11 @@
overflow: hidden; overflow: hidden;
} }
.device-desktop .pholio-thumb-box {
/* Provide room for the draggable grip. */
margin-left: 12px;
}
.device .pholio-thumb-box { .device .pholio-thumb-box {
float: none; float: none;
margin: 0 auto; margin: 0 auto;
@ -59,7 +65,7 @@
} }
.pholio-image-details { .pholio-image-details {
margin-left: 312px; margin-left: 324px;
} }
.device .pholio-image-details { .device .pholio-image-details {
@ -129,3 +135,17 @@
.pholio-drop-undo a { .pholio-drop-undo a {
font-weight: bold; font-weight: bold;
} }
.pholio-drag-handle {
position: absolute;
height: 100%;
width: 12px;
cursor: move;
background-image: url(/rsrc/image/texture/grip.png);
background-position: center center;
background-repeat: no-repeat;
}
.device .pholio-drag-handle {
display: none;
}

View file

@ -6,13 +6,15 @@
* javelin-workflow * javelin-workflow
* phabricator-phtize * phabricator-phtize
* phabricator-drag-and-drop-file-upload * phabricator-drag-and-drop-file-upload
* phabricator-draggable-list
*/ */
JX.behavior('pholio-mock-edit', function(config) { JX.behavior('pholio-mock-edit', function(config) {
var pht = JX.phtize(config.pht); var pht = JX.phtize(config.pht);
var nodes = { var nodes = {
list: JX.$(config.listID), list: JX.$(config.listID),
drop: JX.$(config.dropID) drop: JX.$(config.dropID),
order: JX.$(config.orderID)
}; };
var uploading = []; var uploading = [];
@ -39,6 +41,36 @@ JX.behavior('pholio-mock-edit', function(config) {
}); });
/* -( Reordering Images )-------------------------------------------------- */
var draglist = new JX.DraggableList('pholio-drop-image', nodes.list)
.setGhostNode(JX.$N('div', {className: 'drag-ghost'}))
.setFindItemsHandler(function() {
return JX.DOM.scry(nodes.list, 'div', 'pholio-drop-image');
});
// Only let the user drag images by the handle, not the whole entry.
draglist.listen('shouldBeginDrag', function(e) {
if (!e.getNode('pholio-drag-handle')) {
JX.Stratcom.context().prevent();
}
});
// Reflect the display order in a hidden input.
var synchronize_order = function() {
var items = draglist.findItems();
var order = [];
for (var ii = 0; ii < items.length; ii++) {
order.push(JX.Stratcom.getData(items[ii]).filePHID);
}
nodes.order.value = order.join(',');
};
draglist.listen('didDrop', synchronize_order);
synchronize_order();
/* -( Build )-------------------------------------------------------------- */ /* -( Build )-------------------------------------------------------------- */

View file

@ -63,6 +63,11 @@ JX.install('DraggableList', {
return this._ghostNode; return this._ghostNode;
}, },
setGhostNode : function(node) {
this._ghostNode = node;
return this;
},
_defaultGhostHandler : function(ghost, target) { _defaultGhostHandler : function(ghost, target) {
var parent = this._dragging.parentNode; var parent = this._dragging.parentNode;
if (target && target.nextSibling) { if (target && target.nextSibling) {
@ -124,7 +129,7 @@ JX.install('DraggableList', {
this._target = null; this._target = null;
if (!this.invoke('didBeginDrag', this._dragging).getPrevented()) { if (!this.invoke('didBeginDrag', this._dragging).getPrevented()) {
var ghost = this.getGhostNode(); var ghost = this.getGhostNode();
ghost.style.height = JX.Vector.getDim(this._dragging).y + 'px'; ghost.style.height = JX.Vector.getDim(this._dragging).y + 'px';
JX.DOM.alterClass(this._dragging, 'drag-dragging', true); JX.DOM.alterClass(this._dragging, 'drag-dragging', true);
} }