Compare commits
21 Commits
dean/playe
...
dean/camer
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4f4a539f5 | ||
| 7cef75b2ca | |||
|
|
6d5cd9b1ed | ||
|
|
d59e21c10e | ||
| 9358205327 | |||
| 88634a32e9 | |||
| f7200a2e9f | |||
| 7d839c0fa6 | |||
| ab1e604871 | |||
| deb724b430 | |||
| c586bdf1a6 | |||
|
|
9250e4c639 | ||
| a12b3e1210 | |||
|
|
5cf2dbaf01 | ||
| 239a143554 | |||
|
|
296522afb8 | ||
| f42579076e | |||
|
|
0c9eb4945a | ||
| 1182c15004 | |||
|
|
755336b16a | ||
| c1efe9f5f2 |
780
src/index.tsx
780
src/index.tsx
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@ query getDeployedConfig {
|
|||||||
firebase
|
firebase
|
||||||
minimumAllowedAppVersion
|
minimumAllowedAppVersion
|
||||||
subscriptionGatingEnabled
|
subscriptionGatingEnabled
|
||||||
|
quotaEnforcementEnabled
|
||||||
bannerMessages {
|
bannerMessages {
|
||||||
color
|
color
|
||||||
dismissible
|
dismissible
|
||||||
|
|||||||
@@ -47,6 +47,12 @@ fragment VideoCardFields on VideoGQL {
|
|||||||
pocketSize
|
pocketSize
|
||||||
tags {
|
tags {
|
||||||
name
|
name
|
||||||
|
tagClasses {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
playerSummaries {
|
||||||
|
...PlayerSummaryFields
|
||||||
}
|
}
|
||||||
currentProcessing {
|
currentProcessing {
|
||||||
id
|
id
|
||||||
@@ -95,6 +101,27 @@ query GetVideoFeedSessionCount(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Minimal query for the Home recency nudge ("you haven't recorded in N days").
|
||||||
|
# Only the most recent session's start time — avoids pulling the full
|
||||||
|
# VideoCardFields payload (reactions, comments, player summaries, etc.).
|
||||||
|
query GetLastSessionDate(
|
||||||
|
$filters: VideoFilterInput = null
|
||||||
|
$includePrivate: IncludePrivateEnum = MINE
|
||||||
|
$feedInput: VideoFeedInputGQL = null
|
||||||
|
) {
|
||||||
|
getFeedVideos(
|
||||||
|
limit: 1
|
||||||
|
filters: $filters
|
||||||
|
includePrivate: $includePrivate
|
||||||
|
feedInput: $feedInput
|
||||||
|
) {
|
||||||
|
videos {
|
||||||
|
id
|
||||||
|
startTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
query GetVideoFeed(
|
query GetVideoFeed(
|
||||||
$limit: Int! = 5
|
$limit: Int! = 5
|
||||||
$after: String = null
|
$after: String = null
|
||||||
|
|||||||
@@ -1,3 +1,18 @@
|
|||||||
|
fragment PlayerSummaryFields on PlayerSummaryGQL {
|
||||||
|
clusterId
|
||||||
|
userId
|
||||||
|
username
|
||||||
|
profileImageUri
|
||||||
|
representativeFullFrameUrl
|
||||||
|
totalShots
|
||||||
|
totalShotsMade
|
||||||
|
makePercentage
|
||||||
|
score
|
||||||
|
longestRun
|
||||||
|
averageDifficulty
|
||||||
|
averageTimeBetweenShots
|
||||||
|
}
|
||||||
|
|
||||||
fragment PlayerClusterShotFields on PlayerClusterShotGQL {
|
fragment PlayerClusterShotFields on PlayerClusterShotGQL {
|
||||||
shotId
|
shotId
|
||||||
bboxX1
|
bboxX1
|
||||||
@@ -15,7 +30,10 @@ fragment PlayerClusterFields on PlayerClusterGQL {
|
|||||||
clusterId
|
clusterId
|
||||||
nShots
|
nShots
|
||||||
userId
|
userId
|
||||||
|
username
|
||||||
|
profileImageUri
|
||||||
confirmed
|
confirmed
|
||||||
|
score
|
||||||
shots {
|
shots {
|
||||||
...PlayerClusterShotFields
|
...PlayerClusterShotFields
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,6 +132,38 @@ query GetShotsByIds($ids: [Int!]!) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Lightweight clip boundaries for condensed session playback. The inline
|
||||||
|
# session player only needs each shot's frame/time window to seek between
|
||||||
|
# shots — this skips the heavy ShotWithAllFeatures payload (cue/pocketing
|
||||||
|
# features, serialized shot paths, annotations, nested video/playlist). The
|
||||||
|
# startTime/endTime @client resolvers derive their values from the frame
|
||||||
|
# fields + the video (looked up internally), so this is all they require.
|
||||||
|
fragment ShotClipRange on ShotGQL {
|
||||||
|
id
|
||||||
|
videoId
|
||||||
|
startFrame
|
||||||
|
endFrame
|
||||||
|
startTime @client
|
||||||
|
endTime @client
|
||||||
|
}
|
||||||
|
|
||||||
|
query GetShotClipRanges(
|
||||||
|
$filterInput: FilterInput!
|
||||||
|
$shotsOrdering: GetShotsOrdering
|
||||||
|
$limit: Int
|
||||||
|
) {
|
||||||
|
getOrderedShots(
|
||||||
|
filterInput: $filterInput
|
||||||
|
shotsOrdering: $shotsOrdering
|
||||||
|
limit: $limit
|
||||||
|
) {
|
||||||
|
count
|
||||||
|
shots {
|
||||||
|
...ShotClipRange
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fragment ShotWithAllFeatures on ShotGQL {
|
fragment ShotWithAllFeatures on ShotGQL {
|
||||||
id
|
id
|
||||||
videoId
|
videoId
|
||||||
|
|||||||
@@ -49,6 +49,39 @@ query GetUserPlayTime($userId: Int!, $filters: VideoFilterInput) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query GetUploadQuotaStatus {
|
||||||
|
getQuotaStatus {
|
||||||
|
tierName
|
||||||
|
periodStart
|
||||||
|
periodEnd
|
||||||
|
durationUsedSeconds
|
||||||
|
durationLimitSeconds
|
||||||
|
maxVideoDurationSeconds
|
||||||
|
durationRemainingSeconds
|
||||||
|
canUpload
|
||||||
|
importQuotaBuckets {
|
||||||
|
quotaKey
|
||||||
|
appliesToUploadKind
|
||||||
|
periodStart
|
||||||
|
periodEnd
|
||||||
|
durationUsedSeconds
|
||||||
|
durationLimitSeconds
|
||||||
|
durationRemainingSeconds
|
||||||
|
canUpload
|
||||||
|
}
|
||||||
|
recordingQuotaBuckets {
|
||||||
|
quotaKey
|
||||||
|
appliesToUploadKind
|
||||||
|
periodStart
|
||||||
|
periodEnd
|
||||||
|
durationUsedSeconds
|
||||||
|
durationLimitSeconds
|
||||||
|
durationRemainingSeconds
|
||||||
|
canUpload
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
query getUsernames(
|
query getUsernames(
|
||||||
$matchString: String!
|
$matchString: String!
|
||||||
$limit: Int = null
|
$limit: Int = null
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ query GetVideoDetails($videoId: Int!) {
|
|||||||
}
|
}
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
|
playerSummaries {
|
||||||
|
...PlayerSummaryFields
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,6 +139,15 @@ query GetVideoSocialDetailsById($videoId: Int!) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Full card payload for a single video — reuses the same VideoCardFields
|
||||||
|
# fragment the feed list uses, so the session-detail meta header shares one
|
||||||
|
# source of truth (and the normalized Apollo cache) with the feed card.
|
||||||
|
query GetVideoCard($videoId: Int!) {
|
||||||
|
getVideo(videoId: $videoId) {
|
||||||
|
...VideoCardFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
query GetVideos($videoIds: [Int!]!) {
|
query GetVideos($videoIds: [Int!]!) {
|
||||||
getVideos(videoIds: $videoIds) {
|
getVideos(videoIds: $videoIds) {
|
||||||
...VideoStreamMetadata
|
...VideoStreamMetadata
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ type Query {
|
|||||||
myChallengeInvitations: [ChallengeInvitation!]!
|
myChallengeInvitations: [ChallengeInvitation!]!
|
||||||
ruleSets: [RuleSet!]!
|
ruleSets: [RuleSet!]!
|
||||||
myChallengeEntries: [ChallengeEntry!]!
|
myChallengeEntries: [ChallengeEntry!]!
|
||||||
|
getVenues: [VenueGQL!]!
|
||||||
|
getActiveClaim: CameraClaimGQL
|
||||||
getDeployedConfig: DeployedConfigGQL!
|
getDeployedConfig: DeployedConfigGQL!
|
||||||
waitFor(duration: Float!): Float!
|
waitFor(duration: Float!): Float!
|
||||||
getFeedVideos(
|
getFeedVideos(
|
||||||
@@ -406,6 +408,7 @@ type VideoGQL {
|
|||||||
currentProcessing: VideoProcessingGQL
|
currentProcessing: VideoProcessingGQL
|
||||||
reactions: [ReactionGQL!]!
|
reactions: [ReactionGQL!]!
|
||||||
comments: [CommentGQL!]!
|
comments: [CommentGQL!]!
|
||||||
|
playerSummaries: [PlayerSummaryGQL!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShotGQL {
|
type ShotGQL {
|
||||||
@@ -665,6 +668,63 @@ type CommentGQL {
|
|||||||
replies: [CommentGQL!]!
|
replies: [CommentGQL!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PlayerSummaryGQL {
|
||||||
|
clusterId: Int!
|
||||||
|
userId: Int
|
||||||
|
username: String
|
||||||
|
profileImageUri: String
|
||||||
|
representativeFullFrameUrl: String
|
||||||
|
totalShots: Int!
|
||||||
|
totalShotsMade: Int!
|
||||||
|
makePercentage: Float!
|
||||||
|
score: Int
|
||||||
|
longestRun: Int!
|
||||||
|
averageDifficulty: Float
|
||||||
|
averageTimeBetweenShots: Float
|
||||||
|
}
|
||||||
|
|
||||||
|
type VenueGQL {
|
||||||
|
id: Int!
|
||||||
|
name: String!
|
||||||
|
latitude: Float
|
||||||
|
longitude: Float
|
||||||
|
cameras: [VenueCameraGQL!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
type VenueCameraGQL {
|
||||||
|
id: Int!
|
||||||
|
venueId: Int!
|
||||||
|
tableLabel: String!
|
||||||
|
enabled: Boolean!
|
||||||
|
isAvailable: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
type CameraClaimGQL {
|
||||||
|
id: Int!
|
||||||
|
cameraId: Int!
|
||||||
|
userId: Int!
|
||||||
|
videoId: Int
|
||||||
|
status: ClaimStatusEnum!
|
||||||
|
expiresAt: DateTime
|
||||||
|
endedAt: DateTime
|
||||||
|
createdAt: DateTime!
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ClaimStatusEnum {
|
||||||
|
REQUESTED
|
||||||
|
CODE_ISSUED
|
||||||
|
SCANNING
|
||||||
|
SCAN_CONFIRMED
|
||||||
|
INGESTING
|
||||||
|
ACTIVE
|
||||||
|
ENDED_BY_USER
|
||||||
|
EXPIRED
|
||||||
|
STREAM_LOST
|
||||||
|
STREAM_UNREACHABLE
|
||||||
|
CODE_EXPIRED
|
||||||
|
RELEASED_INACTIVE
|
||||||
|
}
|
||||||
|
|
||||||
type DeployedConfigGQL {
|
type DeployedConfigGQL {
|
||||||
allowNewUsers: Boolean!
|
allowNewUsers: Boolean!
|
||||||
firebase: Boolean!
|
firebase: Boolean!
|
||||||
@@ -672,6 +732,7 @@ type DeployedConfigGQL {
|
|||||||
environment: String!
|
environment: String!
|
||||||
minimumAllowedAppVersion: String!
|
minimumAllowedAppVersion: String!
|
||||||
subscriptionGatingEnabled: Boolean!
|
subscriptionGatingEnabled: Boolean!
|
||||||
|
quotaEnforcementEnabled: Boolean!
|
||||||
bannerMessages: [BannerGQL!]!
|
bannerMessages: [BannerGQL!]!
|
||||||
defaultAndroidRecordingFormat: StreamSegmentTypeEnum!
|
defaultAndroidRecordingFormat: StreamSegmentTypeEnum!
|
||||||
bucketUrl: String!
|
bucketUrl: String!
|
||||||
@@ -866,7 +927,10 @@ type PlayerClusterGQL {
|
|||||||
clusterId: Int!
|
clusterId: Int!
|
||||||
nShots: Int!
|
nShots: Int!
|
||||||
userId: Int
|
userId: Int
|
||||||
|
username: String
|
||||||
|
profileImageUri: String
|
||||||
confirmed: Boolean!
|
confirmed: Boolean!
|
||||||
|
score: Int
|
||||||
shots: [PlayerClusterShotGQL!]!
|
shots: [PlayerClusterShotGQL!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1021,6 +1085,19 @@ type QuotaStatusGQL {
|
|||||||
durationUsedSeconds: Float!
|
durationUsedSeconds: Float!
|
||||||
durationLimitSeconds: Int
|
durationLimitSeconds: Int
|
||||||
maxVideoDurationSeconds: Int
|
maxVideoDurationSeconds: Int
|
||||||
|
importQuotaBuckets: [QuotaBucketStatusGQL!]!
|
||||||
|
recordingQuotaBuckets: [QuotaBucketStatusGQL!]!
|
||||||
|
durationRemainingSeconds: Float
|
||||||
|
canUpload: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
type QuotaBucketStatusGQL {
|
||||||
|
quotaKey: String!
|
||||||
|
appliesToUploadKind: String!
|
||||||
|
periodStart: DateTime!
|
||||||
|
periodEnd: DateTime!
|
||||||
|
durationUsedSeconds: Float!
|
||||||
|
durationLimitSeconds: Int
|
||||||
durationRemainingSeconds: Float
|
durationRemainingSeconds: Float
|
||||||
canUpload: Boolean!
|
canUpload: Boolean!
|
||||||
}
|
}
|
||||||
@@ -1096,6 +1173,9 @@ type Mutation {
|
|||||||
submitChallengeEntry(entryId: ID!, videoId: ID!): ChallengeEntry!
|
submitChallengeEntry(entryId: ID!, videoId: ID!): ChallengeEntry!
|
||||||
dismissChallenge(challengeId: ID!): Boolean!
|
dismissChallenge(challengeId: ID!): Boolean!
|
||||||
undismissChallenge(challengeId: ID!): Boolean!
|
undismissChallenge(challengeId: ID!): Boolean!
|
||||||
|
claimCamera(cameraId: Int!, durationMinutes: Int! = 60): CameraClaimGQL!
|
||||||
|
endClaim(claimId: Int!): CameraClaimGQL!
|
||||||
|
extendClaim(claimId: Int!, additionalMinutes: Int! = 60): CameraClaimGQL!
|
||||||
setLoggerLevel(path: String!, level: String!): Boolean!
|
setLoggerLevel(path: String!, level: String!): Boolean!
|
||||||
reactToVideo(videoId: Int!, reaction: ReactionEnum): Boolean!
|
reactToVideo(videoId: Int!, reaction: ReactionEnum): Boolean!
|
||||||
commentOnVideo(
|
commentOnVideo(
|
||||||
@@ -1199,6 +1279,7 @@ input FinalizePlayerAssignmentsInput {
|
|||||||
input ClusterAssignmentInput {
|
input ClusterAssignmentInput {
|
||||||
clusterId: Int!
|
clusterId: Int!
|
||||||
userId: Int = null
|
userId: Int = null
|
||||||
|
score: Int = null
|
||||||
}
|
}
|
||||||
|
|
||||||
input ShotMoveInput {
|
input ShotMoveInput {
|
||||||
|
|||||||
Reference in New Issue
Block a user