mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-10-01 23:58:36 -05:00
Add /api/tournament/:id/streams route (#3067)
This commit is contained in:
80
app/features/api-public/routes/tournament.$id.streams.ts
Normal file
80
app/features/api-public/routes/tournament.$id.streams.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { sql } from "kysely";
|
||||
import { jsonArrayFrom } from "kysely/helpers/sqlite";
|
||||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { z } from "zod";
|
||||
import { db } from "~/db/sql";
|
||||
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
|
||||
import { id } from "~/utils/zod";
|
||||
import type { GetTournamentStreamsResponse } from "../schema";
|
||||
|
||||
const paramsSchema = z.object({
|
||||
id,
|
||||
});
|
||||
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const { id } = parseParams({
|
||||
params,
|
||||
schema: paramsSchema,
|
||||
});
|
||||
|
||||
const tournament = notFoundIfFalsy(
|
||||
await db
|
||||
.selectFrom("Tournament")
|
||||
.select([
|
||||
jsonArrayFrom(
|
||||
db
|
||||
.selectFrom("LiveStream")
|
||||
.leftJoin(
|
||||
"TournamentTeamMember",
|
||||
"TournamentTeamMember.userId",
|
||||
"LiveStream.userId",
|
||||
)
|
||||
.leftJoin(
|
||||
"TournamentTeam",
|
||||
"TournamentTeam.id",
|
||||
"TournamentTeamMember.tournamentTeamId",
|
||||
)
|
||||
.select([
|
||||
"LiveStream.userId",
|
||||
"LiveStream.twitch",
|
||||
"LiveStream.viewerCount",
|
||||
])
|
||||
.where("TournamentTeam.tournamentId", "=", id),
|
||||
).as("playerStreams"),
|
||||
jsonArrayFrom(
|
||||
db
|
||||
.selectFrom("LiveStream")
|
||||
.select(["LiveStream.twitch", "LiveStream.viewerCount"])
|
||||
.where(
|
||||
sql<boolean>`"LiveStream"."twitch" IN (SELECT value FROM json_each("Tournament"."castTwitchAccounts"))`,
|
||||
),
|
||||
).as("castStreams"),
|
||||
])
|
||||
.where("Tournament.id", "=", id)
|
||||
.executeTakeFirst(),
|
||||
);
|
||||
|
||||
const playerStreams: GetTournamentStreamsResponse =
|
||||
tournament?.playerStreams.map((stream) => ({
|
||||
type: "PLAYER",
|
||||
userId: stream.userId!,
|
||||
platform: "TWITCH",
|
||||
channelId: stream.twitch!,
|
||||
viewerCount: stream.viewerCount!,
|
||||
})) ?? [];
|
||||
|
||||
const castStreams: GetTournamentStreamsResponse =
|
||||
tournament?.castStreams.map((stream) => ({
|
||||
type: "CAST",
|
||||
platform: "TWITCH",
|
||||
channelId: stream.twitch!,
|
||||
viewerCount: stream.viewerCount!,
|
||||
})) ?? [];
|
||||
|
||||
const result: GetTournamentStreamsResponse = [
|
||||
...playerStreams,
|
||||
...castStreams,
|
||||
].sort((a, b) => b.viewerCount - a.viewerCount);
|
||||
|
||||
return Response.json(result);
|
||||
};
|
||||
@@ -292,6 +292,16 @@ type TournamentCastChannel = {
|
||||
channelId: string;
|
||||
};
|
||||
|
||||
/** GET /api/tournament/{tournamentId}/streams */
|
||||
|
||||
export type GetTournamentStreamsResponse = Array<
|
||||
{
|
||||
platform: "TWITCH";
|
||||
channelId: string;
|
||||
viewerCount: number;
|
||||
} & ({ type: "PLAYER"; userId: number } | { type: "CAST" })
|
||||
>;
|
||||
|
||||
/** GET /api/tournament-match/{matchId} */
|
||||
|
||||
export interface GetTournamentMatchResponse {
|
||||
|
||||
@@ -339,6 +339,10 @@ export default [
|
||||
"/tournament/:id/starting-brackets",
|
||||
"features/api-public/routes/tournament.$id.starting-brackets.ts",
|
||||
),
|
||||
route(
|
||||
"/tournament/:id/streams",
|
||||
"features/api-public/routes/tournament.$id.streams.ts",
|
||||
),
|
||||
route(
|
||||
"/tournament/:id/teams/:teamId/add-member",
|
||||
"features/api-public/routes/tournament.$id.teams.$teamId.add-member.ts",
|
||||
|
||||
Reference in New Issue
Block a user