Compare commits

..

22 Commits

Author SHA1 Message Date
beeba9207c add difficulty field to aggregate shot metrics operation
All checks were successful
Tests / Tests (pull_request) Successful in 22s
2025-11-13 11:10:58 -08:00
f14e117416 Merge pull request 'Add videoId field to playlist in ShotWithAllFeatures fragment' (#210) from loewy/add-video-id-to-playlist-shots-fragment into master
Reviewed-on: #210
2025-11-12 22:16:58 +00:00
3d86c13291 add videoId field to playlist in shot w features fragment
All checks were successful
Tests / Tests (pull_request) Successful in 10s
2025-11-12 14:08:49 -08:00
e63f8600aa Merge pull request 'Add pocket size field to GraphQL schema and operations' (#209) from dean/add-pocket-size-clean into master
Reviewed-on: #209
2025-11-11 21:09:28 +00:00
7e822446da Merge branch 'master' into dean/add-pocket-size-clean
All checks were successful
Tests / Tests (pull_request) Successful in 9s
2025-11-11 20:34:55 +00:00
75ecc5894b Merge pull request 'dean/add-home-feed-option' (#208) from dean/add-home-feed-option into master
Reviewed-on: #208
2025-11-10 22:09:09 +00:00
73c8dd5f57 Merge branch 'master' into dean/add-home-feed-option
All checks were successful
Tests / Tests (pull_request) Successful in 10s
2025-11-10 19:55:16 +00:00
dean
ce8d2aaec8 Add pocket size field to GraphQL schema and operations
All checks were successful
Tests / Tests (pull_request) Successful in 9s
2025-11-10 10:55:08 -08:00
0f89f97006 Merge pull request 'Add playlist with segment durations to ShotWithAllFeaturesFragment' (#207) from loewy/include-playlist-in-shot-features into master
Reviewed-on: #207
Reviewed-by: dean <deanwenstrand@gmail.com>
2025-11-10 18:15:41 +00:00
dean
e4223a1a17 Add isFollowedByCurrentUser field and hasFollowing to feed query
All checks were successful
Tests / Tests (pull_request) Successful in 9s
Updated GraphQL operations to support efficient follow status checking:
- Added isFollowedByCurrentUser field to UserSocialsFields fragment
- Removed nested followers array from UserSocialsFields (over-fetching)
- Simplified followUser/unfollowUser mutations to return minimal data
- Added hasFollowing field to GetVideoFeed query for feed mode detection
- Updated getUserFollowingFollowers query to include isFollowedByCurrentUser

These changes enable the mobile app to:
- Display correct follow/unfollow button states without client-side lookups
- Differentiate between "Following" and "Popular" feed modes
- Reduce payload size by removing unnecessary nested data

Backend handles efficient resolution via request-scoped caching.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 23:44:39 -08:00
dean
83b7f0d0f6 Add home feed and isFollowedByCurrentUser field
- Add home option to VideoFeedInputGQL for automatic feed selection
- Add hasFollowing field to VideoHistoryGQL response
- Add isFollowedByCurrentUser field to UserGQL to replace followers N+1

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 09:15:39 -08:00
dean
a882f98d91 Add home option to VideoFeedInputGQL
The home feed option enables smart feed selection on the backend:
- If user has following: returns FOLLOWING feed
- If user has no following: returns ALL feed
- Always includes hasFollowing flag so frontend knows which feed it got

This allows frontend to make a single query instead of needing to
check following status separately.
2025-11-07 12:16:01 -08:00
cdf438c089 add playlist w/ segment durations in gql return
All checks were successful
Tests / Tests (pull_request) Successful in 10s
2025-11-07 11:53:13 -08:00
7dbfadf13a Merge pull request 'Notifications Operation' (#206) from loewy/notifications-operations into master
Reviewed-on: #206
2025-11-07 00:15:28 +00:00
a74a11e789 update notif operations
All checks were successful
Tests / Tests (pull_request) Successful in 9s
2025-11-06 16:06:32 -08:00
3b2f88c0e0 update naming of notification fragment 2025-11-06 16:06:32 -08:00
a3ac769cd4 notifications operations 2025-11-06 16:06:32 -08:00
00fc2ab44b Merge pull request 'Notifications schema' (#205) from loewy/notifications-schema into master
Reviewed-on: #205
2025-11-07 00:05:04 +00:00
58ab272289 add follow enum
All checks were successful
Tests / Tests (pull_request) Successful in 9s
2025-11-06 15:33:41 -08:00
242afae92b notifications schema 2025-11-06 15:33:41 -08:00
6bf597a2ec Merge pull request 'add has follwer to feed query' (#204) from dean/add-has-following-to-feed into master
Reviewed-on: #204
2025-11-06 23:30:07 +00:00
5c62d45068 Merge pull request 'Add marketing opt in to schema' (#203) from loewy/add-agrees-to-marketing-schema into master
Reviewed-on: #203
2025-10-20 20:52:17 +00:00
8 changed files with 742 additions and 159 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,7 @@ query GetAggregatedShotMetrics($aggregateInput: AggregateInputGQL!) {
targetMetrics { targetMetrics {
count count
makePercentage makePercentage
averageDifficulty
} }
} }
} }

View File

@@ -19,11 +19,7 @@ fragment UserSocialsFields on UserGQL {
id id
username username
profileImageUri profileImageUri
followers { isFollowedByCurrentUser
id
username
profileImageUri
}
} }
fragment VideoCardFields on VideoGQL { fragment VideoCardFields on VideoGQL {
@@ -116,5 +112,6 @@ query GetVideoFeed(
hasNextPage hasNextPage
endCursor endCursor
} }
hasFollowing
} }
} }

View File

@@ -0,0 +1,58 @@
query GetNotifications(
$limit: Int! = 20
$offset: Int! = 0
$filters: NotificationFilters = null
) {
notifications(limit: $limit, offset: $offset, filters: $filters) {
notifications {
...Notification
}
totalCount
unreadCount
hasMore
}
}
query GetUnreadNotificationCount {
unreadNotificationCount
}
mutation MarkNotificationAsRead($notificationId: Int!) {
markNotificationAsRead(notificationId: $notificationId)
}
mutation MarkNotificationsAsRead($notificationIds: [Int!]!) {
markNotificationsAsRead(notificationIds: $notificationIds)
}
mutation MarkAllNotificationsAsRead {
markAllNotificationsAsRead
}
mutation DeleteNotification($notificationId: Int!) {
deleteNotification(notificationId: $notificationId)
}
fragment Notification on NotificationGQL {
id
notificationType
actor {
id
username
profileImageUri
}
videoId
comment {
id
message
user {
id
username
profileImageUri
}
}
reactionType
isRead
createdAt
readAt
}

View File

@@ -191,6 +191,10 @@ fragment ShotWithAllFeatures on ShotGQL {
id id
streamSegmentType streamSegmentType
} }
playlist {
videoId
segmentDurations
}
} }
} }

