Compare commits

...

5 Commits

Author SHA1 Message Date
d67fdd9fee Merge pull request 'Speed up Shot Lab video source queries' (#304) from codex/fix-shot-lab-video-picker into master
Reviewed-on: #304
2026-07-22 01:08:33 +00:00
d787e5e9a2 Speed up Shot Lab video source queries
All checks were successful
Tests / Tests (pull_request) Successful in 39s
2026-07-21 17:39:55 -07:00
1d73b2d67b Merge pull request 'Declare taxonomy filter variables on the makes/runs leaderboards' (#302) from dean/leaderboard-filter-operations into master
Reviewed-on: #302
2026-07-21 16:59:34 +00:00
Dean Wenstrand
aa731b85fc Declare taxonomy filter variables on the makes/runs leaderboards
All checks were successful
Tests / Tests (pull_request) Successful in 18s
The backend leaderboard resolvers gained game_type, table size and pocket
size filters, but GetMakesLeaderboard and GetRunsLeaderboard never declared
them — GraphQL silently drops undeclared variables, so anything the client
passed was ignored and both boards stayed global.

Declare and forward the five filter args on both queries, matching the
names the drill run leaderboard already uses.
2026-07-21 09:30:37 -07:00
644f70c3b0 Merge pull request 'Shot Lab: video-first GetShotLabVideos (replaces GetRecordedStreams/GetLiveStreams)' (#301) from colonelpanic/shot-lab-video-picker into master 2026-07-21 06:47:45 +00:00
3 changed files with 104 additions and 63 deletions

View File

@@ -5236,6 +5236,11 @@ export type GetVideoFeedQuery = {
export type GetMakesLeaderboardQueryVariables = Exact<{
interval?: InputMaybe<TimeInterval>;
when?: InputMaybe<Scalars["DateTime"]["input"]>;
gameType?: InputMaybe<Scalars["String"]["input"]>;
tableSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
tableSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
pocketSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
pocketSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
}>;
export type GetMakesLeaderboardQuery = {
@@ -5260,6 +5265,11 @@ export type GetMakesLeaderboardQuery = {
export type GetRunsLeaderboardQueryVariables = Exact<{
interval?: InputMaybe<TimeInterval>;
when?: InputMaybe<Scalars["DateTime"]["input"]>;
gameType?: InputMaybe<Scalars["String"]["input"]>;
tableSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
tableSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
pocketSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
pocketSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
}>;
export type GetRunsLeaderboardQuery = {
@@ -6686,6 +6696,7 @@ export type ReactToVideoMutation = {
};
export type GetShotLabVideosQueryVariables = Exact<{
userId: Scalars["Int"]["input"];
limit?: Scalars["Int"]["input"];
}>;
@@ -6736,29 +6747,13 @@ export type GetRecordedStreamShotsQuery = {
__typename?: "SerializedShotPathsGQL";
b64EncodedBuffer?: string | null;
} | null;
cueObjectFeatures?: {
__typename?: "CueObjectFeaturesGQL";
cueObjectDistance?: number | null;
cueObjectAngle?: number | null;
cueBallSpeed?: number | null;
shotDirection?: ShotDirectionEnum | null;
spinType?: SpinTypeEnum | null;
} | null;
pocketingIntentionFeatures?: {
__typename?: "PocketingIntentionFeaturesGQL";
make?: boolean | null;
targetPocketDistance?: number | null;
targetPocketAngle?: number | null;
targetPocketAngleDirection?: ShotDirectionEnum | null;
marginOfErrorInDegrees?: number | null;
intendedPocketType?: PocketEnum | null;
difficulty?: number | null;
} | null;
pocketingIntentionInfo?: {
__typename?: "PocketingIntentionInfoGQL";
ballId: number;
pocketId: PocketIdentifier;
pathMetadataIndex: number;
} | null;
}>;
};
@@ -11754,8 +11749,24 @@ export type GetVideoFeedQueryResult = Apollo.QueryResult<
GetVideoFeedQueryVariables
>;
export const GetMakesLeaderboardDocument = gql`
query GetMakesLeaderboard($interval: TimeInterval, $when: DateTime) {
getMakesLeaderboard(interval: $interval, when: $when) {
query GetMakesLeaderboard(
$interval: TimeInterval
$when: DateTime
$gameType: String
$tableSizeMin: Float
$tableSizeMax: Float
$pocketSizeMin: Float
$pocketSizeMax: Float
) {
getMakesLeaderboard(
interval: $interval
when: $when
gameType: $gameType
tableSizeMin: $tableSizeMin
tableSizeMax: $tableSizeMax
pocketSizeMin: $pocketSizeMin
pocketSizeMax: $pocketSizeMax
) {
entries {
user {
id
@@ -11784,6 +11795,11 @@ export const GetMakesLeaderboardDocument = gql`
* variables: {
* interval: // value for 'interval'
* when: // value for 'when'
* gameType: // value for 'gameType'
* tableSizeMin: // value for 'tableSizeMin'
* tableSizeMax: // value for 'tableSizeMax'
* pocketSizeMin: // value for 'pocketSizeMin'
* pocketSizeMax: // value for 'pocketSizeMax'
* },
* });
*/
@@ -11837,8 +11853,24 @@ export type GetMakesLeaderboardQueryResult = Apollo.QueryResult<
GetMakesLeaderboardQueryVariables
>;
export const GetRunsLeaderboardDocument = gql`
query GetRunsLeaderboard($interval: TimeInterval, $when: DateTime) {
getLongestRunsLeaderboard(interval: $interval, when: $when) {
query GetRunsLeaderboard(
$interval: TimeInterval
$when: DateTime
$gameType: String
$tableSizeMin: Float
$tableSizeMax: Float
$pocketSizeMin: Float
$pocketSizeMax: Float
) {
getLongestRunsLeaderboard(
interval: $interval
when: $when
gameType: $gameType
tableSizeMin: $tableSizeMin
tableSizeMax: $tableSizeMax
pocketSizeMin: $pocketSizeMin
pocketSizeMax: $pocketSizeMax
) {
entries {
id
runLength
@@ -11870,6 +11902,11 @@ export const GetRunsLeaderboardDocument = gql`
* variables: {
* interval: // value for 'interval'
* when: // value for 'when'
* gameType: // value for 'gameType'
* tableSizeMin: // value for 'tableSizeMin'
* tableSizeMax: // value for 'tableSizeMax'
* pocketSizeMin: // value for 'pocketSizeMin'
* pocketSizeMax: // value for 'pocketSizeMax'
* },
* });
*/
@@ -14416,11 +14453,12 @@ export type ReactToVideoMutationOptions = Apollo.BaseMutationOptions<
ReactToVideoMutationVariables
>;
export const GetShotLabVideosDocument = gql`
query GetShotLabVideos($limit: Int! = 25) {
query GetShotLabVideos($userId: Int!, $limit: Int! = 25) {
getFeedVideos(
limit: $limit
includeCallersVideos: false
includePrivate: MINE
feedInput: { allUsers: true }
feedInput: { userId: $userId }
) {
videos {
id
@@ -14456,12 +14494,13 @@ export const GetShotLabVideosDocument = gql`
* @example
* const { data, loading, error } = useGetShotLabVideosQuery({
* variables: {
* userId: // value for 'userId'
* limit: // value for 'limit'
* },
* });
*/
export function useGetShotLabVideosQuery(
baseOptions?: Apollo.QueryHookOptions<
baseOptions: Apollo.QueryHookOptions<
GetShotLabVideosQuery,
GetShotLabVideosQueryVariables
>,
@@ -14524,26 +14563,11 @@ export const GetRecordedStreamShotsDocument = gql`
serializedShotPaths {
b64EncodedBuffer
}
cueObjectFeatures {
cueObjectDistance
cueObjectAngle
cueBallSpeed
shotDirection
spinType
}
pocketingIntentionFeatures {
make
targetPocketDistance
targetPocketAngle
targetPocketAngleDirection
marginOfErrorInDegrees
intendedPocketType
difficulty
}
pocketingIntentionInfo {
ballId
pocketId
pathMetadataIndex
}
}
}

View File

@@ -1,5 +1,21 @@
query GetMakesLeaderboard($interval: TimeInterval, $when: DateTime) {
getMakesLeaderboard(interval: $interval, when: $when) {
query GetMakesLeaderboard(
$interval: TimeInterval
$when: DateTime
$gameType: String
$tableSizeMin: Float
$tableSizeMax: Float
$pocketSizeMin: Float
$pocketSizeMax: Float
) {
getMakesLeaderboard(
interval: $interval
when: $when
gameType: $gameType
tableSizeMin: $tableSizeMin
tableSizeMax: $tableSizeMax
pocketSizeMin: $pocketSizeMin
pocketSizeMax: $pocketSizeMax
) {
entries {
user {
id
@@ -13,8 +29,24 @@ query GetMakesLeaderboard($interval: TimeInterval, $when: DateTime) {
}
}
query GetRunsLeaderboard($interval: TimeInterval, $when: DateTime) {
getLongestRunsLeaderboard(interval: $interval, when: $when) {
query GetRunsLeaderboard(
$interval: TimeInterval
$when: DateTime
$gameType: String
$tableSizeMin: Float
$tableSizeMax: Float
$pocketSizeMin: Float
$pocketSizeMax: Float
) {
getLongestRunsLeaderboard(
interval: $interval
when: $when
gameType: $gameType
tableSizeMin: $tableSizeMin
tableSizeMax: $tableSizeMax
pocketSizeMin: $pocketSizeMin
pocketSizeMax: $pocketSizeMax
) {
entries {
id
runLength

View File

@@ -1,12 +1,12 @@
# Lightweight two-step picker data for Shot Lab's video-first source: recent
# videos (completed or still uploading — no completion gate, so an in-progress
# recording with no shots yet still appears), then that video's shots. The
# stream fields let the client hint at "actively updating" without gating.
query GetShotLabVideos($limit: Int! = 25) {
# Lightweight two-step picker data for Shot Lab's video-first source: the
# caller's recent videos (completed or still uploading), then that video's
# shots. The stream fields hint at "actively updating" without gating.
query GetShotLabVideos($userId: Int!, $limit: Int! = 25) {
getFeedVideos(
limit: $limit
includeCallersVideos: false
includePrivate: MINE
feedInput: { allUsers: true }
feedInput: { userId: $userId }
) {
videos {
id
@@ -43,26 +43,11 @@ query GetRecordedStreamShots($videoId: Int!, $limit: Int! = 200) {
serializedShotPaths {
b64EncodedBuffer
}
cueObjectFeatures {
cueObjectDistance
cueObjectAngle
cueBallSpeed
shotDirection
spinType
}
pocketingIntentionFeatures {
make
targetPocketDistance
targetPocketAngle
targetPocketAngleDirection
marginOfErrorInDegrees
intendedPocketType
difficulty
}
pocketingIntentionInfo {
ballId
pocketId
pathMetadataIndex
}
}
}