@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+83 -6
+4 -3
src/__celerity_resource_map__.php
··· 2217 2217 ), 2218 2218 'javelin-behavior-pholio-mock-edit' => 2219 2219 array( 2220 - 'uri' => '/res/e537a994/rsrc/js/application/pholio/behavior-pholio-mock-edit.js', 2220 + 'uri' => '/res/d5f4b705/rsrc/js/application/pholio/behavior-pholio-mock-edit.js', 2221 2221 'type' => 'js', 2222 2222 'requires' => 2223 2223 array( ··· 2227 2227 3 => 'javelin-workflow', 2228 2228 4 => 'phabricator-phtize', 2229 2229 5 => 'phabricator-drag-and-drop-file-upload', 2230 + 6 => 'phabricator-draggable-list', 2230 2231 ), 2231 2232 'disk' => '/rsrc/js/application/pholio/behavior-pholio-mock-edit.js', 2232 2233 ), ··· 3103 3104 ), 3104 3105 'phabricator-draggable-list' => 3105 3106 array( 3106 - 'uri' => '/res/76ddce56/rsrc/js/core/DraggableList.js', 3107 + 'uri' => '/res/7292a1c4/rsrc/js/core/DraggableList.js', 3107 3108 'type' => 'js', 3108 3109 'requires' => 3109 3110 array( ··· 3705 3706 ), 3706 3707 'pholio-edit-css' => 3707 3708 array( 3708 - 'uri' => '/res/1d07a294/rsrc/css/application/pholio/pholio-edit.css', 3709 + 'uri' => '/res/00e3a3a8/rsrc/css/application/pholio/pholio-edit.css', 3709 3710 'type' => 'css', 3710 3711 'requires' => 3711 3712 array(
+11
src/applications/pholio/controller/PholioMockEditController.php
··· 235 235 236 236 $list_id = celerity_generate_unique_node_id(); 237 237 $drop_id = celerity_generate_unique_node_id(); 238 + $order_id = celerity_generate_unique_node_id(); 238 239 239 240 $list_control = phutil_tag( 240 241 'div', ··· 252 253 ), 253 254 'Drag and drop images here to add them to the mock.'); 254 255 256 + $order_control = phutil_tag( 257 + 'input', 258 + array( 259 + 'type' => 'hidden', 260 + 'name' => 'imageOrder', 261 + 'id' => $order_id, 262 + )); 263 + 255 264 Javelin::initBehavior( 256 265 'pholio-mock-edit', 257 266 array( 258 267 'listID' => $list_id, 259 268 'dropID' => $drop_id, 269 + 'orderID' => $order_id, 260 270 'uploadURI' => '/file/dropupload/', 261 271 'renderURI' => $this->getApplicationURI('image/upload/'), 262 272 'pht' => array( ··· 271 281 $form = id(new AphrontFormView()) 272 282 ->setUser($user) 273 283 ->setFlexible(true) 284 + ->appendChild($order_control) 274 285 ->appendChild( 275 286 id(new AphrontFormTextControl()) 276 287 ->setName('name')
+8
src/applications/pholio/view/PholioUploadedImageView.php
··· 47 47 'style' => 'background-image: url('.$file->getThumb280x210URI().');', 48 48 )); 49 49 50 + $handle = javelin_tag( 51 + 'div', 52 + array( 53 + 'class' => 'pholio-drag-handle', 54 + 'sigil' => 'pholio-drag-handle', 55 + )); 56 + 50 57 $content = hsprintf( 51 58 '<div class="pholio-thumb-box"> 52 59 <div class="pholio-thumb-title"> ··· 92 99 ), 93 100 ), 94 101 array( 102 + $handle, 95 103 $content, 96 104 $input, 97 105 $replaces_input,
+21 -1
webroot/rsrc/css/application/pholio/pholio-edit.css
··· 3 3 */ 4 4 5 5 .pholio-uploaded-image { 6 + position: relative; 6 7 overflow: hidden; 7 8 8 9 /* When we activate the image control to show that we're going to replace ··· 21 22 border-radius: 3px; 22 23 width: 296px; 23 24 overflow: hidden; 25 + } 26 + 27 + .device-desktop .pholio-thumb-box { 28 + /* Provide room for the draggable grip. */ 29 + margin-left: 12px; 24 30 } 25 31 26 32 .device .pholio-thumb-box { ··· 59 65 } 60 66 61 67 .pholio-image-details { 62 - margin-left: 312px; 68 + margin-left: 324px; 63 69 } 64 70 65 71 .device .pholio-image-details { ··· 129 135 .pholio-drop-undo a { 130 136 font-weight: bold; 131 137 } 138 + 139 + .pholio-drag-handle { 140 + position: absolute; 141 + height: 100%; 142 + width: 12px; 143 + cursor: move; 144 + background-image: url(/rsrc/image/texture/grip.png); 145 + background-position: center center; 146 + background-repeat: no-repeat; 147 + } 148 + 149 + .device .pholio-drag-handle { 150 + display: none; 151 + }
+33 -1
webroot/rsrc/js/application/pholio/behavior-pholio-mock-edit.js
··· 6 6 * javelin-workflow 7 7 * phabricator-phtize 8 8 * phabricator-drag-and-drop-file-upload 9 + * phabricator-draggable-list 9 10 */ 10 11 JX.behavior('pholio-mock-edit', function(config) { 11 12 var pht = JX.phtize(config.pht); 12 13 13 14 var nodes = { 14 15 list: JX.$(config.listID), 15 - drop: JX.$(config.dropID) 16 + drop: JX.$(config.dropID), 17 + order: JX.$(config.orderID) 16 18 }; 17 19 18 20 var uploading = []; ··· 37 39 38 40 JX.DOM.replace(node, undo); 39 41 }); 42 + 43 + 44 + /* -( Reordering Images )-------------------------------------------------- */ 45 + 46 + 47 + var draglist = new JX.DraggableList('pholio-drop-image', nodes.list) 48 + .setGhostNode(JX.$N('div', {className: 'drag-ghost'})) 49 + .setFindItemsHandler(function() { 50 + return JX.DOM.scry(nodes.list, 'div', 'pholio-drop-image'); 51 + }); 52 + 53 + // Only let the user drag images by the handle, not the whole entry. 54 + draglist.listen('shouldBeginDrag', function(e) { 55 + if (!e.getNode('pholio-drag-handle')) { 56 + JX.Stratcom.context().prevent(); 57 + } 58 + }); 59 + 60 + // Reflect the display order in a hidden input. 61 + var synchronize_order = function() { 62 + var items = draglist.findItems(); 63 + var order = []; 64 + for (var ii = 0; ii < items.length; ii++) { 65 + order.push(JX.Stratcom.getData(items[ii]).filePHID); 66 + } 67 + nodes.order.value = order.join(','); 68 + }; 69 + 70 + draglist.listen('didDrop', synchronize_order); 71 + synchronize_order(); 40 72 41 73 42 74 /* -( Build )-------------------------------------------------------------- */
+6 -1
webroot/rsrc/js/core/DraggableList.js
··· 63 63 return this._ghostNode; 64 64 }, 65 65 66 + setGhostNode : function(node) { 67 + this._ghostNode = node; 68 + return this; 69 + }, 70 + 66 71 _defaultGhostHandler : function(ghost, target) { 67 72 var parent = this._dragging.parentNode; 68 73 if (target && target.nextSibling) { ··· 124 129 this._target = null; 125 130 126 131 if (!this.invoke('didBeginDrag', this._dragging).getPrevented()) { 127 - var ghost = this.getGhostNode(); 132 + var ghost = this.getGhostNode(); 128 133 ghost.style.height = JX.Vector.getDim(this._dragging).y + 'px'; 129 134 JX.DOM.alterClass(this._dragging, 'drag-dragging', true); 130 135 }