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:
parent
fe766ff683
commit
a167d7463d
6 changed files with 83 additions and 6 deletions
|
@ -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(
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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 )-------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue