Enhance notification enrichment by recursively collecting character IDs and attaching character names

This commit is contained in:
Torsten Schulz (local)
2025-12-09 00:06:09 +01:00
parent 1892877b11
commit 676629bd8d

View File

@@ -4539,39 +4539,52 @@ async function enrichNotificationsWithCharacterNames(notifications) {
const charIds = new Set(); const charIds = new Set();
// recursive collector that extracts any character id fields
function collectIds(obj) {
if (!obj) return;
if (Array.isArray(obj)) {
for (const it of obj) collectIds(it);
return;
}
if (typeof obj !== 'object') return;
for (const [k, v] of Object.entries(obj)) {
if (!v) continue;
if (k === 'character_id' || k === 'characterId') {
charIds.add(Number(v));
continue;
}
if (k === 'character' && typeof v === 'object') {
if (v.id) charIds.add(Number(v.id));
if (v.character_id) charIds.add(Number(v.character_id));
if (v.characterId) charIds.add(Number(v.characterId));
collectIds(v);
continue;
}
collectIds(v);
}
}
// First pass: collect all referenced character ids from notifications
for (const n of notifications) { for (const n of notifications) {
// Notification.tr may be either a translation key or a JSON string with params // parse n.tr if it's JSON
let parsed = null;
try { try {
parsed = typeof n.tr === 'string' && n.tr.trim().startsWith('{') ? JSON.parse(n.tr) : null; if (typeof n.tr === 'string' && n.tr.trim().startsWith('{')) {
} catch (err) { const parsed = JSON.parse(n.tr);
parsed = null; collectIds(parsed);
} }
} catch (err) { /* ignore */ }
// If parsed JSON contains character_id or characterId or character, collect it // parse n.effects if present
if (parsed) {
if (parsed.character_id) charIds.add(parsed.character_id);
if (parsed.characterId) charIds.add(parsed.characterId);
if (parsed.character && typeof parsed.character === 'object' && parsed.character.id) charIds.add(parsed.character.id);
}
// Also check effects or other fields on the notification row
try { try {
if (n.effects) { if (n.effects) {
const eff = typeof n.effects === 'string' && n.effects.trim().startsWith('{') ? JSON.parse(n.effects) : n.effects; const eff = typeof n.effects === 'string' && n.effects.trim().startsWith('{') ? JSON.parse(n.effects) : n.effects;
if (Array.isArray(eff)) { collectIds(eff);
for (const e of eff) {
if (e.character_id) charIds.add(e.character_id);
if (e.characterId) charIds.add(e.characterId);
}
} else if (eff && typeof eff === 'object') {
if (eff.character_id) charIds.add(eff.character_id);
if (eff.characterId) charIds.add(eff.characterId);
}
} }
} catch (err) { } catch (err) { /* ignore */ }
// ignore parse errors
} // top-level fields
if (n.character_id) charIds.add(Number(n.character_id));
if (n.characterId) charIds.add(Number(n.characterId));
} }
const ids = Array.from(charIds).filter(Boolean); const ids = Array.from(charIds).filter(Boolean);
@@ -4592,23 +4605,58 @@ async function enrichNotificationsWithCharacterNames(notifications) {
const first = c.definedFirstName?.name || ''; const first = c.definedFirstName?.name || '';
const last = c.definedLastName?.name || ''; const last = c.definedLastName?.name || '';
const display = `${first} ${last}`.trim() || null; const display = `${first} ${last}`.trim() || null;
nameMap.set(c.id, display || `#${c.id}`); nameMap.set(Number(c.id), display || `#${c.id}`);
} }
// Attach resolved name to notifications // helper to find first character id in an object
for (const n of notifications) { function findFirstId(obj) {
let parsed = null; if (!obj) return null;
try { parsed = typeof n.tr === 'string' && n.tr.trim().startsWith('{') ? JSON.parse(n.tr) : null; } catch (e) { parsed = null; } if (Array.isArray(obj)) {
let foundId = null; for (const it of obj) {
if (parsed) { const r = findFirstId(it);
foundId = parsed.character_id || parsed.characterId || (parsed.character && parsed.character.id) || null; if (r) return r;
}
return null;
} }
if (!foundId && n.character_id) foundId = n.character_id; if (typeof obj !== 'object') return null;
if (!foundId && n.characterId) foundId = n.characterId; for (const [k, v] of Object.entries(obj)) {
if (!v) continue;
if (k === 'character_id' || k === 'characterId') return Number(v);
if (k === 'character' && typeof v === 'object') {
if (v.id) return Number(v.id);
const r = findFirstId(v);
if (r) return r;
}
const r = findFirstId(v);
if (r) return r;
}
return null;
}
if (foundId && nameMap.has(foundId)) { // Attach resolved name to notifications (set both characterName and character_name)
// attach property used by frontend for (const n of notifications) {
n.characterName = nameMap.get(foundId); let foundId = null;
try {
if (typeof n.tr === 'string' && n.tr.trim().startsWith('{')) {
const parsed = JSON.parse(n.tr);
foundId = findFirstId(parsed) || foundId;
}
} catch (err) { /* ignore */ }
try {
if (n.effects) {
const eff = typeof n.effects === 'string' && n.effects.trim().startsWith('{') ? JSON.parse(n.effects) : n.effects;
foundId = findFirstId(eff) || foundId;
}
} catch (err) { /* ignore */ }
if (!foundId && n.character_id) foundId = Number(n.character_id);
if (!foundId && n.characterId) foundId = Number(n.characterId);
if (foundId && nameMap.has(Number(foundId))) {
const resolved = nameMap.get(Number(foundId));
n.characterName = resolved;
n.character_name = resolved;
} }
} }
} }