FIX: Store scroll position when using Back button (#16658)

For some pages, when navigating to a topic and then pressing the Back
browser button to go back to the topic list, the scroll position was
not preserved and the user was taken to the beginning of the list.

This happened because the application failed to detect when the user
used the Back button and whether the topic list should be fetch from
the cache or not. The scroll position is preserved only for cached
topic lists.

Other improvements:

* Improve isPoppedState

* Reset position for topic-lists from user-activity page

* Remove usage of jQuery

* Make sure the scrollTo function has effect

Follow up to 618a1ba571.
This commit is contained in:
Bianca Nenciu 2022-05-10 19:18:55 +03:00 committed by GitHub
parent 6f00feaea0
commit 1d76c5ef5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 40 additions and 16 deletions

View File

@ -1,6 +1,6 @@
import Component from "@ember/component";
import { action } from "@ember/object";
import { schedule } from "@ember/runloop";
import { next, schedule } from "@ember/runloop";
import bootbox from "bootbox";
import { openBookmarkModal } from "discourse/controllers/bookmark";
import { ajax } from "discourse/lib/ajax";
@ -28,10 +28,10 @@ export default Component.extend(Scrolling, {
scrollToLastPosition() {
const scrollTo = this.session.bookmarkListScrollPosition;
if (scrollTo > 0) {
if (scrollTo >= 0) {
schedule("afterRender", () => {
if (this.element && !this.isDestroying && !this.isDestroyed) {
window.scrollTo(0, scrollTo + 1);
next(() => window.scrollTo(0, scrollTo + 1));
}
});
}

View File

@ -1,5 +1,5 @@
import { observes, on } from "discourse-common/utils/decorators";
import { schedule, scheduleOnce } from "@ember/runloop";
import { next, schedule, scheduleOnce } from "@ember/runloop";
import Component from "@ember/component";
import LoadMore from "discourse/mixins/load-more";
import UrlRefresh from "discourse/mixins/url-refresh";
@ -14,8 +14,12 @@ export default Component.extend(UrlRefresh, LoadMore, {
@observes("model")
_readjustScrollPosition() {
const scrollTo = this.session.topicListScrollPosition;
if (scrollTo > 0) {
schedule("afterRender", () => $(window).scrollTop(scrollTo + 1));
if (scrollTo >= 0) {
schedule("afterRender", () => {
if (this.element && !this.isDestroying && !this.isDestroyed) {
next(() => window.scrollTo(0, scrollTo + 1));
}
});
} else {
scheduleOnce("afterRender", this, this.loadMoreUnlessFull);
}

View File

@ -3,7 +3,7 @@ import discourseComputed, { observes } from "discourse-common/utils/decorators";
import Component from "@ember/component";
import LoadMore from "discourse/mixins/load-more";
import { on } from "@ember/object/evented";
import { schedule } from "@ember/runloop";
import { next, schedule } from "@ember/runloop";
import showModal from "discourse/lib/show-modal";
export default Component.extend(LoadMore, {
@ -75,10 +75,10 @@ export default Component.extend(LoadMore, {
}
const scrollTo = this.session.topicListScrollPosition;
if (scrollTo > 0) {
if (scrollTo >= 0) {
schedule("afterRender", () => {
if (this.element && !this.isDestroying && !this.isDestroyed) {
$(window).scrollTop(scrollTo + 1);
next(() => window.scrollTo(0, scrollTo + 1));
}
});
}

View File

@ -11,7 +11,7 @@ import { getOwner } from "discourse-common/lib/get-owner";
import { observes } from "discourse-common/utils/decorators";
import { on } from "@ember/object/evented";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { schedule } from "@ember/runloop";
import { next, schedule } from "@ember/runloop";
export default Component.extend(LoadMore, {
tagName: "ul",
@ -74,10 +74,10 @@ export default Component.extend(LoadMore, {
_scrollToLastPosition() {
const scrollTo = this.session.userStreamScrollPosition;
if (scrollTo > 0) {
if (scrollTo >= 0) {
schedule("afterRender", () => {
if (this.element && !this.isDestroying && !this.isDestroyed) {
window.scrollTo(0, scrollTo + 1);
next(() => window.scrollTo(0, scrollTo + 1));
}
});
}

View File

@ -67,7 +67,7 @@ export default Controller.extend({
this.set("loadingMore", true);
return this._loadMoreBookmarks(this.q)
.then((response) => this._processLoadResponse(response))
.then((response) => this._processLoadResponse(this.q, response))
.catch(() => this._bookmarksListDenied())
.finally(() => this.set("loadingMore", false));
},
@ -91,12 +91,13 @@ export default Controller.extend({
this.set("permissionDenied", true);
},
_processLoadResponse(response) {
_processLoadResponse(searchTerm, response) {
if (!response || !response.user_bookmark_list) {
return;
}
response = response.user_bookmark_list;
this.model.searchTerm = searchTerm;
this.model.loadMoreUrl = response.more_bookmarks_url;
if (response.bookmarks) {

View File

@ -92,7 +92,10 @@ const DiscourseRoute = Route.extend({
},
isPoppedState(transition) {
return !transition._discourse_intercepted && !!transition.intent.url;
return (
!transition._discourse_intercepted &&
(!!transition.intent.url || !!transition.queryParamsOnly)
);
},
});

View File

@ -12,7 +12,11 @@ export default DiscourseRoute.extend({
model(params, transition) {
const controller = this.controllerFor("user-activity-bookmarks");
if (this.isPoppedState(transition) && this.session.bookmarksModel) {
if (
this.isPoppedState(transition) &&
this.session.bookmarksModel &&
this.session.bookmarksModel.searchTerm === params.q
) {
return Promise.resolve(this.session.bookmarksModel);
}

View File

@ -23,6 +23,12 @@ export default UserTopicListRoute.extend({
});
},
afterModel(model, transition) {
if (!this.isPoppedState(transition)) {
this.session.set("topicListScrollPosition", null);
}
},
emptyState() {
const title = I18n.t("user_activity.no_read_topics_title");
const body = I18n.t("user_activity.no_read_topics_body", {

View File

@ -22,6 +22,12 @@ export default UserTopicListRoute.extend({
});
},
afterModel(model, transition) {
if (!this.isPoppedState(transition)) {
this.session.set("topicListScrollPosition", null);
}
},
emptyState() {
const user = this.modelFor("user");
const title = this.isCurrentUser(user)