FIX: Dock the timeline if you scroll down too much
This commit is contained in:
parent
96b2fb791e
commit
fa2bffd618
|
@ -30,7 +30,7 @@ export default MountWidget.extend({
|
||||||
_currentPost: -1,
|
_currentPost: -1,
|
||||||
_currentVisible: null,
|
_currentVisible: null,
|
||||||
|
|
||||||
args: Ember.computed(function() {
|
buildArgs() {
|
||||||
return this.getProperties('posts',
|
return this.getProperties('posts',
|
||||||
'canCreatePost',
|
'canCreatePost',
|
||||||
'multiSelect',
|
'multiSelect',
|
||||||
|
@ -38,7 +38,7 @@ export default MountWidget.extend({
|
||||||
'selectedQuery',
|
'selectedQuery',
|
||||||
'selectedPostsCount',
|
'selectedPostsCount',
|
||||||
'searchService');
|
'searchService');
|
||||||
}).volatile(),
|
},
|
||||||
|
|
||||||
beforePatch() {
|
beforePatch() {
|
||||||
const $body = $(document);
|
const $body = $(document);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import MountWidget from 'discourse/components/mount-widget';
|
import MountWidget from 'discourse/components/mount-widget';
|
||||||
import { observes } from 'ember-addons/ember-computed-decorators';
|
import { observes } from 'ember-addons/ember-computed-decorators';
|
||||||
|
import Docking from 'discourse/mixins/docking';
|
||||||
|
|
||||||
const _flagProperties = [];
|
const _flagProperties = [];
|
||||||
function addFlagProperty(prop) {
|
function addFlagProperty(prop) {
|
||||||
|
@ -8,45 +9,37 @@ function addFlagProperty(prop) {
|
||||||
|
|
||||||
const PANEL_BODY_MARGIN = 30;
|
const PANEL_BODY_MARGIN = 30;
|
||||||
|
|
||||||
const SiteHeaderComponent = MountWidget.extend({
|
const SiteHeaderComponent = MountWidget.extend(Docking, {
|
||||||
widget: 'header',
|
widget: 'header',
|
||||||
docAt: null,
|
docAt: null,
|
||||||
dockedHeader: null,
|
dockedHeader: null,
|
||||||
_topic: null,
|
_topic: null,
|
||||||
|
|
||||||
// profileWidget: true,
|
|
||||||
// classNameBindings: ['editingTopic'],
|
|
||||||
|
|
||||||
@observes('currentUser.unread_notifications', 'currentUser.unread_private_messages')
|
@observes('currentUser.unread_notifications', 'currentUser.unread_private_messages')
|
||||||
_notificationsChanged() {
|
_notificationsChanged() {
|
||||||
this.queueRerender();
|
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');
|
const $body = $('body');
|
||||||
|
const offset = info.offset();
|
||||||
// Check the dock after the current run loop. While rendering,
|
if (offset >= this.docAt) {
|
||||||
// it's much slower to calculate `outlet.offset()`
|
if (!this.dockedHeader) {
|
||||||
Ember.run.next(() => {
|
$body.addClass('docked');
|
||||||
if (this.docAt === null) {
|
this.dockedHeader = true;
|
||||||
const outlet = $('#main-outlet');
|
|
||||||
if (!(outlet && outlet.length === 1)) return;
|
|
||||||
this.docAt = outlet.offset().top;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
const offset = window.pageYOffset || $('html').scrollTop();
|
if (this.dockedHeader) {
|
||||||
if (offset >= this.docAt) {
|
$body.removeClass('docked');
|
||||||
if (!this.dockedHeader) {
|
this.dockedHeader = false;
|
||||||
$body.addClass('docked');
|
|
||||||
this.dockedHeader = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.dockedHeader) {
|
|
||||||
$body.removeClass('docked');
|
|
||||||
this.dockedHeader = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setTopic(topic) {
|
setTopic(topic) {
|
||||||
|
@ -56,8 +49,6 @@ const SiteHeaderComponent = MountWidget.extend({
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this._super();
|
this._super();
|
||||||
$(window).bind('scroll.discourse-dock', () => this.examineDockHeader());
|
|
||||||
$(document).bind('touchmove.discourse-dock', () => this.examineDockHeader());
|
|
||||||
$(window).on('resize.discourse-menu-panel', () => this.afterRender());
|
$(window).on('resize.discourse-menu-panel', () => this.afterRender());
|
||||||
|
|
||||||
this.appEvents.on('header:show-topic', topic => this.setTopic(topic));
|
this.appEvents.on('header:show-topic', topic => this.setTopic(topic));
|
||||||
|
@ -72,16 +63,13 @@ const SiteHeaderComponent = MountWidget.extend({
|
||||||
this.eventDispatched('dom:clean', 'header');
|
this.eventDispatched('dom:clean', 'header');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.examineDockHeader();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
this._super();
|
this._super();
|
||||||
$(window).unbind('scroll.discourse-dock');
|
|
||||||
$(document).unbind('touchmove.discourse-dock');
|
|
||||||
$('body').off('keydown.header');
|
$('body').off('keydown.header');
|
||||||
this.appEvents.off('notifications:changed');
|
this.appEvents.off('notifications:changed');
|
||||||
|
this.appEvents.off('header:keyboard-trigger');
|
||||||
$(window).off('resize.discourse-menu-panel');
|
$(window).off('resize.discourse-menu-panel');
|
||||||
|
|
||||||
this.appEvents.off('header:show-topic');
|
this.appEvents.off('header:show-topic');
|
||||||
|
|
|
@ -1,16 +1,43 @@
|
||||||
import MountWidget from 'discourse/components/mount-widget';
|
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({
|
export default MountWidget.extend(Docking, {
|
||||||
widget: 'topic-timeline',
|
widget: 'topic-timeline-container',
|
||||||
|
dockAt: null,
|
||||||
|
|
||||||
@computed('topic')
|
buildArgs() {
|
||||||
args(topic) {
|
return { topic: this.get('topic'),
|
||||||
return { topic, topicTrackingState: this.topicTrackingState };
|
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() {
|
didInsertElement() {
|
||||||
this._super();
|
this._super();
|
||||||
this.dispatch('topic:current-post-changed', 'timeline-scrollarea');
|
this.dispatch('topic:current-post-changed', 'timeline-scrollarea');
|
||||||
|
},
|
||||||
|
|
||||||
|
willDestroyElement() {
|
||||||
|
this._super();
|
||||||
|
this.appEvents.off('topic:current-post-changed');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
|
@ -72,13 +72,11 @@
|
||||||
<div class="posts-wrapper">
|
<div class="posts-wrapper">
|
||||||
|
|
||||||
{{#if showTimeline}}
|
{{#if showTimeline}}
|
||||||
<div class='fixed-gutter'>
|
{{topic-timeline topic=model
|
||||||
{{topic-timeline topic=model
|
jumpTop="jumpTop"
|
||||||
jumpTop="jumpTop"
|
jumpToPost="jumpToPost"
|
||||||
jumpToPost="jumpToPost"
|
jumpBottom="jumpBottom"
|
||||||
jumpBottom="jumpBottom"
|
replyToPost="replyToPost"}}
|
||||||
replyToPost="replyToPost"}}
|
|
||||||
</div>
|
|
||||||
{{else}}
|
{{else}}
|
||||||
{{topic-progress topic=model
|
{{topic-progress topic=model
|
||||||
jumpTop="jumpTop"
|
jumpTop="jumpTop"
|
||||||
|
|
|
@ -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', {
|
export default createWidget('topic-timeline', {
|
||||||
tagName: 'div.topic-timeline',
|
tagName: 'div.topic-timeline',
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,16 @@
|
||||||
width: 900px;
|
width: 900px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fixed-gutter {
|
.timeline-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
margin-left: 757px;
|
margin-left: 757px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 140px;
|
|
||||||
|
&.timeline-docked {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
.topic-timeline {
|
.topic-timeline {
|
||||||
margin-left: 3em;
|
margin-left: 3em;
|
||||||
|
|
Loading…
Reference in New Issue