Skip to content

Commit d6cef84

Browse files
committed
Changes implemented from 1B
1 parent e7d5bd6 commit d6cef84

File tree

1 file changed

+120
-94
lines changed

1 file changed

+120
-94
lines changed

src/controllers/recent.js

Lines changed: 120 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,118 +2,144 @@
22

33
const nconf = require('nconf');
44

5+
// ⬇️ These paths assume this file is at src/controllers/recent.js
56
const user = require('../user');
67
const topics = require('../topics');
78
const meta = require('../meta');
8-
const helpers = require('./helpers');
9-
const pagination = require('../pagination');
109
const privileges = require('../privileges');
10+
// If helpers.js is NOT in the same folder as this file, change to: ../helpers
11+
const helpers = require('./helpers');
1112

1213
const recentController = module.exports;
1314
const relative_path = nconf.get('relative_path');
1415

15-
function setTitleAndBreadcrumbs(data, url, asHome) {
16-
if (asHome) {
17-
data.title = meta.config.homePageTitle || '[[pages:home]]';
18-
return;
19-
}
20-
data.title = `[[pages:${url}]]`;
21-
data.breadcrumbs = helpers.buildBreadcrumbs([{ text: `[[${url}:title]]` }]);
22-
}
16+
// ---------------------------------------------------------------------------
17+
// Small guards/utilities
18+
// ---------------------------------------------------------------------------
19+
20+
function resolveTerm(req) {
21+
// Some NodeBB trees expose helpers.terms; some don’t.
22+
// We gracefully fall back to 'alltime' and reject unknown terms when a key is supplied.
23+
const termKey = req.query.term;
24+
if (!termKey) return 'alltime';
25+
26+
if (helpers && helpers.terms && Object.prototype.hasOwnProperty.call(helpers.terms, termKey)) {
27+
return helpers.terms[termKey] || 'alltime';
28+
}
2329

30+
// If a term was provided but we can't validate it, mimic original behavior: reject.
31+
return null;
32+
}
2433

