Enhance notification handling by enriching notifications with character names
This commit is contained in:
@@ -4200,12 +4200,17 @@ class FalukantService extends BaseService {
|
|||||||
return undergroundTypes;
|
return undergroundTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async getNotifications(hashedUserId) {
|
async getNotifications(hashedUserId) {
|
||||||
const user = await getFalukantUserOrFail(hashedUserId);
|
const user = await getFalukantUserOrFail(hashedUserId);
|
||||||
const notifications = await Notification.findAll({
|
const notifications = await Notification.findAll({
|
||||||
where: { userId: user.id, shown: false },
|
where: { userId: user.id, shown: false },
|
||||||
order: [['createdAt', 'DESC']]
|
order: [['createdAt', 'DESC']]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Enrich notifications: parse JSON payloads and resolve character names
|
||||||
|
await enrichNotificationsWithCharacterNames(notifications);
|
||||||
|
|
||||||
return notifications;
|
return notifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4219,6 +4224,9 @@ class FalukantService extends BaseService {
|
|||||||
offset,
|
offset,
|
||||||
limit,
|
limit,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await enrichNotificationsWithCharacterNames(rows);
|
||||||
|
|
||||||
return { items: rows, total: count, page: Number(page) || 1, size: limit };
|
return { items: rows, total: count, page: Number(page) || 1, size: limit };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4524,3 +4532,83 @@ class FalukantService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default new FalukantService();
|
export default new FalukantService();
|
||||||
|
|
||||||
|
// Helper: parse notifications for character references and attach characterName
|
||||||
|
async function enrichNotificationsWithCharacterNames(notifications) {
|
||||||
|
if (!Array.isArray(notifications) || notifications.length === 0) return;
|
||||||
|
|
||||||
|
const charIds = new Set();
|
||||||
|
|
||||||
|
for (const n of notifications) {
|
||||||
|
// Notification.tr may be either a translation key or a JSON string with params
|
||||||
|
let parsed = null;
|
||||||
|
try {
|
||||||
|
parsed = typeof n.tr === 'string' && n.tr.trim().startsWith('{') ? JSON.parse(n.tr) : null;
|
||||||
|
} catch (err) {
|
||||||
|
parsed = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If parsed JSON contains character_id or characterId or character, collect it
|
||||||
|
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 {
|
||||||
|
if (n.effects) {
|
||||||
|
const eff = typeof n.effects === 'string' && n.effects.trim().startsWith('{') ? JSON.parse(n.effects) : n.effects;
|
||||||
|
if (Array.isArray(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) {
|
||||||
|
// ignore parse errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ids = Array.from(charIds).filter(Boolean);
|
||||||
|
if (!ids.length) return;
|
||||||
|
|
||||||
|
// Batch load characters and their display names
|
||||||
|
const characters = await FalukantCharacter.findAll({
|
||||||
|
where: { id: { [Op.in]: ids } },
|
||||||
|
include: [
|
||||||
|
{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] },
|
||||||
|
{ model: FalukantPredefineLastname, as: 'definedLastName', attributes: ['name'] }
|
||||||
|
],
|
||||||
|
attributes: ['id']
|
||||||
|
});
|
||||||
|
|
||||||
|
const nameMap = new Map();
|
||||||
|
for (const c of characters) {
|
||||||
|
const first = c.definedFirstName?.name || '';
|
||||||
|
const last = c.definedLastName?.name || '';
|
||||||
|
const display = `${first} ${last}`.trim() || null;
|
||||||
|
nameMap.set(c.id, display || `#${c.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach resolved name to notifications
|
||||||
|
for (const n of notifications) {
|
||||||
|
let parsed = null;
|
||||||
|
try { parsed = typeof n.tr === 'string' && n.tr.trim().startsWith('{') ? JSON.parse(n.tr) : null; } catch (e) { parsed = null; }
|
||||||
|
let foundId = null;
|
||||||
|
if (parsed) {
|
||||||
|
foundId = parsed.character_id || parsed.characterId || (parsed.character && parsed.character.id) || null;
|
||||||
|
}
|
||||||
|
if (!foundId && n.character_id) foundId = n.character_id;
|
||||||
|
if (!foundId && n.characterId) foundId = n.characterId;
|
||||||
|
|
||||||
|
if (foundId && nameMap.has(foundId)) {
|
||||||
|
// attach property used by frontend
|
||||||
|
n.characterName = nameMap.get(foundId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user