diff --git a/app/assets/javascripts/job.js b/app/assets/javascripts/job.js index 8dfe8aae5b5..83c38173a1c 100644 --- a/app/assets/javascripts/job.js +++ b/app/assets/javascripts/job.js @@ -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()); diff --git a/app/assets/javascripts/lib/utils/logoutput_behaviours.js b/app/assets/javascripts/lib/utils/logoutput_behaviours.js new file mode 100644 index 00000000000..1bf99d935ef --- /dev/null +++ b/app/assets/javascripts/lib/utils/logoutput_behaviours.js @@ -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); + } +} diff --git a/app/assets/javascripts/lib/utils/scroll_utils.js b/app/assets/javascripts/lib/utils/scroll_utils.js new file mode 100644 index 00000000000..b31a8c38550 --- /dev/null +++ b/app/assets/javascripts/lib/utils/scroll_utils.js @@ -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 {};