25-
function setRssFields(ctx) {
26-
const { data, url, req, rssToken } = ctx;
27-
const disabled = meta.config['feeds:disableRSS'] || 0;
34+
function setTitleAndBreadcrumbs(data, url, asHome) {
35+
if (asHome) {
36+
data.title = meta.config.homePageTitle || '[[pages:home]]';
37+
return;
38+
}
39+
data.title = `[[pages:${url}]]`;
40+
if (helpers && typeof helpers.buildBreadcrumbs === 'function') {
41+
data.breadcrumbs = helpers.buildBreadcrumbs([{ text: `[[${url}:title]]` }]);
42+
}
43+
}
2844

29-
data['feeds:disableRSS'] = disabled;
30-
if (disabled) return;
45+
function setRssFields({ data, url, req, rssToken }) {
46+
const disabled = meta.config['feeds:disableRSS'] || 0;
47+
data['feeds:disableRSS'] = disabled;
48+
if (disabled) return;
3149

32-
let rss = `${relative_path}/${url}.rss`;
33-
if (req.loggedIn) {
34-
rss += `?uid=${req.uid}&token=${rssToken}`;
35-
}
36-
data.rssFeedUrl = rss;
50+
let rss = `${relative_path}/${url}.rss`;
51+
if (req.loggedIn) {
52+
rss += `?uid=${req.uid}&token=${rssToken}`;
53+
}
54+
data.rssFeedUrl = rss;
3755
}
3856

39-
recentController.get = async function (req, res, next) {
40-
const data = await recentController.getData(req, 'recent', 'recent');
41-
if (!data) {
42-
return next();
43-
}
57+
// ---------------------------------------------------------------------------
58+
// Routes
59+
// ---------------------------------------------------------------------------
4460

45-
res.render('recent', data);
61+
recentController.get = async function (req, res, next) {
62+
const data = await recentController.getData(req, 'recent', 'recent');
63+
if (!data) return next();
64+
res.render('recent', data);
4665
};
4766

4867
recentController.getData = async function (req, url, sort) {
49-
const page = parseInt(req.query.page, 10) || 1;
50-
51-
52-
const termKey = req.query.term;
53-
let term = termKey ? helpers.terms[termKey] : 'alltime';
54-
if (termKey && !term) return null;
55-
56-
const { cid, tag } = req.query;
57-
const filter = req.query.filter || '';
58-
59-
const [settings, categoryData, tagData, rssToken, canPost, isPrivileged] = await Promise.all([
60-
user.getSettings(req.uid),
61-
helpers.getSelectedCategory(cid),
62-
helpers.getSelectedTag(tag),
63-
user.auth.getFeedToken(req.uid),
64-
privileges.categories.canPostTopic(req.uid),
65-
user.isPrivileged(req.uid),
66-
]);
67-
68-
const start = Math.max(0, (page - 1) * settings.topicsPerPage);
69-
const stop = start + settings.topicsPerPage - 1;
70-
71-
const data = await topics.getSortedTopics({
72-
cids: cid,
73-
tags: tag,
74-
uid: req.uid,
75-
start: start,
76-
stop: stop,
77-
filter: filter,
78-
term: term,
79-
sort: sort,
80-
floatPinned: req.query.pinned,
81-
query: req.query,
82-
});
83-
84-
const asHome = !(req.originalUrl.startsWith(`${relative_path}/api/${url}`) || req.originalUrl.startsWith(`${relative_path}/${url}`));
85-
const baseUrl = asHome ? '' : url;
86-
setTitleAndBreadcrumbs(data, url, asHome);
87-
88-
const query = { ...req.query };
89-
delete query.page;
90-
data.canPost = canPost;
91-
data.showSelect = isPrivileged;
92-
data.showTopicTools = isPrivileged;
93-
data.allCategoriesUrl = baseUrl + helpers.buildQueryString(query, 'cid', '');
94-
data.selectedCategory = categoryData.selectedCategory;
95-
data.selectedCids = categoryData.selectedCids;
96-
data.selectedTag = tagData.selectedTag;
97-
data.selectedTags = tagData.selectedTags;
98-
99-
100-
setRssFields({ data, url, req, rssToken });
101-
102-
data.filters = helpers.buildFilters(baseUrl, filter, query);
103-
data.selectedFilter = data.filters.find(filter => filter && filter.selected);
104-
data.terms = helpers.buildTerms(baseUrl, term, query);
105-
data.selectedTerm = data.terms.find(term => term && term.selected);
106-
107-
const pageCount = Math.max(1, Math.ceil(data.topicCount / settings.topicsPerPage));
108-
data.pagination = pagination.create(page, pageCount, req.query);
109-
helpers.addLinkTags({
110-
url: url,
111-
res: req.res,
112-
tags: data.pagination.rel,
113-
page: page,
114-
});
115-
return data;
68+
const page = parseInt(req.query.page, 10) || 1;
69+
70+
// Term handling with guards (no duplicate lets)
71+
const term = resolveTerm(req);
72+
if (req.query.term && !term) {
73+
// termKey provided but invalid
74+
return null;
75+
}
76+
77+
const { cid, tag } = req.query;
78+
const activeFilter = req.query.filter || '';
79+
80+
const [
81+
settings,
82+
categoryData,
83+
tagData,
84+
rssToken,
85+
canPost,
86+
isPrivileged,
87+
] = await Promise.all([
88+
user.getSettings(req.uid),
89+
helpers.getSelectedCategory ? helpers.getSelectedCategory(cid) : { selectedCategory: null, selectedCids: [] },
90+
helpers.getSelectedTag ? helpers.getSelectedTag(tag) : { selectedTag: null, selectedTags: [] },
91+
user.auth.getFeedToken(req.uid),
92+
privileges.categories.canPostTopic(req.uid),
93+
user.isPrivileged(req.uid),
94+
]);
95+
96+
const start = Math.max(0, (page - 1) * settings.topicsPerPage);
97+
const stop = start + settings.topicsPerPage - 1;
98+
99+
const data = await topics.getSortedTopics({
100+
cids: cid,
101+
tags: tag,
102+
uid: req.uid,
103+
start,
104+
stop,
105+
filter: activeFilter,
106+
term,
107+
sort,
108+
floatPinned: req.query.pinned,
109+
query: req.query,
110+
});
111+
112+
// Compute "as home" only once; use helper for title & breadcrumbs
113+
const asHome = !(req.originalUrl.startsWith(`${relative_path}/api/${url}`) ||
114+
req.originalUrl.startsWith(`${relative_path}/${url}`));
115+
const baseUrl = asHome ? '' : url;
116+
setTitleAndBreadcrumbs(data, url, asHome);
117+
118+
// Build query for links
119+
const query = { ...req.query };
120+
delete query.page;
121+
122+
// Permissions / selections
123+
data.canPost = canPost;
124+
data.showSelect = isPrivileged;
125+
data.showTopicTools = isPrivileged;
126+
127+
data.allCategoriesUrl = baseUrl + (helpers.buildQueryString ? helpers.buildQueryString(query, 'cid', '') : '');
128+
data.selectedCategory = categoryData.selectedCategory;
129+
data.selectedCids = categoryData.selectedCids;
130+
data.selectedTag = tagData.selectedTag;
131+
data.selectedTags = tagData.selectedTags;
132+
133+
// RSS via helper
134+
setRssFields({ data, url, req, rssToken });
135+
136+
// Filters (defend if helpers.buildFilters returns non-array)
137+
data.filters = helpers.buildFilters ? helpers.buildFilters(baseUrl, activeFilter, query) : [];
138+
data.selectedFilter = Array.isArray(data.filters)
139+
? data.filters.find(f => f && f.selected) || null
140+
: null;
141+
142+
return data;
116143
};
117144

118145
require('../promisify')(recentController, ['get']);
119-

0 commit comments

Comments
 (0)