@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.

Replace height buffer behavior while dragging on workboards with infinite column height

Summary:
Ref T4900. The root problem is that dragging stuff near the bottom of the board can cause jittery, jumpy behaviors.

Internal scrolling has changed the nature of this problem. Previously, the height of the board itself would jump around, but it's now fixed so the height of columns jumps around instead.

We could take the same approach and add a chunk to the bottom of each column when a drag starts, but this is really distracting visually since it's obvious to the user.

Instead, treat columns as infinitely tall (so dragging beneath them still counts as dragging to the bottom position).

Test Plan:
- View a board with a column taller than the screen (has a scrollbar).
- Drag a card to near the bottom position.
- Move the mouse down a little bit at a time, continuing toward the bottom of the page.
- Before patch: at some point, UI flips out and starts rapidly adding, scrolling, and removing the ghost.
- After patch: sensible behavior, ghost is in bottom position for all cursor locations.

Also works for dragging to the top.

(This leaves us with a little less dead space for cancelling drags, but you've still got the left menu, anything offscreen, and the escape key, which seems fine.)

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4900

Differential Revision: https://secure.phabricator.com/D15227

+50 -77
+36 -36
resources/celerity/map.php
··· 8 8 return array( 9 9 'names' => array( 10 10 'core.pkg.css' => 'e8763436', 11 - 'core.pkg.js' => '17380dd3', 11 + 'core.pkg.js' => 'd7daa6d8', 12 12 'darkconsole.pkg.js' => 'e7393ebb', 13 13 'differential.pkg.css' => '2de124c9', 14 14 'differential.pkg.js' => 'd0cd0df6', ··· 415 415 'rsrc/js/application/phortune/phortune-credit-card-form.js' => '2290aeef', 416 416 'rsrc/js/application/policy/behavior-policy-control.js' => 'd0c516d5', 417 417 'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '5e9f347c', 418 - 'rsrc/js/application/projects/Workboard.js' => 'b38d2c73', 419 - 'rsrc/js/application/projects/behavior-project-boards.js' => '7f4359dd', 418 + 'rsrc/js/application/projects/Workboard.js' => 'fa8ab410', 419 + 'rsrc/js/application/projects/behavior-project-boards.js' => '7784bfc6', 420 420 'rsrc/js/application/projects/behavior-project-create.js' => '065227cc', 421 421 'rsrc/js/application/projects/behavior-reorder-columns.js' => 'e1d25dfb', 422 422 'rsrc/js/application/releeph/releeph-preview-branch.js' => 'b2b4fbaf', ··· 449 449 'rsrc/js/application/uiexample/notification-example.js' => '8ce821c5', 450 450 'rsrc/js/core/Busy.js' => '59a7976a', 451 451 'rsrc/js/core/DragAndDropFileUpload.js' => '81f182b5', 452 - 'rsrc/js/core/DraggableList.js' => '705df8d1', 452 + 'rsrc/js/core/DraggableList.js' => '5a13c79f', 453 453 'rsrc/js/core/FileUpload.js' => '680ea2c8', 454 454 'rsrc/js/core/Hovercard.js' => '1bd28176', 455 455 'rsrc/js/core/KeyboardShortcut.js' => '1ae869f2', ··· 656 656 'javelin-behavior-phui-profile-menu' => '12884df9', 657 657 'javelin-behavior-policy-control' => 'd0c516d5', 658 658 'javelin-behavior-policy-rule-editor' => '5e9f347c', 659 - 'javelin-behavior-project-boards' => '7f4359dd', 659 + 'javelin-behavior-project-boards' => '7784bfc6', 660 660 'javelin-behavior-project-create' => '065227cc', 661 661 'javelin-behavior-quicksand-blacklist' => '7927a7d3', 662 662 'javelin-behavior-recurring-edit' => '5f1c4d5f', ··· 723 723 'javelin-view-renderer' => '6c2b09a2', 724 724 'javelin-view-visitor' => 'efe49472', 725 725 'javelin-websocket' => 'e292eaf4', 726 - 'javelin-workboard' => 'b38d2c73', 726 + 'javelin-workboard' => 'fa8ab410', 727 727 'javelin-workflow' => '5b2e3e2b', 728 728 'lightbox-attachment-css' => '7acac05d', 729 729 'maniphest-batch-editor' => 'b0f0b6d5', ··· 745 745 'phabricator-countdown-css' => 'e7544472', 746 746 'phabricator-dashboard-css' => 'eb458607', 747 747 'phabricator-drag-and-drop-file-upload' => '81f182b5', 748 - 'phabricator-draggable-list' => '705df8d1', 748 + 'phabricator-draggable-list' => '5a13c79f', 749 749 'phabricator-fatal-config-template-css' => '8e6c6fcd', 750 750 'phabricator-feed-css' => 'ecd4ec57', 751 751 'phabricator-file-upload' => '680ea2c8', ··· 1255 1255 'javelin-dom', 1256 1256 'javelin-stratcom', 1257 1257 ), 1258 + '5a13c79f' => array( 1259 + 'javelin-install', 1260 + 'javelin-dom', 1261 + 'javelin-stratcom', 1262 + 'javelin-util', 1263 + 'javelin-vector', 1264 + 'javelin-magical-init', 1265 + ), 1258 1266 '5b2e3e2b' => array( 1259 1267 'javelin-stratcom', 1260 1268 'javelin-request', ··· 1356 1364 'javelin-typeahead', 1357 1365 'javelin-uri', 1358 1366 ), 1359 - '705df8d1' => array( 1360 - 'javelin-install', 1361 - 'javelin-dom', 1362 - 'javelin-stratcom', 1363 - 'javelin-util', 1364 - 'javelin-vector', 1365 - 'javelin-magical-init', 1366 - ), 1367 1367 '70baed2f' => array( 1368 1368 'javelin-install', 1369 1369 'javelin-dom', ··· 1407 1407 'javelin-reactor', 1408 1408 'javelin-util', 1409 1409 ), 1410 + '7784bfc6' => array( 1411 + 'javelin-behavior', 1412 + 'javelin-dom', 1413 + 'javelin-util', 1414 + 'javelin-vector', 1415 + 'javelin-stratcom', 1416 + 'javelin-workflow', 1417 + 'phabricator-draggable-list', 1418 + 'phabricator-drag-and-drop-file-upload', 1419 + 'javelin-workboard', 1420 + ), 1410 1421 '782ab6e7' => array( 1411 1422 'javelin-behavior', 1412 1423 'javelin-dom', ··· 1445 1456 '7ee2b591' => array( 1446 1457 'javelin-behavior', 1447 1458 'javelin-history', 1448 - ), 1449 - '7f4359dd' => array( 1450 - 'javelin-behavior', 1451 - 'javelin-dom', 1452 - 'javelin-util', 1453 - 'javelin-vector', 1454 - 'javelin-stratcom', 1455 - 'javelin-workflow', 1456 - 'phabricator-draggable-list', 1457 - 'phabricator-drag-and-drop-file-upload', 1458 - 'javelin-workboard', 1459 1459 ), 1460 1460 '805b806a' => array( 1461 1461 'javelin-magical-init', ··· 1716 1716 'javelin-dom', 1717 1717 'javelin-uri', 1718 1718 'javelin-request', 1719 - ), 1720 - 'b38d2c73' => array( 1721 - 'javelin-install', 1722 - 'javelin-dom', 1723 - 'javelin-util', 1724 - 'javelin-vector', 1725 - 'javelin-stratcom', 1726 - 'javelin-workflow', 1727 - 'phabricator-draggable-list', 1728 - 'phabricator-drag-and-drop-file-upload', 1729 1719 ), 1730 1720 'b3a4b884' => array( 1731 1721 'javelin-behavior', ··· 2087 2077 'javelin-dom', 2088 2078 'javelin-vector', 2089 2079 'javelin-magical-init', 2080 + ), 2081 + 'fa8ab410' => array( 2082 + 'javelin-install', 2083 + 'javelin-dom', 2084 + 'javelin-util', 2085 + 'javelin-vector', 2086 + 'javelin-stratcom', 2087 + 'javelin-workflow', 2088 + 'phabricator-draggable-list', 2089 + 'phabricator-drag-and-drop-file-upload', 2090 2090 ), 2091 2091 'fb20ac8d' => array( 2092 2092 'javelin-behavior',
+2 -5
webroot/rsrc/js/application/projects/Workboard.js
··· 140 140 var list = new JX.DraggableList('project-card', column) 141 141 .setOuterContainer(board_node) 142 142 .setFindItemsHandler(JX.bind(this, this._findCardsInColumn, column)) 143 - .setCanDragX(true); 143 + .setCanDragX(true) 144 + .setHasInfiniteHeight(true); 144 145 145 146 // TODO: Restore these behaviors. 146 147 // list.listen('didSend', JX.bind(list, onupdate, cols[ii])); ··· 148 149 // onupdate(cols[ii]); 149 150 150 151 list.listen('didDrop', JX.bind(this, this._onmovecard, list)); 151 - 152 - // TODO: Restore these behaviors. 153 - // list.listen('didBeginDrag', JX.bind(null, onbegindrag)); 154 - // list.listen('didEndDrag', JX.bind(null, onenddrag)); 155 152 156 153 lists.push(list); 157 154 }
-35
webroot/rsrc/js/application/projects/behavior-project-boards.js
··· 79 79 return 0; 80 80 } 81 81 82 - function getcontainer() { 83 - return JX.DOM.find( 84 - JX.$(statics.boardID), 85 - 'div', 86 - 'aphront-multi-column-view'); 87 - } 88 - 89 - function onbegindrag(item) { 90 - // If the longest column on the board is taller than the window, the board 91 - // will scroll vertically. Dragging an item to the longest column may 92 - // make it longer, by the total height of the board, plus the height of 93 - // the drop target. 94 - 95 - // If this happens, the scrollbar will jump around and the scroll position 96 - // can be adjusted in a disorienting way. To reproduce this, drag a task 97 - // to the bottom of the longest column on a scrolling board and wave the 98 - // task in and out of the column. The scroll bar will jump around and 99 - // it will be hard to lock onto a target. 100 - 101 - // To fix this, set the minimum board height to the current board height 102 - // plus the size of the drop target (which is the size of the item plus 103 - // a bit of margin). This makes sure the scroll bar never needs to 104 - // recalculate. 105 - 106 - var item_size = JX.Vector.getDim(item); 107 - var container = getcontainer(); 108 - var container_size = JX.Vector.getDim(container); 109 - 110 - container.style.minHeight = (item_size.y + container_size.y + 12) + 'px'; 111 - } 112 - 113 - function onenddrag() { 114 - getcontainer().style.minHeight = ''; 115 - } 116 - 117 82 function onedit(column, r) { 118 83 var new_card = JX.$H(r.tasks).getNode(); 119 84 var new_data = JX.Stratcom.getData(new_card);
+12 -1
webroot/rsrc/js/core/DraggableList.js
··· 40 40 properties : { 41 41 findItemsHandler: null, 42 42 canDragX: false, 43 - outerContainer: null 43 + outerContainer: null, 44 + hasInfiniteHeight: false 44 45 }, 45 46 46 47 members : { ··· 286 287 287 288 _getTargetList : function(p) { 288 289 var target_list; 290 + var infinity; 289 291 if (this._hasGroup()) { 290 292 var group = this._group; 291 293 for (var ii = 0; ii < group.length; ii++) { 292 294 var root = group[ii].getRootNode(); 293 295 var rp = JX.$V(root); 294 296 var rd = JX.Vector.getDim(root); 297 + 298 + if (group[ii].getHasInfiniteHeight()) { 299 + // The math doesn't work out quite right if we actually use 300 + // Math.Infinity, so approximate infinity as the document height. 301 + infinity = infinity || JX.Vector.getDocument().y; 302 + 303 + rp.y = 0; 304 + rd.y = infinity; 305 + } 295 306 296 307 var is_target = false; 297 308 if (p.x >= rp.x && p.y >= rp.y) {