Show viewer name on active streams for app clients.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jos Vooges | STH 2026-09-08 13:47:12 +02:00
parent 79f9d8b7f8
commit 6a637ab2ef

View file

@ -271,7 +271,13 @@ export async function registerAdminRoutes(app: FastifyInstance, config: Config)
}, },
include: { include: {
node: { select: { id: true, name: true } }, node: { select: { id: true, name: true } },
addonToken: { select: { id: true, label: true } }, addonToken: {
select: {
id: true,
label: true,
viewerUser: { select: { id: true, name: true, email: true } },
},
},
mediaFile: { mediaFile: {
include: { include: {
movie: { select: { title: true, year: true } }, movie: { select: { title: true, year: true } },
@ -285,6 +291,31 @@ export async function registerAdminRoutes(app: FastifyInstance, config: Config)
take: 100, take: 100,
}); });
// App-clients zetten ViewerUser.id in userId (zonder addonToken).
const viewerIds = [...new Set(sessions.map((s) => s.userId).filter((id): id is string => !!id))];
const viewerUsers =
viewerIds.length > 0
? await prisma.viewerUser.findMany({
where: { id: { in: viewerIds } },
select: { id: true, name: true, email: true },
})
: [];
const viewerById = new Map(viewerUsers.map((v) => [v.id, v]));
function streamViewerLabel(s: (typeof sessions)[number]): string {
const tokenLabel = s.addonToken?.label?.trim();
if (tokenLabel) return tokenLabel;
const linked =
s.addonToken?.viewerUser?.name?.trim() ||
s.addonToken?.viewerUser?.email?.trim();
if (linked) return linked;
if (s.userId) {
const v = viewerById.get(s.userId);
if (v) return v.name?.trim() || v.email;
}
return "Onbekend";
}
// Eén rij per kijker+titel (hoogste bytes wint) — niet per mediabestand. // Eén rij per kijker+titel (hoogste bytes wint) — niet per mediabestand.
const best = new Map<string, (typeof sessions)[number]>(); const best = new Map<string, (typeof sessions)[number]>();
for (const s of sessions) { for (const s of sessions) {
@ -293,7 +324,8 @@ export async function registerAdminRoutes(app: FastifyInstance, config: Config)
(s.mediaFile.episode (s.mediaFile.episode
? `ep:${s.mediaFile.episode.seriesId ?? ""}:${s.mediaFile.episode.seasonNumber}:${s.mediaFile.episode.episodeNumber}` ? `ep:${s.mediaFile.episode.seriesId ?? ""}:${s.mediaFile.episode.seasonNumber}:${s.mediaFile.episode.episodeNumber}`
: s.mediaFileId); : s.mediaFileId);
const key = `${s.addonTokenId ?? s.id}:${titleKey}`; const viewerKey = s.addonTokenId ?? s.userId ?? s.id;
const key = `${viewerKey}:${titleKey}`;
const prev = best.get(key); const prev = best.get(key);
if (!prev || s.bytesSent > prev.bytesSent) best.set(key, s); if (!prev || s.bytesSent > prev.bytesSent) best.set(key, s);
} }
@ -317,7 +349,7 @@ export async function registerAdminRoutes(app: FastifyInstance, config: Config)
id: s.id, id: s.id,
node: s.node.name, node: s.node.name,
status: s.status, status: s.status,
viewer: s.addonToken?.label?.trim() || "Onbekend", viewer: streamViewerLabel(s),
addonTokenId: s.addonToken?.id ?? null, addonTokenId: s.addonToken?.id ?? null,
createdAt: s.createdAt, createdAt: s.createdAt,
lastActivity: s.lastActivity, lastActivity: s.lastActivity,