sidebar blurring
This commit is contained in:
@@ -14410,10 +14410,10 @@ body.scroller-active #gchat-reopen-bubble {
|
|||||||
/* Filter badge style on navbar */
|
/* Filter badge style on navbar */
|
||||||
.filter-badge {
|
.filter-badge {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -13px;
|
bottom: -14px;
|
||||||
font-size: 8px;
|
font-size: 9px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
padding: 1px 4px;
|
padding: 2px 4px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
@@ -14705,4 +14705,10 @@ body.scroller-active #gchat-reopen-bubble {
|
|||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
font-size: 11px !important;
|
font-size: 11px !important;
|
||||||
line-height: 1 !important;
|
line-height: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sidebar activity thumbnails blur support (SFW/Untagged only; NSFW/NSFL use pre-blurred static images directly) */
|
||||||
|
.blur-sfw-active .sidebar-thumb-link[data-mode="sfw"] img,
|
||||||
|
.blur-untagged-active .sidebar-thumb-link[data-mode="untagged"] img {
|
||||||
|
filter: blur(8px) contrast(0.85) brightness(0.85);
|
||||||
}
|
}
|
||||||
@@ -397,13 +397,30 @@
|
|||||||
let itemPreview = '';
|
let itemPreview = '';
|
||||||
if (c.item_id) {
|
if (c.item_id) {
|
||||||
let mediaHtml = '';
|
let mediaHtml = '';
|
||||||
|
const rClass = c.item_rating_class || 'untagged';
|
||||||
|
const blurNsfw = localStorage.getItem('blurNsfw') === 'true';
|
||||||
|
const blurNsfl = localStorage.getItem('blurNsfl') === 'true';
|
||||||
|
const blurSfw = localStorage.getItem('blurSfw') === 'true';
|
||||||
|
const blurUntagged = localStorage.getItem('blurUntagged') === 'true';
|
||||||
|
|
||||||
|
let isBlurred = false;
|
||||||
|
if (rClass === 'nsfw' && blurNsfw) isBlurred = true;
|
||||||
|
else if (rClass === 'nsfl' && blurNsfl) isBlurred = true;
|
||||||
|
else if (rClass === 'sfw' && blurSfw) isBlurred = true;
|
||||||
|
else if (rClass === 'untagged' && blurUntagged) isBlurred = true;
|
||||||
|
|
||||||
let thumbUrl = `/t/${c.item_id}.webp`;
|
let thumbUrl = `/t/${c.item_id}.webp`;
|
||||||
|
if (isBlurred && (rClass === 'nsfw' || rClass === 'nsfl')) {
|
||||||
|
thumbUrl = `/t/${c.item_id}_blur.webp`;
|
||||||
|
}
|
||||||
|
|
||||||
if (window.applyThumbCacheBust) thumbUrl = window.applyThumbCacheBust(thumbUrl);
|
if (window.applyThumbCacheBust) thumbUrl = window.applyThumbCacheBust(thumbUrl);
|
||||||
|
|
||||||
mediaHtml = `<img src="${thumbUrl}" style="width: 32px; height: 32px; object-fit: cover; border-radius: 2px;" loading="lazy" onerror="this.style.display='none'" />`;
|
mediaHtml = `<img src="${thumbUrl}" style="width: 32px; height: 32px; object-fit: cover; border-radius: 2px;" loading="lazy" onerror="this.style.display='none'" />`;
|
||||||
|
|
||||||
itemPreview = `
|
itemPreview = `
|
||||||
<div class="item-preview">
|
<div class="item-preview">
|
||||||
<a href="/${c.item_id}">${mediaHtml}</a>
|
<a href="/${c.item_id}" class="sidebar-thumb-link" data-mode="${rClass}">${mediaHtml}</a>
|
||||||
<a href="/${c.item_id}#c${c.id}" style="font-size: 0.8em; color: var(--accent); text-decoration: none;">${(window.f0ckI18n && window.f0ckI18n.sidebar_view) || 'View'} »</a>
|
<a href="/${c.item_id}#c${c.id}" style="font-size: 0.8em; color: var(--accent); text-decoration: none;">${(window.f0ckI18n && window.f0ckI18n.sidebar_view) || 'View'} »</a>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@
|
|||||||
"blur_sfw": "SFW weichzeichnen",
|
"blur_sfw": "SFW weichzeichnen",
|
||||||
"blur_sfw_hint": "Zeichnet SFW-Vorschaubilder weich.",
|
"blur_sfw_hint": "Zeichnet SFW-Vorschaubilder weich.",
|
||||||
"blur_untagged": "Unmarkierte weichzeichnen",
|
"blur_untagged": "Unmarkierte weichzeichnen",
|
||||||
"blur_untagged_hint": "Zeichnet unmarkierte Vorschaubilder weich. Klicken zum Aufdecken, Klick auf das durchgestrichene Auge zum erneuten Falten.",
|
"blur_untagged_hint": "Zeichnet unmarkierte Vorschaubilder weich.",
|
||||||
"render_emojis": "Emojis in Zitatantworten anzeigen",
|
"render_emojis": "Emojis in Zitatantworten anzeigen",
|
||||||
"render_emojis_hint": ":emoji:-Bilder in >zitierten Zeilen anzeigen",
|
"render_emojis_hint": ":emoji:-Bilder in >zitierten Zeilen anzeigen",
|
||||||
"embed_yt": "YouTube-Videos in Kommentaren einbetten",
|
"embed_yt": "YouTube-Videos in Kommentaren einbetten",
|
||||||
|
|||||||
@@ -149,14 +149,14 @@
|
|||||||
"image_expand_on_click_hint": "Anstatt dat Scroll-Zoom-Moped aufzumache, wird n Bild beim Klickle uff volle Größ im Bereich uffgepumpt.",
|
"image_expand_on_click_hint": "Anstatt dat Scroll-Zoom-Moped aufzumache, wird n Bild beim Klickle uff volle Größ im Bereich uffgepumpt.",
|
||||||
"enable_bg_blur": "Hintergrundunschärfe aktivieren",
|
"enable_bg_blur": "Hintergrundunschärfe aktivieren",
|
||||||
"enable_bg_blur_hint": "Gefalteten Hintergrund auf Elementen anzeigen",
|
"enable_bg_blur_hint": "Gefalteten Hintergrund auf Elementen anzeigen",
|
||||||
"blur_nsfw": "NSFW falten",
|
"blur_nsfw": "NSFW verwischen",
|
||||||
"blur_nsfw_hint": "Faltet NSFW-Vorschaubilder.",
|
"blur_nsfw_hint": "Verwischt NSFW-Vorschaubilder.",
|
||||||
"blur_nsfl": "NSFL falten",
|
"blur_nsfl": "NSFL verwischen",
|
||||||
"blur_nsfl_hint": "Faltet NSFL-Vorschaubilder.",
|
"blur_nsfl_hint": "Verwischt NSFL-Vorschaubilder.",
|
||||||
"blur_sfw": "SFW falten",
|
"blur_sfw": "SFW verwischen",
|
||||||
"blur_sfw_hint": "Faltet SFW-Vorschaubilder.",
|
"blur_sfw_hint": "Verwischt SFW-Vorschaubilder.",
|
||||||
"blur_untagged": "Unmarkierte falten",
|
"blur_untagged": "Unmarkierte verwischen",
|
||||||
"blur_untagged_hint": "Faltet unmarkierte Vorschaubilder.",
|
"blur_untagged_hint": "Verwischt unmarkierte Vorschaubilder.",
|
||||||
"render_emojis": "Emojis in Zitatantworten darstellen",
|
"render_emojis": "Emojis in Zitatantworten darstellen",
|
||||||
"render_emojis_hint": ":emoji:-Bilder innerhalb von >zitierten Zeilen anzeigen",
|
"render_emojis_hint": ":emoji:-Bilder innerhalb von >zitierten Zeilen anzeigen",
|
||||||
"embed_yt": "Röhrenelfen in Kommentaren einbetten",
|
"embed_yt": "Röhrenelfen in Kommentaren einbetten",
|
||||||
|
|||||||
@@ -418,8 +418,23 @@ export default (router, tpl) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Notify for live updates
|
// Notify for live updates
|
||||||
// Fetch the trigger-updated xd_score from the DB (trigger runs synchronously before we get here)
|
// Fetch the trigger-updated xd_score and the item rating tag from the DB (trigger runs synchronously before we get here)
|
||||||
const [xdRow] = await db`SELECT xd_score FROM items WHERE id = ${item_id}`;
|
const itemQuery = await db`
|
||||||
|
SELECT
|
||||||
|
i.xd_score,
|
||||||
|
(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[])
|
||||||
|
ORDER BY ta.tag_id LIMIT 1) AS rating_tag_id
|
||||||
|
FROM items i WHERE i.id = ${item_id}
|
||||||
|
`;
|
||||||
|
const xdRow = itemQuery[0];
|
||||||
|
const ratingTagId = itemQuery[0]?.rating_tag_id;
|
||||||
|
let ratingLabel = '?';
|
||||||
|
let ratingClass = 'untagged';
|
||||||
|
if (ratingTagId == 1) { ratingLabel = 'SFW'; ratingClass = 'sfw'; }
|
||||||
|
else if (ratingTagId == 2) { ratingLabel = 'NSFW'; ratingClass = 'nsfw'; }
|
||||||
|
else if (ratingTagId == (cfg.nsfl_tag_id || 3)) { ratingLabel = 'NSFL'; ratingClass = 'nsfl'; }
|
||||||
|
|
||||||
// Truncate body to 500 chars: PostgreSQL NOTIFY has an 8000-byte hard limit.
|
// Truncate body to 500 chars: PostgreSQL NOTIFY has an 8000-byte hard limit.
|
||||||
// Large comments would silently drop the notification. The client fetches
|
// Large comments would silently drop the notification. The client fetches
|
||||||
// the full content via _silentSync; the NOTIFY only needs to trigger the update.
|
// the full content via _silentSync; the NOTIFY only needs to trigger the update.
|
||||||
@@ -450,7 +465,14 @@ export default (router, tpl) => {
|
|||||||
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_label: ratingLabel,
|
||||||
|
avatar: req.session.avatar,
|
||||||
|
avatar_file: req.session.avatar_file,
|
||||||
|
username: req.session.user,
|
||||||
|
username_color: req.session.username_color,
|
||||||
|
display_name: req.session.display_name || null
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Automatically subscribe user to the thread
|
// Automatically subscribe user to the thread
|
||||||
@@ -806,6 +828,9 @@ export default (router, tpl) => {
|
|||||||
i.mime,
|
i.mime,
|
||||||
i.id as item_id,
|
i.id as item_id,
|
||||||
i.dest as item_dest,
|
i.dest as item_dest,
|
||||||
|
(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[])
|
||||||
|
ORDER BY ta.tag_id LIMIT 1) AS rating_tag_id,
|
||||||
u.user as username,
|
u.user as username,
|
||||||
uo.avatar,
|
uo.avatar,
|
||||||
uo.avatar_file,
|
uo.avatar_file,
|
||||||
@@ -827,10 +852,18 @@ export default (router, tpl) => {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const processedComments = comments.map(c => {
|
const processedComments = comments.map(c => {
|
||||||
|
let ratingLabel = '?';
|
||||||
|
let ratingClass = 'untagged';
|
||||||
|
if (c.rating_tag_id == 1) { ratingLabel = 'SFW'; ratingClass = 'sfw'; }
|
||||||
|
else if (c.rating_tag_id == 2) { ratingLabel = 'NSFW'; ratingClass = 'nsfw'; }
|
||||||
|
else if (c.rating_tag_id == (cfg.nsfl_tag_id || 3)) { ratingLabel = 'NSFL'; ratingClass = 'nsfl'; }
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...c,
|
...c,
|
||||||
content: (c.content || '').trim(),
|
content: (c.content || '').trim(),
|
||||||
username_color: c.username_color
|
username_color: c.username_color,
|
||||||
|
item_rating_class: ratingClass,
|
||||||
|
item_rating_label: ratingLabel
|
||||||
// created_at stays as the raw ISO timestamp so the frontend f0ckTimeAgo can localize it
|
// created_at stays as the raw ISO timestamp so the frontend f0ckTimeAgo can localize it
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user