From 71116165bc89c2c486c0936f96126c00d673f0b3 Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Thu, 9 Jul 2026 00:54:37 -0700 Subject: [PATCH] Add getLiveTableState query and live-stream operations - schema: getLiveTableState(videoId) returning LiveTableStateGQL (videoId, frameIndex, tableState) - operations: GetLiveTableState in shot_simulation.gql, lightweight GetLiveStreams listing in live_streams.gql - regenerated TS client outputs Co-Authored-By: Claude Fable 5 --- src/index.tsx | 274 +++++++++++++++++++++++++++++ src/operations/live_streams.gql | 34 ++++ src/operations/shot_simulation.gql | 13 ++ src/schema.gql | 7 + 4 files changed, 328 insertions(+) create mode 100644 src/operations/live_streams.gql diff --git a/src/index.tsx b/src/index.tsx index 4c3fe89..844a878 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2426,6 +2426,13 @@ export type IntPoint2DInput = { y: Scalars["Int"]["input"]; }; +export type LiveTableStateGql = { + __typename?: "LiveTableStateGQL"; + frameIndex: Scalars["Int"]["output"]; + tableState: TableStateGql; + videoId: Scalars["Int"]["output"]; +}; + export type MakePercentageIntervalGql = { __typename?: "MakePercentageIntervalGQL"; elapsedTime: Scalars["Float"]["output"]; @@ -3029,6 +3036,7 @@ export type Query = { getDrillRunLeaderboard: DrillRunLeaderboardGql; getFeedVideos: VideoHistoryGql; getGameTypeTagMetrics: Array; + getLiveTableState: LiveTableStateGql; getLoggedInUser?: Maybe; getLongestRunsLeaderboard: RunLeaderboardGql; getMakesLeaderboard: CountLeaderboardGql; @@ -3133,6 +3141,10 @@ export type QueryGetGameTypeTagMetricsArgs = { input: GameTypeTagMetricsInput; }; +export type QueryGetLiveTableStateArgs = { + videoId: Scalars["Int"]["input"]; +}; + export type QueryGetLongestRunsLeaderboardArgs = { interval?: InputMaybe; limit?: Scalars["Int"]["input"]; @@ -5101,6 +5113,43 @@ export type GetMyDrillRunsQuery = { }>; }; +export type GetLiveStreamsQueryVariables = Exact<{ + limit?: Scalars["Int"]["input"]; +}>; + +export type GetLiveStreamsQuery = { + __typename?: "Query"; + getFeedVideos: { + __typename?: "VideoHistoryGQL"; + videos: Array<{ + __typename?: "VideoGQL"; + id: number; + name?: string | null; + startTime?: any | null; + createdAt?: any | null; + screenshotUri?: string | null; + elapsedTime?: number | null; + owner?: { + __typename?: "UserGQL"; + id: number; + username: string; + profileImageUri?: string | null; + } | null; + stream?: { + __typename?: "UploadStreamGQL"; + id: string; + isCompleted: boolean; + lastSegmentUploadedAt?: any | null; + } | null; + }>; + pageInfo: { + __typename?: "PageInfoGQL"; + hasNextPage: boolean; + endCursor?: string | null; + }; + }; +}; + export type GetVideoMakePercentageIntervalsQueryVariables = Exact<{ videoId: Scalars["ID"]["input"]; intervalDuration: Scalars["Int"]["input"]; @@ -6504,6 +6553,51 @@ export type GetTableStateQuery = { }; }; +export type GetLiveTableStateQueryVariables = Exact<{ + videoId: Scalars["Int"]["input"]; +}>; + +export type GetLiveTableStateQuery = { + __typename?: "Query"; + getLiveTableState: { + __typename?: "LiveTableStateGQL"; + videoId: number; + frameIndex: number; + tableState: { + __typename?: "TableStateGQL"; + identifierToPosition: Array>; + homography?: { + __typename?: "HomographyInfoGQL"; + id: number; + frameIndex: number; + crop: { + __typename?: "BoundingBoxGQL"; + left: number; + top: number; + width: number; + height: number; + }; + pockets: Array<{ + __typename?: "BoundingBoxGQL"; + left: number; + top: number; + width: number; + height: number; + }>; + sourcePoints: { + __typename?: "PocketPointsGQL"; + topLeft: { __typename?: "IntPoint2D"; x: number; y: number }; + topSide: { __typename?: "IntPoint2D"; x: number; y: number }; + topRight: { __typename?: "IntPoint2D"; x: number; y: number }; + bottomLeft: { __typename?: "IntPoint2D"; x: number; y: number }; + bottomSide: { __typename?: "IntPoint2D"; x: number; y: number }; + bottomRight: { __typename?: "IntPoint2D"; x: number; y: number }; + }; + } | null; + }; + }; +}; + export type SimulateShotQueryVariables = Exact<{ simulationInput: SimulateShotInputGql; }>; @@ -11386,6 +11480,105 @@ export type GetMyDrillRunsQueryResult = Apollo.QueryResult< GetMyDrillRunsQuery, GetMyDrillRunsQueryVariables >; +export const GetLiveStreamsDocument = gql` + query GetLiveStreams($limit: Int! = 25) { + getFeedVideos( + limit: $limit + filters: { isStreamCompleted: false, requireCursorCompletion: false } + includePrivate: MINE + feedInput: { allUsers: true } + ) { + videos { + id + name + startTime + createdAt + screenshotUri + elapsedTime + owner { + id + username + profileImageUri + } + stream { + id + isCompleted + lastSegmentUploadedAt + } + } + pageInfo { + hasNextPage + endCursor + } + } + } +`; + +/** + * __useGetLiveStreamsQuery__ + * + * To run a query within a React component, call `useGetLiveStreamsQuery` and pass it any options that fit your needs. + * When your component renders, `useGetLiveStreamsQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetLiveStreamsQuery({ + * variables: { + * limit: // value for 'limit' + * }, + * }); + */ +export function useGetLiveStreamsQuery( + baseOptions?: Apollo.QueryHookOptions< + GetLiveStreamsQuery, + GetLiveStreamsQueryVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useQuery( + GetLiveStreamsDocument, + options, + ); +} +export function useGetLiveStreamsLazyQuery( + baseOptions?: Apollo.LazyQueryHookOptions< + GetLiveStreamsQuery, + GetLiveStreamsQueryVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useLazyQuery( + GetLiveStreamsDocument, + options, + ); +} +export function useGetLiveStreamsSuspenseQuery( + baseOptions?: Apollo.SuspenseQueryHookOptions< + GetLiveStreamsQuery, + GetLiveStreamsQueryVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useSuspenseQuery< + GetLiveStreamsQuery, + GetLiveStreamsQueryVariables + >(GetLiveStreamsDocument, options); +} +export type GetLiveStreamsQueryHookResult = ReturnType< + typeof useGetLiveStreamsQuery +>; +export type GetLiveStreamsLazyQueryHookResult = ReturnType< + typeof useGetLiveStreamsLazyQuery +>; +export type GetLiveStreamsSuspenseQueryHookResult = ReturnType< + typeof useGetLiveStreamsSuspenseQuery +>; +export type GetLiveStreamsQueryResult = Apollo.QueryResult< + GetLiveStreamsQuery, + GetLiveStreamsQueryVariables +>; export const GetVideoMakePercentageIntervalsDocument = gql` query GetVideoMakePercentageIntervals( $videoId: ID! @@ -13909,6 +14102,87 @@ export type GetTableStateQueryResult = Apollo.QueryResult< GetTableStateQuery, GetTableStateQueryVariables >; +export const GetLiveTableStateDocument = gql` + query GetLiveTableState($videoId: Int!) { + getLiveTableState(videoId: $videoId) { + videoId + frameIndex + tableState { + identifierToPosition + homography { + ...HomographyInfo + } + } + } + } + ${HomographyInfoFragmentDoc} +`; + +/** + * __useGetLiveTableStateQuery__ + * + * To run a query within a React component, call `useGetLiveTableStateQuery` and pass it any options that fit your needs. + * When your component renders, `useGetLiveTableStateQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetLiveTableStateQuery({ + * variables: { + * videoId: // value for 'videoId' + * }, + * }); + */ +export function useGetLiveTableStateQuery( + baseOptions: Apollo.QueryHookOptions< + GetLiveTableStateQuery, + GetLiveTableStateQueryVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useQuery< + GetLiveTableStateQuery, + GetLiveTableStateQueryVariables + >(GetLiveTableStateDocument, options); +} +export function useGetLiveTableStateLazyQuery( + baseOptions?: Apollo.LazyQueryHookOptions< + GetLiveTableStateQuery, + GetLiveTableStateQueryVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useLazyQuery< + GetLiveTableStateQuery, + GetLiveTableStateQueryVariables + >(GetLiveTableStateDocument, options); +} +export function useGetLiveTableStateSuspenseQuery( + baseOptions?: Apollo.SuspenseQueryHookOptions< + GetLiveTableStateQuery, + GetLiveTableStateQueryVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useSuspenseQuery< + GetLiveTableStateQuery, + GetLiveTableStateQueryVariables + >(GetLiveTableStateDocument, options); +} +export type GetLiveTableStateQueryHookResult = ReturnType< + typeof useGetLiveTableStateQuery +>; +export type GetLiveTableStateLazyQueryHookResult = ReturnType< + typeof useGetLiveTableStateLazyQuery +>; +export type GetLiveTableStateSuspenseQueryHookResult = ReturnType< + typeof useGetLiveTableStateSuspenseQuery +>; +export type GetLiveTableStateQueryResult = Apollo.QueryResult< + GetLiveTableStateQuery, + GetLiveTableStateQueryVariables +>; export const SimulateShotDocument = gql` query SimulateShot($simulationInput: SimulateShotInputGQL!) { simulateShot(simulationInput: $simulationInput) { diff --git a/src/operations/live_streams.gql b/src/operations/live_streams.gql new file mode 100644 index 0000000..45e4167 --- /dev/null +++ b/src/operations/live_streams.gql @@ -0,0 +1,34 @@ +# Lightweight listing of live (in-progress) streams for pickers like the +# Shot Lab "follow a live stream" flow. Selects only what a picker card +# needs; intentionally avoids the heavy VideoCardFields fragment. +query GetLiveStreams($limit: Int! = 25) { + getFeedVideos( + limit: $limit + filters: { isStreamCompleted: false, requireCursorCompletion: false } + includePrivate: MINE + feedInput: { allUsers: true } + ) { + videos { + id + name + startTime + createdAt + screenshotUri + elapsedTime + owner { + id + username + profileImageUri + } + stream { + id + isCompleted + lastSegmentUploadedAt + } + } + pageInfo { + hasNextPage + endCursor + } + } +} diff --git a/src/operations/shot_simulation.gql b/src/operations/shot_simulation.gql index 75281bd..cb4016e 100644 --- a/src/operations/shot_simulation.gql +++ b/src/operations/shot_simulation.gql @@ -12,6 +12,19 @@ query GetTableState( } } +query GetLiveTableState($videoId: Int!) { + getLiveTableState(videoId: $videoId) { + videoId + frameIndex + tableState { + identifierToPosition + homography { + ...HomographyInfo + } + } + } +} + query SimulateShot($simulationInput: SimulateShotInputGQL!) { simulateShot(simulationInput: $simulationInput) { trajectories { diff --git a/src/schema.gql b/src/schema.gql index 1367f66..37f4517 100644 --- a/src/schema.gql +++ b/src/schema.gql @@ -72,6 +72,7 @@ type Query { tableSize: Float = 100 useHomography: HomographyInputGQL = null ): TableStateGQL! + getLiveTableState(videoId: Int!): LiveTableStateGQL! simulateShot(simulationInput: SimulateShotInputGQL!): ShotProjectionGQL! computePotAim( simulationInput: SimulateShotInputGQL! @@ -1043,6 +1044,12 @@ input IntPoint2DInput { y: Int! } +type LiveTableStateGQL { + videoId: Int! + frameIndex: Int! + tableState: TableStateGQL! +} + type ShotProjectionGQL { trajectories: [BallTrajectoryGQL!]! events: [SimulationEventGQL!]!