Skip to content

feat(repo)!: v10.0.0#2499

Open
xsahil03x wants to merge 140 commits into
masterfrom
v10.0.0
Open

feat(repo)!: v10.0.0#2499
xsahil03x wants to merge 140 commits into
masterfrom
v10.0.0

Conversation

@xsahil03x
Copy link
Copy Markdown
Member

@xsahil03x xsahil03x commented Feb 2, 2026

v10.0.0 — Design Refresh & API Modernization

This is the v10.0.0 major release for Stream Chat Flutter. It introduces a refreshed UI, redesigned customization APIs, new chat features (location sharing, delete-for-me, slow mode UI), and aligns naming with the Android and iOS SDKs.

📖 Full migration guide — start here if you're upgrading from v9.x or any v10 beta.


Headline changes

🎨 SDK redesign (#2503)

A full visual refresh across the entire UI package, synced with the Figma design system. New default theme, updated channel/message/composer/poll/media surfaces, simplified icon set (#2619).

💬 New chat features

🧱 Breaking API redesigns

🛠 Other notable changes

🐞 Notable fixes


Scope

  • 1,243 files changed, +95,965 / −73,263 lines
  • 135 commits since master (12 beta releases: 10.0.0-beta.1 through 10.0.0-beta.13)
  • Latest master merged in via chore(repo): merge master into v10.0.0 #2682 and the merge commit at the tip of this branch

Test plan

  • melos run test:all passes (Dart + Flutter, CI goldens)
  • melos run lint:all passes (analyze + format)
  • melos run generate:all produces no diff
  • Sample app runs against a live channel: send/edit/delete messages, react, share location, create poll, change channel info
  • Migration guide validated end-to-end against a v9.x upgrade in a scratch project
  • Existing beta consumers verified against v10.0.0-beta.1310.0.0

🤖 Generated with Claude Code

xsahil03x and others added 30 commits May 26, 2025 16:59
Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com>
Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com>
Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com>
# Conflicts:
#	packages/stream_chat_flutter/CHANGELOG.md
Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com>
# Conflicts:
#	packages/stream_chat_flutter/CHANGELOG.md
# Conflicts:
#	packages/stream_chat_flutter/CHANGELOG.md
#	packages/stream_chat_flutter_core/CHANGELOG.md
# Conflicts:
#	melos.yaml
#	packages/stream_chat/CHANGELOG.md
#	packages/stream_chat/example/pubspec.yaml
#	packages/stream_chat/lib/version.dart
#	packages/stream_chat/pubspec.yaml
#	packages/stream_chat_flutter/example/pubspec.yaml
#	packages/stream_chat_flutter/pubspec.yaml
#	packages/stream_chat_flutter_core/example/pubspec.yaml
#	packages/stream_chat_flutter_core/pubspec.yaml
#	packages/stream_chat_localizations/CHANGELOG.md
#	packages/stream_chat_localizations/example/pubspec.yaml
#	packages/stream_chat_localizations/pubspec.yaml
#	packages/stream_chat_persistence/CHANGELOG.md
#	packages/stream_chat_persistence/example/pubspec.yaml
#	packages/stream_chat_persistence/pubspec.yaml
#	sample_app/pubspec.yaml
# Conflicts:
#	packages/stream_chat/CHANGELOG.md
#	packages/stream_chat_flutter_core/CHANGELOG.md
# Conflicts:
#	melos.yaml
#	packages/stream_chat/CHANGELOG.md
#	packages/stream_chat/example/pubspec.yaml
#	packages/stream_chat/lib/version.dart
#	packages/stream_chat/pubspec.yaml
#	packages/stream_chat_flutter/CHANGELOG.md
#	packages/stream_chat_flutter/example/pubspec.yaml
#	packages/stream_chat_flutter/pubspec.yaml
#	packages/stream_chat_flutter_core/example/pubspec.yaml
#	packages/stream_chat_flutter_core/pubspec.yaml
#	packages/stream_chat_localizations/CHANGELOG.md
#	packages/stream_chat_localizations/example/pubspec.yaml
#	packages/stream_chat_localizations/pubspec.yaml
#	packages/stream_chat_persistence/CHANGELOG.md
#	packages/stream_chat_persistence/example/pubspec.yaml
#	packages/stream_chat_persistence/pubspec.yaml
#	sample_app/pubspec.yaml
Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com>
# Conflicts:
#	packages/stream_chat/CHANGELOG.md
#	packages/stream_chat_flutter_core/CHANGELOG.md
# Conflicts:
#	packages/stream_chat_flutter/CHANGELOG.md
#	packages/stream_chat_flutter/lib/src/message_input/stream_message_input.dart
#	packages/stream_chat_persistence/CHANGELOG.md
The animation curves and durations for the reaction picker and message modal have been updated for a smoother user experience.

- The `reaction_picker_icon_list.dart` animation curve is now `Curves.easeOutBack` and the duration is 335 milliseconds.
- The `message_modal.dart` transition duration is now 335 milliseconds, and the scale animation curve is `Curves.easeOutBack`.
# Conflicts:
#	packages/stream_chat_persistence/CHANGELOG.md
#	packages/stream_chat_persistence/lib/src/db/drift_chat_database.dart
xsahil03x and others added 8 commits April 29, 2026 06:46
* Fix docs background color

* update screenshots

* chore: Update Goldens

---------

Co-authored-by: renefloor <15101411+renefloor@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com>
… sdks (#2643)

Renames the message widget and its sub-components to match the naming
conventions used by stream-chat-android (Compose) and stream-chat-swiftui.

Symbol renames:
- StreamMessageWidget → StreamMessageItem (+ .fromProps)
- DefaultStreamMessage → DefaultStreamMessageItem
- StreamMessageWidgetProps → StreamMessageItemProps
- StreamMessageWidgetBuilder typedef → StreamMessageItemBuilder
- StreamMessageAnnotations → StreamMessageHeader
- StreamMessageMetadata → StreamMessageFooter
- ParseAttachments → StreamMessageAttachments
- GiphyEphemeralMessage → StreamGiphyEphemeralMessage
- streamChatComponentBuilders(messageWidget:) → messageItem:
- StreamMessageContent(annotation:, metadata:) → header:, footer:

File renames (lib/src/message_widget/):
- message_widget.dart → stream_message_item.dart
- parse_attachments.dart → stream_message_attachments.dart
- ephemeral_message.dart → stream_ephemeral_message.dart
- giphy_ephemeral_message.dart → stream_giphy_ephemeral_message.dart
- moderated_message.dart → stream_moderated_message.dart
- system_message.dart → stream_system_message.dart
- components/stream_message_annotations.dart → stream_message_header.dart
- components/stream_message_metadata.dart → stream_message_footer.dart

Updates CHANGELOG, v10 migration guide, redesign migration docs, README,
inline doc comments, the example tutorial, and the sample app.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Move draftlist from sdk to sample app.

* remove unused imports

* removed theme class

* chore(ui, sample): export scroll-view load-more widgets and tidy draft list

Export StreamScrollViewLoadMoreError and StreamScrollViewLoadMoreIndicator
from the public API (their EmptyWidget/ErrorWidget/LoadingWidget siblings
were already exported). The sample app's draft list view now uses the
public API for these widgets and the rest of its empty/error/loading
builders, and drops the boilerplate SDK-style customization hooks it
didn't need.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(ui, sample): export StreamTimestamp and use it in draft tile

Export StreamTimestamp along with its DateFormatter typedef and the
formatDate / formatRecentDateTime helpers from the public API, then use
StreamTimestamp in the sample app's StreamDraftListTile instead of a
hand-rolled Jiffy formatter. The default formatter also adds a
"Yesterday" case the inline version was missing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Sahil Kumar <sahil@getstream.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* rename message composer

* Move factory for composer

* fix picker sync

* Add separate composer input for factory

* formatting

* remove unused prop

* Fix isFloating bool

* format exports

* Fix review issues

* chore: Update Goldens

* fix unit tests

* re-enable skipped tests

* don't run pub get parallel

* Move composer parts to chat

* fix composer migration docs

* fix async context issue

* improve composer props

* close attachment picker with locked recording

* update core dependency

---------

Co-authored-by: renefloor <15101411+renefloor@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{}

renefloor and others added 15 commits May 15, 2026 11:01
* rename input controller to composer controller

* Fix controller lifecycle management

* fix restoration edit mode
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…_picker 11 (#2644)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
resolves #2599
* theme cleanup

* removed brightness

* unused files cleanup

* removed brightness and unused widgets

* removed theme wrapper

* dart format

* analyse fix

* fix

* chore: Update Goldens

* fix

* dark theme tests fix

* chore: Update Goldens

* more brightness tests fixes

* chore: Update Goldens

---------

Co-authored-by: Brazol <5622717+Brazol@users.noreply.github.com>
* Improve slow mode UI

* disabled color for border of composer input

* Remove nested builders

* remove default value

* use constant keys

* formatting

* Added slow mode snapshot tests

* chore: Update Goldens

* cleanup test import

* only add callback when onAttachmentButtonPressed is not null

* simplify side padding

---------

Co-authored-by: renefloor <15101411+renefloor@users.noreply.github.com>
* attachment filesize requirement

* Update packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_controller.dart

Co-authored-by: Rene Floor <rene.floor@getstream.io>

---------

Co-authored-by: Rene Floor <rene.floor@getstream.io>
* docs(ui): pin platform and align emoji baseline in docs snapshots

Doc snapshots previously rendered differently depending on the host running
the tests (macOS dev machines vs Linux CI) because three platform reads were
unpinned: `CurrentPlatform.type`, `defaultTargetPlatform`, and
`Theme.of(context).platform`. Code paths conditional on any of these would
flip — most visibly the mic button visibility in `StreamMessageComposer`.

Introduce `docsGoldenTest`, a wrapper around alchemist's `goldenTest` that
pins all three platform reads to iOS:

- `CurrentPlatform.debugCurrentPlatformOverride` and
  `debugDefaultTargetPlatformOverride` are set inside the alchemist
  `pumpWidget` hook (i.e. inside the test body) and reset via
  `whilePerforming`'s cleanup callback — the latest hook before
  `_verifyInvariants` enforces that foundation debug vars are null.
- `Theme.of(context).platform` is pinned via `ThemeData.platform` on
  `docsScreenshotsTheme()`.

Also adopt the `GoldenComponentFactory` from #2649, wired automatically
into every snapshot through the same `pumpWidget` hook so no per-test
plumbing is needed. It overrides the `emoji` component builder to add an
8 px top padding, nudging emoji glyphs to align with surrounding text.

Goldens regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): fall back to platform emoji fonts for inline glyphs

Roboto carries no emoji glyphs, so any inline emoji in plain Text widgets
(message bodies, etc.) would render as tofu. Add the emoji font families
loaded by `_loadEmojiFont` to the textTheme's fallback chain so Flutter
finds the glyph automatically.

Defensive change — no current snapshot has inline emoji in plain text;
goldens unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): render docs snapshots with real San Francisco on macOS

Pinning the platform to iOS makes Material's iOS typography request the
`CupertinoSystemDisplay` and `CupertinoSystemText` family aliases. On a
real device the platform resolves those to SF Pro automatically; the
Flutter test renderer has no such mapping, so until now we worked around
it by overriding everything to Roboto.

Register `/System/Library/Fonts/SFNS.ttf` under both alias family names
via `FontLoader` in `_loadAppleSystemFont`. With that in place we can
drop the `fontFamily: 'Roboto'` override on `ThemeData` and switch Stream's
`StreamTextTheme` to `CupertinoSystemText` — Material widgets, message
text, and headings all now render in authentic SF on macOS.

The loader is a no-op outside macOS. Linux CI doesn't have SFNS.ttf, but
its goldens use `obscureText: true` so every glyph is replaced with an
Ahem block regardless — no behavioral change there.

Goldens regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): group host-font loaders behind a single entry point

`_loadEmojiFont` and `_loadAppleSystemFont` both register absolute-path
host system fonts that aren't in any asset manifest. Wrap them in a
single `_loadHostSystemFonts()` so `testExecutable` reads as two awaits
(asset-manifest fonts, then host fonts) instead of three.

Pure refactor — no behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ci(goldens): split update_goldens into SDK/docs targets with platform-aware runners

The single Linux job previously regenerated `goldens/ci/*.png` for every
alchemist-dependent package — which is what the SDK packages commit, but
not what `docs_screenshots` commits. Docs snapshots commit
`goldens/macos/*.png` (real-text variant rendered with SF on macOS); the
Linux runner can never produce them.

Split the workflow by adding a `workflow_dispatch.inputs.target` choice
(`sdk` | `docs`) that routes to one of two jobs:

- `update_sdk_goldens` on ubuntu-latest — runs the new
  `update:goldens:sdk` melos script, which skips `docs_*` packages.
  Auto-commits `packages/**/goldens/**/*.png`.
- `update_docs_goldens` on macos-latest — runs `update:goldens:docs`,
  scoped to `docs_*` and exporting `UPDATE_PLATFORM_GOLDENS=1`.
  Auto-commits `docs/**/goldens/macos/*.png`.

`UPDATE_PLATFORM_GOLDENS` is a carve-out in
`docs/docs_screenshots/test/flutter_test_config.dart`: by default the CI
variant gate (`isRunningInCi → CiGoldens only`) skips the platform
snapshots, which is correct for any other runner; setting the env var
flips PlatformGoldens back on so the macOS job actually regenerates the
files it's there for.

The macOS job stays manual-dispatch only and is opt-in via the choice
input — macOS runner minutes cost ~10x Linux on GitHub Actions, so
defaulting to `sdk` keeps routine regenerations cheap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ci(goldens): docs_screenshots emits only the platform variant

`.gitignore` for docs_screenshots commits only `goldens/macos/*.png` —
the CI/obscured variant exists transiently on disk but is never inspected
and never compared against anything in the repo. Generating it wastes
test time and obscures intent.

Simplify `docs/docs_screenshots/test/flutter_test_config.dart` to enable
only `PlatformGoldensConfig` regardless of the host. The
`UPDATE_PLATFORM_GOLDENS` env-var carve-out is no longer needed (the gate
it flipped is gone), so drop it from `update:goldens:docs` in melos.yaml.

Side effect: with PlatformGoldens always on, running docs_screenshots
tests on a Linux runner would compare against a nonexistent `goldens/linux/`
set and fail. Add `--ignore="docs_*"` to the `test:flutter` melos script
so the regular Linux CI pipeline skips them entirely — docs goldens are
regenerated and verified through the dedicated macOS `update_docs_goldens`
job instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: Update Docs Snapshots

* docs(ui): drop redundant theme-level emoji fontFamilyFallback

`DefaultStreamEmoji` carries its own `fontFamilyFallback` chain pointing
at the platform emoji fonts, and that's the path every emoji in the
current snapshot set takes. No test renders an inline emoji glyph
through a plain Text widget, so the theme-level fallback was defending a
case that doesn't exist.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): try multiple SF font paths in _loadAppleSystemFont

Mirrors the candidate-list pattern in `_loadEmojiFont`: walk a list of
absolute font paths and bail at the first one that exists. Catches
pre-Catalina macOS where the system font ships as `SFNSDisplay.ttf`
instead of the modern `SFNS.ttf`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): render user and channel avatars from design-system fixtures

