This commit is contained in:
2026-08-09 02:41:57 +02:00
parent b10ddac6f3
commit 98ee76f61c
3 changed files with 37 additions and 34 deletions

View File

@@ -643,7 +643,6 @@ export default {
where where
${itemLookup} and ${itemLookup} and
items.active = true items.active = true
${!session && getGlobalfilter() ? db`and not exists (select 1 from tags_assign where item_id = items.id and (${db.unsafe(getGlobalfilter())}))` : db``}
limit 1 limit 1
`; `;
@@ -692,22 +691,22 @@ export default {
last_viewed = now() last_viewed = now()
`.catch(e => console.error('Failed to track view:', e)); `.catch(e => console.error('Failed to track view:', e));
} }
// Guest global filter check if item was filtered out // Guest global filter check for public items (unlisted items requested by direct link/slug bypass guest rating blocks)
if (!session && getGlobalfilter() && !actitem) { if (!session && getGlobalfilter() && (actitem.visibility || 0) === 0) {
const unfilteredItem = await db` const filteredItem = await db`
select id from items where ${itemLookup} and active = true limit 1 select 1 from tags_assign where item_id = ${itemid} and (${db.unsafe(getGlobalfilter())}) limit 1
`; `;
if (unfilteredItem[0]) { if (filteredItem.length > 0) {
const hallSlug = hall && typeof hall === 'object' ? hall.slug : hall; const hallSlug = hall && typeof hall === 'object' ? hall.slug : hall;
return { return {
success: false, success: false,
message: "Sorry, this post is currently not visible.", message: "Sorry, this post is currently not visible.",
item: { item: {
id: unfilteredItem[0].id, id: itemid,
og_thumbnail: `${cfg.websrv.paths.thumbnails}/${unfilteredItem[0].id}_blur.webp`, og_thumbnail: `${cfg.websrv.paths.thumbnails}/${itemid}_blur.webp`,
og_url: hallSlug og_url: hallSlug
? `https://${cfg.main.url.domain}/h/${encodeURIComponent(hallSlug)}/${unfilteredItem[0].id}` ? `https://${cfg.main.url.domain}/h/${encodeURIComponent(hallSlug)}/${itemid}`
: `https://${cfg.main.url.domain}/${unfilteredItem[0].id}`, : `https://${cfg.main.url.domain}/${itemid}`,
og_description: `Content not visible in current mode` og_description: `Content not visible in current mode`
} }
}; };

View File

@@ -574,6 +574,7 @@ export default (router, tpl) => {
SELECT SELECT
i.slug, i.slug,
i.xd_score, i.xd_score,
COALESCE(i.visibility, 0) as visibility,
(SELECT ta.tag_id FROM tags_assign ta (SELECT ta.tag_id FROM tags_assign ta
WHERE ta.item_id = i.id AND ta.tag_id = ANY(${[1, 2, cfg.nsfl_tag_id || 3]}::int[]) WHERE ta.item_id = i.id AND ta.tag_id = ANY(${[1, 2, cfg.nsfl_tag_id || 3]}::int[])
ORDER BY ta.tag_id LIMIT 1) AS rating_tag_id ORDER BY ta.tag_id LIMIT 1) AS rating_tag_id
@@ -613,29 +614,30 @@ export default (router, tpl) => {
// 1. Thread live update // 1. Thread live update
db.notify('comments', JSON.stringify(livePayload)); db.notify('comments', JSON.stringify(livePayload));
// 2. Sidebar activity update // 2. Sidebar activity update (only for public items)
// Compute is_long using the full content (not the truncated notifyBody) so the const itemVisibility = itemQuery[0]?.visibility ?? 0;
// sidebar renders the correct clamped state immediately on first paint. if (itemVisibility === 0) {
const activityIsLong = content.length > 120 const activityIsLong = content.length > 120
|| content.split('\n').length > 2 || content.split('\n').length > 2
|| activityFiles.length > 0 || activityFiles.length > 0
|| /\[(video|audio|youtube|img)\]|!\[|https?:\/\//i.test(content); || /\[(video|audio|youtube|img)\]|!\[|https?:\/\//i.test(content);
db.notify('activity', JSON.stringify({ db.notify('activity', JSON.stringify({
user_id: req.session.id, user_id: req.session.id,
item_id: item_id, item_id: item_id,
type: 'comment', type: 'comment',
body: notifyBody, body: notifyBody,
id: commentId, id: commentId,
item_rating_class: ratingClass, item_rating_class: ratingClass,
item_rating_label: ratingLabel, item_rating_label: ratingLabel,
avatar: req.session.avatar, avatar: req.session.avatar,
avatar_file: req.session.avatar_file, avatar_file: req.session.avatar_file,
username: req.session.user, username: req.session.user,
username_color: req.session.username_color, username_color: req.session.username_color,
display_name: req.session.display_name || null, display_name: req.session.display_name || null,
files: activityFiles, files: activityFiles,
is_long: activityIsLong is_long: activityIsLong
})); }));
}
// Automatically subscribe user to the thread // Automatically subscribe user to the thread
const subResult = await db` const subResult = await db`
@@ -1024,6 +1026,7 @@ export default (router, tpl) => {
WHERE c.is_deleted = false WHERE c.is_deleted = false
AND i.active = true AND i.active = true
AND i.is_deleted = false AND i.is_deleted = false
AND COALESCE(i.visibility, 0) = 0
AND ${db.unsafe(modequery)} AND ${db.unsafe(modequery)}
${!req.session && globalfilter ? db`and not exists (select 1 from tags_assign where item_id = i.id and (${db.unsafe(globalfilter)}))` : db``} ${!req.session && globalfilter ? db`and not exists (select 1 from tags_assign where item_id = i.id and (${db.unsafe(globalfilter)}))` : db``}
${excludedTags.length > 0 ? db`and not exists (select 1 from tags_assign where item_id = i.id and tag_id = any(${excludedTags}::int[]))` : db``} ${excludedTags.length > 0 ? db`and not exists (select 1 from tags_assign where item_id = i.id and tag_id = any(${excludedTags}::int[]))` : db``}

View File

@@ -123,7 +123,7 @@ db.listen('activity', async (payload) => {
// We need the username, avatar, and item mime for the preview // We need the username, avatar, and item mime for the preview
// trigger only gave us user_id and item_id // trigger only gave us user_id and item_id
const [details] = await db` const [details] = await db`
SELECT u.id as user_id, u.user as username, uo.avatar, uo.avatar_file, uo.username_color, uo.display_name, i.mime, i.slug as item_slug, SELECT u.id as user_id, u.user as username, uo.avatar, uo.avatar_file, uo.username_color, uo.display_name, i.mime, i.slug as item_slug, COALESCE(i.visibility, 0) as visibility,
(SELECT tag_id FROM tags_assign WHERE item_id = i.id AND tag_id IN (1, 2) LIMIT 1) as tag_id (SELECT tag_id FROM tags_assign WHERE item_id = i.id AND tag_id IN (1, 2) LIMIT 1) as tag_id
FROM "user" u FROM "user" u
LEFT JOIN user_options uo ON u.id = uo.user_id LEFT JOIN user_options uo ON u.id = uo.user_id
@@ -132,6 +132,7 @@ db.listen('activity', async (payload) => {
`; `;
if (details) { if (details) {
if (details.visibility > 0) return;
data.username = details.username; data.username = details.username;
data.avatar = details.avatar; data.avatar = details.avatar;
data.avatar_file = details.avatar_file; data.avatar_file = details.avatar_file;