Commit f1f45d4a authored by Kushal Pandya's avatar Kushal Pandya

Improve isInViewport impl, autoscroll behavior

- Improve isInViewport impementation to be robust.
- Autoscroll is now a status indicator instead of toggle button
- Scrolling build log enables autoscroll itself when scrolled to bottom.
parent 07174514
...@@ -10,24 +10,16 @@ ...@@ -10,24 +10,16 @@
Build.state = null; Build.state = null;
function isInViewPort(el) { function isInViewport(el) {
var elTop = el.offset().top; // Courtesy http://stackoverflow.com/a/7557433/414749
var elBottom = elTop + el.outerHeight(); var rect = el[0].getBoundingClientRect();
var vpBottom = $(window).scrollTop() + $(window).height();
return (
return vpBottom > elTop; rect.top >= 0 &&
} rect.left >= 0 &&
rect.bottom <= $(window).height() &&
function toggleAutoScroll(state) { rect.right <= $(window).width()
var $autoScrollBtn = $('#autoscroll-button'); );
if (state) {
$autoScrollBtn.data("state", "enabled");
$autoScrollBtn.text("Disable autoscroll");
} else {
$autoScrollBtn.data("state", "disabled");
$autoScrollBtn.text("Enable autoscroll");
}
} }
function Build(options) { function Build(options) {
...@@ -52,6 +44,7 @@ ...@@ -52,6 +44,7 @@
this.$document.off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.sidebarOnClick.bind(this)); this.$document.off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.sidebarOnClick.bind(this));
this.$document.off('click', '.stage-item').on('click', '.stage-item', this.updateDropdown); this.$document.off('click', '.stage-item').on('click', '.stage-item', this.updateDropdown);
this.$document.on('scroll', this.initScrollMonitor.bind(this));
$(window).off('resize.build').on('resize.build', this.sidebarOnResize.bind(this)); $(window).off('resize.build').on('resize.build', this.sidebarOnResize.bind(this));
$('a', this.$buildScroll).off('click.stepTrace').on('click.stepTrace', this.stepTrace); $('a', this.$buildScroll).off('click.stepTrace').on('click.stepTrace', this.stepTrace);
this.updateArtifactRemoveDate(); this.updateArtifactRemoveDate();
...@@ -60,26 +53,6 @@ ...@@ -60,26 +53,6 @@
this.initScrollButtonAffix(); this.initScrollButtonAffix();
} }
if (this.buildStatus === "running" || this.buildStatus === "pending") { if (this.buildStatus === "running" || this.buildStatus === "pending") {
// Bind document scroll listener to detect if user has scrolled to page bottom
// and enable autoscroll of build log, disable autoscroll otherwise
this.$document.on('scroll', function() {
var $autoScrollBtn = $('#autoscroll-button');
if (isInViewPort($('.js-build-refresh'))) { // Check if Refresh Animation is in Viewport
if ($autoScrollBtn.data("state") === 'disabled') {
toggleAutoScroll(true); // Enable Autoscroll
}
} else {
if ($autoScrollBtn.data("state") === 'enabled') {
toggleAutoScroll(false); // Disable Autoscroll
}
}
});
// Bind autoscroll button to follow build output
$('#autoscroll-button').on('click', function() {
toggleAutoScroll($(this).data("state") === 'disabled');
});
Build.interval = setInterval((function(_this) { Build.interval = setInterval((function(_this) {
// Check for new build output if user still watching build page // Check for new build output if user still watching build page
// Only valid for runnig build when output changes during time // Only valid for runnig build when output changes during time
...@@ -150,22 +123,85 @@ ...@@ -150,22 +123,85 @@
}; };
Build.prototype.checkAutoscroll = function() { Build.prototype.checkAutoscroll = function() {
if ("enabled" === $("#autoscroll-button").data("state")) { if ("enabled" === $("#autoscroll-status").data("state")) {
return $("html,body").scrollTop($("#build-trace").height()); return $("html,body").scrollTop($("#build-trace").height());
} }
}; };
Build.prototype.initScrollButtonAffix = function() { Build.prototype.initScrollButtonAffix = function() {
var $body, $buildTrace; var $body = $('body');
$body = $('body'); var $buildTrace = $('#build-trace');
$buildTrace = $('#build-trace'); var $scrollTopBtn = $('#scroll-top');
return this.$buildScroll.affix({ var $scrollBottomBtn = $('#scroll-bottom');
offset: { var $autoScrollContainer = $('.autoscroll-container');
bottom: function() {
return $body.outerHeight() - ($buildTrace.outerHeight() + $buildTrace.offset().top); $scrollTopBtn.hide().removeClass('sticky');
$scrollBottomBtn.show().addClass('sticky');
if ($autoScrollContainer.length) {
$scrollBottomBtn.hide();
$autoScrollContainer.show().css({ bottom: 50 });
}
}
// Page scroll listener to detect if user has scrolling page
// and handle following cases
// 1) User is at Top of Build Log;
// - Hide Top Arrow button
// - Show Bottom Arrow button
// - Disable Autoscroll and hide indicator (when build is running)
// 2) User is at Bottom of Build Log;
// - Show Top Arrow button
// - Hide Bottom Arrow button
// - Enable Autoscroll and show indicator (when build is running)
// 3) User is somewhere in middle of Build Log;
// - Show Top Arrow button
// - Show Bottom Arrow button
// - Disable Autoscroll and hide indicator (when build is running)
Build.prototype.initScrollMonitor = function() {
var $body = $('body');
var $buildTrace = $('#build-trace');
var $autoScrollContainer = $('.autoscroll-container');
var $autoScrollStatus = $('#autoscroll-status');
var $upBuildTrace = $('#up-build-trace');
var $downBuildTrace = $('#down-build-trace');
var $scrollTopBtn = $('#scroll-top');
var $scrollBottomBtn = $('#scroll-bottom');
if (isInViewport($upBuildTrace)) { // User is at Top of Build Log
$scrollTopBtn.hide().removeClass('sticky');
$scrollBottomBtn.show().addClass('sticky');
}
if (isInViewport($downBuildTrace)) { // User is at Bottom of Build Log
$scrollTopBtn.show().addClass('sticky');
$scrollBottomBtn.hide().removeClass('sticky');
if ($autoScrollContainer.length) { // Show and Reposition Autoscroll Status Message
$autoScrollContainer.show().css({ top: $body.outerHeight() - 75 });
}
}
if (!isInViewport($upBuildTrace) && !isInViewport($downBuildTrace)) { // User is somewhere in middle of Build Log
$scrollTopBtn.show().addClass('sticky');
$scrollBottomBtn.show().addClass('sticky');
if ($autoScrollContainer.length) {
$autoScrollContainer.hide();
}
}
if (this.buildStatus === "running" || this.buildStatus === "pending") {
if (isInViewport($('.js-build-refresh'))) { // Check if Refresh Animation is in Viewport
if ($autoScrollStatus.data("state") === 'disabled') {
$autoScrollStatus.data("state", 'enabled'); // Enable Autoscroll
}
} else {
if ($autoScrollStatus.data("state") === 'enabled') {
$autoScrollStatus.data("state", 'disabled'); // Disable Autoscroll
}
} }
} }
});
}; };
Build.prototype.shouldHideSidebarForViewport = function() { Build.prototype.shouldHideSidebarForViewport = function() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment