From 755336b16aee9fcec21673317f822e61cc33c28f Mon Sep 17 00:00:00 2001 From: Dean Wenstrand Date: Sat, 9 May 2026 12:02:57 -0700 Subject: [PATCH] Add playerSummaries to schema + Video fragments Backs the multi-player vs UI: feed cards and the detail page both read `video.playerSummaries`, a per-cluster rollup with username, profile image, representative full-frame URL, makes/total/percentage. - PlayerSummaryFields fragment in shooter.gql - VideoCardFields (feed) and GetVideoDetails (detail) include playerSummaries via the new fragment - VideoCardFields tag selection extended to include tagClasses, needed for the FE's player_count detection Generated by `just gql` from the BE additions in railbird PR dean/video-player-summaries. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/index.tsx | 110 ++++++++++++++++++++++++++++++++++++- src/operations/feed.gql | 6 ++ src/operations/shooter.gql | 11 ++++ src/operations/video.gql | 3 + src/schema.gql | 12 ++++ 5 files changed, 139 insertions(+), 3 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index fddbb05..b04875a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2718,6 +2718,18 @@ export type PlayerClusterShotGql = { shotId: Scalars["Int"]["output"]; }; +export type PlayerSummaryGql = { + __typename?: "PlayerSummaryGQL"; + clusterId: Scalars["Int"]["output"]; + makePercentage: Scalars["Float"]["output"]; + profileImageUri?: Maybe; + representativeFullFrameUrl?: Maybe; + totalShots: Scalars["Int"]["output"]; + totalShotsMade: Scalars["Int"]["output"]; + userId?: Maybe; + username?: Maybe; +}; + export enum PocketEnum { Corner = "CORNER", Side = "SIDE", @@ -3557,6 +3569,7 @@ export type VideoGql = { medianRun?: Maybe; name?: Maybe; owner?: Maybe; + playerSummaries: Array; playlist?: Maybe; pocketSize?: Maybe; private: Scalars["Boolean"]["output"]; @@ -4174,7 +4187,22 @@ export type GetFeedQuery = { lastIntendedSegmentBound?: number | null; streamSegmentType: StreamSegmentTypeEnum; } | null; - tags: Array<{ __typename?: "VideoTag"; name: string }>; + tags: Array<{ + __typename?: "VideoTag"; + name: string; + tagClasses: Array<{ __typename?: "VideoTagClass"; name: string }>; + }>; + playerSummaries: Array<{ + __typename?: "PlayerSummaryGQL"; + clusterId: number; + userId?: number | null; + username?: string | null; + profileImageUri?: string | null; + representativeFullFrameUrl?: string | null; + totalShots: number; + totalShotsMade: number; + makePercentage: number; + }>; currentProcessing?: { __typename?: "VideoProcessingGQL"; id: number; @@ -4259,7 +4287,22 @@ export type VideoCardFieldsFragment = { lastIntendedSegmentBound?: number | null; streamSegmentType: StreamSegmentTypeEnum; } | null; - tags: Array<{ __typename?: "VideoTag"; name: string }>; + tags: Array<{ + __typename?: "VideoTag"; + name: string; + tagClasses: Array<{ __typename?: "VideoTagClass"; name: string }>; + }>; + playerSummaries: Array<{ + __typename?: "PlayerSummaryGQL"; + clusterId: number; + userId?: number | null; + username?: string | null; + profileImageUri?: string | null; + representativeFullFrameUrl?: string | null; + totalShots: number; + totalShotsMade: number; + makePercentage: number; + }>; currentProcessing?: { __typename?: "VideoProcessingGQL"; id: number; @@ -4358,7 +4401,22 @@ export type GetVideoFeedQuery = { lastIntendedSegmentBound?: number | null; streamSegmentType: StreamSegmentTypeEnum; } | null; - tags: Array<{ __typename?: "VideoTag"; name: string }>; + tags: Array<{ + __typename?: "VideoTag"; + name: string; + tagClasses: Array<{ __typename?: "VideoTagClass"; name: string }>; + }>; + playerSummaries: Array<{ + __typename?: "PlayerSummaryGQL"; + clusterId: number; + userId?: number | null; + username?: string | null; + profileImageUri?: string | null; + representativeFullFrameUrl?: string | null; + totalShots: number; + totalShotsMade: number; + makePercentage: number; + }>; currentProcessing?: { __typename?: "VideoProcessingGQL"; id: number; @@ -4929,6 +4987,18 @@ export type GetRunsWithTimestampsQuery = { }; }; +export type PlayerSummaryFieldsFragment = { + __typename?: "PlayerSummaryGQL"; + clusterId: number; + userId?: number | null; + username?: string | null; + profileImageUri?: string | null; + representativeFullFrameUrl?: string | null; + totalShots: number; + totalShotsMade: number; + makePercentage: number; +}; + export type PlayerClusterShotFieldsFragment = { __typename?: "PlayerClusterShotGQL"; shotId: number; @@ -5955,6 +6025,17 @@ export type GetVideoDetailsQuery = { name: string; tagClasses: Array<{ __typename?: "VideoTagClass"; name: string }>; }>; + playerSummaries: Array<{ + __typename?: "PlayerSummaryGQL"; + clusterId: number; + userId?: number | null; + username?: string | null; + profileImageUri?: string | null; + representativeFullFrameUrl?: string | null; + totalShots: number; + totalShotsMade: number; + makePercentage: number; + }>; }; }; @@ -6612,6 +6693,18 @@ export type GetUploadStreamsWithDetailsQuery = { }; }; +export const PlayerSummaryFieldsFragmentDoc = gql` + fragment PlayerSummaryFields on PlayerSummaryGQL { + clusterId + userId + username + profileImageUri + representativeFullFrameUrl + totalShots + totalShotsMade + makePercentage + } +`; export const UserSocialsFieldsFragmentDoc = gql` fragment UserSocialsFields on UserGQL { id @@ -6646,6 +6739,12 @@ export const VideoCardFieldsFragmentDoc = gql` pocketSize tags { name + tagClasses { + name + } + } + playerSummaries { + ...PlayerSummaryFields } currentProcessing { id @@ -6673,6 +6772,7 @@ export const VideoCardFieldsFragmentDoc = gql` } } } + ${PlayerSummaryFieldsFragmentDoc} ${UserSocialsFieldsFragmentDoc} `; export const MedalFieldsFragmentDoc = gql` @@ -12666,8 +12766,12 @@ export const GetVideoDetailsDocument = gql` } name } + playerSummaries { + ...PlayerSummaryFields + } } } + ${PlayerSummaryFieldsFragmentDoc} `; /** diff --git a/src/operations/feed.gql b/src/operations/feed.gql index e679e80..b85ffb9 100644 --- a/src/operations/feed.gql +++ b/src/operations/feed.gql @@ -47,6 +47,12 @@ fragment VideoCardFields on VideoGQL { pocketSize tags { name + tagClasses { + name + } + } + playerSummaries { + ...PlayerSummaryFields } currentProcessing { id diff --git a/src/operations/shooter.gql b/src/operations/shooter.gql index 84b2e1c..e855563 100644 --- a/src/operations/shooter.gql +++ b/src/operations/shooter.gql @@ -1,3 +1,14 @@ +fragment PlayerSummaryFields on PlayerSummaryGQL { + clusterId + userId + username + profileImageUri + representativeFullFrameUrl + totalShots + totalShotsMade + makePercentage +} + fragment PlayerClusterShotFields on PlayerClusterShotGQL { shotId bboxX1 diff --git a/src/operations/video.gql b/src/operations/video.gql index 91a0196..bbf0c46 100644 --- a/src/operations/video.gql +++ b/src/operations/video.gql @@ -83,6 +83,9 @@ query GetVideoDetails($videoId: Int!) { } name } + playerSummaries { + ...PlayerSummaryFields + } } } diff --git a/src/schema.gql b/src/schema.gql index 6bde6b7..e802033 100644 --- a/src/schema.gql +++ b/src/schema.gql @@ -406,6 +406,7 @@ type VideoGQL { currentProcessing: VideoProcessingGQL reactions: [ReactionGQL!]! comments: [CommentGQL!]! + playerSummaries: [PlayerSummaryGQL!]! } type ShotGQL { @@ -665,6 +666,17 @@ type CommentGQL { replies: [CommentGQL!]! } +type PlayerSummaryGQL { + clusterId: Int! + userId: Int + username: String + profileImageUri: String + representativeFullFrameUrl: String + totalShots: Int! + totalShotsMade: Int! + makePercentage: Float! +} + type DeployedConfigGQL { allowNewUsers: Boolean! firebase: Boolean! -- 2.49.1