UI: Scroll to the bottom of the page when the scrollbar hits the end (#8101)

This commit is contained in:
Daniel Waterworth 2019-10-08 01:00:58 +00:00 committed by Sam
parent 3f172deab5
commit 87f0b56191
4 changed files with 32 additions and 12 deletions

View File

@ -707,6 +707,12 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
}); });
}, },
jumpEnd() {
DiscourseURL.routeTo(this.get("model.lastPostUrl"), {
jumpEnd: true
});
},
jumpUnread() { jumpUnread() {
this._jumpToPostId(this.get("model.last_read_post_id")); this._jumpToPostId(this.get("model.last_read_post_id"));
}, },

View File

@ -93,6 +93,12 @@ const DiscourseURL = Ember.Object.extend({
let elementId; let elementId;
let holder; let holder;
if (opts.jumpEnd) {
$(window).scrollTop($(document).height() - $(window).height());
_transitioning = false;
return;
}
if (postNumber === 1 && !opts.anchor) { if (postNumber === 1 && !opts.anchor) {
$(window).scrollTop(0); $(window).scrollTop(0);
_transitioning = false; _transitioning = false;
@ -347,7 +353,8 @@ const DiscourseURL = Ember.Object.extend({
this.appEvents.trigger("post:highlight", closest); this.appEvents.trigger("post:highlight", closest);
const jumpOpts = { const jumpOpts = {
skipIfOnScreen: routeOpts.skipIfOnScreen skipIfOnScreen: routeOpts.skipIfOnScreen,
jumpEnd: routeOpts.jumpEnd
}; };
const m = /#.+$/.exec(path); const m = /#.+$/.exec(path);

View File

@ -124,6 +124,7 @@
jumpToPost=(action "jumpToPost") jumpToPost=(action "jumpToPost")
jumpTop=(action "jumpTop") jumpTop=(action "jumpTop")
jumpBottom=(action "jumpBottom") jumpBottom=(action "jumpBottom")
jumpEnd=(action "jumpEnd")
jumpToPostPrompt=(action "jumpToPostPrompt") jumpToPostPrompt=(action "jumpToPostPrompt")
jumpToIndex=(action "jumpToIndex") jumpToIndex=(action "jumpToIndex")
replyToPost=(action "replyToPost") replyToPost=(action "replyToPost")

View File

@ -148,7 +148,8 @@ createWidget("timeline-scrollarea", {
const postStream = topic.get("postStream"); const postStream = topic.get("postStream");
const total = postStream.get("filteredPostsCount"); const total = postStream.get("filteredPostsCount");
const current = clamp(Math.floor(total * percentage) + 1, 1, total); const scrollPosition = clamp(Math.floor(total * percentage), 0, total) + 1;
const current = clamp(scrollPosition, 1, total);
const daysAgo = postStream.closestDaysAgoFor(current); const daysAgo = postStream.closestDaysAgoFor(current);
let date; let date;
@ -168,6 +169,7 @@ createWidget("timeline-scrollarea", {
const result = { const result = {
current, current,
scrollPosition,
total, total,
date, date,
lastRead: null, lastRead: null,
@ -183,9 +185,9 @@ createWidget("timeline-scrollarea", {
result.lastReadPercentage = this._percentFor(topic, idx); result.lastReadPercentage = this._percentFor(topic, idx);
} }
if (this.state.position !== result.current) { if (this.state.position !== result.scrollPosition) {
this.state.position = result.current; this.state.position = result.scrollPosition;
this.sendWidgetAction("updatePosition", result.current); this.sendWidgetAction("updatePosition", result.position, result.scrollPosition);
} }
return result; return result;
@ -259,7 +261,11 @@ createWidget("timeline-scrollarea", {
const position = this.position(); const position = this.position();
this.state.scrolledPost = position.current; this.state.scrolledPost = position.current;
this.sendWidgetAction("jumpToIndex", position.current); if (position.current === position.scrollPosition) {
this.sendWidgetAction("jumpToIndex", position.current);
} else {
this.sendWidgetAction("jumpEnd");
}
}, },
topicCurrentPostScrolled(event) { topicCurrentPostScrolled(event) {
@ -380,25 +386,25 @@ export default createWidget("topic-timeline", {
return { position: null, excerpt: null }; return { position: null, excerpt: null };
}, },
updatePosition(pos) { updatePosition(postIdx, scrollPosition) {
if (!this.attrs.fullScreen) { if (!this.attrs.fullScreen) {
return; return;
} }
this.state.position = pos; this.state.position = scrollPosition;
this.state.excerpt = ""; this.state.excerpt = "";
const stream = this.attrs.topic.get("postStream"); const stream = this.attrs.topic.get("postStream");
// a little debounce to avoid flashing // a little debounce to avoid flashing
Ember.run.later(() => { Ember.run.later(() => {
if (!this.state.position === pos) { if (!this.state.position === scrollPosition) {
return; return;
} }
// we have an off by one, stream is zero based, // we have an off by one, stream is zero based,
// pos is 1 based // postIdx is 1 based
stream.excerpt(pos - 1).then(info => { stream.excerpt(postIdx - 1).then(info => {
if (info && this.state.position === pos) { if (info && this.state.position === scrollPosition) {
let excerpt = ""; let excerpt = "";
if (info.username) { if (info.username) {