mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 23:06:57 +08:00
FIX: Better handling of position when near the top or bottom
This commit is contained in:
parent
a3907e1fbb
commit
0b8a3ff5da
|
@ -88,11 +88,6 @@ export default MountWidget.extend({
|
|||
|
||||
const offset = offsetCalculator();
|
||||
const topCheck = Math.ceil(windowTop + offset);
|
||||
if (windowTop < offset) {
|
||||
currentPost = 0;
|
||||
const $post = $($posts[0]);
|
||||
percent = windowTop > 0 ? (topCheck - $post.offset().top) / $post.height() : 0;
|
||||
}
|
||||
|
||||
// uncomment to debug the eyeline
|
||||
// $('.debug-eyeline').css({ height: '1px', width: '100%', backgroundColor: 'blue', position: 'absolute', top: `${topCheck}px` });
|
||||
|
@ -106,15 +101,15 @@ export default MountWidget.extend({
|
|||
|
||||
const viewTop = $post.offset().top;
|
||||
const postHeight = $post.height();
|
||||
const viewBottom = viewTop + postHeight;
|
||||
const viewBottom = Math.ceil(viewTop + postHeight);
|
||||
|
||||
if (viewTop > viewportBottom) { break; }
|
||||
|
||||
if (viewBottom > windowTop && viewTop <= windowBottom) {
|
||||
if (viewBottom >= windowTop && viewTop <= windowBottom) {
|
||||
onscreen.push(bottomView);
|
||||
}
|
||||
|
||||
if (currentPost === null && (viewTop <= topCheck) && (viewBottom > topCheck)) {
|
||||
if (currentPost === null && (viewTop <= topCheck) && (viewBottom >= topCheck)) {
|
||||
percent = (topCheck - viewTop) / postHeight;
|
||||
currentPost = bottomView;
|
||||
}
|
||||
|
@ -163,9 +158,13 @@ export default MountWidget.extend({
|
|||
this.sendAction('currentPostChanged', { post });
|
||||
}
|
||||
|
||||
if (percent !== null && this._currentPercent !== percent) {
|
||||
this._currentPercent = percent;
|
||||
this.sendAction('currentPostScrolled', { percent });
|
||||
if (percent !== null) {
|
||||
if (percent > 1.0) { percent = 1.0; }
|
||||
|
||||
if (this._currentPercent !== percent) {
|
||||
this._currentPercent = percent;
|
||||
this.sendAction('currentPostScrolled', { percent });
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -211,7 +211,7 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
|
|||
|
||||
currentPostScrolled(event) {
|
||||
this.appEvents.trigger('topic:current-post-scrolled', {
|
||||
postNumber: this._progressIndex,
|
||||
postIndex: this._progressIndex,
|
||||
percent: event.percent
|
||||
});
|
||||
},
|
||||
|
|
|
@ -1,8 +1,26 @@
|
|||
export default function offsetCalculator() {
|
||||
const $header = $('header');
|
||||
const $title = $('#topic-title');
|
||||
const windowHeight = $(window).height() - $title.height();
|
||||
const rawWinHeight = $(window).height();
|
||||
const windowHeight = rawWinHeight - $title.height();
|
||||
const expectedOffset = $title.height() - $header.find('.contents').height() + (windowHeight / 5);
|
||||
const ideal = $header.outerHeight(true) + ((expectedOffset < 0) ? 0 : expectedOffset);
|
||||
|
||||
return $header.outerHeight(true) + ((expectedOffset < 0) ? 0 : expectedOffset);
|
||||
const $container = $('.posts-wrapper');
|
||||
const topPos = $container.offset().top;
|
||||
|
||||
const scrollTop = $(window).scrollTop();
|
||||
const docHeight = $(document).height();
|
||||
const scrollPercent = (scrollTop / (docHeight-rawWinHeight));
|
||||
|
||||
const inter = topPos - scrollTop + ($container.height() * scrollPercent);
|
||||
|
||||
if (inter > ideal) {
|
||||
const bottom = $('#topic-bottom').offset().top;
|
||||
if (bottom > (scrollTop + rawWinHeight)) {
|
||||
return ideal;
|
||||
}
|
||||
}
|
||||
|
||||
return inter;
|
||||
}
|
||||
|
|
|
@ -8,10 +8,15 @@ export default Ember.Mixin.create({
|
|||
init() {
|
||||
this._super();
|
||||
this.queueDockCheck = () => {
|
||||
Ember.run.debounce(this, this.dockCheck, helper, 5);
|
||||
Ember.run.debounce(this, this.safeDockCheck, 5);
|
||||
};
|
||||
},
|
||||
|
||||
safeDockCheck() {
|
||||
if (this.isDestroyed || this.isDestroying) { return; }
|
||||
this.dockCheck(helper);
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super();
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ createWidget('timeline-scrollarea', {
|
|||
const topic = attrs.topic;
|
||||
const postStream = topic.get('postStream');
|
||||
const total = postStream.get('filteredPostsCount');
|
||||
let current = Math.floor(total * percentage);
|
||||
let current = Math.floor(total * percentage) + 1;
|
||||
|
||||
if (current < 1) { current = 1; }
|
||||
if (current > total) { current = total; }
|
||||
|
@ -168,15 +168,15 @@ createWidget('timeline-scrollarea', {
|
|||
},
|
||||
|
||||
topicCurrentPostScrolled(event) {
|
||||
const { postNumber, percent } = event;
|
||||
const { postIndex, percent } = event;
|
||||
|
||||
// If the post number didn't change keep our scroll position
|
||||
this.state.percentage = this._percentFor(this.attrs.topic, parseFloat(postNumber) + percent);
|
||||
this.state.percentage = this._percentFor(this.attrs.topic, parseFloat(postIndex) + percent);
|
||||
},
|
||||
|
||||
_percentFor(topic, postNumber) {
|
||||
_percentFor(topic, postIndex) {
|
||||
const total = topic.get('postStream.filteredPostsCount');
|
||||
let result = (postNumber === 1) ? 0.0 : parseFloat(postNumber) / total;
|
||||
let result = parseFloat(postIndex - 1.0) / total;
|
||||
|
||||
if (result < 0) { return 0.0; }
|
||||
if (result > 1.0) { return 1.0; }
|
||||
|
|
Loading…
Reference in New Issue
Block a user