Page MenuHomePhabricator

D19167.diff
No OneTemporary

D19167.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -78,7 +78,7 @@
'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 @@
'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 @@
'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 @@
'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 @@
'185bbd53' => array(
'javelin-install',
),
+ '191b4909' => array(
+ 'javelin-behavior',
+ ),
'1ad0a787' => array(
'javelin-install',
'javelin-reactor',
@@ -1765,9 +1768,6 @@
'javelin-util',
'phabricator-prefab',
),
- 'ab1173d1' => array(
- 'javelin-behavior',
- ),
'ab2f381b' => array(
'javelin-request',
'javelin-behavior',
diff --git a/src/applications/harbormaster/controller/HarbormasterBuildLogRenderController.php b/src/applications/harbormaster/controller/HarbormasterBuildLogRenderController.php
--- a/src/applications/harbormaster/controller/HarbormasterBuildLogRenderController.php
+++ b/src/applications/harbormaster/controller/HarbormasterBuildLogRenderController.php
@@ -720,12 +720,16 @@
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 @@
$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 @@
array(
'class' => 'harbormaster-log-follow',
),
- $follow),
+ array(
+ $follow,
+ $stop_following,
+ )),
);
return $this->renderActionTable($expand_cells);
diff --git a/webroot/rsrc/css/application/harbormaster/harbormaster.css b/webroot/rsrc/css/application/harbormaster/harbormaster.css
--- a/webroot/rsrc/css/application/harbormaster/harbormaster.css
+++ b/webroot/rsrc/css/application/harbormaster/harbormaster.css
@@ -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;
+ }
+}
diff --git a/webroot/rsrc/js/application/harbormaster/behavior-harbormaster-log.js b/webroot/rsrc/js/application/harbormaster/behavior-harbormaster-log.js
--- a/webroot/rsrc/js/application/harbormaster/behavior-harbormaster-log.js
+++ b/webroot/rsrc/js/application/harbormaster/behavior-harbormaster-log.js
@@ -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 @@
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 @@
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);
-
- setTimeout(follow, 500);
+ 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);
+
+ // 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;

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 26, 3:09 AM (20 h, 26 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6787870
Default Alt Text
D19167.diff (7 KB)

Event Timeline