Skip to content

feat(chat): edit a group's balance requirements from Edit Group - #1720

Merged
bmc08gt merged 6 commits into
code/cashfrom
feat/group-balance-requirement-edit
Oct 29, 2026
Merged

bmc08gt merged 6 commits into
code/cashfrom
feat/group-balance-requirement-edit

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Edit Group now lets a group's creator change its Join and Chat minimums. Saving sends the group's full rule set through EditChat (EditChatParameters.rules), and every member's chat follows a rules change as it arrives.

Depends on #1876 (flipcash2 0.23.0 scaffolding), which adds EditChatRequest.rules and MetadataUpdate.RulesChanged.

Which groups can be edited
EditChatRequest.rules only accepts a public group created with a listener minimum: a private group is DENIED and any other group is INVALID_RULES. The Balance Requirements card is always shown, but its rows only open the keypad for such a group (isBalanceEditable). A rule this build can't decode (UnsupportedSpeakerRule) also makes the rows read-only, since sending the set back would have to drop it.

What gets sent

  • The outgoing set starts from the group's current rules and changes only the edited minimum. Staff, creator and any other rules go back as they are (withMinimum, withoutSpeakerMinimum in shared/chat/GroupRulesEdit.kt).
  • The listener rule keeps its currency and mints. A speaker rule takes the listener rule's mints and is stored in its currency, which isn't necessarily USD. The keypad entry is converted into that currency through USD and rounded to its decimals (minimumBalanceIn). This replaces the USD-only minimumBalanceFor.
  • On success the Metadata from the response is stored, so the screen doesn't wait for the event.

Checked before sending

  • Every amount is at least the currency's minimum transfer value ($0.01, ¥1). Below that, Save stays disabled.
  • An amount equal to the current rule leaves Save disabled.
  • A Chat amount at or below Join plus the minimum transfer value shows "Chat Minimum Too Low". A Join amount that would no longer sit below Chat shows "This Requirement Isn't Valid".
  • When the caller's balances and rates are known, new minimums the creator doesn't meet show "You Don't Meet This Requirement". Only the minimum-balance rules are weighed; the server judges the rest.

Removing the Chat minimum. The Chat keypad has a Remove action in its app bar when the group has its own speaker rule. It sends the set without that rule, so speaking needs only joining. Without a speaker rule, the Edit Group Chat row shows the Join amount, as the profile does.

Server errors. RULES_NOT_SATISFIED shows "You Don't Meet This Requirement". INVALID_RULES shows "This Requirement Isn't Valid" and is reported to Bugsnag, as are other failures ("Couldn't Save the Requirement"). The Unavailable stub, its "Not Available Yet" copy and its test are gone.

The old known gap, where the Chat row treated the Join amount as its current value and saving it created a separate chat rule, is closed: a Chat amount at or below Join is now blocked before sending.

Rules changing live
RulesChanged was already mapped and stored through ChatMetadataDao.updateRules, and the in-chat consumers (subject, bottom bar, gate bars, holding label, profile card) read the stored row, so a member's chat follows it without reopening. A member who falls below a raised Join minimum stays in the group and keeps reading but loses speaking, the same state as when their balance drops.

RulesChanged only reaches members, so this adds ChatCoordinator.refreshRules (a GetChat that stores only the rules) for the places it doesn't:

  • when the viewer is found outside a stored group, as after a leave, so rejoining is judged against current rules;
  • after a join fails with RULES_NOT_SATISFIED;
  • when a non-member opens Group Info.

Tests. EditGroupBalanceRequirementViewModelTest covers each rule above. GroupRulesEditTest covers editability and the rule-set builders. ChatMetadataDaoTest and the mapper tests show rules_json round-trips a speaker rule being added and removed, and that the stored chat re-emits on updateRules. GroupFeedDelegateTest covers refreshRules.

@bmc08gt bmc08gt self-assigned this Oct 7, 2026
@github-actions github-actions Bot added type: feature New functionality area: network gRPC, connectivity, API, exchange rates labels Oct 7, 2026
Edit Group now shows the Balance Requirements card under its rows. The
Join row reads the listener rule and the Chat row reads the speaker rule,
falling back to Join's, as the group profile does. A row the group has no
rule for reads "None". Tapping a row opens the shared amount keypad for
that rule.

The keypad enters in the preferred currency and saves in USD, through the
same conversion group creation uses. That conversion moves to
shared/chat as minimumBalanceFor. The keypad is seeded with the current
rule. A replaced rule keeps its mints; a new rule names none. Save stays
disabled for an empty or zero entry, without a usable rate, or when the
entry matches the current rule to the cent. Saving asks for confirmation
first.

flipcash2-client-protocol 0.18.0 has no RPC that changes a group's rules
after StartChat. GroupOperations.setMinimumBalance therefore fails with
SetGroupMinimumBalanceError.Unavailable for now. The screen shows that as
"Not Available Yet" and does not report it; any other failure is reported.
Swap in the real call inside GroupFeedDelegate.setMinimumBalance.
Send the group's whole rule set back with only the edited minimum changed,
in the listener rule's currency, and refuse locally what the server would:
amounts under the minimum transfer value, a Chat minimum not above Join,
a Join minimum not below Chat, and minimums the creator doesn't meet.
The Chat minimum can be removed. Replaces the Unavailable stub.
Members follow a rules change through RulesChanged into rules_json, and
every in-chat consumer reads that row. A viewer outside the group, as
after a leave, gets no events for it, so the gate before Join could show
an old minimum. ChatViewModel now fetches the rules once each time the
viewer is found outside the group, and again when a join fails with
RULES_NOT_SATISFIED, through ChatCoordinator.refreshRules.

Tests cover rules_json round-tripping a speaker rule added and removed,
and the stored chat row re-emitting on each updateRules.
@bmc08gt
bmc08gt force-pushed the feat/group-balance-requirement-edit branch from 1d9b737 to 7f8b9ce Compare October 29, 2026 14:28
@bmc08gt
bmc08gt merged commit 8ab72d5 into code/cash Oct 29, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: network gRPC, connectivity, API, exchange rates type: feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant