bkmdfg
This commit is contained in:
+30
-4
@@ -3196,13 +3196,11 @@ body.sidebar-right-hidden #sidebar-drag-zone {
|
|||||||
.sidebar-video-meta {
|
.sidebar-video-meta {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
flex-wrap: wrap;
|
||||||
|
gap: 3px 5px;
|
||||||
font-size: 0.7em;
|
font-size: 0.7em;
|
||||||
color: #777;
|
color: #777;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-video-time {
|
.sidebar-video-time {
|
||||||
@@ -3232,6 +3230,34 @@ body.sidebar-right-hidden #sidebar-drag-zone {
|
|||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-dev-score {
|
||||||
|
font-size: 0.85em;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 1px 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
background: rgba(255, 170, 0, 0.16);
|
||||||
|
color: #ffaa00;
|
||||||
|
border: 1px solid rgba(255, 170, 0, 0.4);
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
font-family: monospace, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-dev-score i {
|
||||||
|
font-size: 0.85em;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[theme='light'] .sidebar-dev-score,
|
||||||
|
html[theme='paper'] .sidebar-dev-score {
|
||||||
|
background: rgba(217, 119, 6, 0.14);
|
||||||
|
color: #b45309;
|
||||||
|
border-color: rgba(217, 119, 6, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
/* Light / Paper themes */
|
/* Light / Paper themes */
|
||||||
html[theme='light'] .sidebar-tabs,
|
html[theme='light'] .sidebar-tabs,
|
||||||
html[theme='paper'] .sidebar-tabs {
|
html[theme='paper'] .sidebar-tabs {
|
||||||
|
|||||||
+26
-6
@@ -6668,14 +6668,23 @@ window.cancelAnimFrame = (function () {
|
|||||||
if (!tagname) return;
|
if (!tagname) return;
|
||||||
suggestions.style.display = 'none';
|
suggestions.style.display = 'none';
|
||||||
try {
|
try {
|
||||||
|
const csrf = window.f0ckSession?.csrf_token || document.querySelector('input[name="csrf_token"]')?.value || '';
|
||||||
const res = await fetch('/api/v2/settings/excluded_tags', {
|
const res = await fetch('/api/v2/settings/excluded_tags', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: {
|
||||||
body: JSON.stringify({ tagname })
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-Token': csrf
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ tagname, csrf_token: csrf })
|
||||||
});
|
});
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data.success) { renderTags(); input.value = ''; }
|
if (data.success) {
|
||||||
else window.flashMessage(data.msg || 'Error adding tag', 3000, 'error');
|
renderTags();
|
||||||
|
input.value = '';
|
||||||
|
if (typeof gridCacheMap !== 'undefined') gridCacheMap.clear();
|
||||||
|
} else {
|
||||||
|
window.flashMessage(data.msg || 'Error adding tag', 3000, 'error');
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -6699,9 +6708,20 @@ window.cancelAnimFrame = (function () {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const tag = e.target.getAttribute('data-tag');
|
const tag = e.target.getAttribute('data-tag');
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/v2/settings/excluded_tags/${encodeURIComponent(tag)}`, { method: 'DELETE' });
|
const csrf = window.f0ckSession?.csrf_token || document.querySelector('input[name="csrf_token"]')?.value || '';
|
||||||
|
const res = await fetch(`/api/v2/settings/excluded_tags/${encodeURIComponent(tag)}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-Token': csrf
|
||||||
|
}
|
||||||
|
});
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data.success) renderTags();
|
if (data.success) {
|
||||||
|
renderTags();
|
||||||
|
if (typeof gridCacheMap !== 'undefined') gridCacheMap.clear();
|
||||||
|
} else {
|
||||||
|
window.flashMessage(data.msg || 'Error removing tag', 3000, 'error');
|
||||||
|
}
|
||||||
} catch (e) { console.error(e); }
|
} catch (e) { console.error(e); }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1199,6 +1199,19 @@
|
|||||||
? `<span class="sidebar-personalized-pill" title="Personalized recommendation based on your interests"><i class="fa-solid fa-wand-magic-sparkles"></i> For You</span>`
|
? `<span class="sidebar-personalized-pill" title="Personalized recommendation based on your interests"><i class="fa-solid fa-wand-magic-sparkles"></i> For You</span>`
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
|
const isDev = !!(window.f0ckSession && window.f0ckSession.development);
|
||||||
|
const rawScore = (typeof video.score === 'number')
|
||||||
|
? video.score
|
||||||
|
: (typeof video.rank_score === 'number' ? video.rank_score : (video.xd_score || 0));
|
||||||
|
const formattedScore = (typeof rawScore === 'number')
|
||||||
|
? (Number.isInteger(rawScore) ? rawScore : +(rawScore.toFixed(1)))
|
||||||
|
: rawScore;
|
||||||
|
|
||||||
|
const devScoreAttr = isDev ? ` data-score="${escapeHtml(String(formattedScore))}"` : '';
|
||||||
|
const devScoreBadge = isDev
|
||||||
|
? `<span class="sidebar-video-score sidebar-dev-score" title="Development Score: ${formattedScore} (Algo: ${video.score ?? video.rank_score ?? 0}, xD: ${video.xd_score ?? 0})"><i class="fa-solid fa-code"></i> score: ${formattedScore}</span>`
|
||||||
|
: '';
|
||||||
|
|
||||||
const isTagFeed = options.isTagFeed || false;
|
const isTagFeed = options.isTagFeed || false;
|
||||||
const tagContext = options.tag || null;
|
const tagContext = options.tag || null;
|
||||||
const targetHref = (isTagFeed && tagContext)
|
const targetHref = (isTagFeed && tagContext)
|
||||||
@@ -1207,7 +1220,7 @@
|
|||||||
const activeClass = options.isActive ? ' active-tag-item' : '';
|
const activeClass = options.isActive ? ' active-tag-item' : '';
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="sidebar-video-card${activeClass}" data-id="${video.id}" data-slug="${escapeHtml(video.slug || '')}" data-file="${escapeHtml(video.dest || '')}" data-mime="${escapeHtml(video.mime || '')}" data-ext="${escapeHtml(ext ? ext.toLowerCase() : '')}" data-mode="${rClass}" data-personalized="${video.personalized ? 'true' : 'false'}">
|
<div class="sidebar-video-card${activeClass}" data-id="${video.id}" data-slug="${escapeHtml(video.slug || '')}" data-file="${escapeHtml(video.dest || '')}" data-mime="${escapeHtml(video.mime || '')}" data-ext="${escapeHtml(ext ? ext.toLowerCase() : '')}" data-mode="${rClass}" data-personalized="${video.personalized ? 'true' : 'false'}"${devScoreAttr}>
|
||||||
<a href="${targetHref}" class="sidebar-video-link" data-mode="${rClass}" data-inherit-context="false">
|
<a href="${targetHref}" class="sidebar-video-link" data-mode="${rClass}" data-inherit-context="false">
|
||||||
<div class="sidebar-video-thumb-wrap" data-file="${escapeHtml(video.dest || '')}" data-mime="${escapeHtml(video.mime || '')}" data-ext="${escapeHtml(ext ? ext.toLowerCase() : '')}" data-mode="${rClass}">
|
<div class="sidebar-video-thumb-wrap" data-file="${escapeHtml(video.dest || '')}" data-mime="${escapeHtml(video.mime || '')}" data-ext="${escapeHtml(ext ? ext.toLowerCase() : '')}" data-mode="${rClass}">
|
||||||
${thumbContentHtml}
|
${thumbContentHtml}
|
||||||
@@ -1226,6 +1239,8 @@
|
|||||||
${xdBadge}
|
${xdBadge}
|
||||||
${((timeStr || xdBadge) && forYouBadge) ? `•` : ''}
|
${((timeStr || xdBadge) && forYouBadge) ? `•` : ''}
|
||||||
${forYouBadge}
|
${forYouBadge}
|
||||||
|
${((timeStr || xdBadge || forYouBadge) && devScoreBadge) ? `•` : ''}
|
||||||
|
${devScoreBadge}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+71
-7
@@ -19,6 +19,10 @@ import queue from "../src/inc/queue.mjs";
|
|||||||
import cfg from "../src/inc/config.mjs";
|
import cfg from "../src/inc/config.mjs";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
const STATE_FILE = path.join(__dirname, '.regen_state.json');
|
||||||
|
|
||||||
const args = process.argv.slice(2);
|
const args = process.argv.slice(2);
|
||||||
|
|
||||||
@@ -31,6 +35,8 @@ if (args.length === 0) {
|
|||||||
console.log(' node regen.mjs --pdf - Regenerate all PDF items');
|
console.log(' node regen.mjs --pdf - Regenerate all PDF items');
|
||||||
console.log(' node regen.mjs --youtube - Regenerate all YouTube thumbnails');
|
console.log(' node regen.mjs --youtube - Regenerate all YouTube thumbnails');
|
||||||
console.log(' node regen.mjs --blur - Regenerate ONLY the blurred thumbnails for all items');
|
console.log(' node regen.mjs --blur - Regenerate ONLY the blurred thumbnails for all items');
|
||||||
|
console.log(' --from <id> - Resume/start from a specific item ID (inclusive)');
|
||||||
|
console.log(' --resume - Resume from last checkpoint saved in .regen_state.json');
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,6 +51,33 @@ const THUMB_SIZE = 512;
|
|||||||
const blurOnly = args.includes('--blur');
|
const blurOnly = args.includes('--blur');
|
||||||
console.log(`[regen] Thumb size: ${THUMB_SIZE}px\n`);
|
console.log(`[regen] Thumb size: ${THUMB_SIZE}px\n`);
|
||||||
|
|
||||||
|
let fromId = null;
|
||||||
|
const fromIdx = args.indexOf('--from');
|
||||||
|
if (fromIdx !== -1 && args[fromIdx + 1]) {
|
||||||
|
fromId = parseInt(args[fromIdx + 1], 10);
|
||||||
|
if (isNaN(fromId)) {
|
||||||
|
console.error('Invalid ID provided for --from');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fromId && args.includes('--resume')) {
|
||||||
|
try {
|
||||||
|
const raw = await fs.readFile(STATE_FILE, 'utf8');
|
||||||
|
const state = JSON.parse(raw);
|
||||||
|
if (state.lastId) {
|
||||||
|
fromId = state.lastId;
|
||||||
|
console.log(`[regen] Resuming from checkpoint at item ID: ${fromId}\n`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`[regen] No previous state checkpoint found to resume from.\n`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromId) {
|
||||||
|
console.log(`[regen] Starting from item ID >= ${fromId}\n`);
|
||||||
|
}
|
||||||
|
|
||||||
const regen = async (item) => {
|
const regen = async (item) => {
|
||||||
const { id, dest, mime, src } = item;
|
const { id, dest, mime, src } = item;
|
||||||
|
|
||||||
@@ -89,46 +122,77 @@ const regen = async (item) => {
|
|||||||
|
|
||||||
// Shared NOT IN clause for Flash exclusion
|
// Shared NOT IN clause for Flash exclusion
|
||||||
const flashExclude = db`mime NOT IN ${db(FLASH_MIMES)}`;
|
const flashExclude = db`mime NOT IN ${db(FLASH_MIMES)}`;
|
||||||
|
const fromClause = fromId ? db`AND id >= ${fromId}` : db``;
|
||||||
|
|
||||||
|
const saveState = async (id) => {
|
||||||
|
try {
|
||||||
|
await fs.writeFile(STATE_FILE, JSON.stringify({ lastId: id, timestamp: new Date().toISOString() }, null, 2));
|
||||||
|
} catch (_) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
let currentItemId = null;
|
||||||
|
process.on('SIGINT', async () => {
|
||||||
|
if (currentItemId) {
|
||||||
|
await saveState(currentItemId);
|
||||||
|
console.log(`\n[regen] Interrupted! Saved state at item ID ${currentItemId}.`);
|
||||||
|
console.log(`[regen] Resume anytime with: node scripts/regen.mjs --resume (or --from ${currentItemId})\n`);
|
||||||
|
}
|
||||||
|
process.exit(130);
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let items;
|
let items;
|
||||||
|
|
||||||
if (args.includes('--all')) {
|
if (args.includes('--all')) {
|
||||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND ${flashExclude} ORDER BY id`;
|
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND ${flashExclude} ${fromClause} ORDER BY id`;
|
||||||
console.log(`Regenerating ALL ${items.length} non-Flash items...\n`);
|
console.log(`Regenerating ALL ${items.length} non-Flash items...\n`);
|
||||||
} else if (args.includes('--audio')) {
|
} else if (args.includes('--audio')) {
|
||||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime ILIKE 'audio/%' ORDER BY id`;
|
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime ILIKE 'audio/%' ${fromClause} ORDER BY id`;
|
||||||
console.log(`Regenerating ${items.length} audio items...\n`);
|
console.log(`Regenerating ${items.length} audio items...\n`);
|
||||||
} else if (args.includes('--pdf')) {
|
} else if (args.includes('--pdf')) {
|
||||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime = 'application/pdf' ORDER BY id`;
|
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime = 'application/pdf' ${fromClause} ORDER BY id`;
|
||||||
console.log(`Regenerating ${items.length} PDF items...\n`);
|
console.log(`Regenerating ${items.length} PDF items...\n`);
|
||||||
} else if (args.includes('--youtube')) {
|
} else if (args.includes('--youtube')) {
|
||||||
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime = 'video/youtube' ORDER BY id`;
|
items = await db`SELECT id, dest, mime, src FROM items WHERE active = true AND is_deleted = false AND mime = 'video/youtube' ${fromClause} ORDER BY id`;
|
||||||
console.log(`Regenerating ${items.length} YouTube items...\n`);
|
console.log(`Regenerating ${items.length} YouTube items...\n`);
|
||||||
} else if (blurOnly) {
|
} else if (blurOnly) {
|
||||||
items = await db`
|
items = await db`
|
||||||
SELECT id, dest, mime, src
|
SELECT id, dest, mime, src
|
||||||
FROM items
|
FROM items
|
||||||
WHERE active = true AND is_deleted = false AND ${flashExclude}
|
WHERE active = true AND is_deleted = false AND ${flashExclude} ${fromClause}
|
||||||
ORDER BY id
|
ORDER BY id
|
||||||
`;
|
`;
|
||||||
console.log(`Regenerating ONLY blurred thumbnails for all ${items.length} non-Flash items...\n`);
|
console.log(`Regenerating ONLY blurred thumbnails for all ${items.length} non-Flash items...\n`);
|
||||||
} else {
|
} else {
|
||||||
const ids = args.map(Number).filter(n => !isNaN(n) && n > 0);
|
const positionalArgs = [];
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
if (args[i] === '--from') {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[i].startsWith('--')) continue;
|
||||||
|
positionalArgs.push(args[i]);
|
||||||
|
}
|
||||||
|
const ids = positionalArgs.map(Number).filter(n => !isNaN(n) && n > 0);
|
||||||
if (ids.length === 0) {
|
if (ids.length === 0) {
|
||||||
console.error('No valid item IDs provided.');
|
console.error('No valid item IDs provided.');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
items = await db`SELECT id, dest, mime, src FROM items WHERE id IN ${db(ids)} ORDER BY id`;
|
items = await db`SELECT id, dest, mime, src FROM items WHERE id IN ${db(ids)} ${fromClause} ORDER BY id`;
|
||||||
const found = items.map(i => i.id);
|
const found = items.map(i => i.id);
|
||||||
const missing = ids.filter(id => !found.includes(id));
|
const missing = ids.filter(id => !found.includes(id));
|
||||||
if (missing.length) console.warn(`Items not found: ${missing.join(', ')}\n`);
|
if (missing.length) console.warn(`Items not found: ${missing.join(', ')}\n`);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
|
currentItemId = item.id;
|
||||||
await regen(item);
|
await regen(item);
|
||||||
|
await saveState(item.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean up state file on normal completion
|
||||||
|
await fs.unlink(STATE_FILE).catch(() => {});
|
||||||
|
|
||||||
console.log(`\nDone. ${items.length} items processed.`);
|
console.log(`\nDone. ${items.length} items processed.`);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -277,7 +277,8 @@
|
|||||||
"video": "Video",
|
"video": "Video",
|
||||||
"audio": "Audio",
|
"audio": "Audio",
|
||||||
"image": "Bild",
|
"image": "Bild",
|
||||||
"flash": "Flash"
|
"flash": "Flash",
|
||||||
|
"grid_mode": "Thumbnailgröße"
|
||||||
},
|
},
|
||||||
"shortcuts": {
|
"shortcuts": {
|
||||||
"title": "Tastaturkürzel",
|
"title": "Tastaturkürzel",
|
||||||
|
|||||||
@@ -277,7 +277,8 @@
|
|||||||
"video": "Video",
|
"video": "Video",
|
||||||
"audio": "Audio",
|
"audio": "Audio",
|
||||||
"image": "Image",
|
"image": "Image",
|
||||||
"flash": "Flash"
|
"flash": "Flash",
|
||||||
|
"grid_mode": "Thumbnail size"
|
||||||
},
|
},
|
||||||
"shortcuts": {
|
"shortcuts": {
|
||||||
"title": "Keyboard Shortcuts",
|
"title": "Keyboard Shortcuts",
|
||||||
|
|||||||
@@ -275,7 +275,8 @@
|
|||||||
"video": "Video",
|
"video": "Video",
|
||||||
"audio": "Audio",
|
"audio": "Audio",
|
||||||
"image": "Afbeelding",
|
"image": "Afbeelding",
|
||||||
"flash": "Flash"
|
"flash": "Flash",
|
||||||
|
"grid_mode": "Thumbnailgrootte"
|
||||||
},
|
},
|
||||||
"shortcuts": {
|
"shortcuts": {
|
||||||
"title": "Sneltoetsen",
|
"title": "Sneltoetsen",
|
||||||
|
|||||||
@@ -273,7 +273,8 @@
|
|||||||
"video": "Video",
|
"video": "Video",
|
||||||
"audio": "Tondatei",
|
"audio": "Tondatei",
|
||||||
"image": "Bild",
|
"image": "Bild",
|
||||||
"flash": "Blitz"
|
"flash": "Blitz",
|
||||||
|
"grid_mode": "Vorschaubildgröße"
|
||||||
},
|
},
|
||||||
"shortcuts": {
|
"shortcuts": {
|
||||||
"title": "Tastaturkürzel",
|
"title": "Tastaturkürzel",
|
||||||
|
|||||||
@@ -2203,7 +2203,9 @@ const f0cklib = {
|
|||||||
xd_label: meta.label,
|
xd_label: meta.label,
|
||||||
width: r.width,
|
width: r.width,
|
||||||
height: r.height,
|
height: r.height,
|
||||||
has_coverart: !!r.has_coverart
|
has_coverart: !!r.has_coverart,
|
||||||
|
score: 0,
|
||||||
|
rank_score: 0
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -2481,7 +2483,9 @@ const f0cklib = {
|
|||||||
width: r.width,
|
width: r.width,
|
||||||
height: r.height,
|
height: r.height,
|
||||||
has_coverart: !!r.has_coverart,
|
has_coverart: !!r.has_coverart,
|
||||||
personalized: true
|
personalized: true,
|
||||||
|
score: r.rank_score != null ? Math.round(Number(r.rank_score) * 10) / 10 : 0,
|
||||||
|
rank_score: r.rank_score != null ? Math.round(Number(r.rank_score) * 10) / 10 : 0
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -2682,7 +2686,9 @@ const f0cklib = {
|
|||||||
xd_label: meta.label,
|
xd_label: meta.label,
|
||||||
width: r.width,
|
width: r.width,
|
||||||
height: r.height,
|
height: r.height,
|
||||||
has_coverart: !!r.has_coverart
|
has_coverart: !!r.has_coverart,
|
||||||
|
score: r.xd_score || 0,
|
||||||
|
rank_score: 0
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -761,7 +761,9 @@ export default router => {
|
|||||||
rating_class: item.rating_class,
|
rating_class: item.rating_class,
|
||||||
xd_score: item.xd_score,
|
xd_score: item.xd_score,
|
||||||
xd_tier: item.xd_tier,
|
xd_tier: item.xd_tier,
|
||||||
personalized: !!item.personalized
|
personalized: !!item.personalized,
|
||||||
|
score: typeof item.score === 'number' ? item.score : (typeof item.rank_score === 'number' ? item.rank_score : (item.xd_score || 0)),
|
||||||
|
rank_score: item.rank_score ?? item.score ?? 0
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export default router => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
group.post(/\/excluded_tags/, lib.loggedin, async (req, res) => {
|
group.post(/\/excluded_tags/, lib.loggedin, async (req, res) => {
|
||||||
const tagname = req.post.tagname;
|
const tagname = req.post?.tagname || req.body?.tagname;
|
||||||
if (!tagname) return res.json({ success: false, msg: 'No tag provided' }, 400);
|
if (!tagname) return res.json({ success: false, msg: 'No tag provided' }, 400);
|
||||||
|
|
||||||
const tag = (await db`select id, tag, normalized from tags where normalized = slugify(${tagname})`)[0];
|
const tag = (await db`select id, tag, normalized from tags where normalized = slugify(${tagname})`)[0];
|
||||||
@@ -92,10 +92,17 @@ export default router => {
|
|||||||
|
|
||||||
await db`
|
await db`
|
||||||
update user_options
|
update user_options
|
||||||
set excluded_tags = array_append(excluded_tags, ${tag.id})
|
set excluded_tags = array_append(coalesce(excluded_tags, '{}'), ${tag.id})
|
||||||
where user_id = ${+req.session.id} and not (${tag.id} = any(excluded_tags))
|
where user_id = ${+req.session.id} and not (${tag.id} = any(coalesce(excluded_tags, '{}')))
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
if (req.session) {
|
||||||
|
if (!req.session.excluded_tags) req.session.excluded_tags = [];
|
||||||
|
if (!req.session.excluded_tags.includes(tag.id)) {
|
||||||
|
req.session.excluded_tags.push(tag.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Return updated list
|
// Return updated list
|
||||||
const tags = await db`
|
const tags = await db`
|
||||||
select t.id, t.tag, t.normalized
|
select t.id, t.tag, t.normalized
|
||||||
@@ -114,10 +121,14 @@ export default router => {
|
|||||||
|
|
||||||
await db`
|
await db`
|
||||||
update user_options
|
update user_options
|
||||||
set excluded_tags = array_remove(excluded_tags, ${tag.id})
|
set excluded_tags = array_remove(coalesce(excluded_tags, '{}'), ${tag.id})
|
||||||
where user_id = ${+req.session.id}
|
where user_id = ${+req.session.id}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
if (req.session && req.session.excluded_tags) {
|
||||||
|
req.session.excluded_tags = req.session.excluded_tags.filter(id => id !== tag.id);
|
||||||
|
}
|
||||||
|
|
||||||
const tags = await db`
|
const tags = await db`
|
||||||
select t.id, t.tag, t.normalized
|
select t.id, t.tag, t.normalized
|
||||||
from unnest((select excluded_tags from user_options where user_id = ${+req.session.id})) as et(id)
|
from unnest((select excluded_tags from user_options where user_id = ${+req.session.id})) as et(id)
|
||||||
|
|||||||
Reference in New Issue
Block a user