Stream's `StreamAvatar` / `StreamNetworkImage` / `CachedNetworkImage`
chain doesn't fetch real network bytes in tests — and even if it tried,
`flutter_test`'s HttpClient short-circuits every request. Up until now
every `User(image: 'https://…')` rendered as the gradient-letter
placeholder, which makes the docs look like nothing's loading.

Intercept the chain at the `StreamComponentFactory.networkImage` hook:
`GoldenComponentFactory` now installs a builder that returns an
`Image.memory` backed by one of 18 portrait fixtures sourced directly
from Stream's Chat SDK Design System Figma (node 2867:55922, "User
Photo"). Files live in `test/fixtures/avatars/` and are named to match
the Figma component names (e.g. `amelia-moore.png`); add or replace one
by dropping a PNG there and listing its slug in `_avatarSlugs`.

URLs hash deterministically into the list, so the same
`User(image: 'https://docs.fixture/avatar/bob.png')` always resolves to
the same person across snapshots.

To make this actually fire across the suite:

- `setupMockChannel` stubs `channel.image` and the default member User's
  image to synthetic `https://docs.fixture/avatar/{id}.png` URLs. Every
  channel previously had `channel.image: null`, so the channel-avatar
  branch never even reached `StreamNetworkImage`.
- Sweep across `User(id: '…')` constructions in test files — same
  `image:` URL pattern derived from the id — so user avatars in poll,
  thread, message, and search snapshots route through the same fixture.
