This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/components/topic-timeline.js.es6
Sam f4418ae884 PERF: fast docking of timeline so it does not overlap
In the past we debounced all dock check this causes situations where
sometimes timeline would not dock in time especially on slow computers

This works around it by performing the dock by hand.

Also there was missing integer casting causing over aggressive re-rendering
2018-02-22 12:52:43 +11:00

111 lines
3.2 KiB
JavaScript

import MountWidget from 'discourse/components/mount-widget';
import Docking from 'discourse/mixins/docking';
import { observes } from 'ember-addons/ember-computed-decorators';
import optionalService from 'discourse/lib/optional-service';
const headerPadding = () => parseInt($('#main-outlet').css('padding-top')) + 3;
export default MountWidget.extend(Docking, {
adminTools: optionalService(),
widget: 'topic-timeline-container',
dockBottom: null,
dockAt: null,
buildArgs() {
let attrs = {
topic: this.get('topic'),
notificationLevel: this.get('notificationLevel'),
topicTrackingState: this.topicTrackingState,
enteredIndex: this.get('enteredIndex'),
dockAt: this.dockAt,
dockBottom: this.dockBottom,
mobileView: this.get('site.mobileView')
};
let event = this.get('prevEvent');
if (event) {
attrs.enteredIndex = event.postIndex-1;
}
if (this.get('fullscreen')) {
attrs.fullScreen = true;
attrs.addShowClass = this.get('addShowClass');
} else {
attrs.top = this.dockAt || headerPadding();
}
return attrs;
},
@observes('topic.highest_post_number', 'loading')
newPostAdded() {
this.queueRerender(() => this.queueDockCheck());
},
@observes('topic.details.notification_level')
_queueRerender() {
this.queueRerender();
},
fastDockCheck(){
// we need to dock super fast here, avoid any slow methods
// this is not debounced
const offset = window.pageYOffset;
if (offset && this.fastDockAt && offset > this.fastDockAt) {
this.fastDockAt = null;
$('.timeline-container').addClass('timeline-docked timeline-docked-bottom');
}
},
dockCheck(info) {
const mainOffset = $('#main').offset();
const offsetTop = mainOffset ? mainOffset.top : 0;
const topicTop = $('.container.posts').offset().top - offsetTop;
const topicBottom = $('#topic-bottom').offset().top;
const $timeline = this.$('.timeline-container');
const timelineHeight = $timeline.height() || 400;
const footerHeight = $('.timeline-footer-controls').outerHeight(true) || 0;
const prev = this.dockAt;
const posTop = headerPadding() + info.offset();
const pos = posTop + timelineHeight;
this.dockBottom = false;
if (posTop < topicTop) {
this.dockAt = parseInt(topicTop, 10);
} else if (pos > topicBottom + footerHeight) {
this.dockAt = parseInt((topicBottom - timelineHeight) + footerHeight, 10);
this.dockBottom = true;
if (this.dockAt < 0) { this.dockAt = 0; }
} else {
this.dockAt = null;
this.fastDockAt = parseInt(topicBottom - timelineHeight + footerHeight - offsetTop, 10);
}
if (this.dockAt !== prev) {
this.queueRerender();
}
},
didInsertElement() {
this._super();
if (this.get('fullscreen') && !this.get('addShowClass')) {
Em.run.next(()=>{
this.set('addShowClass', true);
this.queueRerender();
});
}
this.dispatch('topic:current-post-scrolled', 'timeline-scrollarea');
},
showModerationHistory() {
this.get('adminTools').showModerationHistory({
filter: 'topic',
topic_id: this.get('topic.id')
});
}
});