diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -9,11 +9,11 @@ 'names' => array( 'conpherence.pkg.css' => 'e68cf1fa', 'conpherence.pkg.js' => '15191c65', - 'core.pkg.css' => 'ce8c2a58', - 'core.pkg.js' => '4c79d74f', + 'core.pkg.css' => 'e4f098a5', + 'core.pkg.js' => '3ac6e174', 'darkconsole.pkg.js' => '1f9a31bc', - 'differential.pkg.css' => '1522c3ad', - 'differential.pkg.js' => '19ee9979', + 'differential.pkg.css' => '113e692c', + 'differential.pkg.js' => '5d53d5ce', 'diffusion.pkg.css' => 'a2d17c7d', 'diffusion.pkg.js' => '6134c5a1', 'favicon.ico' => '30672e08', @@ -31,7 +31,7 @@ 'rsrc/css/aphront/multi-column.css' => '84cc6640', 'rsrc/css/aphront/notification.css' => '457861ec', 'rsrc/css/aphront/panel-view.css' => '8427b78d', - 'rsrc/css/aphront/phabricator-nav-view.css' => 'faf6a6fc', + 'rsrc/css/aphront/phabricator-nav-view.css' => '028126f6', 'rsrc/css/aphront/table-view.css' => '8c9bbafe', 'rsrc/css/aphront/tokenizer.css' => '15d5ff71', 'rsrc/css/aphront/tooltip.css' => '173b9431', @@ -121,7 +121,7 @@ 'rsrc/css/font/font-awesome.css' => 'e838e088', 'rsrc/css/font/font-lato.css' => 'c7ccd872', 'rsrc/css/font/phui-font-icon-base.css' => '870a7360', - 'rsrc/css/layout/phabricator-filetree-view.css' => 'ea5b30a9', + 'rsrc/css/layout/phabricator-filetree-view.css' => 'b912ad97', 'rsrc/css/layout/phabricator-source-code-view.css' => 'aea41829', 'rsrc/css/phui/button/phui-button-bar.css' => 'f1ff5494', 'rsrc/css/phui/button/phui-button-simple.css' => '8e1baf68', @@ -395,8 +395,8 @@ 'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => '408bf173', 'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375', 'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63', - 'rsrc/js/application/diff/DiffChangeset.js' => '99abf4cd', - 'rsrc/js/application/diff/DiffChangesetList.js' => '3b77efdd', + 'rsrc/js/application/diff/DiffChangeset.js' => 'b49b59d6', + 'rsrc/js/application/diff/DiffChangesetList.js' => '1f2e5265', 'rsrc/js/application/diff/DiffInline.js' => 'e83d28f3', 'rsrc/js/application/diff/behavior-preview-link.js' => '051c7832', 'rsrc/js/application/differential/behavior-comment-preview.js' => '51c5ad07', @@ -498,7 +498,7 @@ 'rsrc/js/core/behavior-more.js' => 'a80d0378', 'rsrc/js/core/behavior-object-selector.js' => '77c1f0b0', 'rsrc/js/core/behavior-oncopy.js' => '2926fff2', - 'rsrc/js/core/behavior-phabricator-nav.js' => '947753e0', + 'rsrc/js/core/behavior-phabricator-nav.js' => '81144dfa', 'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'acd29eee', 'rsrc/js/core/behavior-read-only-warning.js' => 'ba158207', 'rsrc/js/core/behavior-refresh-csrf.js' => 'ab2f381b', @@ -657,7 +657,7 @@ 'javelin-behavior-phabricator-keyboard-pager' => 'a8da01f0', 'javelin-behavior-phabricator-keyboard-shortcuts' => '01fca1f0', 'javelin-behavior-phabricator-line-linker' => '1499a8cb', - 'javelin-behavior-phabricator-nav' => '947753e0', + 'javelin-behavior-phabricator-nav' => '81144dfa', 'javelin-behavior-phabricator-notification-example' => '8ce821c5', 'javelin-behavior-phabricator-object-selector' => '77c1f0b0', 'javelin-behavior-phabricator-oncopy' => '2926fff2', @@ -775,8 +775,8 @@ 'phabricator-darklog' => 'c8e1ffe3', 'phabricator-darkmessage' => 'c48cccdd', 'phabricator-dashboard-css' => 'fe5b1869', - 'phabricator-diff-changeset' => '99abf4cd', - 'phabricator-diff-changeset-list' => '3b77efdd', + 'phabricator-diff-changeset' => 'b49b59d6', + 'phabricator-diff-changeset-list' => '1f2e5265', 'phabricator-diff-inline' => 'e83d28f3', 'phabricator-drag-and-drop-file-upload' => '58dea2fa', 'phabricator-draggable-list' => 'bea6e7f4', @@ -784,12 +784,12 @@ 'phabricator-favicon' => '1fe2510c', 'phabricator-feed-css' => 'ecd4ec57', 'phabricator-file-upload' => '680ea2c8', - 'phabricator-filetree-view-css' => 'ea5b30a9', + 'phabricator-filetree-view-css' => 'b912ad97', 'phabricator-flag-css' => 'bba8f811', 'phabricator-keyboard-shortcut' => '1ae869f2', 'phabricator-keyboard-shortcut-manager' => 'c19dd9b9', 'phabricator-main-menu-view' => '1802a242', - 'phabricator-nav-view-css' => 'faf6a6fc', + 'phabricator-nav-view-css' => '028126f6', 'phabricator-notification' => '008faf9c', 'phabricator-notification-css' => '457861ec', 'phabricator-notification-menu-css' => '10685bd4', @@ -1044,6 +1044,10 @@ 'javelin-uri', 'javelin-routable', ), + '1f2e5265' => array( + 'javelin-install', + 'phuix-button-view', + ), '1f6794f6' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1143,10 +1147,6 @@ 'javelin-dom', 'javelin-magical-init', ), - '3b77efdd' => array( - 'javelin-install', - 'phuix-button-view', - ), '3cb0b2fc' => array( 'javelin-behavior', 'javelin-dom', @@ -1561,6 +1561,16 @@ '7f243deb' => array( 'javelin-install', ), + '81144dfa' => array( + 'javelin-behavior', + 'javelin-behavior-device', + 'javelin-stratcom', + 'javelin-dom', + 'javelin-magical-init', + 'javelin-vector', + 'javelin-request', + 'javelin-util', + ), '834a1173' => array( 'javelin-behavior', 'javelin-scrollbar', @@ -1648,16 +1658,6 @@ 'javelin-workflow', 'javelin-dom', ), - '947753e0' => array( - 'javelin-behavior', - 'javelin-behavior-device', - 'javelin-stratcom', - 'javelin-dom', - 'javelin-magical-init', - 'javelin-vector', - 'javelin-request', - 'javelin-util', - ), '949c0fe5' => array( 'javelin-install', ), @@ -1678,17 +1678,6 @@ 'javelin-mask', 'phabricator-drag-and-drop-file-upload', ), - '99abf4cd' => array( - 'javelin-dom', - 'javelin-util', - 'javelin-stratcom', - 'javelin-install', - 'javelin-workflow', - 'javelin-router', - 'javelin-behavior-device', - 'javelin-vector', - 'phabricator-diff-inline', - ), '9a6dd75c' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1837,6 +1826,17 @@ 'b3e7d692' => array( 'javelin-install', ), + 'b49b59d6' => array( + 'javelin-dom', + 'javelin-util', + 'javelin-stratcom', + 'javelin-install', + 'javelin-workflow', + 'javelin-router', + 'javelin-behavior-device', + 'javelin-vector', + 'phabricator-diff-inline', + ), 'b59e1e96' => array( 'javelin-behavior', 'javelin-stratcom', diff --git a/src/applications/differential/view/DifferentialChangesetDetailView.php b/src/applications/differential/view/DifferentialChangesetDetailView.php --- a/src/applications/differential/view/DifferentialChangesetDetailView.php +++ b/src/applications/differential/view/DifferentialChangesetDetailView.php @@ -206,6 +206,7 @@ 'displayPath' => hsprintf('%s', $display_parts), 'path' => $display_filename, 'icon' => $display_icon, + 'treeNodeID' => 'tree-node-'.$changeset->getAnchorName(), ), 'class' => $class, 'id' => $id, diff --git a/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php b/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php --- a/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php +++ b/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php @@ -96,11 +96,20 @@ $icon = $data->newFileTreeIcon(); $classes[] = $data->getFileTreeClass(); + + $count = phutil_tag( + 'span', + array( + 'class' => 'filetree-progress-hint', + 'id' => 'tree-node-'.$data->getAnchorName(), + )); } else { $name .= '/'; $title = $path->getFullPath().'/'; $icon = id(new PHUIIconView()) ->setIcon('fa-folder-open blue'); + + $count = null; } $name_element = phutil_tag( @@ -110,6 +119,7 @@ ), $name); + $filetree[] = javelin_tag( $href ? 'a' : 'span', array( @@ -118,7 +128,7 @@ 'title' => $title, 'class' => implode(' ', $classes), ), - array($icon, $name_element)); + array($count, $icon, $name_element)); } $tree->destroy(); diff --git a/webroot/rsrc/css/aphront/phabricator-nav-view.css b/webroot/rsrc/css/aphront/phabricator-nav-view.css --- a/webroot/rsrc/css/aphront/phabricator-nav-view.css +++ b/webroot/rsrc/css/aphront/phabricator-nav-view.css @@ -44,7 +44,7 @@ position: fixed; top: 0; bottom: 0; - left: 205px; + left: 410px; width: 7px; cursor: col-resize; @@ -66,7 +66,7 @@ .device-desktop .phabricator-standard-page-body .has-drag-nav .phabricator-nav-content { - margin-left: 212px; + margin-left: 417px; } .device-desktop .phabricator-standard-page-body .has-drag-nav @@ -81,7 +81,7 @@ } .device-desktop .phui-navigation-shell .has-drag-nav .phabricator-nav-local { - width: 205px; + width: 410px; padding: 0; background: transparent; } diff --git a/webroot/rsrc/css/layout/phabricator-filetree-view.css b/webroot/rsrc/css/layout/phabricator-filetree-view.css --- a/webroot/rsrc/css/layout/phabricator-filetree-view.css +++ b/webroot/rsrc/css/layout/phabricator-filetree-view.css @@ -50,11 +50,6 @@ background-color: {$hovergrey}; } -.phabricator-filetree .phabricator-active-nav-focus { - background-color: {$hovergrey}; - border-left: 4px solid {$sky}; -} - .phabricator-filetree .filetree-added { background: {$sh-greenbackground}; } @@ -66,3 +61,31 @@ .phabricator-filetree .filetree-movecopy { background: {$sh-orangebackground}; } + +.phabricator-filetree .phabricator-active-nav-focus { + background-color: {$hovergrey}; + border-left: 4px solid {$sky}; +} + +.phabricator-filetree .filetree-progress-hint { + width: 24px; + margin-right: 6px; + display: inline-block; + padding: 0 4px; + border-radius: 4px; + font-size: smaller; + background: {$greybackground}; + text-align: center; + opacity: 0.5; +} + +.phabricator-filetree .filetree-comments-visible { + background: {$lightblue}; + opacity: 0.75; + color: {$darkgreytext}; +} + +.phabricator-filetree .filetree-comments-completed { + background: {$darkgreybackground}; + color: {$greytext}; +} diff --git a/webroot/rsrc/js/application/diff/DiffChangeset.js b/webroot/rsrc/js/application/diff/DiffChangeset.js --- a/webroot/rsrc/js/application/diff/DiffChangeset.js +++ b/webroot/rsrc/js/application/diff/DiffChangeset.js @@ -27,6 +27,7 @@ this._highlight = data.highlight; this._encoding = data.encoding; this._loaded = data.loaded; + this._treeNodeID = data.treeNodeID; this._leftID = data.left; this._rightID = data.right; @@ -62,6 +63,7 @@ _changesetList: null, _icon: null, + _treeNodeID: null, getLeftChangesetID: function() { return this._leftID; @@ -737,7 +739,8 @@ _rebuildAllInlines: function() { var rows = JX.DOM.scry(this._node, 'tr'); - for (var ii = 0; ii < rows.length; ii++) { + var ii; + for (ii = 0; ii < rows.length; ii++) { var row = rows[ii]; if (this._getRowType(row) != 'comment') { continue; @@ -749,6 +752,75 @@ } }, + redrawFileTree: function() { + var tree; + try { + tree = JX.$(this._treeNodeID); + } catch (e) { + return; + } + + var inlines = this._inlines; + var done = []; + var undone = []; + var inline; + + for (var ii = 0; ii < inlines.length; ii++) { + inline = inlines[ii]; + + if (inline.isDeleted()) { + continue; + } + + if (inline.isSynthetic()) { + continue; + } + + if (inline.isEditing()) { + continue; + } + + if (!inline.getID()) { + // These are new comments which have been cancelled, and do not + // count as anything. + continue; + } + + if (inline.isDraft()) { + continue; + } + + if (!inline.isDone()) { + undone.push(inline); + } else { + done.push(inline); + } + } + + var total = done.length + undone.length; + + var hint; + var is_visible; + var is_completed; + if (total) { + if (done.length) { + hint = [done.length, '/', total]; + } else { + hint = total; + } + is_visible = true; + is_completed = (done.length == total); + } else { + hint = '-'; + is_visible = false; + is_completed = false; + } + + JX.DOM.setContent(tree, hint); + JX.DOM.alterClass(tree, 'filetree-comments-visible', is_visible); + JX.DOM.alterClass(tree, 'filetree-comments-completed', is_completed); + }, + toggleVisibility: function() { this._visible = !this._visible; diff --git a/webroot/rsrc/js/application/diff/DiffChangesetList.js b/webroot/rsrc/js/application/diff/DiffChangesetList.js --- a/webroot/rsrc/js/application/diff/DiffChangesetList.js +++ b/webroot/rsrc/js/application/diff/DiffChangesetList.js @@ -915,6 +915,11 @@ this._bannerChangeset = null; this._redrawBanner(); + + var changesets = this._changesets; + for (var ii = 0; ii < changesets.length; ii++) { + changesets[ii].redrawFileTree(); + } }, _onscroll: function() { diff --git a/webroot/rsrc/js/core/behavior-phabricator-nav.js b/webroot/rsrc/js/core/behavior-phabricator-nav.js --- a/webroot/rsrc/js/core/behavior-phabricator-nav.js +++ b/webroot/rsrc/js/core/behavior-phabricator-nav.js @@ -28,6 +28,10 @@ JX.enableDispatch(document.body, 'mousemove'); JX.DOM.listen(drag, 'mousedown', null, function(e) { + if (!e.isNormalMouseEvent()) { + return; + } + dragging = JX.$V(e); // Show the "col-resize" cursor on the whole document while we're