- `docsGoldenTest` default `pumpBeforeTest` is now alchemist's
  `precacheImages` (was `onlyPumpAndSettle`). Without that pump,
  `MemoryImage` decode races the frame and the avatar circle shows the
  default background color instead of the actual bytes.

Goldens regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): use design-system sample users and member-derived channel avatars

Two related cleanups, both about making the snapshots reflect a real
chat in a real product.

**Sample users in one file.** Inline `User(id: 'user-2', name: 'Bob', …)`
constructions were scattered across nine test files with arbitrary IDs
that didn't match anything in the design system. Move all of them into
`test/src/sample_users.dart` as named constants (`ameliaMoore`,
`noahSmith`, …) corresponding to the 18 named users in Figma node
2867:55922. Tests now reference users by name; adding or replacing a
sample user is one constant + one fixture PNG.

**Channel avatars derive from members.** `setupMockChannel` previously
stubbed `channel.image` to a synthetic URL, so every channel snapshot
took the `channel.image` branch in `StreamChannelAvatar` and rendered a
single circle. Real chats almost never set `channel.image` on group
channels — the avatar is derived from the member set. Stub
`channel.image` back to `null`, default the member list to three sample
users so the channel-list snapshot shows the stacked group avatar from
`StreamUserAvatarGroup`. Distinct DM channels with two members render
the other member's avatar, matching production behavior.

Also along the way:

