This commit is contained in:
2026-09-14 22:30:09 +02:00
parent 22ffc3b51a
commit 912deeb28e
42 changed files with 2998 additions and 618 deletions
+26 -3
View File
@@ -265,6 +265,8 @@ export default (router, tpl) => {
f0cklib.updateUserTagAffinity({ user_id: req.session.id, tag: reqTag, scoreDelta: 2.0 }).catch(() => {});
}
const bypassFilter = !!(req.query?.force === '1' || req.query?.allow === '1' || req.query?.bypass === '1' || req.url.qs?.force === '1' || req.url.qs?.allow === '1' || req.url.qs?.bypass === '1' || req.query?.see_anyways === '1' || req.url.qs?.see_anyways === '1');
const data = await (req.params.itemid ? f0cklib.getf0ck : f0cklib.getf0cks)({
user: req.params.user,
tag: reqTag,
@@ -274,6 +276,7 @@ export default (router, tpl) => {
hall: req.params.hall,
fav: req.params.mode == 'favs',
mode: req.mode,
bypass_filter: bypassFilter,
ratings: (() => { if (req.mode === 2 || req.mode === 3) return null; const r = req.cookies.ratings; return r ? decodeURIComponent(r).split(/[|,]/).filter(x => ['sfw','nsfw','nsfl','untagged'].includes(x)) : null; })(),
session: req.session,
user_id: req.session?.id,
@@ -333,19 +336,22 @@ export default (router, tpl) => {
const statusCode = data.item ? 200 : 404;
const reqMode = req.mode ?? 0;
const modeLabels = { 0: 'SFW', 1: 'NSFW', 2: 'Untagged', 4: 'NSFL' };
const errorModeLabel = (req.session && reqMode !== 3) ? (modeLabels[reqMode] || null) : null;
const errorModeLabel = reqMode !== 3 ? (modeLabels[reqMode] || 'SFW') : null;
const { t: tErr } = createI18n(req.session?.language || req.lang || 'en');
return res.reply({
code: statusCode,
body: tpl.render('error', {
message: tErr('error.post_not_visible'),
item: data.item, // For OG meta tags on filtered NSFW items
item_id: data.item?.id || req.params.itemid,
item_slug: data.item?.slug || (typeof req.params.itemid === 'string' ? req.params.itemid : null),
domain: cfg.main.url.domain,
tmp: null,
session: req.session ? { ...req.session } : false,
error_mode_label: errorModeLabel,
error_filter_hint: errorModeLabel ? tErr('error.filter_hint', { mode: `<strong>${errorModeLabel}</strong>` }) : null,
error_filter_hint_link: tErr('error.filter_hint_link')
error_filter_hint_link: tErr('error.filter_hint_link'),
error_see_anyways: tErr('error.see_anyways')
}, req)
});
}
@@ -420,7 +426,7 @@ export default (router, tpl) => {
// YouTube items use oEmbed via /meta/fetch; all non-flash MIME types are eligible.
data.can_extract_meta = !!(item.mime && item.mime.indexOf('flash') === -1 && !(item.mime.startsWith('application/') && cfg.mimes[item.mime] && !['swf', 'pdf'].includes(cfg.mimes[item.mime])));
// Has the current user favorited this item?
data.user_has_favorited = !!(session && Array.isArray(item.favorites) && item.favorites.some(f => f.user === session.user));
data.user_has_favorited = lib.userHasFavorited(session, item.favorites);
// Hall columns for display
data.halls_slugs = Array.isArray(item.halls) ? item.halls.map(h => h.slug).join(',') : '';
data.user_halls_slugs = Array.isArray(item.user_halls) ? item.user_halls.map(h => h.slug).join(',') : '';
@@ -442,6 +448,23 @@ export default (router, tpl) => {
data.uploader.id = null;
data.uploader.color = null;
}
if (Array.isArray(item.favorites)) {
item.favorites = item.favorites.map(f => {
const isSelf = session && session.id && f.user_id && Number(f.user_id) === Number(session.id);
if (isSelf) return f;
return {
user_id: null,
user: 'anonymous',
login: 'anonymous',
display_name: 'Anonymous',
avatar: null,
avatar_file: null,
username_color: null,
hide_fav_badge: f.hide_fav_badge,
is_anon: true
};
});
}
}
// Precomputed for template engine compatibility (avoids nested { } inside {{ }})
data.item_rating_class = item.is_nsfl ? 'is-nsfl' : (item.is_nsfw ? 'is-nsfw' : (item.is_sfw ? 'is-sfw' : 'is-untagged'));