Compare commits

...

16 Commits

Author SHA1 Message Date
Dean Wenstrand
3ad12182d8 Regenerate schema and hooks from backend master
Union of the cohort funnel, Shot Lab picker queries, and transient
homography IDs — converges the three divergent submodule pointers
(gql master, railbird master, railbird-mobile master).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 18:00:43 -07:00
Dean Wenstrand
4122284bbd Merge Shot Lab queries with cohort funnel 2026-07-12 17:59:33 -07:00
b30dbd01f5 Fetch shot paths and features for the Shot Lab picker
All checks were successful
Tests / Tests (pull_request) Successful in 11s
The recorded-shot picker now renders per-shot table diagrams, so
GetRecordedStreamShots needs serializedShotPaths plus the pocketing and
cue-object features that PlaneShotDiagram consumes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 11:13:17 -07:00
6d13dc3eb1 Merge remote-tracking branch 'origin/master' into colonelpanic/allow-transient-homography-ids 2026-07-12 00:19:46 -07:00
e3524cab97 Merge pull request 'Add weekly cohort funnel to getUsageStats' (#293) from dean/usage-stats-cohorts into master
Reviewed-on: #293
2026-07-12 04:07:43 +00:00
303261f2d7 Add recorded Shot Lab queries 2026-07-11 20:56:47 -07:00
20a70fad2a Allow transient homography IDs 2026-07-11 20:55:53 -07:00
Dean Wenstrand
35c7c23ba9 Add disjoint activated segment to cohorts for stacking
All checks were successful
Tests / Tests (pull_request) Successful in 10s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 17:45:01 -07:00
Dean Wenstrand
40c4b82a59 Add weekly cohort funnel to getUsageStats
All checks were successful
Tests / Tests (pull_request) Successful in 13s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 17:40:10 -07:00
9ebe2e61df Merge pull request 'dean/usage-stats' (#292) from dean/usage-stats into master
Reviewed-on: #292
2026-07-11 19:26:13 +00:00
Dean Wenstrand
6f356f9535 Add freemium epoch + era conversion to funnel
All checks were successful
Tests / Tests (pull_request) Successful in 12s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 11:38:20 -07:00
Dean Wenstrand
5c0ff8c31b Add freemium funnel to getUsageStats
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 10:48:25 -07:00
Dean Wenstrand
582c20170d Add getUsageStats admin query + operation (schema regen on shot-lab tip)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 10:36:47 -07:00
dc02fd8387 Merge pull request 'Select detected ball colors for Shot Lab' (#291) from colonelpanic/shot-lab-image-colors into master
Reviewed-on: #291
2026-07-10 17:20:37 +00:00
ef4782fc14 Select detected ball colors for Shot Lab
All checks were successful
Tests / Tests (pull_request) Successful in 33s
2026-07-10 00:12:06 -07:00
905a1ca6db Merge pull request 'Add RGBColorGQL and identifierToColor to TableStateGQL' (#290) from shot-lab-ball-colors into master 2026-07-10 03:36:33 +00:00
5 changed files with 878 additions and 232 deletions

View File

@@ -260,6 +260,15 @@ export type ClusterAssignmentInput = {
userId?: InputMaybe<Scalars["Int"]["input"]>;
};
export type CohortStatsGql = {
__typename?: "CohortStatsGQL";
activated7d: Scalars["Int"]["output"];
activatedNotPaid7d: Scalars["Int"]["output"];
paid7d: Scalars["Int"]["output"];
signups: Scalars["Int"]["output"];
weekStart: Scalars["Date"]["output"];
};
export type CommentGql = {
__typename?: "CommentGQL";
id: Scalars["Int"]["output"];
@@ -2299,6 +2308,20 @@ export type FloatRangeFilter = {
lessThanInclusive?: Scalars["Boolean"]["input"];
};
export type FunnelStatsGql = {
__typename?: "FunnelStatsGQL";
activationActivated: Scalars["Int"]["output"];
activationCohort: Scalars["Int"]["output"];
eraPaying: Scalars["Int"]["output"];
eraSignups: Scalars["Int"]["output"];
freemiumEpoch: Scalars["Date"]["output"];
newPaid7d: Scalars["Int"]["output"];
newPaid30d: Scalars["Int"]["output"];
payingUsers: Scalars["Int"]["output"];
retentionPrevActive: Scalars["Int"]["output"];
retentionReturned: Scalars["Int"]["output"];
};
export type GameTypeTagMetric = {
__typename?: "GameTypeTagMetric";
madeShots: Scalars["Int"]["output"];
@@ -2386,7 +2409,7 @@ export type HomographyInfoGql = {
crop: BoundingBoxGql;
destPoints: PocketPointsGql;
frameIndex: Scalars["Int"]["output"];
id: Scalars["Int"]["output"];
id?: Maybe<Scalars["Int"]["output"]>;
pockets: Array<BoundingBoxGql>;
sourcePoints: PocketPointsGql;
};
@@ -3018,6 +3041,12 @@ export type ProcessingFailedErr = {
processing: VideoProcessingGql;
};
export type ProcessingStatusCountGql = {
__typename?: "ProcessingStatusCountGQL";
count: Scalars["Int"]["output"];
status: Scalars["String"]["output"];
};
export enum ProcessingStatusEnum {
Created = "CREATED",
Failed = "FAILED",
@@ -3060,11 +3089,13 @@ export type Query = {
getResolvedTier: ResolvedTierGql;
getRuns: GetRunsResult;
getShotAnnotationTypes: Array<ShotAnnotationTypeGql>;
getShotTableState: ShotTableStateGql;
getShots: Array<ShotGql>;
getShotsByIds: Array<ShotGql>;
getShotsWithMetadata: GetShotsResult;
getStorageStatus?: Maybe<StorageStatusGql>;
getTableState: TableStateGql;
getUsageStats: UsageStatsGql;
getUser?: Maybe<UserGql>;
getUserRelationshipsMatching: UserRelationshipsResult;
getUserSubscriptionStatus: UserSubscriptionStatusGql;
@@ -3204,6 +3235,10 @@ export type QueryGetShotAnnotationTypesArgs = {
errorTypes?: InputMaybe<Scalars["Boolean"]["input"]>;
};
export type QueryGetShotTableStateArgs = {
shotId: Scalars["Int"]["input"];
};
export type QueryGetShotsArgs = {
countRespectsLimit?: Scalars["Boolean"]["input"];
filterInput: FilterInput;
@@ -3229,6 +3264,10 @@ export type QueryGetTableStateArgs = {
useHomography?: InputMaybe<HomographyInputGql>;
};
export type QueryGetUsageStatsArgs = {
days?: Scalars["Int"]["input"];
};
export type QueryGetUserArgs = {
userId: Scalars["Int"]["input"];
};
@@ -3579,6 +3618,14 @@ export type ShotProjectionGql = {
trajectories: Array<BallTrajectoryGql>;
};
export type ShotTableStateGql = {
__typename?: "ShotTableStateGQL";
frameIndex: Scalars["Int"]["output"];
shotId: Scalars["Int"]["output"];
tableState: TableStateGql;
videoId: Scalars["Int"]["output"];
};
export type ShotsOrderingComponent =
| {
difficulty: FloatOrdering;
@@ -3944,6 +3991,37 @@ export type UploadStreamGql = {
uploadsCompleted: Scalars["Int"]["output"];
};
export type UsageStatsDailyGql = {
__typename?: "UsageStatsDailyGQL";
activeUsers: Scalars["Int"]["output"];
day: Scalars["Date"]["output"];
newUsers: Scalars["Int"]["output"];
sessions: Scalars["Int"]["output"];
shots: Scalars["Int"]["output"];
};
export type UsageStatsGql = {
__typename?: "UsageStatsGQL";
cohorts: Array<CohortStatsGql>;
daily: Array<UsageStatsDailyGql>;
funnel: FunnelStatsGql;
processingLast24h: Array<ProcessingStatusCountGql>;
totalRuns: Scalars["Int"]["output"];
totalShots: Scalars["Int"]["output"];
totalUsers: Scalars["Int"]["output"];
totalVideos: Scalars["Int"]["output"];
windows: Array<UsageStatsWindowGql>;
};
export type UsageStatsWindowGql = {
__typename?: "UsageStatsWindowGQL";
activeUsers: Scalars["Int"]["output"];
label: Scalars["String"]["output"];
newUsers: Scalars["Int"]["output"];
sessions: Scalars["Int"]["output"];
shots: Scalars["Int"]["output"];
};
export type UserGql = {
__typename?: "UserGQL";
activeVideoId?: Maybe<Scalars["Int"]["output"]>;
@@ -6538,6 +6616,79 @@ export type ReactToVideoMutation = {
reactToVideo: boolean;
};
export type GetRecordedStreamsQueryVariables = Exact<{
limit?: Scalars["Int"]["input"];
}>;
export type GetRecordedStreamsQuery = {
__typename?: "Query";
getFeedVideos: {
__typename?: "VideoHistoryGQL";
videos: Array<{
__typename?: "VideoGQL";
id: number;
name?: string | null;
createdAt?: any | null;
screenshotUri?: string | null;
framesPerSecond: number;
totalShots: number;
owner?: {
__typename?: "UserGQL";
id: number;
username: string;
profileImageUri?: string | null;
} | null;
}>;
};
};
export type GetRecordedStreamShotsQueryVariables = Exact<{
videoId: Scalars["Int"]["input"];
limit?: Scalars["Int"]["input"];
}>;
export type GetRecordedStreamShotsQuery = {
__typename?: "Query";
getOrderedShots: {
__typename?: "GetShotsResult";
shots: Array<{
__typename?: "ShotGQL";
id: number;
videoId: number;
startFrame: number;
endFrame: number;
serializedShotPaths?: {
__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;
}>;
};
};
export type GetRunsForHighlightsQueryVariables = Exact<{
filterInput: RunFilterInput;
runIds?: InputMaybe<Array<Scalars["Int"]["input"]> | Scalars["Int"]["input"]>;
@@ -6745,6 +6896,10 @@ export type GetTableStateQuery = {
getTableState: {
__typename?: "TableStateGQL";
identifierToPosition: Array<Array<number>>;
identifierToColor: Array<{
__typename?: "RGBColorGQL";
hex: string;
} | null>;
};
};
@@ -6761,9 +6916,37 @@ export type GetLiveTableStateQuery = {
tableState: {
__typename?: "TableStateGQL";
identifierToPosition: Array<Array<number>>;
identifierToColor: Array<{
__typename?: "RGBColorGQL";
hex: string;
} | null>;
<<<<<<< HEAD
};
};
};
export type GetShotTableStateQueryVariables = Exact<{
shotId: Scalars["Int"]["input"];
}>;
export type GetShotTableStateQuery = {
__typename?: "Query";
getShotTableState: {
__typename?: "ShotTableStateGQL";
shotId: number;
videoId: number;
frameIndex: number;
tableState: {
__typename?: "TableStateGQL";
identifierToPosition: Array<Array<number>>;
identifierToColor: Array<{
__typename?: "RGBColorGQL";
hex: string;
} | null>;
=======
homography?: {
__typename?: "HomographyInfoGQL";
id: number;
id?: number | null;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
@@ -6789,6 +6972,7 @@ export type GetLiveTableStateQuery = {
bottomRight: { __typename?: "IntPoint2D"; x: number; y: number };
};
} | null;
>>>>>>> 6d13dc3
};
};
};
@@ -7387,6 +7571,63 @@ export type DeleteTagsMutation = {
deleteTags: boolean;
};
export type GetUsageStatsQueryVariables = Exact<{
days?: Scalars["Int"]["input"];
}>;
export type GetUsageStatsQuery = {
__typename?: "Query";
getUsageStats: {
__typename?: "UsageStatsGQL";
totalUsers: number;
totalVideos: number;
totalShots: number;
totalRuns: number;
funnel: {
__typename?: "FunnelStatsGQL";
freemiumEpoch: any;
eraSignups: number;
eraPaying: number;
activationCohort: number;
activationActivated: number;
payingUsers: number;
newPaid7d: number;
newPaid30d: number;
retentionPrevActive: number;
retentionReturned: number;
};
cohorts: Array<{
__typename?: "CohortStatsGQL";
weekStart: any;
signups: number;
activated7d: number;
paid7d: number;
activatedNotPaid7d: number;
}>;
windows: Array<{
__typename?: "UsageStatsWindowGQL";
label: string;
newUsers: number;
activeUsers: number;
sessions: number;
shots: number;
}>;
daily: Array<{
__typename?: "UsageStatsDailyGQL";
day: any;
newUsers: number;
activeUsers: number;
sessions: number;
shots: number;
}>;
processingLast24h: Array<{
__typename?: "ProcessingStatusCountGQL";
status: string;
count: number;
}>;
};
};
export type GetProfileImageUploadLinkMutationVariables = Exact<{
fileExt?: InputMaybe<Scalars["String"]["input"]>;
}>;
@@ -7743,7 +7984,7 @@ export type GetStreamMonitoringDetailsQuery = {
elapsedTime?: number | null;
currentHomography?: {
__typename?: "HomographyInfoGQL";
id: number;
id?: number | null;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
@@ -8157,7 +8398,7 @@ export type GetVideoQuery = {
} | null;
homographyHistory: Array<{
__typename?: "HomographyInfoGQL";
id: number;
id?: number | null;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
@@ -8405,7 +8646,7 @@ export type FindPrerecordTableLayoutMutation = {
__typename?: "Mutation";
findPrerecordTableLayout?: {
__typename?: "HomographyInfoGQL";
id: number;
id?: number | null;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
@@ -8435,7 +8676,7 @@ export type FindPrerecordTableLayoutMutation = {
export type HomographyInfoFragment = {
__typename?: "HomographyInfoGQL";
id: number;
id?: number | null;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
@@ -14089,6 +14330,203 @@ export type ReactToVideoMutationOptions = Apollo.BaseMutationOptions<
ReactToVideoMutation,
ReactToVideoMutationVariables
>;
export const GetRecordedStreamsDocument = gql`
query GetRecordedStreams($limit: Int! = 25) {
getFeedVideos(
limit: $limit
filters: { isStreamCompleted: true, excludeVideosWithNoShots: true }
includePrivate: MINE
feedInput: { allUsers: true }
) {
videos {
id
name
createdAt
screenshotUri
framesPerSecond
totalShots
owner {
id
username
profileImageUri
}
}
}
}
`;
/**
* __useGetRecordedStreamsQuery__
*
* To run a query within a React component, call `useGetRecordedStreamsQuery` and pass it any options that fit your needs.
* When your component renders, `useGetRecordedStreamsQuery` 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 } = useGetRecordedStreamsQuery({
* variables: {
* limit: // value for 'limit'
* },
* });
*/
export function useGetRecordedStreamsQuery(
baseOptions?: Apollo.QueryHookOptions<
GetRecordedStreamsQuery,
GetRecordedStreamsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useQuery<
GetRecordedStreamsQuery,
GetRecordedStreamsQueryVariables
>(GetRecordedStreamsDocument, options);
}
export function useGetRecordedStreamsLazyQuery(
baseOptions?: Apollo.LazyQueryHookOptions<
GetRecordedStreamsQuery,
GetRecordedStreamsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useLazyQuery<
GetRecordedStreamsQuery,
GetRecordedStreamsQueryVariables
>(GetRecordedStreamsDocument, options);
}
export function useGetRecordedStreamsSuspenseQuery(
baseOptions?: Apollo.SuspenseQueryHookOptions<
GetRecordedStreamsQuery,
GetRecordedStreamsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useSuspenseQuery<
GetRecordedStreamsQuery,
GetRecordedStreamsQueryVariables
>(GetRecordedStreamsDocument, options);
}
export type GetRecordedStreamsQueryHookResult = ReturnType<
typeof useGetRecordedStreamsQuery
>;
export type GetRecordedStreamsLazyQueryHookResult = ReturnType<
typeof useGetRecordedStreamsLazyQuery
>;
export type GetRecordedStreamsSuspenseQueryHookResult = ReturnType<
typeof useGetRecordedStreamsSuspenseQuery
>;
export type GetRecordedStreamsQueryResult = Apollo.QueryResult<
GetRecordedStreamsQuery,
GetRecordedStreamsQueryVariables
>;
export const GetRecordedStreamShotsDocument = gql`
query GetRecordedStreamShots($videoId: Int!, $limit: Int! = 200) {
getOrderedShots(
filterInput: { videoId: [$videoId] }
shotsOrdering: { orderings: [{ startFrame: { descending: false } }] }
limit: $limit
) {
shots {
id
videoId
startFrame
endFrame
serializedShotPaths {
b64EncodedBuffer
}
cueObjectFeatures {
cueObjectDistance
cueObjectAngle
cueBallSpeed
shotDirection
spinType
}
pocketingIntentionFeatures {
make
targetPocketDistance
targetPocketAngle
targetPocketAngleDirection
marginOfErrorInDegrees
intendedPocketType
difficulty
}
pocketingIntentionInfo {
ballId
pocketId
pathMetadataIndex
}
}
}
}
`;
/**
* __useGetRecordedStreamShotsQuery__
*
* To run a query within a React component, call `useGetRecordedStreamShotsQuery` and pass it any options that fit your needs.
* When your component renders, `useGetRecordedStreamShotsQuery` 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 } = useGetRecordedStreamShotsQuery({
* variables: {
* videoId: // value for 'videoId'
* limit: // value for 'limit'
* },
* });
*/
export function useGetRecordedStreamShotsQuery(
baseOptions: Apollo.QueryHookOptions<
GetRecordedStreamShotsQuery,
GetRecordedStreamShotsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useQuery<
GetRecordedStreamShotsQuery,
GetRecordedStreamShotsQueryVariables
>(GetRecordedStreamShotsDocument, options);
}
export function useGetRecordedStreamShotsLazyQuery(
baseOptions?: Apollo.LazyQueryHookOptions<
GetRecordedStreamShotsQuery,
GetRecordedStreamShotsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useLazyQuery<
GetRecordedStreamShotsQuery,
GetRecordedStreamShotsQueryVariables
>(GetRecordedStreamShotsDocument, options);
}
export function useGetRecordedStreamShotsSuspenseQuery(
baseOptions?: Apollo.SuspenseQueryHookOptions<
GetRecordedStreamShotsQuery,
GetRecordedStreamShotsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useSuspenseQuery<
GetRecordedStreamShotsQuery,
GetRecordedStreamShotsQueryVariables
>(GetRecordedStreamShotsDocument, options);
}
export type GetRecordedStreamShotsQueryHookResult = ReturnType<
typeof useGetRecordedStreamShotsQuery
>;
export type GetRecordedStreamShotsLazyQueryHookResult = ReturnType<
typeof useGetRecordedStreamShotsLazyQuery
>;
export type GetRecordedStreamShotsSuspenseQueryHookResult = ReturnType<
typeof useGetRecordedStreamShotsSuspenseQuery
>;
export type GetRecordedStreamShotsQueryResult = Apollo.QueryResult<
GetRecordedStreamShotsQuery,
GetRecordedStreamShotsQueryVariables
>;
export const GetRunsForHighlightsDocument = gql`
query GetRunsForHighlights(
$filterInput: RunFilterInput!
@@ -14426,6 +14864,9 @@ export const GetTableStateDocument = gql`
useHomography: $useHomography
) {
identifierToPosition
identifierToColor {
hex
}
}
}
`;
@@ -14504,13 +14945,12 @@ export const GetLiveTableStateDocument = gql`
frameIndex
tableState {
identifierToPosition
homography {
...HomographyInfo
identifierToColor {
hex
}
}
}
}
${HomographyInfoFragmentDoc}
`;
/**
@@ -14578,6 +15018,87 @@ export type GetLiveTableStateQueryResult = Apollo.QueryResult<
GetLiveTableStateQuery,
GetLiveTableStateQueryVariables
>;
export const GetShotTableStateDocument = gql`
query GetShotTableState($shotId: Int!) {
getShotTableState(shotId: $shotId) {
shotId
videoId
frameIndex
tableState {
identifierToPosition
identifierToColor {
hex
}
}
}
}
`;
/**
* __useGetShotTableStateQuery__
*
* To run a query within a React component, call `useGetShotTableStateQuery` and pass it any options that fit your needs.
* When your component renders, `useGetShotTableStateQuery` 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 } = useGetShotTableStateQuery({
* variables: {
* shotId: // value for 'shotId'
* },
* });
*/
export function useGetShotTableStateQuery(
baseOptions: Apollo.QueryHookOptions<
GetShotTableStateQuery,
GetShotTableStateQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useQuery<
GetShotTableStateQuery,
GetShotTableStateQueryVariables
>(GetShotTableStateDocument, options);
}
export function useGetShotTableStateLazyQuery(
baseOptions?: Apollo.LazyQueryHookOptions<
GetShotTableStateQuery,
GetShotTableStateQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useLazyQuery<
GetShotTableStateQuery,
GetShotTableStateQueryVariables
>(GetShotTableStateDocument, options);
}
export function useGetShotTableStateSuspenseQuery(
baseOptions?: Apollo.SuspenseQueryHookOptions<
GetShotTableStateQuery,
GetShotTableStateQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useSuspenseQuery<
GetShotTableStateQuery,
GetShotTableStateQueryVariables
>(GetShotTableStateDocument, options);
}
export type GetShotTableStateQueryHookResult = ReturnType<
typeof useGetShotTableStateQuery
>;
export type GetShotTableStateLazyQueryHookResult = ReturnType<
typeof useGetShotTableStateLazyQuery
>;
export type GetShotTableStateSuspenseQueryHookResult = ReturnType<
typeof useGetShotTableStateSuspenseQuery
>;
export type GetShotTableStateQueryResult = Apollo.QueryResult<
GetShotTableStateQuery,
GetShotTableStateQueryVariables
>;
export const SimulateShotDocument = gql`
query SimulateShot($simulationInput: SimulateShotInputGQL!) {
simulateShot(simulationInput: $simulationInput) {
@@ -15655,6 +16176,119 @@ export type DeleteTagsMutationOptions = Apollo.BaseMutationOptions<
DeleteTagsMutation,
DeleteTagsMutationVariables
>;
export const GetUsageStatsDocument = gql`
query getUsageStats($days: Int! = 30) {
getUsageStats(days: $days) {
funnel {
freemiumEpoch
eraSignups
eraPaying
activationCohort
activationActivated
payingUsers
newPaid7d
newPaid30d
retentionPrevActive
retentionReturned
}
cohorts {
weekStart
signups
activated7d
paid7d
activatedNotPaid7d
}
totalUsers
totalVideos
totalShots
totalRuns
windows {
label
newUsers
activeUsers
sessions
shots
}
daily {
day
newUsers
activeUsers
sessions
shots
}
processingLast24h {
status
count
}
}
}
`;
/**
* __useGetUsageStatsQuery__
*
* To run a query within a React component, call `useGetUsageStatsQuery` and pass it any options that fit your needs.
* When your component renders, `useGetUsageStatsQuery` 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 } = useGetUsageStatsQuery({
* variables: {
* days: // value for 'days'
* },
* });
*/
export function useGetUsageStatsQuery(
baseOptions?: Apollo.QueryHookOptions<
GetUsageStatsQuery,
GetUsageStatsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useQuery<GetUsageStatsQuery, GetUsageStatsQueryVariables>(
GetUsageStatsDocument,
options,
);
}
export function useGetUsageStatsLazyQuery(
baseOptions?: Apollo.LazyQueryHookOptions<
GetUsageStatsQuery,
GetUsageStatsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useLazyQuery<GetUsageStatsQuery, GetUsageStatsQueryVariables>(
GetUsageStatsDocument,
options,
);
}
export function useGetUsageStatsSuspenseQuery(
baseOptions?: Apollo.SuspenseQueryHookOptions<
GetUsageStatsQuery,
GetUsageStatsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useSuspenseQuery<
GetUsageStatsQuery,
GetUsageStatsQueryVariables
>(GetUsageStatsDocument, options);
}
export type GetUsageStatsQueryHookResult = ReturnType<
typeof useGetUsageStatsQuery
>;
export type GetUsageStatsLazyQueryHookResult = ReturnType<
typeof useGetUsageStatsLazyQuery
>;
export type GetUsageStatsSuspenseQueryHookResult = ReturnType<
typeof useGetUsageStatsSuspenseQuery
>;
export type GetUsageStatsQueryResult = Apollo.QueryResult<
GetUsageStatsQuery,
GetUsageStatsQueryVariables
>;
export const GetProfileImageUploadLinkDocument = gql`
mutation getProfileImageUploadLink($fileExt: String = ".png") {
getProfileImageUploadLink(fileExt: $fileExt) {

View File

@@ -0,0 +1,62 @@
# Lightweight two-step picker data for loading a recorded shot into Shot Lab.
query GetRecordedStreams($limit: Int! = 25) {
getFeedVideos(
limit: $limit
filters: { isStreamCompleted: true, excludeVideosWithNoShots: true }
includePrivate: MINE
feedInput: { allUsers: true }
) {
videos {
id
name
createdAt
screenshotUri
framesPerSecond
totalShots
owner {
id
username
profileImageUri
}
}
}
}
query GetRecordedStreamShots($videoId: Int!, $limit: Int! = 200) {
getOrderedShots(
filterInput: { videoId: [$videoId] }
shotsOrdering: { orderings: [{ startFrame: { descending: false } }] }
limit: $limit
) {
shots {
id
videoId
startFrame
endFrame
serializedShotPaths {
b64EncodedBuffer
}
cueObjectFeatures {
cueObjectDistance
cueObjectAngle
cueBallSpeed
shotDirection
spinType
}
pocketingIntentionFeatures {
make
targetPocketDistance
targetPocketAngle
targetPocketAngleDirection
marginOfErrorInDegrees
intendedPocketType
difficulty
}
pocketingIntentionInfo {
ballId
pocketId
pathMetadataIndex
}
}
}
}

View File

@@ -9,6 +9,9 @@ query GetTableState(
useHomography: $useHomography
) {
identifierToPosition
identifierToColor {
hex
}
}
}
@@ -18,8 +21,22 @@ query GetLiveTableState($videoId: Int!) {
frameIndex
tableState {
identifierToPosition
homography {
...HomographyInfo
identifierToColor {
hex
}
}
}
}
query GetShotTableState($shotId: Int!) {
getShotTableState(shotId: $shotId) {
shotId
videoId
frameIndex
tableState {
identifierToPosition
identifierToColor {
hex
}
}
}

View File

@@ -0,0 +1,45 @@
query getUsageStats($days: Int! = 30) {
getUsageStats(days: $days) {
funnel {
freemiumEpoch
eraSignups
eraPaying
activationCohort
activationActivated
payingUsers
newPaid7d
newPaid30d
retentionPrevActive
retentionReturned
}
cohorts {
weekStart
signups
activated7d
paid7d
activatedNotPaid7d
}
totalUsers
totalVideos
totalShots
totalRuns
windows {
label
newUsers
activeUsers
sessions
shots
}
daily {
day
newUsers
activeUsers
sessions
shots
}
processingLast24h {
status
count
}
}
}

View File

@@ -1,7 +1,5 @@
type Query {
getAggregatedShotMetrics(
aggregateInput: AggregateInputGQL!
): [AggregateResultGQL!]!
getAggregatedShotMetrics(aggregateInput: AggregateInputGQL!): [AggregateResultGQL!]!
getBucketSet(keyName: String!): BucketSetGQL
challenges(includeDismissed: Boolean! = false): [Challenge!]!
myDismissedChallenges: [Challenge!]!
@@ -13,44 +11,14 @@ type Query {
myChallengeEntries: [ChallengeEntry!]!
getDeployedConfig: DeployedConfigGQL!
waitFor(duration: Float!): Float!
getFeedVideos(
limit: Int! = 5
after: String = null
includePrivate: IncludePrivateEnum! = MINE
includeCallersVideos: Boolean = true
filters: VideoFilterInput = null
feedInput: VideoFeedInputGQL = null
): VideoHistoryGQL!
getVideoMakePercentageIntervals(
videoId: ID!
intervalDuration: Int! = 300
): [MakePercentageIntervalGQL!]!
getLongestRunsLeaderboard(
interval: TimeInterval = null
when: DateTime = null
limit: Int! = 50
requiredTags: [String!] = null
): RunLeaderboardGQL!
getDrillRunLeaderboard(
drillTag: String!
interval: TimeInterval = null
limit: Int! = 50
tableSizeMin: Float = null
tableSizeMax: Float = null
pocketSizeMin: Float = null
pocketSizeMax: Float = null
): DrillRunLeaderboardGQL!
getFeedVideos(limit: Int! = 5, after: String = null, includePrivate: IncludePrivateEnum! = MINE, includeCallersVideos: Boolean = true, filters: VideoFilterInput = null, feedInput: VideoFeedInputGQL = null): VideoHistoryGQL!
getVideoMakePercentageIntervals(videoId: ID!, intervalDuration: Int! = 300): [MakePercentageIntervalGQL!]!
getLongestRunsLeaderboard(interval: TimeInterval = null, when: DateTime = null, limit: Int! = 50, requiredTags: [String!] = null): RunLeaderboardGQL!
getDrillRunLeaderboard(drillTag: String!, interval: TimeInterval = null, limit: Int! = 50, tableSizeMin: Float = null, tableSizeMax: Float = null, pocketSizeMin: Float = null, pocketSizeMax: Float = null): DrillRunLeaderboardGQL!
getMyDrillRuns(drillTag: String!, limit: Int! = 50): [RunGQL!]!
getMakesLeaderboard(
interval: TimeInterval = null
when: DateTime = null
): CountLeaderboardGQL!
getMakesLeaderboard(interval: TimeInterval = null, when: DateTime = null): CountLeaderboardGQL!
getMedals(scope: MedalScope!, userId: Int = null): RequestedMedalsGQL!
notifications(
limit: Int! = 20
offset: Int! = 0
filters: NotificationFilters = null
): NotificationConnection!
notifications(limit: Int! = 20, offset: Int! = 0, filters: NotificationFilters = null): NotificationConnection!
unreadNotificationCount: Int!
poolHalls: [PoolHall!]!
claimablePoolHalls: [PoolHall!]!
@@ -58,67 +26,25 @@ type Query {
claimableCameras(poolHallId: ID!): [PoolHallCamera!]!
cameraClaimSession(id: ID!): CameraClaimSession
activeCameraLease: CameraLease
getRuns(
filterInput: RunFilterInput!
runIds: [Int!] = null
runsOrdering: GetRunsOrdering = null
limit: Int! = 500
countRespectsLimit: Boolean! = false
): GetRunsResult!
getRuns(filterInput: RunFilterInput!, runIds: [Int!] = null, runsOrdering: GetRunsOrdering = null, limit: Int! = 500, countRespectsLimit: Boolean! = false): GetRunsResult!
videoPlayerClusters(videoId: Int!): [PlayerClusterGQL!]!
getShotAnnotationTypes(errorTypes: Boolean = false): [ShotAnnotationTypeGQL!]!
getTableState(
b64Image: String!
tableSize: Float = 100
useHomography: HomographyInputGQL = null
): TableStateGQL!
getTableState(b64Image: String!, tableSize: Float = 100, useHomography: HomographyInputGQL = null): TableStateGQL!
getLiveTableState(videoId: Int!): LiveTableStateGQL!
getShotTableState(shotId: Int!): ShotTableStateGQL!
simulateShot(simulationInput: SimulateShotInputGQL!): ShotProjectionGQL!
computePotAim(
simulationInput: SimulateShotInputGQL!
targetBallId: Int!
pocket: PocketIdentifier!
): PotAimGQL!
getOrderedShots(
filterInput: FilterInput!
ids: [Int!] = null
shotsOrdering: GetShotsOrdering = null
limit: Int! = 500
countRespectsLimit: Boolean! = false
): GetShotsResult!
getShotsWithMetadata(
filterInput: FilterInput!
ids: [Int!] = null
shotsPagination: GetShotsPagination = null
limit: Int! = 500
countRespectsLimit: Boolean! = false
): GetShotsResult!
getShots(
filterInput: FilterInput!
shotsPagination: GetShotsPagination = null
limit: Int! = 500
countRespectsLimit: Boolean! = false
): [ShotGQL!]!
computePotAim(simulationInput: SimulateShotInputGQL!, targetBallId: Int!, pocket: PocketIdentifier!): PotAimGQL!
getOrderedShots(filterInput: FilterInput!, ids: [Int!] = null, shotsOrdering: GetShotsOrdering = null, limit: Int! = 500, countRespectsLimit: Boolean! = false): GetShotsResult!
getShotsWithMetadata(filterInput: FilterInput!, ids: [Int!] = null, shotsPagination: GetShotsPagination = null, limit: Int! = 500, countRespectsLimit: Boolean! = false): GetShotsResult!
getShots(filterInput: FilterInput!, shotsPagination: GetShotsPagination = null, limit: Int! = 500, countRespectsLimit: Boolean! = false): [ShotGQL!]!
getShotsByIds(ids: [Int!]!): [ShotGQL!]!
getUsageStats(days: Int! = 30): UsageStatsGQL!
getUser(userId: Int!): UserGQL
doesUsernameExist(candidateUsername: String!): Boolean!
getLoggedInUser: UserGQL
getUsernames(
matchString: String = null
limit: Int = null
after: String = null
): [String!]!
getUsersMatching(
matchString: String = null
limit: Int = null
after: String = null
): [UserGQL!]!
getUserRelationshipsMatching(
userId: Int!
matchString: String = null
limit: Int = 100
after: String = null
): UserRelationshipsResult!
getUsernames(matchString: String = null, limit: Int = null, after: String = null): [String!]!
getUsersMatching(matchString: String = null, limit: Int = null, after: String = null): [UserGQL!]!
getUserRelationshipsMatching(userId: Int!, matchString: String = null, limit: Int = 100, after: String = null): UserRelationshipsResult!
getAvailableSubscriptionOptions: StripeSubscriptionOptionsGQL!
getUserSubscriptionStatus: UserSubscriptionStatusGQL!
getResolvedTier: ResolvedTierGQL!
@@ -126,12 +52,7 @@ type Query {
getQuotaStatus: QuotaStatusGQL!
getStorageStatus: StorageStatusGQL
getPlayTime(userId: Int!, filters: VideoFilterInput = null): UserPlayTimeGQL!
getUserVideos(
userId: Int = null
limit: Int! = 5
after: String = null
filters: VideoFilterInput = null
): VideoHistoryGQL!
getUserVideos(userId: Int = null, limit: Int! = 5, after: String = null, filters: VideoFilterInput = null): VideoHistoryGQL!
getUserTags(includeRetiredTags: Boolean = false): [TagGQL!]!
getGameTypeTagMetrics(input: GameTypeTagMetricsInput!): [GameTypeTagMetric!]!
videoExportJob(jobId: Int!): VideoExportJobGQL
@@ -203,9 +124,7 @@ input DatetimeRangeAggregationInput {
feature: String! = "created_at"
}
"""
Date with time (isoformat)
"""
"""Date with time (isoformat)"""
scalar DateTime
input TimeInterval @oneOf {
@@ -321,9 +240,7 @@ input DateRangeFilter {
greaterThanInclusive: Boolean! = true
}
"""
Date (isoformat)
"""
"""Date (isoformat)"""
scalar Date
type BucketSetGQL {
@@ -608,7 +525,7 @@ type VideoTagClass {
}
type HomographyInfoGQL {
id: Int!
id: Int
frameIndex: Int!
crop: BoundingBoxGQL!
pockets: [BoundingBoxGQL!]!
@@ -849,8 +766,7 @@ type MedalGQL {
input MedalScope @oneOf {
videoId: Int
interval: TimeInterval
@deprecated(reason: "NO LONGER SUPPORTED, USE DATETIME_RANGE")
interval: TimeInterval @deprecated(reason: "NO LONGER SUPPORTED, USE DATETIME_RANGE")
datetimeRange: DatetimeRangeAggregationInput
}
@@ -1064,6 +980,13 @@ type LiveTableStateGQL {
tableState: TableStateGQL!
}
type ShotTableStateGQL {
shotId: Int!
videoId: Int!
frameIndex: Int!
tableState: TableStateGQL!
}
type ShotProjectionGQL {
trajectories: [BallTrajectoryGQL!]!
events: [SimulationEventGQL!]!
@@ -1168,6 +1091,60 @@ input CreatedAfter @oneOf {
createdAt: DateTime
}
type UsageStatsGQL {
funnel: FunnelStatsGQL!
totalUsers: Int!
totalVideos: Int!
totalShots: Int!
totalRuns: Int!
cohorts: [CohortStatsGQL!]!
windows: [UsageStatsWindowGQL!]!
daily: [UsageStatsDailyGQL!]!
processingLast24h: [ProcessingStatusCountGQL!]!
}
type FunnelStatsGQL {
freemiumEpoch: Date!
eraSignups: Int!
eraPaying: Int!
activationCohort: Int!
activationActivated: Int!
payingUsers: Int!
newPaid7d: Int!
newPaid30d: Int!
retentionPrevActive: Int!
retentionReturned: Int!
}
type CohortStatsGQL {
weekStart: Date!
signups: Int!
activated7d: Int!
paid7d: Int!
activatedNotPaid7d: Int!
}
type UsageStatsWindowGQL {
label: String!
newUsers: Int!
activeUsers: Int!
sessions: Int!
shots: Int!
}
type UsageStatsDailyGQL {
day: Date!
newUsers: Int!
activeUsers: Int!
sessions: Int!
shots: Int!
}
type ProcessingStatusCountGQL {
status: String!
count: Int!
}
type UserRelationshipsResult {
inquiringUser: UserGQL!
relationships: [UserRelationship!]!
@@ -1308,9 +1285,7 @@ type StorageStatusGQL {
lastCalculatedAt: DateTime
}
"""
Integer value that can exceed GraphQL Int's 32-bit range.
"""
"""Integer value that can exceed GraphQL Int's 32-bit range."""
scalar BigInt
type UserPlayTimeGQL {
@@ -1381,34 +1356,14 @@ enum VideoExportStatusEnum {
"""
The `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf).
"""
scalar JSON
@specifiedBy(
url: "https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf"
)
scalar JSON @specifiedBy(url: "https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf")
type Mutation {
createBucketSet(params: CreateBucketSetInput!): BucketSetGQL!
createRuleSet(name: String!, description: String = null): RuleSet!
createChallenge(
name: String!
ruleSetId: ID!
minimumShots: Int!
startDate: DateTime!
endDate: DateTime!
description: String = null
requiredTableSize: Float = null
requiredPocketSize: Float = null
isPublic: Boolean! = false
maxAttempts: Int = null
): Challenge!
inviteUsersToChallenge(
challengeId: ID!
userIds: [ID!]!
): [ChallengeInvitation!]!
respondToChallengeInvitation(
invitationId: ID!
accept: Boolean!
): ChallengeInvitation!
createChallenge(name: String!, ruleSetId: ID!, minimumShots: Int!, startDate: DateTime!, endDate: DateTime!, description: String = null, requiredTableSize: Float = null, requiredPocketSize: Float = null, isPublic: Boolean! = false, maxAttempts: Int = null): Challenge!
inviteUsersToChallenge(challengeId: ID!, userIds: [ID!]!): [ChallengeInvitation!]!
respondToChallengeInvitation(invitationId: ID!, accept: Boolean!): ChallengeInvitation!
startChallenge(challengeId: ID!): ChallengeEntry!
recalculateChallengeEntry(entryId: ID!): ChallengeEntry!
submitChallengeEntry(entryId: ID!, videoId: ID!): ChallengeEntry!
@@ -1416,61 +1371,30 @@ type Mutation {
undismissChallenge(challengeId: ID!): Boolean!
setLoggerLevel(path: String!, level: String!): Boolean!
reactToVideo(videoId: Int!, reaction: ReactionEnum): Boolean!
commentOnVideo(
videoId: Int!
message: String!
parentCommentId: Int
): Boolean!
commentOnVideo(videoId: Int!, message: String!, parentCommentId: Int): Boolean!
editComment(videoId: Int!, commentId: Int!, newMessage: String!): Boolean!
deleteComment(videoId: Int!, commentId: Int!): Boolean!
blockContent(videoId: Int!): Boolean!
blockUser(userId: Int!): Boolean!
reportContent(
videoId: Int!
reason: ReportReasonEnum!
customReason: String = null
): Boolean!
reportContent(videoId: Int!, reason: ReportReasonEnum!, customReason: String = null): Boolean!
markNotificationAsRead(notificationId: Int!): Boolean!
markAllNotificationsAsRead: Boolean!
markNotificationsAsRead(notificationIds: [Int!]!): Boolean!
deleteNotification(notificationId: Int!): Boolean!
createPoolHall(input: CreatePoolHallInput!): PoolHall!
updatePoolHall(input: UpdatePoolHallInput!): PoolHall!
createPoolHallCamera(
input: CreatePoolHallCameraInput!
): PoolHallCameraStreamCredentials!
createPoolHallCamera(input: CreatePoolHallCameraInput!): PoolHallCameraStreamCredentials!
updatePoolHallCamera(input: UpdatePoolHallCameraInput!): PoolHallCamera!
rotatePoolHallCameraStreamKey(cameraId: ID!): PoolHallCameraStreamCredentials!
createCameraClaimSession(
cameraId: ID!
durationMinutes: Int = null
videoName: String = null
videoPrivate: Boolean = null
agreedTermsVersion: Int = null
tags: [VideoTagInput!] = null
): CameraClaimSession!
createCameraClaimSession(cameraId: ID!, durationMinutes: Int = null, videoName: String = null, videoPrivate: Boolean = null, agreedTermsVersion: Int = null, tags: [VideoTagInput!] = null): CameraClaimSession!
cancelCameraClaimSession(claimSessionId: ID!): CameraClaimSession!
endCameraLease(leaseId: ID!): CameraLease!
extendCameraLease(leaseId: ID!, additionalMinutes: Int! = 60): CameraLease!
finalizePlayerAssignments(
input: FinalizePlayerAssignmentsInput!
): [PlayerClusterGQL!]!
addAnnotationToShot(
shotId: Int!
annotationName: String!
notes: String = null
): AddShotAnnotationReturn!
updateShotAnnotations(
shotId: Int!
annotations: [UpdateAnnotationInputGQL!]!
): UpdateShotAnnotationReturn!
editShot(
shotId: Int!
fieldsToEdit: EditableShotFieldInputGQL!
): EditShotReturn!
getProfileImageUploadLink(
fileExt: String = ".png"
): GetProfileUploadLinkReturn!
finalizePlayerAssignments(input: FinalizePlayerAssignmentsInput!): [PlayerClusterGQL!]!
addAnnotationToShot(shotId: Int!, annotationName: String!, notes: String = null): AddShotAnnotationReturn!
updateShotAnnotations(shotId: Int!, annotations: [UpdateAnnotationInputGQL!]!): UpdateShotAnnotationReturn!
editShot(shotId: Int!, fieldsToEdit: EditableShotFieldInputGQL!): EditShotReturn!
getProfileImageUploadLink(fileExt: String = ".png"): GetProfileUploadLinkReturn!
editProfileImageUri(profileImageUri: String!): UserGQL!
editUser(input: EditUserInputGQL!): UserGQL!
followUser(followedUserId: Int!): UserGQL!
@@ -1478,39 +1402,20 @@ type Mutation {
retireTags(tagIds: [Int!]!): Boolean!
ensureStripeCustomerExists: UserGQL!
deleteUser: Boolean!
syncAppleSubscription(
input: SyncAppleSubscriptionInputGQL!
): SyncAppleSubscriptionResultGQL!
syncAppleSubscription(input: SyncAppleSubscriptionInputGQL!): SyncAppleSubscriptionResultGQL!
createSubscription(priceId: String!): CreateSubscriptionResultGQL!
createCustomerPortalSession: CreateCustomerPortalSessionResultGQL!
cancelSubscription: UserSubscriptionStatusGQL!
grantManualEntitlement(
userId: Int!
tierName: String! = "pro"
startsAt: DateTime = null
endsAt: DateTime = null
reason: String = null
): UserSubscriptionStatusGQL!
grantManualEntitlement(userId: Int!, tierName: String! = "pro", startsAt: DateTime = null, endsAt: DateTime = null, reason: String = null): UserSubscriptionStatusGQL!
revokeManualEntitlement(userId: Int!): UserSubscriptionStatusGQL!
submitCancellationFeedback(
reasons: [CancellationReasonEnum!] = null
feedback: String = null
metadata: CancellationFeedbackMetadataInput = null
): Boolean!
submitCancellationFeedback(reasons: [CancellationReasonEnum!] = null, feedback: String = null, metadata: CancellationFeedbackMetadataInput = null): Boolean!
requestVideoExport(input: RequestVideoExportInput!): VideoExportJobGQL!
dismissVideoExport(jobId: Int!): Boolean!
findPrerecordTableLayout(b64Image: String!, videoId: Int!): HomographyInfoGQL
createUploadStream(
videoMetadata: VideoMetadataInput!
expectedDurationSeconds: Float = null
): CreateUploadStreamReturn!
createUploadStream(videoMetadata: VideoMetadataInput!, expectedDurationSeconds: Float = null): CreateUploadStreamReturn!
getUploadLink(videoId: Int!, segmentIndex: Int!): GetUploadLinkReturn!
getHlsInitUploadLink(videoId: Int!): GetUploadLinkReturn!
setSegmentDuration(
videoId: Int!
segmentIndex: Int!
duration: Float!
): Boolean!
setSegmentDuration(videoId: Int!, segmentIndex: Int!, duration: Float!): Boolean!
editUploadStream(videoId: Int!, videoMetadata: VideoMetadataInput!): Boolean!
deleteVideo(videoId: Int!): Boolean!
deleteTags(videoId: Int!, tagsToDelete: [VideoTagInput!]!): Boolean!
@@ -1602,9 +1507,7 @@ type AddShotAnnotationReturn {
value: SuccessfulAddAddShotAnnotationErrors!
}
union SuccessfulAddAddShotAnnotationErrors =
SuccessfulAdd
| AddShotAnnotationErrors
union SuccessfulAddAddShotAnnotationErrors = SuccessfulAdd | AddShotAnnotationErrors
type SuccessfulAdd {
value: Boolean!
@@ -1614,9 +1517,7 @@ type AddShotAnnotationErrors {
error: DoesNotOwnShotErrOtherErrorNeedsNote!
}
union DoesNotOwnShotErrOtherErrorNeedsNote =
DoesNotOwnShotErr
| OtherErrorNeedsNote
union DoesNotOwnShotErrOtherErrorNeedsNote = DoesNotOwnShotErr | OtherErrorNeedsNote
type DoesNotOwnShotErr {
shotId: Int!
@@ -1657,9 +1558,7 @@ type GetProfileUploadLinkReturn {
value: UploadLinkGetProfileUploadLinkErrors!
}
union UploadLinkGetProfileUploadLinkErrors =
UploadLink
| GetProfileUploadLinkErrors
union UploadLinkGetProfileUploadLinkErrors = UploadLink | GetProfileUploadLinkErrors
type UploadLink {
uploadUrl: String!
@@ -1746,12 +1645,9 @@ input VideoMetadataInput {
videoName: String = null
startTime: DateTime = null
endTime: DateTime = null
gameType: String = null
@deprecated(reason: "`game_type` is deprecated. Use `tags` instead.")
gameType: String = null @deprecated(reason: "`game_type` is deprecated. Use `tags` instead.")
"""
A list of tags associated with the video. Replace `game_type`
"""
"""A list of tags associated with the video. Replace `game_type`"""
tags: [VideoTagInput!] = null
tableSize: Float = null
pocketSize: Float = null
@@ -1780,15 +1676,7 @@ type GetUploadLinkErrors {
error: MustHaveSetForUploadLinkErrSegmentAlreadyUploadedErrProcessingFailedErrNoInitForChunkedUploadErrTooManyProfileImageUploadsErrInitUploadAlreadyCompletedErrTooManyInitUploadsErrStorageLimitExceededErr!
}
union MustHaveSetForUploadLinkErrSegmentAlreadyUploadedErrProcessingFailedErrNoInitForChunkedUploadErrTooManyProfileImageUploadsErrInitUploadAlreadyCompletedErrTooManyInitUploadsErrStorageLimitExceededErr =
MustHaveSetForUploadLinkErr
| SegmentAlreadyUploadedErr
| ProcessingFailedErr
| NoInitForChunkedUploadErr
| TooManyProfileImageUploadsErr
| InitUploadAlreadyCompletedErr
| TooManyInitUploadsErr
| StorageLimitExceededErr
union MustHaveSetForUploadLinkErrSegmentAlreadyUploadedErrProcessingFailedErrNoInitForChunkedUploadErrTooManyProfileImageUploadsErrInitUploadAlreadyCompletedErrTooManyInitUploadsErrStorageLimitExceededErr = MustHaveSetForUploadLinkErr | SegmentAlreadyUploadedErr | ProcessingFailedErr | NoInitForChunkedUploadErr | TooManyProfileImageUploadsErr | InitUploadAlreadyCompletedErr | TooManyInitUploadsErr | StorageLimitExceededErr
type MustHaveSetForUploadLinkErr {
resolution: Boolean