mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 16:22:43 +01:00
Improve live Harbormaster log follow behaviors
Summary: Depends on D19166. Ref T13088. When the user scrolls away from a followed log, break the focus lock. Let users stop following a live log. Show when lines are added more clearly. Don't refresh quite as quickly give users a better shot at clicking the stop button. These behaviors can probably be refined but are at least more plausible and less actively user-hostile than the first version of this behavior was. Test Plan: Used `write-log --rate` to write a large log slowly. Clicked "Follow Log", followed for a bit. Scrolled away, still got live updates but no more scroll lock. Clicked stop, no more updates. Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam Maniphest Tasks: T13088 Differential Revision: https://secure.phabricator.com/D19167
This commit is contained in:
parent
4e91ad276d
commit
1f40e50f7e
4 changed files with 93 additions and 18 deletions
|
@ -78,7 +78,7 @@ return array(
|
|||
'rsrc/css/application/feed/feed.css' => 'ecd4ec57',
|
||||
'rsrc/css/application/files/global-drag-and-drop.css' => 'b556a948',
|
||||
'rsrc/css/application/flag/flag.css' => 'bba8f811',
|
||||
'rsrc/css/application/harbormaster/harbormaster.css' => 'cd73d427',
|
||||
'rsrc/css/application/harbormaster/harbormaster.css' => '730a4a3c',
|
||||
'rsrc/css/application/herald/herald-test.css' => 'a52e323e',
|
||||
'rsrc/css/application/herald/herald.css' => 'cd8d0134',
|
||||
'rsrc/css/application/maniphest/report.css' => '9b9580b7',
|
||||
|
@ -416,7 +416,7 @@ return array(
|
|||
'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef',
|
||||
'rsrc/js/application/files/behavior-icon-composer.js' => '8499b6ab',
|
||||
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
|
||||
'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => 'ab1173d1',
|
||||
'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => '191b4909',
|
||||
'rsrc/js/application/herald/HeraldRuleEditor.js' => 'dca75c0e',
|
||||
'rsrc/js/application/herald/PathTypeahead.js' => 'f7fc67ec',
|
||||
'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3',
|
||||
|
@ -579,7 +579,7 @@ return array(
|
|||
'font-fontawesome' => 'e838e088',
|
||||
'font-lato' => 'c7ccd872',
|
||||
'global-drag-and-drop-css' => 'b556a948',
|
||||
'harbormaster-css' => 'cd73d427',
|
||||
'harbormaster-css' => '730a4a3c',
|
||||
'herald-css' => 'cd8d0134',
|
||||
'herald-rule-editor' => 'dca75c0e',
|
||||
'herald-test-css' => 'a52e323e',
|
||||
|
@ -636,7 +636,7 @@ return array(
|
|||
'javelin-behavior-event-all-day' => 'b41537c9',
|
||||
'javelin-behavior-fancy-datepicker' => 'ecf4e799',
|
||||
'javelin-behavior-global-drag-and-drop' => '960f6a39',
|
||||
'javelin-behavior-harbormaster-log' => 'ab1173d1',
|
||||
'javelin-behavior-harbormaster-log' => '191b4909',
|
||||
'javelin-behavior-herald-rule-editor' => '7ebaeed3',
|
||||
'javelin-behavior-high-security-warning' => 'a464fe03',
|
||||
'javelin-behavior-history-install' => '7ee2b591',
|
||||
|
@ -1022,6 +1022,9 @@ return array(
|
|||
'185bbd53' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
'191b4909' => array(
|
||||
'javelin-behavior',
|
||||
),
|
||||
'1ad0a787' => array(
|
||||
'javelin-install',
|
||||
'javelin-reactor',
|
||||
|
@ -1765,9 +1768,6 @@ return array(
|
|||
'javelin-util',
|
||||
'phabricator-prefab',
|
||||
),
|
||||
'ab1173d1' => array(
|
||||
'javelin-behavior',
|
||||
),
|
||||
'ab2f381b' => array(
|
||||
'javelin-request',
|
||||
'javelin-behavior',
|
||||
|
|
|
@ -720,12 +720,16 @@ final class HarbormasterBuildLogRenderController
|
|||
|
||||
private function renderLiveRow($log_size) {
|
||||
$icon_down = id(new PHUIIconView())
|
||||
->setIcon('fa-chevron-down');
|
||||
->setIcon('fa-angle-double-down');
|
||||
|
||||
$icon_pause = id(new PHUIIconView())
|
||||
->setIcon('fa-pause');
|
||||
|
||||
$follow = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'sigil' => 'harbormaster-log-expand harbormaster-log-live',
|
||||
'class' => 'harbormaster-log-follow-start',
|
||||
'meta' => array(
|
||||
'headOffset' => $log_size,
|
||||
'head' => 0,
|
||||
|
@ -737,8 +741,21 @@ final class HarbormasterBuildLogRenderController
|
|||
$icon_down,
|
||||
' ',
|
||||
pht('Follow Log'),
|
||||
));
|
||||
|
||||
$stop_following = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'sigil' => 'harbormaster-log-expand',
|
||||
'class' => 'harbormaster-log-follow-stop',
|
||||
'meta' => array(
|
||||
'stop' => true,
|
||||
),
|
||||
),
|
||||
array(
|
||||
$icon_pause,
|
||||
' ',
|
||||
$icon_down,
|
||||
pht('Stop Following Log'),
|
||||
));
|
||||
|
||||
$expand_cells = array(
|
||||
|
@ -747,7 +764,10 @@ final class HarbormasterBuildLogRenderController
|
|||
array(
|
||||
'class' => 'harbormaster-log-follow',
|
||||
),
|
||||
$follow),
|
||||
array(
|
||||
$follow,
|
||||
$stop_following,
|
||||
)),
|
||||
);
|
||||
|
||||
return $this->renderActionTable($expand_cells);
|
||||
|
|
|
@ -139,3 +139,31 @@
|
|||
.harbormaster-log-expand-down .phui-icon-view {
|
||||
margin: 0 4px 0 0;
|
||||
}
|
||||
|
||||
|
||||
.harbormaster-log-following .harbormaster-log-table
|
||||
.harbormaster-log-follow-start {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.harbormaster-log-table .harbormaster-log-follow-stop {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.harbormaster-log-following .harbormaster-log-table
|
||||
.harbormaster-log-follow-stop {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.harbormaster-log-appear > td {
|
||||
animation: harbormaster-fade-in 1s linear;
|
||||
}
|
||||
|
||||
@keyframes harbormaster-fade-in {
|
||||
0% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
100% {
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
JX.behavior('harbormaster-log', function(config) {
|
||||
var contentNode = JX.$(config.contentNodeID);
|
||||
|
||||
var following = false;
|
||||
var autoscroll = false;
|
||||
|
||||
JX.DOM.listen(contentNode, 'click', 'harbormaster-log-expand', function(e) {
|
||||
if (!e.isNormalClick()) {
|
||||
|
@ -14,20 +16,29 @@ JX.behavior('harbormaster-log', function(config) {
|
|||
|
||||
e.kill();
|
||||
|
||||
expand(e.getTarget());
|
||||
expand(e.getTarget(), true);
|
||||
});
|
||||
|
||||
function expand(node) {
|
||||
function expand(node, is_action) {
|
||||
var row = JX.DOM.findAbove(node, 'tr');
|
||||
row = JX.DOM.findAbove(row, 'tr');
|
||||
|
||||
var data = JX.Stratcom.getData(node);
|
||||
|
||||
if (data.stop) {
|
||||
following = false;
|
||||
autoscroll = false;
|
||||
JX.DOM.alterClass(contentNode, 'harbormaster-log-following', false);
|
||||
return;
|
||||
}
|
||||
|
||||
var uri = new JX.URI(config.renderURI)
|
||||
.addQueryParams(data);
|
||||
|
||||
if (data.live) {
|
||||
if (data.live && is_action) {
|
||||
following = true;
|
||||
autoscroll = true;
|
||||
JX.DOM.alterClass(contentNode, 'harbormaster-log-following', true);
|
||||
}
|
||||
|
||||
var request = new JX.Request(uri, function(r) {
|
||||
|
@ -46,18 +57,34 @@ JX.behavior('harbormaster-log', function(config) {
|
|||
if (data.live) {
|
||||
// If this was a live follow, scroll the new data into view. This is
|
||||
// probably intensely annoying in practice but seems cool for now.
|
||||
var last_row = rows[rows.length - 1];
|
||||
var tail_pos = JX.$V(last_row).y + JX.Vector.getDim(last_row).y;
|
||||
var view_y = JX.Vector.getViewport().y;
|
||||
JX.DOM.scrollToPosition(null, (tail_pos - view_y) + 32);
|
||||
if (autoscroll) {
|
||||
var last_row = rows[rows.length - 1];
|
||||
var tail_pos = JX.$V(last_row).y + JX.Vector.getDim(last_row).y;
|
||||
var view_y = JX.Vector.getViewport().y;
|
||||
JX.DOM.scrollToPosition(null, (tail_pos - view_y) + 32);
|
||||
|
||||
setTimeout(follow, 500);
|
||||
// This will fire a scroll event, but we want to keep autoscroll
|
||||
// enabled until we see an explicit scroll event by the user.
|
||||
setTimeout(function() { autoscroll = true; }, 0);
|
||||
}
|
||||
|
||||
setTimeout(follow, 2000);
|
||||
|
||||
for (var ii = 1; ii < (rows.length - 1); ii++) {
|
||||
JX.DOM.alterClass(rows[ii], 'harbormaster-log-appear', true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
request.send();
|
||||
}
|
||||
|
||||
// If the user explicitly scrolls while following a log, keep live updating
|
||||
// it but stop following it with the scrollbar.
|
||||
JX.Stratcom.listen('scroll', null, function() {
|
||||
autoscroll = false;
|
||||
});
|
||||
|
||||
function follow() {
|
||||
if (!following) {
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue