Skip to content

fix(web): confirm before publishing a collection's hidden tracks#14524

Merged
dylanjeffers merged 1 commit into
mainfrom
fix/publish-playlist-hidden-tracks-confirmation
Jul 16, 2026
Merged

fix(web): confirm before publishing a collection's hidden tracks#14524
dylanjeffers merged 1 commit into
mainfrom
fix/publish-playlist-hidden-tracks-confirmation

Conversation

@dylanjeffers

Copy link
Copy Markdown
Contributor

The bug

Making a hidden playlist or album public force-published every hidden child track, silently. The cascade in commonSagas.ts was:

if (track.is_unlisted && (!track.is_scheduled_release || isEarlyRelease)) {
  yield* put(trackPageActions.makeTrackPublic(track.track_id))
}

This drew no distinction between a track the user deliberately hid and one that is simply a scheduled pre-release, and asked for no confirmation. A user publishing a playlist could unintentionally make hidden tracks public — not something they can quietly undo, since publishing notifies followers.

User-facing change

When a user publishes a collection that contains deliberately-hidden tracks (is_unlisted && !is_scheduled_release), they now get a prompt naming how many:

  • Publish Playlist & Tracks — the previous behavior.
  • Keep Tracks Hidden — publishes the collection but leaves those tracks hidden.

The collection itself is published on both paths; the choice only controls the cascade. Dismissing the modal (esc / overlay / X) takes the conservative path, so tracks are never published by an accidental dismiss.

No prompt appears when there is nothing to warn about, so the common case is unchanged.

Scheduled releases are unaffected. They still publish only as an early release — i.e. when the collection is itself a scheduled release and all of its tracks are scheduled. That branch never prompts.

Where the check lives

The gate is in the sagas rather than the UI. Publish is dispatched from four web call sites (the publish button, useCollectionPage, the overflow modal, and the edit form) and today only the publish button opens any confirmation. Putting the check in the saga covers all of them, and both the edit path and the publish path, in one place — no future caller can forget it.

Within the saga the prompt is raised before the write begins. The publish path applies the result inside a confirmer success callback, which serializes writes per collection; blocking there would hold that queue while the modal is up, and would deadlock the collection outright if the modal ever failed to resolve.

Two small sagas are now exported (confirmPublishHiddenTracks, publishHiddenChildTracks) so the branch logic can be tested directly.

Mobile needs a follow-up

Worth flagging, since it's not what you'd expect: mobile has no copy of this logicpackages/mobile/src/store/cache/collections/sagas.ts imports web's commonSagas through the common/* tsconfig alias, so mobile runs this exact code.

What mobile lacks is the drawer. Prompting there would block the publish forever on a modal that never renders, so confirmPublishHiddenTracks returns early on isNativeMobile and keeps the previous publish-everything behavior. The follow-up is to add a PublishHiddenTracksConfirmationDrawer (alongside the existing PublishConfirmationDrawer) and delete that branch — the saga and the modal slice in packages/common are already shared and need no changes.

Testing

12 unit tests in publishHiddenChildTracks.test.ts cover the prompt (count, album/playlist wording, confirm, keep-private, mobile) and the cascade (early release, non-scheduled collections, empty collections).

Two notes for reviewers:

  • The tests drive the generators through a small effect interpreter instead of redux-saga-test-plan. The web vitest setup replaces redux-saga with a stub, and redux-saga-test-plan fails to load under vitest's ESM interop — which is why the package has no saga tests today.
  • I verified they aren't vacuous: reintroducing the original bug in either half (never prompting, or always cascading) fails 3 and 2 tests respectively.

Full web unit suite passes (25 files). tsc --noEmit clean for web and common. The 7 pre-existing failures in common's upload/selectors.test.ts are unrelated and fail on main too.

🤖 Generated with Claude Code

Making a hidden playlist or album public force-published every hidden
child track, with no distinction between a track the user deliberately
hid and a scheduled pre-release, and no confirmation. Hidden tracks
could go public unintentionally.

Publishing now prompts when the collection contains deliberately-hidden
tracks, offering to publish them alongside the collection or to keep
them hidden. The collection is published either way. Scheduled releases
are unaffected: they still publish only as an early release.

The prompt is raised in the collections sagas so it covers every publish
entry point (the publish button, the overflow menus, the collection page
and the edit form) rather than each caller having to remember it. Mobile
shares these sagas but renders no drawer for the prompt yet, so it keeps
the previous behavior until that lands.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 5f8f4da

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@dylanjeffers
dylanjeffers merged commit b37a98f into main Jul 16, 2026
13 checks passed
@dylanjeffers
dylanjeffers deleted the fix/publish-playlist-hidden-tracks-confirmation branch July 16, 2026 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant