Skip to content

feat(profile): Message settings group — visibility, length, page size, advanced options (#32) - #99

Merged
Adron merged 1 commit into
parity/queuefrom
issue/32-settings-message-group
Sep 16, 2026
Merged

Adron merged 1 commit into
parity/queuefrom
issue/32-settings-message-group

Conversation

@Adron

@Adron Adron commented Sep 16, 2026

Copy link
Copy Markdown
Member

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/settings lists Profile settings → "Max message
length: 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/messages is blunter still: "Each user has a configurable message
length limit (default 666 characters). Adjust it in Settings, then Profile (not Message
Settings)."

So:

Group Setting
Profile (new) Message character limit
View preferences (existing, appended) Messages per page
Message settings (new) Default message visibility, Advanced post settings

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 the
entry 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 a
legitimate 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, longitude and notificationTrayLimit as
string, yet types isPrivateAccount as boolean. That inconsistency only makes sense if the
generator inferred from a coercing handler rather than a real contract — and the spec's own 200
example returns maxMessageLength: 666 as a number. The live GET /api/user agrees.

So the spec's string is a generator artifact; the repo's natural-JSON-types choice stands, and the
tests now assert isString == false on the wire body for all four fields.

Verification

./gradlew :app:assembleDebug testDebugUnitTest → BUILD SUCCESSFUL, 821 tests repo-wide, 0
failures
. 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

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant