sendou.ink/app/features/core/streams/streams.server.ts
2026-03-08 08:02:05 +02:00

72 lines
2.1 KiB
TypeScript

import type { TournamentTierNumber } from "~/features/tournament/core/tiering";
import { RunningTournaments } from "~/features/tournament-bracket/core/RunningTournaments.server";
import type { Tournament } from "~/features/tournament-bracket/core/Tournament";
import { Status } from "~/modules/brackets-model";
import { cache } from "~/utils/cache.server";
import { dateToDatabaseTimestamp } from "~/utils/dates";
import { tournamentStreamsPage } from "~/utils/urls";
export const COMBINED_STREAMS_KEY = "combined-streams";
export function clearCombinedStreamsCache() {
cache.delete(COMBINED_STREAMS_KEY);
}
export type SidebarStream = {
id: string;
name: string;
imageUrl: string;
overlayIconUrl?: string;
url: string;
subtitle: string;
startsAt: number;
tier: TournamentTierNumber | null;
tentativeTier?: number;
peakXp?: number;
twitchUsername?: string;
};
export function getLiveTournamentStreams(): SidebarStream[] {
const streams: SidebarStream[] = [];
for (const tournament of RunningTournaments.all) {
streams.push({
id: `tournament-${tournament.ctx.id}`,
name: tournament.ctx.name,
imageUrl: tournament.ctx.logoUrl,
url: tournamentStreamsPage(tournament.ctx.id),
subtitle: deriveCurrentRound(tournament),
startsAt: dateToDatabaseTimestamp(tournament.ctx.startTime),
tier: tournament.ctx.tier,
});
}
return streams;
}
function deriveCurrentRound(tournament: Tournament): string {
for (const bracket of tournament.brackets.toReversed()) {
if (bracket.preview) continue;
if (bracket.isUnderground) continue;
for (const match of bracket.data.match) {
const isActive =
match.status === Status.Ready || match.status === Status.Running;
const hasParticipants = match.opponent1 && match.opponent2;
const isNotFinished =
!match.opponent1?.result && !match.opponent2?.result;
if (isActive && hasParticipants && isNotFinished) {
const context = tournament.matchContextNamesById(match.id);
if (context?.roundNameWithoutMatchIdentifier) {
return context.roundNameWithoutMatchIdentifier;
}
}
}
return bracket.name;
}
return "";
}