View File

@@ -88,31 +88,15 @@ query GetUserTags {
mutation followUser($followedUserId: Int!) { mutation followUser($followedUserId: Int!) {
followUser(followedUserId: $followedUserId) { followUser(followedUserId: $followedUserId) {
username
id id
following { username
id
username
}
followers {
id
username
}
} }
} }
mutation unfollowUser($followedUserId: Int!) { mutation unfollowUser($followedUserId: Int!) {
unfollowUser(followedUserId: $followedUserId) { unfollowUser(followedUserId: $followedUserId) {
username
id id
following { username
id
username
}
followers {
id
username
}
} }
} }
@@ -123,11 +107,13 @@ query getUserFollowingFollowers {
id id
username username
profileImageUri profileImageUri
isFollowedByCurrentUser
} }
followers { followers {
id id
username username
profileImageUri profileImageUri
isFollowedByCurrentUser
} }
} }
} }

View File

@@ -36,6 +36,7 @@ query GetVideoUpdatePageDetails($videoId: Int!) {
makePercentage makePercentage
elapsedTime elapsedTime
tableSize tableSize
pocketSize
private private
tags { tags {
tagClasses { tagClasses {
@@ -66,6 +67,7 @@ query GetVideoDetails($videoId: Int!) {
createdAt createdAt
updatedAt updatedAt
tableSize tableSize
pocketSize
private private
owner { owner {
id id
@@ -86,17 +88,16 @@ fragment UserSocialsFields on UserGQL {
id id
username username
profileImageUri profileImageUri
followers { isFollowedByCurrentUser
id
username
profileImageUri
}
} }
query GetVideoSocialDetailsById($videoId: Int!) { query GetVideoSocialDetailsById($videoId: Int!) {
getVideo(videoId: $videoId) { getVideo(videoId: $videoId) {
id id
name name
screenshotUri
makePercentage
totalShots
owner { owner {
id id
firebaseUid firebaseUid

View File

@@ -28,6 +28,12 @@ type Query {
when: DateTime = null when: DateTime = null
): CountLeaderboardGQL! ): CountLeaderboardGQL!
getMedals(scope: MedalScope!, userId: Int = null): RequestedMedalsGQL! getMedals(scope: MedalScope!, userId: Int = null): RequestedMedalsGQL!
notifications(
limit: Int! = 20
offset: Int! = 0
filters: NotificationFilters = null
): NotificationConnection!
unreadNotificationCount: Int!
getRuns( getRuns(
filterInput: RunFilterInput! filterInput: RunFilterInput!
runIds: [Int!] = null runIds: [Int!] = null
@@ -342,6 +348,7 @@ type VideoGQL {
elapsedTime: Float elapsedTime: Float
framesPerSecond: Float! framesPerSecond: Float!
tableSize: Float! tableSize: Float!
pocketSize: Float
private: Boolean! private: Boolean!
stream: UploadStreamGQL stream: UploadStreamGQL
playlist: HLSPlaylistGQL playlist: HLSPlaylistGQL
@@ -368,6 +375,7 @@ type UserGQL {
agreesToMarketing: Boolean agreesToMarketing: Boolean
following: [UserGQL!] following: [UserGQL!]
followers: [UserGQL!] followers: [UserGQL!]
isFollowedByCurrentUser: Boolean
} }
type ShotGQL { type ShotGQL {
@@ -647,6 +655,7 @@ input VideoFeedInputGQL @oneOf {
followedByUserId: Int followedByUserId: Int
userId: Int userId: Int
allUsers: Boolean allUsers: Boolean
home: Boolean
} }
type MakePercentageIntervalGQL { type MakePercentageIntervalGQL {
@@ -715,6 +724,37 @@ input MedalScope @oneOf {
datetimeRange: DatetimeRangeAggregationInput datetimeRange: DatetimeRangeAggregationInput
} }
type NotificationConnection {
notifications: [NotificationGQL!]!
totalCount: Int!
unreadCount: Int!
hasMore: Boolean!
}
type NotificationGQL {
id: Int!
notificationType: NotificationTypeEnum!
actor: UserGQL!
videoId: Int
comment: CommentGQL
reactionType: String
isRead: Boolean!
createdAt: DateTime!
readAt: DateTime
}
enum NotificationTypeEnum {
COMMENT
COMMENT_REPLY
REACTION
FOLLOW
}
input NotificationFilters {
isRead: Boolean = null
notificationTypes: [NotificationTypeEnum!] = null
}
type GetRunsResult { type GetRunsResult {
runs: [RunGQL!]! runs: [RunGQL!]!
count: Int count: Int
@@ -916,6 +956,10 @@ type Mutation {
reason: ReportReasonEnum! reason: ReportReasonEnum!
customReason: String = null customReason: String = null
): Boolean! ): Boolean!
markNotificationAsRead(notificationId: Int!): Boolean!
markAllNotificationsAsRead: Boolean!
markNotificationsAsRead(notificationIds: [Int!]!): Boolean!
deleteNotification(notificationId: Int!): Boolean!
addAnnotationToShot( addAnnotationToShot(
shotId: Int! shotId: Int!
annotationName: String! annotationName: String!
@@ -1081,6 +1125,7 @@ input VideoMetadataInput {
""" """
tags: [VideoTagInput!] = null tags: [VideoTagInput!] = null
tableSize: Float = null tableSize: Float = null
pocketSize: Float = null
lastIntendedSegmentBound: Int = null lastIntendedSegmentBound: Int = null
streamSegmentType: StreamSegmentTypeEnum = null streamSegmentType: StreamSegmentTypeEnum = null
private: Boolean = null private: Boolean = null