fix(embed): honor is_streamable so inactive artists' tracks don't render - #14571
Merged
Merged
Conversation
apps#14570 gated the web and mobile track pages on `is_streamable`, but the embed player is its own app and was left rendering the full card - title, artist, artwork, play button - for a track whose owner deactivated their own account or was delisted by the trusted notifier. api#1023 made the stream endpoint 404, so the player was already unable to play these; it just showed the metadata and then failed silently on press. Route non-streamable tracks into the existing not-available treatment. The copy is its own message rather than reusing the deleted-by-creator string: the same flag covers a self deactivation and a delisted account, and we shouldn't tell listeners the creator removed a track when moderation suppressed it. Wording matches the web tombstone from #14570. The check is an explicit `=== false` because an absent field must not read as unavailable. Verified against audius.co/rehoxx/just-for-tonight-wmellark-hoonds in all three flavors (card, compact, tiny) and both routes (hash id and permalink), with a streamable track confirmed unaffected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
dylanjeffers
added a commit
that referenced
this pull request
Sep 9, 2026
The embed player has had **no deploy path since 2026-06-23**. CircleCI shipped it via `embed-deploy-production-cloudflare`; #14504 deleted `.circleci` without porting that job, and nothing in `.github/` has referenced `packages/embed` since. The package README still says "Deployed via CI". Caught because #14571 sat merged for four days with the old bundle still serving on `audius.co/embed`. ## The port Adds an `embed-deploy` job to `web.yml`. Three deliberate differences from the CircleCI original: | | CircleCI | here | |---|---|---| | trigger | `release*` branches | `main` | | gate | none | none (see below) | | deploy cmd | `npm run deploy:prod` | `npx wrangler@4.54.0 deploy`, matching the web deploy | Not behind the `production` gate that web and desktop share. The embed is a self-contained player with no desktop/S3 half to coordinate with, and gating it would mean the deploy that just rotted for two months needs a human every time. Easy to add `needs: [production-gate]` if you'd rather it wait. Also adds `packages/embed/**` to the workflow path filters — without it an embed-only change doesn't trigger this workflow at all, which is why #14571 ran no CI beyond the security scanners. ## Two fixes it depends on - **`wrangler.toml` was wrangler-1.x era.** `type = "webpack"` is silently ignored and `[site] entry-point` is deprecated; both replaced with a top-level `main`. Verified with `--dry-run` on the pinned 3.30.1 *and* 4.54.0 — clean on both, warnings on neither. - **`deploy:prod` called `wrangler publish`**, which no longer exists in wrangler 4. So the manual deploy documented in the README was already broken on any current wrangler. Now `wrangler deploy --env production`. The odd-looking build/deploy split is preserved, not fixed: `build:prod` renames `build/` → `build-production/` and the deploy job renames it back, because `[site] bucket` points at `./build`. That split across repo and CI is why `build:prod && deploy:prod` deploys nothing on its own. Worth collapsing someday; left alone here to keep this a port. ## Verification Ran the job's exact step sequence locally: `npm run build:prod` → `workers-site npm i` → `mv build-production build` → `npx wrangler@4.54.0 deploy --env production --dry-run`. Uploads 57.95 KiB, zero warnings. Confirmed the built bundle contains #14571's strings, so this would ship the fix that's currently stuck. Only thing not verifiable without merging: that `secrets.CLOUDFLARE_API_TOKEN` (already used by the web deploy in this same workflow) has access to the `embed` worker. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
dylanjeffers
added a commit
that referenced
this pull request
Sep 24, 2026
Follow-ups from reviewing #14561, #14562, #14567, #14568, #14569, #14570, #14571 and #14572. **Logic fixes** - **Wallet auth, reconnect race (#14567):** a lazily loaded wagmi config starts out `disconnected`, and only WagmiProvider's re-render kicks off `reconnect()`. If the SDK read the status first, an external-wallet user was cached with an empty Hedgehog client. `getAudiusWalletClient` now starts the reconnect itself. - **Wallet auth, failed chunk load (#14567):** if the AppKit chunk failed to load, `initSdk` threw and left `inProgress` stuck, so every later `audiusSdk()` call hung. It now falls back to Hedgehog, and the memoized import resets so it can be retried. - **Direct AppKit imports (#14567):** importing `ReownAppKitModal` directly (Buy/Sell, sign-in) never marked AppKit as loaded. wagmi hooks kept reading the placeholder config, and sign-out skipped the wallet disconnect. The module now registers itself when it is evaluated. - **Placeholder wagmi config (#14567):** it silently reconnected any injected wallet the site had been authorized for, because injected-wallet discovery was on and there was no storage. Discovery is now off and it has no connectors. - **Duplicate chain definition (#14567):** `audiusChain` was defined twice; there is now one definition. - **Upload seed (#14561):** the upload form re-applied `initialMetadata` (contest genre/remix/artwork, coin-gate conditions) on every reinitialize. Example: switching a coin-gated upload to Public, cancelling the confirm modal and continuing again brought the gate back. The seed is now applied once, when leaving the select step. - **Lazy Lottie playback (#14568):** effects that call `lottieRef.current.play()` ran before the lazy chunk loaded and never re-ran, so the play-bar loading spinner could stay frozen. `LazyLottie` now reports when the ref is ready (callers re-run their effect) and renders a sized placeholder while the chunk loads. - **Unavailable tracks (#14570/#14572):** owners are exempt from the non-streamable redirect, so an artist can reach their own track once the API also flags no-audio tracks (api#1032). The redirect to 404 now replaces history, so Back doesn't loop. - **Empty-feed suggestions (#14562):** mobile web now uses the personalized follow suggestions, and the native empty feed switches its copy when suggestions are personalized. **Comment cleanup:** shortened or removed long history-style comments from these PRs, and dropped the no-`track_cid` claim, since api#1032 isn't merged. **Tests** - `tsc` passes for web, common, harmony, mobile and sdk. - vitest passes: `UploadTrackForm.test.ts`, the new `SelectPage.test.ts` and `trackAvailability.test.ts`, `FanClubDetailPage.test.tsx`, `ProfilePage.test.tsx`. - eslint passes on changed files. - Local dev server: - A signed-out visitor with no persisted wallet doesn't load AppKit. - With a fake persisted `wagmi.store`, AppKit loads, the reconnect runs, and the SDK initializes (falls back to Hedgehog, no hang). - Importing `ReownAppKitModal` directly marks AppKit as loaded. - Not tested with a real external wallet. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <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.
Follow-up to #14570, which gated the web and mobile track pages on
is_streamable. The embed player is its own app and was missed — it still rendered the full card (title, artist, artwork, play button) for a track whose owner deactivated their own account or was delisted by the trusted notifier.AudiusProject/api#1023 already made
/v1/tracks/{id}/stream404, so the player couldn't actually play these. It just showed the metadata and then failed silently on press.Change
Route non-streamable tracks into the existing not-available treatment (the same path a 404 takes), with its own copy rather than reusing the deleted-by-creator string — the same flag covers a self deactivation and a delisted account, and we shouldn't tell listeners the creator removed a track when moderation suppressed it. Wording matches the web tombstone from #14570.
The check is an explicit
=== false, matchingisTrackUnavailablein common: an absent field must not read as unavailable. (The embed depends on@audius/sdkrather than@audius/common, so the helper isn't importable here.)Verification
Ran against prod data using
audius.co/rehoxx/just-for-tonight-wmellark-hoonds(ENxw4), the track from the original report:cardcompacttinyBoth routes covered — hash id (
getTrack) and permalink (getBulkTracks). A streamable trending track still renders normally with artwork and play button.vite build,eslint, andjestall pass.Note
The remaining gap is server-side:
/v1/tracks/{id}still returns a signed content-node URL for these tracks, which AudiusProject/api#1024 fixes.🤖 Generated with Claude Code