DEV: Refactor build-topic-route to define abstract controller

This makes more sense (and is likely faster) than redefining the entire route for every call to `buildTopicRoute`. Also moves the top-specific logic into the route rather than injecting it via an initializer.

Similar to d5107d1aba
This commit is contained in:
David Taylor 2023-08-04 13:49:21 +01:00
parent 14348fc2f5
commit a502eb1097
2 changed files with 83 additions and 99 deletions

View File

@ -1,7 +1,6 @@
import DiscoverySortableController from "discourse/controllers/discovery-sortable";
import Site from "discourse/models/site";
import TagShowRoute from "discourse/routes/tag-show";
import User from "discourse/models/user";
import buildCategoryRoute from "discourse/routes/build-category-route";
import buildTopicRoute from "discourse/routes/build-topic-route";
import { dasherize } from "@ember/string";
@ -52,33 +51,10 @@ export default {
DiscoverySortableController.extend()
);
if (filter === "top") {
app.register(
"route:discovery.top",
buildTopicRoute("top", {
actions: {
willTransition() {
User.currentProp(
"user_option.should_be_redirected_to_top",
false
);
if (User.currentProp("user_option.redirected_to_top")) {
User.currentProp(
"user_option.redirected_to_top.reason",
null
);
}
return this._super(...arguments);
},
},
})
);
} else {
app.register(
`route:discovery.${filterDasherized}`,
buildTopicRoute(filter)
);
}
app.register(
`route:discovery.${filterDasherized}`,
buildTopicRoute(filter)
);
app.register(
`route:discovery.${filterDasherized}-category`,

View File

@ -12,9 +12,10 @@ import { defaultHomepage } from "discourse/lib/utilities";
import { isEmpty } from "@ember/utils";
import { inject as service } from "@ember/service";
import { action } from "@ember/object";
import User from "discourse/models/user";
// A helper to build a topic route for a filter
function filterQueryParams(params, defaultParams) {
export function filterQueryParams(params, defaultParams) {
const findOpts = Object.assign({}, defaultParams || {});
if (params) {
@ -27,7 +28,7 @@ function filterQueryParams(params, defaultParams) {
return findOpts;
}
async function findTopicList(
export async function findTopicList(
store,
tracking,
filter,
@ -94,86 +95,93 @@ async function findTopicList(
return list;
}
export default function (filter, extras) {
extras = extras || {};
return DiscourseRoute.extend(
{
screenTrack: service(),
queryParams,
const AbstractTopicRoute = DiscourseRoute.extend({
screenTrack: service(),
queryParams,
beforeModel() {
this.controllerFor("navigation/default").set(
"filterType",
filter.split("/")[0]
);
},
beforeModel() {
this.controllerFor("navigation/default").set(
"filterType",
this.routeConfig.filter.split("/")[0]
);
},
model(data, transition) {
// attempt to stop early cause we need this to be called before .sync
this.screenTrack.stop();
model(data, transition) {
// attempt to stop early cause we need this to be called before .sync
this.screenTrack.stop();
const findOpts = filterQueryParams(data),
findExtras = { cached: this.isPoppedState(transition) };
const findOpts = filterQueryParams(data),
findExtras = { cached: this.isPoppedState(transition) };
return findTopicList(
this.store,
this.topicTrackingState,
filter,
findOpts,
findExtras
);
},
return findTopicList(
this.store,
this.topicTrackingState,
this.routeConfig.filter,
findOpts,
findExtras
);
},
titleToken() {
if (filter === defaultHomepage()) {
return;
}
titleToken() {
if (this.routeConfig.filter === defaultHomepage()) {
return;
}
const filterText = I18n.t(
"filters." + filter.replace("/", ".") + ".title"
);
return I18n.t("filters.with_topics", { filter: filterText });
},
const filterText = I18n.t(
"filters." + this.routeConfig.filter.replace("/", ".") + ".title"
);
return I18n.t("filters.with_topics", { filter: filterText });
},
setupController(controller, model) {
const topicOpts = {
model,
category: null,
period: model.get("for_period") || model.get("params.period"),
selected: [],
expandAllPinned: false,
expandGloballyPinned: true,
};
setupController(controller, model) {
const topicOpts = {
model,
category: null,
period: model.get("for_period") || model.get("params.period"),
selected: [],
expandAllPinned: false,
expandGloballyPinned: true,
};
this.controllerFor("discovery/topics").setProperties(topicOpts);
this.controllerFor("discovery/topics").setProperties(topicOpts);
this.controllerFor("navigation/default").set(
"canCreateTopic",
model.get("can_create_topic")
);
},
this.controllerFor("navigation/default").set(
"canCreateTopic",
model.get("can_create_topic")
);
},
renderTemplate() {
this.render("navigation/default", { outlet: "navigation-bar" });
renderTemplate() {
this.render("navigation/default", { outlet: "navigation-bar" });
this.render("discovery/topics", {
controller: "discovery/topics",
outlet: "list-container",
});
},
this.render("discovery/topics", {
controller: "discovery/topics",
outlet: "list-container",
});
},
@action
changeSort(sortBy) {
changeSort.call(this, sortBy);
},
@action
changeSort(sortBy) {
changeSort.call(this, sortBy);
},
@action
resetParams(skipParams = []) {
resetParams.call(this, skipParams);
},
},
extras
);
@action
resetParams(skipParams = []) {
resetParams.call(this, skipParams);
},
@action
willTransition() {
if (this.routeConfig.filter === "top") {
User.currentProp("user_option.should_be_redirected_to_top", false);
if (User.currentProp("user_option.redirected_to_top")) {
User.currentProp("user_option.redirected_to_top.reason", null);
}
}
return this._super(...arguments);
},
});
export default function buildTopicRoute(filter) {
return AbstractTopicRoute.extend({ routeConfig: { filter } });
}
export { filterQueryParams, findTopicList };