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
@@ -1,4 +1,5 @@
import f0cklib from "../routeinc/f0cklib.mjs";
import lib from "../lib.mjs";
import url from "url";
import cfg from "../config.mjs";
import { createI18n } from "../i18n.mjs";
@@ -41,10 +42,12 @@ export default (router, tpl) => {
const ratingsArr = isGuest ? ['sfw'] : ((reqMode === 2 || reqMode === 3) ? null : (ratingsRaw ? decodeURIComponent(ratingsRaw).split(/[|,]/).filter(r => ['sfw','nsfw','nsfl','untagged'].includes(r)) : null));
const itemid = req.params.itemid || req.url.pathname.match(/\/ajax\/item\/([a-zA-Z0-9_-]{11}|\d+)/)?.[1];
const bypassFilter = !!(query.force === '1' || query.force === 'true' || query.allow === '1' || query.allow === 'true' || query.bypass === '1' || query.bypass === 'true' || query.see_anyways === '1');
const data = await f0cklib.getf0ck({
itemid: itemid,
mode: reqMode,
ratings: ratingsArr,
bypass_filter: bypassFilter,
session: req.session,
url: contextUrl,
user: query.user,
@@ -67,15 +70,18 @@ export default (router, tpl) => {
if (!data.success) {
const reqMode = (query.mode !== undefined ? +query.mode : 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');
const errorHtml = tpl.render('error-partial', {
message: tErr('error.post_not_visible'),
tmp: null,
session: req.session ? { ...req.session } : false,
item_id: data.item?.id || itemid,
item_slug: data.item?.slug || (typeof itemid === 'string' ? itemid : null),
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);
return res.reply({
headers: { 'Content-Type': 'application/json' },
@@ -161,12 +167,29 @@ 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
};
});
}
}
const isAnon = !!(session && (session.is_anon || (session.user && (session.user === 'anonymous' || session.user.startsWith('anon_')))));
data.is_mod_or_admin = !!(session && (session.admin || session.is_moderator));
data.can_manage_item = !isAnon && !!(session && (session.admin || session.is_moderator || (session.user && item.username && session.user.toLowerCase() === item.username.toLowerCase())));
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])));
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);
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(',') : '';
// Precomputed for template engine compatibility (avoids nested { } inside {{ }})