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

When updating a workboard with "R", send the client visible set with version numbers

Summary:
Depends on D20652. Ref T4900. When the user presses "R", send a list of cards currently visible on the client and their version numbers.

On the server:

- Compare the client verisons to the server versions so we can skip updates for objects which have not changed. (For now, the client version is always "1" and the server version is always "2", so this doesn't do anything meaningful, and every card is always updated.)
- Compare the client visible set to the server visible set and "remove" any cards which have been removed from the board.

I believe this means that "R" always puts the board into the right state (except for some issues with client orderings not being fully handled yet). It's not tremendously efficient, but we can make versioning better (using the largest object transaction ID) to improve that and loading the page in the first place doesn't take all that long so even sending down the full visible set shouldn't be a huge problem.

Test Plan:
- In window A, removed a card from a board.
- In window B, pressed "R" and saw the removal reflected on the client.
- (Also added cards, edited cards, etc., and didn't catch anything exploding.)

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T4900

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

+69 -22
+19 -19
resources/celerity/map.php
··· 412 412 'rsrc/js/application/phortune/phortune-credit-card-form.js' => 'd12d214f', 413 413 'rsrc/js/application/policy/behavior-policy-control.js' => '0eaa33a9', 414 414 'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '9347f172', 415 - 'rsrc/js/application/projects/WorkboardBoard.js' => '46573d65', 415 + 'rsrc/js/application/projects/WorkboardBoard.js' => '50147a89', 416 416 'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8', 417 - 'rsrc/js/application/projects/WorkboardCardTemplate.js' => '2a61f8d4', 417 + 'rsrc/js/application/projects/WorkboardCardTemplate.js' => '84f82dad', 418 418 'rsrc/js/application/projects/WorkboardColumn.js' => 'c3d24e63', 419 419 'rsrc/js/application/projects/WorkboardController.js' => 'b9d0c2f3', 420 420 'rsrc/js/application/projects/WorkboardDropEffect.js' => '8e0aa661', ··· 743 743 'javelin-view-renderer' => '9aae2b66', 744 744 'javelin-view-visitor' => '308f9fe4', 745 745 'javelin-websocket' => 'fdc13e4e', 746 - 'javelin-workboard-board' => '46573d65', 746 + 'javelin-workboard-board' => '50147a89', 747 747 'javelin-workboard-card' => '0392a5d8', 748 - 'javelin-workboard-card-template' => '2a61f8d4', 748 + 'javelin-workboard-card-template' => '84f82dad', 749 749 'javelin-workboard-column' => 'c3d24e63', 750 750 'javelin-workboard-controller' => 'b9d0c2f3', 751 751 'javelin-workboard-drop-effect' => '8e0aa661', ··· 1133 1133 'javelin-stratcom', 1134 1134 'javelin-behavior', 1135 1135 ), 1136 - '2a61f8d4' => array( 1137 - 'javelin-install', 1138 - ), 1139 1136 '2a8b62d9' => array( 1140 1137 'multirow-row-manager', 1141 1138 'javelin-install', ··· 1292 1289 'javelin-util', 1293 1290 'phabricator-busy', 1294 1291 ), 1295 - '46573d65' => array( 1296 - 'javelin-install', 1297 - 'javelin-dom', 1298 - 'javelin-util', 1299 - 'javelin-stratcom', 1300 - 'javelin-workflow', 1301 - 'phabricator-draggable-list', 1302 - 'javelin-workboard-column', 1303 - 'javelin-workboard-header-template', 1304 - 'javelin-workboard-card-template', 1305 - 'javelin-workboard-order-template', 1306 - ), 1307 1292 '47a0728b' => array( 1308 1293 'javelin-behavior', 1309 1294 'javelin-dom', ··· 1371 1356 ), 1372 1357 '4feea7d3' => array( 1373 1358 'trigger-rule-control', 1359 + ), 1360 + '50147a89' => array( 1361 + 'javelin-install', 1362 + 'javelin-dom', 1363 + 'javelin-util', 1364 + 'javelin-stratcom', 1365 + 'javelin-workflow', 1366 + 'phabricator-draggable-list', 1367 + 'javelin-workboard-column', 1368 + 'javelin-workboard-header-template', 1369 + 'javelin-workboard-card-template', 1370 + 'javelin-workboard-order-template', 1374 1371 ), 1375 1372 '506aa3f4' => array( 1376 1373 'javelin-behavior', ··· 1618 1615 'javelin-dom', 1619 1616 'javelin-resource', 1620 1617 'javelin-routable', 1618 + ), 1619 + '84f82dad' => array( 1620 + 'javelin-install', 1621 1621 ), 1622 1622 '87428eb2' => array( 1623 1623 'javelin-behavior',
+31 -2
src/applications/project/controller/PhabricatorProjectBoardReloadController.php
··· 20 20 $board_phid = $project->getPHID(); 21 21 22 22 $objects = $state->getObjects(); 23 - $object_phids = mpull($objects, 'getPHID'); 23 + $objects = mpull($objects, null, 'getPHID'); 24 + 25 + try { 26 + $client_state = $request->getStr('state'); 27 + $client_state = phutil_json_decode($client_state); 28 + } catch (PhutilJSONParserException $ex) { 29 + $client_state = array(); 30 + } 31 + 32 + // Figure out which objects need to be updated: either the client has an 33 + // out-of-date version of them (objects which have been edited); or they 34 + // exist on the client but not on the server (objects which have been 35 + // removed from the board); or they exist on the server but not on the 36 + // client (objects which have been added to the board). 37 + 38 + $update_objects = array(); 39 + foreach ($objects as $object_phid => $object) { 40 + 41 + // TODO: For now, this is always hard-coded. 42 + $object_version = 2; 43 + 44 + $client_version = idx($client_state, $object_phid, 0); 45 + if ($object_version > $client_version) { 46 + $update_objects[$object_phid] = $object; 47 + } 48 + } 49 + 50 + $update_phids = array_keys($update_objects); 51 + $visible_phids = array_keys($client_state); 24 52 25 53 $engine = id(new PhabricatorBoardResponseEngine()) 26 54 ->setViewer($viewer) 27 55 ->setBoardPHID($board_phid) 28 56 ->setObjects($objects) 29 - ->setUpdatePHIDs($object_phids); 57 + ->setUpdatePHIDs($update_phids) 58 + ->setVisiblePHIDs($visible_phids); 30 59 31 60 // TODO: We don't currently process "order" properly. If a user is viewing 32 61 // a board grouped by "Owner", and another user changes a task to be owned
+14 -1
webroot/rsrc/js/application/projects/WorkboardBoard.js
··· 734 734 }, 735 735 736 736 _reloadCards: function() { 737 - var data = {}; 737 + var state = {}; 738 + 739 + var columns = this.getColumns(); 740 + for (var column_phid in columns) { 741 + var cards = columns[column_phid].getCards(); 742 + for (var card_phid in cards) { 743 + state[card_phid] = this.getCardTemplate(card_phid).getVersion(); 744 + } 745 + } 746 + 747 + var data = { 748 + state: JX.JSON.stringify(state), 749 + }; 750 + 738 751 var on_reload = JX.bind(this, this._onReloadResponse); 739 752 740 753 new JX.Request(this.getController().getReloadURI(), on_reload)
+5
webroot/rsrc/js/application/projects/WorkboardCardTemplate.js
··· 28 28 return this._phid; 29 29 }, 30 30 31 + getVersion: function() { 32 + // TODO: For now, just return a constant version number. 33 + return 1; 34 + }, 35 + 31 36 setNodeHTMLTemplate: function(html) { 32 37 this._html = html; 33 38 return this;