feat(apps): collaborative tracks — display, upload tagging, notifications, accept/leave (behind flag)#14466
Open
raymondjacobson wants to merge 11 commits into
Open
feat(apps): collaborative tracks — display, upload tagging, notifications, accept/leave (behind flag)#14466raymondjacobson wants to merge 11 commits into
raymondjacobson wants to merge 11 commits into
Conversation
… flag) Display slice of the apps phase: renders a track's accepted collaborators as a comma-separated artist line on web track tiles and the track page, behind a new `collaborative_tracks` flag (default off). Ships inert. - packages/common: `TrackMetadata.collaborators` (UserMetadata[]), mapped in userTrackMetadataFromSDK and decoded like the owner. The field isn't in the generated SDK Track type yet, so it's read via a structural extension pending the SDK regen. New COLLABORATIVE_TRACKS feature flag. - packages/web: <TrackArtists> renders the owner plus comma-separated collaborators on one ellipsizing line. With the flag off (or no collaborators) it returns a single owner <UserLink> — a safe drop-in. Wired into desktop TrackTile, mobile-web TrackTile, and GiantTrackTile. Next apps slices: mobile-native tiles, upload tagging UI, notifications + accept UX, SDK write methods. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Contributor
🌐 Web preview readyPreview URL: https://audius-web-preview-pr-14466.audius.workers.dev Unique preview for this PR (deployed from this branch). |
…ind flag) Mobile-native parity for the collaborator artist line, behind the collaborative_tracks flag. - <TrackArtists> (owner UserLink + collaborators) and <CollaboratorLinks> (collaborators-only append), both flag-gated so they're no-ops when off. - TrackCard: owner UserLink -> TrackArtists (collaborators added to the track select). Wrapper centers to preserve the card's centered artist line. - TrackDetailsTile: keeps the owner Text + UserBadges and appends CollaboratorLinks, so the flag-off rendering is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- SDK: TrackCollaborator EntityType; TracksApi.acceptTrackCollaboration / rejectTrackCollaboration (EntityManager Approve/Reject; reject = decline or leave). collaborators added to UploadTrackMetadataSchema (numeric user ids). - Upload adapter maps form collaborator user objects -> numeric ids on-chain. - tan-query: useAcceptTrackCollaboration, useRejectTrackCollaboration. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- CollaboratorsField: search + add collaborators (reuses SearchUsersModal / ArtistChip, like the invite-manager UI) with removable chips. Wired into TrackMetadataFields behind the collaborative_tracks flag. - collaborators added to the upload form schema (full user objects). Mobile upload tagging deferred (needs a native user picker); data plumbing already supports it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…e (behind flag) - Notification types track_collaborator_invite / track_collaborator_accept (NotificationType + PushNotificationType + interfaces + union + adapter cases). - Web: invite notification with inline Accept/Decline (useAccept/RejectTrack- Collaboration), accept notification (display); routing in Notification.tsx. TrackMenu gains a 'Remove Me as Collaborator' item shown to accepted collaborators (not the owner) — the post-accept leave path. - Mobile: invite/accept notification components + routing + navigation handlers (navigate to the track). Deferred follow-ups: mobile upload picker, mobile overflow leave action, a pending-invites list page, and SDK read-type regen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Finishes the deferred mobile pieces. - CollaboratorField: self-contained inline search (useSearchUserResults) + removable chips, added to the mobile edit-track form behind the flag. Selected users flow through the upload metadata adapter to numeric ids. - "Remove Me as Collaborator" overflow action: new OverflowAction.LEAVE_TRACK_COLLABORATION, row label + drawer callback (rejectTrackCollaboration + toast), shown on the track page to accepted collaborators (not the owner). Known limitation: editing a track initializes collaborators from the API's accepted list only, so re-saving could drop still-pending invites — needs an owner-facing "all collaborators" source to fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rder - SDK: the generated Notification union/parser threw on unknown types and the adapter switch couldn't reference them. Add TrackCollaboratorNotification (+ Action/ActionData) generated models and wire them into Notification.ts (union + FromJSONTyped cases) so track_collaborator_invite/accept parse and typecheck. Hand-authored pending an OpenAPI regen. - Fix import/order lint in web Notification.tsx and TrackMenu.tsx, and mobile TrackScreenDetailsTile.tsx. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ivate tracks - Remove the collaborative_tracks feature flag and its gating everywhere; the feature is always on now (display, upload tagging, notifications, leave). - Fix the invite notification doing nothing on a private track: a pending collaborator can't load an unlisted track (the API filters it), so the `if (!track) return null` guard blanked the whole notification — including the Accept/Decline buttons. Render off the inviter alone, fall back to "a track" for the title, and act on the trackId carried by the notification. - Add success/error toasts (and disable-while-submitting) to Accept/Decline so it's no longer silent. Same null-guard relaxed on the accept notifications and the mobile equivalents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The API returns `collaborators` on track responses, but the generated SDK Track/SearchTrack models' FromJSONTyped only copy known fields — so the field was silently dropped during deserialization, and the adapter's structural cast always read `undefined`. Result: accepted collaborators never rendered on track pages/tiles even though the backend returned them. Add `collaborators?: Array<User>` to the generated Track and SearchTrack models (interface + FromJSONTyped + ToJSON, mirroring `user`) so the field survives, and read it directly in the adapter. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Now that the API swagger declares `collaborators` (deployed), ran the real generator (typescript-fetch v7.5.0) against api.audius.co's spec. The output for Track.ts/SearchTrack.ts is byte-identical to the prior hand-edit (only a generator-emitted whitespace differs), confirming the field is now genuinely generated rather than hand-patched. Other models left untouched (unrelated spec drift not pulled in); the hand-authored notification models remain as-is. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The edit form seeded its collaborators field from the track's accepted-only `collaborators`, so saving dropped any still-pending invites (the ETL reconciles the metadata set). Initialize the field from accepted + pending instead. - SDK Track/SearchTrack: add `pendingCollaborators` (hand-edit stopgap; the API swagger now declares `pending_collaborators` in AudiusProject/api#947, so the next regen reproduces this). - Track model + adapter: expose `pending_collaborators` (owner-only). - Web + mobile edit screens: seed the collaborators field with `[...collaborators, ...pending_collaborators]` so pending invites survive a save. Display still uses accepted-only `collaborators` (no regression). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 3 — the apps client for collaborative tracks, all behind the new
collaborative_tracksfeature flag (default off), so it ships inert. Pairs with go-openaudio #345/#346/#349 (ETL) and AudiusProject/api #932 (api). Reviewing as one PR per your request; commits are sliced by concern.What's implemented (web + mobile)
Display —
TrackMetadata.collaborators+ adapter;<TrackArtists>renders owner + comma-separated collaborators with ellipsis overflow on web tiles/track page and mobileTrackCard/TrackDetailsTile. Flag-off = the previous single owner link.SDK + hooks —
TrackCollaboratorEntityType;TracksApi.acceptTrackCollaboration/rejectTrackCollaboration(reject = decline or leave);collaboratorsin the upload metadata schema; upload adapter maps tagged users → numeric on-chain ids; tan-queryuseAccept/RejectTrackCollaboration.Upload tagging — web
CollaboratorsField(reusesSearchUsersModal/ArtistChip) and mobileCollaboratorField(self-contained inline search + chips), both in the edit-track form behind the flag.Notifications + accept/decline —
track_collaborator_invite/track_collaborator_accepttypes, adapter, web + mobile components + routing. Web invite notification has inline Accept/Decline.Leave (remove yourself after accepting) — web
TrackMenuand mobile track-page overflow both gain "Remove Me as Collaborator", shown to accepted collaborators (not the owner).Deferred follow-ups (called out)
GET /users/:id/collaboration_invites.collaboratorson the generatedTracktype + the invites endpoint need an OpenAPI spec update + regen; the read path currently uses a small structural extension.Verification caveat
I could not run the apps typecheck/lint/build locally (the worktree's toolchain/deps don't match this environment). These changes are pattern-copies of the existing manager-invite/approve flow and are CI-pending — please let CI and your review be the gate. (Server-side: notification id hashing is already generic via
trashid.HashifyJson, so the new types' data ids encode correctly with no api change.)🤖 Generated with Claude Code