FIX: Dock the timeline if you scroll down too much

This commit is contained in:
Robin Ward 2016-05-19 12:16:19 -04:00
parent 96b2fb791e
commit fa2bffd618
No known key found for this signature in database
GPG Key ID: 0E091E2B4ED1B83D
7 changed files with 109 additions and 49 deletions

View File

@ -30,7 +30,7 @@ export default MountWidget.extend({
_currentPost: -1,
_currentVisible: null,
args: Ember.computed(function() {
buildArgs() {
return this.getProperties('posts',
'canCreatePost',
'multiSelect',
@ -38,7 +38,7 @@ export default MountWidget.extend({
'selectedQuery',
'selectedPostsCount',
'searchService');
}).volatile(),
},
beforePatch() {
const $body = $(document);

View File

@ -1,5 +1,6 @@
import MountWidget from 'discourse/components/mount-widget';
import { observes } from 'ember-addons/ember-computed-decorators';
import Docking from 'discourse/mixins/docking';
const _flagProperties = [];
function addFlagProperty(prop) {
@ -8,45 +9,37 @@ function addFlagProperty(prop) {
const PANEL_BODY_MARGIN = 30;
const SiteHeaderComponent = MountWidget.extend({
const SiteHeaderComponent = MountWidget.extend(Docking, {
widget: 'header',
docAt: null,
dockedHeader: null,
_topic: null,
// profileWidget: true,
// classNameBindings: ['editingTopic'],
@observes('currentUser.unread_notifications', 'currentUser.unread_private_messages')
_notificationsChanged() {
this.queueRerender();
},
examineDockHeader() {
dockCheck(info) {
if (this.docAt === null) {
const outlet = $('#main-outlet');
if (!(outlet && outlet.length === 1)) return;
this.docAt = outlet.offset().top;
}
const $body = $('body');
// Check the dock after the current run loop. While rendering,
// it's much slower to calculate `outlet.offset()`
Ember.run.next(() => {
if (this.docAt === null) {
const outlet = $('#main-outlet');
if (!(outlet && outlet.length === 1)) return;
this.docAt = outlet.offset().top;
const offset = info.offset();
if (offset >= this.docAt) {
if (!this.dockedHeader) {
$body.addClass('docked');
this.dockedHeader = true;
}
const offset = window.pageYOffset || $('html').scrollTop();
if (offset >= this.docAt) {
if (!this.dockedHeader) {
$body.addClass('docked');
this.dockedHeader = true;
}
} else {
if (this.dockedHeader) {
$body.removeClass('docked');
this.dockedHeader = false;
}
} else {
if (this.dockedHeader) {
$body.removeClass('docked');
this.dockedHeader = false;
}
});
}
},
setTopic(topic) {
@ -56,8 +49,6 @@ const SiteHeaderComponent = MountWidget.extend({
didInsertElement() {
this._super();
$(window).bind('scroll.discourse-dock', () => this.examineDockHeader());
$(document).bind('touchmove.discourse-dock', () => this.examineDockHeader());
$(window).on('resize.discourse-menu-panel', () => this.afterRender());
this.appEvents.on('header:show-topic', topic => this.setTopic(topic));
@ -72,16 +63,13 @@ const SiteHeaderComponent = MountWidget.extend({
this.eventDispatched('dom:clean', 'header');
}
});
this.examineDockHeader();
},
willDestroyElement() {
this._super();
$(window).unbind('scroll.discourse-dock');
$(document).unbind('touchmove.discourse-dock');
$('body').off('keydown.header');
this.appEvents.off('notifications:changed');
this.appEvents.off('header:keyboard-trigger');
$(window).off('resize.discourse-menu-panel');
this.appEvents.off('header:show-topic');

View File

@ -1,16 +1,43 @@
import MountWidget from 'discourse/components/mount-widget';
import computed from 'ember-addons/ember-computed-decorators';
import Docking from 'discourse/mixins/docking';
export default MountWidget.extend({
widget: 'topic-timeline',
export default MountWidget.extend(Docking, {
widget: 'topic-timeline-container',
dockAt: null,
@computed('topic')
args(topic) {
return { topic, topicTrackingState: this.topicTrackingState };
buildArgs() {
return { topic: this.get('topic'),
topicTrackingState: this.topicTrackingState,
dockAt: this.dockAt };
},
dockCheck(info) {
const topicBottom = $('#topic-bottom').offset().top;
const $timeline = this.$('.timeline-container');
const timelineHeight = $timeline.height();
const tTop = 140;
const prev = this.dockAt;
const pos = tTop + info.offset() + timelineHeight;
if (pos > topicBottom) {
this.dockAt = topicBottom - timelineHeight - $timeline.offsetParent().offset().top;
} else {
this.dockAt = null;
}
if (this.dockAt !== prev) {
this.queueRerender();
}
},
didInsertElement() {
this._super();
this.dispatch('topic:current-post-changed', 'timeline-scrollarea');
},
willDestroyElement() {
this._super();
this.appEvents.off('topic:current-post-changed');
}
});

View File

@ -0,0 +1,25 @@
const helper = {
offset: () => window.pageYOffset || $('html').scrollTop()
};
export default Ember.Mixin.create({
_dockHandler: null,
didInsertElement() {
this._super();
// Check the dock after the current run loop since reading sizes is slow
this._dockHandler = () => Ember.run.next(() => this.dockCheck(helper));
$(window).bind('scroll.discourse-dock', this._dockHandler);
$(document).bind('touchmove.discourse-dock', this._dockHandler);
this._dockHandler();
},
willDestroyElement() {
this._super();
$(window).unbind('scroll.discourse-dock', this._dockHandler);
$(document).unbind('touchmove.discourse-dock', this._dockHandler);
}
});

View File

@ -72,13 +72,11 @@
<div class="posts-wrapper">
{{#if showTimeline}}
<div class='fixed-gutter'>
{{topic-timeline topic=model
jumpTop="jumpTop"
jumpToPost="jumpToPost"
jumpBottom="jumpBottom"
replyToPost="replyToPost"}}
</div>
{{topic-timeline topic=model
jumpTop="jumpTop"
jumpToPost="jumpToPost"
jumpBottom="jumpBottom"
replyToPost="replyToPost"}}
{{else}}
{{topic-progress topic=model
jumpTop="jumpTop"

View File

@ -169,6 +169,25 @@ createWidget('timeline-scrollarea', {
}
});
createWidget('topic-timeline-container', {
tagName: 'div.timeline-container',
buildClasses(attrs) {
if (attrs.dockAt) { return 'timeline-docked'; }
},
buildAttributes(attrs) {
if (attrs.dockAt) {
return { style: `top: ${attrs.dockAt}px` };
};
return { style: 'top: 140px' };
},
html(attrs) {
return this.attach('topic-timeline', attrs);
}
});
export default createWidget('topic-timeline', {
tagName: 'div.topic-timeline',

View File

@ -2,13 +2,16 @@
width: 900px;
}
.fixed-gutter {
.timeline-container {
width: 100%;
box-sizing: border-box;
z-index: 1;
margin-left: 757px;
position: fixed;
top: 140px;
&.timeline-docked {
position: absolute;
}
.topic-timeline {
margin-left: 3em;