Show viewer name on active streams for app clients.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
79f9d8b7f8
commit
6a637ab2ef
1 changed files with 35 additions and 3 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue