feat(profile): Message settings group — visibility, length, page size, advanced options (#32) - #99
Merged
Conversation
Exposes the four message-behaviour preferences from PATCH /api/user/update on
the Settings screen, each saved as its own partial PATCH, applied optimistically
and rolled back when the server refuses it.
Grouping mirrors the web, which the help centre spells out: the character limit
sits under Profile ("adjust it in Settings, then Profile (not Message
Settings)"), the page size under View preferences, and only the two composer
toggles under Message settings. The Message settings description points at the
other two so either route finds them.
Adds SettingsNumberRow to the settings kit for the numeric preferences: a
digits-only field flanked by stepper buttons that only reports a whole number
inside its range, so an out-of-range or malformed entry never becomes a request.
Bounds live in SettingsBounds — messagesPerPage 10..30 as documented, and a
deliberately wide 10..10000 for the undocumented character limit, with a
rejected save restoring the previous value.
Consumption of these preferences by the composer and feed is deliberately left
to the :feature:messages lane (#24, #19); #18 already reads defaultPubliclyVisible.
Closes #32
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.
Closes #32. Part of epic #31. Builds on the #33 scaffold.
Grouping mirrors the web — verified, not guessed
The issue flagged that the web puts the character limit under Profile, not Message settings.
Confirmed against the live help centre:
/help/settingslists Profile settings → "Max messagelength: Character limit per message (default 666)"; View preferences → "Messages per page: How
many messages to load at once (10 to 30)"; Message settings → "Default message visibility" +
"Advanced post settings".
/help/messagesis blunter still: "Each user has a configurable messagelength limit (default 666 characters). Adjust it in Settings, then Profile (not Message
Settings)."
So:
Discoverable either way — the Message settings group description says "As on the web, the character
limit is under Profile and the page size under View preferences."
The numeric row
SettingsNumberRow: digits-only field flanked by −/+ steppers. It reports a value only when theentry is a whole number inside its range (on IME Done or a stepper tap), so nonsense can never reach
the API; an invalid entry shows an inline bounds message and is discarded on blur. The field is
keyed on the incoming value, so an optimistic value the server later rejects is replaced by the
restored one rather than lingering on screen. The ViewModel re-checks the range as the real backstop
and refuses out-of-range values without a request.
Bounds live in
SettingsBounds:MESSAGES_PER_PAGE = 10..30(documented),MAX_MESSAGE_LENGTH = 10..10_000— deliberately wide, because no cap is documented anywhere and alegitimate value must never be blocked client-side.
Request-side types — the question from #33 is now answered
The generated spec types
maxMessageLength,messagesPerPage,defaultPubliclyVisible,showPreviews,showAdvancedPostSettings,latitude,longitudeandnotificationTrayLimitasstring, yet typesisPrivateAccountasboolean. That inconsistency only makes sense if thegenerator inferred from a coercing handler rather than a real contract — and the spec's own 200
example returns
maxMessageLength: 666as a number. The liveGET /api/useragrees.So the spec's
stringis a generator artifact; the repo's natural-JSON-types choice stands, and thetests now assert
isString == falseon the wire body for all four fields.Verification
./gradlew :app:assembleDebug testDebugUnitTest→ BUILD SUCCESSFUL, 821 tests repo-wide, 0failures. Coverage: each of the four fields PATCHes alone (asserted at repository level on the
actual JSON key set and primitive type, and at ViewModel level through the real mapper);
optimistic apply + rollback for both switch and numeric rows; out-of-bounds refused with zero
requests; a server rejection restoring the previous value with the server's own wording surfaced.
10 Compose tests compile but were not executed (no emulator).
Reviewer notes
mentions it, but that is the
:feature:messageslane — Composer: honour the account's character limit and the tightest cross-post limit #24 (character limit) and Feed: view preferences (All / My / Following / Followers) andonlyMine#19 (feedpreferences); Composer: public/private visibility toggle (
publiclyVisible) #18 already consumesdefaultPubliclyVisible. No file outside:feature:profilewas touched.
SettingsScreennow takes 9 callbacks and will reach ~13 as Settings: private account toggle (isPrivateAccount) #34–Settings: profile location (latitude/longitude) with runtime permission #37 land. Worth folding into asingle
SettingsActionsholder once those merge — doing it now would conflict with every siblingbranch.
MAX_MESSAGE_LENGTH = 10..10_000is a judgement call, not a contract. If the server's real capsurfaces, tighten it so users get inline validation instead of a round-trip rejection.
theme) #36 (theme) will likely want the same Profile group — expect a small merge conflict there.