Repository navigation
feat(compose): derive reply and repost visibility from the account preference - #37
Merged
Merged
Conversation
…eference Follow-through on the composer change: a repost and an inline reply both create messages, but both still hardcoded `.public`, so an account set to private-by-default had its new messages honour the preference while its replies and reposts silently went public. Both now seed from the same `AppEnvironment.defaultComposeVisibility`: - `RepostSheetViewModel` takes `initialVisibility`, mirroring the composer. The sheet's existing picker still lets the user override it. - `MessageDetailViewModel` takes `defaultVisibility` and `postReply`'s `visibility` argument becomes `Visibility?`, falling back to it when nil. This matters most here: the inline reply composer has no visibility control at all, so the preference is the only thing standing between a private-by-default account and a public reply. An explicit argument still wins, so callers and tests can pin a specific value. The remaining `.public` literals are parameter fallbacks for the signed-out or unresolved-session case, matching `UserSettings.default` — the same fallback `AppEnvironment` applies when `currentUser` is nil. Two more BDD quartets covering seeding, the signed-out fallback, an explicit override, and the empty-body guard. Mutation-checked: restoring either hardcode fails exactly three assertions. Lists are deliberately untouched — `NewListViewModel` defaults to `.private` per the M3 brief, and the preference is scoped to posts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015mnd3dkGEBgakL35cGujBR
This was referenced Sep 9, 2026
Merged
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.
Summary
Follow-through on #34, which shipped the composer half. That PR made a new message honour the account's "New posts are public by default" preference — but a repost and an inline reply both still hardcoded
.public. So ondevtoday, an account set to private-by-default gets private new messages and public replies and reposts.Both are message-creating surfaces, so both now seed from the same
AppEnvironment.defaultComposeVisibilitythat #34 introduced.Changes
RepostSheetViewModeltakesinitialVisibility, mirroring the composer. The sheet's existing picker still lets the user override it.MessageDetailViewModeltakesdefaultVisibility, andpostReply'svisibilityargument becomesVisibility?, falling back to it when nil. This is the one that matters most: the inline reply composer has no visibility control at all, so the preference is the only thing standing between a private-by-default account and a public reply. An explicit argument still wins, so callers and tests can pin a specific value.The remaining
.publicliterals are parameter fallbacks for the signed-out / unresolved-session case — the same fallbackAppEnvironmentapplies whencurrentUseris nil, matchingUserSettings.default.Lists are deliberately untouched:
NewListViewModeldefaults to.privateper the M3 brief, and this preference is scoped to posts.Tests
Two BDD quartets, 8 new tests:
postReply(body:)call the view actually makes posts privately, signed-out falls back to public, an explicit argument overrides, and the empty-body guard still short-circuits before the preference is consulted.Mutation-checked: restoring either hardcode fails exactly three assertions, confirming the tests are not vacuous.
Verification
Branch is cut from current
dev(39fdea1). The cherry-pick conflicted with the message-actions rename inMessageDetailView/ViewModel; both conflicts were parameter-list unions, resolved by keeping botheventBusanddefaultVisibility.xcodebuild ... build→** BUILD SUCCEEDED **xcodebuild ... CODE_SIGNING_ALLOWED=NO test→Executed 752 tests, with 0 failures—** TEST SUCCEEDED **swift test --package-path Packages/InterlinedKit→Executed 398 tests, with 0 failuresswift test --package-path Packages/InterlinedDomain→Executed 772 tests, with 0 failuresswift test --package-path Packages/InterlinedPersistence→Executed 135 tests, with 0 failuresgrep -rn "^import InterlinedKit" App/Features App/Navigation App/MenuCommands→0Note
The manual ⌘W → ⌘N window-state check flagged on #34 still stands, but it does not affect this PR: the repost sheet and message detail view models are built per-presentation, not once per app launch. Only the composer's single-instance
Windowis exposed to that.🤖 Generated with Claude Code
https://claude.ai/code/session_015mnd3dkGEBgakL35cGujBR