1
0
Fork 0
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:
epriestley 2018-03-01 10:43:28 -08:00
parent 4e91ad276d
commit 1f40e50f7e
4 changed files with 93 additions and 18 deletions

View file

@ -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',

View file

@ -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);

View file

@ -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;
}
}

View file

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