- `golden_network_image.dart` now resolves URLs by slug (extracted from
  the last path segment), with a hash-based fallback for dynamic URLs
  like `user-$messageId` that don't match a known slug. `User(image:
  'https://docs.fixture/avatar/amelia-moore.png')` now deterministically
  renders Amelia regardless of how the URL hashes.
- `asOwnUser(user)` helper on `sample_users.dart` for `currentUser`
  stubs.
- `user_list_view` snapshot iterates the full 18-user roster with a
  seeded `Random(42)` toggling online indicators — varied without being
  flaky.

Goldens regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): vary default channel member count per channel id

Default channels all picked the same 3 members (Amelia, Charlotte,
Elena), so every channel-list row rendered the same stacked group
avatar. Switch the `setupMockChannel` fallback to a per-channel
deterministic pick: seed a `Random` off the channel id, choose between
2 and 6 sample users, shuffle them in. Each channel now gets a unique
group avatar (Engineering happens to land on 6 → triggers the "+4"
overflow chip from `StreamUserAvatarGroup`, exactly like a real busy
channel would).

Determinism comes from a stable djb2-ish content hash, not Dart's
process-randomized `String.hashCode` — so the same channel id always
picks the same member set across runs.

Goldens regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): trim user_list_view back to 500h

The full 18-user roster overflows naturally — keeping the snapshot at
the prior 500 px height keeps it consistent with the surrounding
fixtures (channel previews, message lists) and avoids a one-off tall
golden in the docs grid.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): use sample users in message search results

`_makeSearchResult` previously built inline `User(id: 'user-$messageId',
…)` so the URL slug couldn't match any fixture and the avatar resolved
through the hash fallback — names ("Alice", "Bob", "Carol", "Dave")
ended up paired with arbitrary portraits. Pass a `User` directly so the
slug aligns with the photo, and use design-system constants (Amelia,
Noah, Charlotte, Liam) so the names match the rest of the docs.

Side benefit: the first row now reads "You in General" because
`ameliaMoore` is the current user — accurate to how
`StreamMessageSearchListView` renders the current user's own messages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): centralize the signed-in identity as `ownUser`

A single [OwnUser] constant in `sample_users.dart` replaces the
per-file `final _currentUser = ameliaMoore;` / `final _user1 = …;`
aliases and the ad-hoc `asOwnUser(ameliaMoore)` calls scattered across
tests. Because `OwnUser` is-a `User`, the same constant drops into both
`currentUser` stubs and any place a `User` is expected (message authors,
member lists, etc.) — so "who is signed in" is decided in exactly one
place across every doc snapshot.

`asOwnUser` is kept for the rare case where a test needs to promote a
different sample user (e.g. variant tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): scope user_list_view back to 5 users

Match the original snapshot's row count so the diff against the prior
golden stays compact — the design-system roster is still demonstrated
elsewhere via avatars rendering with the new fixture set.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): align appbars, bottom nav, and slidable actions with the sample app

The chat-list, thread-list, and swipe-action snapshots were dressed in
generic Material chrome — `AppBar('Stream Chat')`, a fictional
`Chats / Mentions / Threads` bottom nav, a red "Delete" swipe-action.
Real Stream apps look nothing like that, so the docs misrepresented the
product.

Rework the chrome to match `sample_app`:

- **Channel list & slidable channel list** (`channel_preview_test.dart`)
  swap the generic `AppBar` for `StreamChannelListHeader(title:
  Text('Chats'))`. The leading slot resolves to the signed-in user's
  avatar (Amelia) via the existing `currentUser` stub.
- **Swipe channel reveal** (same file) shows
  `streamIcons.more` (surface bg) + `streamIcons.mute` (accent bg) — the
  exact actions `sample_app/lib/widgets/channel_list.dart` ships.
- **Thread list** (`thread_list_view_test.dart`) uses
  `StreamChannelListHeader(title: Text('Threads'))` and a four-tab
  bottom nav: `Chats` (`streamIcons.messageBubble` / `messageBubbleFill`),
  `Threads` (`streamIcons.thread` / `threadFill`, active),
  `Drafts` (`Icons.drafts_outlined` / `drafts_rounded`), and
  `Reminders` (`Icons.bookmark_outline_rounded` / `bookmark_rounded`).
  The Material icons mirror the sample's actual choices — Stream
  doesn't ship a Drafts or Reminders icon.
- **Poll creator AppBar** (`poll_test.dart`) replaces `Icons.close` and
  `Icons.send` with `streamIcons.xmark` and `streamIcons.send` —
  thinner, design-system shapes.

Goldens regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): use StreamAppBar/StreamButton + wire the trailing slot on list headers

Two follow-ups now that we're using the SDK's header components:

- **Poll creator** swaps Material `AppBar` + `IconButton` for `StreamAppBar`
  + `StreamButton.icon`, the toolbar + button primitives the SDK ships
  for modal/dialog chrome. Circular icon buttons, hairline bottom
  divider, design-system padding — same shape any production app gets
  for free when using these widgets.
- **Channel list, slidable channel list, and thread list** add a trailing
  `StreamButton.icon(icon: Icon(icons.plus))` to `StreamChannelListHeader`.
  The docstring for `StreamChannelListHeader` calls this out as the
  canonical "new chat" affordance, and rendering it makes the header's
  three-slot shape (avatar leading / title / action trailing)
  immediately visible to readers.

Also revert `user_list_view_test.dart` to the explicit five-User array
style — keeps the original visual layout and drops the dart:math import.

Goldens regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): StreamSheetHeader for poll creator + trailing slot on header demos

Two follow-on tweaks to make the header demos cover the full SDK API:

- Poll creator now uses `StreamSheetHeader` (the SDK's modal/dialog
  toolbar) instead of `StreamAppBar`. Visually similar but semantically
  matches what a sheet-launched poll creator actually renders in
  production. Skipped `automaticallyImplyLeading: true` because our
  test scaffold has no popable route — kept the explicit leading
  button.
- `channel_list_header_test.dart` now wires `trailing: StreamButton.icon(
  icon: Icon(context.streamIcons.plus))` on both snapshots. Combined
  with the existing leading (avatar) and `subtitle: Text('12 channels')`,
  the "custom subtitle" snapshot now demos every slot of
  `StreamChannelListHeader` in a single golden.

Goldens regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): authenticate message actions modal + trim bottom nav to chat/threads

Two corrections that bring the docs closer to the production SDK:

- **Message widget actions** stopped reinventing the action list. The
  snapshot used to render Material `Icons.*` against hand-rolled
  placeholder action types — visually plausible but missing the SDK's
  canonical "Mark as Unread" and "Flag Message" entries, and unaware
  of channel capabilities. Switch to
  `StreamMessageActionsBuilder.buildActions(context: ..., message: ...,
  channel: ..., currentUser: ...)` so the modal renders exactly what a
  user sees on long-press: Stream icons, translated labels, capability-
  aware visibility. Channel mock gets the full capability set
  (`sendReply`, `pinMessage`, `quoteMessage`, `readEvents`,
  `update*Message`, `delete*Message`) so every default action surfaces.
- **Thread list bottom nav** trims `Chats / Threads / Drafts / Reminders`
  to just `Chats / Threads` (matches what `sample_app` actually shows
  by default; Drafts and Reminders are config-gated additions there).
  Theming wraps the `BottomNavigationBar` in a `DecoratedBox` with
  `backgroundElevation1` + `borderSubtle` top divider, sets `elevation:
  0`, `iconSize: 20`, `textPrimary`/`textTertiary` item colors, and
  `metadataEmphasis` label styles — copied verbatim from
  `sample_app/lib/pages/channel_list_page.dart`.

Goldens regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): partition destructive actions, match SDK button styling, vary thread authorship

Four corrections to the SDK alignment:

- Message actions modal wraps the builder output in
  `StreamContextMenuAction.partitioned(...)` so the destructive **Delete
  Message** lands at the end with a separator above it — the canonical
  grouping the SDK exposes for that purpose.
- Poll creator's `StreamSheetHeader` buttons now use
  `StreamButton.icon(type: .outline, style: .secondary)` for the
  leading dismiss button (matching the SDK's auto-implied leading on
  sheet routes) and `type: .solid` for the trailing confirm — the
  pattern `sample_app/lib/widgets/add_members_sheet.dart` uses.
- `_makeThread` now takes a `parentAuthor` so the thread list renders
  mixed authorship — one thread started by the current user (rendered as
  "You: …"), the others by Charlotte and Noah. Previously every thread
  was authored by `ownUser`, which made the list look like a single-user
  digest.
- Thread list empty state drops the hand-rolled `Center(Column(...))`
  and lets `StreamThreadListView` render its default
  `StreamScrollViewEmptyWidget` (messageBubblesLarge icon + translated
  "Reply to a message to start a thread") — same widget production
  users see.

Goldens regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): bump message_widget_actions constraint to fit the full action list

`partitioned` adds Flag and Mute on top of Reply/Thread/Mark/Copy/Edit/
Pin/Delete, so the previous 500 px constraint clipped the modal. 700 px
fits the full list with breathing room.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): fix avatar leading on slidable list header + trim actions modal height

Two cleanups:

- `slidable_channel_list` was stubbing `currentUser` *before* the
  `fakeChannel` calls, so each `setupMockChannel` invocation
  overwrote `client.state` with its own `MockClientState()` (whose
  default `currentUser` is `OwnUser(id: 'user-id')`, the "U"
  placeholder). Move the stub after the channels are created so it
  wins, matching the order `channel_list_view` already uses. The
  header now renders Amelia's avatar properly.
- `message_widget_actions` was at 700 px after adding the full action
  list — visibly too tall. Trim to 620 px so the modal fits with
  comfortable margin and no dead space below.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): drop ci/ goldens from version control, fix gitignore pattern

The previous `.gitignore` pattern `!**/goldens/macos/*` only un-ignored
macos files relative to a (missing) preceding ignore rule, so the `ci/`
subdirectory was being tracked alongside `macos/`. With
`flutter_test_config` already disabling `CiGoldensConfig.enabled`, the
`ci/` files were stale leftovers from before that change — committing
them was pure noise.

Switch the ignore to `**/test/**/goldens/**` (recursively ignore
everything under any goldens dir) with `!**/test/**/goldens/macos/**`
re-allowing the macos subtree. Delete the orphan `ci/` PNGs so the
docs only ship the platform variant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): stub channel.memberCount so group headers show member counts

`StreamChannelInfo` (the default subtitle for `StreamChannelHeader`)
branches on `channel.memberCount`: > 2 → "N members, M online", else
the DM-style "Last online …". Our mock left `memberCount` un-stubbed,
so it resolved to null and every snapshot fell into the DM branch —
yielding a misleading "Last online a few seconds ago" for channels
that visibly have 3+ avatars stacked.

Stub `memberCount` (and `memberCountStream`) from the configured member
list in `setupMockChannel`. Group-channel snapshots now read "3 Members"
(or whatever the per-channel deterministic count is), matching what
users actually see.

`channel_list_header` snapshots were already correct — they use the
connection-state default title with no subtitle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): render slidable channel snapshots via real Slidable + drag gesture

The slidable snapshots were hand-rolled — Row+Stack+Transform.translate
faking a swiped state with hardcoded action icons. Replace with the
actual `flutter_slidable` setup the sample app uses
(`sample_app/lib/widgets/channel_list.dart`):
`Slidable` with `endActionPane: ActionPane(extentRatio: 0.4, motion:
BehindMotion(), children: [more, mute])`. For the multi-channel test
the wrap goes through `StreamChannelListView.itemBuilder` so every row
gets the same slidable.

`whilePerforming: (tester) async { await tester.drag(...); await
tester.pumpAndSettle(); }` actually performs the gesture before the
snapshot. The result is a real animated reveal instead of a fake
translation, which catches any drift in Slidable's API or our usage.

Adds `flutter_slidable: ^4.0.0` to docs_screenshots dev_dependencies.
Drops the now-unused mocktail import in this file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: Update Docs Snapshots

* docs(ui): use checkmark icon for poll creator trailing, matching the SDK

`StreamPollCreatorSheet` (the production widget) wires its trailing
`StreamButton.icon` to `context.streamIcons.checkmark`, not `send`. Our
snapshot was showing a paper-plane icon which doesn't appear anywhere
in the real poll creation flow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: Update Docs Snapshots

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com>
* Set appversion to main sdk version

* formatting
* Simplify mesagelist constructor

* rename listview config and builders

* use themeGen on messagelistview theme

* Fixed leftover doc issues

* improve switch and if statements
)

* docs(ui): more docs screenshots

Adds four new snapshot scenarios:

- `flutter_showcase` — hero image with four phone crops on a split
  blue/black background. Two unique screens (message list + channel list),
  each rendered light and dark, with a Flutter logo card centred.
- `localization_support` — two iPhone 13 frames side by side rendering
  the same modal in English and Italian, with a floating
  `StreamMessageComposer` whose placeholder pulls from
  `context.translations.writeAMessageLabel`.
- `theming_default` / `theming_red` — same chat scaffold rendered against
  the docs default theme and a red brand/chrome variant to demonstrate
  `StreamColorScheme` overrides.
- `message_input_custom_buttons` — composer snapshot demonstrating
  `messageComposerLeading` / `*InputLeading` / `*InputTrailing` /
  `*Trailing` builder overrides. The trailing button is a
  `StatefulWidget` that toggles between voice and send icons based on
  text emptiness.

Also adds `docsScreenshotsDarkTheme()` (mirrors the light theme but with
dark brightness, black scaffold/appBar, and `StreamColorScheme.dark()`
text colours) and `stream_chat_localizations` to `dev_dependencies`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: Update Docs Snapshots

* docs(ui): add deviceFrame param to docsGoldenTest, drop flutter_showcase

`docsGoldenTest` gains a `DeviceInfo? deviceFrame` parameter. When set,
the helper wraps the builder's widget in `DeviceFrame(device: …,
isFrameVisible: true, screen: …)` so individual tests no longer need to
construct the wrap themselves. The parameter is opt-in — leaving it
null keeps the previous no-frame behavior for tests like
`localization_support` that manage multiple frames in a single canvas.

Migrate the in-PR theming snapshots and three existing v10.0.0 sites
that used the inline `DeviceFrame(screen: …)` wrap:

- `theming_default` / `theming_red`
- `channel_list_view`, `slidable_channel_list`
- `message_list_view`

Each drops the `DeviceFrame(...)` wrapper around `MaterialApp(...)` and
adds `deviceFrame: Devices.ios.iPhone13` to the `docsGoldenTest` call.

Drop the `flutter_showcase` snapshot — no longer needed.

Also fix `message_styles`: the body text said "This is a message from
Bob." but the author (`_sender`) is now Noah Smith after the
sample-user roster swap. Switch to an interpolation
(`'… from ${_sender.name}.'`) so the copy can't drift again the next
time a sample user is reassigned. Audited the rest of the suite — no
other hardcoded user-name references in message bodies.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): match SDK trailing button size in custom composer snapshot

`DefaultStreamMessageComposerInputTrailing` (the production widget that
renders the send / mic button) ships at `StreamButtonSize.small` (32 px).
Our `_CustomComposerTrailingButton` used `medium` (40 px) for both the
voice and send branches, so the blue circle dwarfed the input pill.
Drop both branches to `small` to match the production button's footprint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): start-align hint in custom composer snapshot

The `message_input_custom_buttons` demo had buttons in both the
`messageComposerInputLeading` (emoji) and `messageComposerInputTrailing`
(attachment) slots. With buttons on both sides of the pill's `TextField`,
the short "Type a message…" hint visually appeared centered between
them, even though it was technically start-aligned within the field.

Remove the inside trailing attachment button so the pill is just
`[emoji | text]` — the hint now sits right after the emoji.

Also bump the outer trailing mic/send button from default `medium`
(40px) to `large` (48px) so it matches `DefaultStreamMessageComposerLeading`'s
`StreamButtonSize.large` attachment button — the snapshot is meant to
show "attachment on outer-left ↔ mic on outer-right" symmetry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): use ghost+secondary mic style at attachment size

In the custom composer snapshot the outer trailing mic/send button
was `solid+primary` (blue circle). Switch it to `ghost+secondary` so it
visually matches the SDK's default `_VoiceRecordingButton`, while keeping
`size: large` to match the outer leading attachment button's footprint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): switch custom composer trailing to outline type

Outline now mirrors `DefaultStreamMessageComposerLeading`'s
`type: outline, style: secondary` attachment button — the trailing
mic/send becomes a visual twin of the leading attachment circle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): solid+primary send variant in custom composer trailing

The voice branch keeps the outline+secondary style (matches an idle
mic affordance), but the send branch flips to solid+primary so it
visually signals "ready to send" — same blue circle the SDK uses by
default in `DefaultStreamMessageComposerInputTrailing`.

The snapshot doesn't change (controller starts empty so only the voice
branch renders), but the demo code now models the toggle correctly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): bump change_position send to large, fix custom_send_icon bg

`message_input_change_position` previously rendered the moved-out
trailing via `DefaultStreamMessageComposerInputTrailing`, which is
hard-coded to `size: small`. Replace with a direct `StreamButton.icon`
at `size: large`, wrapped in a `Row` with a leading `SizedBox(spacing.xs)`
gap — mirrors the spacing the leading `+` button gets on the other side
and matches the trailing button size in `message_input_custom_buttons`.

`message_input_custom_send_icon` builds its own `ThemeData` to demo a
`StreamIcons` override, but didn't set `scaffoldBackgroundColor`. M3's
default light scaffold has a faint pink tint, which produced a coloured
bar above the divider unlike every other composer snapshot. Pin it to
pure white to match.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): align custom composer snapshot height with siblings

`message_input_custom_buttons` was 120 px tall while every other
composer snapshot (default, change_position, custom_send_icon,
slow_mode) is 100 px. Drop to 100 for consistency. The quoted-message
snapshot stays at 160 since it needs room for the quoted-message header.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): override composer send icon via inherited Theme

`message_input_custom_send_icon` was hand-building its own `ThemeData`
to inject a `StreamIcons` override, which forced it to redeclare
`scaffoldBackgroundColor` and re-derive the text theme from scratch.

Use `docsScreenshotsTheme()` as the base and wrap the composer subtree
in a `Builder` + `Theme(data: copyWith(extensions: ...))` so the icon
override flows through Material's inherited `Theme` widget instead of
a duplicated `ThemeData`. Drops the now-unused `stream_core_flutter`
import in this test.

Also bumps the `message_input_quoted_message` snapshot height to 180
so the reply header + composer fit cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): pull MaterialApp wrap into docsGoldenTest

Every docs snapshot builder was rebuilding the same outer wrap —
`MaterialApp(theme: docsScreenshotsTheme(), debugShowCheckedModeBanner: false, home: …)`.

Move that wrap into `docsGoldenTest`'s default `app:` callback so the
builder just returns the `home:` widget. Tests with custom theme/locale
(theming_test, localization_support_test) opt out by passing their own
`app:` callback.

Net −101 lines across 13 files; no golden output changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ci(docs): run analyze/format/test on docs/** changes

`stream_flutter_workflow.yml` only triggered on `packages/**` and
`sample_app/**`, so docs-only PRs (this branch included) skipped the
analyze, format-validate, and test jobs entirely. Add `docs/**` to the
trigger paths.

Also apply the formatter to two files the new check would have flagged
(trailing newline + collapsed one-liner) so the validate step passes on
this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: Update Docs Snapshots

* docs(ui): model custom composer snapshot on WhatsApp layout

Re-arrange the slot demo so it mirrors a recognisable real-world chat
composer (WhatsApp): emoji inside the pill on the left, attachment +
camera icons inside on the right, and a solid green mic/send button
outside on the right.

`StreamButtonTheme` wraps the trailing button to override the primary
solid background to WhatsApp's brand green (#25D366); the state toggle
between voice and send icons stays the same.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): regenerate custom composer snapshot for WhatsApp layout

The previous commit landed the code change but a botched rebase
restored the old PNG. Regenerate so the file actually matches the
emoji + attachment + camera + green-mic layout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): simplify custom composer to Stream-themed slots

Drop the camera slot and the WhatsApp-green override on the trailing
mic/send button. The snapshot now demonstrates the slot mechanics with
a single attachment icon inside the pill and a default-styled mic/send
outside, so the styling falls back to the SDK's primary accent colour
instead of a hard-coded brand colour.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): drop emoji slot from custom composer snapshot

The demo now exercises three slots — outer leading hidden, inner
trailing (attachment), outer trailing (mic/send) — which is enough to
illustrate slot overrides without the extra emoji noise.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: Update Docs Snapshots

---------

Co-authored-by: Sahil Kumar <sahil@getstream.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add snapshots for autocomplete

* update channellistheader snapshots

* Add members snapshots

* chore: Update Docs Snapshots

---------

Co-authored-by: renefloor <15101411+renefloor@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts:
#	.github/workflows/stream_flutter_workflow.yml
#	melos.yaml
#	packages/stream_chat/CHANGELOG.md
#	packages/stream_chat/example/pubspec.yaml
#	packages/stream_chat/lib/src/client/channel.dart
#	packages/stream_chat/lib/src/client/client.dart
#	packages/stream_chat/lib/src/core/util/list_extensions.dart
#	packages/stream_chat/lib/version.dart
#	packages/stream_chat/pubspec.yaml
#	packages/stream_chat/test/src/client/channel_test.dart
#	packages/stream_chat/test/src/client/client_test.dart
#	packages/stream_chat/test/src/core/util/in_flight_cache_test.dart
#	packages/stream_chat/test/src/core/util/list_extensions_test.dart
#	packages/stream_chat_flutter/CHANGELOG.md
#	packages/stream_chat_flutter/example/pubspec.yaml
#	packages/stream_chat_flutter/lib/scrollable_positioned_list/src/positioned_list.dart
#	packages/stream_chat_flutter/lib/scrollable_positioned_list/src/scrollable_positioned_list.dart
#	packages/stream_chat_flutter/lib/scrollable_positioned_list/src/viewport.dart
#	packages/stream_chat_flutter/lib/src/message_input/stream_message_input.dart
#	packages/stream_chat_flutter/lib/src/message_input/stream_message_input_attachment_list.dart
#	packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart
#	packages/stream_chat_flutter/lib/src/misc/separated_reorderable_list_view.dart
#	packages/stream_chat_flutter/lib/src/poll/creator/poll_switch_list_tile.dart
#	packages/stream_chat_flutter/pubspec.yaml
#	packages/stream_chat_flutter/test/scrollable_positioned_list/horizontal_scrollable_positioned_list_test.dart
#	packages/stream_chat_flutter/test/scrollable_positioned_list/item_key_builder_test.dart
#	packages/stream_chat_flutter/test/scrollable_positioned_list/reversed_scrollable_positioned_list_test.dart
#	packages/stream_chat_flutter/test/scrollable_positioned_list/scrollable_positioned_list_test.dart
#	packages/stream_chat_flutter/test/scrollable_positioned_list/separated_scrollable_positioned_list_test.dart
#	packages/stream_chat_flutter/test/scrollable_positioned_list/seperated_horizontal_scrollable_positioned_list_test.dart
#	packages/stream_chat_flutter/test/scrollable_positioned_list/shrink_wrap_scrollable_position_list_test.dart
#	packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_idle_dark.png
#	packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_idle_light.png
#	packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_playing_dark.png
#	packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_playing_light.png
#	packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_playlist_dark.png
#	packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_playlist_light.png
#	packages/stream_chat_flutter/test/src/avatars/goldens/ci/gradient_avatar_issue_2369.png
#	packages/stream_chat_flutter/test/src/avatars/goldens/ci/group_avatar_0.png
#	packages/stream_chat_flutter/test/src/avatars/goldens/ci/user_avatar_0.png
#	packages/stream_chat_flutter/test/src/avatars/goldens/ci/user_avatar_1.png
#	packages/stream_chat_flutter/test/src/bottom_sheets/goldens/ci/attachment_modal_sheet_0.png
#	packages/stream_chat_flutter/test/src/bottom_sheets/goldens/ci/edit_message_sheet_0.png
#	packages/stream_chat_flutter/test/src/bottom_sheets/goldens/ci/error_alert_sheet_0.png
#	packages/stream_chat_flutter/test/src/channel/goldens/ci/channel_header_bottom_widget.png
#	packages/stream_chat_flutter/test/src/dialogs/goldens/ci/confirmation_dialog_0.png
#	packages/stream_chat_flutter/test/src/dialogs/goldens/ci/delete_message_dialog_0.png
#	packages/stream_chat_flutter/test/src/dialogs/goldens/ci/message_dialog_0.png
#	packages/stream_chat_flutter/test/src/dialogs/goldens/ci/message_dialog_1.png
#	packages/stream_chat_flutter/test/src/dialogs/goldens/ci/message_dialog_2.png
#	packages/stream_chat_flutter/test/src/gallery/goldens/ci/gallery_footer_0.png
#	packages/stream_chat_flutter/test/src/gallery/goldens/ci/gallery_header_0.png
#	packages/stream_chat_flutter/test/src/icons/goldens/ci/stream_svg_icon_light.png
#	packages/stream_chat_flutter/test/src/indicators/goldens/ci/sending_indicator_0.png
#	packages/stream_chat_flutter/test/src/indicators/goldens/ci/sending_indicator_1.png
#	packages/stream_chat_flutter/test/src/indicators/goldens/ci/sending_indicator_2.png
#	packages/stream_chat_flutter/test/src/indicators/goldens/ci/sending_indicator_3.png
#	packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_idle_dark.png
#	packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_idle_light.png
#	packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_hold_dark.png
#	packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_hold_light.png
#	packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_locked_dark.png
#	packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_locked_light.png
#	packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_stopped_dark.png
#	packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_stopped_light.png
#	packages/stream_chat_flutter/test/src/message_input/goldens/ci/attachment_button_0.png
#	packages/stream_chat_flutter/test/src/message_input/goldens/ci/clear_input_item_0.png
#	packages/stream_chat_flutter/test/src/message_input/goldens/ci/command_button_0.png
#	packages/stream_chat_flutter/test/src/message_input/goldens/ci/countdown_button_0.png
#	packages/stream_chat_flutter/test/src/message_list_view/auto_scroll_test.dart
#	packages/stream_chat_flutter/test/src/message_list_view/mark_read_test.dart
#	packages/stream_chat_flutter/test/src/message_widget/goldens/ci/deleted_message_custom.png
#	packages/stream_chat_flutter/test/src/message_widget/goldens/ci/deleted_message_dark.png
#	packages/stream_chat_flutter/test/src/message_widget/goldens/ci/deleted_message_light.png
#	packages/stream_chat_flutter/test/src/message_widget/goldens/ci/message_text.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_2.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_dark.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_light.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_dark.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_light.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_custom_dark.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_custom_light.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_dark.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_empty_dark.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_empty_light.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_inverted_dark.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_inverted_light.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_less_data_dark.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_less_data_light.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_light.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_progress_dark.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_progress_light.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_timestamp_dark.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_timestamp_light.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/system_message_dark.png
#	packages/stream_chat_flutter/test/src/misc/goldens/ci/system_message_light.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_delete_option_dialog_dark.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_delete_option_dialog_light.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_dark.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_error_dark.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_error_light.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_light.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_dark.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_error_dark.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_error_light.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_light.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_dark.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_light.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_dark.png
#	packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_light.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_option_reorderable_list_view_dark.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_option_reorderable_list_view_error.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_option_reorderable_list_view_light.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_dark.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_error.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_light.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_dark.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_light.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_dark.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_light.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_options_dialog_dark.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_options_dialog_light.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_dark.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_light.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_with_show_all_dark.png
#	packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_with_show_all_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_with_initial_value_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_with_initial_value_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_end_vote_dialog_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_end_vote_dialog_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_long_question_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_long_question_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_all_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_all_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_disabled_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_disabled_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_limited_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_limited_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_unique_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_unique_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_with_initial_option_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_with_initial_option_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_closed_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_closed_light.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_dark.png
#	packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_light.png
#	packages/stream_chat_flutter/test/src/scroll_view/draft_scroll_view/goldens/ci/stream_draft_list_tile_dark.png
#	packages/stream_chat_flutter/test/src/scroll_view/draft_scroll_view/goldens/ci/stream_draft_list_tile_light.png
#	packages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_thread_list_tile_dark.png
#	packages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_thread_list_tile_light.png
#	packages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_unread_threads_banner_dark.png
#	packages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_unread_threads_banner_light.png
#	packages/stream_chat_flutter_core/CHANGELOG.md
#	packages/stream_chat_flutter_core/example/pubspec.yaml
#	packages/stream_chat_flutter_core/lib/src/better_stream_builder.dart
#	packages/stream_chat_flutter_core/lib/src/message_list_core.dart
#	packages/stream_chat_flutter_core/lib/src/paged_value_scroll_view.dart
#	packages/stream_chat_flutter_core/pubspec.yaml
#	packages/stream_chat_flutter_core/test/message_list_core_test.dart
#	packages/stream_chat_flutter_core/test/stream_channel_test.dart
#	packages/stream_chat_flutter_core/test/stream_chat_core_test.dart
#	packages/stream_chat_localizations/CHANGELOG.md
#	packages/stream_chat_localizations/example/pubspec.yaml
#	packages/stream_chat_localizations/pubspec.yaml
#	packages/stream_chat_persistence/CHANGELOG.md
#	packages/stream_chat_persistence/example/pubspec.yaml
#	packages/stream_chat_persistence/lib/src/db/shared/native_db.dart
#	packages/stream_chat_persistence/lib/src/stream_chat_persistence_client.dart
#	packages/stream_chat_persistence/pubspec.yaml
#	packages/stream_chat_persistence/test/stream_chat_persistence_client_test.dart
#	sample_app/ios/Runner/Info.plist
#	sample_app/ios/fastlane/Fastfile
#	sample_app/lib/app.dart
#	sample_app/lib/firebase_options.dart
#	sample_app/pubspec.yaml
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 28, 2026

⚠️ Database Entity Files Modified

The following database entity files have been modified in this PR:

packages/stream_chat_persistence/lib/src/entity/channel_queries.dart
packages/stream_chat_persistence/lib/src/entity/channels.dart
packages/stream_chat_persistence/lib/src/entity/draft_messages.dart
packages/stream_chat_persistence/lib/src/entity/entity.dart
packages/stream_chat_persistence/lib/src/entity/locations.dart
packages/stream_chat_persistence/lib/src/entity/members.dart
packages/stream_chat_persistence/lib/src/entity/messages.dart
packages/stream_chat_persistence/lib/src/entity/pinned_message_reactions.dart
packages/stream_chat_persistence/lib/src/entity/poll_votes.dart
packages/stream_chat_persistence/lib/src/entity/polls.dart
packages/stream_chat_persistence/lib/src/entity/reactions.dart
packages/stream_chat_persistence/lib/src/entity/reads.dart

📝 Remember to:

  1. Update database version in db/drift_chat_database.dart.
  2. Update entity schema tests if necessary.

Note: This comment is automatically generated by the CI workflow.

renefloor and others added 5 commits May 28, 2026 14:54
* update migration docs with latest changes

* Add migration doc for sort option

* docs: correct migration docs against verified source

Apply ~70+ corrections across all 16 redesign migration docs and
v10-migration.md based on a source-by-source verification pass. Fixes
non-existent symbols, wrong constructor params, wrong typedef
signatures, and stale class names that would prevent migration code
examples from compiling. Adds the missing ClientState collection
immutability breaking-change section (introduced in 2501f53).

Also cleans up five stale dartdoc references in source that seeded
some of the wrong names in the docs (StreamMessagePlacement →
StreamMessageLayout, UrlAttachmentBuilder → LinkPreviewAttachmentBuilder,
StreamChat(config:) → streamChatConfigData:, etc.).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(ui)!: remove unused MessageDetails class

The MessageDetails class was only used by itself — no live consumers in
packages/ or sample_app. The new messageBuilder signature stopped passing
it as an argument, leaving the class as dead public surface area. Delete
the file and its export; update CHANGELOG and the migration doc that
previously said "no longer passed to builders" to reflect the actual
removal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(ui): re-export StreamAvatarTheme/Data from stream_core_flutter

The two avatar theme types live in stream_core_flutter, but consumers
who only depended on stream_chat_flutter had to add a second import to
theme avatars globally. Add them to the show allowlist so existing
StreamAvatarThemeData imports keep working, drop the now-redundant
stream_core_flutter import from stream_media_gallery_item.dart, and
update the migration doc that previously instructed users to import
from stream_core_flutter directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(ui): inline AttachmentPickerOptionsBuilder typedef, drop empty file

stream_attachment_picker_bottom_sheet.dart only held the
AttachmentPickerOptionsBuilder typedef — the filename implied a sheet
class that no longer exists after pickers became inline. Move the
typedef into stream_attachment_picker.dart (next to the picker widgets
and builder functions that use it) and delete the misleading file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: add Stream Core / Stream Chat preamble to redesign README

Front-load the two-layer split so future doc passes don't conflate
"moved to stream_core_flutter" with "removed." Includes a small
core-primitive ↔ chat-wrapper table and a "frequently confused names"
list covering the wrong-name patterns that surfaced during the
verification pass (StreamMessagePlacement → StreamMessageLayout,
kStreamHeaderHeight → kStreamToolbarHeight, etc.).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: address CodeRabbit review comments

- attachments_and_polls.md: fix stale #streamattachmentpickeroption
  anchor (→ #attachment-picker) and drop reference to the removed
  showStreamAttachmentPickerModalBottomSheet function.
- v10-migration.md: stable-release boundary was beta.12, not beta.13
  (matches the upgrade matrix at the top of the doc).
- message_actions.md: drop StreamMessageReactionsModal from the
  showStreamDialog Future<T?> "returns" list — the class is deleted.
- message_composer.md: destructure cooldownTimeOut from
  SlowModePlaceholder so translations.slowModeOnLabel(int) gets its
  required argument; matches the source dartdoc example verbatim.

The fourth flagged comment (onDismissTap row in unread_indicator_button.md)
was already removed in the earlier verification pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(ui): use American spelling "customization" in reaction_picker.md

Line 31 used British "customisation" while the rest of the doc (and the
heading at line 299) uses American "Customization". Match the rest.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fixed last StreamMessagePlacement occurrence

---------

Co-authored-by: Sahil Kumar <xdsahil@gmail.com>
Co-authored-by: Sahil Kumar <sahil@getstream.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Enable drafts and voice recording by default

* update drafts default in sample app

* Disable enforceUniqueReactions by default

* Update changelog

* Add draft mocks
* apply filter of supported emoji

* Update changelog

* Add doc screenshots

* chore: Update Docs Snapshots

* test(docs): settle before precaching so deferred avatars decode

docsGoldenTest's default pumpBeforeTest now calls pumpAndSettle before
precacheImages, so modal sheets and paginated list views finish rendering
before the image scan runs — fixing the empty avatar circles in the
reaction detail sheet and reaction list view goldens. Reaction stubs move
into the test builders now that custom pumpBeforeTest overrides are no
longer needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: remove unused import

* chore: Update Docs Snapshots

---------

Co-authored-by: renefloor <15101411+renefloor@users.noreply.github.com>
Co-authored-by: Sahil Kumar <sahil@getstream.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com>
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.

4 participants