Repository navigation
Add group chats (behind a build switch) - #166
Merged
Merged
Conversation
AI assistance: Claude Code.
GroupService keeps one device's groups: key packages, membership requests, Commits applied strictly in epoch order and checked against the group's rules (renames and roles only from administrators, no membership change in a self-update), messages bound to their authenticated sender and id, member colours shared inside the group, and sends that are never resent automatically. Its MLS records and cursors are saved atomically in an encrypted file. Nine tests run two devices through the real Rust core. AI assistance: Claude Code.
…groups. Wires GroupService into the session (only in builds with --dart-define=FIREPLACE_GROUPS=true) and adds the screens: New chat offers Message someone or New group; groups appear in the chat list and search; invitations wait in Message requests with Join and Decline; the group chat shows names, avatars and each member's colour; Group info lists members and administrators with Add people, Rename, Remove and Leave. Owner's choices (2026-11-14), recorded in 0050: any member invites people they already chat with; only administrators remove and rename; a group ends when its last member leaves; only a message's author edits or deletes it for everyone. AI assistance: Claude Code.
The New chat button now opens a full-height panel: Cancel and the title at the top, a To: field, Create group (when groups are on), and the people you already chat with. Typing filters the list; a username that is not in it can be messaged directly. Group start failures are now printed in debug builds. AI assistance: Claude Code.
The caller disposed the dialog's text controller while the dialog was still animating closed, which tripped a framework assertion on the device. The dialog now owns its controller. AI assistance: Claude Code.
The inviter's device sends the Add Commit and the Welcome with the invitation. The invited phone joins from the Welcome it already has; no other phone is needed. A declined or expired invitation is fenced and removed like a leave. Members answer a newcomer's profile with their own, so someone who joins later has everyone's colour. Changes to the group are written into the history as lines, built from the MLS state before and after each Commit. An administrator can make another.
…ead counts. The conversation reuses the 1:1 bubble, held-message menu, reactions, day separators and composer, and edits in the composer instead of a dialog. Other people's bubbles use the soft tint of their own colour, with their name and avatar in its text shade. The list row has the 1:1 layout and an unread count taken from the local history. Lines say who was added, left, was removed, renamed the group or became an administrator, and a newcomer sees where their history starts. Group info lists people who are invited and lets an administrator make another.
…ne lacks. Found on the emulator: Join left the person on Message requests, and a group from before members answered a newcomer kept showing them in Stone.
Hold the row or use Group info. The mute is kept with the 1:1 mutes and never leaves the phone. A muted group keeps its count on the row, in grey, and is left out of the app icon's badge, which now counts group messages too.
The notes and comments named the second set of changes by a working label that means nothing to a reader.
fireplacechat-com
approved these changes
Nov 14, 2026
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.
Why
Fireplace has only 1:1 chats. This adds group chats: end-to-end encrypted with MLS, up to 16 people, with the same look and behaviour as a 1:1 chat. Design and owner decisions: decision 0050.
Groups are off unless the app is built with
--dart-define=FIREPLACE_GROUPS=true, so an ordinary build is unchanged. They also need the matching server rules and functions, which the owner deploys.What you get
These are widget renders with fictional names (how they are made). The reaction bar shows empty boxes because the preview font has no emoji.
How it works, for a reviewer
This changes what is sent and stored (group requests and membership records), so the design note and the protocol note are updated in this pull request with the reasons and the Firestore cost of each operation: 0050, group-chats-v1.
Code:
lib/src/model/groups/(the service and its models),lib/src/view/groups/(screens),lib/src/app/group_providers.dart. Two shared 1:1 widgets gained an optional parameter each so the group conversation can reuse them (MessageBubble: the colour of someone else's message;ChatComposer: no 1:1 send controller needed). The local history has a new kind of entry for the lines about changes; it is never counted as unread or matched by search. No new package.How it was checked
scripts/check.shpasses: 1,485 tests and 19 timing tests. CI is green.test/model/groups/group_service_test.dart), including joining while the inviter's phone is closed, and 13 screen tests (test/view/groups/group_screens_test.dart).docs/reviews/group-chats/.AI assistance
Claude Code wrote this change, directed by the owner, who tried it on the emulator and chose the behaviour. It builds on a design proposal written with GPT (OpenAI Codex). A human must review the rules-facing and cryptographic parts before release.
Privacy and safety
Not included
🤖 Generated with Claude Code