Backport scroll utilities for the job log component
This commit is contained in:
parent
c640e57924
commit
43e08b1a38
3 changed files with 81 additions and 73 deletions
|
@ -6,9 +6,12 @@ import { visitUrl } from './lib/utils/url_utility';
|
|||
import bp from './breakpoints';
|
||||
import { numberToHumanSize } from './lib/utils/number_utils';
|
||||
import { setCiStatusFavicon } from './lib/utils/common_utils';
|
||||
import { isScrolledToBottom, scrollDown } from './lib/utils/scroll_utils';
|
||||
import LogOutputBehaviours from './lib/utils/logoutput_behaviours';
|
||||
|
||||
export default class Job {
|
||||
export default class Job extends LogOutputBehaviours {
|
||||
constructor(options) {
|
||||
super();
|
||||
this.timeout = null;
|
||||
this.state = null;
|
||||
this.fetchingStatusFavicon = false;
|
||||
|
@ -48,23 +51,14 @@ export default class Job {
|
|||
.off('click', '.stage-item')
|
||||
.on('click', '.stage-item', this.updateDropdown);
|
||||
|
||||
// add event listeners to the scroll buttons
|
||||
this.$scrollTopBtn
|
||||
.off('click')
|
||||
.on('click', this.scrollToTop.bind(this));
|
||||
|
||||
this.$scrollBottomBtn
|
||||
.off('click')
|
||||
.on('click', this.scrollToBottom.bind(this));
|
||||
|
||||
this.scrollThrottled = _.throttle(this.toggleScroll.bind(this), 100);
|
||||
|
||||
this.$window
|
||||
.off('scroll')
|
||||
.on('scroll', () => {
|
||||
if (!this.isScrolledToBottom()) {
|
||||
if (!isScrolledToBottom()) {
|
||||
this.toggleScrollAnimation(false);
|
||||
} else if (this.isScrolledToBottom() && !this.isLogComplete) {
|
||||
} else if (isScrolledToBottom() && !this.isLogComplete) {
|
||||
this.toggleScrollAnimation(true);
|
||||
}
|
||||
this.scrollThrottled();
|
||||
|
@ -83,60 +77,8 @@ export default class Job {
|
|||
StickyFill.add(this.$topBar);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
canScroll() {
|
||||
return $(document).height() > $(window).height();
|
||||
}
|
||||
|
||||
toggleScroll() {
|
||||
const $document = $(document);
|
||||
const currentPosition = $document.scrollTop();
|
||||
const scrollHeight = $document.height();
|
||||
|
||||
const windowHeight = $(window).height();
|
||||
if (this.canScroll()) {
|
||||
if (currentPosition > 0 &&
|
||||
(scrollHeight - currentPosition !== windowHeight)) {
|
||||
// User is in the middle of the log
|
||||
|
||||
this.toggleDisableButton(this.$scrollTopBtn, false);
|
||||
this.toggleDisableButton(this.$scrollBottomBtn, false);
|
||||
} else if (currentPosition === 0) {
|
||||
// User is at Top of Log
|
||||
|
||||
this.toggleDisableButton(this.$scrollTopBtn, true);
|
||||
this.toggleDisableButton(this.$scrollBottomBtn, false);
|
||||
} else if (this.isScrolledToBottom()) {
|
||||
// User is at the bottom of the build log.
|
||||
|
||||
this.toggleDisableButton(this.$scrollTopBtn, false);
|
||||
this.toggleDisableButton(this.$scrollBottomBtn, true);
|
||||
}
|
||||
} else {
|
||||
this.toggleDisableButton(this.$scrollTopBtn, true);
|
||||
this.toggleDisableButton(this.$scrollBottomBtn, true);
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
isScrolledToBottom() {
|
||||
const $document = $(document);
|
||||
|
||||
const currentPosition = $document.scrollTop();
|
||||
const scrollHeight = $document.height();
|
||||
|
||||
const windowHeight = $(window).height();
|
||||
|
||||
return scrollHeight - currentPosition === windowHeight;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
scrollDown() {
|
||||
const $document = $(document);
|
||||
$document.scrollTop($document.height());
|
||||
}
|
||||
|
||||
scrollToBottom() {
|
||||
this.scrollDown();
|
||||
scrollDown();
|
||||
this.hasBeenScrolled = true;
|
||||
this.toggleScroll();
|
||||
}
|
||||
|
@ -147,12 +89,6 @@ export default class Job {
|
|||
this.toggleScroll();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
toggleDisableButton($button, disable) {
|
||||
if (disable && $button.prop('disabled')) return;
|
||||
$button.prop('disabled', disable);
|
||||
}
|
||||
|
||||
toggleScrollAnimation(toggle) {
|
||||
this.$scrollBottomBtn.toggleClass('animate', toggle);
|
||||
}
|
||||
|
@ -184,7 +120,7 @@ export default class Job {
|
|||
this.state = log.state;
|
||||
}
|
||||
|
||||
this.isScrollInBottom = this.isScrolledToBottom();
|
||||
this.isScrollInBottom = isScrolledToBottom();
|
||||
|
||||
if (log.append) {
|
||||
this.$buildTraceOutput.append(log.html);
|
||||
|
@ -224,7 +160,7 @@ export default class Job {
|
|||
})
|
||||
.then(() => {
|
||||
if (this.isScrollInBottom) {
|
||||
this.scrollDown();
|
||||
scrollDown();
|
||||
}
|
||||
})
|
||||
.then(() => this.toggleScroll());
|
||||
|
|
46
app/assets/javascripts/lib/utils/logoutput_behaviours.js
Normal file
46
app/assets/javascripts/lib/utils/logoutput_behaviours.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
import $ from 'jquery';
|
||||
import { canScroll, isScrolledToBottom, toggleDisableButton } from './scroll_utils';
|
||||
|
||||
export default class LogOutputBehaviours {
|
||||
constructor() {
|
||||
// Scroll buttons
|
||||
this.$scrollTopBtn = $('.js-scroll-up');
|
||||
this.$scrollBottomBtn = $('.js-scroll-down');
|
||||
|
||||
this.$scrollTopBtn.off('click').on('click', this.scrollToTop.bind(this));
|
||||
this.$scrollBottomBtn.off('click').on('click', this.scrollToBottom.bind(this));
|
||||
}
|
||||
|
||||
toggleScroll() {
|
||||
const $document = $(document);
|
||||
const currentPosition = $document.scrollTop();
|
||||
const scrollHeight = $document.height();
|
||||
|
||||
const windowHeight = $(window).height();
|
||||
if (canScroll()) {
|
||||
if (currentPosition > 0 && scrollHeight - currentPosition !== windowHeight) {
|
||||
// User is in the middle of the log
|
||||
|
||||
toggleDisableButton(this.$scrollTopBtn, false);
|
||||
toggleDisableButton(this.$scrollBottomBtn, false);
|
||||
} else if (currentPosition === 0) {
|
||||
// User is at Top of Log
|
||||
|
||||
toggleDisableButton(this.$scrollTopBtn, true);
|
||||
toggleDisableButton(this.$scrollBottomBtn, false);
|
||||
} else if (isScrolledToBottom()) {
|
||||
// User is at the bottom of the build log.
|
||||
|
||||
toggleDisableButton(this.$scrollTopBtn, false);
|
||||
toggleDisableButton(this.$scrollBottomBtn, true);
|
||||
}
|
||||
} else {
|
||||
toggleDisableButton(this.$scrollTopBtn, true);
|
||||
toggleDisableButton(this.$scrollBottomBtn, true);
|
||||
}
|
||||
}
|
||||
|
||||
toggleScrollAnimation(toggle) {
|
||||
this.$scrollBottomBtn.toggleClass('animate', toggle);
|
||||
}
|
||||
}
|
26
app/assets/javascripts/lib/utils/scroll_utils.js
Normal file
26
app/assets/javascripts/lib/utils/scroll_utils.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import $ from 'jquery';
|
||||
|
||||
export const canScroll = () => $(document).height() > $(window).height();
|
||||
|
||||
export const isScrolledToBottom = () => {
|
||||
const $document = $(document);
|
||||
|
||||
const currentPosition = $document.scrollTop();
|
||||
const scrollHeight = $document.height();
|
||||
|
||||
const windowHeight = $(window).height();
|
||||
|
||||
return scrollHeight - currentPosition === windowHeight;
|
||||
};
|
||||
|
||||
export const scrollDown = () => {
|
||||
const $document = $(document);
|
||||
$document.scrollTop($document.height());
|
||||
};
|
||||
|
||||
export const toggleDisableButton = ($button, disable) => {
|
||||
if (disable && $button.prop('disabled')) return;
|
||||
$button.prop('disabled', disable);
|
||||
};
|
||||
|
||||
export default {};
|
Loading…
Reference in a new issue