From c9e00d422e585735811010b80b25a747c2acaaaa Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 6 May 2026 14:56:13 +0200 Subject: [PATCH 01/87] Create ChannelPage with floating logic --- .../lib/src/channel/channel_page.dart | 271 ++++++++++++++++++ .../lib/src/channel/thread_page.dart | 85 ++++++ .../stream_message_composer.dart | 49 ++-- .../message_list_view/message_list_view.dart | 14 +- .../lib/stream_chat_flutter.dart | 1 + sample_app/lib/routes/app_routes.dart | 3 +- 6 files changed, 401 insertions(+), 22 deletions(-) create mode 100644 packages/stream_chat_flutter/lib/src/channel/channel_page.dart create mode 100644 packages/stream_chat_flutter/lib/src/channel/thread_page.dart diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart new file mode 100644 index 0000000000..5b4ee980ab --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -0,0 +1,271 @@ +// ignore_for_file: deprecated_member_use, avoid_redundant_argument_values + +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/channel/thread_page.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +/// A channel page with optional floating composer support. +class StreamChannelPage extends StatefulWidget { + /// Creates a [StreamChannelPage]. + const StreamChannelPage({ + super.key, + this.initialScrollIndex, + this.initialAlignment, + this.highlightInitialMessage = false, + this.onBackPressed, + this.onHeaderImageTap, + this.isFloating = false, + }); + + /// Initial scroll index for the message list. + final int? initialScrollIndex; + + /// Initial scroll alignment for the message list. + final double? initialAlignment; + + /// Whether to highlight the initial message. + final bool highlightInitialMessage; + + /// Callback for when the back button is pressed. + final VoidCallback? onBackPressed; + + /// Callback for when the header image is tapped. + final VoidCallback? onHeaderImageTap; + + /// Whether the composer floats over the message list. + /// + /// When true the composer is overlaid at the bottom and the message list + /// scrolls underneath it. Layout is done in a single pass so the list + /// inset and the composer height are always in sync. + final bool isFloating; + + @override + State createState() => _StreamChannelPageState(); +} + +class _StreamChannelPageState extends State { + FocusNode? _focusNode; + final _messageInputController = StreamMessageInputController(); + + @override + void initState() { + _focusNode = FocusNode(); + super.initState(); + } + + @override + void dispose() { + _focusNode!.dispose(); + super.dispose(); + } + + void _reply(Message message) { + _messageInputController.quotedMessage = message; + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + _focusNode!.requestFocus(); + }); + } + + void _editMessage(Message message) { + _messageInputController.editMessage(message); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + _focusNode!.requestFocus(); + }); + } + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final textTheme = theme.textTheme; + final colorTheme = theme.colorTheme; + + final appBar = StreamChannelHeader( + showTypingIndicator: false, + onBackPressed: widget.onBackPressed, + onImageTap: widget.onHeaderImageTap, + ); + + final typingIndicator = StreamTypingIndicator( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + style: textTheme.footnote.copyWith( + color: colorTheme.textLowEmphasis, + ), + ); + + final composer = StreamMessageComposer( + focusNode: _focusNode, + messageInputController: _messageInputController, + onQuotedMessageCleared: _messageInputController.clearQuotedMessage, + enableVoiceRecording: true, + isFloating: widget.isFloating, + ); + + if (widget.isFloating) { + return Scaffold( + backgroundColor: colorTheme.appBg, + appBar: appBar, + body: _FloatingChannelBody( + composer: composer, + typingIndicator: Container( + alignment: Alignment.centerLeft, + color: colorTheme.appBg.withOpacity(.9), + child: typingIndicator, + ), + messageListBuilder: (bottomWidgetsHeight) => StreamMessageListView( + initialScrollIndex: widget.initialScrollIndex, + initialAlignment: widget.initialAlignment, + highlightInitialMessage: widget.highlightInitialMessage, + onEditMessageTap: _editMessage, + onReplyTap: _reply, + swipeToReply: true, + threadBuilder: (_, parentMessage) { + return StreamThreadPage(parent: parentMessage!); + }, + bottomPadding: bottomWidgetsHeight, + ), + ), + ); + } + + return Scaffold( + backgroundColor: colorTheme.appBg, + appBar: appBar, + body: Column( + children: [ + Expanded( + child: Stack( + children: [ + StreamMessageListView( + initialScrollIndex: widget.initialScrollIndex, + initialAlignment: widget.initialAlignment, + highlightInitialMessage: widget.highlightInitialMessage, + onEditMessageTap: _editMessage, + onReplyTap: _reply, + swipeToReply: true, + threadBuilder: (_, parentMessage) { + return StreamThreadPage(parent: parentMessage!); + }, + ), + Positioned( + bottom: 0, + left: 0, + right: 0, + child: Container( + alignment: Alignment.centerLeft, + color: colorTheme.appBg.withOpacity(.9), + child: typingIndicator, + ), + ), + ], + ), + ), + composer, + ], + ), + ); + } +} + +// --------------------------------------------------------------------------- +// Floating layout helpers +// --------------------------------------------------------------------------- + +/// Layout slot identifiers for [_FloatingChannelBodyDelegate]. +enum _Slot { body, typing, composer } + +/// A custom [BoxConstraints] subclass that carries the composer height so that +/// a [LayoutBuilder] inside the body slot can read it without a separate +/// callback or [setState]. +/// +/// The [==] / [hashCode] overrides are intentional: they make the framework +/// re-run [RenderObject.performLayout] on the body child even when the outer +/// size constraints have not changed but only [composerHeight] has. +class _BodyBoxConstraints extends BoxConstraints { + const _BodyBoxConstraints({ + super.maxWidth, + super.maxHeight, + required this.composerHeight, + }) : assert(composerHeight >= 0, 'composerHeight must be non-negative'); + + /// Height of the floating composer, used as the list's bottom inset. + final double composerHeight; + + @override + bool operator ==(Object other) { + if (super != other) return false; + return other is _BodyBoxConstraints && other.composerHeight == composerHeight; + } + + @override + int get hashCode => Object.hash(super.hashCode, composerHeight); +} + +/// [MultiChildLayoutDelegate] that measures the composer first, then lays out +/// the typing indicator and body in the same layout pass — no post-frame +/// callback required. +class _FloatingChannelBodyDelegate extends MultiChildLayoutDelegate { + @override + void performLayout(Size size) { + // 1. Measure + position the composer at the bottom. + final composerSize = layoutChild(_Slot.composer, BoxConstraints.loose(size)); + positionChild(_Slot.composer, Offset(0, size.height - composerSize.height)); + + // 2. Measure + position the typing indicator just above the composer. + final typingSize = layoutChild(_Slot.typing, BoxConstraints(maxWidth: size.width)); + positionChild(_Slot.typing, Offset(0, size.height - composerSize.height - typingSize.height)); + + // 3. Lay out the body with the composer height embedded in the constraints + // so the LayoutBuilder inside can read it synchronously. + layoutChild( + _Slot.body, + _BodyBoxConstraints( + maxWidth: size.width, + maxHeight: size.height, + composerHeight: composerSize.height, + ), + ); + positionChild(_Slot.body, Offset.zero); + } + + @override + bool shouldRelayout(_FloatingChannelBodyDelegate oldDelegate) => false; +} + +/// Stateless widget that wires the floating layout together. +class _FloatingChannelBody extends StatelessWidget { + const _FloatingChannelBody({ + required this.composer, + required this.typingIndicator, + required this.messageListBuilder, + }); + + final Widget composer; + final Widget typingIndicator; + + /// Called with the current composer height so the list can set its inset. + final Widget Function(double bottomWidgetsHeight) messageListBuilder; + + @override + Widget build(BuildContext context) { + return CustomMultiChildLayout( + delegate: _FloatingChannelBodyDelegate(), + children: [ + // Body slot: a LayoutBuilder that reads the custom constraints. + LayoutId( + id: _Slot.body, + child: LayoutBuilder( + builder: (context, constraints) { + final height = constraints is _BodyBoxConstraints ? constraints.composerHeight : 0.0; + return messageListBuilder(height); + }, + ), + ), + LayoutId(id: _Slot.typing, child: typingIndicator), + LayoutId(id: _Slot.composer, child: composer), + ], + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart new file mode 100644 index 0000000000..c6797a901f --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart @@ -0,0 +1,85 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +/// A page that displays a thread of messages for a given parent message. +class StreamThreadPage extends StatefulWidget { + /// Creates a [StreamThreadPage]. + const StreamThreadPage({ + super.key, + required this.parent, + this.initialScrollIndex, + this.initialAlignment, + this.onViewInChannelTap, + }); + + /// The parent message of the thread. + final Message parent; + + /// Initial scroll index for the thread message list. + final int? initialScrollIndex; + + /// Initial scroll alignment for the thread message list. + final double? initialAlignment; + + /// Called when the user taps "View in channel". + final void Function(Message message)? onViewInChannelTap; + + @override + State createState() => _StreamThreadPageState(); +} + +class _StreamThreadPageState extends State { + final FocusNode _focusNode = FocusNode(); + late StreamMessageInputController _messageInputController; + + @override + void initState() { + super.initState(); + _messageInputController = StreamMessageInputController( + message: Message(parentId: widget.parent.id), + ); + } + + @override + void dispose() { + _focusNode.dispose(); + super.dispose(); + } + + void _reply(Message message) { + _messageInputController.quotedMessage = message; + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + _focusNode.requestFocus(); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: StreamChatTheme.of(context).colorTheme.appBg, + appBar: StreamThreadHeader(parent: widget.parent), + body: Column( + children: [ + Expanded( + child: StreamMessageListView( + parentMessage: widget.parent, + initialScrollIndex: widget.initialScrollIndex, + initialAlignment: widget.initialAlignment, + onReplyTap: _reply, + swipeToReply: true, + showScrollToBottom: false, + highlightInitialMessage: true, + onViewInChannelTap: widget.onViewInChannelTap, + ), + ), + if (widget.parent.type != 'deleted') + StreamMessageComposer( + focusNode: _focusNode, + messageInputController: _messageInputController, + enableVoiceRecording: true, + ), + ], + ), + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 565d63b10c..c59327dcb9 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -95,6 +95,7 @@ class StreamMessageComposer extends StatelessWidget { TextCapitalization textCapitalization = TextCapitalization.sentences, bool autofocus = false, bool autoCorrect = true, + bool isFloating = false, }) : props = .new( onMessageSent: onMessageSent, preMessageSending: preMessageSending, @@ -130,6 +131,7 @@ class StreamMessageComposer extends StatelessWidget { textCapitalization: textCapitalization, autofocus: autofocus, autoCorrect: autoCorrect, + isFloating: isFloating, ); /// Creates a [StreamMessageComposer] from a pre-built [MessageComposerProps]. @@ -190,6 +192,7 @@ class MessageComposerProps { this.textCapitalization = TextCapitalization.sentences, this.autofocus = false, this.autoCorrect = true, + this.isFloating = false, }); /// Function called after sending the message. @@ -384,6 +387,8 @@ class MessageComposerProps { /// Defaults to true. final bool autoCorrect; + /// Whether the message composer is floating. + final bool isFloating; /// Returns a copy of this [MessageComposerProps] with the given fields /// replaced with new values. MessageComposerProps copyWith({ @@ -789,25 +794,30 @@ class DefaultStreamMessageComposerState extends State _StreamMessageListViewState(); } @@ -593,7 +600,10 @@ class _StreamMessageListViewState extends State { }, child: ScrollablePositionedList.separated( key: Key('mlv-${streamChannel?.channel.cid}-${widget.parentMessage?.id}'), - padding: .symmetric(vertical: context.streamSpacing.sm), + padding: .only( + top: context.streamSpacing.sm, + bottom: max(widget.bottomPadding, context.streamSpacing.sm), + ), keyboardDismissBehavior: widget.config.keyboardDismissBehavior, itemPositionsListener: _itemPositionListener, initialScrollIndex: initialIndex, @@ -1040,7 +1050,7 @@ class _StreamMessageListViewState extends State { } return PositionedDirectional( - bottom: 16, + bottom: max(16, widget.bottomPadding), end: 16, child: button, ); diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index a434f1a6e5..de2b6ac64d 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -168,6 +168,7 @@ export 'src/channel/channel_header.dart'; export 'src/channel/channel_info.dart'; export 'src/channel/channel_list_header.dart'; export 'src/channel/channel_name.dart'; +export 'src/channel/channel_page.dart'; export 'src/channel/stream_channel_name.dart'; export 'src/channel/stream_draft_message_preview_text.dart'; export 'src/channel/stream_message_preview_text.dart'; diff --git a/sample_app/lib/routes/app_routes.dart b/sample_app/lib/routes/app_routes.dart index 3e11a35f2f..3cae1e3392 100644 --- a/sample_app/lib/routes/app_routes.dart +++ b/sample_app/lib/routes/app_routes.dart @@ -46,8 +46,9 @@ final appRoutes = [ builder: (context) { return (parentMessage != null) ? ThreadPage(parent: parentMessage) - : ChannelPage( + : StreamChannelPage( highlightInitialMessage: messageId != null, + isFloating: true, ); }, ), From 9e5ba935261887870102c13b6f96b21f24b59122 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 6 May 2026 17:36:26 +0200 Subject: [PATCH 02/87] simplify composer setup --- .../lib/src/channel/channel_page.dart | 148 ++++-------------- 1 file changed, 28 insertions(+), 120 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index 5b4ee980ab..602cfa9e6f 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -107,25 +107,34 @@ class _StreamChannelPageState extends State { return Scaffold( backgroundColor: colorTheme.appBg, appBar: appBar, - body: _FloatingChannelBody( - composer: composer, - typingIndicator: Container( - alignment: Alignment.centerLeft, - color: colorTheme.appBg.withOpacity(.9), - child: typingIndicator, - ), - messageListBuilder: (bottomWidgetsHeight) => StreamMessageListView( - initialScrollIndex: widget.initialScrollIndex, - initialAlignment: widget.initialAlignment, - highlightInitialMessage: widget.highlightInitialMessage, - onEditMessageTap: _editMessage, - onReplyTap: _reply, - swipeToReply: true, - threadBuilder: (_, parentMessage) { - return StreamThreadPage(parent: parentMessage!); - }, - bottomPadding: bottomWidgetsHeight, - ), + extendBody: true, + bottomNavigationBar: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + alignment: Alignment.centerLeft, + color: colorTheme.appBg.withOpacity(.9), + child: typingIndicator, + ), + composer, + ], + ), + body: Builder( + builder: (context) { + final bottomInset = MediaQuery.of(context).padding.bottom; + return StreamMessageListView( + initialScrollIndex: widget.initialScrollIndex, + initialAlignment: widget.initialAlignment, + highlightInitialMessage: widget.highlightInitialMessage, + onEditMessageTap: _editMessage, + onReplyTap: _reply, + swipeToReply: true, + threadBuilder: (_, parentMessage) { + return StreamThreadPage(parent: parentMessage!); + }, + bottomPadding: bottomInset, + ); + }, ), ); } @@ -168,104 +177,3 @@ class _StreamChannelPageState extends State { ); } } - -// --------------------------------------------------------------------------- -// Floating layout helpers -// --------------------------------------------------------------------------- - -/// Layout slot identifiers for [_FloatingChannelBodyDelegate]. -enum _Slot { body, typing, composer } - -/// A custom [BoxConstraints] subclass that carries the composer height so that -/// a [LayoutBuilder] inside the body slot can read it without a separate -/// callback or [setState]. -/// -/// The [==] / [hashCode] overrides are intentional: they make the framework -/// re-run [RenderObject.performLayout] on the body child even when the outer -/// size constraints have not changed but only [composerHeight] has. -class _BodyBoxConstraints extends BoxConstraints { - const _BodyBoxConstraints({ - super.maxWidth, - super.maxHeight, - required this.composerHeight, - }) : assert(composerHeight >= 0, 'composerHeight must be non-negative'); - - /// Height of the floating composer, used as the list's bottom inset. - final double composerHeight; - - @override - bool operator ==(Object other) { - if (super != other) return false; - return other is _BodyBoxConstraints && other.composerHeight == composerHeight; - } - - @override - int get hashCode => Object.hash(super.hashCode, composerHeight); -} - -/// [MultiChildLayoutDelegate] that measures the composer first, then lays out -/// the typing indicator and body in the same layout pass — no post-frame -/// callback required. -class _FloatingChannelBodyDelegate extends MultiChildLayoutDelegate { - @override - void performLayout(Size size) { - // 1. Measure + position the composer at the bottom. - final composerSize = layoutChild(_Slot.composer, BoxConstraints.loose(size)); - positionChild(_Slot.composer, Offset(0, size.height - composerSize.height)); - - // 2. Measure + position the typing indicator just above the composer. - final typingSize = layoutChild(_Slot.typing, BoxConstraints(maxWidth: size.width)); - positionChild(_Slot.typing, Offset(0, size.height - composerSize.height - typingSize.height)); - - // 3. Lay out the body with the composer height embedded in the constraints - // so the LayoutBuilder inside can read it synchronously. - layoutChild( - _Slot.body, - _BodyBoxConstraints( - maxWidth: size.width, - maxHeight: size.height, - composerHeight: composerSize.height, - ), - ); - positionChild(_Slot.body, Offset.zero); - } - - @override - bool shouldRelayout(_FloatingChannelBodyDelegate oldDelegate) => false; -} - -/// Stateless widget that wires the floating layout together. -class _FloatingChannelBody extends StatelessWidget { - const _FloatingChannelBody({ - required this.composer, - required this.typingIndicator, - required this.messageListBuilder, - }); - - final Widget composer; - final Widget typingIndicator; - - /// Called with the current composer height so the list can set its inset. - final Widget Function(double bottomWidgetsHeight) messageListBuilder; - - @override - Widget build(BuildContext context) { - return CustomMultiChildLayout( - delegate: _FloatingChannelBodyDelegate(), - children: [ - // Body slot: a LayoutBuilder that reads the custom constraints. - LayoutId( - id: _Slot.body, - child: LayoutBuilder( - builder: (context, constraints) { - final height = constraints is _BodyBoxConstraints ? constraints.composerHeight : 0.0; - return messageListBuilder(height); - }, - ), - ), - LayoutId(id: _Slot.typing, child: typingIndicator), - LayoutId(id: _Slot.composer, child: composer), - ], - ); - } -} From e6e34444b3ca56edcd6e93607e8c109dad17aa0b Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 6 May 2026 17:40:57 +0200 Subject: [PATCH 03/87] poc for floating app bar --- .../lib/src/channel/channel_page.dart | 15 ++++++++++++--- .../src/message_list_view/message_list_view.dart | 13 ++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index 602cfa9e6f..08c7bb5963 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -104,10 +104,18 @@ class _StreamChannelPageState extends State { ); if (widget.isFloating) { + final floatingAppBar = StreamChannelHeader( + showTypingIndicator: false, + onBackPressed: widget.onBackPressed, + onImageTap: widget.onHeaderImageTap, + backgroundColor: Colors.transparent, + ); + return Scaffold( backgroundColor: colorTheme.appBg, - appBar: appBar, + appBar: floatingAppBar, extendBody: true, + extendBodyBehindAppBar: true, bottomNavigationBar: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -121,7 +129,7 @@ class _StreamChannelPageState extends State { ), body: Builder( builder: (context) { - final bottomInset = MediaQuery.of(context).padding.bottom; + final insets = MediaQuery.of(context).padding; return StreamMessageListView( initialScrollIndex: widget.initialScrollIndex, initialAlignment: widget.initialAlignment, @@ -132,7 +140,8 @@ class _StreamChannelPageState extends State { threadBuilder: (_, parentMessage) { return StreamThreadPage(parent: parentMessage!); }, - bottomPadding: bottomInset, + topPadding: insets.top, + bottomPadding: insets.bottom, ); }, ), diff --git a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart index f97b7e5570..f9c9f722ac 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart @@ -125,6 +125,7 @@ class StreamMessageListView extends StatefulWidget { this.onMessageLongPress, this.config = const StreamMessageListViewConfiguration(), this.builders = const StreamMessageListViewBuilders(), + this.topPadding = 0, this.bottomPadding = 0, }); @@ -259,6 +260,12 @@ class StreamMessageListView extends StatefulWidget { /// Defaults to [StreamMessageListViewBuilders] with no overrides. final StreamMessageListViewBuilders builders; + /// Top padding added to the message list scroll view. + /// + /// Used by the floating app bar layout to keep the first message visible + /// below the app bar without requiring a separate [setState] call. + final double topPadding; + /// Bottom padding added to the message list scroll view. /// /// Used by the floating composer layout to keep the last message visible @@ -601,7 +608,7 @@ class _StreamMessageListViewState extends State { child: ScrollablePositionedList.separated( key: Key('mlv-${streamChannel?.channel.cid}-${widget.parentMessage?.id}'), padding: .only( - top: context.streamSpacing.sm, + top: max(widget.topPadding, context.streamSpacing.sm), bottom: max(widget.bottomPadding, context.streamSpacing.sm), ), keyboardDismissBehavior: widget.config.keyboardDismissBehavior, @@ -758,7 +765,7 @@ class _StreamMessageListViewState extends State { ), if (widget.config.showFloatingDateDivider) Positioned( - top: context.streamSpacing.sm, + top: max(widget.topPadding, context.streamSpacing.sm), child: FloatingDateDivider( itemCount: itemCount, reverse: widget.config.reverse, @@ -786,7 +793,7 @@ class _StreamMessageListViewState extends State { ), if (widget.config.showUnreadIndicator && !_isThreadConversation) Positioned( - top: context.streamSpacing.sm, + top: max(widget.topPadding, context.streamSpacing.sm), child: UnreadIndicatorButton( onJumpTap: scrollToUnreadDefaultTapAction, onDismissTap: _markMessagesAsRead, From c99bc631d5beedfca64974478d52ff79b96706f9 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 27 May 2026 11:05:44 +0200 Subject: [PATCH 04/87] fixes for merge issues --- .../lib/src/channel/channel_page.dart | 67 ++++++++----------- .../lib/src/channel/thread_page.dart | 19 +++--- 2 files changed, 40 insertions(+), 46 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index 08c7bb5963..01562c7011 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -13,8 +13,8 @@ class StreamChannelPage extends StatefulWidget { this.initialAlignment, this.highlightInitialMessage = false, this.onBackPressed, - this.onHeaderImageTap, - this.isFloating = false, + this.onChannelAvatarPressed, + this.isFloating = true, }); /// Initial scroll index for the message list. @@ -29,8 +29,8 @@ class StreamChannelPage extends StatefulWidget { /// Callback for when the back button is pressed. final VoidCallback? onBackPressed; - /// Callback for when the header image is tapped. - final VoidCallback? onHeaderImageTap; + /// Called when the default channel-avatar trailing is pressed. + final void Function(Channel channel)? onChannelAvatarPressed; /// Whether the composer floats over the message list. /// @@ -45,7 +45,7 @@ class StreamChannelPage extends StatefulWidget { class _StreamChannelPageState extends State { FocusNode? _focusNode; - final _messageInputController = StreamMessageInputController(); + final _messageComposerController = StreamMessageComposerController(); @override void initState() { @@ -60,14 +60,14 @@ class _StreamChannelPageState extends State { } void _reply(Message message) { - _messageInputController.quotedMessage = message; + _messageComposerController.quotedMessage = message; WidgetsBinding.instance.addPostFrameCallback((timeStamp) { _focusNode!.requestFocus(); }); } void _editMessage(Message message) { - _messageInputController.editMessage(message); + _messageComposerController.editMessage(message); WidgetsBinding.instance.addPostFrameCallback((timeStamp) { _focusNode!.requestFocus(); }); @@ -75,45 +75,30 @@ class _StreamChannelPageState extends State { @override Widget build(BuildContext context) { - final theme = StreamChatTheme.of(context); - final textTheme = theme.textTheme; - final colorTheme = theme.colorTheme; - - final appBar = StreamChannelHeader( - showTypingIndicator: false, - onBackPressed: widget.onBackPressed, - onImageTap: widget.onHeaderImageTap, - ); - final typingIndicator = StreamTypingIndicator( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4, ), - style: textTheme.footnote.copyWith( - color: colorTheme.textLowEmphasis, + style: context.streamTextTheme.captionDefault.copyWith( + color: context.streamColorScheme.textSecondary, ), ); final composer = StreamMessageComposer( focusNode: _focusNode, - messageInputController: _messageInputController, - onQuotedMessageCleared: _messageInputController.clearQuotedMessage, + messageComposerController: _messageComposerController, + onQuotedMessageCleared: _messageComposerController.clearQuotedMessage, enableVoiceRecording: true, isFloating: widget.isFloating, ); if (widget.isFloating) { - final floatingAppBar = StreamChannelHeader( - showTypingIndicator: false, - onBackPressed: widget.onBackPressed, - onImageTap: widget.onHeaderImageTap, - backgroundColor: Colors.transparent, - ); - return Scaffold( - backgroundColor: colorTheme.appBg, - appBar: floatingAppBar, + backgroundColor: context.streamColorScheme.backgroundApp, + appBar: StreamChannelHeader( + onChannelAvatarPressed: widget.onChannelAvatarPressed, + ), extendBody: true, extendBodyBehindAppBar: true, bottomNavigationBar: Column( @@ -121,7 +106,7 @@ class _StreamChannelPageState extends State { children: [ Container( alignment: Alignment.centerLeft, - color: colorTheme.appBg.withOpacity(.9), + color: context.streamColorScheme.backgroundApp.withOpacity(.9), child: typingIndicator, ), composer, @@ -133,10 +118,12 @@ class _StreamChannelPageState extends State { return StreamMessageListView( initialScrollIndex: widget.initialScrollIndex, initialAlignment: widget.initialAlignment, - highlightInitialMessage: widget.highlightInitialMessage, + config: StreamMessageListViewConfiguration( + highlightInitialMessage: widget.highlightInitialMessage, + swipeToReply: true, + ), onEditMessageTap: _editMessage, onReplyTap: _reply, - swipeToReply: true, threadBuilder: (_, parentMessage) { return StreamThreadPage(parent: parentMessage!); }, @@ -149,8 +136,10 @@ class _StreamChannelPageState extends State { } return Scaffold( - backgroundColor: colorTheme.appBg, - appBar: appBar, + backgroundColor: context.streamColorScheme.backgroundApp, + appBar: StreamChannelHeader( + onChannelAvatarPressed: widget.onChannelAvatarPressed, + ), body: Column( children: [ Expanded( @@ -159,10 +148,12 @@ class _StreamChannelPageState extends State { StreamMessageListView( initialScrollIndex: widget.initialScrollIndex, initialAlignment: widget.initialAlignment, - highlightInitialMessage: widget.highlightInitialMessage, + config: StreamMessageListViewConfiguration( + highlightInitialMessage: widget.highlightInitialMessage, + swipeToReply: true, + ), onEditMessageTap: _editMessage, onReplyTap: _reply, - swipeToReply: true, threadBuilder: (_, parentMessage) { return StreamThreadPage(parent: parentMessage!); }, @@ -173,7 +164,7 @@ class _StreamChannelPageState extends State { right: 0, child: Container( alignment: Alignment.centerLeft, - color: colorTheme.appBg.withOpacity(.9), + color: context.streamColorScheme.backgroundApp.withOpacity(.9), child: typingIndicator, ), ), diff --git a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart index c6797a901f..ead1d8f08c 100644 --- a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart @@ -30,12 +30,12 @@ class StreamThreadPage extends StatefulWidget { class _StreamThreadPageState extends State { final FocusNode _focusNode = FocusNode(); - late StreamMessageInputController _messageInputController; + late StreamMessageComposerController _messageComposerController; @override void initState() { super.initState(); - _messageInputController = StreamMessageInputController( + _messageComposerController = StreamMessageComposerController( message: Message(parentId: widget.parent.id), ); } @@ -43,11 +43,12 @@ class _StreamThreadPageState extends State { @override void dispose() { _focusNode.dispose(); + _messageComposerController.dispose(); super.dispose(); } void _reply(Message message) { - _messageInputController.quotedMessage = message; + _messageComposerController.quotedMessage = message; WidgetsBinding.instance.addPostFrameCallback((timeStamp) { _focusNode.requestFocus(); }); @@ -56,7 +57,7 @@ class _StreamThreadPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: StreamChatTheme.of(context).colorTheme.appBg, + backgroundColor: context.streamColorScheme.backgroundApp, appBar: StreamThreadHeader(parent: widget.parent), body: Column( children: [ @@ -66,16 +67,18 @@ class _StreamThreadPageState extends State { initialScrollIndex: widget.initialScrollIndex, initialAlignment: widget.initialAlignment, onReplyTap: _reply, - swipeToReply: true, - showScrollToBottom: false, - highlightInitialMessage: true, + config: const StreamMessageListViewConfiguration( + swipeToReply: true, + showScrollToBottom: false, + highlightInitialMessage: true, + ), onViewInChannelTap: widget.onViewInChannelTap, ), ), if (widget.parent.type != 'deleted') StreamMessageComposer( focusNode: _focusNode, - messageInputController: _messageInputController, + messageComposerController: _messageComposerController, enableVoiceRecording: true, ), ], From 905b8684c3d775e413a4259348b688e238ed6289 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 27 May 2026 11:07:59 +0200 Subject: [PATCH 05/87] Revert "simplify composer setup" This reverts commit 8f3f336471607690ecfc9305af9be1b5ed99aaa3. # Conflicts: # packages/stream_chat_flutter/lib/src/channel/channel_page.dart --- .../lib/src/channel/channel_page.dart | 152 ++++++++++++++---- 1 file changed, 121 insertions(+), 31 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index 01562c7011..19b8ea5648 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -99,38 +99,27 @@ class _StreamChannelPageState extends State { appBar: StreamChannelHeader( onChannelAvatarPressed: widget.onChannelAvatarPressed, ), - extendBody: true, - extendBodyBehindAppBar: true, - bottomNavigationBar: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - alignment: Alignment.centerLeft, - color: context.streamColorScheme.backgroundApp.withOpacity(.9), - child: typingIndicator, + body: _FloatingChannelBody( + composer: composer, + typingIndicator: Container( + alignment: Alignment.centerLeft, + color: context.streamColorScheme.backgroundApp.withOpacity(.9), + child: typingIndicator, + ), + messageListBuilder: (bottomWidgetsHeight) => StreamMessageListView( + initialScrollIndex: widget.initialScrollIndex, + initialAlignment: widget.initialAlignment, + config: StreamMessageListViewConfiguration( + highlightInitialMessage: widget.highlightInitialMessage, + swipeToReply: true, ), - composer, - ], - ), - body: Builder( - builder: (context) { - final insets = MediaQuery.of(context).padding; - return StreamMessageListView( - initialScrollIndex: widget.initialScrollIndex, - initialAlignment: widget.initialAlignment, - config: StreamMessageListViewConfiguration( - highlightInitialMessage: widget.highlightInitialMessage, - swipeToReply: true, - ), - onEditMessageTap: _editMessage, - onReplyTap: _reply, - threadBuilder: (_, parentMessage) { - return StreamThreadPage(parent: parentMessage!); - }, - topPadding: insets.top, - bottomPadding: insets.bottom, - ); - }, + onEditMessageTap: _editMessage, + onReplyTap: _reply, + threadBuilder: (_, parentMessage) { + return StreamThreadPage(parent: parentMessage!); + }, + bottomPadding: bottomWidgetsHeight, + ), ), ); } @@ -177,3 +166,104 @@ class _StreamChannelPageState extends State { ); } } + +// --------------------------------------------------------------------------- +// Floating layout helpers +// --------------------------------------------------------------------------- + +/// Layout slot identifiers for [_FloatingChannelBodyDelegate]. +enum _Slot { body, typing, composer } + +/// A custom [BoxConstraints] subclass that carries the composer height so that +/// a [LayoutBuilder] inside the body slot can read it without a separate +/// callback or [setState]. +/// +/// The [==] / [hashCode] overrides are intentional: they make the framework +/// re-run [RenderObject.performLayout] on the body child even when the outer +/// size constraints have not changed but only [composerHeight] has. +class _BodyBoxConstraints extends BoxConstraints { + const _BodyBoxConstraints({ + super.maxWidth, + super.maxHeight, + required this.composerHeight, + }) : assert(composerHeight >= 0, 'composerHeight must be non-negative'); + + /// Height of the floating composer, used as the list's bottom inset. + final double composerHeight; + + @override + bool operator ==(Object other) { + if (super != other) return false; + return other is _BodyBoxConstraints && other.composerHeight == composerHeight; + } + + @override + int get hashCode => Object.hash(super.hashCode, composerHeight); +} + +/// [MultiChildLayoutDelegate] that measures the composer first, then lays out +/// the typing indicator and body in the same layout pass — no post-frame +/// callback required. +class _FloatingChannelBodyDelegate extends MultiChildLayoutDelegate { + @override + void performLayout(Size size) { + // 1. Measure + position the composer at the bottom. + final composerSize = layoutChild(_Slot.composer, BoxConstraints.loose(size)); + positionChild(_Slot.composer, Offset(0, size.height - composerSize.height)); + + // 2. Measure + position the typing indicator just above the composer. + final typingSize = layoutChild(_Slot.typing, BoxConstraints(maxWidth: size.width)); + positionChild(_Slot.typing, Offset(0, size.height - composerSize.height - typingSize.height)); + + // 3. Lay out the body with the composer height embedded in the constraints + // so the LayoutBuilder inside can read it synchronously. + layoutChild( + _Slot.body, + _BodyBoxConstraints( + maxWidth: size.width, + maxHeight: size.height, + composerHeight: composerSize.height, + ), + ); + positionChild(_Slot.body, Offset.zero); + } + + @override + bool shouldRelayout(_FloatingChannelBodyDelegate oldDelegate) => false; +} + +/// Stateless widget that wires the floating layout together. +class _FloatingChannelBody extends StatelessWidget { + const _FloatingChannelBody({ + required this.composer, + required this.typingIndicator, + required this.messageListBuilder, + }); + + final Widget composer; + final Widget typingIndicator; + + /// Called with the current composer height so the list can set its inset. + final Widget Function(double bottomWidgetsHeight) messageListBuilder; + + @override + Widget build(BuildContext context) { + return CustomMultiChildLayout( + delegate: _FloatingChannelBodyDelegate(), + children: [ + // Body slot: a LayoutBuilder that reads the custom constraints. + LayoutId( + id: _Slot.body, + child: LayoutBuilder( + builder: (context, constraints) { + final height = constraints is _BodyBoxConstraints ? constraints.composerHeight : 0.0; + return messageListBuilder(height); + }, + ), + ), + LayoutId(id: _Slot.typing, child: typingIndicator), + LayoutId(id: _Slot.composer, child: composer), + ], + ); + } +} From bb28a92c8736f85c70dc76df22b7b600244b2ab3 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 27 May 2026 11:47:38 +0200 Subject: [PATCH 06/87] fix avatar press --- .../lib/src/channel/channel_page.dart | 7 +++--- sample_app/lib/routes/app_routes.dart | 25 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index 19b8ea5648..3befad17c3 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -30,7 +30,7 @@ class StreamChannelPage extends StatefulWidget { final VoidCallback? onBackPressed; /// Called when the default channel-avatar trailing is pressed. - final void Function(Channel channel)? onChannelAvatarPressed; + final void Function(BuildContext context, Channel channel)? onChannelAvatarPressed; /// Whether the composer floats over the message list. /// @@ -97,8 +97,9 @@ class _StreamChannelPageState extends State { return Scaffold( backgroundColor: context.streamColorScheme.backgroundApp, appBar: StreamChannelHeader( - onChannelAvatarPressed: widget.onChannelAvatarPressed, + onChannelAvatarPressed: (channel) => widget.onChannelAvatarPressed?.call(context, channel), ), + extendBodyBehindAppBar: false, body: _FloatingChannelBody( composer: composer, typingIndicator: Container( @@ -127,7 +128,7 @@ class _StreamChannelPageState extends State { return Scaffold( backgroundColor: context.streamColorScheme.backgroundApp, appBar: StreamChannelHeader( - onChannelAvatarPressed: widget.onChannelAvatarPressed, + onChannelAvatarPressed: (channel) => widget.onChannelAvatarPressed?.call(context, channel), ), body: Column( children: [ diff --git a/sample_app/lib/routes/app_routes.dart b/sample_app/lib/routes/app_routes.dart index 3cae1e3392..2e9e2029ff 100644 --- a/sample_app/lib/routes/app_routes.dart +++ b/sample_app/lib/routes/app_routes.dart @@ -49,6 +49,31 @@ final appRoutes = [ : StreamChannelPage( highlightInitialMessage: messageId != null, isFloating: true, + onChannelAvatarPressed: (context, channel) { + final isOneToOne = channel.isOneToOne; + final currentUserId = StreamChat.of(context).currentUser?.id; + + final channelMembers = channel.state?.members ?? []; + final otherUser = isOneToOne + ? channelMembers.firstWhere((m) => m.userId != currentUserId).user + : null; + + final router = GoRouter.of(context); + + if (otherUser != null) { + router.pushNamed( + Routes.CHAT_INFO_SCREEN.name, + pathParameters: Routes.CHAT_INFO_SCREEN.params(channel), + extra: otherUser, + ); + return; + } + + router.pushNamed( + Routes.GROUP_INFO_SCREEN.name, + pathParameters: Routes.GROUP_INFO_SCREEN.params(channel), + ); + }, ); }, ), From c6b4840e34bd012fa7d5fc0c8c036cf86263fd01 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 27 May 2026 13:53:40 +0200 Subject: [PATCH 07/87] fix composer safeArea --- .../lib/src/message_input/stream_message_composer.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index c59327dcb9..9c18fad145 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -806,7 +806,6 @@ class DefaultStreamMessageComposerState extends State Date: Wed, 27 May 2026 14:04:03 +0200 Subject: [PATCH 08/87] Add floating header --- .../lib/src/channel/channel_header.dart | 7 +- .../lib/src/channel/channel_page.dart | 88 +++++++------------ .../lib/src/misc/back_button.dart | 7 +- 3 files changed, 46 insertions(+), 56 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index 3d1fb1e3e5..5e0c6bfd0a 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -81,6 +81,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget this.trailing, this.primary = true, this.style, + this.floating = false, }); /// Called when the default channel-avatar trailing is pressed. @@ -129,6 +130,9 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget /// [StreamChatThemeData.channelHeaderTheme]. final StreamAppBarStyle? style; + /// Whether the header is floating. + final bool floating; + @override Size get preferredSize => const Size.fromHeight(kStreamToolbarHeight); @@ -139,7 +143,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget var leading = this.leading; if (leading == null && automaticallyImplyLeading) { - leading = const StreamBackButton(showUnreadCount: true); + leading = StreamBackButton(showUnreadCount: true, floating: floating); } var title = this.title; @@ -187,6 +191,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget trailing: trailing, primary: primary, style: style, + floating: floating, ), ), ); diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index 3befad17c3..f9dc58a029 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -93,70 +93,43 @@ class _StreamChannelPageState extends State { isFloating: widget.isFloating, ); - if (widget.isFloating) { - return Scaffold( - backgroundColor: context.streamColorScheme.backgroundApp, - appBar: StreamChannelHeader( - onChannelAvatarPressed: (channel) => widget.onChannelAvatarPressed?.call(context, channel), - ), - extendBodyBehindAppBar: false, - body: _FloatingChannelBody( - composer: composer, - typingIndicator: Container( - alignment: Alignment.centerLeft, - color: context.streamColorScheme.backgroundApp.withOpacity(.9), - child: typingIndicator, - ), - messageListBuilder: (bottomWidgetsHeight) => StreamMessageListView( - initialScrollIndex: widget.initialScrollIndex, - initialAlignment: widget.initialAlignment, - config: StreamMessageListViewConfiguration( - highlightInitialMessage: widget.highlightInitialMessage, - swipeToReply: true, - ), - onEditMessageTap: _editMessage, - onReplyTap: _reply, - threadBuilder: (_, parentMessage) { - return StreamThreadPage(parent: parentMessage!); - }, - bottomPadding: bottomWidgetsHeight, - ), - ), - ); - } + final appBar = StreamChannelHeader( + onChannelAvatarPressed: (channel) => widget.onChannelAvatarPressed?.call(context, channel), + floating: widget.isFloating, + ); - return Scaffold( - backgroundColor: context.streamColorScheme.backgroundApp, - appBar: StreamChannelHeader( - onChannelAvatarPressed: (channel) => widget.onChannelAvatarPressed?.call(context, channel), + StreamMessageListView messageListBuilder(double bottomPadding) => StreamMessageListView( + initialScrollIndex: widget.initialScrollIndex, + initialAlignment: widget.initialAlignment, + config: StreamMessageListViewConfiguration( + highlightInitialMessage: widget.highlightInitialMessage, + swipeToReply: true, + ), + onEditMessageTap: _editMessage, + onReplyTap: _reply, + threadBuilder: (_, parentMessage) { + return StreamThreadPage(parent: parentMessage!); + }, + bottomPadding: bottomPadding, + ); + + final body = switch (widget.isFloating) { + true => _FloatingChannelBody( + composer: composer, + typingIndicator: typingIndicator, + messageListBuilder: messageListBuilder, ), - body: Column( + false => Column( children: [ Expanded( child: Stack( children: [ - StreamMessageListView( - initialScrollIndex: widget.initialScrollIndex, - initialAlignment: widget.initialAlignment, - config: StreamMessageListViewConfiguration( - highlightInitialMessage: widget.highlightInitialMessage, - swipeToReply: true, - ), - onEditMessageTap: _editMessage, - onReplyTap: _reply, - threadBuilder: (_, parentMessage) { - return StreamThreadPage(parent: parentMessage!); - }, - ), + messageListBuilder(0), Positioned( bottom: 0, left: 0, right: 0, - child: Container( - alignment: Alignment.centerLeft, - color: context.streamColorScheme.backgroundApp.withOpacity(.9), - child: typingIndicator, - ), + child: typingIndicator, ), ], ), @@ -164,6 +137,13 @@ class _StreamChannelPageState extends State { composer, ], ), + }; + + return Scaffold( + backgroundColor: context.streamColorScheme.backgroundApp, + appBar: appBar, + extendBodyBehindAppBar: widget.isFloating, + body: body, ); } } diff --git a/packages/stream_chat_flutter/lib/src/misc/back_button.dart b/packages/stream_chat_flutter/lib/src/misc/back_button.dart index 7b440227e2..2910fc903e 100644 --- a/packages/stream_chat_flutter/lib/src/misc/back_button.dart +++ b/packages/stream_chat_flutter/lib/src/misc/back_button.dart @@ -11,6 +11,7 @@ class StreamBackButton extends StatelessWidget { this.onPressed, this.showUnreadCount = false, this.channelId, + this.floating = false, }); /// Callback for when button is pressed @@ -22,6 +23,9 @@ class StreamBackButton extends StatelessWidget { /// Channel ID used to retrieve unread count final String? channelId; + /// Whether the back button is floating. + final bool floating; + @override Widget build(BuildContext context) { final iconData = switch (Theme.of(context).platform) { @@ -30,7 +34,8 @@ class StreamBackButton extends StatelessWidget { }; Widget button = StreamButton.icon( - type: .ghost, + type: floating ? .outline : .ghost, + isFloating: floating, size: .medium, style: .secondary, icon: Icon(iconData), From 66af71247da87628da905dc2ffa2be32ff93634d Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 27 May 2026 14:57:23 +0200 Subject: [PATCH 09/87] Cleanup sample app --- .../lib/src/channel/channel_page.dart | 2 +- .../lib/stream_chat_flutter.dart | 1 + sample_app/lib/pages/channel_page.dart | 209 ------------------ sample_app/lib/pages/draft_list_page.dart | 6 +- sample_app/lib/pages/thread_list_page.dart | 3 +- sample_app/lib/pages/thread_page.dart | 86 ------- sample_app/lib/routes/app_routes.dart | 6 +- 7 files changed, 7 insertions(+), 306 deletions(-) delete mode 100644 sample_app/lib/pages/channel_page.dart delete mode 100644 sample_app/lib/pages/thread_page.dart diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index f9dc58a029..7a1fcaf18b 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -14,7 +14,7 @@ class StreamChannelPage extends StatefulWidget { this.highlightInitialMessage = false, this.onBackPressed, this.onChannelAvatarPressed, - this.isFloating = true, + this.isFloating = false, }); /// Initial scroll index for the message list. diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index de2b6ac64d..a3184b341f 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -172,6 +172,7 @@ export 'src/channel/channel_page.dart'; export 'src/channel/stream_channel_name.dart'; export 'src/channel/stream_draft_message_preview_text.dart'; export 'src/channel/stream_message_preview_text.dart'; +export 'src/channel/thread_page.dart'; // region SDK Design Refresh Components export 'src/components/avatar/stream_channel_avatar.dart'; export 'src/components/avatar/stream_user_avatar.dart'; diff --git a/sample_app/lib/pages/channel_page.dart b/sample_app/lib/pages/channel_page.dart deleted file mode 100644 index b04d751638..0000000000 --- a/sample_app/lib/pages/channel_page.dart +++ /dev/null @@ -1,209 +0,0 @@ -// ignore_for_file: deprecated_member_use, avoid_redundant_argument_values - -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:sample_app/config/sample_app_config.dart'; -import 'package:sample_app/pages/thread_page.dart'; -import 'package:sample_app/routes/routes.dart'; -import 'package:sample_app/widgets/location/location_picker_dialog.dart'; -import 'package:sample_app/widgets/location/location_picker_option.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -class ChannelPage extends StatefulWidget { - const ChannelPage({ - super.key, - this.initialScrollIndex, - this.initialAlignment, - this.highlightInitialMessage = false, - }); - final int? initialScrollIndex; - final double? initialAlignment; - final bool highlightInitialMessage; - - @override - State createState() => _ChannelPageState(); -} - -class _ChannelPageState extends State { - FocusNode? _focusNode; - final _messageComposerController = StreamMessageComposerController(); - - @override - void initState() { - _focusNode = FocusNode(); - super.initState(); - } - - @override - void dispose() { - _focusNode!.dispose(); - _messageComposerController.dispose(); - super.dispose(); - } - - void _reply(Message message) { - _messageComposerController.quotedMessage = message; - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - _focusNode!.requestFocus(); - }); - } - - void _editMessage(Message message) { - _messageComposerController.editMessage(message); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - _focusNode!.requestFocus(); - }); - } - - @override - Widget build(BuildContext context) { - final channel = StreamChannel.of(context).channel; - final config = channel.config; - - return Scaffold( - backgroundColor: context.streamColorScheme.backgroundApp, - appBar: StreamChannelHeader( - onChannelAvatarPressed: (channel) { - final isOneToOne = channel.isOneToOne; - final currentUserId = StreamChat.of(context).currentUser?.id; - - final channelMembers = channel.state?.members ?? []; - final otherUser = isOneToOne ? channelMembers.firstWhere((m) => m.userId != currentUserId).user : null; - - _pushChannelInfo(context, channel, otherUser); - }, - ), - body: Column( - children: [ - Expanded( - child: Stack( - children: [ - StreamMessageListView( - initialScrollIndex: widget.initialScrollIndex, - initialAlignment: widget.initialAlignment, - config: StreamMessageListViewConfiguration( - swipeToReply: true, - highlightInitialMessage: widget.highlightInitialMessage, - ), - onEditMessageTap: _editMessage, - onReplyTap: _reply, - threadBuilder: (_, parentMessage) { - return ThreadPage(parent: parentMessage!); - }, - ), - Positioned( - bottom: 0, - left: 0, - right: 0, - child: Container( - alignment: Alignment.centerLeft, - color: context.streamColorScheme.backgroundApp.withOpacity(.9), - child: StreamTypingIndicator( - padding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - style: context.streamTextTheme.captionDefault.copyWith( - color: context.streamColorScheme.textSecondary, - ), - ), - ), - ), - ], - ), - ), - Builder( - builder: (context) { - final appConfig = context.sampleAppConfig; - final locationEnabled = - appConfig.enableLocationSharing && config?.sharedLocations == true && channel.canShareLocation; - - return StreamMessageComposer( - focusNode: _focusNode, - messageComposerController: _messageComposerController, - onQuotedMessageCleared: _messageComposerController.clearQuotedMessage, - enableVoiceRecording: true, - allowedAttachmentPickerTypes: [ - ...AttachmentPickerType.values, - if (locationEnabled) const LocationPickerType(), - ], - onAttachmentPickerResult: (result) { - return _onCustomAttachmentPickerResult(channel, result); - }, - attachmentPickerOptionsBuilder: (context, defaultOptions) => [ - ...defaultOptions, - if (locationEnabled) - TabbedAttachmentPickerOption( - key: 'location-picker', - icon: context.streamIcons.location, - supportedTypes: [const LocationPickerType()], - isEnabled: (value) { - if (value.isEmpty) return true; - return value.extraData['location'] != null; - }, - optionViewBuilder: (context, controller) => LocationPicker( - onLocationPicked: (locationResult) { - if (locationResult == null) return; - - controller.notifyCustomResult( - LocationPicked(location: locationResult), - ); - }, - ), - ), - ], - ); - }, - ), - ], - ), - ); - } - - bool _onCustomAttachmentPickerResult( - Channel channel, - StreamAttachmentPickerResult result, - ) { - if (result is LocationPicked) { - _onShareLocationPicked(channel, result.location).ignore(); - return true; // Notify that the result was handled. - } - - return false; // Notify that the result was not handled. - } - - Future _onShareLocationPicked( - Channel channel, - LocationPickerResult result, - ) async { - if (result.endSharingAt case final endSharingAt?) { - return channel.startLiveLocationSharing( - endSharingAt: endSharingAt, - location: result.coordinates, - ); - } - - return channel.sendStaticLocation(location: result.coordinates); - } -} - -// Pushes the chat / group info screen depending on whether [user] was -// resolved. 1-1 channels pass the other member here (forwarded as `extra` -// to the chat-info route); group channels pass `null` and route to the -// group info screen. -Future _pushChannelInfo(BuildContext context, Channel channel, User? user) { - final router = GoRouter.of(context); - - if (user != null) { - return router.pushNamed( - Routes.CHAT_INFO_SCREEN.name, - pathParameters: Routes.CHAT_INFO_SCREEN.params(channel), - extra: user, - ); - } - - return router.pushNamed( - Routes.GROUP_INFO_SCREEN.name, - pathParameters: Routes.GROUP_INFO_SCREEN.params(channel), - ); -} diff --git a/sample_app/lib/pages/draft_list_page.dart b/sample_app/lib/pages/draft_list_page.dart index e486ac9d05..fa50bf2464 100644 --- a/sample_app/lib/pages/draft_list_page.dart +++ b/sample_app/lib/pages/draft_list_page.dart @@ -1,7 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; -import 'package:sample_app/pages/channel_page.dart'; -import 'package:sample_app/pages/thread_page.dart'; import 'package:sample_app/widgets/stream_draft_list_view.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -71,10 +69,10 @@ class _DraftListPageState extends State { channel: channel, initialMessageId: draft.parentId, child: switch (draft.parentMessage) { - final parent? => ThreadPage( + final parent? => StreamThreadPage( parent: parent.copyWith(draft: draft), ), - _ => const ChannelPage(), + _ => const StreamChannelPage(), }, ); }, diff --git a/sample_app/lib/pages/thread_list_page.dart b/sample_app/lib/pages/thread_list_page.dart index ef0bd215a3..b9cfaf29f8 100644 --- a/sample_app/lib/pages/thread_list_page.dart +++ b/sample_app/lib/pages/thread_list_page.dart @@ -1,7 +1,6 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; -import 'package:sample_app/pages/thread_page.dart'; import 'package:sample_app/routes/routes.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -63,7 +62,7 @@ class _ThreadListPageState extends State { .where((msg) => msg != null) .cast(), builder: (_, parentMessage) { - return ThreadPage( + return StreamThreadPage( parent: parentMessage, onViewInChannelTap: (message) { GoRouter.of(context).goNamed( diff --git a/sample_app/lib/pages/thread_page.dart b/sample_app/lib/pages/thread_page.dart deleted file mode 100644 index f2bd9711e9..0000000000 --- a/sample_app/lib/pages/thread_page.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -class ThreadPage extends StatefulWidget { - const ThreadPage({ - super.key, - required this.parent, - this.initialScrollIndex, - this.initialAlignment, - this.onViewInChannelTap, - }); - final Message parent; - final int? initialScrollIndex; - final double? initialAlignment; - final void Function(Message message)? onViewInChannelTap; - - @override - State createState() => _ThreadPageState(); -} - -class _ThreadPageState extends State { - final FocusNode _focusNode = FocusNode(); - late StreamMessageComposerController _messageComposerController; - - @override - void initState() { - super.initState(); - _messageComposerController = StreamMessageComposerController( - message: Message(parentId: widget.parent.id), - ); - } - - @override - void dispose() { - _focusNode.dispose(); - _messageComposerController.dispose(); - super.dispose(); - } - - void _reply(Message message) { - _messageComposerController.quotedMessage = message; - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - _focusNode.requestFocus(); - }); - } - - void _editMessage(Message message) { - _messageComposerController.editMessage(message); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - _focusNode.requestFocus(); - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: context.streamColorScheme.backgroundApp, - appBar: StreamThreadHeader(parent: widget.parent), - body: Column( - children: [ - Expanded( - child: StreamMessageListView( - parentMessage: widget.parent, - initialScrollIndex: widget.initialScrollIndex, - initialAlignment: widget.initialAlignment, - onReplyTap: _reply, - onEditMessageTap: _editMessage, - config: const StreamMessageListViewConfiguration( - swipeToReply: true, - showScrollToBottom: false, - highlightInitialMessage: true, - ), - onViewInChannelTap: widget.onViewInChannelTap, - ), - ), - if (widget.parent.type != 'deleted') - StreamMessageComposer( - focusNode: _focusNode, - messageComposerController: _messageComposerController, - enableVoiceRecording: true, - ), - ], - ), - ); - } -} diff --git a/sample_app/lib/routes/app_routes.dart b/sample_app/lib/routes/app_routes.dart index 2e9e2029ff..13ad07a72a 100644 --- a/sample_app/lib/routes/app_routes.dart +++ b/sample_app/lib/routes/app_routes.dart @@ -3,14 +3,12 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/pages/advanced_options_page.dart'; import 'package:sample_app/pages/channel_list_page.dart'; -import 'package:sample_app/pages/channel_page.dart'; import 'package:sample_app/pages/chat_info_screen.dart'; import 'package:sample_app/pages/choose_user_page.dart'; import 'package:sample_app/pages/group_chat_details_screen.dart'; import 'package:sample_app/pages/group_info_screen.dart'; import 'package:sample_app/pages/new_chat_screen.dart'; import 'package:sample_app/pages/new_group_chat_screen.dart'; -import 'package:sample_app/pages/thread_page.dart'; import 'package:sample_app/routes/routes.dart'; import 'package:sample_app/state/new_group_chat_state.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -45,10 +43,10 @@ final appRoutes = [ child: Builder( builder: (context) { return (parentMessage != null) - ? ThreadPage(parent: parentMessage) + ? StreamThreadPage(parent: parentMessage) : StreamChannelPage( highlightInitialMessage: messageId != null, - isFloating: true, + isFloating: false, onChannelAvatarPressed: (context, channel) { final isOneToOne = channel.isOneToOne; final currentUserId = StreamChat.of(context).currentUser?.id; From 2c156b21e66b85ce5aa51a2d65f7d99a686f0da5 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 27 May 2026 15:55:53 +0200 Subject: [PATCH 10/87] Fix topPadding on listview --- .../stream_chat_flutter/lib/src/channel/channel_page.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index 7a1fcaf18b..bec5116152 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -1,7 +1,6 @@ // ignore_for_file: deprecated_member_use, avoid_redundant_argument_values import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/channel/thread_page.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// A channel page with optional floating composer support. @@ -98,6 +97,8 @@ class _StreamChannelPageState extends State { floating: widget.isFloating, ); + final topPadding = widget.isFloating ? appBar.preferredSize.height + MediaQuery.of(context).padding.top : 0.0; + StreamMessageListView messageListBuilder(double bottomPadding) => StreamMessageListView( initialScrollIndex: widget.initialScrollIndex, initialAlignment: widget.initialAlignment, @@ -110,6 +111,7 @@ class _StreamChannelPageState extends State { threadBuilder: (_, parentMessage) { return StreamThreadPage(parent: parentMessage!); }, + topPadding: topPadding, bottomPadding: bottomPadding, ); From d42cc51365c41af78c48adc4267450135139ba52 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 27 May 2026 16:07:09 +0200 Subject: [PATCH 11/87] Fix attachment picker padding --- .../lib/src/scroll_view/photo_gallery/stream_photo_gallery.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/scroll_view/photo_gallery/stream_photo_gallery.dart b/packages/stream_chat_flutter/lib/src/scroll_view/photo_gallery/stream_photo_gallery.dart index 1b224a1726..f18f1e479f 100644 --- a/packages/stream_chat_flutter/lib/src/scroll_view/photo_gallery/stream_photo_gallery.dart +++ b/packages/stream_chat_flutter/lib/src/scroll_view/photo_gallery/stream_photo_gallery.dart @@ -321,7 +321,7 @@ class StreamPhotoGallery extends StatelessWidget { primary: primary, physics: physics, shrinkWrap: shrinkWrap, - padding: padding, + padding: padding ?? EdgeInsets.only(top: 0, bottom: MediaQuery.paddingOf(context).bottom), scrollController: scrollController, addAutomaticKeepAlives: addAutomaticKeepAlives, addRepaintBoundaries: addRepaintBoundaries, From 68f1ed060315b4c9159c0302636c0463e993ccea Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 28 May 2026 15:21:10 +0200 Subject: [PATCH 12/87] Using theming for floating config --- .../lib/src/channel/channel_header.dart | 10 ++++---- .../lib/src/channel/channel_page.dart | 18 ++++----------- .../stream_message_composer.dart | 23 +++++++++++++------ sample_app/lib/routes/app_routes.dart | 1 - 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index 5e0c6bfd0a..7968d91747 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; +import 'package:stream_core_flutter/stream_core_flutter.dart'; /// {@template streamChannelHeader} /// A top-of-screen header for a single channel. @@ -81,7 +82,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget this.trailing, this.primary = true, this.style, - this.floating = false, + this.appBarBehavior, }); /// Called when the default channel-avatar trailing is pressed. @@ -131,7 +132,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget final StreamAppBarStyle? style; /// Whether the header is floating. - final bool floating; + final AppBarBehavior? appBarBehavior; @override Size get preferredSize => const Size.fromHeight(kStreamToolbarHeight); @@ -143,7 +144,8 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget var leading = this.leading; if (leading == null && automaticallyImplyLeading) { - leading = StreamBackButton(showUnreadCount: true, floating: floating); + final effectiveAppBarBehavior = appBarBehavior ?? StreamTheme.of(context).appStyle.appBarBehavior; + leading = StreamBackButton(showUnreadCount: true, floating: effectiveAppBarBehavior == .floating); } var title = this.title; @@ -191,7 +193,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget trailing: trailing, primary: primary, style: style, - floating: floating, + appBarBehavior: appBarBehavior, ), ), ); diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index bec5116152..c6f438e1d5 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -13,7 +13,6 @@ class StreamChannelPage extends StatefulWidget { this.highlightInitialMessage = false, this.onBackPressed, this.onChannelAvatarPressed, - this.isFloating = false, }); /// Initial scroll index for the message list. @@ -31,13 +30,6 @@ class StreamChannelPage extends StatefulWidget { /// Called when the default channel-avatar trailing is pressed. final void Function(BuildContext context, Channel channel)? onChannelAvatarPressed; - /// Whether the composer floats over the message list. - /// - /// When true the composer is overlaid at the bottom and the message list - /// scrolls underneath it. Layout is done in a single pass so the list - /// inset and the composer height are always in sync. - final bool isFloating; - @override State createState() => _StreamChannelPageState(); } @@ -89,15 +81,15 @@ class _StreamChannelPageState extends State { messageComposerController: _messageComposerController, onQuotedMessageCleared: _messageComposerController.clearQuotedMessage, enableVoiceRecording: true, - isFloating: widget.isFloating, ); + final isFloating = StreamTheme.of(context).appStyle.appBarBehavior == .floating; + final appBar = StreamChannelHeader( onChannelAvatarPressed: (channel) => widget.onChannelAvatarPressed?.call(context, channel), - floating: widget.isFloating, ); - final topPadding = widget.isFloating ? appBar.preferredSize.height + MediaQuery.of(context).padding.top : 0.0; + final topPadding = isFloating ? appBar.preferredSize.height + MediaQuery.of(context).padding.top : 0.0; StreamMessageListView messageListBuilder(double bottomPadding) => StreamMessageListView( initialScrollIndex: widget.initialScrollIndex, @@ -115,7 +107,7 @@ class _StreamChannelPageState extends State { bottomPadding: bottomPadding, ); - final body = switch (widget.isFloating) { + final body = switch (isFloating) { true => _FloatingChannelBody( composer: composer, typingIndicator: typingIndicator, @@ -144,7 +136,7 @@ class _StreamChannelPageState extends State { return Scaffold( backgroundColor: context.streamColorScheme.backgroundApp, appBar: appBar, - extendBodyBehindAppBar: widget.isFloating, + extendBodyBehindAppBar: isFloating, body: body, ); } diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 9c18fad145..c8428f1e9a 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -7,6 +7,7 @@ import 'package:flutter/services.dart'; import 'package:stream_chat_flutter/src/message_input/error_alert_sheet.dart'; import 'package:stream_chat_flutter/src/message_input/stream_chat_message_input.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; +import 'package:stream_core_flutter/stream_core_flutter.dart'; const _kCommandTrigger = '/'; const _kMentionTrigger = '@'; @@ -95,7 +96,7 @@ class StreamMessageComposer extends StatelessWidget { TextCapitalization textCapitalization = TextCapitalization.sentences, bool autofocus = false, bool autoCorrect = true, - bool isFloating = false, + ComposerLocation? composerLocation, }) : props = .new( onMessageSent: onMessageSent, preMessageSending: preMessageSending, @@ -131,7 +132,7 @@ class StreamMessageComposer extends StatelessWidget { textCapitalization: textCapitalization, autofocus: autofocus, autoCorrect: autoCorrect, - isFloating: isFloating, + composerLocation: composerLocation, ); /// Creates a [StreamMessageComposer] from a pre-built [MessageComposerProps]. @@ -192,7 +193,7 @@ class MessageComposerProps { this.textCapitalization = TextCapitalization.sentences, this.autofocus = false, this.autoCorrect = true, - this.isFloating = false, + this.composerLocation, }); /// Function called after sending the message. @@ -387,8 +388,8 @@ class MessageComposerProps { /// Defaults to true. final bool autoCorrect; - /// Whether the message composer is floating. - final bool isFloating; + /// The location of the message composer. + final ComposerLocation? composerLocation; /// Returns a copy of this [MessageComposerProps] with the given fields /// replaced with new values. MessageComposerProps copyWith({ @@ -793,11 +794,17 @@ class DefaultStreamMessageComposerState extends State null, + .docked => context.streamColorScheme.backgroundElevation1, + }, ), child: AnimatedBuilder( animation: _pickerAnimation, @@ -884,6 +891,8 @@ class DefaultStreamMessageComposerState extends State Date: Thu, 28 May 2026 16:46:59 +0200 Subject: [PATCH 13/87] improve using default floatings from theme --- .../lib/src/channel/channel_header.dart | 3 +-- .../lib/src/channel/thread_page.dart | 7 ++++++- .../lib/src/misc/back_button.dart | 12 ++++++++---- .../stream_chat_flutter/lib/stream_chat_flutter.dart | 3 +++ sample_app/lib/app.dart | 12 ++++++++++-- 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index 7968d91747..ccc4cfb49d 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -144,8 +144,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget var leading = this.leading; if (leading == null && automaticallyImplyLeading) { - final effectiveAppBarBehavior = appBarBehavior ?? StreamTheme.of(context).appStyle.appBarBehavior; - leading = StreamBackButton(showUnreadCount: true, floating: effectiveAppBarBehavior == .floating); + leading = StreamBackButton(showUnreadCount: true, appBarBehavior: appBarBehavior); } var title = this.title; diff --git a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart index ead1d8f08c..fcb1777ebe 100644 --- a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart @@ -56,9 +56,13 @@ class _StreamThreadPageState extends State { @override Widget build(BuildContext context) { + final appBar = StreamThreadHeader(parent: widget.parent); + final isFloating = StreamTheme.of(context).appStyle.appBarBehavior == .floating; + return Scaffold( backgroundColor: context.streamColorScheme.backgroundApp, - appBar: StreamThreadHeader(parent: widget.parent), + appBar: appBar, + extendBodyBehindAppBar: isFloating, body: Column( children: [ Expanded( @@ -73,6 +77,7 @@ class _StreamThreadPageState extends State { highlightInitialMessage: true, ), onViewInChannelTap: widget.onViewInChannelTap, + topPadding: isFloating ? appBar.preferredSize.height + MediaQuery.of(context).padding.top : 0.0, ), ), if (widget.parent.type != 'deleted') diff --git a/packages/stream_chat_flutter/lib/src/misc/back_button.dart b/packages/stream_chat_flutter/lib/src/misc/back_button.dart index 2910fc903e..a649ccdcb1 100644 --- a/packages/stream_chat_flutter/lib/src/misc/back_button.dart +++ b/packages/stream_chat_flutter/lib/src/misc/back_button.dart @@ -11,7 +11,7 @@ class StreamBackButton extends StatelessWidget { this.onPressed, this.showUnreadCount = false, this.channelId, - this.floating = false, + this.appBarBehavior, }); /// Callback for when button is pressed @@ -24,7 +24,7 @@ class StreamBackButton extends StatelessWidget { final String? channelId; /// Whether the back button is floating. - final bool floating; + final AppBarBehavior? appBarBehavior; @override Widget build(BuildContext context) { @@ -32,10 +32,14 @@ class StreamBackButton extends StatelessWidget { .iOS || .macOS => context.streamIcons.chevronLeft, _ => context.streamIcons.arrowLeft, }; + final isFloating = switch (appBarBehavior ?? StreamTheme.of(context).appStyle.appBarBehavior) { + .floating => true, + .regular => false, + }; Widget button = StreamButton.icon( - type: floating ? .outline : .ghost, - isFloating: floating, + type: isFloating ? .outline : .ghost, + isFloating: isFloating, size: .medium, style: .secondary, icon: Icon(iconData), diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index a3184b341f..b58f5d6371 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -3,6 +3,9 @@ export 'package:photo_manager/photo_manager.dart' show ThumbnailSize, ThumbnailF export 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; export 'package:stream_core_flutter/stream_core_flutter.dart' show + StreamAppStyle, + ComposerLocation, + AppBarBehavior, StreamAppBar, StreamAppBarProps, StreamAppBarStyle, diff --git a/sample_app/lib/app.dart b/sample_app/lib/app.dart index ba2fc8c5d8..de507c91e6 100644 --- a/sample_app/lib/app.dart +++ b/sample_app/lib/app.dart @@ -173,11 +173,19 @@ class _StreamChatSampleAppState extends State return MaterialApp.router( theme: ThemeData( brightness: .light, - extensions: [StreamTheme.light()], + extensions: [ + StreamTheme.light().copyWith( + appStyle: const StreamAppStyle.floating(), + ), + ], ), darkTheme: ThemeData( brightness: .dark, - extensions: [StreamTheme.dark()], + extensions: [ + StreamTheme.dark().copyWith( + appStyle: const StreamAppStyle.floating(), + ), + ], ), themeMode: config.themeMode, locale: config.locale, From 558f07376a1b8203ddacf45fc65d499c7eb3bb66 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 29 May 2026 09:21:45 +0200 Subject: [PATCH 14/87] Use streamscaffold --- .../lib/src/channel/channel_page.dart | 203 +++++------------ .../lib/src/channel/thread_page.dart | 79 ++++--- .../lib/stream_chat_flutter.dart | 3 + sample_app/lib/pages/channel_list_page.dart | 205 +++++++++++++++--- sample_app/lib/widgets/channel_list.dart | 24 +- 5 files changed, 305 insertions(+), 209 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index c6f438e1d5..48e21105f4 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -1,5 +1,3 @@ -// ignore_for_file: deprecated_member_use, avoid_redundant_argument_values - import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -66,14 +64,8 @@ class _StreamChannelPageState extends State { @override Widget build(BuildContext context) { - final typingIndicator = StreamTypingIndicator( - padding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - style: context.streamTextTheme.captionDefault.copyWith( - color: context.streamColorScheme.textSecondary, - ), + final appBar = StreamChannelHeader( + onChannelAvatarPressed: (channel) => widget.onChannelAvatarPressed?.call(context, channel), ); final composer = StreamMessageComposer( @@ -83,161 +75,82 @@ class _StreamChannelPageState extends State { enableVoiceRecording: true, ); - final isFloating = StreamTheme.of(context).appStyle.appBarBehavior == .floating; - - final appBar = StreamChannelHeader( - onChannelAvatarPressed: (channel) => widget.onChannelAvatarPressed?.call(context, channel), - ); - - final topPadding = isFloating ? appBar.preferredSize.height + MediaQuery.of(context).padding.top : 0.0; - - StreamMessageListView messageListBuilder(double bottomPadding) => StreamMessageListView( - initialScrollIndex: widget.initialScrollIndex, - initialAlignment: widget.initialAlignment, - config: StreamMessageListViewConfiguration( - highlightInitialMessage: widget.highlightInitialMessage, - swipeToReply: true, - ), - onEditMessageTap: _editMessage, - onReplyTap: _reply, - threadBuilder: (_, parentMessage) { - return StreamThreadPage(parent: parentMessage!); - }, - topPadding: topPadding, - bottomPadding: bottomPadding, - ); - - final body = switch (isFloating) { - true => _FloatingChannelBody( - composer: composer, - typingIndicator: typingIndicator, - messageListBuilder: messageListBuilder, + final typingIndicator = StreamTypingIndicator( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, ), - false => Column( - children: [ - Expanded( - child: Stack( - children: [ - messageListBuilder(0), - Positioned( - bottom: 0, - left: 0, - right: 0, - child: typingIndicator, - ), - ], - ), - ), - composer, - ], + style: context.streamTextTheme.captionDefault.copyWith( + color: context.streamColorScheme.textSecondary, ), - }; + ); - return Scaffold( + return StreamScaffold( backgroundColor: context.streamColorScheme.backgroundApp, appBar: appBar, - extendBodyBehindAppBar: isFloating, - body: body, - ); - } -} - -// --------------------------------------------------------------------------- -// Floating layout helpers -// --------------------------------------------------------------------------- - -/// Layout slot identifiers for [_FloatingChannelBodyDelegate]. -enum _Slot { body, typing, composer } - -/// A custom [BoxConstraints] subclass that carries the composer height so that -/// a [LayoutBuilder] inside the body slot can read it without a separate -/// callback or [setState]. -/// -/// The [==] / [hashCode] overrides are intentional: they make the framework -/// re-run [RenderObject.performLayout] on the body child even when the outer -/// size constraints have not changed but only [composerHeight] has. -class _BodyBoxConstraints extends BoxConstraints { - const _BodyBoxConstraints({ - super.maxWidth, - super.maxHeight, - required this.composerHeight, - }) : assert(composerHeight >= 0, 'composerHeight must be non-negative'); - - /// Height of the floating composer, used as the list's bottom inset. - final double composerHeight; - - @override - bool operator ==(Object other) { - if (super != other) return false; - return other is _BodyBoxConstraints && other.composerHeight == composerHeight; - } - - @override - int get hashCode => Object.hash(super.hashCode, composerHeight); -} - -/// [MultiChildLayoutDelegate] that measures the composer first, then lays out -/// the typing indicator and body in the same layout pass — no post-frame -/// callback required. -class _FloatingChannelBodyDelegate extends MultiChildLayoutDelegate { - @override - void performLayout(Size size) { - // 1. Measure + position the composer at the bottom. - final composerSize = layoutChild(_Slot.composer, BoxConstraints.loose(size)); - positionChild(_Slot.composer, Offset(0, size.height - composerSize.height)); - - // 2. Measure + position the typing indicator just above the composer. - final typingSize = layoutChild(_Slot.typing, BoxConstraints(maxWidth: size.width)); - positionChild(_Slot.typing, Offset(0, size.height - composerSize.height - typingSize.height)); - - // 3. Lay out the body with the composer height embedded in the constraints - // so the LayoutBuilder inside can read it synchronously. - layoutChild( - _Slot.body, - _BodyBoxConstraints( - maxWidth: size.width, - maxHeight: size.height, - composerHeight: composerSize.height, + bottom: composer, + body: _ChannelPageBody( + initialScrollIndex: widget.initialScrollIndex, + initialAlignment: widget.initialAlignment, + highlightInitialMessage: widget.highlightInitialMessage, + onReply: _reply, + onEditMessage: _editMessage, + typingIndicator: typingIndicator, ), ); - positionChild(_Slot.body, Offset.zero); } - - @override - bool shouldRelayout(_FloatingChannelBodyDelegate oldDelegate) => false; } -/// Stateless widget that wires the floating layout together. -class _FloatingChannelBody extends StatelessWidget { - const _FloatingChannelBody({ - required this.composer, +/// The body of [StreamChannelPage]. +/// +/// Reads [StreamScaffoldInsets] to provide correct [topPadding] and +/// [bottomPadding] to [StreamMessageListView], and positions the typing +/// indicator just above the composer (floating or docked) using the same +/// inset values. +class _ChannelPageBody extends StatelessWidget { + const _ChannelPageBody({ required this.typingIndicator, - required this.messageListBuilder, + required this.onReply, + required this.onEditMessage, + this.initialScrollIndex, + this.initialAlignment, + this.highlightInitialMessage = false, }); - final Widget composer; final Widget typingIndicator; - - /// Called with the current composer height so the list can set its inset. - final Widget Function(double bottomWidgetsHeight) messageListBuilder; + final void Function(Message) onReply; + final void Function(Message) onEditMessage; + final int? initialScrollIndex; + final double? initialAlignment; + final bool highlightInitialMessage; @override Widget build(BuildContext context) { - return CustomMultiChildLayout( - delegate: _FloatingChannelBodyDelegate(), + final insets = StreamScaffoldInsets.of(context); + + return Stack( children: [ - // Body slot: a LayoutBuilder that reads the custom constraints. - LayoutId( - id: _Slot.body, - child: LayoutBuilder( - builder: (context, constraints) { - final height = constraints is _BodyBoxConstraints ? constraints.composerHeight : 0.0; - return messageListBuilder(height); - }, + StreamMessageListView( + initialScrollIndex: initialScrollIndex, + initialAlignment: initialAlignment, + config: StreamMessageListViewConfiguration( + highlightInitialMessage: highlightInitialMessage, + swipeToReply: true, ), + onEditMessageTap: onEditMessage, + onReplyTap: onReply, + threadBuilder: (_, parentMessage) { + return StreamThreadPage(parent: parentMessage!); + }, + topPadding: insets.topPadding, + bottomPadding: insets.bottomPadding, + ), + Positioned( + bottom: insets.bottomPadding, + left: 0, + right: 0, + child: typingIndicator, ), - LayoutId(id: _Slot.typing, child: typingIndicator), - LayoutId(id: _Slot.composer, child: composer), ], ); } diff --git a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart index fcb1777ebe..aeaf40523f 100644 --- a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart @@ -57,37 +57,62 @@ class _StreamThreadPageState extends State { @override Widget build(BuildContext context) { final appBar = StreamThreadHeader(parent: widget.parent); - final isFloating = StreamTheme.of(context).appStyle.appBarBehavior == .floating; - return Scaffold( + final composer = widget.parent.type != 'deleted' + ? StreamMessageComposer( + focusNode: _focusNode, + messageComposerController: _messageComposerController, + enableVoiceRecording: true, + ) + : null; + + return StreamScaffold( backgroundColor: context.streamColorScheme.backgroundApp, appBar: appBar, - extendBodyBehindAppBar: isFloating, - body: Column( - children: [ - Expanded( - child: StreamMessageListView( - parentMessage: widget.parent, - initialScrollIndex: widget.initialScrollIndex, - initialAlignment: widget.initialAlignment, - onReplyTap: _reply, - config: const StreamMessageListViewConfiguration( - swipeToReply: true, - showScrollToBottom: false, - highlightInitialMessage: true, - ), - onViewInChannelTap: widget.onViewInChannelTap, - topPadding: isFloating ? appBar.preferredSize.height + MediaQuery.of(context).padding.top : 0.0, - ), - ), - if (widget.parent.type != 'deleted') - StreamMessageComposer( - focusNode: _focusNode, - messageComposerController: _messageComposerController, - enableVoiceRecording: true, - ), - ], + bottom: composer, + body: _ThreadBody( + parent: widget.parent, + initialScrollIndex: widget.initialScrollIndex, + initialAlignment: widget.initialAlignment, + onReply: _reply, + onViewInChannelTap: widget.onViewInChannelTap, + ), + ); + } +} + +class _ThreadBody extends StatelessWidget { + const _ThreadBody({ + required this.parent, + required this.onReply, + this.initialScrollIndex, + this.initialAlignment, + this.onViewInChannelTap, + }); + + final Message parent; + final void Function(Message) onReply; + final int? initialScrollIndex; + final double? initialAlignment; + final void Function(Message message)? onViewInChannelTap; + + @override + Widget build(BuildContext context) { + final insets = StreamScaffoldInsets.of(context); + + return StreamMessageListView( + parentMessage: parent, + initialScrollIndex: initialScrollIndex, + initialAlignment: initialAlignment, + onReplyTap: onReply, + config: const StreamMessageListViewConfiguration( + swipeToReply: true, + showScrollToBottom: false, + highlightInitialMessage: true, ), + onViewInChannelTap: onViewInChannelTap, + topPadding: insets.topPadding, + bottomPadding: insets.bottomPadding, ); } } diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index b58f5d6371..208846f2a5 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -6,6 +6,9 @@ export 'package:stream_core_flutter/stream_core_flutter.dart' StreamAppStyle, ComposerLocation, AppBarBehavior, + BottomBarBehavior, + StreamScaffold, + StreamScaffoldInsets, StreamAppBar, StreamAppBarProps, StreamAppBarStyle, diff --git a/sample_app/lib/pages/channel_list_page.dart b/sample_app/lib/pages/channel_list_page.dart index 4b7cd032a3..6eb99de8df 100644 --- a/sample_app/lib/pages/channel_list_page.dart +++ b/sample_app/lib/pages/channel_list_page.dart @@ -1,4 +1,4 @@ -// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use, avoid_redundant_argument_values import 'dart:async'; @@ -74,40 +74,27 @@ class _ChannelListPageState extends State { final enabledTabs = allTabs.where((t) => t.enabled).toList(); - return Scaffold( + final isFloating = StreamTheme.of(context).appStyle.bottomBarBehavior == BottomBarBehavior.floating; + + final bottomNav = isFloating + ? _FloatingTabBar( + currentIndex: _currentIndex, + tabs: enabledTabs, + onTap: (i) => setState(() => _currentIndex = i), + ) + : _RegularBottomNavBar( + currentIndex: _currentIndex, + tabs: enabledTabs, + onTap: (i) => setState(() => _currentIndex = i), + ); + + return StreamScaffold( backgroundColor: colorScheme.backgroundApp, appBar: StreamChannelListHeader( title: Text(enabledTabs[_currentIndex].label, style: textTheme.headingSm), ), drawer: LeftDrawer(user: user), - bottomNavigationBar: DecoratedBox( - decoration: BoxDecoration( - color: colorScheme.backgroundElevation1, - border: Border(top: BorderSide(color: colorScheme.borderSubtle)), - ), - child: StreamBadgeNotificationTheme( - data: const .new(size: .xs), - child: BottomNavigationBar( - elevation: 0, - iconSize: 20, - currentIndex: _currentIndex, - type: BottomNavigationBarType.fixed, - selectedItemColor: colorScheme.textPrimary, - unselectedItemColor: colorScheme.textTertiary, - backgroundColor: Colors.transparent, - selectedLabelStyle: textTheme.metadataEmphasis, - unselectedLabelStyle: textTheme.metadataEmphasis, - onTap: (index) => setState(() => _currentIndex = index), - items: enabledTabs.map((tab) { - return BottomNavigationBarItem( - icon: tab.icon, - activeIcon: tab.selectedIcon, - label: tab.label, - ); - }).toList(), - ), - ), - ), + bottom: bottomNav, body: IndexedStack( index: _currentIndex, children: [for (final tab in enabledTabs) tab.page], @@ -141,6 +128,164 @@ class _ChannelListPageState extends State { } } +// --------------------------------------------------------------------------- +// Floating pill tab bar (floating bottom bar behavior) +// --------------------------------------------------------------------------- + +class _FloatingTabBar extends StatelessWidget { + const _FloatingTabBar({ + required this.currentIndex, + required this.tabs, + required this.onTap, + }); + + final int currentIndex; + final List<_TabDef> tabs; + final ValueChanged onTap; + + @override + Widget build(BuildContext context) { + final colorScheme = context.streamColorScheme; + final spacing = context.streamSpacing; + final radius = context.streamRadius; + + return SafeArea( + top: false, + child: Padding( + padding: EdgeInsets.only( + left: spacing.xl, + right: spacing.xl, + ), + child: Container( + decoration: BoxDecoration( + color: colorScheme.backgroundElevation1, + borderRadius: BorderRadius.all(radius.max), + boxShadow: context.streamBoxShadow.elevation1, + ), + foregroundDecoration: BoxDecoration( + borderRadius: BorderRadius.all(radius.max), + border: Border.all(color: colorScheme.borderSubtle), + ), + child: Padding( + padding: EdgeInsets.symmetric(vertical: spacing.xs), + child: StreamBadgeNotificationTheme( + data: const .new(size: .xs), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + for (var i = 0; i < tabs.length; i++) + _FloatingTabItem( + tab: tabs[i], + selected: i == currentIndex, + onTap: () => onTap(i), + ), + ], + ), + ), + ), + ), + ), + ); + } +} + +class _FloatingTabItem extends StatelessWidget { + const _FloatingTabItem({ + required this.tab, + required this.selected, + required this.onTap, + }); + + final _TabDef tab; + final bool selected; + final VoidCallback onTap; + + @override + Widget build(BuildContext context) { + final textTheme = context.streamTextTheme; + final colorScheme = context.streamColorScheme; + final spacing = context.streamSpacing; + final color = selected ? colorScheme.textPrimary : colorScheme.textTertiary; + + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: onTap, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: spacing.md, vertical: spacing.xxs), + child: Column( + mainAxisSize: MainAxisSize.min, + spacing: spacing.xxxs, + children: [ + IconTheme( + data: IconThemeData(color: color, size: 20), + child: selected ? tab.selectedIcon : tab.icon, + ), + Text( + tab.label, + style: textTheme.metadataEmphasis.copyWith(color: color), + ), + ], + ), + ), + ); + } +} + +// --------------------------------------------------------------------------- +// Regular (docked) bottom navigation bar +// --------------------------------------------------------------------------- + +class _RegularBottomNavBar extends StatelessWidget { + const _RegularBottomNavBar({ + required this.currentIndex, + required this.tabs, + required this.onTap, + }); + + final int currentIndex; + final List<_TabDef> tabs; + final ValueChanged onTap; + + @override + Widget build(BuildContext context) { + final colorScheme = context.streamColorScheme; + final textTheme = context.streamTextTheme; + + return DecoratedBox( + decoration: BoxDecoration( + color: colorScheme.backgroundElevation1, + border: Border(top: BorderSide(color: colorScheme.borderSubtle)), + ), + child: StreamBadgeNotificationTheme( + data: const .new(size: .xs), + child: BottomNavigationBar( + elevation: 0, + iconSize: 20, + currentIndex: currentIndex, + type: BottomNavigationBarType.fixed, + selectedItemColor: colorScheme.textPrimary, + unselectedItemColor: colorScheme.textTertiary, + backgroundColor: Colors.transparent, + selectedLabelStyle: textTheme.metadataEmphasis, + unselectedLabelStyle: textTheme.metadataEmphasis, + onTap: onTap, + items: tabs.map((tab) { + return BottomNavigationBarItem( + icon: tab.icon, + activeIcon: tab.selectedIcon, + label: tab.label, + ); + }).toList(), + ), + ), + ); + } +} + +// --------------------------------------------------------------------------- +// Tab definition +// --------------------------------------------------------------------------- + class _TabDef { const _TabDef({ required this.icon, diff --git a/sample_app/lib/widgets/channel_list.dart b/sample_app/lib/widgets/channel_list.dart index c32abfd2e5..ed3191e852 100644 --- a/sample_app/lib/widgets/channel_list.dart +++ b/sample_app/lib/widgets/channel_list.dart @@ -89,14 +89,21 @@ class _ChannelList extends State { }, child: NestedScrollView( controller: _scrollController, - headerSliverBuilder: (_, __) => [ - SliverToBoxAdapter( - child: SearchTextField( - controller: _controller, - hintText: 'Search', + headerSliverBuilder: (context, __) { + // When the app bar is floating it overlaps this scroll view from + // the top. Insert a spacer sliver so the search bar starts below + // the visible bottom edge of the floating bar. + final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + return [ + if (topInset > 0) SliverToBoxAdapter(child: SizedBox(height: topInset)), + SliverToBoxAdapter( + child: SearchTextField( + controller: _controller, + hintText: 'Search', + ), ), - ), - ], + ]; + }, body: _isSearchActive ? _ChannelListSearch(_messageSearchListController) : _ChannelListDefault(_channelListController), @@ -113,11 +120,14 @@ class _ChannelListDefault extends StatelessWidget { @override Widget build(BuildContext context) { + final bottomPadding = StreamScaffoldInsets.maybeOf(context)?.bottomPadding ?? 0.0; + return SlidableAutoCloseBehavior( child: RefreshIndicator( onRefresh: channelListController.refresh, child: StreamChannelListView( controller: channelListController, + padding: bottomPadding > 0 ? EdgeInsets.only(bottom: bottomPadding) : null, itemBuilder: (context, channels, index, defaultWidget) { final channel = channels[index]; From 1ff997d1fd3d38197b274d9d5704af0d62fc3803 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 29 May 2026 13:15:37 +0200 Subject: [PATCH 15/87] migrate to SDK navbar --- .../lib/stream_chat_flutter.dart | 2 + sample_app/lib/pages/channel_list_page.dart | 216 +++--------------- 2 files changed, 30 insertions(+), 188 deletions(-) diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 208846f2a5..03f5ded2d1 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -25,6 +25,8 @@ export 'package:stream_core_flutter/stream_core_flutter.dart' StreamBottomAppBarStyle, StreamBottomAppBarTheme, StreamBottomAppBarThemeData, + StreamBottomNavBar, + StreamBottomNavBarItem, StreamButton, StreamButtonSize, StreamButtonStyle, diff --git a/sample_app/lib/pages/channel_list_page.dart b/sample_app/lib/pages/channel_list_page.dart index 6eb99de8df..98c5a6309e 100644 --- a/sample_app/lib/pages/channel_list_page.dart +++ b/sample_app/lib/pages/channel_list_page.dart @@ -45,28 +45,36 @@ class _ChannelListPageState extends State { final allTabs = <_TabDef>[ _TabDef( - icon: StreamUnreadIndicator(child: Icon(icons.messageBubble)), - selectedIcon: StreamUnreadIndicator(child: Icon(icons.messageBubbleFill)), - label: 'Chats', + navItem: StreamBottomNavBarItem( + icon: StreamUnreadIndicator(child: Icon(icons.messageBubble)), + selectedIcon: StreamUnreadIndicator(child: Icon(icons.messageBubbleFill)), + label: 'Chats', + ), page: const ChannelList(), ), _TabDef( - icon: StreamUnreadIndicator.threads(child: Icon(icons.thread)), - selectedIcon: StreamUnreadIndicator.threads(child: Icon(icons.threadFill)), - label: 'Threads', + navItem: StreamBottomNavBarItem( + icon: StreamUnreadIndicator.threads(child: Icon(icons.thread)), + selectedIcon: StreamUnreadIndicator.threads(child: Icon(icons.threadFill)), + label: 'Threads', + ), page: const ThreadListPage(), ), _TabDef( - icon: const Icon(Icons.drafts_outlined), - selectedIcon: const Icon(Icons.drafts_rounded), - label: 'Drafts', + navItem: const StreamBottomNavBarItem( + icon: Icon(Icons.drafts_outlined), + selectedIcon: Icon(Icons.drafts_rounded), + label: 'Drafts', + ), page: const DraftListPage(), enabled: config.draftMessagesEnabled, ), _TabDef( - icon: const Icon(Icons.bookmark_outline_rounded), - selectedIcon: const Icon(Icons.bookmark_rounded), - label: 'Reminders', + navItem: const StreamBottomNavBarItem( + icon: Icon(Icons.bookmark_outline_rounded), + selectedIcon: Icon(Icons.bookmark_rounded), + label: 'Reminders', + ), page: const RemindersPage(), enabled: config.enableReminderActions, ), @@ -74,27 +82,17 @@ class _ChannelListPageState extends State { final enabledTabs = allTabs.where((t) => t.enabled).toList(); - final isFloating = StreamTheme.of(context).appStyle.bottomBarBehavior == BottomBarBehavior.floating; - - final bottomNav = isFloating - ? _FloatingTabBar( - currentIndex: _currentIndex, - tabs: enabledTabs, - onTap: (i) => setState(() => _currentIndex = i), - ) - : _RegularBottomNavBar( - currentIndex: _currentIndex, - tabs: enabledTabs, - onTap: (i) => setState(() => _currentIndex = i), - ); - return StreamScaffold( backgroundColor: colorScheme.backgroundApp, appBar: StreamChannelListHeader( - title: Text(enabledTabs[_currentIndex].label, style: textTheme.headingSm), + title: Text(enabledTabs[_currentIndex].navItem.label, style: textTheme.headingSm), ), drawer: LeftDrawer(user: user), - bottom: bottomNav, + bottom: StreamBottomNavBar( + currentIndex: _currentIndex, + onTap: (i) => setState(() => _currentIndex = i), + items: [for (final tab in enabledTabs) tab.navItem], + ), body: IndexedStack( index: _currentIndex, children: [for (final tab in enabledTabs) tab.page], @@ -128,176 +126,18 @@ class _ChannelListPageState extends State { } } -// --------------------------------------------------------------------------- -// Floating pill tab bar (floating bottom bar behavior) -// --------------------------------------------------------------------------- - -class _FloatingTabBar extends StatelessWidget { - const _FloatingTabBar({ - required this.currentIndex, - required this.tabs, - required this.onTap, - }); - - final int currentIndex; - final List<_TabDef> tabs; - final ValueChanged onTap; - - @override - Widget build(BuildContext context) { - final colorScheme = context.streamColorScheme; - final spacing = context.streamSpacing; - final radius = context.streamRadius; - - return SafeArea( - top: false, - child: Padding( - padding: EdgeInsets.only( - left: spacing.xl, - right: spacing.xl, - ), - child: Container( - decoration: BoxDecoration( - color: colorScheme.backgroundElevation1, - borderRadius: BorderRadius.all(radius.max), - boxShadow: context.streamBoxShadow.elevation1, - ), - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.all(radius.max), - border: Border.all(color: colorScheme.borderSubtle), - ), - child: Padding( - padding: EdgeInsets.symmetric(vertical: spacing.xs), - child: StreamBadgeNotificationTheme( - data: const .new(size: .xs), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - for (var i = 0; i < tabs.length; i++) - _FloatingTabItem( - tab: tabs[i], - selected: i == currentIndex, - onTap: () => onTap(i), - ), - ], - ), - ), - ), - ), - ), - ); - } -} - -class _FloatingTabItem extends StatelessWidget { - const _FloatingTabItem({ - required this.tab, - required this.selected, - required this.onTap, - }); - - final _TabDef tab; - final bool selected; - final VoidCallback onTap; - - @override - Widget build(BuildContext context) { - final textTheme = context.streamTextTheme; - final colorScheme = context.streamColorScheme; - final spacing = context.streamSpacing; - final color = selected ? colorScheme.textPrimary : colorScheme.textTertiary; - - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Padding( - padding: EdgeInsets.symmetric(horizontal: spacing.md, vertical: spacing.xxs), - child: Column( - mainAxisSize: MainAxisSize.min, - spacing: spacing.xxxs, - children: [ - IconTheme( - data: IconThemeData(color: color, size: 20), - child: selected ? tab.selectedIcon : tab.icon, - ), - Text( - tab.label, - style: textTheme.metadataEmphasis.copyWith(color: color), - ), - ], - ), - ), - ); - } -} - -// --------------------------------------------------------------------------- -// Regular (docked) bottom navigation bar -// --------------------------------------------------------------------------- - -class _RegularBottomNavBar extends StatelessWidget { - const _RegularBottomNavBar({ - required this.currentIndex, - required this.tabs, - required this.onTap, - }); - - final int currentIndex; - final List<_TabDef> tabs; - final ValueChanged onTap; - - @override - Widget build(BuildContext context) { - final colorScheme = context.streamColorScheme; - final textTheme = context.streamTextTheme; - - return DecoratedBox( - decoration: BoxDecoration( - color: colorScheme.backgroundElevation1, - border: Border(top: BorderSide(color: colorScheme.borderSubtle)), - ), - child: StreamBadgeNotificationTheme( - data: const .new(size: .xs), - child: BottomNavigationBar( - elevation: 0, - iconSize: 20, - currentIndex: currentIndex, - type: BottomNavigationBarType.fixed, - selectedItemColor: colorScheme.textPrimary, - unselectedItemColor: colorScheme.textTertiary, - backgroundColor: Colors.transparent, - selectedLabelStyle: textTheme.metadataEmphasis, - unselectedLabelStyle: textTheme.metadataEmphasis, - onTap: onTap, - items: tabs.map((tab) { - return BottomNavigationBarItem( - icon: tab.icon, - activeIcon: tab.selectedIcon, - label: tab.label, - ); - }).toList(), - ), - ), - ); - } -} - // --------------------------------------------------------------------------- // Tab definition // --------------------------------------------------------------------------- class _TabDef { const _TabDef({ - required this.icon, - required this.selectedIcon, - required this.label, + required this.navItem, required this.page, this.enabled = true, }); - final Widget icon; - final Widget selectedIcon; - final String label; + final StreamBottomNavBarItem navItem; final Widget page; final bool enabled; } From 4bd8056662fb248a28052e9a2f10114813002d38 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 10 Jun 2026 12:20:48 +0200 Subject: [PATCH 16/87] fix edit message in thread broken due to merge --- .../lib/src/channel/thread_page.dart | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart index aeaf40523f..a68d4cfdd3 100644 --- a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart @@ -54,6 +54,13 @@ class _StreamThreadPageState extends State { }); } + void _editMessage(Message message) { + _messageComposerController.editMessage(message); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + _focusNode.requestFocus(); + }); + } + @override Widget build(BuildContext context) { final appBar = StreamThreadHeader(parent: widget.parent); @@ -67,7 +74,6 @@ class _StreamThreadPageState extends State { : null; return StreamScaffold( - backgroundColor: context.streamColorScheme.backgroundApp, appBar: appBar, bottom: composer, body: _ThreadBody( @@ -75,6 +81,7 @@ class _StreamThreadPageState extends State { initialScrollIndex: widget.initialScrollIndex, initialAlignment: widget.initialAlignment, onReply: _reply, + onEditMessageTap: _editMessage, onViewInChannelTap: widget.onViewInChannelTap, ), ); @@ -85,6 +92,7 @@ class _ThreadBody extends StatelessWidget { const _ThreadBody({ required this.parent, required this.onReply, + required this.onEditMessageTap, this.initialScrollIndex, this.initialAlignment, this.onViewInChannelTap, @@ -95,6 +103,7 @@ class _ThreadBody extends StatelessWidget { final int? initialScrollIndex; final double? initialAlignment; final void Function(Message message)? onViewInChannelTap; + final void Function(Message message)? onEditMessageTap; @override Widget build(BuildContext context) { @@ -105,6 +114,7 @@ class _ThreadBody extends StatelessWidget { initialScrollIndex: initialScrollIndex, initialAlignment: initialAlignment, onReplyTap: onReply, + onEditMessageTap: onEditMessageTap, config: const StreamMessageListViewConfiguration( swipeToReply: true, showScrollToBottom: false, From 84e85ce4cd515b588c2fd70189dfb25b1ee876e8 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 11 Jun 2026 16:46:47 +0200 Subject: [PATCH 17/87] Add shadow to avatar on channel header --- .../lib/src/channel/channel_header.dart | 15 +++++++++++++-- .../components/avatar/stream_channel_avatar.dart | 11 +++++++++++ .../src/components/avatar/stream_user_avatar.dart | 9 +++++++++ .../avatar/stream_user_avatar_group.dart | 9 +++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index ccc4cfb49d..89d7aaac20 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -153,8 +153,17 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget var subtitle = this.subtitle; subtitle ??= StreamChannelInfo(channel: channel); + final showAvatarShadow = switch (appBarBehavior ?? StreamTheme.of(context).appStyle.appBarBehavior) { + .floating => true, + .regular => false, + }; + var trailing = this.trailing; - trailing ??= _DefaultChannelAvatar(channel: channel, onPressed: onChannelAvatarPressed); + trailing ??= _DefaultChannelAvatar( + channel: channel, + onPressed: onChannelAvatarPressed, + showShadow: showAvatarShadow, + ); return Portal( child: StreamConnectionStatusBuilder( @@ -203,10 +212,11 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget } class _DefaultChannelAvatar extends StatelessWidget { - const _DefaultChannelAvatar({required this.channel, this.onPressed}); + const _DefaultChannelAvatar({required this.channel, this.onPressed, this.showShadow = false}); final Channel channel; final void Function(Channel channel)? onPressed; + final bool showShadow; @override Widget build(BuildContext context) { @@ -227,6 +237,7 @@ class _DefaultChannelAvatar extends StatelessWidget { child: StreamChannelAvatar( size: .lg, channel: channel, + showShadow: showShadow, ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart index 92739aa219..8ac6723233 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart @@ -54,6 +54,7 @@ class StreamChannelAvatar extends StatelessWidget { super.key, this.size, required this.channel, + this.showShadow = false, }); /// The channel whose avatar is displayed. @@ -64,6 +65,13 @@ class StreamChannelAvatar extends StatelessWidget { /// If null, defaults to [StreamAvatarGroupSize.lg]. final StreamAvatarGroupSize? size; + /// Whether to show a drop shadow around the avatar. + /// + /// Defaults to false. The shadow style is determined by + /// [StreamAvatarThemeData.boxShadow], falling back to + /// [StreamBoxShadow.elevation3]. + final bool showShadow; + @override Widget build(BuildContext context) { assert(channel.state != null, 'Channel ${channel.id} is not initialized'); @@ -76,6 +84,7 @@ class StreamChannelAvatar extends StatelessWidget { builder: (context, channelImage) => StreamAvatar( imageUrl: channelImage, size: _avatarSizeForAvatarGroupSize(effectiveSize), + showShadow: showShadow, placeholder: (_) => const _StreamChannelAvatarPlaceholder(), ), noDataBuilder: (context) => BetterStreamBuilder( @@ -95,12 +104,14 @@ class StreamChannelAvatar extends StatelessWidget { size: _avatarSizeForAvatarGroupSize(effectiveSize), // TODO: make this configurable when the online state is shown. showOnlineIndicator: otherUser.online, + showShadow: showShadow, ); } return StreamUserAvatarGroup( size: effectiveSize, users: users.sortedBy((it) => it.id == currentUserId ? 1 : 0), + showShadow: showShadow, ); }, ), diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart index 81ad91a98a..747ae2b5f0 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart @@ -68,6 +68,7 @@ class StreamUserAvatar extends StatelessWidget { required this.user, this.showBorder = true, this.showOnlineIndicator = true, + this.showShadow = false, }); /// The user whose avatar is displayed. @@ -84,6 +85,13 @@ class StreamUserAvatar extends StatelessWidget { /// Defaults to true. final bool showOnlineIndicator; + /// Whether to show a drop shadow around the avatar. + /// + /// Defaults to false. The shadow style is determined by + /// [StreamAvatarThemeData.boxShadow], falling back to + /// [StreamBoxShadow.elevation3]. + final bool showShadow; + /// The size of the avatar. /// /// If null, uses [StreamAvatarThemeData.size], or falls back to @@ -107,6 +115,7 @@ class StreamUserAvatar extends StatelessWidget { size: effectiveSize, imageUrl: user.image, showBorder: showBorder, + showShadow: showShadow, backgroundColor: effectiveBackgroundColor, foregroundColor: effectiveForegroundColor, placeholder: (_) => _StreamUserAvatarPlaceholder(user: user, size: effectiveSize), diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart index 5b557f4e6b..aebd47c9ae 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart @@ -55,6 +55,7 @@ class StreamUserAvatarGroup extends StatelessWidget { super.key, required this.users, this.size, + this.showShadow = false, }); /// The list of users whose avatars are displayed. @@ -65,6 +66,13 @@ class StreamUserAvatarGroup extends StatelessWidget { /// If null, defaults to [StreamAvatarGroupSize.lg]. final StreamAvatarGroupSize? size; + /// Whether to show a drop shadow around the avatar group. + /// + /// Defaults to false. The shadow style is determined by + /// [StreamAvatarThemeData.boxShadow], falling back to + /// [StreamBoxShadow.elevation3]. + final bool showShadow; + @override Widget build(BuildContext context) { return StreamAvatarGroup( @@ -73,6 +81,7 @@ class StreamUserAvatarGroup extends StatelessWidget { (user) => StreamUserAvatar( user: user, showOnlineIndicator: false, + showShadow: showShadow, ), ), ); From c27569b3761ba3ec1c0e9c965da861503986de18 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 12 Jun 2026 09:35:37 +0200 Subject: [PATCH 18/87] Add gradient behind floating composer --- .../lib/src/channel/channel_list_header.dart | 15 +- .../stream_message_composer.dart | 218 ++++++++++++------ 2 files changed, 155 insertions(+), 78 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart index e4ed899c7b..4e9198bde2 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart @@ -80,6 +80,7 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi this.trailing, this.primary = true, this.style, + this.appBarBehavior, }); /// Use this if you don't have a [StreamChatClient] in your widget tree. @@ -117,6 +118,9 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi /// [StreamChatThemeData.channelListHeaderTheme]. final StreamAppBarStyle? style; + /// Whether the header is floating. + final AppBarBehavior? appBarBehavior; + @override Size get preferredSize => const Size.fromHeight(kStreamToolbarHeight); @@ -125,7 +129,12 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi final _client = client ?? StreamChat.of(context).client; final headerTheme = StreamChatTheme.of(context).channelListHeaderTheme; - final leading = _DefaultUserAvatar(client: _client, onPressed: onUserAvatarPressed); + final hasAvatarShadow = switch (appBarBehavior ?? StreamTheme.of(context).appStyle.appBarBehavior) { + .floating => true, + .regular => false, + }; + + final leading = _DefaultUserAvatar(client: _client, onPressed: onUserAvatarPressed, showShadow: hasAvatarShadow); return Portal( child: StreamConnectionStatusBuilder( @@ -179,10 +188,11 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi } class _DefaultUserAvatar extends StatelessWidget { - const _DefaultUserAvatar({required this.client, this.onPressed}); + const _DefaultUserAvatar({required this.client, this.onPressed, this.showShadow = false}); final StreamChatClient client; final void Function(User user)? onPressed; + final bool showShadow; @override Widget build(BuildContext context) { @@ -211,6 +221,7 @@ class _DefaultUserAvatar extends StatelessWidget { size: .lg, user: user, showOnlineIndicator: false, + showShadow: showShadow, ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index c8428f1e9a..180a7c1cc6 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -7,11 +7,13 @@ import 'package:flutter/services.dart'; import 'package:stream_chat_flutter/src/message_input/error_alert_sheet.dart'; import 'package:stream_chat_flutter/src/message_input/stream_chat_message_input.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; -import 'package:stream_core_flutter/stream_core_flutter.dart'; const _kCommandTrigger = '/'; const _kMentionTrigger = '@'; +/// Fixed height of the inline attachment picker body. +const _kPickerBodyHeight = 333.0; + /// Signature for the function that determines if a [matchedUri] should be /// previewed as an OG Attachment. typedef OgPreviewFilter = bool Function(Uri matchedUri, String messageText); @@ -797,34 +799,56 @@ class DefaultStreamMessageComposerState extends State 0) { + final bandColor = context.streamColorScheme.backgroundElevation1; + return Stack( + children: [ + Positioned( + bottom: 0, + left: 0, + right: 0, + height: safeAreaPadding.bottom, + child: ColoredBox(color: bandColor), + ), + Padding(padding: safeAreaPadding, child: child), + ], + ); + } + + return Padding(padding: safeAreaPadding, child: child); + }, + child: Center(heightFactor: 1, child: messageInput), + ); + return Material( color: Colors.transparent, - child: DecoratedBox( - decoration: BoxDecoration( - color: switch (effectiveComposerLocation) { - .floating => null, - .docked => context.streamColorScheme.backgroundElevation1, - }, + child: switch (effectiveComposerLocation) { + .floating => composerBody, + .docked => DecoratedBox( + decoration: BoxDecoration(color: context.streamColorScheme.backgroundElevation1), + child: composerBody, ), - child: AnimatedBuilder( - animation: _pickerAnimation, - builder: (context, child) { - final safeAreaPadding = safeAreaEnabled - ? EdgeInsets.lerp( - EdgeInsets.only( - left: viewPadding.left, - right: viewPadding.right, - bottom: math.max(viewPadding.bottom, spacing.md), - ), - EdgeInsets.zero, - _pickerAnimation.value, - )! - : EdgeInsets.zero; - return Padding(padding: safeAreaPadding, child: child); - }, - child: Center(heightFactor: 1, child: messageInput), - ), - ), + }, ); } @@ -893,64 +917,106 @@ class DefaultStreamMessageComposerState extends State PopScope( - canPop: !_isPickerVisible, - onPopInvokedWithResult: (didPop, _) { - if (!didPop) _hidePicker(); - }, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - DropTarget( - onDragDone: (details) async { - final attachments = []; - for (final file in details.files) { - attachments.add(await file.toAttachment(type: AttachmentType.file)); - } - if (attachments.isNotEmpty) _addAttachments(attachments); + builder: (context, value, _) { + // Extracted so the floating gradient can wrap just the pill, keeping + // gradient height stable when the picker (a sibling) opens. + final pill = DropTarget( + onDragDone: (details) async { + final attachments = []; + for (final file in details.files) { + attachments.add(await file.toAttachment(type: AttachmentType.file)); + } + if (attachments.isNotEmpty) _addAttachments(attachments); + }, + onDragEntered: (_) {}, + onDragExited: (_) {}, + child: Focus( + skipTraversal: true, + onKeyEvent: _handleKeyPressed, + child: StreamChatMessageInput( + controller: controller, + currentUserId: currentUserId, + onAttachmentButtonPressed: widget.props.disableAttachments ? null : _onAttachmentButtonPressed, + isPickerOpen: _isPickerVisible, + placeholder: _buildPlaceholder(context), + focusNode: focusNode, + onSendPressed: sendMessage, + canAlsoSendToChannel: _shouldShowSendToChannelCheckbox(), + audioRecorderController: widget.props.enableVoiceRecording ? _audioRecorderController : null, + sendVoiceRecordingAutomatically: widget.props.sendVoiceRecordingAutomatically, + feedback: widget.props.voiceRecordingFeedback, + onQuotedMessageCleared: () { + _effectiveController.clearQuotedMessage(); + widget.props.onQuotedMessageCleared?.call(); }, - onDragEntered: (_) {}, - onDragExited: (_) {}, - child: Focus( - skipTraversal: true, - onKeyEvent: _handleKeyPressed, - child: StreamChatMessageInput( - controller: controller, - currentUserId: currentUserId, - onAttachmentButtonPressed: widget.props.disableAttachments ? null : _onAttachmentButtonPressed, - isPickerOpen: _isPickerVisible, - placeholder: _buildPlaceholder(context), - focusNode: focusNode, - onSendPressed: sendMessage, - canAlsoSendToChannel: _shouldShowSendToChannelCheckbox(), - audioRecorderController: widget.props.enableVoiceRecording ? _audioRecorderController : null, - sendVoiceRecordingAutomatically: widget.props.sendVoiceRecordingAutomatically, - feedback: widget.props.voiceRecordingFeedback, - onQuotedMessageCleared: () { - _effectiveController.clearQuotedMessage(); - widget.props.onQuotedMessageCleared?.call(); - }, - textInputAction: widget.props.textInputAction, - keyboardType: widget.props.keyboardType, - textCapitalization: widget.props.textCapitalization, - autofocus: widget.props.autofocus, - autocorrect: widget.props.autoCorrect, - isFloating: effectiveComposerLocation == .floating, - ), - ), - ), - SizeTransition( - sizeFactor: _pickerAnimation, - // ignore: deprecated_member_use - axisAlignment: -1, - child: _buildInlineAttachmentPicker(context), + textInputAction: widget.props.textInputAction, + keyboardType: widget.props.keyboardType, + textCapitalization: widget.props.textCapitalization, + autofocus: widget.props.autofocus, + autocorrect: widget.props.autoCorrect, + isFloating: isFloating, ), + ), + ); + + return PopScope( + canPop: !_isPickerVisible, + onPopInvokedWithResult: (didPop, _) { + if (!didPop) _hidePicker(); + }, + child: Column( + mainAxisSize: MainAxisSize.min, + // Reversed paint order so the pill (and its shadow) paints on top + // of the picker panel. VerticalDirection.up keeps the pill visually + // above the picker while making it the last-painted child. + verticalDirection: VerticalDirection.up, + children: [ + SizeTransition( + sizeFactor: _pickerAnimation, + // ignore: deprecated_member_use + axisAlignment: -1, + child: _buildInlineAttachmentPicker(context), + ), + // Gradient wraps only the pill — not the picker sibling — so + // the gradient height tracks the pill and doesn't stretch when + // the picker opens or closes. + if (isFloating) _buildFloatingComposerBand(context, pill) else pill, + ], + ), + ); + }, + ); + } + + /// Wraps [child] (the pill widget) with a floating gradient background that + /// fades from transparent at the top to solid + /// [StreamColorScheme.backgroundElevation1] at the bottom. + /// + /// Applied to just the pill [DropTarget] so the gradient height tracks the + /// pill (growing with attachments) and is unaffected by the picker opening. + Widget _buildFloatingComposerBand(BuildContext context, Widget child) { + final bandColor = context.streamColorScheme.backgroundElevation1; + + return DecoratedBox( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + bandColor.withAlpha(0x00), // transparent at top of composer band + bandColor.withAlpha(0x40), // ~25 % + bandColor.withAlpha(0xA8), // ~66 % + bandColor.withAlpha(0xE8), // ~91 % + bandColor, // solid at bottom (safe area) ], + stops: const [0.0, 0.55, 0.75, 0.90, 1.0], ), ), + child: child, ); } From 4b0a70013250612d7f54e673df4cbccac3458ab2 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 12 Jun 2026 10:28:17 +0200 Subject: [PATCH 19/87] fix attachmentpicker background --- .../stream_message_composer.dart | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 180a7c1cc6..8f7e1eeaf7 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -392,6 +392,7 @@ class MessageComposerProps { /// The location of the message composer. final ComposerLocation? composerLocation; + /// Returns a copy of this [MessageComposerProps] with the given fields /// replaced with new values. MessageComposerProps copyWith({ @@ -1031,28 +1032,28 @@ class DefaultStreamMessageComposerState extends State Date: Fri, 12 Jun 2026 10:40:02 +0200 Subject: [PATCH 20/87] Add sample app config --- docs/docs_screenshots/pubspec.yaml | 2 +- melos.yaml | 2 +- packages/stream_chat_flutter/pubspec.yaml | 2 +- sample_app/lib/app.dart | 34 ++++++++++--------- sample_app/lib/config/sample_app_config.dart | 25 ++++++++++++++ .../lib/config/sample_app_config_screen.dart | 13 +++++++ 6 files changed, 59 insertions(+), 19 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index df13ee5a7f..e4850a697d 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: 43f90a46d8092ca2c1e24c36af06f05fc0c633a6 + ref: bb75889af53a2a9e42939adb4e222680b18142d4 path: packages/stream_core_flutter dev_dependencies: diff --git a/melos.yaml b/melos.yaml index fa5882a546..960b81fb44 100644 --- a/melos.yaml +++ b/melos.yaml @@ -101,7 +101,7 @@ command: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: 43f90a46d8092ca2c1e24c36af06f05fc0c633a6 + ref: bb75889af53a2a9e42939adb4e222680b18142d4 path: packages/stream_core_flutter synchronized: ^3.4.0 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 791b2e8fa1..374ccefdd0 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -68,7 +68,7 @@ dependencies: # ignore: invalid_dependency git: url: https://github.com/GetStream/stream-core-flutter - ref: 43f90a46d8092ca2c1e24c36af06f05fc0c633a6 + ref: bb75889af53a2a9e42939adb4e222680b18142d4 path: packages/stream_core_flutter svg_icon_widget: ^0.0.1 synchronized: ^3.4.0 diff --git a/sample_app/lib/app.dart b/sample_app/lib/app.dart index de507c91e6..6e69708419 100644 --- a/sample_app/lib/app.dart +++ b/sample_app/lib/app.dart @@ -170,23 +170,25 @@ class _StreamChatSampleAppState extends State child: Builder( builder: (context) { final config = context.sampleAppConfig; + + StreamAppStyle appStyle() => switch (config.appStyle) { + SampleAppStyle.regular => const StreamAppStyle.regular(), + SampleAppStyle.floating => const StreamAppStyle.floating(), + }; + + ThemeData theme(Brightness brightness) => ThemeData( + brightness: brightness, + extensions: [ + StreamTheme( + brightness: brightness, + appStyle: appStyle(), + ), + ], + ); + return MaterialApp.router( - theme: ThemeData( - brightness: .light, - extensions: [ - StreamTheme.light().copyWith( - appStyle: const StreamAppStyle.floating(), - ), - ], - ), - darkTheme: ThemeData( - brightness: .dark, - extensions: [ - StreamTheme.dark().copyWith( - appStyle: const StreamAppStyle.floating(), - ), - ], - ), + theme: theme(.light), + darkTheme: theme(.dark), themeMode: config.themeMode, locale: config.locale, supportedLocales: supportedLocales, diff --git a/sample_app/lib/config/sample_app_config.dart b/sample_app/lib/config/sample_app_config.dart index 40bdac4021..13d5fbf0c2 100644 --- a/sample_app/lib/config/sample_app_config.dart +++ b/sample_app/lib/config/sample_app_config.dart @@ -3,11 +3,25 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_localizations/stream_chat_localizations.dart'; import 'package:streaming_shared_preferences/streaming_shared_preferences.dart'; +// --------------------------------------------------------------------------- +// AppStyle enum +// --------------------------------------------------------------------------- + +/// The visual style for the app's UI chrome (app bar, composer, bottom bar). +enum SampleAppStyle { + /// Standard docked composer with solid app bar and bottom bar. + regular, + + /// Floating composer with translucent overlapping chrome. + floating, +} + // --------------------------------------------------------------------------- // Preference keys // --------------------------------------------------------------------------- const _kThemeMode = 'config.themeMode'; +const _kAppStyle = 'config.appStyle'; const _kForceRtl = 'config.forceRtl'; const _kEnableReminderActions = 'config.enableReminderActions'; const _kEnableDeleteForMe = 'config.enableDeleteForMe'; @@ -38,6 +52,7 @@ class SampleAppConfigData { factory SampleAppConfigData({ Locale? locale, ThemeMode themeMode = .system, + SampleAppStyle appStyle = .floating, bool forceRtl = false, bool enableReminderActions = false, bool enableDeleteForMe = false, @@ -50,6 +65,7 @@ class SampleAppConfigData { }) { return SampleAppConfigData.raw( themeMode: themeMode, + appStyle: appStyle, locale: locale, forceRtl: forceRtl, enableReminderActions: enableReminderActions, @@ -66,6 +82,7 @@ class SampleAppConfigData { /// Raw constructor used internally and by persistence. const SampleAppConfigData.raw({ required this.themeMode, + required this.appStyle, required this.locale, required this.forceRtl, required this.enableReminderActions, @@ -81,8 +98,10 @@ class SampleAppConfigData { /// Loads config from [StreamingSharedPreferences], falling back to defaults. factory SampleAppConfigData.fromPreferences(StreamingSharedPreferences prefs) { final localeStr = prefs.getString(_kLocale, defaultValue: '').getValue(); + final appStyleIndex = prefs.getInt(_kAppStyle, defaultValue: SampleAppStyle.floating.index).getValue(); return SampleAppConfigData.raw( themeMode: ThemeMode.values[prefs.getInt(_kThemeMode, defaultValue: ThemeMode.system.index).getValue()], + appStyle: SampleAppStyle.values[appStyleIndex.clamp(0, SampleAppStyle.values.length - 1)], locale: localeStr.isEmpty ? null : Locale(localeStr), forceRtl: prefs.getBool(_kForceRtl, defaultValue: false).getValue(), enableReminderActions: prefs.getBool(_kEnableReminderActions, defaultValue: false).getValue(), @@ -101,6 +120,9 @@ class SampleAppConfigData { /// The theme mode for the app (system, light, dark). final ThemeMode themeMode; + /// The visual style for the app chrome (app bar, composer, bottom bar). + final SampleAppStyle appStyle; + /// The locale override for the app. When null, the system locale is used. final Locale? locale; @@ -141,6 +163,7 @@ class SampleAppConfigData { /// pass explicitly as `null` to reset to default/system. SampleAppConfigData copyWith({ ThemeMode? themeMode, + SampleAppStyle? appStyle, Object? locale = _sentinel, bool? forceRtl, bool? enableReminderActions, @@ -154,6 +177,7 @@ class SampleAppConfigData { }) { return SampleAppConfigData.raw( themeMode: themeMode ?? this.themeMode, + appStyle: appStyle ?? this.appStyle, locale: locale == _sentinel ? this.locale : locale as Locale?, forceRtl: forceRtl ?? this.forceRtl, enableReminderActions: enableReminderActions ?? this.enableReminderActions, @@ -174,6 +198,7 @@ class SampleAppConfigData { /// Persists all fields to [StreamingSharedPreferences]. void saveToPreferences(StreamingSharedPreferences prefs) { prefs.setInt(_kThemeMode, themeMode.index); + prefs.setInt(_kAppStyle, appStyle.index); prefs.setString(_kLocale, locale?.languageCode ?? ''); prefs.setBool(_kForceRtl, forceRtl); prefs.setBool(_kEnableReminderActions, enableReminderActions); diff --git a/sample_app/lib/config/sample_app_config_screen.dart b/sample_app/lib/config/sample_app_config_screen.dart index f6bfffa0e8..02ae33e58e 100644 --- a/sample_app/lib/config/sample_app_config_screen.dart +++ b/sample_app/lib/config/sample_app_config_screen.dart @@ -43,6 +43,19 @@ class SampleAppConfigScreen extends StatelessWidget { }, onChanged: (v) => SampleAppConfig.update(context, config.copyWith(themeMode: v)), ), + _SegmentedRow( + title: 'App Style', + value: config.appStyle, + segments: const { + SampleAppStyle.regular: 'Regular', + SampleAppStyle.floating: 'Floating', + }, + segmentIcons: const { + SampleAppStyle.regular: Icons.web_asset_outlined, + SampleAppStyle.floating: Icons.filter_none_outlined, + }, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(appStyle: v)), + ), _LocaleRow(config: config), _SwitchRow( icon: icons.reorder, From 9ba1ba8dcb6082e6b428cdbd17de1bce0d3aafe2 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 12 Jun 2026 13:44:53 +0200 Subject: [PATCH 21/87] Fix extra padding on loading skeletons --- .../stream_channel_list_skeleton_loading.dart | 1 + .../thread_scroll_view/stream_thread_list_skeleton_loading.dart | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_skeleton_loading.dart b/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_skeleton_loading.dart index 005f4d3fe3..c76f8f1101 100644 --- a/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_skeleton_loading.dart +++ b/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_skeleton_loading.dart @@ -19,6 +19,7 @@ class StreamChannelListSkeletonLoading extends StatelessWidget { Widget build(BuildContext context) { return StreamSkeletonLoading( child: ListView.separated( + padding: EdgeInsets.zero, physics: const NeverScrollableScrollPhysics(), itemCount: itemCount, separatorBuilder: (context, index) => const SizedBox(height: 1), diff --git a/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_skeleton_loading.dart b/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_skeleton_loading.dart index 6a92bc91ee..fb6300e8ee 100644 --- a/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_skeleton_loading.dart +++ b/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_skeleton_loading.dart @@ -19,6 +19,7 @@ class StreamThreadListSkeletonLoading extends StatelessWidget { Widget build(BuildContext context) { return StreamSkeletonLoading( child: ListView.separated( + padding: EdgeInsets.zero, physics: const NeverScrollableScrollPhysics(), itemCount: itemCount, separatorBuilder: (context, index) => const SizedBox(height: 1), From dfedb968e97bb12e625928a40ba4dc2210b254b9 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 12 Jun 2026 14:34:40 +0200 Subject: [PATCH 22/87] Update all sample app pages --- .../lib/config/sample_app_config_screen.dart | 279 +++++++++--------- .../lib/pages/advanced_options_page.dart | 5 +- .../pages/channel_file_display_screen.dart | 80 ++--- .../pages/channel_media_display_screen.dart | 65 ++-- sample_app/lib/pages/chat_info_screen.dart | 47 +-- .../lib/pages/group_chat_details_screen.dart | 210 ++++++------- sample_app/lib/pages/group_info_screen.dart | 51 ++-- sample_app/lib/pages/new_chat_screen.dart | 4 +- .../lib/pages/new_group_chat_screen.dart | 4 +- .../lib/pages/pinned_messages_screen.dart | 16 +- 10 files changed, 401 insertions(+), 360 deletions(-) diff --git a/sample_app/lib/config/sample_app_config_screen.dart b/sample_app/lib/config/sample_app_config_screen.dart index 02ae33e58e..faa08bc543 100644 --- a/sample_app/lib/config/sample_app_config_screen.dart +++ b/sample_app/lib/config/sample_app_config_screen.dart @@ -13,155 +13,160 @@ class SampleAppConfigScreen extends StatelessWidget { final spacing = context.streamSpacing; final icons = context.streamIcons; - return Scaffold( + return StreamScaffold( backgroundColor: colorScheme.backgroundApp, appBar: StreamAppBar(title: const Text('Configuration')), - body: SingleChildScrollView( - padding: EdgeInsets.symmetric(horizontal: spacing.md), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: spacing.xs), - - // ── Appearance ── - const _SectionHeader(title: 'Appearance'), - SizedBox(height: spacing.xs), - _SettingsCard( + body: Builder( + builder: (context) { + final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + return SingleChildScrollView( + padding: EdgeInsets.fromLTRB(spacing.md, topInset, spacing.md, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - _SegmentedRow( - title: 'Theme', - value: config.themeMode, - segments: const { - ThemeMode.system: 'System', - ThemeMode.light: 'Light', - ThemeMode.dark: 'Dark', - }, - segmentIcons: const { - ThemeMode.system: Icons.brightness_auto_outlined, - ThemeMode.light: Icons.light_mode_outlined, - ThemeMode.dark: Icons.dark_mode_outlined, - }, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(themeMode: v)), - ), - _SegmentedRow( - title: 'App Style', - value: config.appStyle, - segments: const { - SampleAppStyle.regular: 'Regular', - SampleAppStyle.floating: 'Floating', - }, - segmentIcons: const { - SampleAppStyle.regular: Icons.web_asset_outlined, - SampleAppStyle.floating: Icons.filter_none_outlined, - }, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(appStyle: v)), - ), - _LocaleRow(config: config), - _SwitchRow( - icon: icons.reorder, - title: 'Force RTL', - subtitle: 'Right-to-left layout direction', - value: config.forceRtl, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(forceRtl: v)), + SizedBox(height: spacing.xs), + + // ── Appearance ── + const _SectionHeader(title: 'Appearance'), + SizedBox(height: spacing.xs), + _SettingsCard( + children: [ + _SegmentedRow( + title: 'Theme', + value: config.themeMode, + segments: const { + ThemeMode.system: 'System', + ThemeMode.light: 'Light', + ThemeMode.dark: 'Dark', + }, + segmentIcons: const { + ThemeMode.system: Icons.brightness_auto_outlined, + ThemeMode.light: Icons.light_mode_outlined, + ThemeMode.dark: Icons.dark_mode_outlined, + }, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(themeMode: v)), + ), + _SegmentedRow( + title: 'App Style', + value: config.appStyle, + segments: const { + SampleAppStyle.regular: 'Regular', + SampleAppStyle.floating: 'Floating', + }, + segmentIcons: const { + SampleAppStyle.regular: Icons.web_asset_outlined, + SampleAppStyle.floating: Icons.filter_none_outlined, + }, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(appStyle: v)), + ), + _LocaleRow(config: config), + _SwitchRow( + icon: icons.reorder, + title: 'Force RTL', + subtitle: 'Right-to-left layout direction', + value: config.forceRtl, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(forceRtl: v)), + ), + ], ), - ], - ), - - SizedBox(height: spacing.xl), - // ── Features ── - const _SectionHeader(title: 'Features'), - SizedBox(height: spacing.xs), - _SettingsCard( - children: [ - _SwitchRow( - icon: icons.bell, - title: 'Reminders', - subtitle: 'Remind me, Save for later, Edit', - value: config.enableReminderActions, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(enableReminderActions: v)), - ), - _SwitchRow( - icon: icons.delete, - title: 'Delete for Me', - subtitle: 'Delete message for current user', - value: config.enableDeleteForMe, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(enableDeleteForMe: v)), - ), - _SwitchRow( - icon: icons.info, - title: 'Message Info', - subtitle: 'Show delivery info sheet', - value: config.enableMessageInfo, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(enableMessageInfo: v)), - ), - _SwitchRow( - icon: icons.location, - title: 'Location Sharing', - subtitle: 'Attachment builder and picker', - value: config.enableLocationSharing, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(enableLocationSharing: v)), + SizedBox(height: spacing.xl), + + // ── Features ── + const _SectionHeader(title: 'Features'), + SizedBox(height: spacing.xs), + _SettingsCard( + children: [ + _SwitchRow( + icon: icons.bell, + title: 'Reminders', + subtitle: 'Remind me, Save for later, Edit', + value: config.enableReminderActions, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(enableReminderActions: v)), + ), + _SwitchRow( + icon: icons.delete, + title: 'Delete for Me', + subtitle: 'Delete message for current user', + value: config.enableDeleteForMe, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(enableDeleteForMe: v)), + ), + _SwitchRow( + icon: icons.info, + title: 'Message Info', + subtitle: 'Show delivery info sheet', + value: config.enableMessageInfo, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(enableMessageInfo: v)), + ), + _SwitchRow( + icon: icons.location, + title: 'Location Sharing', + subtitle: 'Attachment builder and picker', + value: config.enableLocationSharing, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(enableLocationSharing: v)), + ), + ], ), - ], - ), - SizedBox(height: spacing.xl), - - // ── Chat ── - const _SectionHeader(title: 'Chat'), - SizedBox(height: spacing.xs), - _SettingsCard( - children: [ - _SwitchRow( - icon: icons.edit, - title: 'Draft Messages', - subtitle: 'Enable draft message saving', - value: config.draftMessagesEnabled, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(draftMessagesEnabled: v)), - ), - _SwitchRow( - icon: icons.emoji, - title: 'Unique Reactions', - subtitle: 'New reaction replaces existing', - value: config.enforceUniqueReactions, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(enforceUniqueReactions: v)), + SizedBox(height: spacing.xl), + + // ── Chat ── + const _SectionHeader(title: 'Chat'), + SizedBox(height: spacing.xs), + _SettingsCard( + children: [ + _SwitchRow( + icon: icons.edit, + title: 'Draft Messages', + subtitle: 'Enable draft message saving', + value: config.draftMessagesEnabled, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(draftMessagesEnabled: v)), + ), + _SwitchRow( + icon: icons.emoji, + title: 'Unique Reactions', + subtitle: 'New reaction replaces existing', + value: config.enforceUniqueReactions, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(enforceUniqueReactions: v)), + ), + ], ), - ], - ), - SizedBox(height: spacing.xl), - - // ── Reactions ── - const _SectionHeader(title: 'Reactions'), - SizedBox(height: spacing.xs), - _SettingsCard( - children: [ - _SegmentedRow( - title: 'Reaction Type', - value: config.reactionType, - segments: const { - null: 'Default', - StreamReactionsType.segmented: 'Segmented', - StreamReactionsType.clustered: 'Clustered', - }, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(reactionType: v)), - ), - _SegmentedRow( - title: 'Reaction Position', - value: config.reactionPosition, - segments: const { - null: 'Default', - StreamReactionsPosition.header: 'Header', - StreamReactionsPosition.footer: 'Footer', - }, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(reactionPosition: v)), + SizedBox(height: spacing.xl), + + // ── Reactions ── + const _SectionHeader(title: 'Reactions'), + SizedBox(height: spacing.xs), + _SettingsCard( + children: [ + _SegmentedRow( + title: 'Reaction Type', + value: config.reactionType, + segments: const { + null: 'Default', + StreamReactionsType.segmented: 'Segmented', + StreamReactionsType.clustered: 'Clustered', + }, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(reactionType: v)), + ), + _SegmentedRow( + title: 'Reaction Position', + value: config.reactionPosition, + segments: const { + null: 'Default', + StreamReactionsPosition.header: 'Header', + StreamReactionsPosition.footer: 'Footer', + }, + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(reactionPosition: v)), + ), + ], ), + + SizedBox(height: spacing.xxl), ], ), - - SizedBox(height: spacing.xxl), - ], - ), + ); + }, ), ); } diff --git a/sample_app/lib/pages/advanced_options_page.dart b/sample_app/lib/pages/advanced_options_page.dart index 525e4cf2da..6533a122f9 100644 --- a/sample_app/lib/pages/advanced_options_page.dart +++ b/sample_app/lib/pages/advanced_options_page.dart @@ -100,13 +100,14 @@ class _AdvancedOptionsPageState extends State { @override Widget build(BuildContext context) { - return Scaffold( + return StreamScaffold( backgroundColor: context.streamColorScheme.backgroundApp, appBar: StreamAppBar(title: const Text('Custom settings')), body: Builder( builder: (context) { + final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; return Padding( - padding: const EdgeInsets.fromLTRB(16, 16, 16, 0), + padding: EdgeInsets.fromLTRB(16, 16 + topInset, 16, 0), child: Form( key: _formKey, child: Column( diff --git a/sample_app/lib/pages/channel_file_display_screen.dart b/sample_app/lib/pages/channel_file_display_screen.dart index 5cc931d83a..b0effdb1b5 100644 --- a/sample_app/lib/pages/channel_file_display_screen.dart +++ b/sample_app/lib/pages/channel_file_display_screen.dart @@ -39,50 +39,54 @@ class _ChannelFileDisplayScreenState extends State { @override Widget build(BuildContext context) { final colorScheme = context.streamColorScheme; - return Scaffold( + return StreamScaffold( backgroundColor: colorScheme.backgroundApp, appBar: StreamAppBar(title: const Text('Files')), body: ValueListenableBuilder>( valueListenable: _controller, - builder: (context, value, _) => value.when( - (items, nextPageKey, _) { - // Flatten messages → individual file attachments paired with - // the message timestamp we'll bucket on. - final entries = <_FileEntry>[ - for (final response in items) - for (final attachment in response.message.attachments) - if (attachment.type == 'file') - _FileEntry( - attachment: attachment, - sentAt: response.message.createdAt, - ), - ]; - - if (entries.isEmpty) return const Center(child: _EmptyState()); - - // Pre-build a flat row list — interleave a header row above - // each month bucket so a single ListView.builder can render - // both kinds of rows without a CustomScrollView + slivers. - final rows = _buildRows(entries); - - return LazyLoadScrollView( - onEndOfPage: () async { - if (nextPageKey != null) await _controller.loadMore(nextPageKey); - }, - child: ListView.builder( - itemCount: rows.length, - itemBuilder: (context, index) => rows[index].build(context), + builder: (context, value, _) { + final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + return value.when( + (items, nextPageKey, _) { + // Flatten messages → individual file attachments paired with + // the message timestamp we'll bucket on. + final entries = <_FileEntry>[ + for (final response in items) + for (final attachment in response.message.attachments) + if (attachment.type == 'file') + _FileEntry( + attachment: attachment, + sentAt: response.message.createdAt, + ), + ]; + + if (entries.isEmpty) return const Center(child: _EmptyState()); + + // Pre-build a flat row list — interleave a header row above + // each month bucket so a single ListView.builder can render + // both kinds of rows without a CustomScrollView + slivers. + final rows = _buildRows(entries); + + return LazyLoadScrollView( + onEndOfPage: () async { + if (nextPageKey != null) await _controller.loadMore(nextPageKey); + }, + child: ListView.builder( + padding: EdgeInsets.only(top: topInset), + itemCount: rows.length, + itemBuilder: (context, index) => rows[index].build(context), + ), + ); + }, + loading: () => const Center(child: StreamScrollViewLoadingWidget()), + error: (_) => Center( + child: StreamScrollViewErrorWidget( + errorTitle: const Text('Failed to load files'), + onRetryPressed: _controller.refresh, ), - ); - }, - loading: () => const Center(child: StreamScrollViewLoadingWidget()), - error: (_) => Center( - child: StreamScrollViewErrorWidget( - errorTitle: const Text('Failed to load files'), - onRetryPressed: _controller.refresh, ), - ), - ), + ); + }, ), ); } diff --git a/sample_app/lib/pages/channel_media_display_screen.dart b/sample_app/lib/pages/channel_media_display_screen.dart index 3aac2fabf4..01351a702a 100644 --- a/sample_app/lib/pages/channel_media_display_screen.dart +++ b/sample_app/lib/pages/channel_media_display_screen.dart @@ -38,44 +38,49 @@ class _ChannelMediaDisplayScreenState extends State { @override Widget build(BuildContext context) { final colorScheme = context.streamColorScheme; - return Scaffold( + return StreamScaffold( backgroundColor: colorScheme.backgroundApp, appBar: StreamAppBar(title: Text(context.translations.photosAndVideosLabel)), body: ValueListenableBuilder>( valueListenable: _controller, - builder: (context, value, _) => value.when( - (items, nextPageKey, _) { - // Flatten messages → individual image/video attachments. - // Excludes link previews (`ogScrapeUrl != null`) so we don't - // render every shared URL's thumbnail in the grid. - final attachments = [ - for (final response in items) - ...response.message.toMediaGalleryAttachments( - filter: (a) => - (a.type == AttachmentType.image || a.type == AttachmentType.video) && a.ogScrapeUrl == null, - ), - ]; + builder: (context, value, _) { + final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final spacing = context.streamSpacing; + return value.when( + (items, nextPageKey, _) { + // Flatten messages → individual image/video attachments. + // Excludes link previews (`ogScrapeUrl != null`) so we don't + // render every shared URL's thumbnail in the grid. + final attachments = [ + for (final response in items) + ...response.message.toMediaGalleryAttachments( + filter: (a) => + (a.type == AttachmentType.image || a.type == AttachmentType.video) && a.ogScrapeUrl == null, + ), + ]; - if (attachments.isEmpty) return const Center(child: _EmptyState()); + if (attachments.isEmpty) return const Center(child: _EmptyState()); - return LazyLoadScrollView( - onEndOfPage: () async { - if (nextPageKey != null) await _controller.loadMore(nextPageKey); - }, - child: StreamMediaGallery( - attachments: attachments, - onItemTap: (index) => _openPreview(context, attachments, index), + return LazyLoadScrollView( + onEndOfPage: () async { + if (nextPageKey != null) await _controller.loadMore(nextPageKey); + }, + child: StreamMediaGallery( + attachments: attachments, + padding: EdgeInsets.fromLTRB(spacing.xxxs, topInset + spacing.xxxs, spacing.xxxs, spacing.xxxs), + onItemTap: (index) => _openPreview(context, attachments, index), + ), + ); + }, + loading: () => const Center(child: StreamScrollViewLoadingWidget()), + error: (_) => Center( + child: StreamScrollViewErrorWidget( + errorTitle: const Text('Failed to load media'), + onRetryPressed: _controller.refresh, ), - ); - }, - loading: () => const Center(child: StreamScrollViewLoadingWidget()), - error: (_) => Center( - child: StreamScrollViewErrorWidget( - errorTitle: const Text('Failed to load media'), - onRetryPressed: _controller.refresh, ), - ), - ), + ); + }, ), ); } diff --git a/sample_app/lib/pages/chat_info_screen.dart b/sample_app/lib/pages/chat_info_screen.dart index 77906922ed..e9d605132a 100644 --- a/sample_app/lib/pages/chat_info_screen.dart +++ b/sample_app/lib/pages/chat_info_screen.dart @@ -27,31 +27,36 @@ class ChatInfoScreen extends StatelessWidget { final spacing = context.streamSpacing; final colorScheme = context.streamColorScheme; - return Scaffold( + return StreamScaffold( backgroundColor: colorScheme.backgroundApp, appBar: StreamAppBar(title: const Text('Contact Info')), // Action / chevron icons share a uniform 20px size — set once at the // top of the body so individual rows stay style-free. - body: IconTheme.merge( - data: const IconThemeData(size: 20), - child: SingleChildScrollView( - padding: .directional( - top: spacing.xxl, - bottom: spacing.xxxl, - start: spacing.md, - end: spacing.md, - ), - child: Column( - mainAxisSize: .min, - children: [ - _ContactInfoHeader(user: user), - SizedBox(height: spacing.xxl), - const _MediaSection(), - SizedBox(height: spacing.md), - const _ActionsSection(), - ], - ), - ), + body: Builder( + builder: (context) { + final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + return IconTheme.merge( + data: const IconThemeData(size: 20), + child: SingleChildScrollView( + padding: .directional( + top: spacing.xxl + topInset, + bottom: spacing.xxxl, + start: spacing.md, + end: spacing.md, + ), + child: Column( + mainAxisSize: .min, + children: [ + _ContactInfoHeader(user: user), + SizedBox(height: spacing.xxl), + const _MediaSection(), + SizedBox(height: spacing.md), + const _ActionsSection(), + ], + ), + ), + ); + }, ), ); } diff --git a/sample_app/lib/pages/group_chat_details_screen.dart b/sample_app/lib/pages/group_chat_details_screen.dart index 08fc6dbb62..9a7b1adc80 100644 --- a/sample_app/lib/pages/group_chat_details_screen.dart +++ b/sample_app/lib/pages/group_chat_details_screen.dart @@ -48,7 +48,7 @@ class _GroupChatDetailsScreenState extends State { GoRouter.of(context).pop(); return false; }, - child: Scaffold( + child: StreamScaffold( backgroundColor: context.streamColorScheme.backgroundApp, appBar: StreamAppBar( title: const Text('Name of Group Chat'), @@ -105,117 +105,123 @@ class _GroupChatDetailsScreenState extends State { tileAnchor: Alignment.topCenter, childAnchor: Alignment.topCenter, message: statusString, - child: Column( - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 16), - child: Row( - children: [ - Text( - 'Name'.toUpperCase(), - style: TextStyle( - fontSize: 12, - color: context.streamColorScheme.textSecondary, - ), - ), - const SizedBox(width: 16), - Expanded( - child: TextField( - controller: _groupNameController, - decoration: InputDecoration( - isDense: true, - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - errorBorder: InputBorder.none, - disabledBorder: InputBorder.none, - contentPadding: EdgeInsets.zero, - hintText: 'Choose a group chat name', - hintStyle: TextStyle( - fontSize: 14, + child: Builder( + builder: (context) { + final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + return Column( + children: [ + if (topInset > 0) SizedBox(height: topInset), + Padding( + padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 16), + child: Row( + children: [ + Text( + 'Name'.toUpperCase(), + style: TextStyle( + fontSize: 12, color: context.streamColorScheme.textSecondary, ), ), - ), + const SizedBox(width: 16), + Expanded( + child: TextField( + controller: _groupNameController, + decoration: InputDecoration( + isDense: true, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + errorBorder: InputBorder.none, + disabledBorder: InputBorder.none, + contentPadding: EdgeInsets.zero, + hintText: 'Choose a group chat name', + hintStyle: TextStyle( + fontSize: 14, + color: context.streamColorScheme.textSecondary, + ), + ), + ), + ), + ], ), - ], - ), - ), - Container( - width: double.maxFinite, - decoration: BoxDecoration( - color: context.streamColorScheme.backgroundElevation1, - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 8, - horizontal: 8, ), - child: Text( - '$_totalUsers ${_totalUsers > 1 ? 'Members' : 'Member'}', - style: TextStyle( - color: context.streamColorScheme.textSecondary, + Container( + width: double.maxFinite, + decoration: BoxDecoration( + color: context.streamColorScheme.backgroundElevation1, ), - ), - ), - ), - AnimatedBuilder( - animation: widget.groupChatState, - builder: (context, child) { - return Expanded( - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onPanDown: (_) => FocusScope.of(context).unfocus(), - child: ListView.separated( - itemCount: widget.groupChatState.users.length + 1, - separatorBuilder: (_, __) => Container( - height: 1, - color: context.streamColorScheme.borderDefault, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 8, + ), + child: Text( + '$_totalUsers ${_totalUsers > 1 ? 'Members' : 'Member'}', + style: TextStyle( + color: context.streamColorScheme.textSecondary, ), - itemBuilder: (_, index) { - if (index == widget.groupChatState.users.length) { - return Container( + ), + ), + ), + AnimatedBuilder( + animation: widget.groupChatState, + builder: (context, child) { + return Expanded( + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onPanDown: (_) => FocusScope.of(context).unfocus(), + child: ListView.separated( + itemCount: widget.groupChatState.users.length + 1, + separatorBuilder: (_, __) => Container( height: 1, color: context.streamColorScheme.borderDefault, - ); - } - final user = widget.groupChatState.users.elementAt(index); - return ListTile( - key: ObjectKey(user), - leading: StreamUserAvatar( - size: .lg, - user: user, - ), - title: Text( - user.name, - style: const TextStyle(fontWeight: FontWeight.bold), ), - contentPadding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 8, - ), - trailing: IconButton( - icon: Icon( - Icons.clear_rounded, - color: context.streamColorScheme.textPrimary, - ), - padding: EdgeInsets.zero, - splashRadius: 24, - onPressed: () { - widget.groupChatState.removeUser(user); - if (widget.groupChatState.users.isEmpty) { - GoRouter.of(context).pop(); - } - }, - ), - ); - }, - ), - ), - ); - }, - ), - ], + itemBuilder: (_, index) { + if (index == widget.groupChatState.users.length) { + return Container( + height: 1, + color: context.streamColorScheme.borderDefault, + ); + } + final user = widget.groupChatState.users.elementAt(index); + return ListTile( + key: ObjectKey(user), + leading: StreamUserAvatar( + size: .lg, + user: user, + ), + title: Text( + user.name, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + contentPadding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 8, + ), + trailing: IconButton( + icon: Icon( + Icons.clear_rounded, + color: context.streamColorScheme.textPrimary, + ), + padding: EdgeInsets.zero, + splashRadius: 24, + onPressed: () { + widget.groupChatState.removeUser(user); + if (widget.groupChatState.users.isEmpty) { + GoRouter.of(context).pop(); + } + }, + ), + ); + }, + ), + ), + ); + }, + ), + ], + ); + }, ), ); }, diff --git a/sample_app/lib/pages/group_info_screen.dart b/sample_app/lib/pages/group_info_screen.dart index 3f26366c6f..0d1ed66cea 100644 --- a/sample_app/lib/pages/group_info_screen.dart +++ b/sample_app/lib/pages/group_info_screen.dart @@ -24,7 +24,7 @@ class GroupInfoScreen extends StatelessWidget { final colorScheme = context.streamColorScheme; final channel = StreamChannel.of(context).channel; - return Scaffold( + return StreamScaffold( backgroundColor: colorScheme.backgroundApp, appBar: StreamAppBar( title: const Text('Group Info'), @@ -41,28 +41,33 @@ class GroupInfoScreen extends StatelessWidget { ), // Action / chevron icons share a uniform 20px size — set once at the // top of the body so individual rows stay style-free. - body: IconTheme.merge( - data: const IconThemeData(size: 20), - child: SingleChildScrollView( - padding: .directional( - top: spacing.xxl, - bottom: spacing.xxxl, - start: spacing.md, - end: spacing.md, - ), - child: Column( - mainAxisSize: .min, - children: [ - const _GroupInfoHeader(), - SizedBox(height: spacing.xxl), - const _MediaSection(), - SizedBox(height: spacing.md), - const _MembersSection(), - SizedBox(height: spacing.md), - const _ActionsSection(), - ], - ), - ), + body: Builder( + builder: (context) { + final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + return IconTheme.merge( + data: const IconThemeData(size: 20), + child: SingleChildScrollView( + padding: .directional( + top: spacing.xxl + topInset, + bottom: spacing.xxxl, + start: spacing.md, + end: spacing.md, + ), + child: Column( + mainAxisSize: .min, + children: [ + const _GroupInfoHeader(), + SizedBox(height: spacing.xxl), + const _MediaSection(), + SizedBox(height: spacing.md), + const _MembersSection(), + SizedBox(height: spacing.md), + const _ActionsSection(), + ], + ), + ), + ); + }, ), ); } diff --git a/sample_app/lib/pages/new_chat_screen.dart b/sample_app/lib/pages/new_chat_screen.dart index 673292ef39..fecf2a56a4 100644 --- a/sample_app/lib/pages/new_chat_screen.dart +++ b/sample_app/lib/pages/new_chat_screen.dart @@ -138,11 +138,12 @@ class _NewChatScreenState extends State { @override Widget build(BuildContext context) { - return Scaffold( + return StreamScaffold( backgroundColor: context.streamColorScheme.backgroundApp, appBar: StreamAppBar(title: const Text('New Chat')), body: StreamConnectionStatusBuilder( statusBuilder: (context, status) { + final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; var statusString = ''; var showStatus = true; @@ -169,6 +170,7 @@ class _NewChatScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + if (topInset > 0) SizedBox(height: topInset), ChipsInputTextField( key: _chipInputTextFieldStateKey, controller: _controller, diff --git a/sample_app/lib/pages/new_group_chat_screen.dart b/sample_app/lib/pages/new_group_chat_screen.dart index b5d9c2eb53..5f9565fbdf 100644 --- a/sample_app/lib/pages/new_group_chat_screen.dart +++ b/sample_app/lib/pages/new_group_chat_screen.dart @@ -66,7 +66,7 @@ class _NewGroupChatScreenState extends State { animation: groupChatState, builder: (context, child) { final state = groupChatState; - return Scaffold( + return StreamScaffold( backgroundColor: context.streamColorScheme.backgroundApp, appBar: StreamAppBar( title: const Text('Add Group Members'), @@ -108,7 +108,9 @@ class _NewGroupChatScreenState extends State { child: NestedScrollView( floatHeaderSlivers: true, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { + final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; return [ + if (topInset > 0) SliverToBoxAdapter(child: SizedBox(height: topInset)), SliverToBoxAdapter( child: SearchTextField( controller: _controller, diff --git a/sample_app/lib/pages/pinned_messages_screen.dart b/sample_app/lib/pages/pinned_messages_screen.dart index f2b52a4b16..e07c2e1aa3 100644 --- a/sample_app/lib/pages/pinned_messages_screen.dart +++ b/sample_app/lib/pages/pinned_messages_screen.dart @@ -37,13 +37,19 @@ class _PinnedMessagesScreenState extends State { Widget build(BuildContext context) { final colorScheme = context.streamColorScheme; - return Scaffold( + return StreamScaffold( backgroundColor: colorScheme.backgroundApp, appBar: StreamAppBar(title: const Text('Pinned Messages')), - body: StreamMessageSearchListView( - controller: _controller, - emptyBuilder: (_) => const Center(child: _EmptyState()), - onMessageTap: _openMessage, + body: Builder( + builder: (context) { + final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + return StreamMessageSearchListView( + controller: _controller, + padding: EdgeInsets.only(top: topInset), + emptyBuilder: (_) => const Center(child: _EmptyState()), + onMessageTap: _openMessage, + ); + }, ), ); } From c431a3b0ad47abb596f215991eefd0893b77bf12 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 12 Jun 2026 14:35:26 +0200 Subject: [PATCH 23/87] update core dependency --- docs/docs_screenshots/pubspec.yaml | 2 +- melos.yaml | 2 +- packages/stream_chat_flutter/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index e4850a697d..d1b301dc8c 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: bb75889af53a2a9e42939adb4e222680b18142d4 + ref: 6f8ba0c07a6ffbc6e0ea96c560f010cf48b8012b path: packages/stream_core_flutter dev_dependencies: diff --git a/melos.yaml b/melos.yaml index 960b81fb44..1b0b621311 100644 --- a/melos.yaml +++ b/melos.yaml @@ -101,7 +101,7 @@ command: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: bb75889af53a2a9e42939adb4e222680b18142d4 + ref: 6f8ba0c07a6ffbc6e0ea96c560f010cf48b8012b path: packages/stream_core_flutter synchronized: ^3.4.0 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 374ccefdd0..eab51be6bc 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -68,7 +68,7 @@ dependencies: # ignore: invalid_dependency git: url: https://github.com/GetStream/stream-core-flutter - ref: bb75889af53a2a9e42939adb4e222680b18142d4 + ref: 6f8ba0c07a6ffbc6e0ea96c560f010cf48b8012b path: packages/stream_core_flutter svg_icon_widget: ^0.0.1 synchronized: ^3.4.0 From fb4f234f30eab3900f40242d1d3c887429781a54 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 12 Jun 2026 14:55:37 +0200 Subject: [PATCH 24/87] Add global message list config --- packages/stream_chat_flutter/CHANGELOG.md | 1 + .../lib/src/channel/channel_page.dart | 11 ---- .../lib/src/channel/thread_page.dart | 5 -- .../message_list_view/message_list_view.dart | 64 +++++++++++-------- .../lib/src/stream_chat_configuration.dart | 12 ++++ sample_app/lib/app.dart | 4 ++ sample_app/lib/routes/app_routes.dart | 1 - 7 files changed, 54 insertions(+), 44 deletions(-) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 3e97b702a5..f8e94349f5 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -2,6 +2,7 @@ ✅ Added +- Added `messageListViewConfiguration` field to `StreamChatConfigurationData`, allowing a global `StreamMessageListViewConfiguration` default for all `StreamMessageListView` widgets. Pass it via `StreamChat.configData` to configure behaviors like `swipeToReply` and `highlightInitialMessage` app-wide without wiring them per-page. - `StreamMessageComposer` now surfaces the hold-to-record hint through `StreamSnackbar` anchored above the composer, and `StreamChat` provides an app-wide `StreamSnackbarScope` fallback. ⚠️ Deprecated diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index 48e21105f4..e3d18c4212 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -8,7 +8,6 @@ class StreamChannelPage extends StatefulWidget { super.key, this.initialScrollIndex, this.initialAlignment, - this.highlightInitialMessage = false, this.onBackPressed, this.onChannelAvatarPressed, }); @@ -19,9 +18,6 @@ class StreamChannelPage extends StatefulWidget { /// Initial scroll alignment for the message list. final double? initialAlignment; - /// Whether to highlight the initial message. - final bool highlightInitialMessage; - /// Callback for when the back button is pressed. final VoidCallback? onBackPressed; @@ -92,7 +88,6 @@ class _StreamChannelPageState extends State { body: _ChannelPageBody( initialScrollIndex: widget.initialScrollIndex, initialAlignment: widget.initialAlignment, - highlightInitialMessage: widget.highlightInitialMessage, onReply: _reply, onEditMessage: _editMessage, typingIndicator: typingIndicator, @@ -114,7 +109,6 @@ class _ChannelPageBody extends StatelessWidget { required this.onEditMessage, this.initialScrollIndex, this.initialAlignment, - this.highlightInitialMessage = false, }); final Widget typingIndicator; @@ -122,7 +116,6 @@ class _ChannelPageBody extends StatelessWidget { final void Function(Message) onEditMessage; final int? initialScrollIndex; final double? initialAlignment; - final bool highlightInitialMessage; @override Widget build(BuildContext context) { @@ -133,10 +126,6 @@ class _ChannelPageBody extends StatelessWidget { StreamMessageListView( initialScrollIndex: initialScrollIndex, initialAlignment: initialAlignment, - config: StreamMessageListViewConfiguration( - highlightInitialMessage: highlightInitialMessage, - swipeToReply: true, - ), onEditMessageTap: onEditMessage, onReplyTap: onReply, threadBuilder: (_, parentMessage) { diff --git a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart index a68d4cfdd3..00050d4d42 100644 --- a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart @@ -115,11 +115,6 @@ class _ThreadBody extends StatelessWidget { initialAlignment: initialAlignment, onReplyTap: onReply, onEditMessageTap: onEditMessageTap, - config: const StreamMessageListViewConfiguration( - swipeToReply: true, - showScrollToBottom: false, - highlightInitialMessage: true, - ), onViewInChannelTap: onViewInChannelTap, topPadding: insets.topPadding, bottomPadding: insets.bottomPadding, diff --git a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart index f9c9f722ac..d4d02f904f 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart @@ -123,7 +123,7 @@ class StreamMessageListView extends StatefulWidget { this.onEphemeralMessageTap, this.onModeratedMessageTap, this.onMessageLongPress, - this.config = const StreamMessageListViewConfiguration(), + this.config, this.builders = const StreamMessageListViewBuilders(), this.topPadding = 0, this.bottomPadding = 0, @@ -249,8 +249,10 @@ class StreamMessageListView extends StatefulWidget { /// [StreamMessageListViewConfiguration.markReadWhenAtTheBottom], scroll /// physics, and other non-builder, non-theme settings. /// - /// Defaults to [StreamMessageListViewConfiguration] with all defaults. - final StreamMessageListViewConfiguration config; + /// When null, falls back to + /// [StreamChatConfigurationData.messageListViewConfiguration] from the + /// nearest [StreamChatConfiguration] ancestor. + final StreamMessageListViewConfiguration? config; /// Custom slot builders for this message list view. /// @@ -324,6 +326,14 @@ class _StreamMessageListViewState extends State { MessageListController get _messageListController => widget.messageListController ?? _defaultController; + /// Returns the effective [StreamMessageListViewConfiguration] for this list. + /// + /// Uses [widget.config] when explicitly provided, otherwise falls back to + /// [StreamChatConfigurationData.messageListViewConfiguration] from the + /// nearest [StreamChatConfiguration] ancestor. + StreamMessageListViewConfiguration get _config => + widget.config ?? StreamChatConfiguration.of(context).messageListViewConfiguration; + StreamSubscription? _messageNewListener; StreamSubscription? _userReadListener; @@ -351,7 +361,7 @@ class _StreamMessageListViewState extends State { _unreadState.value = _readUnreadSnapshot(); - final highlightInitialMessage = widget.config.highlightInitialMessage; + final highlightInitialMessage = _config.highlightInitialMessage; final highlightMessageId = switch ((highlightInitialMessage, _isThreadConversation)) { (true, true) => _ThreadHighlightScope.of(context), (true, false) => streamChannel?.initialMessageId, @@ -547,9 +557,9 @@ class _StreamMessageListViewState extends State { child: Portal( child: ScaffoldMessenger( child: MessageListCore( - paginationLimit: widget.config.paginationLimit, - maximumMessageLimit: widget.config.maximumMessageLimit, - retentionTrimBuffer: widget.config.retentionTrimBuffer, + paginationLimit: _config.paginationLimit, + maximumMessageLimit: _config.maximumMessageLimit, + retentionTrimBuffer: _config.retentionTrimBuffer, messageFilter: widget.messageFilter, loadingBuilder: defaultLoadingBuilder, emptyBuilder: defaultEmptyBuilder, @@ -593,7 +603,7 @@ class _StreamMessageListViewState extends State { } return StreamInfoTile( - showMessage: widget.config.showConnectionStateTile && showStatus, + showMessage: _config.showConnectionStateTile && showStatus, tileAnchor: Alignment.topCenter, childAnchor: Alignment.topCenter, message: statusString, @@ -611,14 +621,14 @@ class _StreamMessageListViewState extends State { top: max(widget.topPadding, context.streamSpacing.sm), bottom: max(widget.bottomPadding, context.streamSpacing.sm), ), - keyboardDismissBehavior: widget.config.keyboardDismissBehavior, + keyboardDismissBehavior: _config.keyboardDismissBehavior, itemPositionsListener: _itemPositionListener, initialScrollIndex: initialIndex, initialAlignment: initialAlignment, - physics: widget.config.scrollPhysics, + physics: _config.scrollPhysics, itemScrollController: _scrollController, - reverse: widget.config.reverse, - shrinkWrap: widget.config.shrinkWrap, + reverse: _config.reverse, + shrinkWrap: _config.shrinkWrap, itemCount: itemCount, itemKeyBuilder: (index) { // Layout (see comment block below): indices 0/1 and the @@ -662,7 +672,7 @@ class _StreamMessageListViewState extends State { return ThreadSeparator(parentMessage: widget.parentMessage!); } if (i == itemCount - 3) { - if (widget.config.reverse ? widget.builders.header == null : widget.builders.footer == null) { + if (_config.reverse ? widget.builders.header == null : widget.builders.footer == null) { if (messages.isNotEmpty) { final message = messages.last; return _maybeBuildWithUnreadMessagesSeparator( @@ -676,7 +686,7 @@ class _StreamMessageListViewState extends State { return const SizedBox(height: 8); } if (i == 0) { - if (widget.config.reverse ? widget.builders.footer == null : widget.builders.header == null) { + if (_config.reverse ? widget.builders.footer == null : widget.builders.header == null) { return const Empty(); } return const SizedBox(height: 8); @@ -685,7 +695,7 @@ class _StreamMessageListViewState extends State { if (i == 1 || i == itemCount - 4) return const Empty(); late final Message message, nextMessage; - if (widget.config.reverse) { + if (_config.reverse) { message = messages[i - 1]; nextMessage = messages[i - 2]; } else { @@ -722,7 +732,7 @@ class _StreamMessageListViewState extends State { } if (i == itemCount - 2) { - if (widget.config.reverse) { + if (_config.reverse) { return widget.builders.header?.call(context) ?? const Empty(); } else { return widget.builders.footer?.call(context) ?? const Empty(); @@ -744,7 +754,7 @@ class _StreamMessageListViewState extends State { } if (i == 0) { - if (widget.config.reverse) { + if (_config.reverse) { return widget.builders.footer?.call(context) ?? const Empty(); } else { return widget.builders.header?.call(context) ?? const Empty(); @@ -763,13 +773,13 @@ class _StreamMessageListViewState extends State { ); }, ), - if (widget.config.showFloatingDateDivider) + if (_config.showFloatingDateDivider) Positioned( top: max(widget.topPadding, context.streamSpacing.sm), child: FloatingDateDivider( itemCount: itemCount, - reverse: widget.config.reverse, - fadeNearInlineDivider: widget.config.fadeFloatingDateDividerNearInline, + reverse: _config.reverse, + fadeNearInlineDivider: _config.fadeFloatingDateDividerNearInline, itemPositionListener: _itemPositionListener.itemPositions, messages: messages, dateDividerBuilder: switch (widget.builders.floatingDateDivider) { @@ -778,7 +788,7 @@ class _StreamMessageListViewState extends State { }, ), ), - if (widget.config.showScrollToBottom) + if (_config.showScrollToBottom) BetterStreamBuilder( stream: streamChannel!.channel.state!.isUpToDateStream, initialData: streamChannel!.channel.state!.isUpToDate, @@ -791,7 +801,7 @@ class _StreamMessageListViewState extends State { }, ), ), - if (widget.config.showUnreadIndicator && !_isThreadConversation) + if (_config.showUnreadIndicator && !_isThreadConversation) Positioned( top: max(widget.topPadding, context.streamSpacing.sm), child: UnreadIndicatorButton( @@ -989,7 +999,7 @@ class _StreamMessageListViewState extends State { Widget buildParentMessage(Message message) { final parentMessageProps = StreamMessageItemProps( message: message, - swipeToReply: widget.config.swipeToReply, + swipeToReply: _config.swipeToReply, onThreadTap: _onThreadTap, onMessageTap: widget.onMessageTap, onMessageLongPress: widget.onMessageLongPress, @@ -1042,14 +1052,14 @@ class _StreamMessageListViewState extends State { type: .outline, size: .medium, isFloating: true, - icon: switch (widget.config.reverse) { + icon: switch (_config.reverse) { true => Icon(context.streamIcons.arrowDown), false => Icon(context.streamIcons.arrowUp), }, onPressed: () => scrollToBottomDefaultTapAction(unreadCount), ); - if (showUnreadCount && widget.config.showUnreadCountOnScrollToBottom) { + if (showUnreadCount && _config.showUnreadCountOnScrollToBottom) { button = StreamBadgeNotification( label: '${unreadCount > 99 ? '99+' : unreadCount}', child: button, @@ -1110,7 +1120,7 @@ class _StreamMessageListViewState extends State { final messageItemProps = StreamMessageItemProps( message: message, - swipeToReply: widget.config.swipeToReply, + swipeToReply: _config.swipeToReply, onThreadTap: _onThreadTap, onViewInChannelTap: _isThreadConversation ? widget.onViewInChannelTap ?? (message) => Navigator.of(context).pop(message.id) @@ -1195,7 +1205,7 @@ class _StreamMessageListViewState extends State { _lastFullyVisibleMessage = newLastFullyVisibleMessage; // Mark messages as read if needed. - if (widget.config.markReadWhenAtTheBottom) { + if (_config.markReadWhenAtTheBottom) { _maybeMarkMessagesAsRead().ignore(); } } diff --git a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart index f8958c6ffa..6b1e1a072b 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart @@ -165,6 +165,8 @@ class StreamChatConfigurationData { List? attachmentBuilders, StreamReactionsType? reactionType, StreamReactionsPosition? reactionPosition, + StreamMessageListViewConfiguration messageListViewConfiguration = + const StreamMessageListViewConfiguration(), }) { return StreamChatConfigurationData._( reactionIconResolver: reactionIconResolver ?? const DefaultReactionIconResolver(), @@ -175,6 +177,7 @@ class StreamChatConfigurationData { attachmentBuilders: attachmentBuilders, reactionType: reactionType, reactionPosition: reactionPosition, + messageListViewConfiguration: messageListViewConfiguration, ); } @@ -185,6 +188,7 @@ class StreamChatConfigurationData { required this.messagePreviewFormatter, required this.imageCDN, required this.attachmentBuilders, + required this.messageListViewConfiguration, this.reactionType, this.reactionPosition, }); @@ -200,6 +204,7 @@ class StreamChatConfigurationData { List? attachmentBuilders, StreamReactionsType? reactionType, StreamReactionsPosition? reactionPosition, + StreamMessageListViewConfiguration? messageListViewConfiguration, }) { return StreamChatConfigurationData( reactionIconResolver: reactionIconResolver ?? this.reactionIconResolver, @@ -210,6 +215,7 @@ class StreamChatConfigurationData { attachmentBuilders: attachmentBuilders ?? this.attachmentBuilders, reactionType: reactionType ?? this.reactionType, reactionPosition: reactionPosition ?? this.reactionPosition, + messageListViewConfiguration: messageListViewConfiguration ?? this.messageListViewConfiguration, ); } @@ -258,4 +264,10 @@ class StreamChatConfigurationData { /// When null, the widget resolves its own default /// ([StreamReactionsPosition.header]). final StreamReactionsPosition? reactionPosition; + + /// The default [StreamMessageListViewConfiguration] applied to every + /// [StreamMessageListView] that does not provide its own explicit [config]. + /// + /// Defaults to [StreamMessageListViewConfiguration] with all defaults. + final StreamMessageListViewConfiguration messageListViewConfiguration; } diff --git a/sample_app/lib/app.dart b/sample_app/lib/app.dart index 6e69708419..c748278aef 100644 --- a/sample_app/lib/app.dart +++ b/sample_app/lib/app.dart @@ -258,6 +258,10 @@ extension on SampleAppConfigData { }, ), ], + messageListViewConfiguration: const StreamMessageListViewConfiguration( + highlightInitialMessage: true, + swipeToReply: true, + ), ); } } diff --git a/sample_app/lib/routes/app_routes.dart b/sample_app/lib/routes/app_routes.dart index 547ce90cfa..f593cf50ad 100644 --- a/sample_app/lib/routes/app_routes.dart +++ b/sample_app/lib/routes/app_routes.dart @@ -45,7 +45,6 @@ final appRoutes = [ return (parentMessage != null) ? StreamThreadPage(parent: parentMessage) : StreamChannelPage( - highlightInitialMessage: messageId != null, onChannelAvatarPressed: (context, channel) { final isOneToOne = channel.isOneToOne; final currentUserId = StreamChat.of(context).currentUser?.id; From 3ac8eb5cbeca1ab124c6bf9cd403f6b332383e12 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 12 Jun 2026 15:04:20 +0200 Subject: [PATCH 25/87] Fix scroll button showing on thread --- .../message_list_view/message_list_view.dart | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart index d4d02f904f..f83dd7b8c8 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart @@ -789,18 +789,28 @@ class _StreamMessageListViewState extends State { ), ), if (_config.showScrollToBottom) - BetterStreamBuilder( - stream: streamChannel!.channel.state!.isUpToDateStream, - initialData: streamChannel!.channel.state!.isUpToDate, - builder: (context, snapshot) => ValueListenableBuilder( + if (_isThreadConversation) + ValueListenableBuilder( valueListenable: _showScrollToBottom, child: _buildScrollToBottom(), builder: (context, value, child) { - if (!snapshot || value) return child!; + if (value) return child!; return const Empty(); }, + ) + else + BetterStreamBuilder( + stream: streamChannel!.channel.state!.isUpToDateStream, + initialData: streamChannel!.channel.state!.isUpToDate, + builder: (context, snapshot) => ValueListenableBuilder( + valueListenable: _showScrollToBottom, + child: _buildScrollToBottom(), + builder: (context, value, child) { + if (!snapshot || value) return child!; + return const Empty(); + }, + ), ), - ), if (_config.showUnreadIndicator && !_isThreadConversation) Positioned( top: max(widget.topPadding, context.streamSpacing.sm), From cf907e788c41ee77912c245c26f99ff843bd3a50 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 12 Jun 2026 15:37:02 +0200 Subject: [PATCH 26/87] Check if thread replies are enabled --- .../lib/src/message_action/message_actions_builder.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart b/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart index 5167670b0e..0f7213b90c 100644 --- a/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart +++ b/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart @@ -115,6 +115,7 @@ class StreamMessageActionsBuilder { final isParentMessage = (message.replyCount ?? 0) > 0; final canShowInChannel = message.showInChannel ?? true; final isPrivateMessage = message.hasRestrictedVisibility; + final repliesEnabled = channel.config?.replies ?? true; final canSendReply = channel.canSendReply; final canPinMessage = channel.canPinMessage; final canQuoteMessage = channel.canQuoteMessage; @@ -143,7 +144,7 @@ class StreamMessageActionsBuilder { // Thread reply action is only available for parent messages that are not in a // thread view, as replying in a thread that is already being viewed doesn't make sense. // Additionally, the channel needs to support sending replies. - if (canSendReply && !isThreadMessage && !isInThreadView) { + if (canSendReply && repliesEnabled && !isThreadMessage && !isInThreadView) { messageActions.add( StreamContextMenuAction( value: ThreadReply(message: message), From 3e477cc69c43fec8644b32d67809172b584ba165 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 12 Jun 2026 15:37:13 +0200 Subject: [PATCH 27/87] fix background attachment picker --- .../attachment_picker/options/stream_gallery_picker.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart index 0fee3f8071..247956d7fa 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart @@ -75,7 +75,7 @@ class _StreamGalleryPickerState extends State { return FutureBuilder( future: requestPermission, builder: (context, snapshot) { - if (!snapshot.hasData) return const Empty(); + if (!snapshot.hasData) return const SizedBox.expand(); final spacing = context.streamSpacing; final textTheme = context.streamTextTheme; From 74888d12fff5298e85e58d39d368f86b486d31af Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 12 Jun 2026 15:48:12 +0200 Subject: [PATCH 28/87] set default appstyle to regular --- sample_app/lib/config/sample_app_config.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sample_app/lib/config/sample_app_config.dart b/sample_app/lib/config/sample_app_config.dart index 13d5fbf0c2..ca3e39b5df 100644 --- a/sample_app/lib/config/sample_app_config.dart +++ b/sample_app/lib/config/sample_app_config.dart @@ -52,7 +52,7 @@ class SampleAppConfigData { factory SampleAppConfigData({ Locale? locale, ThemeMode themeMode = .system, - SampleAppStyle appStyle = .floating, + SampleAppStyle appStyle = .regular, bool forceRtl = false, bool enableReminderActions = false, bool enableDeleteForMe = false, @@ -98,7 +98,7 @@ class SampleAppConfigData { /// Loads config from [StreamingSharedPreferences], falling back to defaults. factory SampleAppConfigData.fromPreferences(StreamingSharedPreferences prefs) { final localeStr = prefs.getString(_kLocale, defaultValue: '').getValue(); - final appStyleIndex = prefs.getInt(_kAppStyle, defaultValue: SampleAppStyle.floating.index).getValue(); + final appStyleIndex = prefs.getInt(_kAppStyle, defaultValue: SampleAppStyle.regular.index).getValue(); return SampleAppConfigData.raw( themeMode: ThemeMode.values[prefs.getInt(_kThemeMode, defaultValue: ThemeMode.system.index).getValue()], appStyle: SampleAppStyle.values[appStyleIndex.clamp(0, SampleAppStyle.values.length - 1)], From a67a7168e2e8d7fe49b2213d3bb220d1601d1b58 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 12 Jun 2026 17:41:20 +0200 Subject: [PATCH 29/87] fix review comments --- .../lib/src/channel/channel_header.dart | 3 ++- .../lib/src/channel/channel_list_header.dart | 3 ++- .../stream_chat_flutter/lib/src/channel/channel_page.dart | 8 ++++---- .../lib/src/message_input/stream_message_composer.dart | 8 +++----- .../stream_chat_flutter/lib/src/misc/back_button.dart | 3 ++- sample_app/lib/pages/new_group_chat_screen.dart | 2 ++ sample_app/lib/routes/app_routes.dart | 4 ++-- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index 89d7aaac20..a540d68a09 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -131,7 +131,8 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget /// [StreamChatThemeData.channelHeaderTheme]. final StreamAppBarStyle? style; - /// Whether the header is floating. + /// Controls the header's visual/layout behavior (e.g. floating vs pinned). + /// Falls back to the theme's default when null. final AppBarBehavior? appBarBehavior; @override diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart index 4e9198bde2..67b93d3849 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart @@ -118,7 +118,8 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi /// [StreamChatThemeData.channelListHeaderTheme]. final StreamAppBarStyle? style; - /// Whether the header is floating. + /// Controls the header's visual/layout behavior (e.g. floating vs pinned). + /// Falls back to the theme's default when null. final AppBarBehavior? appBarBehavior; @override diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index e3d18c4212..bfe3a29600 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -29,7 +29,7 @@ class StreamChannelPage extends StatefulWidget { } class _StreamChannelPageState extends State { - FocusNode? _focusNode; + late final FocusNode _focusNode; final _messageComposerController = StreamMessageComposerController(); @override @@ -40,21 +40,21 @@ class _StreamChannelPageState extends State { @override void dispose() { - _focusNode!.dispose(); + _focusNode.dispose(); super.dispose(); } void _reply(Message message) { _messageComposerController.quotedMessage = message; WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - _focusNode!.requestFocus(); + _focusNode.requestFocus(); }); } void _editMessage(Message message) { _messageComposerController.editMessage(message); WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - _focusNode!.requestFocus(); + _focusNode.requestFocus(); }); } diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 8f7e1eeaf7..99f170e730 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -11,9 +11,6 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; const _kCommandTrigger = '/'; const _kMentionTrigger = '@'; -/// Fixed height of the inline attachment picker body. -const _kPickerBodyHeight = 333.0; - /// Signature for the function that determines if a [matchedUri] should be /// previewed as an OG Attachment. typedef OgPreviewFilter = bool Function(Uri matchedUri, String messageText); @@ -430,6 +427,7 @@ class MessageComposerProps { TextCapitalization? textCapitalization, bool? autofocus, bool? autoCorrect, + ComposerLocation? composerLocation, }) { return MessageComposerProps( onMessageSent: onMessageSent ?? this.onMessageSent, @@ -466,6 +464,7 @@ class MessageComposerProps { textCapitalization: textCapitalization ?? this.textCapitalization, autofocus: autofocus ?? this.autofocus, autoCorrect: autoCorrect ?? this.autoCorrect, + composerLocation: composerLocation ?? this.composerLocation, ); } @@ -978,8 +977,7 @@ class DefaultStreamMessageComposerState extends State m.userId != currentUserId).user + final otherUser = (isOneToOne && currentUserId != null) + ? channelMembers.firstWhereOrNull((m) => m.userId != currentUserId)?.user : null; final router = GoRouter.of(context); From d1ad9e14f2ebee8ae9d273a34fe509ca20e97264 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Tue, 16 Jun 2026 16:06:46 +0200 Subject: [PATCH 30/87] update core dependency --- docs/docs_screenshots/pubspec.yaml | 2 +- melos.yaml | 2 +- packages/stream_chat_flutter/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index d1b301dc8c..2d1a0f1ea2 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: 6f8ba0c07a6ffbc6e0ea96c560f010cf48b8012b + ref: 682d15f4b23cccd4ca0943b07883fd80d686d8c0 path: packages/stream_core_flutter dev_dependencies: diff --git a/melos.yaml b/melos.yaml index 1b0b621311..883f817cc8 100644 --- a/melos.yaml +++ b/melos.yaml @@ -101,7 +101,7 @@ command: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: 6f8ba0c07a6ffbc6e0ea96c560f010cf48b8012b + ref: 682d15f4b23cccd4ca0943b07883fd80d686d8c0 path: packages/stream_core_flutter synchronized: ^3.4.0 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index eab51be6bc..b9346bf897 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -68,7 +68,7 @@ dependencies: # ignore: invalid_dependency git: url: https://github.com/GetStream/stream-core-flutter - ref: 6f8ba0c07a6ffbc6e0ea96c560f010cf48b8012b + ref: 682d15f4b23cccd4ca0943b07883fd80d686d8c0 path: packages/stream_core_flutter svg_icon_widget: ^0.0.1 synchronized: ^3.4.0 From c44ba13fcdce2cd93284656ca8e51d57b98e0d8b Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Tue, 16 Jun 2026 16:18:46 +0200 Subject: [PATCH 31/87] update changelog --- packages/stream_chat_flutter/CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index f8e94349f5..11292ccf53 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -2,8 +2,15 @@ ✅ Added +- Added `StreamChannelPage` — a ready-to-use channel page widget that wires up `StreamChannelHeader`, `StreamMessageListView`, and `StreamMessageComposer` with floating or docked layout driven by the active app style. +- Added `StreamThreadPage` — a ready-to-use thread page widget with the same floating/docked layout support. +- Added `MessageComposerProps.composerLocation` — explicitly controls whether `StreamMessageComposer` renders in `floating` or `docked` mode; falls back to the theme's `appStyle.composerLocation` when null. `copyWith` now distinguishes "not passed" from "explicitly set to null" via a sentinel so callers can clear an override back to the theme default. +- Added `StreamMessageListView.config` — accepts an explicit `StreamMessageListViewConfiguration` per widget; falls back to `StreamChatConfigurationData.messageListViewConfiguration` from the nearest ancestor when omitted. +- Added `StreamMessageListView.topPadding` and `bottomPadding` — padding applied to the scroll view's top and bottom edges, used by floating app bar / composer layouts to keep messages visible without an extra `setState`. +- Added `appBarBehavior` parameter to `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamBackButton`, controlling floating vs pinned app bar appearance (avatar shadow, back-button style). Falls back to `appStyle.appBarBehavior` from the theme when null. - Added `messageListViewConfiguration` field to `StreamChatConfigurationData`, allowing a global `StreamMessageListViewConfiguration` default for all `StreamMessageListView` widgets. Pass it via `StreamChat.configData` to configure behaviors like `swipeToReply` and `highlightInitialMessage` app-wide without wiring them per-page. - `StreamMessageComposer` now surfaces the hold-to-record hint through `StreamSnackbar` anchored above the composer, and `StreamChat` provides an app-wide `StreamSnackbarScope` fallback. +- Re-exported `StreamScaffold`, `StreamScaffoldInsets`, `StreamBottomNavBar`, `StreamBottomNavBarItem`, `StreamAppStyle`, `AppBarBehavior`, `BottomBarBehavior`, and `ComposerLocation` from `stream_core_flutter` via `package:stream_chat_flutter/stream_chat_flutter.dart`. ⚠️ Deprecated From 0c62f89402e661fd33342f3c3ddb506508b0d8a0 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 17 Jun 2026 11:36:07 +0200 Subject: [PATCH 32/87] update core dependency --- docs/docs_screenshots/pubspec.yaml | 2 +- melos.yaml | 2 +- .../stream_chat_flutter/lib/src/channel/channel_header.dart | 1 - .../attachment_picker/options/stream_gallery_picker.dart | 1 - .../stream_chat_flutter/lib/src/stream_chat_configuration.dart | 3 +-- packages/stream_chat_flutter/pubspec.yaml | 2 +- 6 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index 2d1a0f1ea2..e0ad46a9d9 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: 682d15f4b23cccd4ca0943b07883fd80d686d8c0 + ref: ef83513b075246cb662911926ad49ada2a07f595 path: packages/stream_core_flutter dev_dependencies: diff --git a/melos.yaml b/melos.yaml index 883f817cc8..42dd5cd825 100644 --- a/melos.yaml +++ b/melos.yaml @@ -101,7 +101,7 @@ command: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: 682d15f4b23cccd4ca0943b07883fd80d686d8c0 + ref: ef83513b075246cb662911926ad49ada2a07f595 path: packages/stream_core_flutter synchronized: ^3.4.0 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index a540d68a09..6f0429250c 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; -import 'package:stream_core_flutter/stream_core_flutter.dart'; /// {@template streamChannelHeader} /// A top-of-screen header for a single channel. diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart index 247956d7fa..0bd71c840c 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart @@ -6,7 +6,6 @@ import 'package:path_provider/path_provider.dart'; import 'package:photo_manager/photo_manager.dart'; import 'package:stream_chat_flutter/src/message_input/attachment_picker/stream_attachment_picker.dart'; import 'package:stream_chat_flutter/src/message_input/attachment_picker/stream_attachment_picker_controller.dart'; -import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; import 'package:stream_chat_flutter/src/scroll_view/photo_gallery/stream_photo_gallery.dart'; import 'package:stream_chat_flutter/src/scroll_view/photo_gallery/stream_photo_gallery_controller.dart'; import 'package:stream_chat_flutter/src/utils/utils.dart'; diff --git a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart index 6b1e1a072b..62c46a3ce1 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart @@ -165,8 +165,7 @@ class StreamChatConfigurationData { List? attachmentBuilders, StreamReactionsType? reactionType, StreamReactionsPosition? reactionPosition, - StreamMessageListViewConfiguration messageListViewConfiguration = - const StreamMessageListViewConfiguration(), + StreamMessageListViewConfiguration messageListViewConfiguration = const StreamMessageListViewConfiguration(), }) { return StreamChatConfigurationData._( reactionIconResolver: reactionIconResolver ?? const DefaultReactionIconResolver(), diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index b9346bf897..4d540a9e7e 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -68,7 +68,7 @@ dependencies: # ignore: invalid_dependency git: url: https://github.com/GetStream/stream-core-flutter - ref: 682d15f4b23cccd4ca0943b07883fd80d686d8c0 + ref: ef83513b075246cb662911926ad49ada2a07f595 path: packages/stream_core_flutter svg_icon_widget: ^0.0.1 synchronized: ^3.4.0 From 738d676c63f07c5aa8f3f6431769ee6e53e10ad6 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 17 Jun 2026 11:54:01 +0200 Subject: [PATCH 33/87] fix(ui): channel page controller leak, shared fade helper, photo gallery nit - Fix StreamChannelPage disposing its StreamMessageComposerController in dispose(); aligns it with StreamThreadPage and prevents a resource leak. Align init style: late + super.initState() first, matching the thread page. - Replace inline LinearGradient in _buildFloatingComposerBand with the shared streamFloatingFade() helper from stream_core_flutter; re-export the helper via stream_chat_flutter.dart. - Drop redundant top: 0 from StreamPhotoGallery default padding. Co-Authored-By: Claude Opus 4.8 --- docs/docs_screenshots/pubspec.yaml | 2 +- melos.yaml | 2 +- packages/stream_chat_flutter/CHANGELOG.md | 4 +++- .../lib/src/channel/channel_page.dart | 6 ++++-- .../message_input/stream_message_composer.dart | 16 +++++----------- .../photo_gallery/stream_photo_gallery.dart | 2 +- packages/stream_chat_flutter/pubspec.yaml | 2 +- 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index e0ad46a9d9..a61a06cc5f 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: ef83513b075246cb662911926ad49ada2a07f595 + ref: bed95c6a61dce641a1807cf642ebba66494ca6ec path: packages/stream_core_flutter dev_dependencies: diff --git a/melos.yaml b/melos.yaml index 42dd5cd825..9c9015465a 100644 --- a/melos.yaml +++ b/melos.yaml @@ -101,7 +101,7 @@ command: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: ef83513b075246cb662911926ad49ada2a07f595 + ref: bed95c6a61dce641a1807cf642ebba66494ca6ec path: packages/stream_core_flutter synchronized: ^3.4.0 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 11292ccf53..96ec405c09 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -10,7 +10,7 @@ - Added `appBarBehavior` parameter to `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamBackButton`, controlling floating vs pinned app bar appearance (avatar shadow, back-button style). Falls back to `appStyle.appBarBehavior` from the theme when null. - Added `messageListViewConfiguration` field to `StreamChatConfigurationData`, allowing a global `StreamMessageListViewConfiguration` default for all `StreamMessageListView` widgets. Pass it via `StreamChat.configData` to configure behaviors like `swipeToReply` and `highlightInitialMessage` app-wide without wiring them per-page. - `StreamMessageComposer` now surfaces the hold-to-record hint through `StreamSnackbar` anchored above the composer, and `StreamChat` provides an app-wide `StreamSnackbarScope` fallback. -- Re-exported `StreamScaffold`, `StreamScaffoldInsets`, `StreamBottomNavBar`, `StreamBottomNavBarItem`, `StreamAppStyle`, `AppBarBehavior`, `BottomBarBehavior`, and `ComposerLocation` from `stream_core_flutter` via `package:stream_chat_flutter/stream_chat_flutter.dart`. +- Re-exported `StreamScaffold`, `StreamScaffoldInsets`, `StreamBottomNavBar`, `StreamBottomNavBarItem`, `StreamAppStyle`, `AppBarBehavior`, `BottomBarBehavior`, `ComposerLocation`, and `streamFloatingFade` from `stream_core_flutter` via `package:stream_chat_flutter/stream_chat_flutter.dart`. ⚠️ Deprecated @@ -19,6 +19,8 @@ 🐞 Fixed +- Fixed `StreamChannelPage` leaking its `StreamMessageComposerController` — the state now disposes it in `dispose()`, matching the pattern already used by `StreamThreadPage`. +- Fixed `StreamPhotoGallery` default padding having a redundant explicit `top: 0` (no visual change). - `StreamMessageItem.onUserAvatarTap` now fires when the author avatar is tapped. ([#2741](https://github.com/GetStream/stream-chat-flutter/issues/2741)) - Added `MessageComposerProps.copyWith` so factory overrides can tweak individual props (e.g. `useSystemAttachmentPicker`) without re-specifying every field. ([#2742](https://github.com/GetStream/stream-chat-flutter/issues/2742)) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index bfe3a29600..d05ffe1912 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -30,17 +30,19 @@ class StreamChannelPage extends StatefulWidget { class _StreamChannelPageState extends State { late final FocusNode _focusNode; - final _messageComposerController = StreamMessageComposerController(); + late final StreamMessageComposerController _messageComposerController; @override void initState() { - _focusNode = FocusNode(); super.initState(); + _focusNode = FocusNode(); + _messageComposerController = StreamMessageComposerController(); } @override void dispose() { _focusNode.dispose(); + _messageComposerController.dispose(); super.dispose(); } diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 99f170e730..59a14ca6b2 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -7,6 +7,7 @@ import 'package:flutter/services.dart'; import 'package:stream_chat_flutter/src/message_input/error_alert_sheet.dart'; import 'package:stream_chat_flutter/src/message_input/stream_chat_message_input.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; +import 'package:stream_core_flutter/stream_core_flutter.dart' show streamFloatingFade; const _kCommandTrigger = '/'; const _kMentionTrigger = '@'; @@ -1002,17 +1003,10 @@ class DefaultStreamMessageComposerState extends State Date: Wed, 17 Jun 2026 16:06:48 +0200 Subject: [PATCH 34/87] Update appstyle theming --- .../lib/src/channel/channel_header.dart | 22 ++- .../lib/src/channel/channel_list_header.dart | 19 ++- .../avatar/stream_channel_avatar.dart | 10 +- .../components/avatar/stream_user_avatar.dart | 6 +- .../avatar/stream_user_avatar_group.dart | 6 +- .../stream_message_composer.dart | 20 +-- .../lib/src/misc/back_button.dart | 12 +- .../lib/src/theme/message_composer_theme.dart | 130 ++++++++++++++++++ .../theme/message_composer_theme.g.theme.dart | 83 +++++++++++ .../lib/src/theme/stream_chat_theme.dart | 9 ++ .../src/theme/stream_chat_theme.g.theme.dart | 9 ++ .../lib/src/theme/themes.dart | 1 + .../lib/stream_chat_flutter.dart | 1 - sample_app/lib/app.dart | 4 +- 14 files changed, 285 insertions(+), 47 deletions(-) create mode 100644 packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart create mode 100644 packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index 6f0429250c..2eae9517de 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -81,7 +81,6 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget this.trailing, this.primary = true, this.style, - this.appBarBehavior, }); /// Called when the default channel-avatar trailing is pressed. @@ -130,10 +129,6 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget /// [StreamChatThemeData.channelHeaderTheme]. final StreamAppBarStyle? style; - /// Controls the header's visual/layout behavior (e.g. floating vs pinned). - /// Falls back to the theme's default when null. - final AppBarBehavior? appBarBehavior; - @override Size get preferredSize => const Size.fromHeight(kStreamToolbarHeight); @@ -144,7 +139,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget var leading = this.leading; if (leading == null && automaticallyImplyLeading) { - leading = StreamBackButton(showUnreadCount: true, appBarBehavior: appBarBehavior); + leading = const StreamBackButton(showUnreadCount: true); } var title = this.title; @@ -153,7 +148,11 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget var subtitle = this.subtitle; subtitle ??= StreamChannelInfo(channel: channel); - final showAvatarShadow = switch (appBarBehavior ?? StreamTheme.of(context).appStyle.appBarBehavior) { + final effectiveAppBarBehavior = + style?.behavior ?? + StreamAppBarTheme.of(context).style?.behavior ?? + (StreamTheme.of(context).appStyle.isFloating ? AppBarBehavior.floating : AppBarBehavior.regular); + final showAvatarShadow = switch (effectiveAppBarBehavior) { .floating => true, .regular => false, }; @@ -162,7 +161,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget trailing ??= _DefaultChannelAvatar( channel: channel, onPressed: onChannelAvatarPressed, - showShadow: showAvatarShadow, + isFloating: showAvatarShadow, ); return Portal( @@ -201,7 +200,6 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget trailing: trailing, primary: primary, style: style, - appBarBehavior: appBarBehavior, ), ), ); @@ -212,11 +210,11 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget } class _DefaultChannelAvatar extends StatelessWidget { - const _DefaultChannelAvatar({required this.channel, this.onPressed, this.showShadow = false}); + const _DefaultChannelAvatar({required this.channel, this.onPressed, this.isFloating = false}); final Channel channel; final void Function(Channel channel)? onPressed; - final bool showShadow; + final bool isFloating; @override Widget build(BuildContext context) { @@ -237,7 +235,7 @@ class _DefaultChannelAvatar extends StatelessWidget { child: StreamChannelAvatar( size: .lg, channel: channel, - showShadow: showShadow, + isFloating: isFloating, ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart index 67b93d3849..3ec71a454b 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart @@ -80,7 +80,6 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi this.trailing, this.primary = true, this.style, - this.appBarBehavior, }); /// Use this if you don't have a [StreamChatClient] in your widget tree. @@ -118,10 +117,6 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi /// [StreamChatThemeData.channelListHeaderTheme]. final StreamAppBarStyle? style; - /// Controls the header's visual/layout behavior (e.g. floating vs pinned). - /// Falls back to the theme's default when null. - final AppBarBehavior? appBarBehavior; - @override Size get preferredSize => const Size.fromHeight(kStreamToolbarHeight); @@ -130,12 +125,16 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi final _client = client ?? StreamChat.of(context).client; final headerTheme = StreamChatTheme.of(context).channelListHeaderTheme; - final hasAvatarShadow = switch (appBarBehavior ?? StreamTheme.of(context).appStyle.appBarBehavior) { + final effectiveAppBarBehavior = + style?.behavior ?? + StreamAppBarTheme.of(context).style?.behavior ?? + (StreamTheme.of(context).appStyle.isFloating ? AppBarBehavior.floating : AppBarBehavior.regular); + final hasAvatarShadow = switch (effectiveAppBarBehavior) { .floating => true, .regular => false, }; - final leading = _DefaultUserAvatar(client: _client, onPressed: onUserAvatarPressed, showShadow: hasAvatarShadow); + final leading = _DefaultUserAvatar(client: _client, onPressed: onUserAvatarPressed, isFloating: hasAvatarShadow); return Portal( child: StreamConnectionStatusBuilder( @@ -189,11 +188,11 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi } class _DefaultUserAvatar extends StatelessWidget { - const _DefaultUserAvatar({required this.client, this.onPressed, this.showShadow = false}); + const _DefaultUserAvatar({required this.client, this.onPressed, this.isFloating = false}); final StreamChatClient client; final void Function(User user)? onPressed; - final bool showShadow; + final bool isFloating; @override Widget build(BuildContext context) { @@ -222,7 +221,7 @@ class _DefaultUserAvatar extends StatelessWidget { size: .lg, user: user, showOnlineIndicator: false, - showShadow: showShadow, + isFloating: isFloating, ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart index 8ac6723233..2a4aa7c7e4 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart @@ -54,7 +54,7 @@ class StreamChannelAvatar extends StatelessWidget { super.key, this.size, required this.channel, - this.showShadow = false, + this.isFloating, }); /// The channel whose avatar is displayed. @@ -70,7 +70,7 @@ class StreamChannelAvatar extends StatelessWidget { /// Defaults to false. The shadow style is determined by /// [StreamAvatarThemeData.boxShadow], falling back to /// [StreamBoxShadow.elevation3]. - final bool showShadow; + final bool? isFloating; @override Widget build(BuildContext context) { @@ -84,7 +84,7 @@ class StreamChannelAvatar extends StatelessWidget { builder: (context, channelImage) => StreamAvatar( imageUrl: channelImage, size: _avatarSizeForAvatarGroupSize(effectiveSize), - showShadow: showShadow, + isFloating: isFloating, placeholder: (_) => const _StreamChannelAvatarPlaceholder(), ), noDataBuilder: (context) => BetterStreamBuilder( @@ -104,14 +104,14 @@ class StreamChannelAvatar extends StatelessWidget { size: _avatarSizeForAvatarGroupSize(effectiveSize), // TODO: make this configurable when the online state is shown. showOnlineIndicator: otherUser.online, - showShadow: showShadow, + isFloating: isFloating, ); } return StreamUserAvatarGroup( size: effectiveSize, users: users.sortedBy((it) => it.id == currentUserId ? 1 : 0), - showShadow: showShadow, + isFloating: isFloating, ); }, ), diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart index 747ae2b5f0..ee27cb9b47 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart @@ -68,7 +68,7 @@ class StreamUserAvatar extends StatelessWidget { required this.user, this.showBorder = true, this.showOnlineIndicator = true, - this.showShadow = false, + this.isFloating, }); /// The user whose avatar is displayed. @@ -90,7 +90,7 @@ class StreamUserAvatar extends StatelessWidget { /// Defaults to false. The shadow style is determined by /// [StreamAvatarThemeData.boxShadow], falling back to /// [StreamBoxShadow.elevation3]. - final bool showShadow; + final bool? isFloating; /// The size of the avatar. /// @@ -115,7 +115,7 @@ class StreamUserAvatar extends StatelessWidget { size: effectiveSize, imageUrl: user.image, showBorder: showBorder, - showShadow: showShadow, + isFloating: isFloating, backgroundColor: effectiveBackgroundColor, foregroundColor: effectiveForegroundColor, placeholder: (_) => _StreamUserAvatarPlaceholder(user: user, size: effectiveSize), diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart index aebd47c9ae..b9e295e375 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart @@ -55,7 +55,7 @@ class StreamUserAvatarGroup extends StatelessWidget { super.key, required this.users, this.size, - this.showShadow = false, + this.isFloating, }); /// The list of users whose avatars are displayed. @@ -71,7 +71,7 @@ class StreamUserAvatarGroup extends StatelessWidget { /// Defaults to false. The shadow style is determined by /// [StreamAvatarThemeData.boxShadow], falling back to /// [StreamBoxShadow.elevation3]. - final bool showShadow; + final bool? isFloating; @override Widget build(BuildContext context) { @@ -81,7 +81,7 @@ class StreamUserAvatarGroup extends StatelessWidget { (user) => StreamUserAvatar( user: user, showOnlineIndicator: false, - showShadow: showShadow, + isFloating: isFloating, ), ), ); diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 59a14ca6b2..d219d04c2d 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -96,7 +96,7 @@ class StreamMessageComposer extends StatelessWidget { TextCapitalization textCapitalization = TextCapitalization.sentences, bool autofocus = false, bool autoCorrect = true, - ComposerLocation? composerLocation, + ComposerLocation? location, }) : props = .new( onMessageSent: onMessageSent, preMessageSending: preMessageSending, @@ -132,7 +132,7 @@ class StreamMessageComposer extends StatelessWidget { textCapitalization: textCapitalization, autofocus: autofocus, autoCorrect: autoCorrect, - composerLocation: composerLocation, + location: location, ); /// Creates a [StreamMessageComposer] from a pre-built [MessageComposerProps]. @@ -193,7 +193,7 @@ class MessageComposerProps { this.textCapitalization = TextCapitalization.sentences, this.autofocus = false, this.autoCorrect = true, - this.composerLocation, + this.location, }); /// Function called after sending the message. @@ -389,7 +389,7 @@ class MessageComposerProps { final bool autoCorrect; /// The location of the message composer. - final ComposerLocation? composerLocation; + final ComposerLocation? location; /// Returns a copy of this [MessageComposerProps] with the given fields /// replaced with new values. @@ -428,7 +428,7 @@ class MessageComposerProps { TextCapitalization? textCapitalization, bool? autofocus, bool? autoCorrect, - ComposerLocation? composerLocation, + ComposerLocation? location, }) { return MessageComposerProps( onMessageSent: onMessageSent ?? this.onMessageSent, @@ -465,7 +465,7 @@ class MessageComposerProps { textCapitalization: textCapitalization ?? this.textCapitalization, autofocus: autofocus ?? this.autofocus, autoCorrect: autoCorrect ?? this.autoCorrect, - composerLocation: composerLocation ?? this.composerLocation, + location: location ?? this.location, ); } @@ -798,7 +798,9 @@ class DefaultStreamMessageComposerState extends State context.streamIcons.chevronLeft, _ => context.streamIcons.arrowLeft, }; - final isFloating = switch (appBarBehavior ?? StreamTheme.of(context).appStyle.appBarBehavior) { + final effectiveAppBarBehavior = + appBarBehavior ?? + StreamAppBarTheme.of(context).style?.behavior ?? + (StreamTheme.of(context).appStyle.isFloating ? AppBarBehavior.floating : AppBarBehavior.regular); + final isFloating = switch (effectiveAppBarBehavior) { .floating => true, .regular => false, }; diff --git a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart new file mode 100644 index 0000000000..3cc8c79412 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart @@ -0,0 +1,130 @@ +import 'package:flutter/widgets.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; +import 'package:theme_extensions_builder_annotation/theme_extensions_builder_annotation.dart'; + +part 'message_composer_theme.g.theme.dart'; + +/// The placement of the message composer — floating above the keyboard or +/// docked at the bottom edge of the screen. +/// +/// When null on [StreamMessageComposerThemeData], the ambient [StreamAppStyle] +/// is used as a fallback — [StreamAppStyle.floating] maps to [floating] and +/// [StreamAppStyle.regular] maps to [docked]. +/// +/// See also: +/// +/// * [StreamMessageComposerThemeData.location], which carries this +/// value. +/// * [StreamAppStyle], the global app-wide style that acts as fallback. +enum ComposerLocation { + /// The composer floats above the on-screen keyboard with appropriate safe + /// area padding. + floating, + + /// The composer is docked at the bottom edge of the screen. + docked, +} + +/// Applies a message composer theme to descendant composer widgets. +/// +/// Wrap a subtree with [StreamMessageComposerTheme] to override the composer +/// location. Access the merged theme using [StreamMessageComposerTheme.of]. +/// +/// {@tool snippet} +/// +/// Override composer placement for a specific screen: +/// +/// ```dart +/// StreamMessageComposerTheme( +/// data: StreamMessageComposerThemeData( +/// location: ComposerLocation.floating, +/// ), +/// child: StreamChannel( +/// channel: channel, +/// child: ChannelPage(), +/// ), +/// ) +/// ``` +/// {@end-tool} +/// +/// See also: +/// +/// * [StreamMessageComposerThemeData], which describes the theme data. +/// * [StreamMessageComposerThemeData.location], the setting it holds. +class StreamMessageComposerTheme extends InheritedTheme { + /// Creates a message composer theme that controls descendant composers. + const StreamMessageComposerTheme({ + super.key, + required this.data, + required super.child, + }); + + /// The message composer theme data for descendant widgets. + final StreamMessageComposerThemeData data; + + /// Returns the [StreamMessageComposerThemeData] merged from local and global + /// themes. + /// + /// Local values from the nearest [StreamMessageComposerTheme] ancestor take + /// precedence over global values from [StreamChatTheme.of]. + /// + /// This allows partial overrides — for example, overriding only + /// [StreamMessageComposerThemeData.location] in a subtree while + /// inheriting other properties from the global theme. + static StreamMessageComposerThemeData of(BuildContext context) { + final localTheme = context.dependOnInheritedWidgetOfExactType(); + return StreamChatTheme.of(context).messageComposerTheme.merge(localTheme?.data); + } + + @override + Widget wrap(BuildContext context, Widget child) => StreamMessageComposerTheme(data: data, child: child); + + @override + bool updateShouldNotify(StreamMessageComposerTheme oldWidget) => data != oldWidget.data; +} + +/// Theme data for customizing the message composer placement. +/// +/// All fields are nullable. When a field is null, the consuming widget falls +/// back to the ambient [StreamAppStyle]. +/// +/// {@tool snippet} +/// +/// Override composer placement globally: +/// +/// ```dart +/// StreamChatThemeData( +/// messageComposerTheme: StreamMessageComposerThemeData( +/// location: ComposerLocation.floating, +/// ), +/// ) +/// ``` +/// {@end-tool} +/// +/// See also: +/// +/// * [ComposerLocation], the enum that describes the placement options. +/// * [StreamMessageComposerTheme], for overriding the theme in a subtree. +@themeGen +@immutable +class StreamMessageComposerThemeData with _$StreamMessageComposerThemeData { + /// Creates message composer theme data with optional overrides. + const StreamMessageComposerThemeData({this.location}); + + /// The placement of the message composer. + /// + /// When null the value falls back to the ambient [StreamAppStyle]: + /// [StreamAppStyle.floating] → [ComposerLocation.floating], + /// [StreamAppStyle.regular] → [ComposerLocation.docked]. + /// + /// Set this to override the global style for the composer only, without + /// affecting other components. + final ComposerLocation? location; + + /// Linearly interpolate between two [StreamMessageComposerThemeData] objects. + static StreamMessageComposerThemeData? lerp( + StreamMessageComposerThemeData? a, + StreamMessageComposerThemeData? b, + double t, + ) => _$StreamMessageComposerThemeData.lerp(a, b, t); +} diff --git a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart new file mode 100644 index 0000000000..ddd6ea3c2e --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart @@ -0,0 +1,83 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint, unused_element + +part of 'message_composer_theme.dart'; + +// ************************************************************************** +// ThemeGenGenerator +// ************************************************************************** + +mixin _$StreamMessageComposerThemeData { + bool get canMerge => true; + + static StreamMessageComposerThemeData? lerp( + StreamMessageComposerThemeData? a, + StreamMessageComposerThemeData? b, + double t, + ) { + if (identical(a, b)) { + return a; + } + + if (a == null) { + return t == 1.0 ? b : null; + } + + if (b == null) { + return t == 0.0 ? a : null; + } + + return StreamMessageComposerThemeData( + location: t < 0.5 ? a.location : b.location, + ); + } + + StreamMessageComposerThemeData copyWith({ + ComposerLocation? location, + }) { + final _this = (this as StreamMessageComposerThemeData); + + return StreamMessageComposerThemeData( + location: location ?? _this.location, + ); + } + + StreamMessageComposerThemeData merge(StreamMessageComposerThemeData? other) { + final _this = (this as StreamMessageComposerThemeData); + + if (other == null || identical(_this, other)) { + return _this; + } + + if (!other.canMerge) { + return other; + } + + return copyWith(location: other.location); + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) { + return true; + } + + if (other.runtimeType != runtimeType) { + return false; + } + + final _this = (this as StreamMessageComposerThemeData); + final _other = (other as StreamMessageComposerThemeData); + + return _other.location == _this.location; + } + + @override + int get hashCode { + final _this = (this as StreamMessageComposerThemeData); + + return Object.hash(runtimeType, _this.location); + } +} diff --git a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart index e487996ce0..e883a3f8d8 100644 --- a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart @@ -132,6 +132,7 @@ class StreamChatThemeData extends ThemeExtension with _$Str StreamAppBarThemeData? channelHeaderTheme, StreamAppBarThemeData? channelListHeaderTheme, StreamAppBarThemeData? threadHeaderTheme, + StreamMessageComposerThemeData? messageComposerTheme, StreamMessageListViewThemeData? messageListViewTheme, StreamPollCreatorThemeData? pollCreatorTheme, StreamPollInteractorThemeData? pollInteractorTheme, @@ -149,6 +150,9 @@ class StreamChatThemeData extends ThemeExtension with _$Str channelListHeaderTheme ??= const StreamAppBarThemeData(); threadHeaderTheme ??= const StreamAppBarThemeData(); + // Message composer + messageComposerTheme ??= const StreamMessageComposerThemeData(); + // Message list messageListViewTheme ??= const StreamMessageListViewThemeData(); @@ -170,6 +174,7 @@ class StreamChatThemeData extends ThemeExtension with _$Str channelHeaderTheme: channelHeaderTheme, channelListHeaderTheme: channelListHeaderTheme, threadHeaderTheme: threadHeaderTheme, + messageComposerTheme: messageComposerTheme, messageListViewTheme: messageListViewTheme, pollCreatorTheme: pollCreatorTheme, pollInteractorTheme: pollInteractorTheme, @@ -189,6 +194,7 @@ class StreamChatThemeData extends ThemeExtension with _$Str required this.channelHeaderTheme, required this.channelListHeaderTheme, required this.threadHeaderTheme, + required this.messageComposerTheme, required this.messageListViewTheme, required this.pollCreatorTheme, required this.pollInteractorTheme, @@ -211,6 +217,9 @@ class StreamChatThemeData extends ThemeExtension with _$Str /// The thread header app bar theme for this theme. final StreamAppBarThemeData threadHeaderTheme; + /// The message composer theme for this theme. + final StreamMessageComposerThemeData messageComposerTheme; + /// The message list view theme for this theme. final StreamMessageListViewThemeData messageListViewTheme; diff --git a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.g.theme.dart b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.g.theme.dart index ee0012763b..105993cf0d 100644 --- a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.g.theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.g.theme.dart @@ -15,6 +15,7 @@ mixin _$StreamChatThemeData on ThemeExtension { StreamAppBarThemeData? channelHeaderTheme, StreamAppBarThemeData? channelListHeaderTheme, StreamAppBarThemeData? threadHeaderTheme, + StreamMessageComposerThemeData? messageComposerTheme, StreamMessageListViewThemeData? messageListViewTheme, StreamPollCreatorThemeData? pollCreatorTheme, StreamPollInteractorThemeData? pollInteractorTheme, @@ -34,6 +35,7 @@ mixin _$StreamChatThemeData on ThemeExtension { channelListHeaderTheme: channelListHeaderTheme ?? _this.channelListHeaderTheme, threadHeaderTheme: threadHeaderTheme ?? _this.threadHeaderTheme, + messageComposerTheme: messageComposerTheme ?? _this.messageComposerTheme, messageListViewTheme: messageListViewTheme ?? _this.messageListViewTheme, pollCreatorTheme: pollCreatorTheme ?? _this.pollCreatorTheme, pollInteractorTheme: pollInteractorTheme ?? _this.pollInteractorTheme, @@ -80,6 +82,11 @@ mixin _$StreamChatThemeData on ThemeExtension { other.threadHeaderTheme, t, )!, + messageComposerTheme: StreamMessageComposerThemeData.lerp( + _this.messageComposerTheme, + other.messageComposerTheme, + t, + )!, messageListViewTheme: StreamMessageListViewThemeData.lerp( _this.messageListViewTheme, other.messageListViewTheme, @@ -155,6 +162,7 @@ mixin _$StreamChatThemeData on ThemeExtension { return _other.channelHeaderTheme == _this.channelHeaderTheme && _other.channelListHeaderTheme == _this.channelListHeaderTheme && _other.threadHeaderTheme == _this.threadHeaderTheme && + _other.messageComposerTheme == _this.messageComposerTheme && _other.messageListViewTheme == _this.messageListViewTheme && _other.pollCreatorTheme == _this.pollCreatorTheme && _other.pollInteractorTheme == _this.pollInteractorTheme && @@ -178,6 +186,7 @@ mixin _$StreamChatThemeData on ThemeExtension { _this.channelHeaderTheme, _this.channelListHeaderTheme, _this.threadHeaderTheme, + _this.messageComposerTheme, _this.messageListViewTheme, _this.pollCreatorTheme, _this.pollInteractorTheme, diff --git a/packages/stream_chat_flutter/lib/src/theme/themes.dart b/packages/stream_chat_flutter/lib/src/theme/themes.dart index ab4d9de545..d247f4d95c 100644 --- a/packages/stream_chat_flutter/lib/src/theme/themes.dart +++ b/packages/stream_chat_flutter/lib/src/theme/themes.dart @@ -1,3 +1,4 @@ +export 'message_composer_theme.dart'; export 'message_list_view_theme.dart'; export 'poll_card_style.dart'; export 'poll_comments_sheet_theme.dart'; diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 03f5ded2d1..39cad44f2d 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -4,7 +4,6 @@ export 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; export 'package:stream_core_flutter/stream_core_flutter.dart' show StreamAppStyle, - ComposerLocation, AppBarBehavior, BottomBarBehavior, StreamScaffold, diff --git a/sample_app/lib/app.dart b/sample_app/lib/app.dart index c748278aef..ab5c0ac962 100644 --- a/sample_app/lib/app.dart +++ b/sample_app/lib/app.dart @@ -172,8 +172,8 @@ class _StreamChatSampleAppState extends State final config = context.sampleAppConfig; StreamAppStyle appStyle() => switch (config.appStyle) { - SampleAppStyle.regular => const StreamAppStyle.regular(), - SampleAppStyle.floating => const StreamAppStyle.floating(), + SampleAppStyle.regular => StreamAppStyle.regular, + SampleAppStyle.floating => StreamAppStyle.floating, }; ThemeData theme(Brightness brightness) => ThemeData( From faf7c8a79e006f2c6b4bbbac3d0896e52602ca32 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 17 Jun 2026 16:14:42 +0200 Subject: [PATCH 35/87] update core dependency --- docs/docs_screenshots/pubspec.yaml | 2 +- melos.yaml | 2 +- packages/stream_chat_flutter/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index a61a06cc5f..e7bf56c39b 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: bed95c6a61dce641a1807cf642ebba66494ca6ec + ref: a54e4c81f365d7b477f65b6ccdb3afec9c147cea path: packages/stream_core_flutter dev_dependencies: diff --git a/melos.yaml b/melos.yaml index 9c9015465a..367c9e6ec7 100644 --- a/melos.yaml +++ b/melos.yaml @@ -101,7 +101,7 @@ command: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: bed95c6a61dce641a1807cf642ebba66494ca6ec + ref: a54e4c81f365d7b477f65b6ccdb3afec9c147cea path: packages/stream_core_flutter synchronized: ^3.4.0 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index a72852440c..7803016cc9 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -68,7 +68,7 @@ dependencies: # ignore: invalid_dependency git: url: https://github.com/GetStream/stream-core-flutter - ref: bed95c6a61dce641a1807cf642ebba66494ca6ec + ref: a54e4c81f365d7b477f65b6ccdb3afec9c147cea path: packages/stream_core_flutter svg_icon_widget: ^0.0.1 synchronized: ^3.4.0 From 38a0c596ffbdfce4f09e78e6ff7c7d4e9a9f49e2 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 19 Jun 2026 11:31:25 +0200 Subject: [PATCH 36/87] update core dependency --- docs/docs_screenshots/pubspec.yaml | 2 +- melos.yaml | 2 +- .../lib/src/channel/channel_header.dart | 2 +- .../lib/src/channel/channel_list_header.dart | 2 +- .../lib/src/message_input/stream_message_composer.dart | 8 ++++---- .../stream_chat_flutter/lib/src/misc/back_button.dart | 4 ++-- packages/stream_chat_flutter/pubspec.yaml | 2 +- sample_app/lib/app.dart | 4 ++-- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index 6273fad8f7..00a29c2e1d 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: f94d9ccf3f6cec2c098ec214b1c39095ddec907c + ref: ee041cd2cd63868ea3f02f8e902a631cf748d02a path: packages/stream_core_flutter dev_dependencies: diff --git a/melos.yaml b/melos.yaml index a0d7d1b543..7b9843cff0 100644 --- a/melos.yaml +++ b/melos.yaml @@ -101,7 +101,7 @@ command: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: f94d9ccf3f6cec2c098ec214b1c39095ddec907c + ref: ee041cd2cd63868ea3f02f8e902a631cf748d02a path: packages/stream_core_flutter synchronized: ^3.4.0 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index 2eae9517de..0950f2fc5e 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -151,7 +151,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget final effectiveAppBarBehavior = style?.behavior ?? StreamAppBarTheme.of(context).style?.behavior ?? - (StreamTheme.of(context).appStyle.isFloating ? AppBarBehavior.floating : AppBarBehavior.regular); + (StreamTheme.of(context).appStyle.isFloating ? .floating : .regular); final showAvatarShadow = switch (effectiveAppBarBehavior) { .floating => true, .regular => false, diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart index 3ec71a454b..e4729011ae 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart @@ -128,7 +128,7 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi final effectiveAppBarBehavior = style?.behavior ?? StreamAppBarTheme.of(context).style?.behavior ?? - (StreamTheme.of(context).appStyle.isFloating ? AppBarBehavior.floating : AppBarBehavior.regular); + (StreamTheme.of(context).appStyle.isFloating ? .floating : .regular); final hasAvatarShadow = switch (effectiveAppBarBehavior) { .floating => true, .regular => false, diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 69e19b4dd1..63f323a2a9 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -1050,7 +1050,7 @@ class DefaultStreamMessageComposerState extends State true, .regular => false, diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index bc580f578e..da19df228b 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -60,7 +60,7 @@ dependencies: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter - ref: f94d9ccf3f6cec2c098ec214b1c39095ddec907c + ref: ee041cd2cd63868ea3f02f8e902a631cf748d02a path: packages/stream_core_flutter svg_icon_widget: ^0.0.1 synchronized: ^3.4.0 diff --git a/sample_app/lib/app.dart b/sample_app/lib/app.dart index ab5c0ac962..5a72bbbadd 100644 --- a/sample_app/lib/app.dart +++ b/sample_app/lib/app.dart @@ -172,8 +172,8 @@ class _StreamChatSampleAppState extends State final config = context.sampleAppConfig; StreamAppStyle appStyle() => switch (config.appStyle) { - SampleAppStyle.regular => StreamAppStyle.regular, - SampleAppStyle.floating => StreamAppStyle.floating, + SampleAppStyle.regular => .regular, + SampleAppStyle.floating => .floating, }; ThemeData theme(Brightness brightness) => ThemeData( From 26d0f3f62dbbe5c1bc49c82d368962d928970266 Mon Sep 17 00:00:00 2001 From: renefloor <15101411+renefloor@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:30:11 +0000 Subject: [PATCH 37/87] chore: Update Goldens --- .../goldens/macos/message_widget_actions.png | Bin 54686 -> 51929 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/docs_screenshots/test/message_list/goldens/macos/message_widget_actions.png b/docs/docs_screenshots/test/message_list/goldens/macos/message_widget_actions.png index daca885b8b9b3f580ce6633995cc83cf9d51367c..544a6d85cb7e75b2b6b8b8723485bcfa1a88b251 100644 GIT binary patch literal 51929 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

$Gjg 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≦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 LQiA#X+TZ>M*?!ur literal 54686 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 Date: Fri, 19 Jun 2026 15:10:00 +0200 Subject: [PATCH 38/87] update core and fix analysis --- docs/docs_screenshots/pubspec.yaml | 4 ++-- melos.yaml | 4 ++-- .../src/message_input/stream_message_composer.dart | 1 - packages/stream_chat_flutter/pubspec.yaml | 12 ++++++++++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index 00a29c2e1d..821db406d8 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -21,8 +21,8 @@ dependencies: stream_chat_flutter: ^10.0.1 stream_core_flutter: git: - url: https://github.com/GetStream/stream-core-flutter - ref: ee041cd2cd63868ea3f02f8e902a631cf748d02a + url: https://github.com/GetStream/stream-core-flutter.git + ref: 66ee511050b8ef4f8a39edf0c2c62568b521d34d path: packages/stream_core_flutter dev_dependencies: diff --git a/melos.yaml b/melos.yaml index 7b9843cff0..de07fca715 100644 --- a/melos.yaml +++ b/melos.yaml @@ -100,8 +100,8 @@ command: svg_icon_widget: ^0.0.1 stream_core_flutter: git: - url: https://github.com/GetStream/stream-core-flutter - ref: ee041cd2cd63868ea3f02f8e902a631cf748d02a + url: https://github.com/GetStream/stream-core-flutter.git + ref: 66ee511050b8ef4f8a39edf0c2c62568b521d34d path: packages/stream_core_flutter synchronized: ^3.4.0 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 63f323a2a9..7eae314b1b 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -7,7 +7,6 @@ import 'package:flutter/services.dart'; import 'package:stream_chat_flutter/src/message_input/error_alert_sheet.dart'; import 'package:stream_chat_flutter/src/message_input/stream_chat_message_input.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; -import 'package:stream_core_flutter/stream_core_flutter.dart' show streamFloatingFade; const _kCommandTrigger = '/'; const _kMentionTrigger = '@'; diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index da19df228b..9445f79c56 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -58,9 +58,17 @@ dependencies: shimmer: ^3.0.0 stream_chat_flutter_core: ^10.0.1 stream_core_flutter: + # The ignore below silences `invalid_dependency` because we occasionally + # pin stream_core_flutter to a git ref to iterate on it alongside this + # SDK between its releases. + # + # **Note:** Before publishing stream_chat_flutter, this MUST be swapped + # back to a pub version constraint — git deps are not allowed on pub.dev + # and will block the release. + # ignore: invalid_dependency git: - url: https://github.com/GetStream/stream-core-flutter - ref: ee041cd2cd63868ea3f02f8e902a631cf748d02a + url: https://github.com/GetStream/stream-core-flutter.git + ref: 66ee511050b8ef4f8a39edf0c2c62568b521d34d path: packages/stream_core_flutter svg_icon_widget: ^0.0.1 synchronized: ^3.4.0 From 6b1db2a04ef9c7c4fc046b2b2e1bce7531a059bd Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 19 Jun 2026 15:22:37 +0200 Subject: [PATCH 39/87] add option for reply in channel config --- docs/docs_screenshots/test/src/mocks.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs_screenshots/test/src/mocks.dart b/docs/docs_screenshots/test/src/mocks.dart index ed9c30b5e4..17979a5cdb 100644 --- a/docs/docs_screenshots/test/src/mocks.dart +++ b/docs/docs_screenshots/test/src/mocks.dart @@ -132,7 +132,7 @@ void setupMockChannel({ when(() => channel.lastMessageAtStream).thenAnswer((_) => Stream.value(DateTime.parse('2020-06-22 12:00:00'))); when(() => channel.state).thenReturn(channelState); when(() => channel.client).thenReturn(client); - when(() => channel.config).thenReturn(ChannelConfig(mutes: true)); + when(() => channel.config).thenReturn(ChannelConfig(mutes: true, replies: true)); when(channel.getRemainingCooldown).thenReturn(0); when(() => channel.isDistinct).thenReturn(false); when(() => channel.isMuted).thenReturn(false); From 6593cc7978e3921cc0dbf874b211b38407007d8e Mon Sep 17 00:00:00 2001 From: renefloor <15101411+renefloor@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:33:23 +0000 Subject: [PATCH 40/87] chore: Update Goldens --- .../goldens/macos/message_widget_actions.png | Bin 51929 -> 54686 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/docs_screenshots/test/message_list/goldens/macos/message_widget_actions.png b/docs/docs_screenshots/test/message_list/goldens/macos/message_widget_actions.png index 544a6d85cb7e75b2b6b8b8723485bcfa1a88b251..daca885b8b9b3f580ce6633995cc83cf9d51367c 100644 GIT binary patch literal 54686 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

$Gjg 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≦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 LQiA#X+TZ>M*?!ur From edd53f2bccdde7a6631371c621868d78463e29c5 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 19 Jun 2026 15:43:02 +0200 Subject: [PATCH 41/87] fix not using new api --- .../lib/src/message_input/stream_message_composer.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 7eae314b1b..79f0c6eaed 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -1024,7 +1024,7 @@ class DefaultStreamMessageComposerState extends State Date: Fri, 19 Jun 2026 15:58:01 +0200 Subject: [PATCH 42/87] fix test and analysis --- .../lib/src/message_input/stream_message_composer.dart | 1 + .../test/src/message_action/message_actions_builder_test.dart | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 79f0c6eaed..bd9085cdd6 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -1024,6 +1024,7 @@ class DefaultStreamMessageComposerState extends State customChannel.config).thenReturn(channelConfig); return customChannel; } From 1862ec01c755586875d66de36a555ee92ee36226 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 29 Jul 2026 11:09:18 +0200 Subject: [PATCH 43/87] project update --- .../ios/Runner.xcodeproj/project.pbxproj | 129 ++++-------------- 1 file changed, 24 insertions(+), 105 deletions(-) diff --git a/sample_app/ios/Runner.xcodeproj/project.pbxproj b/sample_app/ios/Runner.xcodeproj/project.pbxproj index 6fa58ae5c8..e1cace4f6a 100644 --- a/sample_app/ios/Runner.xcodeproj/project.pbxproj +++ b/sample_app/ios/Runner.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; 8210C58B8A5DAB805ACF46A1 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4899F8CDC11D7148C6179369 /* Pods_Runner.framework */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; @@ -51,6 +52,7 @@ 4899F8CDC11D7148C6179369 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 90B43020AC538F68084BBAFD /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; @@ -69,6 +71,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, 8210C58B8A5DAB805ACF46A1 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -87,6 +90,7 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, @@ -166,13 +170,15 @@ 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 0BC14C55242B5A7A0028DE94 /* Embed App Extensions */, 7BD3737C65F59B233B7F7FC6 /* [CP] Embed Pods Frameworks */, - 78D972C66518C545847BBB5A /* [CP] Copy Pods Resources */, ); buildRules = ( ); dependencies = ( ); name = Runner; + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productType = "com.apple.product-type.application"; @@ -202,6 +208,9 @@ Base, ); mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */, + ); productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; @@ -243,24 +252,6 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 78D972C66518C545847BBB5A /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/firebase_messaging/firebase_messaging_Privacy.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/firebase_messaging_Privacy.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; 7BD3737C65F59B233B7F7FC6 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -268,97 +259,11 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/DKImagePickerController/DKImagePickerController.framework", - "${BUILT_PRODUCTS_DIR}/DKPhotoGallery/DKPhotoGallery.framework", - "${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework", - "${BUILT_PRODUCTS_DIR}/FirebaseCoreExtension/FirebaseCoreExtension.framework", - "${BUILT_PRODUCTS_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework", - "${BUILT_PRODUCTS_DIR}/FirebaseCrashlytics/FirebaseCrashlytics.framework", - "${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework", - "${BUILT_PRODUCTS_DIR}/FirebaseMessaging/FirebaseMessaging.framework", - "${BUILT_PRODUCTS_DIR}/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.framework", - "${BUILT_PRODUCTS_DIR}/FirebaseSessions/FirebaseSessions.framework", - "${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework", - "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", - "${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework", - "${BUILT_PRODUCTS_DIR}/PromisesSwift/Promises.framework", - "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", - "${BUILT_PRODUCTS_DIR}/SwiftyGif/SwiftyGif.framework", - "${BUILT_PRODUCTS_DIR}/audio_session/audio_session.framework", - "${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework", - "${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework", - "${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework", - "${BUILT_PRODUCTS_DIR}/file_selector_ios/file_selector_ios.framework", - "${BUILT_PRODUCTS_DIR}/flutter_app_badger/flutter_app_badger.framework", - "${BUILT_PRODUCTS_DIR}/flutter_local_notifications/flutter_local_notifications.framework", - "${BUILT_PRODUCTS_DIR}/flutter_secure_storage_darwin/flutter_secure_storage_darwin.framework", - "${BUILT_PRODUCTS_DIR}/gal/gal.framework", - "${BUILT_PRODUCTS_DIR}/geolocator_apple/geolocator_apple.framework", - "${BUILT_PRODUCTS_DIR}/get_thumbnail_video/get_thumbnail_video.framework", - "${BUILT_PRODUCTS_DIR}/image_picker_ios/image_picker_ios.framework", - "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework", - "${BUILT_PRODUCTS_DIR}/just_audio/just_audio.framework", - "${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework", "${BUILT_PRODUCTS_DIR}/media_kit_video/media_kit_video.framework", - "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", - "${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework", - "${BUILT_PRODUCTS_DIR}/photo_manager/photo_manager.framework", - "${BUILT_PRODUCTS_DIR}/record_ios/record_ios.framework", - "${BUILT_PRODUCTS_DIR}/share_plus/share_plus.framework", - "${BUILT_PRODUCTS_DIR}/shared_preferences_foundation/shared_preferences_foundation.framework", - "${BUILT_PRODUCTS_DIR}/sqflite_darwin/sqflite_darwin.framework", - "${BUILT_PRODUCTS_DIR}/sqlite3/sqlite3.framework", - "${BUILT_PRODUCTS_DIR}/sqlite3_flutter_libs/sqlite3_flutter_libs.framework", - "${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework", - "${BUILT_PRODUCTS_DIR}/video_player_avfoundation/video_player_avfoundation.framework", - "${BUILT_PRODUCTS_DIR}/wakelock_plus/wakelock_plus.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DKImagePickerController.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DKPhotoGallery.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreExtension.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreInternal.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCrashlytics.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseMessaging.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseRemoteConfigInterop.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseSessions.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Promises.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyGif.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/audio_session.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_selector_ios.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_app_badger.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_local_notifications.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_secure_storage_darwin.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/gal.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/geolocator_apple.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/get_thumbnail_video.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_picker_ios.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/just_audio.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/media_kit_video.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/photo_manager.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/record_ios.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share_plus.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_foundation.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite_darwin.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqlite3.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqlite3_flutter_libs.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_player_avfoundation.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/wakelock_plus.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -718,6 +623,20 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } From 4490030ba9a02ba5f8a61cd60e6420fb4c2a716f Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 29 Jul 2026 11:56:55 +0200 Subject: [PATCH 44/87] fix pixel artifact between components --- .../stream_message_composer.dart | 76 +++++++++++++++++-- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 72e665fceb..e84da519d6 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -14,6 +14,17 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; const _kCommandTrigger = '/'; const _kMentionTrigger = '@'; +// How far the floating composer's lower background paints bleed *up*, under the +// paint above them. +// +// The floating composer stacks several same-colored fills (the pill's gradient +// band, the picker panel, the safe-area strip). Where two of them merely abut at +// a fractional device-pixel boundary, both edges get antialiased; composited in +// sequence their coverages don't sum to 1, so a hairline of whatever is behind +// (the message list) survives. Overlapping instead of abutting removes the seam, +// and is invisible because the paints share a color. +const _kFloatingSeamBleed = 1.0; + /// Signature for the function that determines if a [matchedUri] should be /// previewed as an OG Attachment. typedef OgPreviewFilter = bool Function(Uri matchedUri, String messageText); @@ -859,7 +870,9 @@ class DefaultStreamMessageComposerState extends State Date: Wed, 29 Jul 2026 14:10:36 +0200 Subject: [PATCH 45/87] change background into 1 gradient --- .../stream_message_composer.dart | 184 +++++++------ .../test/src/channel/channel_page_test.dart | 215 ++++++++++++++++ .../test/src/channel/thread_page_test.dart | 241 ++++++++++++++++++ .../message_composer_location_test.dart | 197 ++++++++++++++ .../theme/message_composer_theme_test.dart | 179 +++++++++++++ 5 files changed, 931 insertions(+), 85 deletions(-) create mode 100644 packages/stream_chat_flutter/test/src/channel/channel_page_test.dart create mode 100644 packages/stream_chat_flutter/test/src/channel/thread_page_test.dart create mode 100644 packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart create mode 100644 packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index e84da519d6..23110fb800 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -3,7 +3,9 @@ import 'dart:math' as math; import 'package:desktop_drop/desktop_drop.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/semantics.dart'; +// Needed for RenderProxyBox; it also re-exports the semantics library that +// Assertiveness comes from, which is why flutter/semantics.dart isn't imported. +import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:stream_chat_flutter/src/message_input/audio_recorder/audio_recorder_announcer.dart'; import 'package:stream_chat_flutter/src/message_input/composer_attachment_announcer.dart'; @@ -14,17 +16,6 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; const _kCommandTrigger = '/'; const _kMentionTrigger = '@'; -// How far the floating composer's lower background paints bleed *up*, under the -// paint above them. -// -// The floating composer stacks several same-colored fills (the pill's gradient -// band, the picker panel, the safe-area strip). Where two of them merely abut at -// a fractional device-pixel boundary, both edges get antialiased; composited in -// sequence their coverages don't sum to 1, so a hairline of whatever is behind -// (the message list) survives. Overlapping instead of abutting removes the seam, -// and is invisible because the paints share a color. -const _kFloatingSeamBleed = 1.0; - /// Signature for the function that determines if a [matchedUri] should be /// previewed as an OG Attachment. typedef OgPreviewFilter = bool Function(Uri matchedUri, String messageText); @@ -858,22 +849,20 @@ class DefaultStreamMessageComposerState extends State 0) { - final bandColor = context.streamColorScheme.backgroundElevation1; + // For floating: one continuous backdrop behind the pill, the picker and + // the safe-area zone. Painting it as a single layer is what keeps it + // seamless — abutting fills would each be antialiased at a fractional + // device-pixel boundary and let a hairline of the message list through. + if (effectiveComposerLocation == .floating) { return Stack( children: [ - Positioned( - bottom: 0, - left: 0, - right: 0, - // Bleeds up under the pill/picker above it to avoid a seam; - // this is a Positioned, so it only affects painting. - height: safeAreaPadding.bottom + _kFloatingSeamBleed, - child: ColoredBox(color: bandColor), + Positioned.fill( + child: CustomPaint( + painter: _FloatingComposerBackdropPainter( + color: context.streamColorScheme.backgroundElevation1, + fadeExtent: _pillHeight, + ), + ), ), Padding(padding: safeAreaPadding, child: child), ], @@ -1053,21 +1042,20 @@ class DefaultStreamMessageComposerState extends State _pillHeight.value = height, child: pill) + else + pill, ], ), ); @@ -1075,26 +1063,10 @@ class DefaultStreamMessageComposerState extends State(0); Widget _buildInlineAttachmentPicker(BuildContext context) { if (!_isPickerVisible) return const SizedBox.shrink(); @@ -1129,8 +1101,8 @@ class DefaultStreamMessageComposerState extends State fadeExtent; @override - Widget build(BuildContext context) { - // CustomPaint runs the painter before the child and never clips, which is - // what lets the fill escape above its own bounds. - return CustomPaint( - painter: _TopBleedFillPainter(color: color, bleed: _kFloatingSeamBleed), - child: child, + void paint(Canvas canvas, Size size) { + if (size.isEmpty) return; + + // The gradient runs bottom-to-top, so the solid run is measured from the + // bottom and the fade occupies the top `extent` pixels. + final extent = math.min(fadeExtent.value, size.height); + final solidFraction = (1 - extent / size.height).clamp(0.0, 1.0); + + final rect = Offset.zero & size; + final gradient = streamFloatingFadeLinearGradient( + color: color, + solidFraction: solidFraction, + begin: Alignment.bottomCenter, + end: Alignment.topCenter, ); + + canvas.drawRect(rect, Paint()..shader = gradient.createShader(rect)); + } + + @override + bool shouldRepaint(_FloatingComposerBackdropPainter oldDelegate) { + return oldDelegate.color != color || oldDelegate.fadeExtent != fadeExtent; } } -class _TopBleedFillPainter extends CustomPainter { - const _TopBleedFillPainter({required this.color, required this.bleed}); +/// Reports [child]'s laid-out height via [onHeightChanged] during layout. +/// +/// Used to feed the pill's height to [_FloatingComposerBackdropPainter]. The +/// callback fires inside `performLayout`, which is safe for the listener to turn +/// into a repaint: the framework flushes all layout before any painting, so the +/// backdrop sees the current height in the same frame. +class _ReportHeight extends SingleChildRenderObjectWidget { + const _ReportHeight({required this.onHeightChanged, required super.child}); - final Color color; - final double bleed; + final ValueChanged onHeightChanged; @override - void paint(Canvas canvas, Size size) { - // Nothing to tuck under when collapsed; skip so we don't leave a stray line. - if (size.isEmpty) return; + _RenderReportHeight createRenderObject(BuildContext context) { + return _RenderReportHeight(onHeightChanged: onHeightChanged); + } - final rect = Rect.fromLTWH(0, -bleed, size.width, size.height + bleed); - canvas.drawRect(rect, Paint()..color = color); + @override + void updateRenderObject(BuildContext context, _RenderReportHeight renderObject) { + renderObject.onHeightChanged = onHeightChanged; } +} + +class _RenderReportHeight extends RenderProxyBox { + _RenderReportHeight({required this.onHeightChanged}); + + ValueChanged onHeightChanged; @override - bool shouldRepaint(_TopBleedFillPainter oldDelegate) { - return oldDelegate.color != color || oldDelegate.bleed != bleed; + void performLayout() { + super.performLayout(); + onHeightChanged(size.height); } } diff --git a/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart b/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart new file mode 100644 index 0000000000..86be8d77e7 --- /dev/null +++ b/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart @@ -0,0 +1,215 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:record/record.dart'; +import 'package:stream_chat_flutter/src/message_input/stream_chat_message_input.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import '../fakes.dart'; +import '../mocks.dart'; + +void main() { + testWidgets('renders a header, a message list and a composer', (tester) async { + await _pumpChannelPage(tester); + + expect(find.byType(StreamChannelHeader), findsOneWidget); + expect(find.byType(StreamMessageListView), findsOneWidget); + expect(find.byType(StreamMessageComposer), findsOneWidget); + }); + + testWidgets('renders a typing indicator above the composer', (tester) async { + await _pumpChannelPage(tester, appStyle: StreamAppStyle.floating); + + final indicator = tester.getRect(_bodyTypingIndicator()); + final composer = tester.getRect(find.byType(StreamMessageComposer)); + + expect(indicator.bottom, lessThanOrEqualTo(composer.top)); + }); + + testWidgets('tapping the channel avatar invokes onChannelAvatarPressed', (tester) async { + Channel? pressedChannel; + await _pumpChannelPage(tester, onChannelAvatarPressed: (_, channel) => pressedChannel = channel); + + await tester.tap(_channelAvatarTapTarget()); + await tester.pumpAndSettle(); + + expect(pressedChannel, isNotNull); + }); + + testWidgets('replying to a message quotes it in the composer', (tester) async { + final message = Message(id: 'message-id', text: 'Hello world!'); + + await _pumpChannelPage(tester); + _messageListView(tester).onReplyTap!(message); + await tester.pumpAndSettle(); + + expect(_composerController(tester).message.quotedMessage, message); + }); + + testWidgets('replying to a message focuses the composer', (tester) async { + final message = Message(id: 'message-id', text: 'Hello world!'); + + await _pumpChannelPage(tester); + _messageListView(tester).onReplyTap!(message); + await tester.pumpAndSettle(); + + expect(_composerFocusNode(tester).hasFocus, isTrue); + }); + + testWidgets('editing a message loads it into the composer', (tester) async { + final message = Message(id: 'message-id', text: 'Hello world!'); + + await _pumpChannelPage(tester); + _messageListView(tester).onEditMessageTap!(message); + await tester.pumpAndSettle(); + + expect(_composerController(tester).messageBeingEdited, message); + }); + + testWidgets('editing a message focuses the composer', (tester) async { + final message = Message(id: 'message-id', text: 'Hello world!'); + + await _pumpChannelPage(tester); + _messageListView(tester).onEditMessageTap!(message); + await tester.pumpAndSettle(); + + expect(_composerFocusNode(tester).hasFocus, isTrue); + }); + + testWidgets('opens a thread page for the tapped parent message', (tester) async { + final parentMessage = Message(id: 'parent-id', text: 'Hello world!'); + + await _pumpChannelPage(tester); + final context = tester.element(find.byType(StreamMessageListView)); + final thread = _messageListView(tester).threadBuilder!(context, parentMessage); + + expect(thread, isA().having((it) => it.parent, 'parent', parentMessage)); + }); + + testWidgets('insets the message list behind a floating app bar and composer', (tester) async { + await _pumpChannelPage(tester, appStyle: StreamAppStyle.floating); + + final messageListView = _messageListView(tester); + + expect(messageListView.topPadding, greaterThan(0)); + expect(messageListView.bottomPadding, greaterThan(0)); + }); + + testWidgets('does not inset the message list when the app style is regular', (tester) async { + await _pumpChannelPage(tester); + + final messageListView = _messageListView(tester); + + expect(messageListView.topPadding, 0); + expect(messageListView.bottomPadding, 0); + }); + + testWidgets('disposes its composer controller when removed from the tree', (tester) async { + await _pumpChannelPage(tester); + final controller = _composerController(tester); + + await tester.pumpWidget(const MaterialApp(home: SizedBox.shrink())); + + // A disposed ChangeNotifier throws when listened to again. + expect(() => controller.addListener(() {}), throwsFlutterError); + }); +} + +StreamMessageListView _messageListView(WidgetTester tester) { + return tester.widget(find.byType(StreamMessageListView)); +} + +/// The typing indicator the page renders in its body. +/// +/// The header renders one of its own as part of the channel subtitle, so the +/// plain type finder is ambiguous. +Finder _bodyTypingIndicator() { + final inHeader = find + .descendant(of: find.byType(StreamChannelHeader), matching: find.byType(StreamTypingIndicator)) + .evaluate() + .toSet(); + + return find.byElementPredicate((element) { + return element.widget is StreamTypingIndicator && !inHeader.contains(element); + }); +} + +/// The gesture detector wrapping the header's channel avatar. +Finder _channelAvatarTapTarget() { + return find.ancestor( + of: find.byType(StreamChannelAvatar), + matching: find.byType(GestureDetector), + ); +} + +/// The controller the page created and handed to its composer. +StreamMessageComposerController _composerController(WidgetTester tester) { + return tester.widget(find.byType(StreamChatMessageInput)).controller!; +} + +/// The focus node the page created and handed to its composer. +FocusNode _composerFocusNode(WidgetTester tester) { + return tester.widget(find.byType(StreamChatMessageInput)).focusNode!; +} + +Future _pumpChannelPage( + WidgetTester tester, { + StreamAppStyle appStyle = StreamAppStyle.regular, + void Function(BuildContext context, Channel channel)? onChannelAvatarPressed, +}) async { + final originalRecordPlatform = RecordPlatform.instance; + RecordPlatform.instance = FakeRecordPlatform(); + addTearDown(() => RecordPlatform.instance = originalRecordPlatform); + + final client = MockClient(); + final clientState = MockClientState(); + final channel = MockChannel(); + final channelState = MockChannelState(); + final currentUser = OwnUser(id: 'user-id'); + + when(() => client.state).thenReturn(clientState); + when(() => clientState.currentUser).thenReturn(currentUser); + when(() => clientState.currentUserStream).thenAnswer((_) => Stream.value(currentUser)); + when(() => clientState.totalUnreadCount).thenReturn(0); + when(() => clientState.totalUnreadCountStream).thenAnswer((_) => Stream.value(0)); + + when(() => channel.client).thenReturn(client); + when(() => channel.state).thenReturn(channelState); + when(channel.getRemainingCooldown).thenReturn(0); + when(() => channel.lastMessageAt).thenReturn(null); + when(() => channel.name).thenReturn('test'); + when(() => channel.nameStream).thenAnswer((_) => Stream.value('test')); + when(() => channel.image).thenReturn(null); + when(() => channel.imageStream).thenAnswer((_) => Stream.value(null)); + when(() => channel.isMuted).thenReturn(false); + when(() => channel.isMutedStream).thenAnswer((_) => Stream.value(false)); + when(() => channel.extraData).thenReturn({'name': 'test'}); + when(() => channel.extraDataStream).thenAnswer((_) => Stream.value({'name': 'test'})); + + when(() => channelState.members).thenReturn([]); + when(() => channelState.membersStream).thenAnswer((_) => Stream.value([])); + when(() => channelState.messages).thenReturn([]); + when(() => channelState.messagesStream).thenAnswer((_) => Stream.value([])); + when(() => channelState.threadsStream).thenAnswer((_) => const Stream.empty()); + when(() => channelState.draft).thenReturn(null); + when(() => channelState.isUpToDateStream).thenAnswer((_) => Stream.value(true)); + when(() => channelState.unreadCountStream).thenAnswer((_) => Stream.value(0)); + when(() => channelState.readStream).thenAnswer((_) => Stream.value([])); + when(() => channelState.currentUserRead).thenReturn(null); + when(() => channelState.currentUserReadStream).thenAnswer((_) => const Stream.empty()); + + await tester.pumpWidget( + MaterialApp( + theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), + home: StreamChat( + client: client, + child: StreamChannel( + channel: channel, + child: StreamChannelPage(onChannelAvatarPressed: onChannelAvatarPressed), + ), + ), + ), + ); + + await tester.pumpAndSettle(); +} diff --git a/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart b/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart new file mode 100644 index 0000000000..dd85333036 --- /dev/null +++ b/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart @@ -0,0 +1,241 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:record/record.dart'; +import 'package:stream_chat_flutter/src/message_input/stream_chat_message_input.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import '../fakes.dart'; +import '../mocks.dart'; + +void main() { + testWidgets('renders a header, a message list and a composer', (tester) async { + await _pumpThreadPage(tester); + + expect(find.byType(StreamThreadHeader), findsOneWidget); + expect(find.byType(StreamMessageListView), findsOneWidget); + expect(find.byType(StreamMessageComposer), findsOneWidget); + }); + + testWidgets('shows the thread of the parent message', (tester) async { + final parent = Message(id: 'parent-id', text: 'Hello world!'); + + await _pumpThreadPage(tester, parent: parent); + + expect(_messageListView(tester).parentMessage, parent); + }); + + testWidgets('addresses new messages to the parent thread', (tester) async { + final parent = Message(id: 'parent-id', text: 'Hello world!'); + + await _pumpThreadPage(tester, parent: parent); + + expect(_composerController(tester).message.parentId, 'parent-id'); + }); + + testWidgets('hides the composer when the parent message is deleted', (tester) async { + final parent = Message(id: 'parent-id', text: 'Hello world!', type: 'deleted'); + + await _pumpThreadPage(tester, parent: parent); + _ignoreDeletedBubbleOverflow(tester); + + expect(find.byType(StreamMessageComposer), findsNothing); + }); + + testWidgets('still shows the thread when the parent message is deleted', (tester) async { + final parent = Message(id: 'parent-id', text: 'Hello world!', type: 'deleted'); + + await _pumpThreadPage(tester, parent: parent); + _ignoreDeletedBubbleOverflow(tester); + + expect(find.byType(StreamMessageListView), findsOneWidget); + }); + + testWidgets('replying to a message quotes it in the composer', (tester) async { + final message = Message(id: 'message-id', text: 'Hello world!'); + + await _pumpThreadPage(tester); + _messageListView(tester).onReplyTap!(message); + await tester.pumpAndSettle(); + + expect(_composerController(tester).message.quotedMessage, message); + }); + + testWidgets('replying to a message focuses the composer', (tester) async { + final message = Message(id: 'message-id', text: 'Hello world!'); + + await _pumpThreadPage(tester); + _messageListView(tester).onReplyTap!(message); + await tester.pumpAndSettle(); + + expect(_composerFocusNode(tester).hasFocus, isTrue); + }); + + testWidgets('editing a message loads it into the composer', (tester) async { + final message = Message(id: 'message-id', text: 'Hello world!'); + + await _pumpThreadPage(tester); + _messageListView(tester).onEditMessageTap!(message); + await tester.pumpAndSettle(); + + expect(_composerController(tester).messageBeingEdited, message); + }); + + testWidgets('editing a message focuses the composer', (tester) async { + final message = Message(id: 'message-id', text: 'Hello world!'); + + await _pumpThreadPage(tester); + _messageListView(tester).onEditMessageTap!(message); + await tester.pumpAndSettle(); + + expect(_composerFocusNode(tester).hasFocus, isTrue); + }); + + testWidgets('forwards onViewInChannelTap to the message list', (tester) async { + final message = Message(id: 'message-id', text: 'Hello world!'); + Message? viewedInChannel; + + await _pumpThreadPage(tester, onViewInChannelTap: (message) => viewedInChannel = message); + _messageListView(tester).onViewInChannelTap!(message); + await tester.pumpAndSettle(); + + expect(viewedInChannel, message); + }); + + testWidgets('insets the message list behind a floating app bar and composer', (tester) async { + await _pumpThreadPage(tester, appStyle: StreamAppStyle.floating); + + final messageListView = _messageListView(tester); + + expect(messageListView.topPadding, greaterThan(0)); + expect(messageListView.bottomPadding, greaterThan(0)); + }); + + testWidgets('does not inset the message list when the app style is regular', (tester) async { + await _pumpThreadPage(tester); + + final messageListView = _messageListView(tester); + + expect(messageListView.topPadding, 0); + expect(messageListView.bottomPadding, 0); + }); + + testWidgets('disposes its composer controller when removed from the tree', (tester) async { + await _pumpThreadPage(tester); + final controller = _composerController(tester); + + await tester.pumpWidget(const MaterialApp(home: SizedBox.shrink())); + + // A disposed ChangeNotifier throws when listened to again. + expect(() => controller.addListener(() {}), throwsFlutterError); + }); +} + +StreamMessageListView _messageListView(WidgetTester tester) { + return tester.widget(find.byType(StreamMessageListView)); +} + +/// Drains the overflow [FlutterError] the deleted-message bubble reports. +/// +/// `StreamMessageDeleted` lays out its icon and label in a fixed-width bubble. +/// The test font is squarer — and so wider — than the font that ships with the +/// app, which pushes the label a few pixels past the bubble. It fits in a real +/// app, so it is not what these tests are about. +void _ignoreDeletedBubbleOverflow(WidgetTester tester) { + final exception = tester.takeException(); + if (exception == null) return; + + expect(exception, isFlutterError); + expect('$exception', contains('overflowed')); +} + +/// The controller the page created and handed to its composer. +StreamMessageComposerController _composerController(WidgetTester tester) { + return tester.widget(find.byType(StreamChatMessageInput)).controller!; +} + +/// The focus node the page created and handed to its composer. +FocusNode _composerFocusNode(WidgetTester tester) { + return tester.widget(find.byType(StreamChatMessageInput)).focusNode!; +} + +Future _pumpThreadPage( + WidgetTester tester, { + Message? parent, + StreamAppStyle appStyle = StreamAppStyle.regular, + void Function(Message message)? onViewInChannelTap, +}) async { + final originalRecordPlatform = RecordPlatform.instance; + RecordPlatform.instance = FakeRecordPlatform(); + addTearDown(() => RecordPlatform.instance = originalRecordPlatform); + + final client = MockClient(); + final clientState = MockClientState(); + final channel = MockChannel(); + final channelState = MockChannelState(); + final currentUser = OwnUser(id: 'user-id'); + final parentMessage = parent ?? Message(id: 'parent-id', text: 'Hello world!'); + + // The thread is loaded — an empty reply list, not a missing one, is what + // takes the message list out of its skeleton-loading state. + final threads = {parentMessage.id: []}; + + when(() => client.state).thenReturn(clientState); + when(() => clientState.currentUser).thenReturn(currentUser); + when(() => clientState.currentUserStream).thenAnswer((_) => Stream.value(currentUser)); + when(() => clientState.totalUnreadCount).thenReturn(0); + when(() => clientState.totalUnreadCountStream).thenAnswer((_) => Stream.value(0)); + when(() => clientState.channels).thenReturn({}); + when(() => clientState.channelsStream).thenAnswer((_) => Stream.value({})); + + when(() => channel.client).thenReturn(client); + when(() => channel.state).thenReturn(channelState); + when(channel.getRemainingCooldown).thenReturn(0); + when(() => channel.lastMessageAt).thenReturn(null); + when(() => channel.name).thenReturn('test'); + when(() => channel.nameStream).thenAnswer((_) => Stream.value('test')); + when(() => channel.image).thenReturn(null); + when(() => channel.imageStream).thenAnswer((_) => Stream.value(null)); + when(() => channel.isMuted).thenReturn(false); + when(() => channel.isMutedStream).thenAnswer((_) => Stream.value(false)); + when(() => channel.extraData).thenReturn({'name': 'test'}); + when(() => channel.extraDataStream).thenAnswer((_) => Stream.value({'name': 'test'})); + when( + () => channel.getReplies( + any(), + options: any(named: 'options'), + preferOffline: any(named: 'preferOffline'), + ), + ).thenAnswer((_) async => QueryRepliesResponse()..messages = []); + + when(() => channelState.members).thenReturn([]); + when(() => channelState.membersStream).thenAnswer((_) => Stream.value([])); + when(() => channelState.messages).thenReturn([]); + when(() => channelState.messagesStream).thenAnswer((_) => Stream.value([])); + when(() => channelState.threads).thenReturn(threads); + when(() => channelState.threadsStream).thenAnswer((_) => Stream.value(threads)); + when(() => channelState.draft).thenReturn(null); + when(() => channelState.isUpToDateStream).thenAnswer((_) => Stream.value(true)); + when(() => channelState.unreadCountStream).thenAnswer((_) => Stream.value(0)); + when(() => channelState.readStream).thenAnswer((_) => Stream.value([])); + when(() => channelState.currentUserRead).thenReturn(null); + when(() => channelState.currentUserReadStream).thenAnswer((_) => const Stream.empty()); + + await tester.pumpWidget( + MaterialApp( + theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), + home: StreamChat( + client: client, + child: StreamChannel( + channel: channel, + child: StreamThreadPage( + parent: parentMessage, + onViewInChannelTap: onViewInChannelTap, + ), + ), + ), + ), + ); + + await tester.pumpAndSettle(); +} diff --git a/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart b/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart new file mode 100644 index 0000000000..729142abac --- /dev/null +++ b/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart @@ -0,0 +1,197 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:record/record.dart'; +import 'package:stream_chat_flutter/src/message_input/stream_chat_message_input.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import '../fakes.dart'; +import '../mocks.dart'; + +void main() { + testWidgets('composer is docked when the app style is regular', (tester) async { + await _pumpComposer(tester, appStyle: StreamAppStyle.regular); + + expect(_resolvedLocation(tester), ComposerLocation.docked); + }); + + testWidgets('composer floats when the app style is floating', (tester) async { + await _pumpComposer(tester, appStyle: StreamAppStyle.floating); + + expect(_resolvedLocation(tester), ComposerLocation.floating); + }); + + testWidgets('the global composer theme overrides the app style', (tester) async { + await _pumpComposer( + tester, + appStyle: StreamAppStyle.regular, + globalTheme: const StreamMessageComposerThemeData(location: ComposerLocation.floating), + ); + + expect(_resolvedLocation(tester), ComposerLocation.floating); + }); + + testWidgets('a local composer theme overrides the global theme', (tester) async { + await _pumpComposer( + tester, + appStyle: StreamAppStyle.floating, + globalTheme: const StreamMessageComposerThemeData(location: ComposerLocation.floating), + localTheme: const StreamMessageComposerThemeData(location: ComposerLocation.docked), + ); + + expect(_resolvedLocation(tester), ComposerLocation.docked); + }); + + testWidgets('the location property overrides both the theme and the app style', (tester) async { + await _pumpComposer( + tester, + appStyle: StreamAppStyle.floating, + globalTheme: const StreamMessageComposerThemeData(location: ComposerLocation.floating), + location: ComposerLocation.docked, + ); + + expect(_resolvedLocation(tester), ComposerLocation.docked); + }); + + testWidgets('the docked composer fills its background with the elevation-1 color', (tester) async { + await _pumpComposer(tester, appStyle: StreamAppStyle.regular); + + expect(_backgroundFillFinder(tester), findsOneWidget); + }); + + testWidgets('the floating composer does not fill its background', (tester) async { + // Floating paints a fading backdrop instead of an opaque fill, so the + // message list stays visible behind the composer. + await _pumpComposer(tester, appStyle: StreamAppStyle.floating); + + expect(_backgroundFillFinder(tester), findsNothing); + }); + + testWidgets('the floating composer lifts the input above the bottom safe area', (tester) async { + const bottomInset = 34.0; + await _pumpComposer(tester, appStyle: StreamAppStyle.floating, bottomPadding: bottomInset); + + final gap = _gapBelowInput(tester); + + expect(gap, moreOrLessEquals(bottomInset)); + }); + + testWidgets('the floating composer keeps a minimum gap when there is no safe area', (tester) async { + await _pumpComposer(tester, appStyle: StreamAppStyle.floating); + + final gap = _gapBelowInput(tester); + + // Falls back to `spacing.md` so the pill never sits flush with the edge. + final context = tester.element(find.byType(StreamChatMessageInput)); + expect(gap, moreOrLessEquals(context.streamSpacing.md)); + }); + + testWidgets('the floating composer leaves no gap when the safe area is disabled', (tester) async { + await _pumpComposer( + tester, + appStyle: StreamAppStyle.floating, + bottomPadding: 34, + enableSafeArea: false, + ); + + final gap = _gapBelowInput(tester); + + expect(gap, moreOrLessEquals(0)); + }); +} + +/// The location the composer resolved, read back from the input it built. +ComposerLocation _resolvedLocation(WidgetTester tester) { + final input = tester.widget(find.byType(StreamChatMessageInput)); + return input.isFloating ? ComposerLocation.floating : ComposerLocation.docked; +} + +/// Finds the opaque background fill the docked composer paints behind itself. +Finder _backgroundFillFinder(WidgetTester tester) { + final context = tester.element(find.byType(StreamChatMessageInput)); + final fill = BoxDecoration(color: context.streamColorScheme.backgroundElevation1); + + return find.descendant( + of: find.byType(StreamMessageComposer), + matching: find.byWidgetPredicate((widget) => widget is DecoratedBox && widget.decoration == fill), + ); +} + +/// The vertical distance between the bottom of the input pill and the bottom +/// of the composer. +double _gapBelowInput(WidgetTester tester) { + final composer = tester.getRect(find.byType(StreamMessageComposer)); + final input = tester.getRect(find.byType(StreamChatMessageInput)); + + return composer.bottom - input.bottom; +} + +/// Pumps a [StreamMessageComposer] with the given placement inputs. +/// +/// The composer is placed at the bottom of the screen so its rect can be +/// compared against the input pill's. +Future _pumpComposer( + WidgetTester tester, { + required StreamAppStyle appStyle, + StreamMessageComposerThemeData? globalTheme, + StreamMessageComposerThemeData? localTheme, + ComposerLocation? location, + bool? enableSafeArea, + double bottomPadding = 0, +}) async { + final originalRecordPlatform = RecordPlatform.instance; + RecordPlatform.instance = FakeRecordPlatform(); + addTearDown(() => RecordPlatform.instance = originalRecordPlatform); + + final client = MockClient(); + final clientState = MockClientState(); + final channel = MockChannel(); + final channelState = MockChannelState(); + + when(() => client.state).thenReturn(clientState); + when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); + when(() => clientState.currentUserStream).thenAnswer((_) => Stream.value(OwnUser(id: 'user-id'))); + when(() => channel.state).thenReturn(channelState); + when(() => channel.client).thenReturn(client); + when(channel.getRemainingCooldown).thenReturn(0); + when(() => channel.lastMessageAt).thenReturn(null); + when(() => channel.extraData).thenReturn({'name': 'test'}); + when(() => channel.extraDataStream).thenAnswer((_) => Stream.value({'name': 'test'})); + when(() => channelState.members).thenReturn([]); + when(() => channelState.membersStream).thenAnswer((_) => Stream.value([])); + when(() => channelState.messages).thenReturn([]); + when(() => channelState.messagesStream).thenAnswer((_) => Stream.value([])); + when(() => channelState.draft).thenReturn(null); + + final composer = StreamMessageComposer( + location: location, + enableSafeArea: enableSafeArea, + ); + + await tester.pumpWidget( + MaterialApp( + theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), + home: MediaQuery( + data: MediaQueryData(padding: EdgeInsets.only(bottom: bottomPadding)), + child: StreamChat( + client: client, + themeData: StreamChatThemeData(messageComposerTheme: globalTheme), + child: StreamChannel( + channel: channel, + child: Scaffold( + body: Align( + alignment: Alignment.bottomCenter, + child: switch (localTheme) { + final localTheme? => StreamMessageComposerTheme(data: localTheme, child: composer), + _ => composer, + }, + ), + ), + ), + ), + ), + ), + ); + + await tester.pumpAndSettle(); +} diff --git a/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart b/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart new file mode 100644 index 0000000000..b5b0a08f9d --- /dev/null +++ b/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart @@ -0,0 +1,179 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import '../mocks.dart'; + +void main() { + test('copyWith with no arguments returns an equal MessageComposerThemeData', () { + const themeData = StreamMessageComposerThemeData(location: ComposerLocation.floating); + + expect(themeData.copyWith(), themeData); + }); + + test('copyWith with no arguments preserves the hashCode', () { + const themeData = StreamMessageComposerThemeData(location: ComposerLocation.floating); + + expect(themeData.copyWith().hashCode, themeData.hashCode); + }); + + test('copyWith overrides the location', () { + const docked = StreamMessageComposerThemeData(location: ComposerLocation.docked); + + expect(docked.copyWith(location: ComposerLocation.floating).location, ComposerLocation.floating); + }); + + test('MessageComposerThemeData instances with different locations are not equal', () { + expect( + const StreamMessageComposerThemeData(location: ComposerLocation.docked), + isNot(const StreamMessageComposerThemeData(location: ComposerLocation.floating)), + ); + }); + + test('lerp at t = 0 resolves to the start location', () { + expect( + StreamMessageComposerThemeData.lerp(_dockedTheme, _floatingTheme, 0)?.location, + ComposerLocation.docked, + ); + }); + + test('lerp below the halfway point resolves to the start location', () { + expect( + StreamMessageComposerThemeData.lerp(_dockedTheme, _floatingTheme, 0.49)?.location, + ComposerLocation.docked, + ); + }); + + test('lerp at or past the halfway point resolves to the end location', () { + expect( + StreamMessageComposerThemeData.lerp(_dockedTheme, _floatingTheme, 0.5)?.location, + ComposerLocation.floating, + ); + }); + + test('lerp at t = 1 resolves to the end location', () { + expect(StreamMessageComposerThemeData.lerp(_dockedTheme, _floatingTheme, 1), _floatingTheme); + }); + + test('merge with null keeps the original location', () { + expect(_dockedTheme.merge(null), _dockedTheme); + }); + + test('merge overrides the location with the other theme', () { + expect(_dockedTheme.merge(_floatingTheme), _floatingTheme); + }); + + test('merge with an empty theme keeps the original location', () { + expect(_floatingTheme.merge(const StreamMessageComposerThemeData()), _floatingTheme); + }); + + testWidgets('of returns a null location when no theme is configured', (tester) async { + final context = await _pumpAndCaptureContext(tester); + + expect(StreamMessageComposerTheme.of(context).location, isNull); + }); + + testWidgets('of returns the global theme location when no local theme is present', (tester) async { + final context = await _pumpAndCaptureContext(tester, globalTheme: _floatingTheme); + + expect(StreamMessageComposerTheme.of(context).location, ComposerLocation.floating); + }); + + testWidgets('of merges the local theme over the global theme', (tester) async { + final context = await _pumpAndCaptureContext( + tester, + globalTheme: _dockedTheme, + localTheme: _floatingTheme, + ); + + expect(StreamMessageComposerTheme.of(context).location, ComposerLocation.floating); + }); + + testWidgets('of falls back to the global theme when the local theme sets no location', (tester) async { + final context = await _pumpAndCaptureContext( + tester, + globalTheme: _floatingTheme, + localTheme: const StreamMessageComposerThemeData(), + ); + + expect(StreamMessageComposerTheme.of(context).location, ComposerLocation.floating); + }); + + testWidgets('wrap re-establishes the theme in a detached subtree', (tester) async { + late BuildContext capturedContext; + await tester.pumpWidget( + MaterialApp( + home: Builder( + builder: (context) { + // `wrap` is what InheritedTheme.captureAll calls to carry the theme + // across a route boundary; assert it round-trips the same data. + final theme = StreamMessageComposerTheme( + data: _floatingTheme, + child: Builder( + builder: (context) { + capturedContext = context; + return const SizedBox.shrink(); + }, + ), + ); + + return theme.wrap(context, theme.child); + }, + ), + ), + ); + + expect(StreamMessageComposerTheme.of(capturedContext).location, ComposerLocation.floating); + }); + + testWidgets('updateShouldNotify is true when the data changes', (tester) async { + const oldWidget = StreamMessageComposerTheme(data: _dockedTheme, child: SizedBox.shrink()); + const newWidget = StreamMessageComposerTheme(data: _floatingTheme, child: SizedBox.shrink()); + + expect(newWidget.updateShouldNotify(oldWidget), isTrue); + }); + + testWidgets('updateShouldNotify is false when the data is unchanged', (tester) async { + const oldWidget = StreamMessageComposerTheme(data: _dockedTheme, child: SizedBox.shrink()); + const newWidget = StreamMessageComposerTheme(data: _dockedTheme, child: SizedBox.shrink()); + + expect(newWidget.updateShouldNotify(oldWidget), isFalse); + }); +} + +const _dockedTheme = StreamMessageComposerThemeData(location: ComposerLocation.docked); +const _floatingTheme = StreamMessageComposerThemeData(location: ComposerLocation.floating); + +/// Pumps a [StreamChat] configured with [globalTheme], optionally wrapped in a +/// local [StreamMessageComposerTheme] carrying [localTheme], and returns a +/// context below both. +Future _pumpAndCaptureContext( + WidgetTester tester, { + StreamMessageComposerThemeData? globalTheme, + StreamMessageComposerThemeData? localTheme, +}) async { + late BuildContext capturedContext; + + final leaf = Builder( + builder: (context) { + capturedContext = context; + return const SizedBox.shrink(); + }, + ); + + await tester.pumpWidget( + MaterialApp( + builder: (context, child) => StreamChat( + client: MockClient(), + themeData: StreamChatThemeData(messageComposerTheme: globalTheme), + child: child, + ), + home: switch (localTheme) { + final localTheme? => StreamMessageComposerTheme(data: localTheme, child: leaf), + _ => leaf, + }, + ), + ); + + return capturedContext; +} From 2fc96e37308958a16262724ee52aa2e276ba89ab Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 29 Jul 2026 14:21:08 +0200 Subject: [PATCH 46/87] Add fixes for channelpage and deleted message --- packages/stream_chat_flutter/CHANGELOG.md | 1 + .../lib/src/channel/channel_page.dart | 11 +++- .../components/stream_message_deleted.dart | 6 ++- .../test/src/channel/channel_page_test.dart | 53 ++++++++++++++++--- .../test/src/channel/thread_page_test.dart | 19 +------ 5 files changed, 65 insertions(+), 25 deletions(-) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 1dfe7f591a..b43db2e84c 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -17,6 +17,7 @@ - Fixed the default `StreamChannel` loading and error states not being themed or localized; `StreamChat` now installs themed, connection-aware defaults, overridable per `StreamChannel` or via `DefaultStreamChannelBuilders`. - Fixed the default list/scroll-view error states (channel, message, member, user, thread, poll-vote, reaction, search, and photo) showing raw or fixed errors; they are now connection-aware (no internet / slow connection), falling back to each view's specific error text. - Fixed `StreamTypingIndicator` briefly showing typing users from a different context (main channel vs. thread) on its first frame. +- Fixed the "Message deleted" bubble overflowing its maximum width when the localized label is long; the label now wraps instead. ## 10.2.0 diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index d05ffe1912..e0b3fcb52e 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -18,7 +18,10 @@ class StreamChannelPage extends StatefulWidget { /// Initial scroll alignment for the message list. final double? initialAlignment; - /// Callback for when the back button is pressed. + /// Called when the header's back button is pressed. + /// + /// Replaces the default action, which pops the current route. When null the + /// default is kept. final VoidCallback? onBackPressed; /// Called when the default channel-avatar trailing is pressed. @@ -63,6 +66,12 @@ class _StreamChannelPageState extends State { @override Widget build(BuildContext context) { final appBar = StreamChannelHeader( + // Leaving this null keeps the header's own default back button, which + // pops the route. + leading: switch (widget.onBackPressed) { + final onBackPressed? => StreamBackButton(onPressed: onBackPressed, showUnreadCount: true), + _ => null, + }, onChannelAvatarPressed: (channel) => widget.onChannelAvatarPressed?.call(context, channel), ); diff --git a/packages/stream_chat_flutter/lib/src/message_widget/components/stream_message_deleted.dart b/packages/stream_chat_flutter/lib/src/message_widget/components/stream_message_deleted.dart index 3e6a7bdeb0..ae0a3316f3 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/components/stream_message_deleted.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/components/stream_message_deleted.dart @@ -29,7 +29,11 @@ class StreamMessageDeleted extends StatelessWidget { mainAxisSize: .min, children: [ Icon(icons.noSign, size: 16), - core.StreamMessageText(padding: .zero, context.translations.messageDeletedLabel), + // Flexible so a long translation wraps inside the bubble instead of + // overflowing it — the bubble has a fixed maximum width. + Flexible( + child: core.StreamMessageText(padding: .zero, context.translations.messageDeletedLabel), + ), ], ), ); diff --git a/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart b/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart index 86be8d77e7..e317fb5d78 100644 --- a/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart @@ -36,6 +36,34 @@ void main() { expect(pressedChannel, isNotNull); }); + testWidgets('tapping back invokes onBackPressed', (tester) async { + var backPressed = 0; + await _pumpChannelPage(tester, onBackPressed: () => backPressed++); + + await tester.tap(find.byType(StreamBackButton)); + await tester.pumpAndSettle(); + + expect(backPressed, 1); + }); + + testWidgets('onBackPressed replaces the default pop', (tester) async { + await _pumpChannelPage(tester, onBackPressed: () {}, pushOntoARoute: true); + + await tester.tap(find.byType(StreamBackButton)); + await tester.pumpAndSettle(); + + expect(find.byType(StreamChannelPage), findsOneWidget); + }); + + testWidgets('pops the route when onBackPressed is not set', (tester) async { + await _pumpChannelPage(tester, pushOntoARoute: true); + + await tester.tap(find.byType(StreamBackButton)); + await tester.pumpAndSettle(); + + expect(find.byType(StreamChannelPage), findsNothing); + }); + testWidgets('replying to a message quotes it in the composer', (tester) async { final message = Message(id: 'message-id', text: 'Hello world!'); @@ -108,7 +136,8 @@ void main() { await _pumpChannelPage(tester); final controller = _composerController(tester); - await tester.pumpWidget(const MaterialApp(home: SizedBox.shrink())); + // A bare widget, so the whole app subtree unmounts. + await tester.pumpWidget(const SizedBox.shrink()); // A disposed ChangeNotifier throws when listened to again. expect(() => controller.addListener(() {}), throwsFlutterError); @@ -156,6 +185,8 @@ Future _pumpChannelPage( WidgetTester tester, { StreamAppStyle appStyle = StreamAppStyle.regular, void Function(BuildContext context, Channel channel)? onChannelAvatarPressed, + VoidCallback? onBackPressed, + bool pushOntoARoute = false, }) async { final originalRecordPlatform = RecordPlatform.instance; RecordPlatform.instance = FakeRecordPlatform(); @@ -198,16 +229,26 @@ Future _pumpChannelPage( when(() => channelState.currentUserRead).thenReturn(null); when(() => channelState.currentUserReadStream).thenAnswer((_) => const Stream.empty()); + final page = StreamChannelPage( + onChannelAvatarPressed: onChannelAvatarPressed, + onBackPressed: onBackPressed, + ); + await tester.pumpWidget( MaterialApp( theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), - home: StreamChat( + // Chat context lives above the navigator so it survives a pop. + builder: (context, child) => StreamChat( client: client, - child: StreamChannel( - channel: channel, - child: StreamChannelPage(onChannelAvatarPressed: onChannelAvatarPressed), - ), + child: StreamChannel(channel: channel, child: child!), ), + // '/channel' seeds the stack with '/' underneath it, giving the back + // button something to pop to. + initialRoute: pushOntoARoute ? '/channel' : '/', + routes: { + '/': (_) => pushOntoARoute ? const Scaffold(body: SizedBox.shrink()) : page, + '/channel': (_) => page, + }, ), ); diff --git a/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart b/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart index dd85333036..381e737919 100644 --- a/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart @@ -37,7 +37,6 @@ void main() { final parent = Message(id: 'parent-id', text: 'Hello world!', type: 'deleted'); await _pumpThreadPage(tester, parent: parent); - _ignoreDeletedBubbleOverflow(tester); expect(find.byType(StreamMessageComposer), findsNothing); }); @@ -46,7 +45,6 @@ void main() { final parent = Message(id: 'parent-id', text: 'Hello world!', type: 'deleted'); await _pumpThreadPage(tester, parent: parent); - _ignoreDeletedBubbleOverflow(tester); expect(find.byType(StreamMessageListView), findsOneWidget); }); @@ -124,7 +122,8 @@ void main() { await _pumpThreadPage(tester); final controller = _composerController(tester); - await tester.pumpWidget(const MaterialApp(home: SizedBox.shrink())); + // A bare widget, so the whole app subtree unmounts. + await tester.pumpWidget(const SizedBox.shrink()); // A disposed ChangeNotifier throws when listened to again. expect(() => controller.addListener(() {}), throwsFlutterError); @@ -135,20 +134,6 @@ StreamMessageListView _messageListView(WidgetTester tester) { return tester.widget(find.byType(StreamMessageListView)); } -/// Drains the overflow [FlutterError] the deleted-message bubble reports. -/// -/// `StreamMessageDeleted` lays out its icon and label in a fixed-width bubble. -/// The test font is squarer — and so wider — than the font that ships with the -/// app, which pushes the label a few pixels past the bubble. It fits in a real -/// app, so it is not what these tests are about. -void _ignoreDeletedBubbleOverflow(WidgetTester tester) { - final exception = tester.takeException(); - if (exception == null) return; - - expect(exception, isFlutterError); - expect('$exception', contains('overflowed')); -} - /// The controller the page created and handed to its composer. StreamMessageComposerController _composerController(WidgetTester tester) { return tester.widget(find.byType(StreamChatMessageInput)).controller!; From a9ad64c5cdb45f544d75efc2b1b77c28fe42e34d Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 29 Jul 2026 14:54:36 +0200 Subject: [PATCH 47/87] Add snapshot tests for deleted message --- packages/stream_chat_flutter/CHANGELOG.md | 24 +-- .../stream_message_deleted_test.dart | 163 ++++++++++++++++++ 2 files changed, 176 insertions(+), 11 deletions(-) create mode 100644 packages/stream_chat_flutter/test/src/message_widget/stream_message_deleted_test.dart diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index b43db2e84c..bc49143f7d 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,7 +1,20 @@ ## Upcoming +⚠️ Changed + +- `StreamPhotoGallery` now defaults its `padding` to the bottom safe-area inset instead of no padding, so the last row clears the home indicator. Pass an explicit `padding` to opt out. + ✅ Added +- Added `StreamChannelPage` — a ready-to-use channel page widget that wires up `StreamChannelHeader`, `StreamMessageListView`, and `StreamMessageComposer` with floating or docked layout driven by the active app style. +- Added `StreamThreadPage` — a ready-to-use thread page widget with the same floating/docked layout support. +- Added `ComposerLocation` and `MessageComposerProps.location` — explicitly controls whether `StreamMessageComposer` renders `floating` or `docked`. When null it falls back to `StreamMessageComposerThemeData.location`, and then to the ambient `StreamAppStyle`. +- Added `StreamMessageComposerTheme` and `StreamMessageComposerThemeData` — a component theme for the composer, also available globally as `StreamChatThemeData.messageComposerTheme`. +- Added `StreamMessageListView.config` — accepts an explicit `StreamMessageListViewConfiguration` per widget; falls back to `StreamChatConfigurationData.messageListViewConfiguration` from the nearest ancestor when omitted. +- Added `StreamMessageListView.topPadding` and `bottomPadding` — padding applied to the scroll view's top and bottom edges, used by floating app bar / composer layouts to keep messages visible without an extra `setState`. +- Added `appBarBehavior` parameter to `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamBackButton`, controlling floating vs pinned app bar appearance (avatar shadow, back-button style). Falls back to `StreamAppBarTheme`, and then to the ambient `StreamAppStyle`, when null. +- Added `messageListViewConfiguration` field to `StreamChatConfigurationData`, allowing a global `StreamMessageListViewConfiguration` default for all `StreamMessageListView` widgets. Pass it via `StreamChat.configData` to configure behaviors like `swipeToReply` and `highlightInitialMessage` app-wide without wiring them per-page. +- Re-exported `StreamScaffold`, `StreamScaffoldInsets`, `StreamBottomNavBar`, `StreamBottomNavBarItem`, `StreamAppStyle`, `StreamAppBarBehavior`, `StreamBottomAppBarBehavior`, and `streamFloatingFadeLinearGradient` from `stream_core_flutter` via `package:stream_chat_flutter/stream_chat_flutter.dart`. - Added `StreamMessageListViewConfiguration.autoScrollPolicy` to control whether and how `StreamMessageListView` scrolls to the newest message when a new message arrives. Use `StreamAutoScrollPolicy.disabled` to fully control scrolling yourself. - Added `onReactionSelected` to `StreamMessageReactionPicker`, a context-aware callback that provides the `BuildContext` for navigation. - Added an `errorSubtitle` to `StreamScrollViewErrorWidget`, which now falls back to the design's generic error copy (title, description, and a "Try Again" retry label) when values aren't provided. @@ -58,15 +71,6 @@ ✅ Added -- Added `StreamChannelPage` — a ready-to-use channel page widget that wires up `StreamChannelHeader`, `StreamMessageListView`, and `StreamMessageComposer` with floating or docked layout driven by the active app style. -- Added `StreamThreadPage` — a ready-to-use thread page widget with the same floating/docked layout support. -- Added `MessageComposerProps.composerLocation` — explicitly controls whether `StreamMessageComposer` renders in `floating` or `docked` mode; falls back to the theme's `appStyle.composerLocation` when null. `copyWith` now distinguishes "not passed" from "explicitly set to null" via a sentinel so callers can clear an override back to the theme default. -- Added `StreamMessageListView.config` — accepts an explicit `StreamMessageListViewConfiguration` per widget; falls back to `StreamChatConfigurationData.messageListViewConfiguration` from the nearest ancestor when omitted. -- Added `StreamMessageListView.topPadding` and `bottomPadding` — padding applied to the scroll view's top and bottom edges, used by floating app bar / composer layouts to keep messages visible without an extra `setState`. -- Added `appBarBehavior` parameter to `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamBackButton`, controlling floating vs pinned app bar appearance (avatar shadow, back-button style). Falls back to `appStyle.appBarBehavior` from the theme when null. -- Added `messageListViewConfiguration` field to `StreamChatConfigurationData`, allowing a global `StreamMessageListViewConfiguration` default for all `StreamMessageListView` widgets. Pass it via `StreamChat.configData` to configure behaviors like `swipeToReply` and `highlightInitialMessage` app-wide without wiring them per-page. -- `StreamMessageComposer` now surfaces the hold-to-record hint through `StreamSnackbar` anchored above the composer, and `StreamChat` provides an app-wide `StreamSnackbarScope` fallback. -- Re-exported `StreamScaffold`, `StreamScaffoldInsets`, `StreamBottomNavBar`, `StreamBottomNavBarItem`, `StreamAppStyle`, `AppBarBehavior`, `BottomBarBehavior`, `ComposerLocation`, and `streamFloatingFade` from `stream_core_flutter` via `package:stream_chat_flutter/stream_chat_flutter.dart`. - Added support for `@channel`, `@here`, role, and user-group mentions — parsed on incoming messages, rendered as styled tappable spans in message text, and selectable from the composer's `@` autocomplete. - Added a single `mentionItemBuilder` on `StreamMessageComposer` and `StreamMentionAutocompleteOptions` that receives `StreamMentionItemProps` and covers every mention kind. Customise globally via `streamChatComponentBuilders(mentionItem: ...)` or per-instance via the new constructor parameter. Defaults are rendered by `DefaultStreamMentionItem`. Also added `onMention*Tap` callbacks on `StreamMentionAutocompleteOptions`. - Added `StreamMessageListView.onMentionTap` and `StreamMessageItem.onMentionTap` — receives a typed `StreamMention` (`StreamUserMention`, `StreamChannelMention`, `StreamHereMention`, `StreamRoleMention`, or `StreamGroupMention`). @@ -88,8 +92,6 @@ 🐞 Fixed -- Fixed `StreamChannelPage` leaking its `StreamMessageComposerController` — the state now disposes it in `dispose()`, matching the pattern already used by `StreamThreadPage`. -- Fixed `StreamPhotoGallery` default padding having a redundant explicit `top: 0` (no visual change). - `StreamMessageItem.onUserAvatarTap` now fires when the author avatar is tapped. ([#2741](https://github.com/GetStream/stream-chat-flutter/issues/2741)) - Added `MessageComposerProps.copyWith` so factory overrides can tweak individual props (e.g. `useSystemAttachmentPicker`) without re-specifying every field. ([#2742](https://github.com/GetStream/stream-chat-flutter/issues/2742)) - `StreamMessageContent` no longer re-runs `setState` on every inherited-widget change when the measured attachment width has not changed. ([#2761](https://github.com/GetStream/stream-chat-flutter/issues/2761)) diff --git a/packages/stream_chat_flutter/test/src/message_widget/stream_message_deleted_test.dart b/packages/stream_chat_flutter/test/src/message_widget/stream_message_deleted_test.dart new file mode 100644 index 0000000000..8fa37a5b75 --- /dev/null +++ b/packages/stream_chat_flutter/test/src/message_widget/stream_message_deleted_test.dart @@ -0,0 +1,163 @@ +import 'package:alchemist/alchemist.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat_flutter/src/message_widget/components/stream_message_deleted.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +void main() { + // The bubble is capped at the message item's max width, so the label has to + // wrap rather than run past it. Guards the `Flexible` around the label. + testWidgets('lays out a long label without overflowing', (tester) async { + await tester.pumpWidget(_wrapWithApp(_deletedBubble(_longLabel))); + + expect(tester.takeException(), isNull); + }); + + testWidgets('lays out the default label without overflowing', (tester) async { + await tester.pumpWidget(_wrapWithApp(_deletedBubble(_shortLabel))); + + expect(tester.takeException(), isNull); + }); + + testWidgets('wraps a long label onto more than one line', (tester) async { + await tester.pumpWidget(_wrapWithApp(_deletedBubble(_shortLabel))); + final singleLine = tester.getSize(find.byType(StreamMessageDeleted)).height; + + await tester.pumpWidget(_wrapWithApp(_deletedBubble(_longLabel))); + final wrapped = tester.getSize(find.byType(StreamMessageDeleted)).height; + + expect(wrapped, greaterThan(singleLine)); + }); + + testWidgets('keeps a long label within the bubble width', (tester) async { + await tester.pumpWidget(_wrapWithApp(_deletedBubble(_longLabel))); + + final width = tester.getSize(find.byType(StreamMessageDeleted)).width; + + expect(width, lessThanOrEqualTo(_bubbleMaxWidth)); + }); + + for (final brightness in Brightness.values) { + goldenTest( + '[${brightness.name}] -> StreamMessageDeleted looks fine', + fileName: 'stream_message_deleted_${brightness.name}', + constraints: const BoxConstraints.tightFor(width: 460, height: 420), + // The app is themed once around the whole group; the scenarios below + // vary only the label. + builder: () => _wrapWithApp( + brightness: brightness, + GoldenTestGroup( + columns: 1, + children: [ + GoldenTestScenario( + name: 'very short label — bubble hugs it', + child: _deletedBubble(_tinyLabel, maxWidth: _goldenBubbleMaxWidth), + ), + GoldenTestScenario( + name: 'short label', + child: _deletedBubble(_shortLabel, maxWidth: _goldenBubbleMaxWidth), + ), + GoldenTestScenario( + name: 'longest shipped translation', + child: _deletedBubble(_longestShippedLabel, maxWidth: _goldenBubbleMaxWidth), + ), + GoldenTestScenario( + name: 'long label wraps inside the bubble', + child: _deletedBubble(_longLabel, maxWidth: _goldenBubbleMaxWidth), + ), + ], + ), + ), + ); + } +} + +/// Mirrors the default `StreamMessageItemProps.maxWidth`, which is what caps +/// the bubble in a real message list. Used by the layout tests, so they pin +/// the real geometry. +const _bubbleMaxWidth = 272.0; + +/// The cap used by the goldens instead of [_bubbleMaxWidth]. +/// +/// Every glyph in the test font is a square of the font size, so text measures +/// far wider here than in a real app — at [_bubbleMaxWidth] even the English +/// label would wrap, which is not what users see. Widening the cap absorbs that +/// difference so the goldens show the line breaks a real font produces. +const _goldenBubbleMaxWidth = 350.0; + +/// Short enough that the bubble hugs it, showing it is not forced to full width. +const _tinyLabel = 'Del'; + +/// The shipped English label. +const _shortLabel = 'Message deleted'; + +/// The longest `messageDeletedLabel` in `stream_chat_localizations` that uses +/// Latin script, so the golden renders it without needing extra fonts. +const _longestShippedLabel = 'Messaggio eliminato'; + +/// Longer than any shipped translation, to show the wrapping behaviour. +const _longLabel = 'This message was deleted by a moderator'; + +/// A [StreamMessageDeleted] reading [label], capped at [maxWidth]. +Widget _deletedBubble(String label, {double maxWidth = _bubbleMaxWidth}) { + return Builder( + builder: (context) => Localizations.override( + context: context, + delegates: [_FixedLabelDelegate(label)], + child: Align( + alignment: Alignment.centerLeft, + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: maxWidth), + child: const StreamMessageDeleted(), + ), + ), + ), + ); +} + +Widget _wrapWithApp(Widget child, {Brightness brightness = Brightness.light}) { + return MaterialApp( + debugShowCheckedModeBanner: false, + theme: ThemeData( + brightness: brightness, + extensions: [StreamTheme(brightness: brightness)], + ), + home: Scaffold( + backgroundColor: brightness == Brightness.dark ? const Color(0xFF101418) : const Color(0xFFF7F7F8), + body: Center(child: child), + ), + ); +} + +/// Serves a [StreamChatLocalizations] whose `messageDeletedLabel` is fixed. +class _FixedLabelDelegate extends LocalizationsDelegate { + const _FixedLabelDelegate(this.label); + + final String label; + + @override + bool isSupported(Locale locale) => true; + + @override + SynchronousFuture load(Locale locale) { + return SynchronousFuture(_FixedLabelTranslations(label)); + } + + @override + bool shouldReload(_FixedLabelDelegate old) => old.label != label; +} + +/// A [StreamChatLocalizations] that only answers `messageDeletedLabel`. +/// +/// [StreamMessageDeleted] reads nothing else, so anything else reaching this +/// stub is a mistake worth failing on rather than quietly defaulting. +class _FixedLabelTranslations implements StreamChatLocalizations { + const _FixedLabelTranslations(this.messageDeletedLabel); + + @override + final String messageDeletedLabel; + + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} From f7ae533d670518001f97b7e2ccf56402906aca1d Mon Sep 17 00:00:00 2001 From: renefloor <15101411+renefloor@users.noreply.github.com> Date: Wed, 29 Jul 2026 13:03:50 +0000 Subject: [PATCH 48/87] chore: Update Goldens --- .../theming/goldens/macos/theming_red.png | Bin 57400 -> 57051 bytes .../ci/stream_message_deleted_dark.png | Bin 0 -> 4536 bytes .../ci/stream_message_deleted_light.png | Bin 0 -> 3908 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/stream_chat_flutter/test/src/message_widget/goldens/ci/stream_message_deleted_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/goldens/ci/stream_message_deleted_light.png diff --git a/docs/docs_screenshots/test/theming/goldens/macos/theming_red.png b/docs/docs_screenshots/test/theming/goldens/macos/theming_red.png index 23a39523774d822b90a1b30e3be2a774cb014a7c..30d11ee982aab45695d963e9f80ac8081401ca5e 100644 GIT binary patch literal 57051 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 literal 57400 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 z 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 diff --git a/packages/stream_chat_flutter/test/src/message_widget/goldens/ci/stream_message_deleted_dark.png b/packages/stream_chat_flutter/test/src/message_widget/goldens/ci/stream_message_deleted_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..e59943949c9160ee22974f7191843811789b346c GIT binary patch literal 4536 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 TgJ*f*H5fQ`!riIf5t;iBf&*Yw literal 0 HcmV?d00001 From a54b59e18ac14868a381421268bfc38b729bb71b Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Wed, 29 Jul 2026 16:20:00 +0200 Subject: [PATCH 49/87] Add floating to edit button group page --- sample_app/lib/pages/group_info_screen.dart | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sample_app/lib/pages/group_info_screen.dart b/sample_app/lib/pages/group_info_screen.dart index 0d1ed66cea..abd08a11d8 100644 --- a/sample_app/lib/pages/group_info_screen.dart +++ b/sample_app/lib/pages/group_info_screen.dart @@ -24,6 +24,16 @@ class GroupInfoScreen extends StatelessWidget { final colorScheme = context.streamColorScheme; final channel = StreamChannel.of(context).channel; + // Mirrors how [StreamAppBar] resolves its own behavior — per-instance + // style, then the ambient app bar theme, then the global app style — so + // the trailing button floats exactly when the bar it sits in does. + final appStyle = context.streamTheme.appStyle; + final isFloatingStyle = switch (context.streamAppBarTheme.style?.behavior) { + .floating => true, + .regular => false, + _ => appStyle.isFloating, + }; + return StreamScaffold( backgroundColor: colorScheme.backgroundApp, appBar: StreamAppBar( @@ -32,7 +42,7 @@ class GroupInfoScreen extends StatelessWidget { true => StreamButton( type: .outline, style: .secondary, - size: .small, + isFloating: isFloatingStyle, onPressed: () => showEditGroupSheet(context, channel), child: const Text('Edit'), ), From 0dd9addc2e3999d71bade6094d608074cb051805 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 09:31:43 +0200 Subject: [PATCH 50/87] use elevation for composer --- .../avatar/stream_channel_avatar.dart | 6 +- .../components/avatar/stream_user_avatar.dart | 6 +- .../avatar/stream_user_avatar_group.dart | 6 +- .../message_composer_input.dart | 55 ++++++++++--------- 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart index 655aed8401..d1bb2dcd65 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart @@ -69,9 +69,9 @@ class StreamChannelAvatar extends StatelessWidget { /// Whether to show a drop shadow around the avatar. /// - /// Defaults to false. The shadow style is determined by - /// [StreamAvatarThemeData.boxShadow], falling back to - /// [StreamBoxShadow.elevation3]. + /// Defaults to false. The shadow depth is determined by + /// [StreamAvatarThemeData.floatingElevation], falling back to + /// [StreamElevation.level2]. final bool? isFloating; /// Screen-reader label for the avatar. diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart index 1f164dc843..48eec8eee2 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart @@ -88,9 +88,9 @@ class StreamUserAvatar extends StatelessWidget { /// Whether to show a drop shadow around the avatar. /// - /// Defaults to false. The shadow style is determined by - /// [StreamAvatarThemeData.boxShadow], falling back to - /// [StreamBoxShadow.elevation3]. + /// Defaults to false. The shadow depth is determined by + /// [StreamAvatarThemeData.floatingElevation], falling back to + /// [StreamElevation.level2]. final bool? isFloating; /// The size of the avatar. diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart index dd2b3c92cd..2be3047f3d 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart @@ -69,9 +69,9 @@ class StreamUserAvatarGroup extends StatelessWidget { /// Whether to show a drop shadow around the avatar group. /// - /// Defaults to false. The shadow style is determined by - /// [StreamAvatarThemeData.boxShadow], falling back to - /// [StreamBoxShadow.elevation3]. + /// Defaults to false. The shadow depth is determined by + /// [StreamAvatarThemeData.floatingElevation], falling back to + /// [StreamElevation.level2]. final bool? isFloating; /// Screen-reader label for the avatar group. diff --git a/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart b/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart index a84afc98bb..6b864cc456 100644 --- a/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart +++ b/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart @@ -1,4 +1,4 @@ -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/src/components/message_composer/message_composer_input_center.dart'; import 'package:stream_chat_flutter/src/components/message_composer/message_composer_input_header.dart'; import 'package:stream_chat_flutter/src/components/message_composer/message_composer_input_leading.dart'; @@ -50,34 +50,39 @@ class DefaultStreamMessageComposerInput extends StatelessWidget { ? context.streamColorScheme.borderDisabled : context.streamColorScheme.borderDefault; - return Container( - clipBehavior: Clip.antiAlias, - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.all(context.streamRadius.xxxl), + final borderRadius = BorderRadius.all(context.streamRadius.xxxl); + + // Material clips its children via PhysicalShape, so the border is drawn + // outside the Material to keep it from being clipped away. + return DecoratedBox( + position: DecorationPosition.foreground, + decoration: BoxDecoration( + borderRadius: borderRadius, border: Border.all(color: borderColor), ), - decoration: BoxDecoration( + child: Material( + clipBehavior: Clip.antiAlias, color: context.streamColorScheme.backgroundElevation1, - borderRadius: BorderRadius.all(context.streamRadius.xxxl), - boxShadow: isFloating ? context.streamBoxShadow.elevation3 : null, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - StreamMessageComposerInputHeader(props: props), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - StreamMessageComposerInputLeading(props: props), - Expanded( - child: StreamMessageComposerInputCenter( - props: MessageComposerInputCenterProps.from(props), + borderRadius: borderRadius, + elevation: isFloating ? StreamElevation.level3 : StreamElevation.none, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + StreamMessageComposerInputHeader(props: props), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + StreamMessageComposerInputLeading(props: props), + Expanded( + child: StreamMessageComposerInputCenter( + props: MessageComposerInputCenterProps.from(props), + ), ), - ), - StreamMessageComposerInputTrailing(props: props), - ], - ), - ], + StreamMessageComposerInputTrailing(props: props), + ], + ), + ], + ), ), ); } From d694d882c587e9a7f102a20d743b4e1928b6a2e7 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 09:48:17 +0200 Subject: [PATCH 51/87] Add composer background animation --- .../message_input/stream_message_composer.dart | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 23110fb800..c0c26aa8b6 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -825,6 +825,7 @@ class DefaultStreamMessageComposerState extends State composerBody, .docked => DecoratedBox( - decoration: BoxDecoration(color: context.streamColorScheme.backgroundElevation1), + decoration: BoxDecoration(color: colorScheme.backgroundElevation1), child: composerBody, ), }, From 775efe06f5562904496cb30cb488d0d1e737f21b Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 10:25:57 +0200 Subject: [PATCH 52/87] update core dependency --- docs/docs_screenshots/pubspec.yaml | 2 +- melos.yaml | 2 +- packages/stream_chat_flutter/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index 66d18ded4d..4781de3142 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter.git - ref: 3d3f22057a89679454e819b4ca8ff55fe800abd9 + ref: 6d217ae17297525629b6ef8c606edfbdf5394f01 path: packages/stream_core_flutter dev_dependencies: diff --git a/melos.yaml b/melos.yaml index cd8f42c760..1b9e8ae379 100644 --- a/melos.yaml +++ b/melos.yaml @@ -107,7 +107,7 @@ command: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter.git - ref: 3d3f22057a89679454e819b4ca8ff55fe800abd9 + ref: 6d217ae17297525629b6ef8c606edfbdf5394f01 path: packages/stream_core_flutter stream_thumbnail: ^0.1.0 synchronized: ^3.4.0 diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index f2b582d727..33ec92a182 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -66,7 +66,7 @@ dependencies: # ignore: invalid_dependency git: url: https://github.com/GetStream/stream-core-flutter.git - ref: 3d3f22057a89679454e819b4ca8ff55fe800abd9 + ref: 6d217ae17297525629b6ef8c606edfbdf5394f01 path: packages/stream_core_flutter stream_thumbnail: ^0.1.0 svg_icon_widget: ^0.0.1 From 69df35abfef3811ac0def7c1780c812dd95505a3 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 14:04:30 +0200 Subject: [PATCH 53/87] update core dependency --- docs/docs_screenshots/pubspec.yaml | 2 +- melos.yaml | 2 +- packages/stream_chat_flutter/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index 4781de3142..e0b7d0e3d1 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter.git - ref: 6d217ae17297525629b6ef8c606edfbdf5394f01 + ref: 8cd63c02bf7dba9bfec79fb795b3ba93cdc61664 path: packages/stream_core_flutter dev_dependencies: diff --git a/melos.yaml b/melos.yaml index 1b9e8ae379..cb92f3bdf9 100644 --- a/melos.yaml +++ b/melos.yaml @@ -107,7 +107,7 @@ command: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter.git - ref: 6d217ae17297525629b6ef8c606edfbdf5394f01 + ref: 8cd63c02bf7dba9bfec79fb795b3ba93cdc61664 path: packages/stream_core_flutter stream_thumbnail: ^0.1.0 synchronized: ^3.4.0 diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 33ec92a182..8352e09ce5 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -66,7 +66,7 @@ dependencies: # ignore: invalid_dependency git: url: https://github.com/GetStream/stream-core-flutter.git - ref: 6d217ae17297525629b6ef8c606edfbdf5394f01 + ref: 8cd63c02bf7dba9bfec79fb795b3ba93cdc61664 path: packages/stream_core_flutter stream_thumbnail: ^0.1.0 svg_icon_widget: ^0.0.1 From d310daa3dfdce969900c204ee5617bf0dbef843e Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 15:09:11 +0200 Subject: [PATCH 54/87] fix change in elevation logic --- .../components/message_composer/message_composer_input.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart b/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart index 6b864cc456..75f9fb005d 100644 --- a/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart +++ b/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart @@ -51,6 +51,7 @@ class DefaultStreamMessageComposerInput extends StatelessWidget { : context.streamColorScheme.borderDefault; final borderRadius = BorderRadius.all(context.streamRadius.xxxl); + final elevation = context.streamElevation; // Material clips its children via PhysicalShape, so the border is drawn // outside the Material to keep it from being clipped away. @@ -64,7 +65,7 @@ class DefaultStreamMessageComposerInput extends StatelessWidget { clipBehavior: Clip.antiAlias, color: context.streamColorScheme.backgroundElevation1, borderRadius: borderRadius, - elevation: isFloating ? StreamElevation.level3 : StreamElevation.none, + elevation: isFloating ? elevation.level3 : elevation.none, child: Column( mainAxisSize: MainAxisSize.min, children: [ From 95cf893bdc0bf24d7a5fb531da0a3d1c27b0e61b Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 15:58:09 +0200 Subject: [PATCH 55/87] fix(sample): restore location sharing in the channel page Moving the channel page into the SDK dropped the sample app's location picker: the composer wiring lived in sample_app/lib/pages/channel_page.dart, which was deleted, and StreamChannelPage owns its composer without exposing any parameters for it. Received locations still rendered via the attachment builder, but nothing could send one -- the "Location Sharing" config toggle was half dead. Register the picker as a `messageComposer` component builder instead of passing it to a composer directly. StreamMessageComposer already resolves that builder from the component factory, so it reaches the composers inside StreamChannelPage and StreamThreadPage without widening their API. Tolerates a missing StreamChannel ancestor, since the factory is global and a composer need not sit inside a channel. Co-Authored-By: Claude Opus 5 --- sample_app/lib/app.dart | 81 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/sample_app/lib/app.dart b/sample_app/lib/app.dart index 4484f351af..f30d6ab80d 100644 --- a/sample_app/lib/app.dart +++ b/sample_app/lib/app.dart @@ -17,6 +17,8 @@ import 'package:sample_app/routes/routes.dart'; import 'package:sample_app/widgets/custom_message_actions.dart'; import 'package:sample_app/widgets/location/location_attachment.dart'; import 'package:sample_app/widgets/location/location_detail_dialog.dart'; +import 'package:sample_app/widgets/location/location_picker_dialog.dart'; +import 'package:sample_app/widgets/location/location_picker_option.dart'; import 'package:sample_app/widgets/video_player.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_localizations/stream_chat_localizations.dart'; @@ -227,6 +229,7 @@ class _StreamChatSampleAppState extends State componentBuilders: StreamComponentBuilders( extensions: streamChatComponentBuilders( messageItem: customMessageItemBuilder, + messageComposer: _locationAwareMessageComposer, videoPlayer: (context, props) => SampleAppVideoPlayer(props: props), ), ), @@ -278,6 +281,84 @@ class _StreamChatSampleAppState extends State } } +/// Builds the composer, adding the location picker when location sharing is +/// available on the surrounding channel. +/// +/// Registered as the `messageComposer` component builder rather than passed to a +/// composer directly, because [StreamChannelPage] and [StreamThreadPage] own +/// their composers and expose no parameters for them. Going through the +/// component factory reaches them anyway. +Widget _locationAwareMessageComposer(BuildContext context, MessageComposerProps props) { + // Null when a composer is built outside a channel; the factory is global, so + // this builder must tolerate that rather than assume a channel ancestor. + final channel = StreamChannel.maybeOf(context)?.channel; + + final locationEnabled = + channel != null && + context.sampleAppConfig.enableLocationSharing && + channel.config?.sharedLocations == true && + channel.canShareLocation; + + if (!locationEnabled) return DefaultStreamMessageComposer(props: props); + + return DefaultStreamMessageComposer( + props: props.copyWith( + allowedAttachmentPickerTypes: [ + ...AttachmentPickerType.values, + const LocationPickerType(), + ], + onAttachmentPickerResult: (result) => _onCustomAttachmentPickerResult(channel, result), + attachmentPickerOptionsBuilder: (context, defaultOptions) => [ + ...defaultOptions, + TabbedAttachmentPickerOption( + key: 'location-picker', + icon: context.streamIcons.location, + supportedTypes: [const LocationPickerType()], + isEnabled: (value) { + if (value.isEmpty) return true; + return value.extraData['location'] != null; + }, + optionViewBuilder: (context, controller) => LocationPicker( + onLocationPicked: (locationResult) { + if (locationResult == null) return; + + controller.notifyCustomResult( + LocationPicked(location: locationResult), + ); + }, + ), + ), + ], + ), + ); +} + +bool _onCustomAttachmentPickerResult( + Channel channel, + StreamAttachmentPickerResult result, +) { + if (result is LocationPicked) { + _onShareLocationPicked(channel, result.location).ignore(); + return true; // Notify that the result was handled. + } + + return false; // Notify that the result was not handled. +} + +Future _onShareLocationPicked( + Channel channel, + LocationPickerResult result, +) async { + if (result.endSharingAt case final endSharingAt?) { + return channel.startLiveLocationSharing( + endSharingAt: endSharingAt, + location: result.coordinates, + ); + } + + return channel.sendStaticLocation(location: result.coordinates); +} + extension on SampleAppConfigData { /// Maps chat-relevant flags to a [StreamChatConfigurationData]. StreamChatConfigurationData toStreamChatConfigurationData() { From e240ac2e3b53e882e7c55384d28226590a1be8f6 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 15:59:34 +0200 Subject: [PATCH 56/87] docs(ui): document the channel/thread page extension points Both pages take four parameters, which reads as a closed surface. It isn't: the component factory reaches inside them, because the components resolve it themselves -- StreamMessageItem and StreamMessageComposer each look up their own builder. Combined with the new global messageListViewConfiguration, that covers the customization callers actually reach for. Document that, with an example, and name the two things that genuinely have no factory entry -- the list-level StreamMessageListViewBuilders slots and the headers' title/subtitle/actions -- so they read as known boundaries rather than oversights. Co-Authored-By: Claude Opus 5 --- .../lib/src/channel/channel_page.dart | 52 +++++++++++++++++++ .../lib/src/channel/thread_page.dart | 21 ++++++++ 2 files changed, 73 insertions(+) diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index e0b3fcb52e..b032422217 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -2,6 +2,58 @@ import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// A channel page with optional floating composer support. +/// +/// Wires up a [StreamChannelHeader], a [StreamMessageListView] and a +/// [StreamMessageComposer], laid out floating or docked according to the ambient +/// [StreamAppStyle]. Expects a [StreamChannel] ancestor. +/// +/// ## Customizing this page +/// +/// The constructor is deliberately small — most customization happens through +/// the component factory and the global configuration, both of which reach +/// inside this page because the components resolve them themselves. +/// +/// Swap out components with [streamChatComponentBuilders], passed to +/// [StreamChat.componentBuilders]: +/// +/// ```dart +/// StreamChat( +/// client: client, +/// componentBuilders: StreamComponentBuilders( +/// extensions: streamChatComponentBuilders( +/// // Applies to the messages this page's list renders. +/// messageItem: (context, props) => DefaultStreamMessageItem( +/// props: props.copyWith(maxWidth: 320), +/// ), +/// // Applies to this page's composer. +/// messageComposer: (context, props) => DefaultStreamMessageComposer( +/// props: props.copyWith(disableAttachments: true), +/// ), +/// ), +/// ), +/// child: child, +/// ) +/// ``` +/// +/// `messageItem`, `messageComposer`, `quotedMessage`, `mentionItem`, the +/// attachment builders, `mediaGallery` and `videoPlayer` all apply here. +/// +/// Change list behaviour — `swipeToReply`, `highlightInitialMessage`, +/// `autoScrollPolicy` and the rest — through +/// [StreamChatConfigurationData.messageListViewConfiguration] on +/// [StreamChat.configData]. +/// +/// Not reachable from here: the list-level slots on +/// [StreamMessageListViewBuilders] (`header`, `footer`, `dateDivider`, +/// `floatingDateDivider`, `threadSeparator`, `scrollToBottomButton`, `empty`, +/// `loading`, `error`) and [StreamChannelHeader]'s title, subtitle and actions. +/// Those have no component-factory entry, so customizing them means composing +/// [StreamMessageListView] and [StreamChannelHeader] directly instead of using +/// this page. +/// +/// See also: +/// +/// * [StreamThreadPage], the equivalent page for a single thread. class StreamChannelPage extends StatefulWidget { /// Creates a [StreamChannelPage]. const StreamChannelPage({ diff --git a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart index 00050d4d42..248ee92bd7 100644 --- a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart @@ -2,6 +2,27 @@ import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// A page that displays a thread of messages for a given parent message. +/// +/// Wires up a [StreamThreadHeader], a [StreamMessageListView] scoped to [parent] +/// and a [StreamMessageComposer] that addresses new messages to the thread, laid +/// out floating or docked according to the ambient [StreamAppStyle]. Expects a +/// [StreamChannel] ancestor. +/// +/// The composer is omitted when [parent] is deleted. +/// +/// ## Customizing this page +/// +/// As with [StreamChannelPage], the constructor is small because customization +/// happens through the component factory and the global configuration rather +/// than through parameters — see [StreamChannelPage] for the full rundown and an +/// example. In short: +/// +/// * Components (`messageItem`, `messageComposer`, attachments, …) — +/// [streamChatComponentBuilders] on [StreamChat.componentBuilders]. +/// * List behaviour — [StreamChatConfigurationData.messageListViewConfiguration] +/// on [StreamChat.configData]. +/// * Not reachable: [StreamMessageListViewBuilders] list-level slots and +/// [StreamThreadHeader]'s title and actions. class StreamThreadPage extends StatefulWidget { /// Creates a [StreamThreadPage]. const StreamThreadPage({ From 557b9ab169309b846b8f5861cce8950df2e83e07 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 16:00:01 +0200 Subject: [PATCH 57/87] docs(changelog): correct the appBarBehavior entry The entry claimed an `appBarBehavior` parameter was added to StreamChannelHeader and StreamChannelListHeader. Only StreamBackButton got one; the two headers read the behavior off their existing StreamAppBarStyle to decide the avatar drop shadow. Co-Authored-By: Claude Opus 5 --- packages/stream_chat_flutter/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 384a163ee3..97770b3c02 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -12,7 +12,7 @@ - Added `StreamMessageComposerTheme` and `StreamMessageComposerThemeData` — a component theme for the composer, also available globally as `StreamChatThemeData.messageComposerTheme`. - Added `StreamMessageListView.config` — accepts an explicit `StreamMessageListViewConfiguration` per widget; falls back to `StreamChatConfigurationData.messageListViewConfiguration` from the nearest ancestor when omitted. - Added `StreamMessageListView.topPadding` and `bottomPadding` — padding applied to the scroll view's top and bottom edges, used by floating app bar / composer layouts to keep messages visible without an extra `setState`. -- Added `appBarBehavior` parameter to `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamBackButton`, controlling floating vs pinned app bar appearance (avatar shadow, back-button style). Falls back to `StreamAppBarTheme`, and then to the ambient `StreamAppStyle`, when null. +- Added an `appBarBehavior` parameter to `StreamBackButton`, controlling floating vs pinned back-button appearance. Falls back to `StreamAppBarTheme`, and then to the ambient `StreamAppStyle`, when null. `StreamChannelHeader` and `StreamChannelListHeader` now resolve the same behavior from their existing `style` to decide whether the avatar gets a drop shadow, using the same fallback chain. - Added `messageListViewConfiguration` field to `StreamChatConfigurationData`, allowing a global `StreamMessageListViewConfiguration` default for all `StreamMessageListView` widgets. Pass it via `StreamChat.configData` to configure behaviors like `swipeToReply` and `highlightInitialMessage` app-wide without wiring them per-page. - Re-exported `StreamScaffold`, `StreamScaffoldInsets`, `StreamBottomNavBar`, `StreamBottomNavBarItem`, `StreamAppStyle`, `StreamAppBarBehavior`, `StreamBottomAppBarBehavior`, and `streamFloatingFadeLinearGradient` from `stream_core_flutter` via `package:stream_chat_flutter/stream_chat_flutter.dart`. - Added `StreamMessageListViewConfiguration.autoScrollPolicy` to control whether and how `StreamMessageListView` scrolls to the newest message when a new message arrives. Use `StreamAutoScrollPolicy.disabled` to fully control scrolling yourself. From 14ed0a6707df9a6c489553f76d6e0c47d4676af6 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 16:00:16 +0200 Subject: [PATCH 58/87] docs(changelog): note the thread scroll-to-bottom fix Threads previously gated the button on the parent channel's isUpToDate stream rather than the thread's own scroll position, so it could show while already at the newest reply. Behaviour change for callers who never set showScrollToBottom, so it belongs in the changelog. Co-Authored-By: Claude Opus 5 --- packages/stream_chat_flutter/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 97770b3c02..92957d0b0e 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -33,6 +33,7 @@ - Fixed the default list/scroll-view error states (channel, message, member, user, thread, poll-vote, reaction, search, and photo) showing raw or fixed errors; they are now connection-aware (no internet / slow connection), falling back to each view's specific error text. - Fixed `StreamTypingIndicator` briefly showing typing users from a different context (main channel vs. thread) on its first frame. - Fixed the "Message deleted" bubble overflowing its maximum width when the localized label is long; the label now wraps instead. +- Fixed the scroll-to-bottom button in thread views keying off the parent channel's up-to-date state instead of the thread's own scroll position, so it no longer appears while already at the newest reply. ## 10.2.0 From ad9e6a68c9227d1772117861ecf2a6a2cd52297b Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 16:04:31 +0200 Subject: [PATCH 59/87] fix(ui): resolve message list config on the build path Making `config` nullable moved its fallback onto an inherited-widget lookup, and `_config` was a getter, so `StreamChatConfiguration.of(context)` now ran from wherever the getter was read -- including the `_messageNewListener` stream callback. dependOnInheritedWidgetOfExactType asserts the element is active, so a message arriving while the list is deactivated (GlobalKey reparent, or racing the cancel in dispose) throws in debug. Reading widget.config, as before, had no such constraint. It also re-ran the lookup ~20x per build. Resolve into a field at the top of didChangeDependencies, and add didUpdateWidget for the case where `config` changes without dependencies changing. The didUpdateWidget test swaps the config via setState below StreamChat rather than a second pumpWidget: StreamChatConfigurationData has no `==`, so rebuilding StreamChat hands StreamChatConfiguration a fresh instance and notifies every dependent, which would re-resolve the config for the wrong reason and hide a missing didUpdateWidget. Verified the test fails with the line removed. Co-Authored-By: Claude Opus 5 --- .../message_list_view/message_list_view.dart | 28 +++- .../message_list_view_test.dart | 139 ++++++++++++++++++ 2 files changed, 162 insertions(+), 5 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart index 51bc73bf44..6cca7cfbe6 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart @@ -352,12 +352,19 @@ class _StreamMessageListViewState extends State { MessageListController get _messageListController => widget.messageListController ?? _defaultController; - /// Returns the effective [StreamMessageListViewConfiguration] for this list. + /// The effective [StreamMessageListViewConfiguration] for this list. /// - /// Uses [widget.config] when explicitly provided, otherwise falls back to - /// [StreamChatConfigurationData.messageListViewConfiguration] from the - /// nearest [StreamChatConfiguration] ancestor. - StreamMessageListViewConfiguration get _config => + /// [StreamMessageListView.config] when explicitly provided, otherwise + /// [StreamChatConfigurationData.messageListViewConfiguration] from the nearest + /// [StreamChatConfiguration] ancestor. + /// + /// Resolved into a field rather than read through a getter because the + /// fallback is an inherited-widget lookup, which asserts the element is active + /// and so must not run from a stream callback — `_messageNewListener` reads + /// this. + late StreamMessageListViewConfiguration _config; + + StreamMessageListViewConfiguration _resolveConfig() => widget.config ?? StreamChatConfiguration.of(context).messageListViewConfiguration; StreamSubscription? _messageNewListener; @@ -377,6 +384,9 @@ class _StreamMessageListViewState extends State { @override void didChangeDependencies() { super.didChangeDependencies(); + // Before anything else — the branches below read `_config`. + _config = _resolveConfig(); + final newStreamChannel = StreamChannel.of(context); if (newStreamChannel != streamChannel) { @@ -446,6 +456,14 @@ class _StreamMessageListViewState extends State { } } + @override + void didUpdateWidget(covariant StreamMessageListView oldWidget) { + super.didUpdateWidget(oldWidget); + // `config` can change without dependencies changing, so re-resolve here as + // well as in `didChangeDependencies`. + if (widget.config != oldWidget.config) _config = _resolveConfig(); + } + @override void dispose() { // Tear down anything that could write to [_unreadState] or diff --git a/packages/stream_chat_flutter/test/src/message_list_view/message_list_view_test.dart b/packages/stream_chat_flutter/test/src/message_list_view/message_list_view_test.dart index 9ba6bbacb6..35ceb47082 100644 --- a/packages/stream_chat_flutter/test/src/message_list_view/message_list_view_test.dart +++ b/packages/stream_chat_flutter/test/src/message_list_view/message_list_view_test.dart @@ -233,4 +233,143 @@ void main() { expect(find.byType(StreamButton), findsNothing); }); + + group('effective configuration', () { + // The scroll-to-bottom button is the observable: it renders as a + // StreamButton, and `showScrollToBottom` decides whether it exists at all. + // Scrolled away from the bottom so it would otherwise be visible. + Future pumpScrolledAwayList( + WidgetTester tester, { + StreamMessageListViewConfiguration? config, + StreamMessageListViewConfiguration? globalConfig, + }) async { + final messages = generateConversation(20, users: [OwnUser(id: 'ownid'), User(id: 'otherid')]); + when(() => channelClientState.messagesStream).thenAnswer((_) => Stream.value(messages)); + when(() => channelClientState.messages).thenReturn(messages); + + await tester.runAsync(() async { + await tester.pumpWidget( + MaterialApp( + home: DefaultAssetBundle( + bundle: rootBundle, + child: StreamChat( + client: client, + configData: switch (globalConfig) { + final globalConfig? => StreamChatConfigurationData(messageListViewConfiguration: globalConfig), + _ => null, + }, + child: StreamChannel( + channel: channel, + child: StreamMessageListView( + initialScrollIndex: 7, + config: config, + ), + ), + ), + ), + ), + ); + await tester.pumpAndSettle(); + }); + } + + testWidgets('falls back to the global configuration when config is null', (tester) async { + await pumpScrolledAwayList( + tester, + globalConfig: const StreamMessageListViewConfiguration(showScrollToBottom: false), + ); + + expect(find.byType(StreamButton), findsNothing); + }); + + testWidgets('prefers an explicit config over the global one', (tester) async { + await pumpScrolledAwayList( + tester, + globalConfig: const StreamMessageListViewConfiguration(showScrollToBottom: false), + config: const StreamMessageListViewConfiguration(), + ); + + expect(find.byType(StreamButton), findsOneWidget); + }); + + testWidgets('picks up a changed global configuration', (tester) async { + await pumpScrolledAwayList( + tester, + globalConfig: const StreamMessageListViewConfiguration(showScrollToBottom: false), + ); + expect(find.byType(StreamButton), findsNothing); + + // Guards the didChangeDependencies re-resolve. + await pumpScrolledAwayList( + tester, + globalConfig: const StreamMessageListViewConfiguration(), + ); + + expect(find.byType(StreamButton), findsOneWidget); + }); + + // Guards the didUpdateWidget re-resolve. The config is cached in a field, so + // a swapped `config` has to invalidate it. + // + // Swapping via setState below the StreamChat ancestor rather than a second + // pumpWidget, because StreamChatConfigurationData has no `==` — rebuilding + // StreamChat hands StreamChatConfiguration a fresh instance, which notifies + // every dependent and re-runs didChangeDependencies. That would resolve the + // config for the wrong reason and hide a missing didUpdateWidget. + testWidgets('picks up a changed config without a dependency change', (tester) async { + final messages = generateConversation(20, users: [OwnUser(id: 'ownid'), User(id: 'otherid')]); + when(() => channelClientState.messagesStream).thenAnswer((_) => Stream.value(messages)); + when(() => channelClientState.messages).thenReturn(messages); + + final swapper = GlobalKey<_ConfigSwapperState>(); + + await tester.runAsync(() async { + await tester.pumpWidget( + MaterialApp( + home: DefaultAssetBundle( + bundle: rootBundle, + child: StreamChat( + client: client, + child: StreamChannel( + channel: channel, + child: _ConfigSwapper( + key: swapper, + initialConfig: const StreamMessageListViewConfiguration(), + ), + ), + ), + ), + ), + ); + await tester.pumpAndSettle(); + }); + + expect(find.byType(StreamButton), findsOneWidget); + + swapper.currentState!.swap(const StreamMessageListViewConfiguration(showScrollToBottom: false)); + await tester.pumpAndSettle(); + + expect(find.byType(StreamButton), findsNothing); + }); + }); +} + +/// Rebuilds only its [StreamMessageListView] child when [swap] is called, +/// leaving every ancestor untouched. +class _ConfigSwapper extends StatefulWidget { + const _ConfigSwapper({super.key, required this.initialConfig}); + + final StreamMessageListViewConfiguration initialConfig; + + @override + State<_ConfigSwapper> createState() => _ConfigSwapperState(); +} + +class _ConfigSwapperState extends State<_ConfigSwapper> { + late StreamMessageListViewConfiguration _config = widget.initialConfig; + + void swap(StreamMessageListViewConfiguration config) => setState(() => _config = config); + + @override + Widget build(BuildContext context) => StreamMessageListView(initialScrollIndex: 7, config: _config); } From 33eeab5658f42d57777dc606c2d1df1c4a6af92c Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 16:05:58 +0200 Subject: [PATCH 60/87] test(ui): cover replies-disabled hiding the thread reply action The `repliesEnabled` guard on ThreadReply landed with only a mock-helper change (adding `replies: true`) so existing tests kept passing -- the new branch itself was untested. Parameterise the helper with `enableReplies` and assert the action drops out while the send-reply capability is still granted, so the test pins the config check rather than the capability check. Also assert QuotedReply survives, since it does not depend on the replies config. Verified the test fails with the guard removed. Co-Authored-By: Claude Opus 5 --- .../message_actions_builder_test.dart | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart b/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart index 1858a6937a..fade6cd1cb 100644 --- a/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart +++ b/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart @@ -71,9 +71,10 @@ void main() { MockChannel _getChannelWithCapabilities( List capabilities, { bool enableMutes = true, + bool enableReplies = true, }) { final customChannel = MockChannel(ownCapabilities: capabilities); - final channelConfig = ChannelConfig(mutes: enableMutes, replies: true); + final channelConfig = ChannelConfig(mutes: enableMutes, replies: enableReplies); when(() => customChannel.config).thenReturn(channelConfig); return customChannel; } @@ -462,6 +463,34 @@ void main() { }, ); + testWidgets( + 'hides thread reply when channel replies are disabled', + (tester) async { + final context = await _getContext(tester); + + // The send-reply capability is granted; only the channel config says no. + final channelWithoutReplies = _getChannelWithCapabilities( + allChannelCapabilities, + enableReplies: false, + ); + + final actions = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channelWithoutReplies, + currentUser: currentUser, + ); + + actions.notExpects( + reason: 'Thread reply unavailable when channel replies are disabled', + ); + + actions.expects( + reason: 'Quoted reply is independent of the replies config', + ); + }, + ); + testWidgets( 'handles thread and quote reply actions correctly', (tester) async { From e97ab7f2f81aebf6f2a062d5d9feca59245fcccf Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 16:07:29 +0200 Subject: [PATCH 61/87] refactor(ui): extract the app bar behavior resolver The three-tier fallback (widget-local override, then StreamAppBarTheme, then the ambient StreamAppStyle) plus an identical two-arm switch was written out three times, and the derived local was named differently in each -- showAvatarShadow, hasAvatarShadow, isFloating. Extract resolveAppBarBehavior and isFloatingAppBar into an internal util, and name the local isFloating at all three sites. Behaviour-preserving; existing header and back-button tests pass unchanged. Kept in stream_chat_flutter rather than stream_core_flutter so this stays self-contained -- noted in the doc comment that next to StreamAppBarBehavior is the better long-term home. Co-Authored-By: Claude Opus 5 --- .../lib/src/channel/channel_header.dart | 12 ++---- .../lib/src/channel/channel_list_header.dart | 12 ++---- .../lib/src/misc/back_button.dart | 10 +---- .../lib/src/utils/app_bar_behavior.dart | 41 +++++++++++++++++++ 4 files changed, 49 insertions(+), 26 deletions(-) create mode 100644 packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index e9ab17159d..47b9fe6bca 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; +import 'package:stream_chat_flutter/src/utils/app_bar_behavior.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// {@template streamChannelHeader} @@ -148,20 +149,13 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget var subtitle = this.subtitle; subtitle ??= StreamChannelInfo(channel: channel); - final effectiveAppBarBehavior = - style?.behavior ?? - StreamAppBarTheme.of(context).style?.behavior ?? - (StreamTheme.of(context).appStyle.isFloating ? .floating : .regular); - final showAvatarShadow = switch (effectiveAppBarBehavior) { - .floating => true, - .regular => false, - }; + final isFloating = isFloatingAppBar(context, override: style?.behavior); var trailing = this.trailing; trailing ??= _DefaultChannelAvatar( channel: channel, onPressed: onChannelAvatarPressed, - isFloating: showAvatarShadow, + isFloating: isFloating, ); return Portal( diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart index e4729011ae..037704cd6e 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; +import 'package:stream_chat_flutter/src/utils/app_bar_behavior.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// {@template streamChannelListHeader} @@ -125,16 +126,9 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi final _client = client ?? StreamChat.of(context).client; final headerTheme = StreamChatTheme.of(context).channelListHeaderTheme; - final effectiveAppBarBehavior = - style?.behavior ?? - StreamAppBarTheme.of(context).style?.behavior ?? - (StreamTheme.of(context).appStyle.isFloating ? .floating : .regular); - final hasAvatarShadow = switch (effectiveAppBarBehavior) { - .floating => true, - .regular => false, - }; + final isFloating = isFloatingAppBar(context, override: style?.behavior); - final leading = _DefaultUserAvatar(client: _client, onPressed: onUserAvatarPressed, isFloating: hasAvatarShadow); + final leading = _DefaultUserAvatar(client: _client, onPressed: onUserAvatarPressed, isFloating: isFloating); return Portal( child: StreamConnectionStatusBuilder( diff --git a/packages/stream_chat_flutter/lib/src/misc/back_button.dart b/packages/stream_chat_flutter/lib/src/misc/back_button.dart index 5c39b3848b..e05c758616 100644 --- a/packages/stream_chat_flutter/lib/src/misc/back_button.dart +++ b/packages/stream_chat_flutter/lib/src/misc/back_button.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/utils/app_bar_behavior.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// {@template streamBackButton} @@ -38,14 +39,7 @@ class StreamBackButton extends StatelessWidget { .iOS || .macOS => context.streamIcons.chevronLeft, _ => context.streamIcons.arrowLeft, }; - final effectiveAppBarBehavior = - appBarBehavior ?? - StreamAppBarTheme.of(context).style?.behavior ?? - (StreamTheme.of(context).appStyle.isFloating ? .floating : .regular); - final isFloating = switch (effectiveAppBarBehavior) { - .floating => true, - .regular => false, - }; + final isFloating = isFloatingAppBar(context, override: appBarBehavior); Widget button = StreamButton.icon( type: isFloating ? .outline : .ghost, diff --git a/packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart b/packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart new file mode 100644 index 0000000000..0114efb1f0 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart @@ -0,0 +1,41 @@ +import 'package:flutter/widgets.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +/// Resolves the effective [StreamAppBarBehavior] for a widget. +/// +/// Precedence, highest first: +/// +/// 1. [override] — a widget-local value, such as +/// [StreamAppBarStyle.behavior] passed to a header or +/// [StreamBackButton.appBarBehavior]. +/// 2. [StreamAppBarStyle.behavior] from the ambient [StreamAppBarTheme]. +/// 3. The ambient [StreamAppStyle] — [StreamAppStyle.floating] maps to +/// [StreamAppBarBehavior.floating], [StreamAppStyle.regular] to +/// [StreamAppBarBehavior.regular]. +/// +/// Internal: shared by [StreamChannelHeader], [StreamChannelListHeader] and +/// [StreamBackButton] so the chain stays in one place. A natural home for this +/// is next to [StreamAppBarBehavior] in `stream_core_flutter`. +StreamAppBarBehavior resolveAppBarBehavior( + BuildContext context, { + StreamAppBarBehavior? override, +}) { + return override ?? + StreamAppBarTheme.of(context).style?.behavior ?? + (StreamTheme.of(context).appStyle.isFloating ? .floating : .regular); +} + +/// Whether the effective [StreamAppBarBehavior] is +/// [StreamAppBarBehavior.floating]. +/// +/// Convenience over [resolveAppBarBehavior] for the common case of driving a +/// boolean — a floating app bar, avatar shadow, or outlined back button. +bool isFloatingAppBar( + BuildContext context, { + StreamAppBarBehavior? override, +}) { + return switch (resolveAppBarBehavior(context, override: override)) { + .floating => true, + .regular => false, + }; +} From 26ea9ff58b7b936d57e0e4fab36c2c1f84790967 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 16:14:49 +0200 Subject: [PATCH 62/87] chore: minor cleanups from PR review Three unrelated nits from the review: - Move `_pillHeight` up with the other state fields in the composer; it was declared between two methods, after both of its use sites. - Drop the ignore_for_file line in channel_list_page.dart entirely. The review flagged `avoid_redundant_argument_values` as too broad; checking it turned out to have no offenders at all, and `deprecated_member_use` went stale when BottomNavigationBar was replaced with StreamBottomNavBar. - Add a `streamTopInset` / `streamBottomInset` BuildContext extension in the sample app, replacing 12 copies of `StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0` across 11 files. Kept in the sample: StreamScaffoldInsets lives in stream_core_flutter. Co-Authored-By: Claude Opus 5 --- .../message_input/stream_message_composer.dart | 10 +++++----- .../lib/config/sample_app_config_screen.dart | 3 ++- sample_app/lib/pages/advanced_options_page.dart | 3 ++- .../lib/pages/channel_file_display_screen.dart | 3 ++- sample_app/lib/pages/channel_list_page.dart | 2 -- .../lib/pages/channel_media_display_screen.dart | 3 ++- sample_app/lib/pages/chat_info_screen.dart | 3 ++- .../lib/pages/group_chat_details_screen.dart | 3 ++- sample_app/lib/pages/group_info_screen.dart | 3 ++- sample_app/lib/pages/new_chat_screen.dart | 3 ++- sample_app/lib/pages/new_group_chat_screen.dart | 3 ++- sample_app/lib/pages/pinned_messages_screen.dart | 3 ++- sample_app/lib/utils/scaffold_insets.dart | 15 +++++++++++++++ sample_app/lib/widgets/channel_list.dart | 5 +++-- 14 files changed, 43 insertions(+), 19 deletions(-) create mode 100644 sample_app/lib/utils/scaffold_insets.dart diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index c0c26aa8b6..8a32a8cb89 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -609,6 +609,11 @@ class DefaultStreamMessageComposerState extends State? _messageUpdatedSubscription; StreamSubscription? _messageDeletedSubscription; + // Height of the floating pill, reported from layout and read back at paint + // time by _FloatingComposerBackdropPainter. Layout always runs before paint, + // so the backdrop's fade is never a frame behind the pill. + final _pillHeight = ValueNotifier(0); + @override void initState() { super.initState(); @@ -1076,11 +1081,6 @@ class DefaultStreamMessageComposerState extends State(0); - Widget _buildInlineAttachmentPicker(BuildContext context) { if (!_isPickerVisible) return const SizedBox.shrink(); diff --git a/sample_app/lib/config/sample_app_config_screen.dart b/sample_app/lib/config/sample_app_config_screen.dart index 3e9e7499c4..71b4a91fe7 100644 --- a/sample_app/lib/config/sample_app_config_screen.dart +++ b/sample_app/lib/config/sample_app_config_screen.dart @@ -3,6 +3,7 @@ import 'dart:io' show Platform; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:sample_app/config/sample_app_config.dart'; +import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Whether dynamic color extraction is supported on the current platform. @@ -27,7 +28,7 @@ class SampleAppConfigScreen extends StatelessWidget { appBar: StreamAppBar(title: const Text('Configuration')), body: Builder( builder: (context) { - final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final topInset = context.streamTopInset; return SingleChildScrollView( padding: EdgeInsets.fromLTRB(spacing.md, topInset, spacing.md, 0), child: Column( diff --git a/sample_app/lib/pages/advanced_options_page.dart b/sample_app/lib/pages/advanced_options_page.dart index 6533a122f9..c99d397b61 100644 --- a/sample_app/lib/pages/advanced_options_page.dart +++ b/sample_app/lib/pages/advanced_options_page.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/auth/auth_controller.dart'; import 'package:sample_app/routes/routes.dart'; +import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:sample_app/widgets/stream_version.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -105,7 +106,7 @@ class _AdvancedOptionsPageState extends State { appBar: StreamAppBar(title: const Text('Custom settings')), body: Builder( builder: (context) { - final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final topInset = context.streamTopInset; return Padding( padding: EdgeInsets.fromLTRB(16, 16 + topInset, 16, 0), child: Form( diff --git a/sample_app/lib/pages/channel_file_display_screen.dart b/sample_app/lib/pages/channel_file_display_screen.dart index b0effdb1b5..362455f200 100644 --- a/sample_app/lib/pages/channel_file_display_screen.dart +++ b/sample_app/lib/pages/channel_file_display_screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Lists every file shared in the enclosing channel, grouped by the @@ -45,7 +46,7 @@ class _ChannelFileDisplayScreenState extends State { body: ValueListenableBuilder>( valueListenable: _controller, builder: (context, value, _) { - final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final topInset = context.streamTopInset; return value.when( (items, nextPageKey, _) { // Flatten messages → individual file attachments paired with diff --git a/sample_app/lib/pages/channel_list_page.dart b/sample_app/lib/pages/channel_list_page.dart index 4838dad340..412b6ebccb 100644 --- a/sample_app/lib/pages/channel_list_page.dart +++ b/sample_app/lib/pages/channel_list_page.dart @@ -1,5 +1,3 @@ -// ignore_for_file: deprecated_member_use, avoid_redundant_argument_values - import 'dart:async'; import 'dart:math' as math; diff --git a/sample_app/lib/pages/channel_media_display_screen.dart b/sample_app/lib/pages/channel_media_display_screen.dart index 01351a702a..c66e67749a 100644 --- a/sample_app/lib/pages/channel_media_display_screen.dart +++ b/sample_app/lib/pages/channel_media_display_screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Lists every photo + video shared in the enclosing channel as a 3-up @@ -44,7 +45,7 @@ class _ChannelMediaDisplayScreenState extends State { body: ValueListenableBuilder>( valueListenable: _controller, builder: (context, value, _) { - final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final topInset = context.streamTopInset; final spacing = context.streamSpacing; return value.when( (items, nextPageKey, _) { diff --git a/sample_app/lib/pages/chat_info_screen.dart b/sample_app/lib/pages/chat_info_screen.dart index e9d605132a..c23ffb92a9 100644 --- a/sample_app/lib/pages/chat_info_screen.dart +++ b/sample_app/lib/pages/chat_info_screen.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:sample_app/pages/channel_file_display_screen.dart'; import 'package:sample_app/pages/channel_media_display_screen.dart'; import 'package:sample_app/pages/pinned_messages_screen.dart'; +import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Detail screen for a 1:1 chat correspondence. @@ -34,7 +35,7 @@ class ChatInfoScreen extends StatelessWidget { // top of the body so individual rows stay style-free. body: Builder( builder: (context) { - final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final topInset = context.streamTopInset; return IconTheme.merge( data: const IconThemeData(size: 20), child: SingleChildScrollView( diff --git a/sample_app/lib/pages/group_chat_details_screen.dart b/sample_app/lib/pages/group_chat_details_screen.dart index 9a7b1adc80..cd72507997 100644 --- a/sample_app/lib/pages/group_chat_details_screen.dart +++ b/sample_app/lib/pages/group_chat_details_screen.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/routes/routes.dart'; import 'package:sample_app/state/new_group_chat_state.dart'; +import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; class GroupChatDetailsScreen extends StatefulWidget { @@ -107,7 +108,7 @@ class _GroupChatDetailsScreenState extends State { message: statusString, child: Builder( builder: (context) { - final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final topInset = context.streamTopInset; return Column( children: [ if (topInset > 0) SizedBox(height: topInset), diff --git a/sample_app/lib/pages/group_info_screen.dart b/sample_app/lib/pages/group_info_screen.dart index abd08a11d8..53f66d3b84 100644 --- a/sample_app/lib/pages/group_info_screen.dart +++ b/sample_app/lib/pages/group_info_screen.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:sample_app/pages/channel_file_display_screen.dart'; import 'package:sample_app/pages/channel_media_display_screen.dart'; import 'package:sample_app/pages/pinned_messages_screen.dart'; +import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:sample_app/widgets/add_members_sheet.dart'; import 'package:sample_app/widgets/all_members_sheet.dart'; import 'package:sample_app/widgets/edit_group_sheet.dart'; @@ -53,7 +54,7 @@ class GroupInfoScreen extends StatelessWidget { // top of the body so individual rows stay style-free. body: Builder( builder: (context) { - final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final topInset = context.streamTopInset; return IconTheme.merge( data: const IconThemeData(size: 20), child: SingleChildScrollView( diff --git a/sample_app/lib/pages/new_chat_screen.dart b/sample_app/lib/pages/new_chat_screen.dart index fecf2a56a4..b323c0d750 100644 --- a/sample_app/lib/pages/new_chat_screen.dart +++ b/sample_app/lib/pages/new_chat_screen.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/routes/routes.dart'; +import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:sample_app/widgets/chips_input_text_field.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -143,7 +144,7 @@ class _NewChatScreenState extends State { appBar: StreamAppBar(title: const Text('New Chat')), body: StreamConnectionStatusBuilder( statusBuilder: (context, status) { - final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final topInset = context.streamTopInset; var statusString = ''; var showStatus = true; diff --git a/sample_app/lib/pages/new_group_chat_screen.dart b/sample_app/lib/pages/new_group_chat_screen.dart index 54c53efa05..338c0b54d3 100644 --- a/sample_app/lib/pages/new_group_chat_screen.dart +++ b/sample_app/lib/pages/new_group_chat_screen.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/routes/routes.dart'; import 'package:sample_app/state/new_group_chat_state.dart'; +import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:sample_app/widgets/search_text_field.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -110,7 +111,7 @@ class _NewGroupChatScreenState extends State { child: NestedScrollView( floatHeaderSlivers: true, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { - final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final topInset = context.streamTopInset; return [ if (topInset > 0) SliverToBoxAdapter(child: SizedBox(height: topInset)), SliverToBoxAdapter( diff --git a/sample_app/lib/pages/pinned_messages_screen.dart b/sample_app/lib/pages/pinned_messages_screen.dart index e07c2e1aa3..7828c72c9b 100644 --- a/sample_app/lib/pages/pinned_messages_screen.dart +++ b/sample_app/lib/pages/pinned_messages_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/routes/routes.dart'; +import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Lists every pinned message in the enclosing channel. @@ -42,7 +43,7 @@ class _PinnedMessagesScreenState extends State { appBar: StreamAppBar(title: const Text('Pinned Messages')), body: Builder( builder: (context) { - final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final topInset = context.streamTopInset; return StreamMessageSearchListView( controller: _controller, padding: EdgeInsets.only(top: topInset), diff --git a/sample_app/lib/utils/scaffold_insets.dart b/sample_app/lib/utils/scaffold_insets.dart new file mode 100644 index 0000000000..47e12098a3 --- /dev/null +++ b/sample_app/lib/utils/scaffold_insets.dart @@ -0,0 +1,15 @@ +import 'package:flutter/widgets.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +/// Reads the surrounding [StreamScaffold]'s floating-chrome insets. +/// +/// Both getters return `0` when there is no [StreamScaffoldInsets] ancestor, or +/// when the chrome is not floating — so a page can add them unconditionally and +/// get the right layout in either app style. +extension StreamScaffoldInsetsContext on BuildContext { + /// Space taken by a floating app bar at the top, including the status bar. + double get streamTopInset => StreamScaffoldInsets.maybeOf(this)?.topPadding ?? 0; + + /// Space taken by a floating bottom widget, including the home indicator. + double get streamBottomInset => StreamScaffoldInsets.maybeOf(this)?.bottomPadding ?? 0; +} diff --git a/sample_app/lib/widgets/channel_list.dart b/sample_app/lib/widgets/channel_list.dart index 6c68eba582..c813994078 100644 --- a/sample_app/lib/widgets/channel_list.dart +++ b/sample_app/lib/widgets/channel_list.dart @@ -5,6 +5,7 @@ import 'package:flutter/rendering.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/routes/routes.dart'; +import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:sample_app/widgets/channel_detail_sheet.dart'; import 'package:sample_app/widgets/search_text_field.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -87,7 +88,7 @@ class _ChannelList extends State { // When the app bar is floating it overlaps this scroll view from // the top. Insert a spacer sliver so the search bar starts below // the visible bottom edge of the floating bar. - final topInset = StreamScaffoldInsets.maybeOf(context)?.topPadding ?? 0.0; + final topInset = context.streamTopInset; return [ if (topInset > 0) SliverToBoxAdapter(child: SizedBox(height: topInset)), SliverToBoxAdapter( @@ -114,7 +115,7 @@ class _ChannelListDefault extends StatelessWidget { @override Widget build(BuildContext context) { - final bottomPadding = StreamScaffoldInsets.maybeOf(context)?.bottomPadding ?? 0.0; + final bottomPadding = context.streamBottomInset; return SlidableAutoCloseBehavior( child: RefreshIndicator( From af5ec1e102f788eaeebdd767bf58936da49601ab Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 16:48:25 +0200 Subject: [PATCH 63/87] move custom composer --- sample_app/lib/app.dart | 84 +----------------- .../location_aware_message_composer.dart | 86 +++++++++++++++++++ 2 files changed, 88 insertions(+), 82 deletions(-) create mode 100644 sample_app/lib/widgets/location/location_aware_message_composer.dart diff --git a/sample_app/lib/app.dart b/sample_app/lib/app.dart index 7bbbfa2ec9..480b2335f2 100644 --- a/sample_app/lib/app.dart +++ b/sample_app/lib/app.dart @@ -16,9 +16,8 @@ import 'package:sample_app/routes/app_routes.dart'; import 'package:sample_app/routes/routes.dart'; import 'package:sample_app/widgets/custom_message_actions.dart'; import 'package:sample_app/widgets/location/location_attachment.dart'; +import 'package:sample_app/widgets/location/location_aware_message_composer.dart'; import 'package:sample_app/widgets/location/location_detail_dialog.dart'; -import 'package:sample_app/widgets/location/location_picker_dialog.dart'; -import 'package:sample_app/widgets/location/location_picker_option.dart'; import 'package:sample_app/widgets/video_player.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_localizations/stream_chat_localizations.dart'; @@ -229,7 +228,7 @@ class _StreamChatSampleAppState extends State componentBuilders: StreamComponentBuilders( extensions: streamChatComponentBuilders( messageItem: customMessageItemBuilder, - messageComposer: _locationAwareMessageComposer, + messageComposer: locationAwareMessageComposer, videoPlayer: (context, props) => SampleAppVideoPlayer(props: props), ), ), @@ -281,85 +280,6 @@ class _StreamChatSampleAppState extends State } } -/// Builds the composer, adding the location picker when location sharing is -/// available on the surrounding channel. -/// -/// Registered as the `messageComposer` component builder rather than passed to a -/// composer directly, because [StreamChannelPage] and [StreamThreadPage] own -/// their composers and expose no parameters for them. Going through the -/// component factory reaches them anyway. -Widget _locationAwareMessageComposer(BuildContext context, MessageComposerProps props) { - // Null when a composer is built outside a channel; the factory is global, so - // this builder must tolerate that rather than assume a channel ancestor. - final channel = StreamChannel.maybeOf(context)?.channel; - - final locationEnabled = - channel != null && - context.sampleAppConfig.enableLocationSharing && - channel.config?.sharedLocations == true && - channel.canShareLocation; - - if (!locationEnabled) return DefaultStreamMessageComposer(props: props); - - return DefaultStreamMessageComposer( - props: props.copyWith( - allowedAttachmentPickerTypes: [ - ...AttachmentPickerType.values, - const LocationPickerType(), - ], - onAttachmentPickerResult: (result) => _onCustomAttachmentPickerResult(channel, result), - attachmentPickerOptionsBuilder: (context, defaultOptions) => [ - ...defaultOptions, - TabbedAttachmentPickerOption( - key: 'location-picker', - title: 'Location', - icon: context.streamIcons.location, - supportedTypes: [const LocationPickerType()], - isEnabled: (value) { - if (value.isEmpty) return true; - return value.extraData['location'] != null; - }, - optionViewBuilder: (context, controller) => LocationPicker( - onLocationPicked: (locationResult) { - if (locationResult == null) return; - - controller.notifyCustomResult( - LocationPicked(location: locationResult), - ); - }, - ), - ), - ], - ), - ); -} - -bool _onCustomAttachmentPickerResult( - Channel channel, - StreamAttachmentPickerResult result, -) { - if (result is LocationPicked) { - _onShareLocationPicked(channel, result.location).ignore(); - return true; // Notify that the result was handled. - } - - return false; // Notify that the result was not handled. -} - -Future _onShareLocationPicked( - Channel channel, - LocationPickerResult result, -) async { - if (result.endSharingAt case final endSharingAt?) { - return channel.startLiveLocationSharing( - endSharingAt: endSharingAt, - location: result.coordinates, - ); - } - - return channel.sendStaticLocation(location: result.coordinates); -} - extension on SampleAppConfigData { /// Maps chat-relevant flags to a [StreamChatConfigurationData]. StreamChatConfigurationData toStreamChatConfigurationData() { diff --git a/sample_app/lib/widgets/location/location_aware_message_composer.dart b/sample_app/lib/widgets/location/location_aware_message_composer.dart new file mode 100644 index 0000000000..84a45d1022 --- /dev/null +++ b/sample_app/lib/widgets/location/location_aware_message_composer.dart @@ -0,0 +1,86 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:sample_app/config/sample_app_config.dart'; +import 'package:sample_app/widgets/location/location_picker_dialog.dart'; +import 'package:sample_app/widgets/location/location_picker_option.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +/// Builds the composer, adding the location picker when location sharing is +/// available on the surrounding channel. +/// +/// Registered as the `messageComposer` component builder rather than passed to a +/// composer directly, because [StreamChannelPage] and [StreamThreadPage] own +/// their composers and expose no parameters for them. Going through the +/// component factory reaches them anyway. +Widget locationAwareMessageComposer(BuildContext context, MessageComposerProps props) { + // Null when a composer is built outside a channel; the factory is global, so + // this builder must tolerate that rather than assume a channel ancestor. + final channel = StreamChannel.maybeOf(context)?.channel; + + final locationEnabled = + channel != null && + context.sampleAppConfig.enableLocationSharing && + channel.config?.sharedLocations == true && + channel.canShareLocation; + + if (!locationEnabled) return DefaultStreamMessageComposer(props: props); + + return DefaultStreamMessageComposer( + props: props.copyWith( + allowedAttachmentPickerTypes: [ + ...AttachmentPickerType.values, + const LocationPickerType(), + ], + onAttachmentPickerResult: (result) => _onCustomAttachmentPickerResult(channel, result), + attachmentPickerOptionsBuilder: (context, defaultOptions) => [ + ...defaultOptions, + TabbedAttachmentPickerOption( + key: 'location-picker', + title: 'Location', + icon: context.streamIcons.location, + supportedTypes: [const LocationPickerType()], + isEnabled: (value) { + if (value.isEmpty) return true; + return value.extraData['location'] != null; + }, + optionViewBuilder: (context, controller) => LocationPicker( + onLocationPicked: (locationResult) { + if (locationResult == null) return; + + controller.notifyCustomResult( + LocationPicked(location: locationResult), + ); + }, + ), + ), + ], + ), + ); +} + +bool _onCustomAttachmentPickerResult( + Channel channel, + StreamAttachmentPickerResult result, +) { + if (result is LocationPicked) { + _onShareLocationPicked(channel, result.location).ignore(); + return true; // Notify that the result was handled. + } + + return false; // Notify that the result was not handled. +} + +Future _onShareLocationPicked( + Channel channel, + LocationPickerResult result, +) async { + if (result.endSharingAt case final endSharingAt?) { + return channel.startLiveLocationSharing( + endSharingAt: endSharingAt, + location: result.coordinates, + ); + } + + return channel.sendStaticLocation(location: result.coordinates); +} From 1a156e4c6595f8f06b5dedc95f1c3dc281dfadb2 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 17:04:53 +0200 Subject: [PATCH 64/87] formatting --- .../message_list_view_test.dart | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/stream_chat_flutter/test/src/message_list_view/message_list_view_test.dart b/packages/stream_chat_flutter/test/src/message_list_view/message_list_view_test.dart index 35ceb47082..71836ff637 100644 --- a/packages/stream_chat_flutter/test/src/message_list_view/message_list_view_test.dart +++ b/packages/stream_chat_flutter/test/src/message_list_view/message_list_view_test.dart @@ -243,7 +243,13 @@ void main() { StreamMessageListViewConfiguration? config, StreamMessageListViewConfiguration? globalConfig, }) async { - final messages = generateConversation(20, users: [OwnUser(id: 'ownid'), User(id: 'otherid')]); + final messages = generateConversation( + 20, + users: [ + OwnUser(id: 'ownid'), + User(id: 'otherid'), + ], + ); when(() => channelClientState.messagesStream).thenAnswer((_) => Stream.value(messages)); when(() => channelClientState.messages).thenReturn(messages); @@ -317,7 +323,13 @@ void main() { // every dependent and re-runs didChangeDependencies. That would resolve the // config for the wrong reason and hide a missing didUpdateWidget. testWidgets('picks up a changed config without a dependency change', (tester) async { - final messages = generateConversation(20, users: [OwnUser(id: 'ownid'), User(id: 'otherid')]); + final messages = generateConversation( + 20, + users: [ + OwnUser(id: 'ownid'), + User(id: 'otherid'), + ], + ); when(() => channelClientState.messagesStream).thenAnswer((_) => Stream.value(messages)); when(() => channelClientState.messages).thenReturn(messages); From 42bfd56968abc3e0ea48f3b99e06f3cabb58b746 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 18:13:56 +0200 Subject: [PATCH 65/87] minor improvements --- packages/stream_chat_flutter/CHANGELOG.md | 9 +- .../lib/src/channel/channel_header.dart | 27 ++-- .../lib/src/channel/channel_list_header.dart | 23 ++-- .../lib/src/channel/channel_page.dart | 18 +-- .../lib/src/channel/thread_page.dart | 45 +++++-- .../stream_message_composer.dart | 27 ++-- .../lib/src/misc/thread_header.dart | 6 +- .../lib/src/theme/message_composer_theme.dart | 14 +- .../theme/message_composer_theme.g.theme.dart | 8 +- .../test/src/channel/channel_header_test.dart | 124 ++++++++++++++++++ .../src/channel/channel_list_header_test.dart | 76 +++++++++++ .../test/src/channel/thread_page_test.dart | 62 +++++++-- .../message_composer_location_test.dart | 26 ++-- .../theme/message_composer_theme_test.dart | 30 ++--- 14 files changed, 381 insertions(+), 114 deletions(-) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 83cef658f5..bcf1a3f365 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -3,16 +3,17 @@ ⚠️ Changed - `StreamPhotoGallery` now defaults its `padding` to the bottom safe-area inset instead of no padding, so the last row clears the home indicator. Pass an explicit `padding` to opt out. +- `StreamMessageListView.config` is now nullable (`StreamMessageListViewConfiguration?`) instead of defaulting to `const StreamMessageListViewConfiguration()`. Passing a value is unchanged; code that *reads* `config` off a `StreamMessageListView` instance now gets a nullable value. ✅ Added - Added `StreamChannelPage` — a ready-to-use channel page widget that wires up `StreamChannelHeader`, `StreamMessageListView`, and `StreamMessageComposer` with floating or docked layout driven by the active app style. -- Added `StreamThreadPage` — a ready-to-use thread page widget with the same floating/docked layout support. -- Added `ComposerLocation` and `MessageComposerProps.location` — explicitly controls whether `StreamMessageComposer` renders `floating` or `docked`. When null it falls back to `StreamMessageComposerThemeData.location`, and then to the ambient `StreamAppStyle`. +- Added `StreamThreadPage` — a ready-to-use thread page widget with the same floating/docked layout support, plus an `onBackPressed` callback that replaces the header back button's default pop. +- Added `StreamComposerLocation` and `MessageComposerProps.location` — explicitly controls whether `StreamMessageComposer` renders `floating` or `docked`. When null it falls back to `StreamMessageComposerThemeData.location`, and then to the ambient `StreamAppStyle`. - Added `StreamMessageComposerTheme` and `StreamMessageComposerThemeData` — a component theme for the composer, also available globally as `StreamChatThemeData.messageComposerTheme`. - Added `StreamMessageListView.config` — accepts an explicit `StreamMessageListViewConfiguration` per widget; falls back to `StreamChatConfigurationData.messageListViewConfiguration` from the nearest ancestor when omitted. - Added `StreamMessageListView.topPadding` and `bottomPadding` — padding applied to the scroll view's top and bottom edges, used by floating app bar / composer layouts to keep messages visible without an extra `setState`. -- Added an `appBarBehavior` parameter to `StreamBackButton`, controlling floating vs pinned back-button appearance. Falls back to `StreamAppBarTheme`, and then to the ambient `StreamAppStyle`, when null. `StreamChannelHeader` and `StreamChannelListHeader` now resolve the same behavior from their existing `style` to decide whether the avatar gets a drop shadow, using the same fallback chain. +- Added an `appBarBehavior` parameter to `StreamBackButton`, controlling floating vs pinned back-button appearance. Falls back to `StreamAppBarTheme`, and then to the ambient `StreamAppStyle`, when null. `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamThreadHeader` now merge their `style` into the `StreamAppBarTheme` they install, so every slot in the bar — the default avatar's drop shadow, the default back button, and any `leading`/`trailing` the caller supplies — resolves the same chain the bar itself uses: `style`, then the per-header theme (`channelHeaderTheme` / `channelListHeaderTheme` / `threadHeaderTheme`), then `StreamAppBarTheme`, then `StreamAppStyle`. - Added `messageListViewConfiguration` field to `StreamChatConfigurationData`, allowing a global `StreamMessageListViewConfiguration` default for all `StreamMessageListView` widgets. Pass it via `StreamChat.configData` to configure behaviors like `swipeToReply` and `highlightInitialMessage` app-wide without wiring them per-page. - Re-exported `StreamScaffold`, `StreamScaffoldInsets`, `StreamBottomNavBar`, `StreamBottomNavBarItem`, `StreamAppStyle`, `StreamAppBarBehavior`, `StreamBottomAppBarBehavior`, and `streamFloatingFadeLinearGradient` from `stream_core_flutter` via `package:stream_chat_flutter/stream_chat_flutter.dart`. - Added `StreamMessageListViewConfiguration.autoScrollPolicy` to control whether and how `StreamMessageListView` scrolls to the newest message when a new message arrives. Use `StreamAutoScrollPolicy.disabled` to fully control scrolling yourself. @@ -34,7 +35,7 @@ - Fixed `StreamTypingIndicator` briefly showing typing users from a different context (main channel vs. thread) on its first frame. - Fixed the attachment picker throwing a `Tooltip` assertion error when a custom `TabbedAttachmentPickerOption` is added without a `title`; the tooltip is now only shown when a title is provided. - Fixed the "Message deleted" bubble overflowing its maximum width when the localized label is long; the label now wraps instead. -- Fixed the scroll-to-bottom button in thread views keying off the parent channel's up-to-date state instead of the thread's own scroll position, so it no longer appears while already at the newest reply. +- Fixed the scroll-to-bottom button in thread views keying off the parent channel's up-to-date state instead of the thread's own scroll position, so it no longer appears while already at the newest reply. Note that thread views now show the button at all: it follows `showScrollToBottom` from the effective `StreamMessageListViewConfiguration`, so set that to `false` to restore the previous always-hidden behavior. ## 10.2.0 diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index 47b9fe6bca..a9a7ec1d75 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -149,14 +149,8 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget var subtitle = this.subtitle; subtitle ??= StreamChannelInfo(channel: channel); - final isFloating = isFloatingAppBar(context, override: style?.behavior); - var trailing = this.trailing; - trailing ??= _DefaultChannelAvatar( - channel: channel, - onPressed: onChannelAvatarPressed, - isFloating: isFloating, - ); + trailing ??= _DefaultChannelAvatar(channel: channel, onPressed: onChannelAvatarPressed); return Portal( child: StreamConnectionStatusBuilder( @@ -182,10 +176,15 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget message: statusString, // Wrap the bar in a [StreamAppBarTheme] so the per-header chat // theme drives all default styling (background, padding, - // typography, divider) — the bar internally merges in any - // [style] override the caller passed. + // typography, divider). + // + // [style] is merged into the theme data as well as passed to the + // bar, so every slot below — the default avatar, the default back + // button, and anything the caller supplied — resolves the same + // chain the bar itself does: [style], then the per-header theme, + // then the ambient app bar theme, then the app style. child: StreamAppBarTheme( - data: headerTheme, + data: headerTheme.merge(StreamAppBarThemeData(style: style)), child: StreamAppBar( leading: leading, automaticallyImplyLeading: false, @@ -205,14 +204,18 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget } class _DefaultChannelAvatar extends StatelessWidget { - const _DefaultChannelAvatar({required this.channel, this.onPressed, this.isFloating = false}); + const _DefaultChannelAvatar({required this.channel, this.onPressed}); final Channel channel; final void Function(Channel channel)? onPressed; - final bool isFloating; @override Widget build(BuildContext context) { + // Resolved from context rather than passed in, so it picks up the header's + // [StreamAppBarTheme] — this widget is built inside it, same as the bar's + // other slots. + final isFloating = isFloatingAppBar(context); + final effectiveOnTap = switch (onPressed) { final cb? => () => cb(channel), _ => null, diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart index 037704cd6e..2204ac9462 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart @@ -126,9 +126,7 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi final _client = client ?? StreamChat.of(context).client; final headerTheme = StreamChatTheme.of(context).channelListHeaderTheme; - final isFloating = isFloatingAppBar(context, override: style?.behavior); - - final leading = _DefaultUserAvatar(client: _client, onPressed: onUserAvatarPressed, isFloating: isFloating); + final leading = _DefaultUserAvatar(client: _client, onPressed: onUserAvatarPressed); return Portal( child: StreamConnectionStatusBuilder( @@ -161,10 +159,15 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi showMessage: showConnectionStateTile && showStatus, message: statusString, // Wrap the bar in a [StreamAppBarTheme] so the per-header chat - // theme drives all default styling — the bar internally merges - // in any [style] override the caller passed. + // theme drives all default styling. + // + // [style] is merged into the theme data as well as passed to the + // bar, so every slot below — the default avatar and anything the + // caller supplied — resolves the same chain the bar itself does: + // [style], then the per-header theme, then the ambient app bar + // theme, then the app style. child: StreamAppBarTheme( - data: headerTheme, + data: headerTheme.merge(StreamAppBarThemeData(style: style)), child: StreamAppBar( leading: leading, title: title, @@ -182,17 +185,21 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi } class _DefaultUserAvatar extends StatelessWidget { - const _DefaultUserAvatar({required this.client, this.onPressed, this.isFloating = false}); + const _DefaultUserAvatar({required this.client, this.onPressed}); final StreamChatClient client; final void Function(User user)? onPressed; - final bool isFloating; @override Widget build(BuildContext context) { final user = client.state.currentUser; if (user == null) return const SizedBox.shrink(); + // Resolved from context rather than passed in, so it picks up the header's + // [StreamAppBarTheme] — this widget is built inside it, same as the bar's + // other slots. + final isFloating = isFloatingAppBar(context); + // Caller-provided handler wins; otherwise mirror Material AppBar and // open the enclosing Scaffold's drawer if one exists. With no callback // and no drawer, the avatar is non-interactive. diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index b032422217..f9b9c02fcb 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -84,15 +84,8 @@ class StreamChannelPage extends StatefulWidget { } class _StreamChannelPageState extends State { - late final FocusNode _focusNode; - late final StreamMessageComposerController _messageComposerController; - - @override - void initState() { - super.initState(); - _focusNode = FocusNode(); - _messageComposerController = StreamMessageComposerController(); - } + late final FocusNode _focusNode = FocusNode(); + late final StreamMessageComposerController _messageComposerController = StreamMessageComposerController(); @override void dispose() { @@ -103,14 +96,16 @@ class _StreamChannelPageState extends State { void _reply(Message message) { _messageComposerController.quotedMessage = message; - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) return; _focusNode.requestFocus(); }); } void _editMessage(Message message) { _messageComposerController.editMessage(message); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) return; _focusNode.requestFocus(); }); } @@ -145,7 +140,6 @@ class _StreamChannelPageState extends State { ); return StreamScaffold( - backgroundColor: context.streamColorScheme.backgroundApp, appBar: appBar, bottom: composer, body: _ChannelPageBody( diff --git a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart index 248ee92bd7..6e50b3cd65 100644 --- a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart @@ -31,6 +31,7 @@ class StreamThreadPage extends StatefulWidget { this.initialScrollIndex, this.initialAlignment, this.onViewInChannelTap, + this.onBackPressed, }); /// The parent message of the thread. @@ -45,21 +46,21 @@ class StreamThreadPage extends StatefulWidget { /// Called when the user taps "View in channel". final void Function(Message message)? onViewInChannelTap; + /// Called when the header's back button is pressed. + /// + /// Replaces the default action, which pops the current route. When null the + /// default is kept. + final VoidCallback? onBackPressed; + @override State createState() => _StreamThreadPageState(); } class _StreamThreadPageState extends State { - final FocusNode _focusNode = FocusNode(); - late StreamMessageComposerController _messageComposerController; - - @override - void initState() { - super.initState(); - _messageComposerController = StreamMessageComposerController( - message: Message(parentId: widget.parent.id), - ); - } + late final FocusNode _focusNode = FocusNode(); + late final StreamMessageComposerController _messageComposerController = StreamMessageComposerController( + message: Message(parentId: widget.parent.id), + ); @override void dispose() { @@ -70,23 +71,39 @@ class _StreamThreadPageState extends State { void _reply(Message message) { _messageComposerController.quotedMessage = message; - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) return; _focusNode.requestFocus(); }); } void _editMessage(Message message) { _messageComposerController.editMessage(message); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) return; _focusNode.requestFocus(); }); } @override Widget build(BuildContext context) { - final appBar = StreamThreadHeader(parent: widget.parent); + final channel = StreamChannel.maybeOf(context)?.channel; + + final appBar = StreamThreadHeader( + parent: widget.parent, + // Leaving this null keeps the header's own default back button, which + // pops the route. + leading: switch (widget.onBackPressed) { + final onBackPressed? => StreamBackButton( + onPressed: onBackPressed, + channelId: channel?.cid, + showUnreadCount: true, + ), + _ => null, + }, + ); - final composer = widget.parent.type != 'deleted' + final composer = !widget.parent.isDeleted ? StreamMessageComposer( focusNode: _focusNode, messageComposerController: _messageComposerController, diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 8a32a8cb89..585a1c2919 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -101,7 +101,7 @@ class StreamMessageComposer extends StatelessWidget { TextCapitalization textCapitalization = TextCapitalization.sentences, bool autofocus = false, bool autoCorrect = true, - ComposerLocation? location, + StreamComposerLocation? location, }) : props = .new( onMessageSent: onMessageSent, preMessageSending: preMessageSending, @@ -412,7 +412,7 @@ class MessageComposerProps { final bool autoCorrect; /// The location of the message composer. - final ComposerLocation? location; + final StreamComposerLocation? location; /// Returns a copy of this [MessageComposerProps] with the given fields /// replaced with new values. @@ -452,7 +452,7 @@ class MessageComposerProps { TextCapitalization? textCapitalization, bool? autofocus, bool? autoCorrect, - ComposerLocation? location, + StreamComposerLocation? location, }) { return MessageComposerProps( onMessageSent: onMessageSent ?? this.onMessageSent, @@ -834,10 +834,7 @@ class DefaultStreamMessageComposerState extends State pumpHeader( + WidgetTester tester, { + StreamAppStyle appStyle = StreamAppStyle.regular, + StreamAppBarBehavior? themeBehavior, + StreamAppBarBehavior? styleBehavior, + }) async { + final client = MockClient(); + final clientState = MockClientState(); + final channel = MockChannel(); + final channelState = MockChannelState(); + final user = OwnUser(id: 'user-id'); + + when(() => client.state).thenReturn(clientState); + when(() => clientState.currentUser).thenReturn(user); + when(() => clientState.currentUserStream).thenAnswer((_) => Stream.value(user)); + when(() => clientState.totalUnreadCount).thenReturn(0); + when(() => clientState.totalUnreadCountStream).thenAnswer((_) => Stream.value(0)); + when(() => client.wsConnectionStatusStream).thenAnswer((_) => Stream.value(ConnectionStatus.connected)); + + when(() => channel.client).thenReturn(client); + when(() => channel.state).thenReturn(channelState); + when(() => channel.lastMessageAt).thenReturn(null); + when(() => channel.name).thenReturn('test'); + when(() => channel.nameStream).thenAnswer((_) => Stream.value('test')); + when(() => channel.image).thenReturn(null); + when(() => channel.imageStream).thenAnswer((_) => Stream.value(null)); + when(() => channel.isMuted).thenReturn(false); + when(() => channel.isMutedStream).thenAnswer((_) => Stream.value(false)); + + when(() => channelState.members).thenReturn([]); + when(() => channelState.membersStream).thenAnswer((_) => Stream.value([])); + when(() => channelState.unreadCount).thenReturn(0); + when(() => channelState.unreadCountStream).thenAnswer((_) => Stream.value(0)); + + await tester.pumpWidget( + MaterialApp( + theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), + home: StreamChat( + client: client, + themeData: StreamChatThemeData( + channelHeaderTheme: switch (themeBehavior) { + final behavior? => StreamAppBarThemeData(style: StreamAppBarStyle(behavior: behavior)), + _ => null, + }, + ), + child: StreamChannel( + channel: channel, + child: Scaffold( + body: StreamChannelHeader( + style: switch (styleBehavior) { + final behavior? => StreamAppBarStyle(behavior: behavior), + _ => null, + }, + ), + ), + ), + ), + ), + ); + await tester.pumpAndSettle(); + } + + bool? avatarIsFloating(WidgetTester tester) { + return tester.widget(find.byType(StreamChannelAvatar)).isFloating; + } + + bool? backButtonIsFloating(WidgetTester tester) { + final button = find.descendant(of: find.byType(StreamBackButton), matching: find.byType(StreamButton)); + return tester.widget(button).props.isFloating; + } + + testWidgets('is not floating by default', (tester) async { + await pumpHeader(tester); + + expect(avatarIsFloating(tester), isNot(isTrue)); + }); + + testWidgets('floats when the app style is floating', (tester) async { + await pumpHeader(tester, appStyle: StreamAppStyle.floating); + + expect(avatarIsFloating(tester), isTrue); + }); + + testWidgets('floats when the header theme says so, over a regular app style', (tester) async { + await pumpHeader(tester, themeBehavior: StreamAppBarBehavior.floating); + + expect(avatarIsFloating(tester), isTrue); + }); + + testWidgets('the header style wins over both the header theme and the app style', (tester) async { + await pumpHeader( + tester, + appStyle: StreamAppStyle.floating, + themeBehavior: StreamAppBarBehavior.floating, + styleBehavior: StreamAppBarBehavior.regular, + ); + + expect(avatarIsFloating(tester), isNot(isTrue)); + }); + + testWidgets('the default back button agrees with the avatar under the header theme', (tester) async { + await pumpHeader(tester, themeBehavior: StreamAppBarBehavior.floating); + + expect(backButtonIsFloating(tester), isTrue); + expect(backButtonIsFloating(tester), avatarIsFloating(tester)); + }); + + testWidgets('the default back button agrees with the avatar under the header style', (tester) async { + await pumpHeader( + tester, + appStyle: StreamAppStyle.floating, + styleBehavior: StreamAppBarBehavior.regular, + ); + + expect(backButtonIsFloating(tester), isNot(isTrue)); + expect(backButtonIsFloating(tester), avatarIsFloating(tester)); + }); + }); } diff --git a/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart b/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart index e23e450846..eb4c607dae 100644 --- a/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart @@ -155,4 +155,80 @@ void main() { expect(trailingTapped, 1); }, ); + + group('default avatar floating behavior', () { + // The header installs its own StreamAppBarTheme around the bar, so the + // avatar has to resolve from inside it — otherwise channelListHeaderTheme + // is invisible to the avatar while the bar honours it. + Future pumpHeader( + WidgetTester tester, { + StreamAppStyle appStyle = StreamAppStyle.regular, + StreamAppBarBehavior? themeBehavior, + StreamAppBarBehavior? styleBehavior, + }) async { + final client = MockClient(); + final clientState = MockClientState(); + + when(() => client.state).thenReturn(clientState); + when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); + when(() => client.wsConnectionStatusStream).thenAnswer((_) => Stream.value(ConnectionStatus.connected)); + + await tester.pumpWidget( + MaterialApp( + theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), + home: StreamChat( + client: client, + themeData: StreamChatThemeData( + channelListHeaderTheme: switch (themeBehavior) { + final behavior? => StreamAppBarThemeData(style: StreamAppBarStyle(behavior: behavior)), + _ => null, + }, + ), + child: Scaffold( + body: StreamChannelListHeader( + style: switch (styleBehavior) { + final behavior? => StreamAppBarStyle(behavior: behavior), + _ => null, + }, + ), + ), + ), + ), + ); + await tester.pumpAndSettle(); + } + + bool? avatarIsFloating(WidgetTester tester) { + return tester.widget(find.byType(StreamUserAvatar)).isFloating; + } + + testWidgets('is not floating by default', (tester) async { + await pumpHeader(tester); + + expect(avatarIsFloating(tester), isNot(isTrue)); + }); + + testWidgets('floats when the app style is floating', (tester) async { + await pumpHeader(tester, appStyle: StreamAppStyle.floating); + + expect(avatarIsFloating(tester), isTrue); + }); + + testWidgets('floats when the header theme says so, over a regular app style', (tester) async { + await pumpHeader(tester, themeBehavior: StreamAppBarBehavior.floating); + + expect(avatarIsFloating(tester), isTrue); + }); + + testWidgets('the header style wins over both the header theme and the app style', (tester) async { + await pumpHeader( + tester, + appStyle: StreamAppStyle.floating, + themeBehavior: StreamAppBarBehavior.floating, + styleBehavior: StreamAppBarBehavior.regular, + ); + + expect(avatarIsFloating(tester), isNot(isTrue)); + }); + }); } diff --git a/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart b/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart index 381e737919..b8c7ae5196 100644 --- a/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart @@ -118,6 +118,34 @@ void main() { expect(messageListView.bottomPadding, 0); }); + testWidgets('tapping back invokes onBackPressed', (tester) async { + var backPressed = 0; + await _pumpThreadPage(tester, onBackPressed: () => backPressed++); + + await tester.tap(find.byType(StreamBackButton)); + await tester.pumpAndSettle(); + + expect(backPressed, 1); + }); + + testWidgets('onBackPressed replaces the default pop', (tester) async { + await _pumpThreadPage(tester, onBackPressed: () {}, pushOntoARoute: true); + + await tester.tap(find.byType(StreamBackButton)); + await tester.pumpAndSettle(); + + expect(find.byType(StreamThreadPage), findsOneWidget); + }); + + testWidgets('pops the route when onBackPressed is not set', (tester) async { + await _pumpThreadPage(tester, pushOntoARoute: true); + + await tester.tap(find.byType(StreamBackButton)); + await tester.pumpAndSettle(); + + expect(find.byType(StreamThreadPage), findsNothing); + }); + testWidgets('disposes its composer controller when removed from the tree', (tester) async { await _pumpThreadPage(tester); final controller = _composerController(tester); @@ -149,6 +177,8 @@ Future _pumpThreadPage( Message? parent, StreamAppStyle appStyle = StreamAppStyle.regular, void Function(Message message)? onViewInChannelTap, + VoidCallback? onBackPressed, + bool pushOntoARoute = false, }) async { final originalRecordPlatform = RecordPlatform.instance; RecordPlatform.instance = FakeRecordPlatform(); @@ -170,8 +200,12 @@ Future _pumpThreadPage( when(() => clientState.currentUserStream).thenAnswer((_) => Stream.value(currentUser)); when(() => clientState.totalUnreadCount).thenReturn(0); when(() => clientState.totalUnreadCountStream).thenAnswer((_) => Stream.value(0)); - when(() => clientState.channels).thenReturn({}); - when(() => clientState.channelsStream).thenAnswer((_) => Stream.value({})); + // Keyed by cid so the header's back button can resolve the channel's unread + // count. Without it StreamUnreadIndicator.channels gets a null stream and + // renders nothing, which silently makes the back button untappable. + final channelsById = {channel.cid!: channel}; + when(() => clientState.channels).thenReturn(channelsById); + when(() => clientState.channelsStream).thenAnswer((_) => Stream.value(channelsById)); when(() => channel.client).thenReturn(client); when(() => channel.state).thenReturn(channelState); @@ -206,19 +240,27 @@ Future _pumpThreadPage( when(() => channelState.currentUserRead).thenReturn(null); when(() => channelState.currentUserReadStream).thenAnswer((_) => const Stream.empty()); + final page = StreamThreadPage( + parent: parentMessage, + onViewInChannelTap: onViewInChannelTap, + onBackPressed: onBackPressed, + ); + await tester.pumpWidget( MaterialApp( theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), - home: StreamChat( + // Chat context lives above the navigator so it survives a pop. + builder: (context, child) => StreamChat( client: client, - child: StreamChannel( - channel: channel, - child: StreamThreadPage( - parent: parentMessage, - onViewInChannelTap: onViewInChannelTap, - ), - ), + child: StreamChannel(channel: channel, child: child!), ), + // '/thread' seeds the stack with '/' underneath it, giving the back + // button something to pop to. + initialRoute: pushOntoARoute ? '/thread' : '/', + routes: { + '/': (_) => pushOntoARoute ? const Scaffold(body: SizedBox.shrink()) : page, + '/thread': (_) => page, + }, ), ); diff --git a/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart b/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart index 729142abac..413bbc2840 100644 --- a/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart +++ b/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart @@ -12,45 +12,45 @@ void main() { testWidgets('composer is docked when the app style is regular', (tester) async { await _pumpComposer(tester, appStyle: StreamAppStyle.regular); - expect(_resolvedLocation(tester), ComposerLocation.docked); + expect(_resolvedLocation(tester), StreamComposerLocation.docked); }); testWidgets('composer floats when the app style is floating', (tester) async { await _pumpComposer(tester, appStyle: StreamAppStyle.floating); - expect(_resolvedLocation(tester), ComposerLocation.floating); + expect(_resolvedLocation(tester), StreamComposerLocation.floating); }); testWidgets('the global composer theme overrides the app style', (tester) async { await _pumpComposer( tester, appStyle: StreamAppStyle.regular, - globalTheme: const StreamMessageComposerThemeData(location: ComposerLocation.floating), + globalTheme: const StreamMessageComposerThemeData(location: StreamComposerLocation.floating), ); - expect(_resolvedLocation(tester), ComposerLocation.floating); + expect(_resolvedLocation(tester), StreamComposerLocation.floating); }); testWidgets('a local composer theme overrides the global theme', (tester) async { await _pumpComposer( tester, appStyle: StreamAppStyle.floating, - globalTheme: const StreamMessageComposerThemeData(location: ComposerLocation.floating), - localTheme: const StreamMessageComposerThemeData(location: ComposerLocation.docked), + globalTheme: const StreamMessageComposerThemeData(location: StreamComposerLocation.floating), + localTheme: const StreamMessageComposerThemeData(location: StreamComposerLocation.docked), ); - expect(_resolvedLocation(tester), ComposerLocation.docked); + expect(_resolvedLocation(tester), StreamComposerLocation.docked); }); testWidgets('the location property overrides both the theme and the app style', (tester) async { await _pumpComposer( tester, appStyle: StreamAppStyle.floating, - globalTheme: const StreamMessageComposerThemeData(location: ComposerLocation.floating), - location: ComposerLocation.docked, + globalTheme: const StreamMessageComposerThemeData(location: StreamComposerLocation.floating), + location: StreamComposerLocation.docked, ); - expect(_resolvedLocation(tester), ComposerLocation.docked); + expect(_resolvedLocation(tester), StreamComposerLocation.docked); }); testWidgets('the docked composer fills its background with the elevation-1 color', (tester) async { @@ -101,9 +101,9 @@ void main() { } /// The location the composer resolved, read back from the input it built. -ComposerLocation _resolvedLocation(WidgetTester tester) { +StreamComposerLocation _resolvedLocation(WidgetTester tester) { final input = tester.widget(find.byType(StreamChatMessageInput)); - return input.isFloating ? ComposerLocation.floating : ComposerLocation.docked; + return input.isFloating ? StreamComposerLocation.floating : StreamComposerLocation.docked; } /// Finds the opaque background fill the docked composer paints behind itself. @@ -135,7 +135,7 @@ Future _pumpComposer( required StreamAppStyle appStyle, StreamMessageComposerThemeData? globalTheme, StreamMessageComposerThemeData? localTheme, - ComposerLocation? location, + StreamComposerLocation? location, bool? enableSafeArea, double bottomPadding = 0, }) async { diff --git a/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart b/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart index b5b0a08f9d..b4e0628c6c 100644 --- a/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart +++ b/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart @@ -6,48 +6,48 @@ import '../mocks.dart'; void main() { test('copyWith with no arguments returns an equal MessageComposerThemeData', () { - const themeData = StreamMessageComposerThemeData(location: ComposerLocation.floating); + const themeData = StreamMessageComposerThemeData(location: StreamComposerLocation.floating); expect(themeData.copyWith(), themeData); }); test('copyWith with no arguments preserves the hashCode', () { - const themeData = StreamMessageComposerThemeData(location: ComposerLocation.floating); + const themeData = StreamMessageComposerThemeData(location: StreamComposerLocation.floating); expect(themeData.copyWith().hashCode, themeData.hashCode); }); test('copyWith overrides the location', () { - const docked = StreamMessageComposerThemeData(location: ComposerLocation.docked); + const docked = StreamMessageComposerThemeData(location: StreamComposerLocation.docked); - expect(docked.copyWith(location: ComposerLocation.floating).location, ComposerLocation.floating); + expect(docked.copyWith(location: StreamComposerLocation.floating).location, StreamComposerLocation.floating); }); test('MessageComposerThemeData instances with different locations are not equal', () { expect( - const StreamMessageComposerThemeData(location: ComposerLocation.docked), - isNot(const StreamMessageComposerThemeData(location: ComposerLocation.floating)), + const StreamMessageComposerThemeData(location: StreamComposerLocation.docked), + isNot(const StreamMessageComposerThemeData(location: StreamComposerLocation.floating)), ); }); test('lerp at t = 0 resolves to the start location', () { expect( StreamMessageComposerThemeData.lerp(_dockedTheme, _floatingTheme, 0)?.location, - ComposerLocation.docked, + StreamComposerLocation.docked, ); }); test('lerp below the halfway point resolves to the start location', () { expect( StreamMessageComposerThemeData.lerp(_dockedTheme, _floatingTheme, 0.49)?.location, - ComposerLocation.docked, + StreamComposerLocation.docked, ); }); test('lerp at or past the halfway point resolves to the end location', () { expect( StreamMessageComposerThemeData.lerp(_dockedTheme, _floatingTheme, 0.5)?.location, - ComposerLocation.floating, + StreamComposerLocation.floating, ); }); @@ -76,7 +76,7 @@ void main() { testWidgets('of returns the global theme location when no local theme is present', (tester) async { final context = await _pumpAndCaptureContext(tester, globalTheme: _floatingTheme); - expect(StreamMessageComposerTheme.of(context).location, ComposerLocation.floating); + expect(StreamMessageComposerTheme.of(context).location, StreamComposerLocation.floating); }); testWidgets('of merges the local theme over the global theme', (tester) async { @@ -86,7 +86,7 @@ void main() { localTheme: _floatingTheme, ); - expect(StreamMessageComposerTheme.of(context).location, ComposerLocation.floating); + expect(StreamMessageComposerTheme.of(context).location, StreamComposerLocation.floating); }); testWidgets('of falls back to the global theme when the local theme sets no location', (tester) async { @@ -96,7 +96,7 @@ void main() { localTheme: const StreamMessageComposerThemeData(), ); - expect(StreamMessageComposerTheme.of(context).location, ComposerLocation.floating); + expect(StreamMessageComposerTheme.of(context).location, StreamComposerLocation.floating); }); testWidgets('wrap re-establishes the theme in a detached subtree', (tester) async { @@ -123,7 +123,7 @@ void main() { ), ); - expect(StreamMessageComposerTheme.of(capturedContext).location, ComposerLocation.floating); + expect(StreamMessageComposerTheme.of(capturedContext).location, StreamComposerLocation.floating); }); testWidgets('updateShouldNotify is true when the data changes', (tester) async { @@ -141,8 +141,8 @@ void main() { }); } -const _dockedTheme = StreamMessageComposerThemeData(location: ComposerLocation.docked); -const _floatingTheme = StreamMessageComposerThemeData(location: ComposerLocation.floating); +const _dockedTheme = StreamMessageComposerThemeData(location: StreamComposerLocation.docked); +const _floatingTheme = StreamMessageComposerThemeData(location: StreamComposerLocation.floating); /// Pumps a [StreamChat] configured with [globalTheme], optionally wrapped in a /// local [StreamMessageComposerTheme] carrying [localTheme], and returns a From e3e50b8130ea744c455d52e8cde144751f948e11 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Thu, 30 Jul 2026 18:19:08 +0200 Subject: [PATCH 66/87] improvements on custom attachment picker --- .../message_composer_location_test.dart | 32 +++++++++++-------- .../location_aware_message_composer.dart | 15 +++++++-- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart b/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart index 413bbc2840..b0405b274a 100644 --- a/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart +++ b/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart @@ -171,20 +171,24 @@ Future _pumpComposer( await tester.pumpWidget( MaterialApp( theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), - home: MediaQuery( - data: MediaQueryData(padding: EdgeInsets.only(bottom: bottomPadding)), - child: StreamChat( - client: client, - themeData: StreamChatThemeData(messageComposerTheme: globalTheme), - child: StreamChannel( - channel: channel, - child: Scaffold( - body: Align( - alignment: Alignment.bottomCenter, - child: switch (localTheme) { - final localTheme? => StreamMessageComposerTheme(data: localTheme, child: composer), - _ => composer, - }, + // Overrides only the padding, so the ambient size, text scale and platform + // brightness the test binding provides are preserved. + home: Builder( + builder: (context) => MediaQuery( + data: MediaQuery.of(context).copyWith(padding: EdgeInsets.only(bottom: bottomPadding)), + child: StreamChat( + client: client, + themeData: StreamChatThemeData(messageComposerTheme: globalTheme), + child: StreamChannel( + channel: channel, + child: Scaffold( + body: Align( + alignment: Alignment.bottomCenter, + child: switch (localTheme) { + final localTheme? => StreamMessageComposerTheme(data: localTheme, child: composer), + _ => composer, + }, + ), ), ), ), diff --git a/sample_app/lib/widgets/location/location_aware_message_composer.dart b/sample_app/lib/widgets/location/location_aware_message_composer.dart index 84a45d1022..b3d317c420 100644 --- a/sample_app/lib/widgets/location/location_aware_message_composer.dart +++ b/sample_app/lib/widgets/location/location_aware_message_composer.dart @@ -28,13 +28,22 @@ Widget locationAwareMessageComposer(BuildContext context, MessageComposerProps p return DefaultStreamMessageComposer( props: props.copyWith( + // Appended to what the caller already allowed rather than replacing it, + // so an upstream narrowing of the picker types still holds. The filter + // keeps the list free of duplicates if location was already allowed. allowedAttachmentPickerTypes: [ - ...AttachmentPickerType.values, + ...props.allowedAttachmentPickerTypes.where((it) => it != const LocationPickerType()), const LocationPickerType(), ], - onAttachmentPickerResult: (result) => _onCustomAttachmentPickerResult(channel, result), + // Location results are handled here; anything else falls through to the + // caller's handler so wrapping the composer doesn't swallow their results. + onAttachmentPickerResult: (result) { + if (_onCustomAttachmentPickerResult(channel, result)) return true; + return props.onAttachmentPickerResult?.call(result) ?? false; + }, attachmentPickerOptionsBuilder: (context, defaultOptions) => [ - ...defaultOptions, + // The caller's builder runs first so its options survive too. + ...(props.attachmentPickerOptionsBuilder?.call(context, defaultOptions) ?? defaultOptions), TabbedAttachmentPickerOption( key: 'location-picker', title: 'Location', From bd3c0a2ef93cbf898175d7905e88929fd29892ba Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 31 Jul 2026 10:08:05 +0200 Subject: [PATCH 67/87] fix test mocks --- .../test/src/channel/channel_page_test.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart b/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart index e317fb5d78..bb7edfa5b9 100644 --- a/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart @@ -203,6 +203,9 @@ Future _pumpChannelPage( when(() => clientState.currentUserStream).thenAnswer((_) => Stream.value(currentUser)); when(() => clientState.totalUnreadCount).thenReturn(0); when(() => clientState.totalUnreadCountStream).thenAnswer((_) => Stream.value(0)); + // Keyed by cid so the header's back button can resolve the open channel's + // unread count and exclude it from the total. + when(() => clientState.channels).thenReturn({channel.cid!: channel}); when(() => channel.client).thenReturn(client); when(() => channel.state).thenReturn(channelState); @@ -224,6 +227,7 @@ Future _pumpChannelPage( when(() => channelState.threadsStream).thenAnswer((_) => const Stream.empty()); when(() => channelState.draft).thenReturn(null); when(() => channelState.isUpToDateStream).thenAnswer((_) => Stream.value(true)); + when(() => channelState.unreadCount).thenReturn(0); when(() => channelState.unreadCountStream).thenAnswer((_) => Stream.value(0)); when(() => channelState.readStream).thenAnswer((_) => Stream.value([])); when(() => channelState.currentUserRead).thenReturn(null); From da535fb975a16676dc92280bc050fafba888801b Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 31 Jul 2026 10:18:32 +0200 Subject: [PATCH 68/87] Simplify back buttons in new pages --- packages/stream_chat_flutter/CHANGELOG.md | 1 + .../lib/src/channel/channel_header.dart | 8 +++ .../lib/src/channel/channel_page.dart | 9 +-- .../lib/src/channel/thread_page.dart | 15 +---- .../lib/src/misc/thread_header.dart | 9 ++- .../test/src/channel/channel_header_test.dart | 56 +++++++++++++++++++ .../test/src/misc/thread_header_test.dart | 55 ++++++++++++++++++ 7 files changed, 134 insertions(+), 19 deletions(-) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 251d9967fa..2c28fa9e39 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -9,6 +9,7 @@ - Added `StreamChannelPage` — a ready-to-use channel page widget that wires up `StreamChannelHeader`, `StreamMessageListView`, and `StreamMessageComposer` with floating or docked layout driven by the active app style. - Added `StreamThreadPage` — a ready-to-use thread page widget with the same floating/docked layout support, plus an `onBackPressed` callback that replaces the header back button's default pop. +- Added `onBackPressed` to `StreamChannelHeader` and `StreamThreadHeader` — replaces the default back button's `Navigator.maybePop` without rebuilding the whole `leading`, so callers keep the header's default unread badge. Ignored when `leading` is supplied. - Added `StreamComposerLocation` and `MessageComposerProps.location` — explicitly controls whether `StreamMessageComposer` renders `floating` or `docked`. When null it falls back to `StreamMessageComposerThemeData.location`, and then to the ambient `StreamAppStyle`. - Added `StreamMessageComposerTheme` and `StreamMessageComposerThemeData` — a component theme for the composer, also available globally as `StreamChatThemeData.messageComposerTheme`. - Added `StreamMessageListView.config` — accepts an explicit `StreamMessageListViewConfiguration` per widget; falls back to `StreamChatConfigurationData.messageListViewConfiguration` from the nearest ancestor when omitted. diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index 4d6a7ba62b..710b39da08 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -77,6 +77,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget this.showConnectionStateTile = false, this.leading, this.automaticallyImplyLeading = true, + this.onBackPressed, this.title, this.subtitle, this.trailing, @@ -105,6 +106,12 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget /// Defaults to `true`. Set to `false` to suppress the back button. final bool automaticallyImplyLeading; + /// Called when the default [StreamBackButton] is pressed, replacing its + /// default `Navigator.maybePop`. + /// + /// Ignored when [leading] is provided. + final VoidCallback? onBackPressed; + /// {@macro StreamAppBar.title} /// /// Defaults to a [StreamChannelName] for the enclosing channel. @@ -141,6 +148,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget var leading = this.leading; if (leading == null && automaticallyImplyLeading) { leading = StreamBackButton( + onPressed: onBackPressed, unreadIndicator: StreamUnreadIndicator(excludeCid: channel.cid), ); } diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index f9b9c02fcb..58ac5880dd 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -113,12 +113,9 @@ class _StreamChannelPageState extends State { @override Widget build(BuildContext context) { final appBar = StreamChannelHeader( - // Leaving this null keeps the header's own default back button, which - // pops the route. - leading: switch (widget.onBackPressed) { - final onBackPressed? => StreamBackButton(onPressed: onBackPressed, showUnreadCount: true), - _ => null, - }, + // Leaving this null keeps the header's default back button, which pops + // the route. + onBackPressed: widget.onBackPressed, onChannelAvatarPressed: (channel) => widget.onChannelAvatarPressed?.call(context, channel), ); diff --git a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart index 6e50b3cd65..6ecfbc881c 100644 --- a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart @@ -87,20 +87,11 @@ class _StreamThreadPageState extends State { @override Widget build(BuildContext context) { - final channel = StreamChannel.maybeOf(context)?.channel; - final appBar = StreamThreadHeader( parent: widget.parent, - // Leaving this null keeps the header's own default back button, which - // pops the route. - leading: switch (widget.onBackPressed) { - final onBackPressed? => StreamBackButton( - onPressed: onBackPressed, - channelId: channel?.cid, - showUnreadCount: true, - ), - _ => null, - }, + // Leaving this null keeps the header's default back button, which pops + // the route. + onBackPressed: widget.onBackPressed, ); final composer = !widget.parent.isDeleted diff --git a/packages/stream_chat_flutter/lib/src/misc/thread_header.dart b/packages/stream_chat_flutter/lib/src/misc/thread_header.dart index 27501123e4..42da929af8 100644 --- a/packages/stream_chat_flutter/lib/src/misc/thread_header.dart +++ b/packages/stream_chat_flutter/lib/src/misc/thread_header.dart @@ -22,6 +22,7 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget required this.parent, this.leading, this.automaticallyImplyLeading = true, + this.onBackPressed, this.title, this.subtitle, this.trailing, @@ -38,6 +39,12 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget /// {@macro StreamAppBar.automaticallyImplyLeading} final bool automaticallyImplyLeading; + /// Called when the default [StreamBackButton] is pressed, replacing its + /// default `Navigator.maybePop`. + /// + /// Ignored when [leading] is provided. + final VoidCallback? onBackPressed; + /// {@macro StreamAppBar.title} /// /// Defaults to the localized "Thread reply" label. @@ -75,7 +82,7 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget final cid? => StreamUnreadIndicator.channels(cid: cid), null => const StreamUnreadIndicator(), }; - leading = StreamBackButton(unreadIndicator: unreadIndicator); + leading = StreamBackButton(onPressed: onBackPressed, unreadIndicator: unreadIndicator); } Widget? fallbackSubtitle; diff --git a/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart b/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart index 591ecbae97..14ef0ffecf 100644 --- a/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart @@ -445,6 +445,62 @@ void main() { }, ); + testWidgets( + 'onBackPressed replaces the default back button pop', + (WidgetTester tester) async { + final client = MockClient(); + final clientState = MockClientState(); + final channel = MockChannel(); + final channelState = MockChannelState(); + final user = OwnUser(id: 'user-id'); + + when(() => client.state).thenReturn(clientState); + when(() => clientState.currentUser).thenReturn(user); + when(() => clientState.currentUserStream).thenAnswer((_) => Stream.value(user)); + when(() => clientState.totalUnreadCount).thenReturn(0); + when(() => clientState.totalUnreadCountStream).thenAnswer((_) => Stream.value(0)); + when(() => clientState.channels).thenReturn({channel.cid!: channel}); + when(() => client.wsConnectionStatusStream).thenAnswer((_) => Stream.value(ConnectionStatus.connected)); + + when(() => channel.client).thenReturn(client); + when(() => channel.state).thenReturn(channelState); + when(() => channel.lastMessageAt).thenReturn(null); + when(() => channel.name).thenReturn('test'); + when(() => channel.nameStream).thenAnswer((_) => Stream.value('test')); + when(() => channel.image).thenReturn(null); + when(() => channel.imageStream).thenAnswer((_) => Stream.value(null)); + when(() => channel.isMuted).thenReturn(false); + when(() => channel.isMutedStream).thenAnswer((_) => Stream.value(false)); + + when(() => channelState.members).thenReturn([]); + when(() => channelState.membersStream).thenAnswer((_) => Stream.value([])); + when(() => channelState.unreadCount).thenReturn(0); + when(() => channelState.unreadCountStream).thenAnswer((_) => Stream.value(0)); + + var backPressed = false; + + await tester.pumpWidget( + MaterialApp( + home: StreamChat( + client: client, + child: StreamChannel( + channel: channel, + child: Scaffold( + body: StreamChannelHeader(onBackPressed: () => backPressed = true), + ), + ), + ), + ), + ); + + await tester.pumpAndSettle(); + + await tester.tap(find.byType(StreamBackButton)); + + expect(backPressed, true); + }, + ); + group('default slot floating behavior', () { // The header installs its own StreamAppBarTheme around the bar, so both // default slots have to resolve from inside it — otherwise diff --git a/packages/stream_chat_flutter/test/src/misc/thread_header_test.dart b/packages/stream_chat_flutter/test/src/misc/thread_header_test.dart index a51b819aab..199bd5938d 100644 --- a/packages/stream_chat_flutter/test/src/misc/thread_header_test.dart +++ b/packages/stream_chat_flutter/test/src/misc/thread_header_test.dart @@ -71,6 +71,61 @@ void main() { }, ); + testWidgets( + 'onBackPressed replaces the default back button pop', + (WidgetTester tester) async { + final client = MockClient(); + final clientState = MockClientState(); + final channel = MockChannel(); + final channelState = MockChannelState(); + + when(() => client.state).thenReturn(clientState); + when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); + when(() => clientState.channels).thenReturn({channel.cid!: channel}); + when(() => clientState.totalUnreadCount).thenReturn(0); + when(() => clientState.totalUnreadCountStream).thenAnswer((_) => Stream.value(0)); + when(() => client.wsConnectionStatusStream).thenAnswer((_) => Stream.value(ConnectionStatus.connected)); + + when(() => channel.state).thenReturn(channelState); + when(() => channel.client).thenReturn(client); + when(() => channel.lastMessageAt).thenReturn(null); + when(() => channel.isMuted).thenReturn(false); + when(() => channel.isMutedStream).thenAnswer((_) => Stream.value(false)); + when(() => channel.name).thenReturn('test'); + when(() => channel.nameStream).thenAnswer((_) => Stream.value('test')); + + when(() => channelState.members).thenReturn([]); + when(() => channelState.membersStream).thenAnswer((_) => Stream.value([])); + when(() => channelState.unreadCount).thenReturn(0); + when(() => channelState.unreadCountStream).thenAnswer((_) => Stream.value(0)); + + var backPressed = false; + + await tester.pumpWidget( + MaterialApp( + home: StreamChat( + client: client, + child: StreamChannel( + channel: channel, + child: Scaffold( + body: StreamThreadHeader( + parent: Message(replyCount: 1), + onBackPressed: () => backPressed = true, + ), + ), + ), + ), + ), + ); + + await tester.pumpAndSettle(); + + await tester.tap(find.byType(StreamBackButton)); + + expect(backPressed, true); + }, + ); + testWidgets( 'it should apply passed props', (WidgetTester tester) async { From 217be1a4ee7b52d00595913ab8b0e80468a5ac44 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Tue, 4 Aug 2026 10:21:48 +0200 Subject: [PATCH 69/87] Minor PR improvements --- packages/stream_chat_flutter/CHANGELOG.md | 4 +- .../lib/src/channel/channel_page.dart | 4 +- .../lib/src/channel/thread_page.dart | 2 +- .../stream_message_composer.dart | 100 +++++++++--------- .../lib/src/misc/back_button.dart | 13 +-- .../lib/src/theme/message_composer_theme.dart | 42 ++++---- .../theme/message_composer_theme.g.theme.dart | 14 +-- .../lib/src/utils/app_bar_behavior.dart | 3 +- ...rt => message_composer_behavior_test.dart} | 38 +++---- .../theme/message_composer_theme_test.dart | 79 +++++++------- sample_app/lib/app.dart | 6 +- sample_app/lib/config/sample_app_config.dart | 23 +--- .../lib/config/sample_app_config_screen.dart | 10 +- 13 files changed, 163 insertions(+), 175 deletions(-) rename packages/stream_chat_flutter/test/src/message_input/{message_composer_location_test.dart => message_composer_behavior_test.dart} (80%) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 2c28fa9e39..614e9a1b83 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -10,11 +10,11 @@ - Added `StreamChannelPage` — a ready-to-use channel page widget that wires up `StreamChannelHeader`, `StreamMessageListView`, and `StreamMessageComposer` with floating or docked layout driven by the active app style. - Added `StreamThreadPage` — a ready-to-use thread page widget with the same floating/docked layout support, plus an `onBackPressed` callback that replaces the header back button's default pop. - Added `onBackPressed` to `StreamChannelHeader` and `StreamThreadHeader` — replaces the default back button's `Navigator.maybePop` without rebuilding the whole `leading`, so callers keep the header's default unread badge. Ignored when `leading` is supplied. -- Added `StreamComposerLocation` and `MessageComposerProps.location` — explicitly controls whether `StreamMessageComposer` renders `floating` or `docked`. When null it falls back to `StreamMessageComposerThemeData.location`, and then to the ambient `StreamAppStyle`. +- Added `StreamMessageComposerBehavior` and `MessageComposerProps.behavior` — explicitly controls whether `StreamMessageComposer` renders `floating` or `regular`. When null it falls back to `StreamMessageComposerThemeData.behavior`, and then to the ambient `StreamAppStyle`. - Added `StreamMessageComposerTheme` and `StreamMessageComposerThemeData` — a component theme for the composer, also available globally as `StreamChatThemeData.messageComposerTheme`. - Added `StreamMessageListView.config` — accepts an explicit `StreamMessageListViewConfiguration` per widget; falls back to `StreamChatConfigurationData.messageListViewConfiguration` from the nearest ancestor when omitted. - Added `StreamMessageListView.topPadding` and `bottomPadding` — padding applied to the scroll view's top and bottom edges, used by floating app bar / composer layouts to keep messages visible without an extra `setState`. -- Added an `appBarBehavior` parameter to `StreamBackButton`, controlling floating vs pinned back-button appearance. Falls back to `StreamAppBarTheme`, and then to the ambient `StreamAppStyle`, when null. `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamThreadHeader` now merge their `style` into the `StreamAppBarTheme` they install, so every slot in the bar — the default avatar's drop shadow, the default back button, and any `leading`/`trailing` the caller supplies — resolves the same chain the bar itself uses: `style`, then the per-header theme (`channelHeaderTheme` / `channelListHeaderTheme` / `threadHeaderTheme`), then `StreamAppBarTheme`, then `StreamAppStyle`. +- Added an `isFloating` parameter to `StreamBackButton`, controlling floating vs pinned back-button appearance. Falls back to `StreamAppBarTheme`, and then to the ambient `StreamAppStyle`, when null. `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamThreadHeader` now merge their `style` into the `StreamAppBarTheme` they install, so every slot in the bar — the default avatar's drop shadow, the default back button, and any `leading`/`trailing` the caller supplies — resolves the same chain the bar itself uses: `style`, then the per-header theme (`channelHeaderTheme` / `channelListHeaderTheme` / `threadHeaderTheme`), then `StreamAppBarTheme`, then `StreamAppStyle`. - Added `messageListViewConfiguration` field to `StreamChatConfigurationData`, allowing a global `StreamMessageListViewConfiguration` default for all `StreamMessageListView` widgets. Pass it via `StreamChat.configData` to configure behaviors like `swipeToReply` and `highlightInitialMessage` app-wide without wiring them per-page. - Re-exported `StreamScaffold`, `StreamScaffoldInsets`, `StreamBottomNavBar`, `StreamBottomNavBarItem`, `StreamAppStyle`, `StreamAppBarBehavior`, `StreamBottomAppBarBehavior`, and `streamFloatingFadeLinearGradient` from `stream_core_flutter` via `package:stream_chat_flutter/stream_chat_flutter.dart`. - Added `StreamMessageListViewConfiguration.autoScrollPolicy` to control whether and how `StreamMessageListView` scrolls to the newest message when a new message arrives. Use `StreamAutoScrollPolicy.disabled` to fully control scrolling yourself. diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart index 58ac5880dd..e0ca75360b 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_page.dart @@ -4,7 +4,7 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// A channel page with optional floating composer support. /// /// Wires up a [StreamChannelHeader], a [StreamMessageListView] and a -/// [StreamMessageComposer], laid out floating or docked according to the ambient +/// [StreamMessageComposer], laid out floating or regular according to the ambient /// [StreamAppStyle]. Expects a [StreamChannel] ancestor. /// /// ## Customizing this page @@ -154,7 +154,7 @@ class _StreamChannelPageState extends State { /// /// Reads [StreamScaffoldInsets] to provide correct [topPadding] and /// [bottomPadding] to [StreamMessageListView], and positions the typing -/// indicator just above the composer (floating or docked) using the same +/// indicator just above the composer (floating or regular) using the same /// inset values. class _ChannelPageBody extends StatelessWidget { const _ChannelPageBody({ diff --git a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart index 6ecfbc881c..f12c1d7b67 100644 --- a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart +++ b/packages/stream_chat_flutter/lib/src/channel/thread_page.dart @@ -5,7 +5,7 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// /// Wires up a [StreamThreadHeader], a [StreamMessageListView] scoped to [parent] /// and a [StreamMessageComposer] that addresses new messages to the thread, laid -/// out floating or docked according to the ambient [StreamAppStyle]. Expects a +/// out floating or regular according to the ambient [StreamAppStyle]. Expects a /// [StreamChannel] ancestor. /// /// The composer is omitted when [parent] is deleted. diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 585a1c2919..b388c20195 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -101,7 +101,7 @@ class StreamMessageComposer extends StatelessWidget { TextCapitalization textCapitalization = TextCapitalization.sentences, bool autofocus = false, bool autoCorrect = true, - StreamComposerLocation? location, + StreamMessageComposerBehavior? behavior, }) : props = .new( onMessageSent: onMessageSent, preMessageSending: preMessageSending, @@ -139,7 +139,7 @@ class StreamMessageComposer extends StatelessWidget { textCapitalization: textCapitalization, autofocus: autofocus, autoCorrect: autoCorrect, - location: location, + behavior: behavior, ); /// Creates a [StreamMessageComposer] from a pre-built [MessageComposerProps]. @@ -201,7 +201,7 @@ class MessageComposerProps { this.textCapitalization = TextCapitalization.sentences, this.autofocus = false, this.autoCorrect = true, - this.location, + this.behavior, }); /// Function called after sending the message. @@ -411,8 +411,8 @@ class MessageComposerProps { /// Defaults to true. final bool autoCorrect; - /// The location of the message composer. - final StreamComposerLocation? location; + /// The behavior of the message composer. + final StreamMessageComposerBehavior? behavior; /// Returns a copy of this [MessageComposerProps] with the given fields /// replaced with new values. @@ -452,7 +452,7 @@ class MessageComposerProps { TextCapitalization? textCapitalization, bool? autofocus, bool? autoCorrect, - StreamComposerLocation? location, + StreamMessageComposerBehavior? behavior, }) { return MessageComposerProps( onMessageSent: onMessageSent ?? this.onMessageSent, @@ -490,7 +490,7 @@ class MessageComposerProps { textCapitalization: textCapitalization ?? this.textCapitalization, autofocus: autofocus ?? this.autofocus, autoCorrect: autoCorrect ?? this.autoCorrect, - location: location ?? this.location, + behavior: behavior ?? this.behavior, ); } @@ -834,7 +834,7 @@ class DefaultStreamMessageComposerState extends State composerBody, - .docked => DecoratedBox( + .regular => DecoratedBox( decoration: BoxDecoration(color: colorScheme.backgroundElevation1), child: composerBody, ), @@ -990,13 +990,13 @@ class DefaultStreamMessageComposerState extends State _pillHeight.value = height, child: pill) else pill, + SizeTransition( + sizeFactor: _pickerAnimation, + // ignore: deprecated_member_use, alternative is only available since Flutter 3.44 + axisAlignment: -1, + child: _buildInlineAttachmentPicker(context), + ), ], ), ); @@ -1095,31 +1091,31 @@ class DefaultStreamMessageComposerState extends State context.streamIcons.chevronLeft, _ => context.streamIcons.arrowLeft, }; - final isFloating = isFloatingAppBar(context, override: appBarBehavior); + final isFloating = this.isFloating ?? isFloatingAppBar(context); Widget button = StreamButton.icon( type: isFloating ? .outline : .ghost, diff --git a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart index 31c6da8025..1a259c6012 100644 --- a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart @@ -4,31 +4,35 @@ import 'package:theme_extensions_builder_annotation/theme_extensions_builder_ann part 'message_composer_theme.g.theme.dart'; -/// The placement of the message composer — floating above the keyboard or -/// docked at the bottom edge of the screen. +/// The message composer's visual/layout behavior — floating above the keyboard +/// or docked at the bottom edge of the screen. +/// +/// Mirrors [StreamAppBarBehavior] and [StreamBottomAppBarBehavior] so every +/// component names its placement the same way. /// /// When null on [StreamMessageComposerThemeData], the ambient [StreamAppStyle] /// is used as a fallback — [StreamAppStyle.floating] maps to [floating] and -/// [StreamAppStyle.regular] maps to [docked]. +/// [StreamAppStyle.regular] maps to [regular]. /// /// See also: /// -/// * [StreamMessageComposerThemeData.location], which carries this +/// * [StreamMessageComposerThemeData.behavior], which carries this /// value. /// * [StreamAppStyle], the global app-wide style that acts as fallback. -enum StreamComposerLocation { +enum StreamMessageComposerBehavior { + /// The composer sits within the layout flow, docked at the bottom edge of + /// the screen. + regular, + /// The composer floats above the on-screen keyboard with appropriate safe /// area padding. floating, - - /// The composer is docked at the bottom edge of the screen. - docked, } /// Applies a message composer theme to descendant composer widgets. /// /// Wrap a subtree with [StreamMessageComposerTheme] to override the composer -/// location. Access the merged theme using [StreamMessageComposerTheme.of]. +/// behavior. Access the merged theme using [StreamMessageComposerTheme.of]. /// /// {@tool snippet} /// @@ -37,7 +41,7 @@ enum StreamComposerLocation { /// ```dart /// StreamMessageComposerTheme( /// data: StreamMessageComposerThemeData( -/// location: StreamComposerLocation.floating, +/// behavior: StreamMessageComposerBehavior.floating, /// ), /// child: StreamChannel( /// channel: channel, @@ -50,7 +54,7 @@ enum StreamComposerLocation { /// See also: /// /// * [StreamMessageComposerThemeData], which describes the theme data. -/// * [StreamMessageComposerThemeData.location], the setting it holds. +/// * [StreamMessageComposerThemeData.behavior], the setting it holds. class StreamMessageComposerTheme extends InheritedTheme { /// Creates a message composer theme that controls descendant composers. const StreamMessageComposerTheme({ @@ -69,7 +73,7 @@ class StreamMessageComposerTheme extends InheritedTheme { /// precedence over global values from [StreamChatTheme.of]. /// /// This allows partial overrides — for example, overriding only - /// [StreamMessageComposerThemeData.location] in a subtree while + /// [StreamMessageComposerThemeData.behavior] in a subtree while /// inheriting other properties from the global theme. static StreamMessageComposerThemeData of(BuildContext context) { final localTheme = context.dependOnInheritedWidgetOfExactType(); @@ -95,7 +99,7 @@ class StreamMessageComposerTheme extends InheritedTheme { /// ```dart /// StreamChatThemeData( /// messageComposerTheme: StreamMessageComposerThemeData( -/// location: StreamComposerLocation.floating, +/// behavior: StreamMessageComposerBehavior.floating, /// ), /// ) /// ``` @@ -103,23 +107,23 @@ class StreamMessageComposerTheme extends InheritedTheme { /// /// See also: /// -/// * [StreamComposerLocation], the enum that describes the placement options. +/// * [StreamMessageComposerBehavior], the enum that describes the placement options. /// * [StreamMessageComposerTheme], for overriding the theme in a subtree. @themeGen @immutable class StreamMessageComposerThemeData with _$StreamMessageComposerThemeData { /// Creates message composer theme data with optional overrides. - const StreamMessageComposerThemeData({this.location}); + const StreamMessageComposerThemeData({this.behavior}); - /// The placement of the message composer. + /// The visual/layout behavior of the message composer. /// /// When null the value falls back to the ambient [StreamAppStyle]: - /// [StreamAppStyle.floating] → [StreamComposerLocation.floating], - /// [StreamAppStyle.regular] → [StreamComposerLocation.docked]. + /// [StreamAppStyle.floating] → [StreamMessageComposerBehavior.floating], + /// [StreamAppStyle.regular] → [StreamMessageComposerBehavior.regular]. /// /// Set this to override the global style for the composer only, without /// affecting other components. - final StreamComposerLocation? location; + final StreamMessageComposerBehavior? behavior; /// Linearly interpolate between two [StreamMessageComposerThemeData] objects. static StreamMessageComposerThemeData? lerp( diff --git a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart index 3e4243e602..25f94550a6 100644 --- a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart @@ -30,14 +30,16 @@ mixin _$StreamMessageComposerThemeData { } return StreamMessageComposerThemeData( - location: t < 0.5 ? a.location : b.location, + behavior: t < 0.5 ? a.behavior : b.behavior, ); } - StreamMessageComposerThemeData copyWith({StreamComposerLocation? location}) { + StreamMessageComposerThemeData copyWith({ + StreamMessageComposerBehavior? behavior, + }) { final _this = (this as StreamMessageComposerThemeData); - return StreamMessageComposerThemeData(location: location ?? _this.location); + return StreamMessageComposerThemeData(behavior: behavior ?? _this.behavior); } StreamMessageComposerThemeData merge(StreamMessageComposerThemeData? other) { @@ -51,7 +53,7 @@ mixin _$StreamMessageComposerThemeData { return other; } - return copyWith(location: other.location); + return copyWith(behavior: other.behavior); } @override @@ -67,13 +69,13 @@ mixin _$StreamMessageComposerThemeData { final _this = (this as StreamMessageComposerThemeData); final _other = (other as StreamMessageComposerThemeData); - return _other.location == _this.location; + return _other.behavior == _this.behavior; } @override int get hashCode { final _this = (this as StreamMessageComposerThemeData); - return Object.hash(runtimeType, _this.location); + return Object.hash(runtimeType, _this.behavior); } } diff --git a/packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart b/packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart index 0114efb1f0..50d8e7a671 100644 --- a/packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart +++ b/packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart @@ -6,8 +6,7 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Precedence, highest first: /// /// 1. [override] — a widget-local value, such as -/// [StreamAppBarStyle.behavior] passed to a header or -/// [StreamBackButton.appBarBehavior]. +/// [StreamAppBarStyle.behavior] passed to a header. /// 2. [StreamAppBarStyle.behavior] from the ambient [StreamAppBarTheme]. /// 3. The ambient [StreamAppStyle] — [StreamAppStyle.floating] maps to /// [StreamAppBarBehavior.floating], [StreamAppStyle.regular] to diff --git a/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart b/packages/stream_chat_flutter/test/src/message_input/message_composer_behavior_test.dart similarity index 80% rename from packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart rename to packages/stream_chat_flutter/test/src/message_input/message_composer_behavior_test.dart index b0405b274a..1cf498e6b7 100644 --- a/packages/stream_chat_flutter/test/src/message_input/message_composer_location_test.dart +++ b/packages/stream_chat_flutter/test/src/message_input/message_composer_behavior_test.dart @@ -9,51 +9,51 @@ import '../fakes.dart'; import '../mocks.dart'; void main() { - testWidgets('composer is docked when the app style is regular', (tester) async { + testWidgets('composer is regular when the app style is regular', (tester) async { await _pumpComposer(tester, appStyle: StreamAppStyle.regular); - expect(_resolvedLocation(tester), StreamComposerLocation.docked); + expect(_resolvedBehavior(tester), StreamMessageComposerBehavior.regular); }); testWidgets('composer floats when the app style is floating', (tester) async { await _pumpComposer(tester, appStyle: StreamAppStyle.floating); - expect(_resolvedLocation(tester), StreamComposerLocation.floating); + expect(_resolvedBehavior(tester), StreamMessageComposerBehavior.floating); }); testWidgets('the global composer theme overrides the app style', (tester) async { await _pumpComposer( tester, appStyle: StreamAppStyle.regular, - globalTheme: const StreamMessageComposerThemeData(location: StreamComposerLocation.floating), + globalTheme: const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating), ); - expect(_resolvedLocation(tester), StreamComposerLocation.floating); + expect(_resolvedBehavior(tester), StreamMessageComposerBehavior.floating); }); testWidgets('a local composer theme overrides the global theme', (tester) async { await _pumpComposer( tester, appStyle: StreamAppStyle.floating, - globalTheme: const StreamMessageComposerThemeData(location: StreamComposerLocation.floating), - localTheme: const StreamMessageComposerThemeData(location: StreamComposerLocation.docked), + globalTheme: const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating), + localTheme: const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.regular), ); - expect(_resolvedLocation(tester), StreamComposerLocation.docked); + expect(_resolvedBehavior(tester), StreamMessageComposerBehavior.regular); }); - testWidgets('the location property overrides both the theme and the app style', (tester) async { + testWidgets('the behavior property overrides both the theme and the app style', (tester) async { await _pumpComposer( tester, appStyle: StreamAppStyle.floating, - globalTheme: const StreamMessageComposerThemeData(location: StreamComposerLocation.floating), - location: StreamComposerLocation.docked, + globalTheme: const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating), + behavior: StreamMessageComposerBehavior.regular, ); - expect(_resolvedLocation(tester), StreamComposerLocation.docked); + expect(_resolvedBehavior(tester), StreamMessageComposerBehavior.regular); }); - testWidgets('the docked composer fills its background with the elevation-1 color', (tester) async { + testWidgets('the regular composer fills its background with the elevation-1 color', (tester) async { await _pumpComposer(tester, appStyle: StreamAppStyle.regular); expect(_backgroundFillFinder(tester), findsOneWidget); @@ -100,13 +100,13 @@ void main() { }); } -/// The location the composer resolved, read back from the input it built. -StreamComposerLocation _resolvedLocation(WidgetTester tester) { +/// The behavior the composer resolved, read back from the input it built. +StreamMessageComposerBehavior _resolvedBehavior(WidgetTester tester) { final input = tester.widget(find.byType(StreamChatMessageInput)); - return input.isFloating ? StreamComposerLocation.floating : StreamComposerLocation.docked; + return input.isFloating ? StreamMessageComposerBehavior.floating : StreamMessageComposerBehavior.regular; } -/// Finds the opaque background fill the docked composer paints behind itself. +/// Finds the opaque background fill the regular composer paints behind itself. Finder _backgroundFillFinder(WidgetTester tester) { final context = tester.element(find.byType(StreamChatMessageInput)); final fill = BoxDecoration(color: context.streamColorScheme.backgroundElevation1); @@ -135,7 +135,7 @@ Future _pumpComposer( required StreamAppStyle appStyle, StreamMessageComposerThemeData? globalTheme, StreamMessageComposerThemeData? localTheme, - StreamComposerLocation? location, + StreamMessageComposerBehavior? behavior, bool? enableSafeArea, double bottomPadding = 0, }) async { @@ -164,7 +164,7 @@ Future _pumpComposer( when(() => channelState.draft).thenReturn(null); final composer = StreamMessageComposer( - location: location, + behavior: behavior, enableSafeArea: enableSafeArea, ); diff --git a/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart b/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart index b4e0628c6c..6faa545847 100644 --- a/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart +++ b/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart @@ -6,97 +6,100 @@ import '../mocks.dart'; void main() { test('copyWith with no arguments returns an equal MessageComposerThemeData', () { - const themeData = StreamMessageComposerThemeData(location: StreamComposerLocation.floating); + const themeData = StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating); expect(themeData.copyWith(), themeData); }); test('copyWith with no arguments preserves the hashCode', () { - const themeData = StreamMessageComposerThemeData(location: StreamComposerLocation.floating); + const themeData = StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating); expect(themeData.copyWith().hashCode, themeData.hashCode); }); - test('copyWith overrides the location', () { - const docked = StreamMessageComposerThemeData(location: StreamComposerLocation.docked); + test('copyWith overrides the behavior', () { + const regular = StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.regular); - expect(docked.copyWith(location: StreamComposerLocation.floating).location, StreamComposerLocation.floating); + expect( + regular.copyWith(behavior: StreamMessageComposerBehavior.floating).behavior, + StreamMessageComposerBehavior.floating, + ); }); - test('MessageComposerThemeData instances with different locations are not equal', () { + test('MessageComposerThemeData instances with different behaviors are not equal', () { expect( - const StreamMessageComposerThemeData(location: StreamComposerLocation.docked), - isNot(const StreamMessageComposerThemeData(location: StreamComposerLocation.floating)), + const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.regular), + isNot(const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating)), ); }); - test('lerp at t = 0 resolves to the start location', () { + test('lerp at t = 0 resolves to the start behavior', () { expect( - StreamMessageComposerThemeData.lerp(_dockedTheme, _floatingTheme, 0)?.location, - StreamComposerLocation.docked, + StreamMessageComposerThemeData.lerp(_regularTheme, _floatingTheme, 0)?.behavior, + StreamMessageComposerBehavior.regular, ); }); - test('lerp below the halfway point resolves to the start location', () { + test('lerp below the halfway point resolves to the start behavior', () { expect( - StreamMessageComposerThemeData.lerp(_dockedTheme, _floatingTheme, 0.49)?.location, - StreamComposerLocation.docked, + StreamMessageComposerThemeData.lerp(_regularTheme, _floatingTheme, 0.49)?.behavior, + StreamMessageComposerBehavior.regular, ); }); - test('lerp at or past the halfway point resolves to the end location', () { + test('lerp at or past the halfway point resolves to the end behavior', () { expect( - StreamMessageComposerThemeData.lerp(_dockedTheme, _floatingTheme, 0.5)?.location, - StreamComposerLocation.floating, + StreamMessageComposerThemeData.lerp(_regularTheme, _floatingTheme, 0.5)?.behavior, + StreamMessageComposerBehavior.floating, ); }); - test('lerp at t = 1 resolves to the end location', () { - expect(StreamMessageComposerThemeData.lerp(_dockedTheme, _floatingTheme, 1), _floatingTheme); + test('lerp at t = 1 resolves to the end behavior', () { + expect(StreamMessageComposerThemeData.lerp(_regularTheme, _floatingTheme, 1), _floatingTheme); }); - test('merge with null keeps the original location', () { - expect(_dockedTheme.merge(null), _dockedTheme); + test('merge with null keeps the original behavior', () { + expect(_regularTheme.merge(null), _regularTheme); }); - test('merge overrides the location with the other theme', () { - expect(_dockedTheme.merge(_floatingTheme), _floatingTheme); + test('merge overrides the behavior with the other theme', () { + expect(_regularTheme.merge(_floatingTheme), _floatingTheme); }); - test('merge with an empty theme keeps the original location', () { + test('merge with an empty theme keeps the original behavior', () { expect(_floatingTheme.merge(const StreamMessageComposerThemeData()), _floatingTheme); }); - testWidgets('of returns a null location when no theme is configured', (tester) async { + testWidgets('of returns a null behavior when no theme is configured', (tester) async { final context = await _pumpAndCaptureContext(tester); - expect(StreamMessageComposerTheme.of(context).location, isNull); + expect(StreamMessageComposerTheme.of(context).behavior, isNull); }); - testWidgets('of returns the global theme location when no local theme is present', (tester) async { + testWidgets('of returns the global theme behavior when no local theme is present', (tester) async { final context = await _pumpAndCaptureContext(tester, globalTheme: _floatingTheme); - expect(StreamMessageComposerTheme.of(context).location, StreamComposerLocation.floating); + expect(StreamMessageComposerTheme.of(context).behavior, StreamMessageComposerBehavior.floating); }); testWidgets('of merges the local theme over the global theme', (tester) async { final context = await _pumpAndCaptureContext( tester, - globalTheme: _dockedTheme, + globalTheme: _regularTheme, localTheme: _floatingTheme, ); - expect(StreamMessageComposerTheme.of(context).location, StreamComposerLocation.floating); + expect(StreamMessageComposerTheme.of(context).behavior, StreamMessageComposerBehavior.floating); }); - testWidgets('of falls back to the global theme when the local theme sets no location', (tester) async { + testWidgets('of falls back to the global theme when the local theme sets no behavior', (tester) async { final context = await _pumpAndCaptureContext( tester, globalTheme: _floatingTheme, localTheme: const StreamMessageComposerThemeData(), ); - expect(StreamMessageComposerTheme.of(context).location, StreamComposerLocation.floating); + expect(StreamMessageComposerTheme.of(context).behavior, StreamMessageComposerBehavior.floating); }); testWidgets('wrap re-establishes the theme in a detached subtree', (tester) async { @@ -123,26 +126,26 @@ void main() { ), ); - expect(StreamMessageComposerTheme.of(capturedContext).location, StreamComposerLocation.floating); + expect(StreamMessageComposerTheme.of(capturedContext).behavior, StreamMessageComposerBehavior.floating); }); testWidgets('updateShouldNotify is true when the data changes', (tester) async { - const oldWidget = StreamMessageComposerTheme(data: _dockedTheme, child: SizedBox.shrink()); + const oldWidget = StreamMessageComposerTheme(data: _regularTheme, child: SizedBox.shrink()); const newWidget = StreamMessageComposerTheme(data: _floatingTheme, child: SizedBox.shrink()); expect(newWidget.updateShouldNotify(oldWidget), isTrue); }); testWidgets('updateShouldNotify is false when the data is unchanged', (tester) async { - const oldWidget = StreamMessageComposerTheme(data: _dockedTheme, child: SizedBox.shrink()); - const newWidget = StreamMessageComposerTheme(data: _dockedTheme, child: SizedBox.shrink()); + const oldWidget = StreamMessageComposerTheme(data: _regularTheme, child: SizedBox.shrink()); + const newWidget = StreamMessageComposerTheme(data: _regularTheme, child: SizedBox.shrink()); expect(newWidget.updateShouldNotify(oldWidget), isFalse); }); } -const _dockedTheme = StreamMessageComposerThemeData(location: StreamComposerLocation.docked); -const _floatingTheme = StreamMessageComposerThemeData(location: StreamComposerLocation.floating); +const _regularTheme = StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.regular); +const _floatingTheme = StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating); /// Pumps a [StreamChat] configured with [globalTheme], optionally wrapped in a /// local [StreamMessageComposerTheme] carrying [localTheme], and returns a diff --git a/sample_app/lib/app.dart b/sample_app/lib/app.dart index 480b2335f2..08d31d7762 100644 --- a/sample_app/lib/app.dart +++ b/sample_app/lib/app.dart @@ -179,11 +179,7 @@ class _StreamChatSampleAppState extends State child: Builder( builder: (context) { final config = context.sampleAppConfig; - - final appStyle = switch (config.appStyle) { - SampleAppStyle.regular => StreamAppStyle.regular, - SampleAppStyle.floating => StreamAppStyle.floating, - }; + final appStyle = config.appStyle; return DynamicColorBuilder( builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) { diff --git a/sample_app/lib/config/sample_app_config.dart b/sample_app/lib/config/sample_app_config.dart index 08b4edf00e..7b495968fd 100644 --- a/sample_app/lib/config/sample_app_config.dart +++ b/sample_app/lib/config/sample_app_config.dart @@ -3,19 +3,6 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_localizations/stream_chat_localizations.dart'; import 'package:streaming_shared_preferences/streaming_shared_preferences.dart'; -// --------------------------------------------------------------------------- -// AppStyle enum -// --------------------------------------------------------------------------- - -/// The visual style for the app's UI chrome (app bar, composer, bottom bar). -enum SampleAppStyle { - /// Standard docked composer with solid app bar and bottom bar. - regular, - - /// Floating composer with translucent overlapping chrome. - floating, -} - // --------------------------------------------------------------------------- // Preference keys // --------------------------------------------------------------------------- @@ -53,7 +40,7 @@ class SampleAppConfigData { factory SampleAppConfigData({ Locale? locale, ThemeMode themeMode = .system, - SampleAppStyle appStyle = .regular, + StreamAppStyle appStyle = .regular, bool forceRtl = false, bool enableDynamicColor = false, bool enableReminderActions = false, @@ -102,10 +89,10 @@ class SampleAppConfigData { /// Loads config from [StreamingSharedPreferences], falling back to defaults. factory SampleAppConfigData.fromPreferences(StreamingSharedPreferences prefs) { final localeStr = prefs.getString(_kLocale, defaultValue: '').getValue(); - final appStyleIndex = prefs.getInt(_kAppStyle, defaultValue: SampleAppStyle.regular.index).getValue(); + final appStyleIndex = prefs.getInt(_kAppStyle, defaultValue: StreamAppStyle.regular.index).getValue(); return SampleAppConfigData.raw( themeMode: ThemeMode.values[prefs.getInt(_kThemeMode, defaultValue: ThemeMode.system.index).getValue()], - appStyle: SampleAppStyle.values[appStyleIndex.clamp(0, SampleAppStyle.values.length - 1)], + appStyle: StreamAppStyle.values[appStyleIndex.clamp(0, StreamAppStyle.values.length - 1)], locale: localeStr.isEmpty ? null : Locale(localeStr), forceRtl: prefs.getBool(_kForceRtl, defaultValue: false).getValue(), enableDynamicColor: prefs.getBool(_kEnableDynamicColor, defaultValue: false).getValue(), @@ -126,7 +113,7 @@ class SampleAppConfigData { final ThemeMode themeMode; /// The visual style for the app chrome (app bar, composer, bottom bar). - final SampleAppStyle appStyle; + final StreamAppStyle appStyle; /// The locale override for the app. When null, the system locale is used. final Locale? locale; @@ -172,7 +159,7 @@ class SampleAppConfigData { /// pass explicitly as `null` to reset to default/system. SampleAppConfigData copyWith({ ThemeMode? themeMode, - SampleAppStyle? appStyle, + StreamAppStyle? appStyle, Object? locale = _sentinel, bool? forceRtl, bool? enableDynamicColor, diff --git a/sample_app/lib/config/sample_app_config_screen.dart b/sample_app/lib/config/sample_app_config_screen.dart index 71b4a91fe7..89b28e13c3 100644 --- a/sample_app/lib/config/sample_app_config_screen.dart +++ b/sample_app/lib/config/sample_app_config_screen.dart @@ -56,16 +56,16 @@ class SampleAppConfigScreen extends StatelessWidget { }, onChanged: (v) => SampleAppConfig.update(context, config.copyWith(themeMode: v)), ), - _SegmentedRow( + _SegmentedRow( title: 'App Style', value: config.appStyle, segments: const { - SampleAppStyle.regular: 'Regular', - SampleAppStyle.floating: 'Floating', + StreamAppStyle.regular: 'Regular', + StreamAppStyle.floating: 'Floating', }, segmentIcons: const { - SampleAppStyle.regular: Icons.web_asset_outlined, - SampleAppStyle.floating: Icons.filter_none_outlined, + StreamAppStyle.regular: Icons.web_asset_outlined, + StreamAppStyle.floating: Icons.filter_none_outlined, }, onChanged: (v) => SampleAppConfig.update(context, config.copyWith(appStyle: v)), ), From 427bcdc070938d7f9147ced701ee43ad43921b6c Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Tue, 4 Aug 2026 10:47:15 +0200 Subject: [PATCH 70/87] fix ripple effect on attachments --- .../stream_message_composer.dart | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index b388c20195..342712ca68 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -852,6 +852,20 @@ class DefaultStreamMessageComposerState extends State composerBody, - .regular => DecoratedBox( - decoration: BoxDecoration(color: colorScheme.backgroundElevation1), - child: composerBody, - ), - }, - ); + final composer = switch (effectiveComposerBehavior) { + .floating => composerBody, + .regular => DecoratedBox( + decoration: BoxDecoration(color: colorScheme.backgroundElevation1), + child: composerBody, + ), + }; return ComposerAttachmentAnnouncer( controller: _effectiveController, From d07bcf5c4154ed4084d4e179fbc3bffc171cba1d Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Tue, 4 Aug 2026 13:11:26 +0200 Subject: [PATCH 71/87] revert repliesEnabled change --- .../lib/src/message_action/message_actions_builder.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart b/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart index d8e82115d4..ddbf28adf5 100644 --- a/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart +++ b/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart @@ -115,7 +115,6 @@ class StreamMessageActionsBuilder { final isParentMessage = (message.replyCount ?? 0) > 0; final canShowInChannel = message.showInChannel ?? true; final isPrivateMessage = message.hasRestrictedVisibility; - final repliesEnabled = channel.config?.replies ?? true; final canSendReply = channel.canSendReply; final canPinMessage = channel.canPinMessage; final canQuoteMessage = channel.canQuoteMessage; @@ -144,7 +143,7 @@ class StreamMessageActionsBuilder { // Thread reply action is only available for parent messages that are not in a // thread view, as replying in a thread that is already being viewed doesn't make sense. // Additionally, the channel needs to support sending replies. - if (canSendReply && repliesEnabled && !isThreadMessage && !isInThreadView) { + if (canSendReply && !isThreadMessage && !isInThreadView) { messageActions.add( StreamContextMenuAction( value: ThreadReply(message: message), From c4b5391a67a3fc92f5986f6061789781869f2596 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 6 Aug 2026 18:33:41 +0200 Subject: [PATCH 72/87] wip: floating message list + toolbar migration (checkpoint before master merge) Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/docs_screenshots/pubspec.yaml | 5 +- melos.yaml | 5 +- packages/stream_chat_flutter/CHANGELOG.md | 3 +- .../xcschemes/Runner.xcscheme.backup | 91 +++++++++ .../src/item_positions_listener.dart | 30 ++- .../src/positioned_list.dart | 57 +++++- .../lib/src/channel/channel_header.dart | 24 +-- .../lib/src/channel/channel_list_header.dart | 23 +-- .../stream_media_gallery_preview_footer.dart | 10 +- .../floating_date_divider.dart | 26 ++- .../message_list_view/message_list_view.dart | 47 ++--- .../lib/src/message_list_view/mlv_utils.dart | 16 +- .../lib/src/misc/back_button.dart | 19 +- .../lib/src/misc/thread_header.dart | 13 +- .../src/{channel => pages}/channel_page.dart | 18 +- .../src/{channel => pages}/thread_page.dart | 4 - .../stream_channel_list_skeleton_loading.dart | 9 +- .../stream_channel_list_view.dart | 2 +- .../photo_gallery/stream_photo_gallery.dart | 2 +- .../stream_thread_list_skeleton_loading.dart | 9 +- .../stream_thread_list_view.dart | 4 +- .../lib/src/theme/message_composer_theme.dart | 2 +- .../lib/src/utils/app_bar_behavior.dart | 40 ---- .../lib/stream_chat_flutter.dart | 4 +- packages/stream_chat_flutter/pubspec.yaml | 13 +- ...dding_scrollable_positioned_list_test.dart | 187 +++++++++++++++++ .../test/src/channel/channel_header_test.dart | 14 +- .../src/channel/channel_list_header_test.dart | 10 +- .../stream_message_item_test.dart | 192 ++++++++++++++++++ .../lib/config/sample_app_config_screen.dart | 5 +- .../lib/pages/advanced_options_page.dart | 3 +- .../pages/channel_file_display_screen.dart | 6 +- .../pages/channel_media_display_screen.dart | 5 +- sample_app/lib/pages/chat_info_screen.dart | 3 +- .../lib/pages/group_chat_details_screen.dart | 4 +- sample_app/lib/pages/group_info_screen.dart | 3 +- sample_app/lib/pages/new_chat_screen.dart | 4 +- .../lib/pages/new_group_chat_screen.dart | 4 +- .../lib/pages/pinned_messages_screen.dart | 3 +- sample_app/lib/utils/scaffold_insets.dart | 15 -- sample_app/lib/widgets/channel_list.dart | 11 +- .../macos/Runner.xcodeproj/project.pbxproj | 42 ++-- .../xcshareddata/xcschemes/Runner.xcscheme | 18 ++ 43 files changed, 742 insertions(+), 263 deletions(-) create mode 100644 packages/stream_chat_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme.backup rename packages/stream_chat_flutter/lib/src/{channel => pages}/channel_page.dart (91%) rename packages/stream_chat_flutter/lib/src/{channel => pages}/thread_page.dart (97%) delete mode 100644 packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart create mode 100644 packages/stream_chat_flutter/test/scrollable_positioned_list/padding_scrollable_positioned_list_test.dart create mode 100644 packages/stream_chat_flutter/test/src/message_widget/stream_message_item_test.dart delete mode 100644 sample_app/lib/utils/scaffold_insets.dart diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index f97017629a..6b5eb4fa05 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -20,10 +20,7 @@ dependencies: record: ^6.2.0 stream_chat_flutter: ^10.2.0 stream_core_flutter: - git: - url: https://github.com/GetStream/stream-core-flutter.git - ref: ab4b1fb0a0be01b4270823c5c2c7b0c21ad886f8 - path: packages/stream_core_flutter + path: /Users/xsahil03x/StudioProjects/stream-core-flutter/packages/stream_core_flutter dev_dependencies: alchemist: ^0.14.0 diff --git a/melos.yaml b/melos.yaml index 795c1b71d1..41066ba080 100644 --- a/melos.yaml +++ b/melos.yaml @@ -105,10 +105,7 @@ command: streaming_shared_preferences: ^2.0.0 svg_icon_widget: ^0.0.1 stream_core_flutter: - git: - url: https://github.com/GetStream/stream-core-flutter.git - ref: ab4b1fb0a0be01b4270823c5c2c7b0c21ad886f8 - path: packages/stream_core_flutter + path: /Users/xsahil03x/StudioProjects/stream-core-flutter/packages/stream_core_flutter stream_thumbnail: ^0.1.0 synchronized: ^3.4.0 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 614e9a1b83..2f5d641603 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -4,6 +4,7 @@ - `StreamPhotoGallery` now defaults its `padding` to the bottom safe-area inset instead of no padding, so the last row clears the home indicator. Pass an explicit `padding` to opt out. - `StreamMessageListView.config` is now nullable (`StreamMessageListViewConfiguration?`) instead of defaulting to `const StreamMessageListViewConfiguration()`. Passing a value is unchanged; code that *reads* `config` off a `StreamMessageListView` instance now gets a nullable value. +- `StreamMediaGalleryPreview` chrome now follows the app style — when floating, the header and footer float over full-bleed media and the footer's share / gallery buttons outline + elevate to match the back button; when regular, the chrome is docked and the media is inset between the bars. ✅ Added @@ -14,7 +15,7 @@ - Added `StreamMessageComposerTheme` and `StreamMessageComposerThemeData` — a component theme for the composer, also available globally as `StreamChatThemeData.messageComposerTheme`. - Added `StreamMessageListView.config` — accepts an explicit `StreamMessageListViewConfiguration` per widget; falls back to `StreamChatConfigurationData.messageListViewConfiguration` from the nearest ancestor when omitted. - Added `StreamMessageListView.topPadding` and `bottomPadding` — padding applied to the scroll view's top and bottom edges, used by floating app bar / composer layouts to keep messages visible without an extra `setState`. -- Added an `isFloating` parameter to `StreamBackButton`, controlling floating vs pinned back-button appearance. Falls back to `StreamAppBarTheme`, and then to the ambient `StreamAppStyle`, when null. `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamThreadHeader` now merge their `style` into the `StreamAppBarTheme` they install, so every slot in the bar — the default avatar's drop shadow, the default back button, and any `leading`/`trailing` the caller supplies — resolves the same chain the bar itself uses: `style`, then the per-header theme (`channelHeaderTheme` / `channelListHeaderTheme` / `threadHeaderTheme`), then `StreamAppBarTheme`, then `StreamAppStyle`. +- Added an `isFloating` parameter to `StreamBackButton`, controlling floating vs pinned back-button appearance. Falls back to `StreamAppBarTheme`, and then to the ambient `StreamAppStyle`, when null. `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamThreadHeader` now apply their per-header theme (`channelHeaderTheme` / `channelListHeaderTheme` / `threadHeaderTheme`) as a `StreamAppBarTheme` and pass `style` to the bar, which republishes its resolved behavior to its slots — so every slot in the bar — the default avatar's drop shadow, the default back button, and any `leading`/`trailing` the caller supplies — resolves the same chain the bar itself uses: `style`, then the per-header theme, then the ambient `StreamAppBarTheme`, then `StreamAppStyle`. - Added `messageListViewConfiguration` field to `StreamChatConfigurationData`, allowing a global `StreamMessageListViewConfiguration` default for all `StreamMessageListView` widgets. Pass it via `StreamChat.configData` to configure behaviors like `swipeToReply` and `highlightInitialMessage` app-wide without wiring them per-page. - Re-exported `StreamScaffold`, `StreamScaffoldInsets`, `StreamBottomNavBar`, `StreamBottomNavBarItem`, `StreamAppStyle`, `StreamAppBarBehavior`, `StreamBottomAppBarBehavior`, and `streamFloatingFadeLinearGradient` from `stream_core_flutter` via `package:stream_chat_flutter/stream_chat_flutter.dart`. - Added `StreamMessageListViewConfiguration.autoScrollPolicy` to control whether and how `StreamMessageListView` scrolls to the newest message when a new message arrives. Use `StreamAutoScrollPolicy.disabled` to fully control scrolling yourself. diff --git a/packages/stream_chat_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme.backup b/packages/stream_chat_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme.backup new file mode 100644 index 0000000000..e67b2808af --- /dev/null +++ b/packages/stream_chat_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme.backup @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart b/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart index 808a2906fd..3e7fdd694b 100644 --- a/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart +++ b/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart @@ -24,6 +24,8 @@ class ItemPosition { required this.index, required this.itemLeadingEdge, required this.itemTrailingEdge, + this.contentLeadingEdge, + this.contentTrailingEdge, }); /// Index of the item. @@ -41,6 +43,20 @@ class ItemPosition { /// May be greater than one if the item is partially visible. final double itemTrailingEdge; + /// Distance in proportion of the visible content's main axis length from the + /// leading edge of that content to the leading edge of the item. + /// + /// The visible content is the area inside the list's padding. `null` when the + /// list has no padding. Use for overlays inside the padded area, such as under + /// a floating bar; scroll logic keeps using [itemLeadingEdge]. + final double? contentLeadingEdge; + + /// Distance in proportion of the visible content's main axis length from the + /// leading edge of that content to the trailing edge of the item. + /// + /// See [contentLeadingEdge]. + final double? contentTrailingEdge; + @override bool operator ==(Object other) => identical(this, other) || @@ -48,12 +64,20 @@ class ItemPosition { runtimeType == other.runtimeType && index == other.index && itemLeadingEdge == other.itemLeadingEdge && - itemTrailingEdge == other.itemTrailingEdge; + itemTrailingEdge == other.itemTrailingEdge && + contentLeadingEdge == other.contentLeadingEdge && + contentTrailingEdge == other.contentTrailingEdge; @override - int get hashCode => 31 * (31 * (index.hashCode + 7) + itemLeadingEdge.hashCode) + itemTrailingEdge.hashCode; + int get hashCode => Object.hash( + index, + itemLeadingEdge, + itemTrailingEdge, + contentLeadingEdge, + contentTrailingEdge, + ); @override String toString() => - '''ItemPosition(index: $index, itemLeadingEdge: $itemLeadingEdge, itemTrailingEdge: $itemTrailingEdge)'''; + '''ItemPosition(index: $index, itemLeadingEdge: $itemLeadingEdge, itemTrailingEdge: $itemTrailingEdge, contentLeadingEdge: $contentLeadingEdge, contentTrailingEdge: $contentTrailingEdge)'''; } diff --git a/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/positioned_list.dart b/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/positioned_list.dart index 45d97036a8..f5e3bfd0fd 100644 --- a/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/positioned_list.dart +++ b/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/positioned_list.dart @@ -337,7 +337,7 @@ class _PositionedListState extends State { @override Widget build(BuildContext context) { _rebuildKeyIndexMap(); - return RegistryWidget( + Widget list = RegistryWidget( elementNotifier: registeredElements, child: UnboundedCustomScrollView( anchor: widget.alignment, @@ -410,6 +410,23 @@ class _PositionedListState extends State { ], ), ); + + // Match BoxScrollView: when the main-axis MediaQuery padding was + // auto-consumed (no explicit padding), strip it from descendants so nested + // widgets and scrollables don't inset for it a second time. + final mediaQuery = MediaQuery.maybeOf(context); + if (widget.padding == null && mediaQuery != null) { + list = MediaQuery( + data: mediaQuery.copyWith( + padding: widget.scrollDirection == Axis.vertical + ? mediaQuery.padding.copyWith(top: 0, bottom: 0) + : mediaQuery.padding.copyWith(left: 0, right: 0), + ), + child: list, + ); + } + + return list; } Widget _buildSeparatedListElement(int index) { @@ -441,8 +458,19 @@ class _PositionedListState extends State { ); } - EdgeInsets get _resolvedPadding => - widget.padding?.resolve(Directionality.maybeOf(context) ?? TextDirection.ltr) ?? EdgeInsets.zero; + EdgeInsets get _resolvedPadding { + final padding = widget.padding; + if (padding != null) { + return padding.resolve(Directionality.maybeOf(context) ?? TextDirection.ltr); + } + // Match BoxScrollView: with no explicit padding, consume the main-axis + // MediaQuery padding so the list auto-insets like a ListView. The cross-axis + // remainder is handed to descendants in [build]. + final mediaPadding = MediaQuery.maybeOf(context)?.padding ?? EdgeInsets.zero; + return widget.scrollDirection == Axis.vertical + ? mediaPadding.copyWith(left: 0, right: 0) + : mediaPadding.copyWith(top: 0, bottom: 0); + } AxisDirection get _axisDirection { if (widget.scrollDirection == Axis.vertical) { @@ -563,12 +591,22 @@ class _PositionedListState extends State { final reveal = viewport!.getOffsetToReveal(box, 0).offset; if (!reveal.isFinite) continue; final itemOffset = reveal - viewport.offset.pixels + anchor * viewport.size.height; + final viewportDimension = scrollController.position.viewportDimension; + // content* edges are measured from the visible content (inside the + // padding) so overlays under a floating bar can key off 0..1; + // subtract the leading padding (the bottom when reversed, which + // `_leadingSliverPadding` resolves). item* stays viewport-relative + // for scroll mechanics (alignment / anchor preservation). + final leadingPad = _leadingSliverPadding.vertical; + final contentExtent = viewportDimension - _resolvedPadding.vertical; + final contentDenom = contentExtent > 0 ? contentExtent : viewportDimension; positions.add( ItemPosition( index: key.index, - itemLeadingEdge: itemOffset.round() / scrollController.position.viewportDimension, - itemTrailingEdge: - (itemOffset + box.size.height).round() / scrollController.position.viewportDimension, + itemLeadingEdge: itemOffset.round() / viewportDimension, + itemTrailingEdge: (itemOffset + box.size.height).round() / viewportDimension, + contentLeadingEdge: (itemOffset - leadingPad).round() / contentDenom, + contentTrailingEdge: (itemOffset + box.size.height - leadingPad).round() / contentDenom, ), ); } else { @@ -579,11 +617,18 @@ class _PositionedListState extends State { final isRight = _axisDirection == AxisDirection.right; final leadingPx = isRight ? itemOffset : viewportDimension - (itemOffset + box.size.width); final trailingPx = isRight ? itemOffset + box.size.width : viewportDimension - itemOffset; + // content* edges (see the vertical branch): drop the leading + // padding so 0..1 spans the visible content. + final leadingPad = _leadingSliverPadding.horizontal; + final contentExtent = viewportDimension - _resolvedPadding.horizontal; + final contentDenom = contentExtent > 0 ? contentExtent : viewportDimension; positions.add( ItemPosition( index: key.index, itemLeadingEdge: leadingPx.round() / viewportDimension, itemTrailingEdge: trailingPx.round() / viewportDimension, + contentLeadingEdge: (leadingPx - leadingPad).round() / contentDenom, + contentTrailingEdge: (trailingPx - leadingPad).round() / contentDenom, ), ); } diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index 710b39da08..171c7d8d62 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; -import 'package:stream_chat_flutter/src/utils/app_bar_behavior.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// {@template streamChannelHeader} @@ -184,17 +183,10 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget return StreamInfoTile( showMessage: showConnectionStateTile && showStatus, message: statusString, - // Wrap the bar in a [StreamAppBarTheme] so the per-header chat - // theme drives all default styling (background, padding, - // typography, divider). - // - // [style] is merged into the theme data as well as passed to the - // bar, so every slot below — the default avatar, the default back - // button, and anything the caller supplied — resolves the same - // chain the bar itself does: [style], then the per-header theme, - // then the ambient app bar theme, then the app style. + // Apply the per-header theme as a theme; the bar resolves `style` + // over it and republishes the resolved behaviour to its slots. child: StreamAppBarTheme( - data: headerTheme.merge(StreamAppBarThemeData(style: style)), + data: headerTheme, child: StreamAppBar( leading: leading, automaticallyImplyLeading: false, @@ -221,10 +213,10 @@ class _DefaultChannelAvatar extends StatelessWidget { @override Widget build(BuildContext context) { - // Resolved from context rather than passed in, so it picks up the header's - // [StreamAppBarTheme] — this widget is built inside it, same as the bar's - // other slots. - final isFloating = isFloatingAppBar(context); + final appStyle = StreamTheme.of(context).appStyle; + final toolbarBehavior = StreamToolbarScope.maybeOf(context); + + final effectiveIsFloating = toolbarBehavior?.isFloating ?? appStyle.isFloating; final effectiveOnTap = switch (onPressed) { final cb? => () => cb(channel), @@ -243,7 +235,7 @@ class _DefaultChannelAvatar extends StatelessWidget { child: StreamChannelAvatar( size: .lg, channel: channel, - isFloating: isFloating, + isFloating: effectiveIsFloating, ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart index 2204ac9462..1f0df916b1 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; -import 'package:stream_chat_flutter/src/utils/app_bar_behavior.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// {@template streamChannelListHeader} @@ -158,16 +157,10 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi return StreamInfoTile( showMessage: showConnectionStateTile && showStatus, message: statusString, - // Wrap the bar in a [StreamAppBarTheme] so the per-header chat - // theme drives all default styling. - // - // [style] is merged into the theme data as well as passed to the - // bar, so every slot below — the default avatar and anything the - // caller supplied — resolves the same chain the bar itself does: - // [style], then the per-header theme, then the ambient app bar - // theme, then the app style. + // Apply the per-header theme as a theme; the bar resolves `style` + // over it and republishes the resolved behaviour to its slots. child: StreamAppBarTheme( - data: headerTheme.merge(StreamAppBarThemeData(style: style)), + data: headerTheme, child: StreamAppBar( leading: leading, title: title, @@ -195,10 +188,10 @@ class _DefaultUserAvatar extends StatelessWidget { final user = client.state.currentUser; if (user == null) return const SizedBox.shrink(); - // Resolved from context rather than passed in, so it picks up the header's - // [StreamAppBarTheme] — this widget is built inside it, same as the bar's - // other slots. - final isFloating = isFloatingAppBar(context); + final appStyle = StreamTheme.of(context).appStyle; + final toolbarBehavior = StreamToolbarScope.maybeOf(context); + + final effectiveIsFloating = toolbarBehavior?.isFloating ?? appStyle.isFloating; // Caller-provided handler wins; otherwise mirror Material AppBar and // open the enclosing Scaffold's drawer if one exists. With no callback @@ -222,7 +215,7 @@ class _DefaultUserAvatar extends StatelessWidget { size: .lg, user: user, showOnlineIndicator: false, - isFloating: isFloating, + isFloating: effectiveIsFloating, ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/media_gallery_preview/stream_media_gallery_preview_footer.dart b/packages/stream_chat_flutter/lib/src/media_gallery_preview/stream_media_gallery_preview_footer.dart index b9a07ba71d..b516f63553 100644 --- a/packages/stream_chat_flutter/lib/src/media_gallery_preview/stream_media_gallery_preview_footer.dart +++ b/packages/stream_chat_flutter/lib/src/media_gallery_preview/stream_media_gallery_preview_footer.dart @@ -65,16 +65,14 @@ class StreamMediaGalleryPreviewFooter extends StatelessWidget implements Preferr final icons = context.streamIcons; return StreamBottomAppBar( - leading: StreamButton.icon( - type: StreamButtonType.ghost, - style: StreamButtonStyle.secondary, + leading: StreamToolbarButton.icon( + style: .secondary, icon: Icon(icons.export), onPressed: onSharePressed, ), title: title, - trailing: StreamButton.icon( - type: StreamButtonType.ghost, - style: StreamButtonStyle.secondary, + trailing: StreamToolbarButton.icon( + style: .secondary, icon: Icon(icons.gallery), onPressed: onGalleryPressed, ), diff --git a/packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart b/packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart index 908d0d9dda..99a717fda3 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart @@ -138,24 +138,30 @@ class FloatingDateDivider extends StatelessWidget { for (final p in positions) { if (p.index != itemIndex) continue; + // Measured against the visible content (inside the list's padding), so a + // floating bar's inset doesn't shift where the fade hands off. Falls back + // to the viewport-relative edges when content edges aren't provided. + final leadingEdge = p.contentLeadingEdge ?? p.itemLeadingEdge; + final trailingEdge = p.contentTrailingEdge ?? p.itemTrailingEdge; + var opacity = 1.0; if (reverse) { // Fade as the inline divider ABOVE becomes visible - // (trailing edge = top of item, 1.0 = viewport top). - if (hasDateDividerAbove && p.itemTrailingEdge < 1) { + // (trailing edge = top of item, 1.0 = content top). + if (hasDateDividerAbove && trailingEdge < 1) { opacity = clampDouble( - (p.itemTrailingEdge - (1.0 - _fadeRange)) / _fadeRange, + (trailingEdge - (1.0 - _fadeRange)) / _fadeRange, 0, 1, ); } - // Fade as the inline divider BELOW approaches the viewport top + // Fade as the inline divider BELOW approaches the content top // (leading edge = bottom of item, approaching 1.0). if (hasDateDividerBelow) { final t = clampDouble( - ((1.0 - _fadeRange) - p.itemLeadingEdge) / _fadeRange, + ((1.0 - _fadeRange) - leadingEdge) / _fadeRange, 0, 1, ); @@ -163,20 +169,20 @@ class FloatingDateDivider extends StatelessWidget { } } else { // Fade as the inline divider ABOVE becomes visible - // (leading edge = top of item, 0.0 = viewport top). - if (hasDateDividerAbove && p.itemLeadingEdge > 0) { + // (leading edge = top of item, 0.0 = content top). + if (hasDateDividerAbove && leadingEdge > 0) { opacity = clampDouble( - (_fadeRange - p.itemLeadingEdge) / _fadeRange, + (_fadeRange - leadingEdge) / _fadeRange, 0, 1, ); } - // Fade as the inline divider BELOW approaches the viewport top + // Fade as the inline divider BELOW approaches the content top // (trailing edge = bottom of item, approaching 0.0). if (hasDateDividerBelow) { final t = clampDouble( - (p.itemTrailingEdge - _fadeRange) / _fadeRange, + (trailingEdge - _fadeRange) / _fadeRange, 0, 1, ); diff --git a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart index 6cca7cfbe6..c8179c3adb 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart @@ -1,5 +1,5 @@ import 'dart:async'; -import 'dart:math'; +import 'dart:math' as math; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; @@ -127,8 +127,6 @@ class StreamMessageListView extends StatefulWidget { this.onMessageLongPress, this.config, this.builders = const StreamMessageListViewBuilders(), - this.topPadding = 0, - this.bottomPadding = 0, }); /// Predicate used to filter messages. @@ -288,18 +286,6 @@ class StreamMessageListView extends StatefulWidget { /// Defaults to [StreamMessageListViewBuilders] with no overrides. final StreamMessageListViewBuilders builders; - /// Top padding added to the message list scroll view. - /// - /// Used by the floating app bar layout to keep the first message visible - /// below the app bar without requiring a separate [setState] call. - final double topPadding; - - /// Bottom padding added to the message list scroll view. - /// - /// Used by the floating composer layout to keep the last message visible - /// above the composer without requiring a separate [setState] call. - final double bottomPadding; - @override _StreamMessageListViewState createState() => _StreamMessageListViewState(); } @@ -363,9 +349,10 @@ class _StreamMessageListViewState extends State { /// and so must not run from a stream callback — `_messageNewListener` reads /// this. late StreamMessageListViewConfiguration _config; - - StreamMessageListViewConfiguration _resolveConfig() => - widget.config ?? StreamChatConfiguration.of(context).messageListViewConfiguration; + StreamMessageListViewConfiguration _resolveConfig() { + if (widget.config case final config?) return config; + return StreamChatConfiguration.of(context).messageListViewConfiguration; + } StreamSubscription? _messageNewListener; StreamSubscription? _userReadListener; @@ -573,6 +560,11 @@ class _StreamMessageListViewState extends State { ); } + // Safe-area insets injected into MediaQuery by the enclosing scaffold (a + // floating app bar / composer, or the system safe area). Read directly so the + // list self-insets without the caller threading padding in. + EdgeInsets get _scaffoldInsets => MediaQuery.paddingOf(context); + @override Widget build(BuildContext context) { Widget defaultLoadingBuilder(BuildContext context) { @@ -675,8 +667,8 @@ class _StreamMessageListViewState extends State { child: ScrollablePositionedList.separated( key: Key('mlv-${streamChannel?.channel.cid}-${widget.parentMessage?.id}'), padding: .only( - top: max(widget.topPadding, context.streamSpacing.sm), - bottom: max(widget.bottomPadding, context.streamSpacing.sm), + top: _scaffoldInsets.top + context.streamSpacing.sm, + bottom: _scaffoldInsets.bottom + context.streamSpacing.sm, ), keyboardDismissBehavior: _config.keyboardDismissBehavior, itemPositionsListener: _itemPositionListener, @@ -832,7 +824,7 @@ class _StreamMessageListViewState extends State { ), if (_config.showFloatingDateDivider) Positioned( - top: max(widget.topPadding, context.streamSpacing.sm), + top: math.max(_scaffoldInsets.top, context.streamSpacing.sm), child: FloatingDateDivider( itemCount: itemCount, reverse: _config.reverse, @@ -870,7 +862,7 @@ class _StreamMessageListViewState extends State { ), if (_config.showUnreadIndicator && !_isThreadConversation) Positioned( - top: max(widget.topPadding, context.streamSpacing.sm), + top: _scaffoldInsets.top + context.streamSpacing.sm, child: UnreadIndicatorButton( onJumpTap: scrollToUnreadDefaultTapAction, onDismissTap: _markMessagesAsRead, @@ -978,7 +970,7 @@ class _StreamMessageListViewState extends State { if (_scrollController case final controller? when controller.isAttached) { return controller.scrollTo( - index: max(firstUnreadMessageIndex + 2, 0), + index: math.max(firstUnreadMessageIndex + 2, 0), alignment: 0.5, // center the message in the viewport ); } @@ -1147,7 +1139,7 @@ class _StreamMessageListViewState extends State { } return PositionedDirectional( - bottom: max(16, widget.bottomPadding), + bottom: _scaffoldInsets.bottom + 16, end: 16, child: button, ); @@ -1261,9 +1253,10 @@ class _StreamMessageListViewState extends State { var isLastItemFullyVisible = false; if (lastItemPosition != null) { - // We consider the last item fully visible if its leading edge (reversed) - // is greater than or equal to 0. - isLastItemFullyVisible = lastItemPosition.itemLeadingEdge >= 0; + // Fully visible = its leading edge (reversed) sits within the visible + // content (>= 0), not merely within the raw viewport — so an item behind + // the floating composer counts as hidden and the scroll-to-bottom shows. + isLastItemFullyVisible = (lastItemPosition.contentLeadingEdge ?? lastItemPosition.itemLeadingEdge) >= 0; } if (mounted) _showScrollToBottom.value = !isLastItemFullyVisible; diff --git a/packages/stream_chat_flutter/lib/src/message_list_view/mlv_utils.dart b/packages/stream_chat_flutter/lib/src/message_list_view/mlv_utils.dart index 5977cbefe5..04909f5620 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view/mlv_utils.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view/mlv_utils.dart @@ -43,8 +43,11 @@ int getInitialIndex( return 0; } -/// Gets the index of the top element in the viewport. +/// Gets the index of the top element in the visible content. int? getTopElementIndex(Iterable values) { + // Measured against the visible content (inside the list's padding) so a + // floating bar's inset doesn't skew which item counts as "on top". + double trailing(ItemPosition p) => p.contentTrailingEdge ?? p.itemTrailingEdge; final inView = values.where((position) { if (position.itemLeadingEdge == position.itemTrailingEdge) { // If the item's leading and trailing edges are the same, it means the @@ -52,17 +55,18 @@ int? getTopElementIndex(Iterable values) { return false; } - return position.itemTrailingEdge > 0; + return trailing(position) > 0; }); if (inView.isEmpty) return null; return inView.reduce((min, position) { - return position.itemTrailingEdge < min.itemTrailingEdge ? position : min; + return trailing(position) < trailing(min) ? position : min; }).index; } -/// Gets the index of the bottom element in the viewport. +/// Gets the index of the bottom element in the visible content. int? getBottomElementIndex(Iterable values) { + double leading(ItemPosition p) => p.contentLeadingEdge ?? p.itemLeadingEdge; final inView = values.where((position) { if (position.itemLeadingEdge == position.itemTrailingEdge) { // If the item's leading and trailing edges are the same, it means the @@ -70,12 +74,12 @@ int? getBottomElementIndex(Iterable values) { return false; } - return position.itemLeadingEdge < 1; + return leading(position) < 1; }); if (inView.isEmpty) return null; return inView.reduce((max, position) { - return position.itemLeadingEdge > max.itemLeadingEdge ? position : max; + return leading(position) > leading(max) ? position : max; }).index; } diff --git a/packages/stream_chat_flutter/lib/src/misc/back_button.dart b/packages/stream_chat_flutter/lib/src/misc/back_button.dart index a51e2a6dcd..f259b83d3d 100644 --- a/packages/stream_chat_flutter/lib/src/misc/back_button.dart +++ b/packages/stream_chat_flutter/lib/src/misc/back_button.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/utils/app_bar_behavior.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// {@template streamBackButton} @@ -20,7 +19,6 @@ class StreamBackButton extends StatelessWidget { 'This will be removed in a future version.', ) this.channelId, - this.isFloating, Widget? unreadIndicator = _unset, }) : _unreadIndicator = unreadIndicator; @@ -41,13 +39,6 @@ class StreamBackButton extends StatelessWidget { ) final String? channelId; - /// Whether the button adopts its floating presentation — an outlined button - /// instead of a ghost one. - /// - /// When null, falls back to [StreamAppBarStyle.behavior] from the ambient - /// [StreamAppBarTheme], then to the ambient [StreamAppStyle]. - final bool? isFloating; - /// The unread badge overlaid on the top-end corner of the button. /// /// Typically a [StreamUnreadIndicator]. The badge hides itself when its @@ -65,11 +56,15 @@ class StreamBackButton extends StatelessWidget { .iOS || .macOS => context.streamIcons.chevronLeft, _ => context.streamIcons.arrowLeft, }; - final isFloating = this.isFloating ?? isFloatingAppBar(context); + + final appStyle = StreamTheme.of(context).appStyle; + final toolbarBehavior = StreamToolbarScope.maybeOf(context); + + final effectiveIsFloating = toolbarBehavior?.isFloating ?? appStyle.isFloating; Widget button = StreamButton.icon( - type: isFloating ? .outline : .ghost, - isFloating: isFloating, + type: effectiveIsFloating ? .outline : .ghost, + isFloating: effectiveIsFloating, size: .medium, style: .secondary, tooltip: backTooltip, diff --git a/packages/stream_chat_flutter/lib/src/misc/thread_header.dart b/packages/stream_chat_flutter/lib/src/misc/thread_header.dart index 42da929af8..dcc9989518 100644 --- a/packages/stream_chat_flutter/lib/src/misc/thread_header.dart +++ b/packages/stream_chat_flutter/lib/src/misc/thread_header.dart @@ -82,7 +82,10 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget final cid? => StreamUnreadIndicator.channels(cid: cid), null => const StreamUnreadIndicator(), }; - leading = StreamBackButton(onPressed: onBackPressed, unreadIndicator: unreadIndicator); + leading = StreamBackButton( + onPressed: onBackPressed, + unreadIndicator: unreadIndicator, + ); } Widget? fallbackSubtitle; @@ -100,12 +103,10 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget alternativeWidget: fallbackSubtitle, ); - // [style] is merged into the theme data as well as passed to the bar, so - // every slot below — the default back button and anything the caller - // supplied — resolves the same chain the bar itself does: [style], then the - // per-header theme, then the ambient app bar theme, then the app style. + // Apply the per-header theme as a theme; the bar resolves `style` over it + // and republishes the resolved behaviour to its slots. return StreamAppBarTheme( - data: headerTheme.merge(StreamAppBarThemeData(style: style)), + data: headerTheme, child: StreamAppBar( leading: leading, automaticallyImplyLeading: automaticallyImplyLeading, diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart b/packages/stream_chat_flutter/lib/src/pages/channel_page.dart similarity index 91% rename from packages/stream_chat_flutter/lib/src/channel/channel_page.dart rename to packages/stream_chat_flutter/lib/src/pages/channel_page.dart index e0ca75360b..b50f16963b 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/pages/channel_page.dart @@ -152,10 +152,10 @@ class _StreamChannelPageState extends State { /// The body of [StreamChannelPage]. /// -/// Reads [StreamScaffoldInsets] to provide correct [topPadding] and -/// [bottomPadding] to [StreamMessageListView], and positions the typing -/// indicator just above the composer (floating or regular) using the same -/// inset values. +/// Positions the typing indicator just above the composer (floating or docked) +/// via a bottom [SafeArea] over the floating-bar insets in `MediaQuery.padding` +/// (injected by [StreamScaffold]). [StreamMessageListView] reads the same insets +/// directly to pad its scroll content. class _ChannelPageBody extends StatelessWidget { const _ChannelPageBody({ required this.typingIndicator, @@ -173,8 +173,6 @@ class _ChannelPageBody extends StatelessWidget { @override Widget build(BuildContext context) { - final insets = StreamScaffoldInsets.of(context); - return Stack( children: [ StreamMessageListView( @@ -185,14 +183,14 @@ class _ChannelPageBody extends StatelessWidget { threadBuilder: (_, parentMessage) { return StreamThreadPage(parent: parentMessage!); }, - topPadding: insets.topPadding, - bottomPadding: insets.bottomPadding, ), Positioned( - bottom: insets.bottomPadding, left: 0, right: 0, - child: typingIndicator, + bottom: 0, + // A bottom SafeArea lifts the indicator above the composer / bottom + // bar — the scaffold injects its extent into MediaQuery.padding.bottom. + child: SafeArea(top: false, child: typingIndicator), ), ], ); diff --git a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart b/packages/stream_chat_flutter/lib/src/pages/thread_page.dart similarity index 97% rename from packages/stream_chat_flutter/lib/src/channel/thread_page.dart rename to packages/stream_chat_flutter/lib/src/pages/thread_page.dart index f12c1d7b67..c7676fcf42 100644 --- a/packages/stream_chat_flutter/lib/src/channel/thread_page.dart +++ b/packages/stream_chat_flutter/lib/src/pages/thread_page.dart @@ -136,8 +136,6 @@ class _ThreadBody extends StatelessWidget { @override Widget build(BuildContext context) { - final insets = StreamScaffoldInsets.of(context); - return StreamMessageListView( parentMessage: parent, initialScrollIndex: initialScrollIndex, @@ -145,8 +143,6 @@ class _ThreadBody extends StatelessWidget { onReplyTap: onReply, onEditMessageTap: onEditMessageTap, onViewInChannelTap: onViewInChannelTap, - topPadding: insets.topPadding, - bottomPadding: insets.bottomPadding, ); } } diff --git a/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_skeleton_loading.dart b/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_skeleton_loading.dart index 61878a4567..610f1fd774 100644 --- a/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_skeleton_loading.dart +++ b/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_skeleton_loading.dart @@ -10,16 +10,23 @@ class StreamChannelListSkeletonLoading extends StatelessWidget { const StreamChannelListSkeletonLoading({ super.key, this.itemCount = 7, + this.padding, }); /// The number of skeleton items to display. final int itemCount; + /// Padding around the skeleton list. + /// + /// When null, the list auto-insets from `MediaQuery.padding` — matching the + /// real [StreamChannelListView] so the layout doesn't shift once it loads. + final EdgeInsetsGeometry? padding; + @override Widget build(BuildContext context) { return StreamSkeletonLoading( child: ListView.separated( - padding: EdgeInsets.zero, + padding: padding, physics: const NeverScrollableScrollPhysics(), itemCount: itemCount, separatorBuilder: (context, index) => const SizedBox(height: 1), diff --git a/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_view.dart b/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_view.dart index 79eed6e1d9..e1a8fb49ac 100644 --- a/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/scroll_view/channel_scroll_view/stream_channel_list_view.dart @@ -333,7 +333,7 @@ class StreamChannelListView extends StatelessWidget { child: StreamLoadingSpinner(), ), ), - loadingBuilder: (context) => loadingBuilder?.call(context) ?? const StreamChannelListSkeletonLoading(), + loadingBuilder: (context) => loadingBuilder?.call(context) ?? StreamChannelListSkeletonLoading(padding: padding), errorBuilder: (context, error) { if (errorBuilder?.call(context, error) case final builder?) return builder; diff --git a/packages/stream_chat_flutter/lib/src/scroll_view/photo_gallery/stream_photo_gallery.dart b/packages/stream_chat_flutter/lib/src/scroll_view/photo_gallery/stream_photo_gallery.dart index ff3e6cd7b4..f19cdaa817 100644 --- a/packages/stream_chat_flutter/lib/src/scroll_view/photo_gallery/stream_photo_gallery.dart +++ b/packages/stream_chat_flutter/lib/src/scroll_view/photo_gallery/stream_photo_gallery.dart @@ -322,7 +322,7 @@ class StreamPhotoGallery extends StatelessWidget { primary: primary, physics: physics, shrinkWrap: shrinkWrap, - padding: padding ?? EdgeInsets.only(bottom: MediaQuery.paddingOf(context).bottom), + padding: padding, scrollController: scrollController, addAutomaticKeepAlives: addAutomaticKeepAlives, addRepaintBoundaries: addRepaintBoundaries, diff --git a/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_skeleton_loading.dart b/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_skeleton_loading.dart index 2ab714d71f..8e7637730c 100644 --- a/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_skeleton_loading.dart +++ b/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_skeleton_loading.dart @@ -10,16 +10,23 @@ class StreamThreadListSkeletonLoading extends StatelessWidget { const StreamThreadListSkeletonLoading({ super.key, this.itemCount = 6, + this.padding, }); /// The number of skeleton items to display. final int itemCount; + /// Padding around the skeleton list. + /// + /// When null, the list auto-insets from `MediaQuery.padding` — matching the + /// real [StreamThreadListView] so the layout doesn't shift once it loads. + final EdgeInsetsGeometry? padding; + @override Widget build(BuildContext context) { return StreamSkeletonLoading( child: ListView.separated( - padding: EdgeInsets.zero, + padding: padding, physics: const NeverScrollableScrollPhysics(), itemCount: itemCount, separatorBuilder: (context, index) => const SizedBox(height: 1), diff --git a/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_view.dart b/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_view.dart index 4fcd721dba..2a23ec5c72 100644 --- a/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/scroll_view/thread_scroll_view/stream_thread_list_view.dart @@ -334,8 +334,8 @@ class StreamThreadListView extends StatelessWidget { ), loadingBuilder: (context) => loadingBuilder?.call(context) ?? - const Center( - child: StreamThreadListSkeletonLoading(), + Center( + child: StreamThreadListSkeletonLoading(padding: padding), ), errorBuilder: (context, error) { if (errorBuilder?.call(context, error) case final builder?) return builder; diff --git a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart index 1a259c6012..d42a612c88 100644 --- a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart @@ -7,7 +7,7 @@ part 'message_composer_theme.g.theme.dart'; /// The message composer's visual/layout behavior — floating above the keyboard /// or docked at the bottom edge of the screen. /// -/// Mirrors [StreamAppBarBehavior] and [StreamBottomAppBarBehavior] so every +/// Mirrors [StreamToolbarBehavior] so every /// component names its placement the same way. /// /// When null on [StreamMessageComposerThemeData], the ambient [StreamAppStyle] diff --git a/packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart b/packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart deleted file mode 100644 index 50d8e7a671..0000000000 --- a/packages/stream_chat_flutter/lib/src/utils/app_bar_behavior.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// Resolves the effective [StreamAppBarBehavior] for a widget. -/// -/// Precedence, highest first: -/// -/// 1. [override] — a widget-local value, such as -/// [StreamAppBarStyle.behavior] passed to a header. -/// 2. [StreamAppBarStyle.behavior] from the ambient [StreamAppBarTheme]. -/// 3. The ambient [StreamAppStyle] — [StreamAppStyle.floating] maps to -/// [StreamAppBarBehavior.floating], [StreamAppStyle.regular] to -/// [StreamAppBarBehavior.regular]. -/// -/// Internal: shared by [StreamChannelHeader], [StreamChannelListHeader] and -/// [StreamBackButton] so the chain stays in one place. A natural home for this -/// is next to [StreamAppBarBehavior] in `stream_core_flutter`. -StreamAppBarBehavior resolveAppBarBehavior( - BuildContext context, { - StreamAppBarBehavior? override, -}) { - return override ?? - StreamAppBarTheme.of(context).style?.behavior ?? - (StreamTheme.of(context).appStyle.isFloating ? .floating : .regular); -} - -/// Whether the effective [StreamAppBarBehavior] is -/// [StreamAppBarBehavior.floating]. -/// -/// Convenience over [resolveAppBarBehavior] for the common case of driving a -/// boolean — a floating app bar, avatar shadow, or outlined back button. -bool isFloatingAppBar( - BuildContext context, { - StreamAppBarBehavior? override, -}) { - return switch (resolveAppBarBehavior(context, override: override)) { - .floating => true, - .regular => false, - }; -} diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 9d5e38808e..c8bda939e7 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -39,11 +39,9 @@ export 'src/channel/channel_header.dart'; export 'src/channel/channel_info.dart'; export 'src/channel/channel_list_header.dart'; export 'src/channel/channel_name.dart'; -export 'src/channel/channel_page.dart'; export 'src/channel/stream_channel_name.dart'; export 'src/channel/stream_draft_message_preview_text.dart'; export 'src/channel/stream_message_preview_text.dart'; -export 'src/channel/thread_page.dart'; // region SDK Design Refresh Components export 'src/components/avatar/stream_channel_avatar.dart'; export 'src/components/avatar/stream_user_avatar.dart'; @@ -115,6 +113,8 @@ export 'src/misc/stream_neumorphic_button.dart'; export 'src/misc/swipeable.dart'; export 'src/misc/thread_header.dart'; export 'src/misc/timestamp.dart'; +export 'src/pages/channel_page.dart'; +export 'src/pages/thread_page.dart'; export 'src/poll/creator/stream_poll_creator_sheet.dart'; export 'src/poll/creator/stream_poll_creator_widget.dart'; export 'src/poll/interactor/stream_poll_interactor.dart'; diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 153e5138ef..94c383c7c1 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -56,18 +56,7 @@ dependencies: shimmer: ^3.0.0 stream_chat_flutter_core: ^10.2.0 stream_core_flutter: - # The ignore below silences `invalid_dependency` because we occasionally - # pin stream_core_flutter to a git ref to iterate on it alongside this - # SDK between its releases. - # - # **Note:** Before publishing stream_chat_flutter, this MUST be swapped - # back to a pub version constraint — git deps are not allowed on pub.dev - # and will block the release. - # ignore: invalid_dependency - git: - url: https://github.com/GetStream/stream-core-flutter.git - ref: ab4b1fb0a0be01b4270823c5c2c7b0c21ad886f8 - path: packages/stream_core_flutter + path: /Users/xsahil03x/StudioProjects/stream-core-flutter/packages/stream_core_flutter stream_thumbnail: ^0.1.0 svg_icon_widget: ^0.0.1 synchronized: ^3.4.0 diff --git a/packages/stream_chat_flutter/test/scrollable_positioned_list/padding_scrollable_positioned_list_test.dart b/packages/stream_chat_flutter/test/scrollable_positioned_list/padding_scrollable_positioned_list_test.dart new file mode 100644 index 0000000000..4e7f5cd9be --- /dev/null +++ b/packages/stream_chat_flutter/test/scrollable_positioned_list/padding_scrollable_positioned_list_test.dart @@ -0,0 +1,187 @@ +// Verifies ScrollablePositionedList handles `padding` the same way a plain +// ListView (BoxScrollView) does — in particular, auto-consuming +// `MediaQuery.padding` when `padding` is null. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat_flutter/scrollable_positioned_list/scrollable_positioned_list.dart'; + +const screenHeight = 400.0; +const screenWidth = 400.0; +const itemHeight = screenHeight / 10.0; +const itemCount = 500; + +Future pumpList( + WidgetTester tester, { + required EdgeInsets? padding, + EdgeInsets mediaPadding = EdgeInsets.zero, + bool reverse = false, + int initialScrollIndex = 0, + double initialAlignment = 0.0, +}) async { + tester.view.devicePixelRatio = 1.0; + tester.view.physicalSize = const Size(screenWidth, screenHeight); + addTearDown(tester.view.reset); + + await tester.pumpWidget( + MaterialApp( + home: Builder( + builder: (context) => MediaQuery( + data: MediaQuery.of(context).copyWith(padding: mediaPadding, viewPadding: mediaPadding), + child: ScrollablePositionedList.builder( + itemCount: itemCount, + reverse: reverse, + padding: padding, + initialScrollIndex: initialScrollIndex, + initialAlignment: initialAlignment, + itemBuilder: (context, index) => SizedBox(height: itemHeight, child: Text('Item $index')), + ), + ), + ), + ), + ); +} + +// The concrete padding on every SliverPadding SPL emits, in tree order +// (leading?, center, trailing?). ListView emits exactly one. +List sliverPaddings(WidgetTester tester) { + return tester + .widgetList(find.byType(SliverPadding)) + .map((w) => w.padding.resolve(TextDirection.ltr)) + .toList(); +} + +// A plain ListView pumped identically, used as the parity oracle. +Future listViewFirstItemTop( + WidgetTester tester, { + required EdgeInsets? padding, + EdgeInsets mediaPadding = EdgeInsets.zero, +}) async { + tester.view.devicePixelRatio = 1.0; + tester.view.physicalSize = const Size(screenWidth, screenHeight); + addTearDown(tester.view.reset); + + await tester.pumpWidget( + MaterialApp( + home: Builder( + builder: (context) => MediaQuery( + data: MediaQuery.of(context).copyWith(padding: mediaPadding, viewPadding: mediaPadding), + child: ListView.builder( + itemCount: itemCount, + padding: padding, + itemBuilder: (context, index) => SizedBox(height: itemHeight, child: Text('LV $index')), + ), + ), + ), + ), + ); + return tester.getTopLeft(find.text('LV 0')).dy; +} + +void main() { + group('ScrollablePositionedList padding parity with ListView', () { + testWidgets('null padding auto-consumes MediaQuery.padding.top (like ListView)', (tester) async { + await pumpList(tester, padding: null, mediaPadding: const EdgeInsets.only(top: 50, bottom: 30)); + // First item rests below the top MediaQuery inset, not at y = 0. + expect(tester.getTopLeft(find.text('Item 0')).dy, 50); + }); + + testWidgets('reversed: null padding auto-consumes MediaQuery.padding.bottom', (tester) async { + await pumpList(tester, reverse: true, padding: null, mediaPadding: const EdgeInsets.only(bottom: 30)); + // Item 0 sits at the visual bottom of a reversed list; it clears the inset. + expect(tester.getBottomLeft(find.text('Item 0')).dy, screenHeight - 30); + }); + + testWidgets('matches a plain ListView for the same null-padding + MediaQuery', (tester) async { + await pumpList(tester, padding: null, mediaPadding: const EdgeInsets.only(top: 44)); + final splTop = tester.getTopLeft(find.text('Item 0')).dy; + + final lvTop = await listViewFirstItemTop(tester, padding: null, mediaPadding: const EdgeInsets.only(top: 44)); + + expect(splTop, lvTop); + }); + + testWidgets('explicit padding is used verbatim and ignores MediaQuery', (tester) async { + await pumpList(tester, padding: const EdgeInsets.only(top: 100), mediaPadding: const EdgeInsets.only(top: 50)); + expect(tester.getTopLeft(find.text('Item 0')).dy, 100); + }); + + testWidgets('reversed + explicit bottom padding: newest item (0) clears the bottom', (tester) async { + // Mirrors the message list: reverse:true, explicit padding. Item 0 (newest) + // sits at the visual bottom and must clear the composer inset. + await pumpList(tester, reverse: true, padding: const EdgeInsets.only(bottom: 100)); + expect(tester.getBottomLeft(find.text('Item 0')).dy, screenHeight - 100); + }); + + testWidgets('no padding and no MediaQuery inset keeps the first item at the top', (tester) async { + await pumpList(tester, padding: null); + expect(tester.getTopLeft(find.text('Item 0')).dy, 0); + }); + }); + + // SPL splits its padding across up to three slivers (leading / center / + // trailing) because of its centre anchor. These verify the auto-consumed + // inset is distributed so each edge is applied EXACTLY once — matching what + // ListView does with its single SliverPadding, regardless of anchor position. + group('3-sliver split places each edge inset exactly once', () { + const mq = EdgeInsets.only(top: 50, bottom: 30); + + testWidgets('anchor at first item: center owns top, trailing owns bottom', (tester) async { + await pumpList(tester, padding: null, mediaPadding: mq, initialScrollIndex: 0); + // No leading sliver (nothing before index 0): center(item 0) + trailing. + expect(sliverPaddings(tester), const [ + EdgeInsets.only(top: 50), // center, isFirst -> owns top + EdgeInsets.only(bottom: 30), // trailing -> owns bottom + ]); + }); + + testWidgets('anchor in the middle: leading owns top, center owns neither, trailing owns bottom', (tester) async { + // Interior anchor at mid-alignment keeps all three slivers on-screen/in-cache. + await pumpList(tester, padding: null, mediaPadding: mq, initialScrollIndex: 3, initialAlignment: 0.5); + expect(sliverPaddings(tester), const [ + EdgeInsets.only(top: 50), // leading -> owns top + EdgeInsets.zero, // center, neither first nor last -> no double inset + EdgeInsets.only(bottom: 30), // trailing -> owns bottom + ]); + }); + + testWidgets('anchor at last item: leading owns top, center owns bottom', (tester) async { + // Anchor the last item mid-viewport so both it (center) and the leading sliver stay mounted. + await pumpList(tester, padding: null, mediaPadding: mq, initialScrollIndex: itemCount - 1, initialAlignment: 0.5); + // No trailing sliver (nothing after the last index): leading + center(last). + expect(sliverPaddings(tester), const [ + EdgeInsets.only(top: 50), // leading -> owns top + EdgeInsets.only(bottom: 30), // center, isLast -> owns bottom + ]); + }); + + testWidgets('aggregate (first sliver top + last sliver bottom) equals ListView single SliverPadding', (tester) async { + // ListView oracle: one SliverPadding carrying the whole main-axis inset. + tester.view + ..devicePixelRatio = 1.0 + ..physicalSize = const Size(screenWidth, screenHeight); + addTearDown(tester.view.reset); + await tester.pumpWidget( + MaterialApp( + home: Builder( + builder: (context) => MediaQuery( + data: MediaQuery.of(context).copyWith(padding: mq, viewPadding: mq), + child: ListView.builder( + itemCount: itemCount, + itemBuilder: (context, index) => SizedBox(height: itemHeight, child: Text('LV $index')), + ), + ), + ), + ), + ); + final lvPad = sliverPaddings(tester).single; + expect(lvPad, mq); + + // SPL with an interior anchor: top from the first sliver, bottom from the last. + await pumpList(tester, padding: null, mediaPadding: mq, initialScrollIndex: 3, initialAlignment: 0.5); + final splPads = sliverPaddings(tester); + final aggregate = EdgeInsets.only(top: splPads.first.top, bottom: splPads.last.bottom); + expect(aggregate, lvPad); + }); + }); +} diff --git a/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart b/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart index 14ef0ffecf..389b0a672d 100644 --- a/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart @@ -509,8 +509,8 @@ void main() { Future pumpHeader( WidgetTester tester, { StreamAppStyle appStyle = StreamAppStyle.regular, - StreamAppBarBehavior? themeBehavior, - StreamAppBarBehavior? styleBehavior, + StreamToolbarBehavior? themeBehavior, + StreamToolbarBehavior? styleBehavior, }) async { final client = MockClient(); final clientState = MockClientState(); @@ -591,7 +591,7 @@ void main() { }); testWidgets('floats when the header theme says so, over a regular app style', (tester) async { - await pumpHeader(tester, themeBehavior: StreamAppBarBehavior.floating); + await pumpHeader(tester, themeBehavior: StreamToolbarBehavior.floating); expect(avatarIsFloating(tester), isTrue); }); @@ -600,15 +600,15 @@ void main() { await pumpHeader( tester, appStyle: StreamAppStyle.floating, - themeBehavior: StreamAppBarBehavior.floating, - styleBehavior: StreamAppBarBehavior.regular, + themeBehavior: StreamToolbarBehavior.floating, + styleBehavior: StreamToolbarBehavior.regular, ); expect(avatarIsFloating(tester), isNot(isTrue)); }); testWidgets('the default back button agrees with the avatar under the header theme', (tester) async { - await pumpHeader(tester, themeBehavior: StreamAppBarBehavior.floating); + await pumpHeader(tester, themeBehavior: StreamToolbarBehavior.floating); expect(backButtonIsFloating(tester), isTrue); expect(backButtonIsFloating(tester), avatarIsFloating(tester)); @@ -618,7 +618,7 @@ void main() { await pumpHeader( tester, appStyle: StreamAppStyle.floating, - styleBehavior: StreamAppBarBehavior.regular, + styleBehavior: StreamToolbarBehavior.regular, ); expect(backButtonIsFloating(tester), isNot(isTrue)); diff --git a/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart b/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart index eb4c607dae..519462f38a 100644 --- a/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart @@ -163,8 +163,8 @@ void main() { Future pumpHeader( WidgetTester tester, { StreamAppStyle appStyle = StreamAppStyle.regular, - StreamAppBarBehavior? themeBehavior, - StreamAppBarBehavior? styleBehavior, + StreamToolbarBehavior? themeBehavior, + StreamToolbarBehavior? styleBehavior, }) async { final client = MockClient(); final clientState = MockClientState(); @@ -215,7 +215,7 @@ void main() { }); testWidgets('floats when the header theme says so, over a regular app style', (tester) async { - await pumpHeader(tester, themeBehavior: StreamAppBarBehavior.floating); + await pumpHeader(tester, themeBehavior: StreamToolbarBehavior.floating); expect(avatarIsFloating(tester), isTrue); }); @@ -224,8 +224,8 @@ void main() { await pumpHeader( tester, appStyle: StreamAppStyle.floating, - themeBehavior: StreamAppBarBehavior.floating, - styleBehavior: StreamAppBarBehavior.regular, + themeBehavior: StreamToolbarBehavior.floating, + styleBehavior: StreamToolbarBehavior.regular, ); expect(avatarIsFloating(tester), isNot(isTrue)); diff --git a/packages/stream_chat_flutter/test/src/message_widget/stream_message_item_test.dart b/packages/stream_chat_flutter/test/src/message_widget/stream_message_item_test.dart new file mode 100644 index 0000000000..624f46f5ad --- /dev/null +++ b/packages/stream_chat_flutter/test/src/message_widget/stream_message_item_test.dart @@ -0,0 +1,192 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/semantics.dart' show CustomSemanticsAction; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import '../mocks.dart'; + +void main() { + final hanSolo = User(id: 'han-solo', name: 'Han Solo'); + + // On mobile the message text renders non-selectable, letting the item's + // MergeSemantics flatten the whole message into one node — the behavior + // these tests assert. (On desktop/web the selectable text keeps its own + // text-field node for selection support.) + setUp(() => CurrentPlatform.debugCurrentPlatformOverride = PlatformType.android); + tearDown(() => CurrentPlatform.debugCurrentPlatformOverride = null); + + Future pumpItem( + WidgetTester tester, { + required Message message, + StreamMessageAlignment alignment = StreamMessageAlignment.start, + StreamChatConfigurationData? configData, + }) async { + final client = MockClient(); + final clientState = MockClientState(); + final currentUser = OwnUser(id: 'current-user', name: 'Current User'); + + when(() => client.state).thenReturn(clientState); + when(() => clientState.currentUser).thenReturn(currentUser); + when(() => clientState.currentUserStream).thenAnswer((_) => Stream.value(currentUser)); + + await tester.pumpWidget( + MaterialApp( + home: StreamChat( + client: client, + themeData: StreamChatThemeData(), + configData: configData, + child: StreamMessageLayout( + data: StreamMessageLayoutData(alignment: alignment), + child: Scaffold( + // A generous maxWidth — the wide Ahem test font overflows the + // deleted-message row at the default bubble width. + body: Center(child: StreamMessageItem(message: message, maxWidth: 500)), + ), + ), + ), + ), + ); + await tester.pump(); + } + + group('StreamMessageItem a11y', () { + testWidgets('merges the whole item into a single message summary', (tester) async { + final handle = tester.ensureSemantics(); + final message = Message( + text: 'Are we still meeting tomorrow?', + user: hanSolo, + createdAt: DateTime.now(), + replyCount: 3, + ); + + await pumpItem(tester, message: message); + await tester.pumpAndSettle(); + + // One swipe stop carries the sender prefix, the message text, the + // thread replies count, and the footer's timestamp — in that order. + final summary = tester.getSemantics( + find.bySemanticsLabel( + RegExp( + 'Han Solo said.*Are we still meeting tomorrow.*3 replies.*Just now', + dotAll: true, + ), + ), + ); + + // The sender name is announced once — the footer username is excluded. + expect('Han Solo'.allMatches(summary.label).length, 1); + + handle.dispose(); + }); + + testWidgets('exposes the message-options custom action on the summary', (tester) async { + final handle = tester.ensureSemantics(); + final message = Message(text: 'Hello', user: hanSolo, createdAt: DateTime.now()); + + await pumpItem(tester, message: message); + await tester.pumpAndSettle(); + + final summary = tester.getSemantics(find.bySemanticsLabel(RegExp('Han Solo said'))); + expect( + summary, + isSemantics( + customActions: [const CustomSemanticsAction(label: 'Show message options')], + ), + ); + handle.dispose(); + }); + + testWidgets('keeps interactive content operable by skipping the merge', (tester) async { + final handle = tester.ensureSemantics(); + final message = Message( + user: hanSolo, + createdAt: DateTime.now(), + attachments: [ + Attachment( + type: AttachmentType.voiceRecording, + assetUrl: 'https://example.com/x.m4a', + uploadState: const UploadState.success(), + ), + ], + ); + + await pumpItem( + tester, + message: message, + configData: StreamChatConfigurationData( + // Stands in for the real voice player, whose controls must stay + // individually reachable. + attachmentBuilders: const [_PlayButtonAttachmentBuilder()], + ), + ); + + // Both controls remain independently operable nodes instead of being + // flattened into the message summary. + final play = tester.getSemantics(find.bySemanticsLabel('PLAY-SENTINEL')); + final speed = tester.getSemantics(find.bySemanticsLabel('SPEED-SENTINEL')); + expect(play, isSemantics(isButton: true, hasTapAction: true)); + expect(speed, isSemantics(isButton: true, hasTapAction: true)); + expect(play.isMergedIntoParent, isFalse); + expect(speed.isMergedIntoParent, isFalse); + handle.dispose(); + }); + + testWidgets('deleted message summary announces the sender', (tester) async { + final handle = tester.ensureSemantics(); + final message = Message(type: MessageType.deleted, user: hanSolo, createdAt: DateTime.now()); + + await pumpItem(tester, message: message); + await tester.pumpAndSettle(); + + expect( + find.bySemanticsLabel(RegExp('Han Solo, message deleted.', dotAll: true)), + findsOneWidget, + ); + handle.dispose(); + }); + }); +} + +// Renders a voice-recording attachment with two tappable controls — like the +// real player's play and speed buttons — so the test can assert interactive +// controls survive outside the item merge. +class _PlayButtonAttachmentBuilder extends StreamAttachmentWidgetBuilder { + const _PlayButtonAttachmentBuilder(); + + @override + bool canHandle(Message message, Map> attachments) { + return attachments.containsKey(AttachmentType.voiceRecording); + } + + @override + bool hasInteractiveControls( + Message message, + Map> attachments, + ) { + return true; + } + + @override + Widget? build( + BuildContext context, + Message message, + Map> attachments, + ) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Semantics( + button: true, + label: 'PLAY-SENTINEL', + child: GestureDetector(onTap: () {}, child: const SizedBox(width: 50, height: 50)), + ), + Semantics( + button: true, + label: 'SPEED-SENTINEL', + child: GestureDetector(onTap: () {}, child: const SizedBox(width: 50, height: 50)), + ), + ], + ); + } +} diff --git a/sample_app/lib/config/sample_app_config_screen.dart b/sample_app/lib/config/sample_app_config_screen.dart index 89b28e13c3..710b9cd241 100644 --- a/sample_app/lib/config/sample_app_config_screen.dart +++ b/sample_app/lib/config/sample_app_config_screen.dart @@ -3,7 +3,6 @@ import 'dart:io' show Platform; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:sample_app/config/sample_app_config.dart'; -import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Whether dynamic color extraction is supported on the current platform. @@ -28,9 +27,9 @@ class SampleAppConfigScreen extends StatelessWidget { appBar: StreamAppBar(title: const Text('Configuration')), body: Builder( builder: (context) { - final topInset = context.streamTopInset; + final topInset = MediaQuery.paddingOf(context).top; return SingleChildScrollView( - padding: EdgeInsets.fromLTRB(spacing.md, topInset, spacing.md, 0), + padding: EdgeInsets.symmetric(horizontal: spacing.md) + EdgeInsets.only(top: topInset), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/sample_app/lib/pages/advanced_options_page.dart b/sample_app/lib/pages/advanced_options_page.dart index c99d397b61..ff37ad2e7c 100644 --- a/sample_app/lib/pages/advanced_options_page.dart +++ b/sample_app/lib/pages/advanced_options_page.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/auth/auth_controller.dart'; import 'package:sample_app/routes/routes.dart'; -import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:sample_app/widgets/stream_version.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -106,7 +105,7 @@ class _AdvancedOptionsPageState extends State { appBar: StreamAppBar(title: const Text('Custom settings')), body: Builder( builder: (context) { - final topInset = context.streamTopInset; + final topInset = MediaQuery.paddingOf(context).top; return Padding( padding: EdgeInsets.fromLTRB(16, 16 + topInset, 16, 0), child: Form( diff --git a/sample_app/lib/pages/channel_file_display_screen.dart b/sample_app/lib/pages/channel_file_display_screen.dart index 362455f200..060853d122 100644 --- a/sample_app/lib/pages/channel_file_display_screen.dart +++ b/sample_app/lib/pages/channel_file_display_screen.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Lists every file shared in the enclosing channel, grouped by the @@ -46,7 +45,6 @@ class _ChannelFileDisplayScreenState extends State { body: ValueListenableBuilder>( valueListenable: _controller, builder: (context, value, _) { - final topInset = context.streamTopInset; return value.when( (items, nextPageKey, _) { // Flatten messages → individual file attachments paired with @@ -72,8 +70,10 @@ class _ChannelFileDisplayScreenState extends State { onEndOfPage: () async { if (nextPageKey != null) await _controller.loadMore(nextPageKey); }, + // No `padding` — the ListView auto-insets from the + // MediaQuery.padding injected by StreamScaffold (floating bars + // and the system safe area). child: ListView.builder( - padding: EdgeInsets.only(top: topInset), itemCount: rows.length, itemBuilder: (context, index) => rows[index].build(context), ), diff --git a/sample_app/lib/pages/channel_media_display_screen.dart b/sample_app/lib/pages/channel_media_display_screen.dart index c66e67749a..2974c472b9 100644 --- a/sample_app/lib/pages/channel_media_display_screen.dart +++ b/sample_app/lib/pages/channel_media_display_screen.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Lists every photo + video shared in the enclosing channel as a 3-up @@ -45,7 +44,7 @@ class _ChannelMediaDisplayScreenState extends State { body: ValueListenableBuilder>( valueListenable: _controller, builder: (context, value, _) { - final topInset = context.streamTopInset; + final topInset = MediaQuery.paddingOf(context).top; final spacing = context.streamSpacing; return value.when( (items, nextPageKey, _) { @@ -68,7 +67,7 @@ class _ChannelMediaDisplayScreenState extends State { }, child: StreamMediaGallery( attachments: attachments, - padding: EdgeInsets.fromLTRB(spacing.xxxs, topInset + spacing.xxxs, spacing.xxxs, spacing.xxxs), + padding: EdgeInsets.all(spacing.xxxs) + EdgeInsets.only(top: topInset), onItemTap: (index) => _openPreview(context, attachments, index), ), ); diff --git a/sample_app/lib/pages/chat_info_screen.dart b/sample_app/lib/pages/chat_info_screen.dart index c23ffb92a9..c286f7bd71 100644 --- a/sample_app/lib/pages/chat_info_screen.dart +++ b/sample_app/lib/pages/chat_info_screen.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:sample_app/pages/channel_file_display_screen.dart'; import 'package:sample_app/pages/channel_media_display_screen.dart'; import 'package:sample_app/pages/pinned_messages_screen.dart'; -import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Detail screen for a 1:1 chat correspondence. @@ -35,7 +34,7 @@ class ChatInfoScreen extends StatelessWidget { // top of the body so individual rows stay style-free. body: Builder( builder: (context) { - final topInset = context.streamTopInset; + final topInset = MediaQuery.paddingOf(context).top; return IconTheme.merge( data: const IconThemeData(size: 20), child: SingleChildScrollView( diff --git a/sample_app/lib/pages/group_chat_details_screen.dart b/sample_app/lib/pages/group_chat_details_screen.dart index cd72507997..6a332a3ed7 100644 --- a/sample_app/lib/pages/group_chat_details_screen.dart +++ b/sample_app/lib/pages/group_chat_details_screen.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/routes/routes.dart'; import 'package:sample_app/state/new_group_chat_state.dart'; -import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; class GroupChatDetailsScreen extends StatefulWidget { @@ -108,7 +107,7 @@ class _GroupChatDetailsScreenState extends State { message: statusString, child: Builder( builder: (context) { - final topInset = context.streamTopInset; + final topInset = MediaQuery.paddingOf(context).top; return Column( children: [ if (topInset > 0) SizedBox(height: topInset), @@ -172,6 +171,7 @@ class _GroupChatDetailsScreenState extends State { behavior: HitTestBehavior.opaque, onPanDown: (_) => FocusScope.of(context).unfocus(), child: ListView.separated( + padding: EdgeInsets.only(bottom: MediaQuery.paddingOf(context).bottom), itemCount: widget.groupChatState.users.length + 1, separatorBuilder: (_, __) => Container( height: 1, diff --git a/sample_app/lib/pages/group_info_screen.dart b/sample_app/lib/pages/group_info_screen.dart index 53f66d3b84..48d48bd554 100644 --- a/sample_app/lib/pages/group_info_screen.dart +++ b/sample_app/lib/pages/group_info_screen.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:sample_app/pages/channel_file_display_screen.dart'; import 'package:sample_app/pages/channel_media_display_screen.dart'; import 'package:sample_app/pages/pinned_messages_screen.dart'; -import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:sample_app/widgets/add_members_sheet.dart'; import 'package:sample_app/widgets/all_members_sheet.dart'; import 'package:sample_app/widgets/edit_group_sheet.dart'; @@ -54,7 +53,7 @@ class GroupInfoScreen extends StatelessWidget { // top of the body so individual rows stay style-free. body: Builder( builder: (context) { - final topInset = context.streamTopInset; + final topInset = MediaQuery.paddingOf(context).top; return IconTheme.merge( data: const IconThemeData(size: 20), child: SingleChildScrollView( diff --git a/sample_app/lib/pages/new_chat_screen.dart b/sample_app/lib/pages/new_chat_screen.dart index b323c0d750..ce49b62776 100644 --- a/sample_app/lib/pages/new_chat_screen.dart +++ b/sample_app/lib/pages/new_chat_screen.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/routes/routes.dart'; -import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:sample_app/widgets/chips_input_text_field.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -144,7 +143,7 @@ class _NewChatScreenState extends State { appBar: StreamAppBar(title: const Text('New Chat')), body: StreamConnectionStatusBuilder( statusBuilder: (context, status) { - final topInset = context.streamTopInset; + final topInset = MediaQuery.paddingOf(context).top; var statusString = ''; var showStatus = true; @@ -281,6 +280,7 @@ class _NewChatScreenState extends State { onPanDown: (_) => FocusScope.of(context).unfocus(), child: StreamUserListView( controller: userListController, + padding: EdgeInsets.only(bottom: MediaQuery.paddingOf(context).bottom), onUserTap: (user) { _controller.clear(); if (!_selectedUsers.contains(user)) { diff --git a/sample_app/lib/pages/new_group_chat_screen.dart b/sample_app/lib/pages/new_group_chat_screen.dart index 338c0b54d3..2ed56a2f33 100644 --- a/sample_app/lib/pages/new_group_chat_screen.dart +++ b/sample_app/lib/pages/new_group_chat_screen.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/routes/routes.dart'; import 'package:sample_app/state/new_group_chat_state.dart'; -import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:sample_app/widgets/search_text_field.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -111,7 +110,7 @@ class _NewGroupChatScreenState extends State { child: NestedScrollView( floatHeaderSlivers: true, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { - final topInset = context.streamTopInset; + final topInset = MediaQuery.paddingOf(context).top; return [ if (topInset > 0) SliverToBoxAdapter(child: SizedBox(height: topInset)), SliverToBoxAdapter( @@ -209,6 +208,7 @@ class _NewGroupChatScreenState extends State { onPanDown: (_) => FocusScope.of(context).unfocus(), child: StreamUserListView( controller: userListController, + padding: EdgeInsets.only(bottom: MediaQuery.paddingOf(context).bottom), itemBuilder: (context, items, index, defaultWidget) { return defaultWidget.copyWith( selected: state.users.contains(items[index]), diff --git a/sample_app/lib/pages/pinned_messages_screen.dart b/sample_app/lib/pages/pinned_messages_screen.dart index 7828c72c9b..602ae144be 100644 --- a/sample_app/lib/pages/pinned_messages_screen.dart +++ b/sample_app/lib/pages/pinned_messages_screen.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/routes/routes.dart'; -import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Lists every pinned message in the enclosing channel. @@ -43,7 +42,7 @@ class _PinnedMessagesScreenState extends State { appBar: StreamAppBar(title: const Text('Pinned Messages')), body: Builder( builder: (context) { - final topInset = context.streamTopInset; + final topInset = MediaQuery.paddingOf(context).top; return StreamMessageSearchListView( controller: _controller, padding: EdgeInsets.only(top: topInset), diff --git a/sample_app/lib/utils/scaffold_insets.dart b/sample_app/lib/utils/scaffold_insets.dart deleted file mode 100644 index 47e12098a3..0000000000 --- a/sample_app/lib/utils/scaffold_insets.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// Reads the surrounding [StreamScaffold]'s floating-chrome insets. -/// -/// Both getters return `0` when there is no [StreamScaffoldInsets] ancestor, or -/// when the chrome is not floating — so a page can add them unconditionally and -/// get the right layout in either app style. -extension StreamScaffoldInsetsContext on BuildContext { - /// Space taken by a floating app bar at the top, including the status bar. - double get streamTopInset => StreamScaffoldInsets.maybeOf(this)?.topPadding ?? 0; - - /// Space taken by a floating bottom widget, including the home indicator. - double get streamBottomInset => StreamScaffoldInsets.maybeOf(this)?.bottomPadding ?? 0; -} diff --git a/sample_app/lib/widgets/channel_list.dart b/sample_app/lib/widgets/channel_list.dart index c813994078..fb43d15d8b 100644 --- a/sample_app/lib/widgets/channel_list.dart +++ b/sample_app/lib/widgets/channel_list.dart @@ -5,7 +5,6 @@ import 'package:flutter/rendering.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/routes/routes.dart'; -import 'package:sample_app/utils/scaffold_insets.dart'; import 'package:sample_app/widgets/channel_detail_sheet.dart'; import 'package:sample_app/widgets/search_text_field.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -88,7 +87,7 @@ class _ChannelList extends State { // When the app bar is floating it overlaps this scroll view from // the top. Insert a spacer sliver so the search bar starts below // the visible bottom edge of the floating bar. - final topInset = context.streamTopInset; + final topInset = MediaQuery.paddingOf(context).top; return [ if (topInset > 0) SliverToBoxAdapter(child: SizedBox(height: topInset)), SliverToBoxAdapter( @@ -115,14 +114,18 @@ class _ChannelListDefault extends StatelessWidget { @override Widget build(BuildContext context) { - final bottomPadding = context.streamBottomInset; + final bottomPadding = MediaQuery.paddingOf(context).bottom; return SlidableAutoCloseBehavior( child: RefreshIndicator( onRefresh: channelListController.refresh, child: StreamChannelListView( controller: channelListController, - padding: bottomPadding > 0 ? EdgeInsets.only(bottom: bottomPadding) : null, + // Always explicit (never null) — the header already handles the top + // inset via a spacer sliver, so the list must NOT auto-consume the + // injected top padding a second time. A null padding would do exactly + // that whenever bottomPadding is 0 (e.g. a docked bottom bar). + padding: EdgeInsets.only(bottom: bottomPadding), itemBuilder: (context, channels, index, defaultWidget) { final channel = channels[index]; diff --git a/sample_app/macos/Runner.xcodeproj/project.pbxproj b/sample_app/macos/Runner.xcodeproj/project.pbxproj index 0204e8aab2..6b034893f5 100644 --- a/sample_app/macos/Runner.xcodeproj/project.pbxproj +++ b/sample_app/macos/Runner.xcodeproj/project.pbxproj @@ -28,6 +28,7 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -70,6 +71,7 @@ 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 782D013032AAC6BDCC56A273 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 929AC42CE2CDA27FE9235234 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; @@ -83,6 +85,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, 1E52A3376056853520695B44 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -135,6 +138,7 @@ 33CEB47122A05771004F2AC0 /* Flutter */ = { isa = PBXGroup; children = ( + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, @@ -189,7 +193,6 @@ 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, 5EA8C195DB09CB61CDB56B17 /* [CP] Embed Pods Frameworks */, - 61600C7AED8D72CB17EDB92D /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -197,6 +200,9 @@ 33CC11202044C79F0003C045 /* PBXTargetDependency */, ); name = Runner; + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); productName = Runner; productReference = 33CC10ED2044A3C60003C045 /* stream_chat_v1.app */; productType = "com.apple.product-type.application"; @@ -235,6 +241,9 @@ Base, ); mainGroup = 33CC10E42044A3C60003C045; + packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */, + ); productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -336,23 +345,6 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 61600C7AED8D72CB17EDB92D /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -658,6 +650,20 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 33CC10E52044A3C60003C045 /* Project object */; } diff --git a/sample_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/sample_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index ce0fd11fd0..4c9b426aa4 100644 --- a/sample_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/sample_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -5,6 +5,24 @@ + + + + + + + + + + Date: Thu, 6 Aug 2026 19:04:09 +0200 Subject: [PATCH 73/87] docs(ui): address channel-page PR review doc findings - StreamThreadHeader.onBackPressed: note it's also ignored when automaticallyImplyLeading is false (not only when leading is set). - StreamChatConfigurationData.messageListViewConfiguration: fix the dangling [config] doc reference to [StreamMessageListView.config]. - MessageComposerInput / StreamChatMessageInput isFloating: document the false default. Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/stream_chat_flutter/lib/src/misc/thread_header.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/misc/thread_header.dart b/packages/stream_chat_flutter/lib/src/misc/thread_header.dart index dcc9989518..4ca82604f8 100644 --- a/packages/stream_chat_flutter/lib/src/misc/thread_header.dart +++ b/packages/stream_chat_flutter/lib/src/misc/thread_header.dart @@ -42,7 +42,8 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget /// Called when the default [StreamBackButton] is pressed, replacing its /// default `Navigator.maybePop`. /// - /// Ignored when [leading] is provided. + /// Ignored when [leading] is provided or [automaticallyImplyLeading] is + /// false, since no default back button is built in those cases. final VoidCallback? onBackPressed; /// {@macro StreamAppBar.title} From ffb6485c20a1a8654dfb34638308329208c9612b Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 6 Aug 2026 19:04:27 +0200 Subject: [PATCH 74/87] docs(ui): fix dangling [config] ref + document isFloating default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to 277c60e — the previous commit only captured thread_header.dart because of a bad pathspec. - StreamChatConfigurationData.messageListViewConfiguration: dangling [config] -> [StreamMessageListView.config]. - MessageComposerInput / StreamChatMessageInput isFloating: document the false default. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../message_composer/message_composer_component_props.dart | 2 ++ .../lib/src/message_input/stream_chat_message_input.dart | 2 ++ .../stream_chat_flutter/lib/src/stream_chat_configuration.dart | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_component_props.dart b/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_component_props.dart index 5a76b977b7..8967af8ee5 100644 --- a/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_component_props.dart +++ b/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_component_props.dart @@ -55,6 +55,8 @@ class MessageComposerComponentProps { final StreamMessageComposerController controller; /// Whether the message composer is floating. + /// + /// Defaults to false. final bool isFloating; /// The callback for when the send button is pressed. diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_chat_message_input.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_chat_message_input.dart index 60ab8ccdb5..3a67ecf434 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_chat_message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_chat_message_input.dart @@ -96,6 +96,8 @@ class StreamChatMessageInput extends StatefulWidget { final bool autocorrect; /// Whether the message composer is floating. + /// + /// Defaults to false. final bool isFloating; @override diff --git a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart index 62c46a3ce1..9154ccd3f1 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart @@ -265,7 +265,8 @@ class StreamChatConfigurationData { final StreamReactionsPosition? reactionPosition; /// The default [StreamMessageListViewConfiguration] applied to every - /// [StreamMessageListView] that does not provide its own explicit [config]. + /// [StreamMessageListView] that does not provide its own explicit + /// [StreamMessageListView.config]. /// /// Defaults to [StreamMessageListViewConfiguration] with all defaults. final StreamMessageListViewConfiguration messageListViewConfiguration; From a70661f2a2993d6e67822e9cae540ed16300d149 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 6 Aug 2026 19:06:40 +0200 Subject: [PATCH 75/87] docs(ui): tighten StreamThreadHeader.onBackPressed per Effective Dart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Drop the redundant "since no default back button is built" clause (the two conditions already imply it) — prefer brevity. - Link [Navigator.maybePop] instead of backtick-quoting it, so dart doc resolves the reference. Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/stream_chat_flutter/lib/src/misc/thread_header.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/misc/thread_header.dart b/packages/stream_chat_flutter/lib/src/misc/thread_header.dart index 4ca82604f8..70ace2cf49 100644 --- a/packages/stream_chat_flutter/lib/src/misc/thread_header.dart +++ b/packages/stream_chat_flutter/lib/src/misc/thread_header.dart @@ -40,10 +40,10 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget final bool automaticallyImplyLeading; /// Called when the default [StreamBackButton] is pressed, replacing its - /// default `Navigator.maybePop`. + /// default [Navigator.maybePop]. /// /// Ignored when [leading] is provided or [automaticallyImplyLeading] is - /// false, since no default back button is built in those cases. + /// false. final VoidCallback? onBackPressed; /// {@macro StreamAppBar.title} From 00e420b9d6040acde9c7a7ee722e341529308431 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 6 Aug 2026 19:15:39 +0200 Subject: [PATCH 76/87] test(ui): cover ItemPosition content edges + correct their doc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The content* edges are always populated by PositionedList (equal to the item* edges when there's no inset), never null-when-unpadded as the doc claimed — the null case is only for externally-built ItemPositions that omit them. Fix the doc to say so and add SPL coverage for the previously-untested fields: - under a leading inset, content* is content-relative (item 0 flush with the content top reads 0) while item* stays viewport-relative (0.25); - with no inset, content* equals item*. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/item_positions_listener.dart | 8 +- .../content_edges_test.dart | 79 +++++++++++++++++++ 2 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 packages/stream_chat_flutter/test/scrollable_positioned_list/content_edges_test.dart diff --git a/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart b/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart index 3e7fdd694b..58a212eae2 100644 --- a/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart +++ b/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart @@ -46,9 +46,11 @@ class ItemPosition { /// Distance in proportion of the visible content's main axis length from the /// leading edge of that content to the leading edge of the item. /// - /// The visible content is the area inside the list's padding. `null` when the - /// list has no padding. Use for overlays inside the padded area, such as under - /// a floating bar; scroll logic keeps using [itemLeadingEdge]. + /// The visible content is the area inside the list's padding. Use this for + /// overlays inside that area, such as under a floating bar; scroll logic keeps + /// using [itemLeadingEdge]. Equal to [itemLeadingEdge] when the list has no + /// inset, and `null` only when the source omits it (a list always provides + /// it). final double? contentLeadingEdge; /// Distance in proportion of the visible content's main axis length from the diff --git a/packages/stream_chat_flutter/test/scrollable_positioned_list/content_edges_test.dart b/packages/stream_chat_flutter/test/scrollable_positioned_list/content_edges_test.dart new file mode 100644 index 0000000000..844bb6d444 --- /dev/null +++ b/packages/stream_chat_flutter/test/scrollable_positioned_list/content_edges_test.dart @@ -0,0 +1,79 @@ +// Verifies ItemPosition.contentLeadingEdge / contentTrailingEdge — the +// content-relative edges (measured inside the list's padding) that overlays +// like the floating date divider key off, as distinct from the +// viewport-relative itemLeadingEdge / itemTrailingEdge that scroll mechanics +// use. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat_flutter/scrollable_positioned_list/scrollable_positioned_list.dart'; + +const screenHeight = 400.0; +const screenWidth = 400.0; +const itemHeight = 40.0; +const itemCount = 500; + +Future pumpList( + WidgetTester tester, { + required EdgeInsets? padding, + bool reverse = false, +}) async { + tester.view.devicePixelRatio = 1.0; + tester.view.physicalSize = const Size(screenWidth, screenHeight); + addTearDown(tester.view.reset); + + final positionsListener = ItemPositionsListener.create(); + await tester.pumpWidget( + MaterialApp( + home: ScrollablePositionedList.builder( + itemCount: itemCount, + reverse: reverse, + padding: padding, + itemPositionsListener: positionsListener, + itemBuilder: (context, index) => SizedBox(height: itemHeight, child: Text('Item $index')), + ), + ), + ); + return positionsListener; +} + +ItemPosition positionOf(ItemPositionsListener listener, int index) { + return listener.itemPositions.value.firstWhere((p) => p.index == index); +} + +void main() { + group('ItemPosition content edges', () { + testWidgets('are content-relative under a leading inset, while the item edges stay viewport-relative', ( + tester, + ) async { + // A 100px top inset in a 400px viewport: item 0 rests flush against the + // content top, and the content area spans the remaining 300px. + final listener = await pumpList(tester, padding: const EdgeInsets.only(top: 100)); + + // Sanity: item 0 renders below the inset, not at the viewport top. + expect(tester.getTopLeft(find.text('Item 0')).dy, 100); + + final position = positionOf(listener, 0); + + // Viewport-relative: item 0 sits 100/400 down from the viewport's top. + expect(position.itemLeadingEdge, closeTo(0.25, 1e-6)); + expect(position.itemTrailingEdge, closeTo(0.35, 1e-6)); + + // Content-relative: measured inside the 100px inset (content extent 300), + // item 0 is flush with the content's leading edge, so it reads 0. + expect(position.contentLeadingEdge, closeTo(0, 1e-6)); + expect(position.contentTrailingEdge, closeTo(40 / 300, 1e-6)); + }); + + testWidgets('equal the viewport edges when the list has no inset', (tester) async { + final listener = await pumpList(tester, padding: null); + + final positions = listener.itemPositions.value; + expect(positions, isNotEmpty); + for (final position in positions) { + expect(position.contentLeadingEdge, closeTo(position.itemLeadingEdge, 1e-9)); + expect(position.contentTrailingEdge, closeTo(position.itemTrailingEdge, 1e-9)); + } + }); + }); +} From b05efccc6651ffeeafb1fe64410223b6afaefdda Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 7 Aug 2026 09:26:24 +0200 Subject: [PATCH 77/87] fix(repo): point stream_core_flutter at the core PR ref for CI The dependency had been switched to a local absolute path for cross-repo iteration, which breaks pub get on CI. Restore the git dependency (core PR #146, ref 8425a0f8) in pubspec.yaml, melos.yaml, and docs_screenshots. Local dev keeps using the path override in the gitignored pubspec_overrides.yaml. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/docs_screenshots/pubspec.yaml | 5 ++++- melos.yaml | 5 ++++- packages/stream_chat_flutter/pubspec.yaml | 13 ++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index 6b5eb4fa05..8a4e1c916d 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -20,7 +20,10 @@ dependencies: record: ^6.2.0 stream_chat_flutter: ^10.2.0 stream_core_flutter: - path: /Users/xsahil03x/StudioProjects/stream-core-flutter/packages/stream_core_flutter + git: + url: https://github.com/GetStream/stream-core-flutter.git + ref: 8425a0f80ef9079a07605f96d775d8057f6ca58c + path: packages/stream_core_flutter dev_dependencies: alchemist: ^0.14.0 diff --git a/melos.yaml b/melos.yaml index 2dae81e026..5259ea78ad 100644 --- a/melos.yaml +++ b/melos.yaml @@ -105,7 +105,10 @@ command: streaming_shared_preferences: ^2.0.0 svg_icon_widget: ^0.0.1 stream_core_flutter: - path: /Users/xsahil03x/StudioProjects/stream-core-flutter/packages/stream_core_flutter + git: + url: https://github.com/GetStream/stream-core-flutter.git + ref: 8425a0f80ef9079a07605f96d775d8057f6ca58c + path: packages/stream_core_flutter stream_thumbnail: ^0.1.0 synchronized: ^3.4.0 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 94c383c7c1..f09f666d46 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -56,7 +56,18 @@ dependencies: shimmer: ^3.0.0 stream_chat_flutter_core: ^10.2.0 stream_core_flutter: - path: /Users/xsahil03x/StudioProjects/stream-core-flutter/packages/stream_core_flutter + # The ignore below silences `invalid_dependency` because we occasionally + # pin stream_core_flutter to a git ref to iterate on it alongside this + # SDK between its releases. + # + # **Note:** Before publishing stream_chat_flutter, this MUST be swapped + # back to a pub version constraint — git deps are not allowed on pub.dev + # and will block the release. + # ignore: invalid_dependency + git: + url: https://github.com/GetStream/stream-core-flutter.git + ref: 8425a0f80ef9079a07605f96d775d8057f6ca58c + path: packages/stream_core_flutter stream_thumbnail: ^0.1.0 svg_icon_widget: ^0.0.1 synchronized: ^3.4.0 From be12eb684813bbd665ef81e2a0db43bc9ce1db7d Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 7 Aug 2026 09:26:25 +0200 Subject: [PATCH 78/87] test(ui): drop StreamMessageItem a11y tests without backing impl Added in a WIP checkpoint, these semantics tests assert a merged-summary behavior with no corresponding implementation on this branch, so they fail (getSemantics finds no matching node). The a11y work can land in its own PR. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../stream_message_item_test.dart | 192 ------------------ 1 file changed, 192 deletions(-) delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/stream_message_item_test.dart diff --git a/packages/stream_chat_flutter/test/src/message_widget/stream_message_item_test.dart b/packages/stream_chat_flutter/test/src/message_widget/stream_message_item_test.dart deleted file mode 100644 index 624f46f5ad..0000000000 --- a/packages/stream_chat_flutter/test/src/message_widget/stream_message_item_test.dart +++ /dev/null @@ -1,192 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/semantics.dart' show CustomSemanticsAction; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -import '../mocks.dart'; - -void main() { - final hanSolo = User(id: 'han-solo', name: 'Han Solo'); - - // On mobile the message text renders non-selectable, letting the item's - // MergeSemantics flatten the whole message into one node — the behavior - // these tests assert. (On desktop/web the selectable text keeps its own - // text-field node for selection support.) - setUp(() => CurrentPlatform.debugCurrentPlatformOverride = PlatformType.android); - tearDown(() => CurrentPlatform.debugCurrentPlatformOverride = null); - - Future pumpItem( - WidgetTester tester, { - required Message message, - StreamMessageAlignment alignment = StreamMessageAlignment.start, - StreamChatConfigurationData? configData, - }) async { - final client = MockClient(); - final clientState = MockClientState(); - final currentUser = OwnUser(id: 'current-user', name: 'Current User'); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(currentUser); - when(() => clientState.currentUserStream).thenAnswer((_) => Stream.value(currentUser)); - - await tester.pumpWidget( - MaterialApp( - home: StreamChat( - client: client, - themeData: StreamChatThemeData(), - configData: configData, - child: StreamMessageLayout( - data: StreamMessageLayoutData(alignment: alignment), - child: Scaffold( - // A generous maxWidth — the wide Ahem test font overflows the - // deleted-message row at the default bubble width. - body: Center(child: StreamMessageItem(message: message, maxWidth: 500)), - ), - ), - ), - ), - ); - await tester.pump(); - } - - group('StreamMessageItem a11y', () { - testWidgets('merges the whole item into a single message summary', (tester) async { - final handle = tester.ensureSemantics(); - final message = Message( - text: 'Are we still meeting tomorrow?', - user: hanSolo, - createdAt: DateTime.now(), - replyCount: 3, - ); - - await pumpItem(tester, message: message); - await tester.pumpAndSettle(); - - // One swipe stop carries the sender prefix, the message text, the - // thread replies count, and the footer's timestamp — in that order. - final summary = tester.getSemantics( - find.bySemanticsLabel( - RegExp( - 'Han Solo said.*Are we still meeting tomorrow.*3 replies.*Just now', - dotAll: true, - ), - ), - ); - - // The sender name is announced once — the footer username is excluded. - expect('Han Solo'.allMatches(summary.label).length, 1); - - handle.dispose(); - }); - - testWidgets('exposes the message-options custom action on the summary', (tester) async { - final handle = tester.ensureSemantics(); - final message = Message(text: 'Hello', user: hanSolo, createdAt: DateTime.now()); - - await pumpItem(tester, message: message); - await tester.pumpAndSettle(); - - final summary = tester.getSemantics(find.bySemanticsLabel(RegExp('Han Solo said'))); - expect( - summary, - isSemantics( - customActions: [const CustomSemanticsAction(label: 'Show message options')], - ), - ); - handle.dispose(); - }); - - testWidgets('keeps interactive content operable by skipping the merge', (tester) async { - final handle = tester.ensureSemantics(); - final message = Message( - user: hanSolo, - createdAt: DateTime.now(), - attachments: [ - Attachment( - type: AttachmentType.voiceRecording, - assetUrl: 'https://example.com/x.m4a', - uploadState: const UploadState.success(), - ), - ], - ); - - await pumpItem( - tester, - message: message, - configData: StreamChatConfigurationData( - // Stands in for the real voice player, whose controls must stay - // individually reachable. - attachmentBuilders: const [_PlayButtonAttachmentBuilder()], - ), - ); - - // Both controls remain independently operable nodes instead of being - // flattened into the message summary. - final play = tester.getSemantics(find.bySemanticsLabel('PLAY-SENTINEL')); - final speed = tester.getSemantics(find.bySemanticsLabel('SPEED-SENTINEL')); - expect(play, isSemantics(isButton: true, hasTapAction: true)); - expect(speed, isSemantics(isButton: true, hasTapAction: true)); - expect(play.isMergedIntoParent, isFalse); - expect(speed.isMergedIntoParent, isFalse); - handle.dispose(); - }); - - testWidgets('deleted message summary announces the sender', (tester) async { - final handle = tester.ensureSemantics(); - final message = Message(type: MessageType.deleted, user: hanSolo, createdAt: DateTime.now()); - - await pumpItem(tester, message: message); - await tester.pumpAndSettle(); - - expect( - find.bySemanticsLabel(RegExp('Han Solo, message deleted.', dotAll: true)), - findsOneWidget, - ); - handle.dispose(); - }); - }); -} - -// Renders a voice-recording attachment with two tappable controls — like the -// real player's play and speed buttons — so the test can assert interactive -// controls survive outside the item merge. -class _PlayButtonAttachmentBuilder extends StreamAttachmentWidgetBuilder { - const _PlayButtonAttachmentBuilder(); - - @override - bool canHandle(Message message, Map> attachments) { - return attachments.containsKey(AttachmentType.voiceRecording); - } - - @override - bool hasInteractiveControls( - Message message, - Map> attachments, - ) { - return true; - } - - @override - Widget? build( - BuildContext context, - Message message, - Map> attachments, - ) { - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - Semantics( - button: true, - label: 'PLAY-SENTINEL', - child: GestureDetector(onTap: () {}, child: const SizedBox(width: 50, height: 50)), - ), - Semantics( - button: true, - label: 'SPEED-SENTINEL', - child: GestureDetector(onTap: () {}, child: const SizedBox(width: 50, height: 50)), - ), - ], - ); - } -} From d5e807a3171e88cbffc88c79ea0df053e71aea19 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 7 Aug 2026 09:26:25 +0200 Subject: [PATCH 79/87] refactor(ui): adopt StreamSurfaceStyle and address PR review Replace StreamAppStyle / StreamMessageComposerBehavior with the unified StreamSurfaceStyle across the composer, headers, theme, and sample app, and drive the composer's collapsing safe area with StreamSafeArea.driven. Align dartdoc with the style guide (private members use //, US spelling, contract-not-implementation, documented null fallbacks) and remove dead code. Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/stream_chat_flutter/CHANGELOG.md | 7 +- .../src/item_positions_listener.dart | 6 +- .../lib/src/channel/channel_header.dart | 12 +- .../lib/src/channel/channel_list_header.dart | 10 +- .../avatar/stream_channel_avatar.dart | 4 +- .../components/avatar/stream_user_avatar.dart | 4 +- .../avatar/stream_user_avatar_group.dart | 4 +- .../message_composer_input.dart | 2 +- .../media_gallery/stream_media_gallery.dart | 51 ++--- .../stream_message_composer.dart | 196 ++++++++---------- .../message_list_view/message_list_view.dart | 31 ++- .../lib/src/misc/back_button.dart | 6 +- .../lib/src/misc/thread_header.dart | 2 +- .../lib/src/pages/channel_page.dart | 18 +- .../lib/src/pages/thread_page.dart | 4 +- .../lib/src/stream_chat_configuration.dart | 3 +- .../lib/src/theme/message_composer_theme.dart | 56 ++--- .../theme/message_composer_theme.g.theme.dart | 16 +- .../test/src/channel/channel_header_test.dart | 32 +-- .../src/channel/channel_list_header_test.dart | 26 +-- .../test/src/channel/channel_page_test.dart | 23 +- .../test/src/channel/thread_page_test.dart | 21 +- ... message_composer_surface_style_test.dart} | 98 ++++++--- .../theme/message_composer_theme_test.dart | 62 +++--- sample_app/lib/app.dart | 10 +- sample_app/lib/config/sample_app_config.dart | 20 +- .../lib/config/sample_app_config_screen.dart | 16 +- .../pages/channel_file_display_screen.dart | 79 ++++--- .../pages/channel_media_display_screen.dart | 3 - sample_app/lib/pages/group_info_screen.dart | 15 +- .../lib/pages/new_group_chat_screen.dart | 102 ++++----- .../lib/pages/pinned_messages_screen.dart | 14 +- sample_app/lib/widgets/channel_list.dart | 37 ++-- 33 files changed, 476 insertions(+), 514 deletions(-) rename packages/stream_chat_flutter/test/src/message_input/{message_composer_behavior_test.dart => message_composer_surface_style_test.dart} (58%) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 3feadaf023..583e988ac2 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -11,13 +11,12 @@ - Added `StreamChannelPage` — a ready-to-use channel page widget that wires up `StreamChannelHeader`, `StreamMessageListView`, and `StreamMessageComposer` with floating or docked layout driven by the active app style. - Added `StreamThreadPage` — a ready-to-use thread page widget with the same floating/docked layout support, plus an `onBackPressed` callback that replaces the header back button's default pop. - Added `onBackPressed` to `StreamChannelHeader` and `StreamThreadHeader` — replaces the default back button's `Navigator.maybePop` without rebuilding the whole `leading`, so callers keep the header's default unread badge. Ignored when `leading` is supplied. -- Added `StreamMessageComposerBehavior` and `MessageComposerProps.behavior` — explicitly controls whether `StreamMessageComposer` renders `floating` or `regular`. When null it falls back to `StreamMessageComposerThemeData.behavior`, and then to the ambient `StreamAppStyle`. +- Added `MessageComposerProps.surfaceStyle` (a `StreamSurfaceStyle`) — explicitly controls whether `StreamMessageComposer` renders `floating` or `regular`. When null it falls back to `StreamMessageComposerThemeData.surfaceStyle`, and then to the ambient `StreamSurfaceStyle`. - Added `StreamMessageComposerTheme` and `StreamMessageComposerThemeData` — a component theme for the composer, also available globally as `StreamChatThemeData.messageComposerTheme`. - Added `StreamMessageListView.config` — accepts an explicit `StreamMessageListViewConfiguration` per widget; falls back to `StreamChatConfigurationData.messageListViewConfiguration` from the nearest ancestor when omitted. -- Added `StreamMessageListView.topPadding` and `bottomPadding` — padding applied to the scroll view's top and bottom edges, used by floating app bar / composer layouts to keep messages visible without an extra `setState`. -- Added an `isFloating` parameter to `StreamBackButton`, controlling floating vs pinned back-button appearance. Falls back to `StreamAppBarTheme`, and then to the ambient `StreamAppStyle`, when null. `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamThreadHeader` now apply their per-header theme (`channelHeaderTheme` / `channelListHeaderTheme` / `threadHeaderTheme`) as a `StreamAppBarTheme` and pass `style` to the bar, which republishes its resolved behavior to its slots — so every slot in the bar — the default avatar's drop shadow, the default back button, and any `leading`/`trailing` the caller supplies — resolves the same chain the bar itself uses: `style`, then the per-header theme, then the ambient `StreamAppBarTheme`, then `StreamAppStyle`. +- Added an `isFloating` parameter to `StreamBackButton`, controlling floating vs pinned back-button appearance. Falls back to `StreamAppBarTheme`, and then to the ambient `StreamSurfaceStyle`, when null. `StreamChannelHeader`, `StreamChannelListHeader`, and `StreamThreadHeader` now apply their per-header theme (`channelHeaderTheme` / `channelListHeaderTheme` / `threadHeaderTheme`) as a `StreamAppBarTheme` and pass `style` to the bar, which republishes its resolved behavior to its slots — so every slot in the bar — the default avatar's drop shadow, the default back button, and any `leading`/`trailing` the caller supplies — resolves the same chain the bar itself uses: `style`, then the per-header theme, then the ambient `StreamAppBarTheme`, then `StreamSurfaceStyle`. - Added `messageListViewConfiguration` field to `StreamChatConfigurationData`, allowing a global `StreamMessageListViewConfiguration` default for all `StreamMessageListView` widgets. Pass it via `StreamChat.configData` to configure behaviors like `swipeToReply` and `highlightInitialMessage` app-wide without wiring them per-page. -- Re-exported `StreamScaffold`, `StreamScaffoldInsets`, `StreamBottomNavBar`, `StreamBottomNavBarItem`, `StreamAppStyle`, `StreamAppBarBehavior`, `StreamBottomAppBarBehavior`, and `streamFloatingFadeLinearGradient` from `stream_core_flutter` via `package:stream_chat_flutter/stream_chat_flutter.dart`. +- Re-exported `StreamScaffold`, `StreamScaffoldInsets`, `StreamBottomNavBar`, `StreamBottomNavBarItem`, `StreamSurfaceStyle`, and `streamFloatingFadeLinearGradient` from `stream_core_flutter` via `package:stream_chat_flutter/stream_chat_flutter.dart`. - Added `StreamMessageListViewConfiguration.autoScrollPolicy` to control whether and how `StreamMessageListView` scrolls to the newest message when a new message arrives. Use `StreamAutoScrollPolicy.disabled` to fully control scrolling yourself. - Added `onReactionSelected` to `StreamMessageReactionPicker`, a context-aware callback that provides the `BuildContext` for navigation. - Added an `errorSubtitle` to `StreamScrollViewErrorWidget`, which now falls back to the design's generic error copy (title, description, and a "Try Again" retry label) when values aren't provided. diff --git a/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart b/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart index 58a212eae2..7827e3ef93 100644 --- a/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart +++ b/packages/stream_chat_flutter/lib/scrollable_positioned_list/src/item_positions_listener.dart @@ -46,9 +46,9 @@ class ItemPosition { /// Distance in proportion of the visible content's main axis length from the /// leading edge of that content to the leading edge of the item. /// - /// The visible content is the area inside the list's padding. Use this for - /// overlays inside that area, such as under a floating bar; scroll logic keeps - /// using [itemLeadingEdge]. Equal to [itemLeadingEdge] when the list has no + /// The visible content is the area inside the list's padding. Consider using + /// this for overlays inside that area, such as under a floating bar; scroll + /// logic keeps using [itemLeadingEdge]. Equal to [itemLeadingEdge] when the list has no /// inset, and `null` only when the source omits it (a list always provides /// it). final double? contentLeadingEdge; diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart index 171c7d8d62..1dcc9759c2 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_header.dart @@ -14,7 +14,7 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// suppress the default, or pass [leading] to replace it entirely. /// /// The default trailing is the channel avatar (via [StreamChannelAvatar]). -/// Tap behaviour is wired through [onChannelAvatarPressed]; when the +/// Tap behavior is wired through [onChannelAvatarPressed]; when the /// callback is null the avatar is rendered non-interactive. Pass [trailing] /// to replace the avatar with a custom action — the callback is then /// ignored. @@ -106,7 +106,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget final bool automaticallyImplyLeading; /// Called when the default [StreamBackButton] is pressed, replacing its - /// default `Navigator.maybePop`. + /// default [Navigator.maybePop]. /// /// Ignored when [leading] is provided. final VoidCallback? onBackPressed; @@ -184,7 +184,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget showMessage: showConnectionStateTile && showStatus, message: statusString, // Apply the per-header theme as a theme; the bar resolves `style` - // over it and republishes the resolved behaviour to its slots. + // over it and republishes the resolved behavior to its slots. child: StreamAppBarTheme( data: headerTheme, child: StreamAppBar( @@ -213,10 +213,10 @@ class _DefaultChannelAvatar extends StatelessWidget { @override Widget build(BuildContext context) { - final appStyle = StreamTheme.of(context).appStyle; - final toolbarBehavior = StreamToolbarScope.maybeOf(context); + final surfaceStyle = StreamTheme.of(context).surfaceStyle; + final toolbarSurfaceStyle = StreamToolbarScope.maybeOf(context); - final effectiveIsFloating = toolbarBehavior?.isFloating ?? appStyle.isFloating; + final effectiveIsFloating = toolbarSurfaceStyle?.isFloating ?? surfaceStyle.isFloating; final effectiveOnTap = switch (onPressed) { final cb? => () => cb(channel), diff --git a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart index 1f0df916b1..0a458b6eb7 100644 --- a/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel/channel_list_header.dart @@ -11,7 +11,7 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// loading spinner + _Searching for network…_ when connecting, and an /// _Offline_ label with a _try again_ affordance when disconnected. /// -/// The leading slot is always the signed-in user's avatar. Tap behaviour +/// The leading slot is always the signed-in user's avatar. Tap behavior /// is wired through [onUserAvatarPressed]; when the callback is null the /// avatar mirrors Material [AppBar]'s auto-implied leading by opening the /// enclosing [Scaffold]'s drawer if one exists, and is otherwise rendered @@ -158,7 +158,7 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi showMessage: showConnectionStateTile && showStatus, message: statusString, // Apply the per-header theme as a theme; the bar resolves `style` - // over it and republishes the resolved behaviour to its slots. + // over it and republishes the resolved behavior to its slots. child: StreamAppBarTheme( data: headerTheme, child: StreamAppBar( @@ -188,10 +188,10 @@ class _DefaultUserAvatar extends StatelessWidget { final user = client.state.currentUser; if (user == null) return const SizedBox.shrink(); - final appStyle = StreamTheme.of(context).appStyle; - final toolbarBehavior = StreamToolbarScope.maybeOf(context); + final surfaceStyle = StreamTheme.of(context).surfaceStyle; + final toolbarSurfaceStyle = StreamToolbarScope.maybeOf(context); - final effectiveIsFloating = toolbarBehavior?.isFloating ?? appStyle.isFloating; + final effectiveIsFloating = toolbarSurfaceStyle?.isFloating ?? surfaceStyle.isFloating; // Caller-provided handler wins; otherwise mirror Material AppBar and // open the enclosing Scaffold's drawer if one exists. With no callback diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart index d1bb2dcd65..79ebc043e2 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_channel_avatar.dart @@ -69,8 +69,8 @@ class StreamChannelAvatar extends StatelessWidget { /// Whether to show a drop shadow around the avatar. /// - /// Defaults to false. The shadow depth is determined by - /// [StreamAvatarThemeData.floatingElevation], falling back to + /// Defaults to null, treated as not floating. The shadow depth is determined + /// by [StreamAvatarThemeData.floatingElevation], falling back to /// [StreamElevation.level2]. final bool? isFloating; diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart index 48eec8eee2..d4a82df40d 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar.dart @@ -88,8 +88,8 @@ class StreamUserAvatar extends StatelessWidget { /// Whether to show a drop shadow around the avatar. /// - /// Defaults to false. The shadow depth is determined by - /// [StreamAvatarThemeData.floatingElevation], falling back to + /// Defaults to null, treated as not floating. The shadow depth is determined + /// by [StreamAvatarThemeData.floatingElevation], falling back to /// [StreamElevation.level2]. final bool? isFloating; diff --git a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart index 2be3047f3d..d976aefa23 100644 --- a/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart +++ b/packages/stream_chat_flutter/lib/src/components/avatar/stream_user_avatar_group.dart @@ -69,8 +69,8 @@ class StreamUserAvatarGroup extends StatelessWidget { /// Whether to show a drop shadow around the avatar group. /// - /// Defaults to false. The shadow depth is determined by - /// [StreamAvatarThemeData.floatingElevation], falling back to + /// Defaults to null, treated as not floating. The shadow depth is determined + /// by [StreamAvatarThemeData.floatingElevation], falling back to /// [StreamElevation.level2]. final bool? isFloating; diff --git a/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart b/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart index 75f9fb005d..82f61cc6ae 100644 --- a/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart +++ b/packages/stream_chat_flutter/lib/src/components/message_composer/message_composer_input.dart @@ -62,9 +62,9 @@ class DefaultStreamMessageComposerInput extends StatelessWidget { border: Border.all(color: borderColor), ), child: Material( + borderRadius: borderRadius, clipBehavior: Clip.antiAlias, color: context.streamColorScheme.backgroundElevation1, - borderRadius: borderRadius, elevation: isFloating ? elevation.level3 : elevation.none, child: Column( mainAxisSize: MainAxisSize.min, diff --git a/packages/stream_chat_flutter/lib/src/media_gallery/stream_media_gallery.dart b/packages/stream_chat_flutter/lib/src/media_gallery/stream_media_gallery.dart index 7dac486102..23557c0beb 100644 --- a/packages/stream_chat_flutter/lib/src/media_gallery/stream_media_gallery.dart +++ b/packages/stream_chat_flutter/lib/src/media_gallery/stream_media_gallery.dart @@ -5,10 +5,10 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// companion to [StreamMediaGalleryPreview]. /// /// Each cell is rendered by a [StreamMediaGalleryItem] in a 1:1 grid with -/// the sender's avatar surfaced on every tile. Inter-cell gutters and the -/// outer padding both default to `spacing.xxxs` (2 logical pixels) so -/// every gap in the grid is uniform; pass [StreamMediaGalleryProps.padding] -/// to override. +/// the sender's avatar surfaced on every tile. Inter-cell gutters default to +/// `spacing.xxxs` (2 logical pixels) so every gap in the grid is uniform. The +/// grid has no outer padding of its own; supply [StreamMediaGalleryProps.padding] +/// to inset it from its container. /// /// {@tool snippet} /// @@ -92,7 +92,8 @@ class StreamMediaGalleryProps { /// Number of tiles per row. Defaults to 3. final int crossAxisCount; - /// Padding around the grid. + /// Padding around the grid. Defaults to null, leaving the grid to inherit + /// any insets from its surroundings. final EdgeInsetsGeometry? padding; /// Scroll controller for the underlying [GridView]. @@ -121,31 +122,25 @@ class DefaultStreamMediaGallery extends StatelessWidget { @override Widget build(BuildContext context) { final spacing = context.streamSpacing; - final effectivePadding = props.padding ?? EdgeInsets.all(spacing.xxxs); - return MediaQuery.removePadding( - context: context, - removeTop: true, - removeBottom: true, - child: GridView.builder( - padding: effectivePadding, - controller: props.scrollController, - itemCount: props.attachments.length, - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: props.crossAxisCount, - crossAxisSpacing: spacing.xxxs, - mainAxisSpacing: spacing.xxxs, - ), - itemBuilder: (context, index) { - final ga = props.attachments[index]; - return StreamMediaGalleryItem( - attachment: ga.attachment, - author: ga.message.user, - onTap: props.onItemTap == null ? null : () => props.onItemTap!(index), - onLongPress: props.onItemLongPress == null ? null : () => props.onItemLongPress!(index), - ); - }, + return GridView.builder( + padding: props.padding, + controller: props.scrollController, + itemCount: props.attachments.length, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: props.crossAxisCount, + crossAxisSpacing: spacing.xxxs, + mainAxisSpacing: spacing.xxxs, ), + itemBuilder: (context, index) { + final ga = props.attachments[index]; + return StreamMediaGalleryItem( + attachment: ga.attachment, + author: ga.message.user, + onTap: props.onItemTap == null ? null : () => props.onItemTap!(index), + onLongPress: props.onItemLongPress == null ? null : () => props.onItemLongPress!(index), + ); + }, ); } } diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 342712ca68..65f60ee0d8 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -101,7 +101,7 @@ class StreamMessageComposer extends StatelessWidget { TextCapitalization textCapitalization = TextCapitalization.sentences, bool autofocus = false, bool autoCorrect = true, - StreamMessageComposerBehavior? behavior, + StreamSurfaceStyle? surfaceStyle, }) : props = .new( onMessageSent: onMessageSent, preMessageSending: preMessageSending, @@ -139,7 +139,7 @@ class StreamMessageComposer extends StatelessWidget { textCapitalization: textCapitalization, autofocus: autofocus, autoCorrect: autoCorrect, - behavior: behavior, + surfaceStyle: surfaceStyle, ); /// Creates a [StreamMessageComposer] from a pre-built [MessageComposerProps]. @@ -201,7 +201,7 @@ class MessageComposerProps { this.textCapitalization = TextCapitalization.sentences, this.autofocus = false, this.autoCorrect = true, - this.behavior, + this.surfaceStyle, }); /// Function called after sending the message. @@ -411,8 +411,11 @@ class MessageComposerProps { /// Defaults to true. final bool autoCorrect; - /// The behavior of the message composer. - final StreamMessageComposerBehavior? behavior; + /// The surface style of the message composer. + /// + /// When null, falls back to [StreamMessageComposerThemeData.surfaceStyle], + /// then the ambient [StreamSurfaceStyle]. + final StreamSurfaceStyle? surfaceStyle; /// Returns a copy of this [MessageComposerProps] with the given fields /// replaced with new values. @@ -452,7 +455,7 @@ class MessageComposerProps { TextCapitalization? textCapitalization, bool? autofocus, bool? autoCorrect, - StreamMessageComposerBehavior? behavior, + StreamSurfaceStyle? surfaceStyle, }) { return MessageComposerProps( onMessageSent: onMessageSent ?? this.onMessageSent, @@ -490,7 +493,7 @@ class MessageComposerProps { textCapitalization: textCapitalization ?? this.textCapitalization, autofocus: autofocus ?? this.autofocus, autoCorrect: autoCorrect ?? this.autoCorrect, - behavior: behavior ?? this.behavior, + surfaceStyle: surfaceStyle ?? this.surfaceStyle, ); } @@ -830,84 +833,37 @@ class DefaultStreamMessageComposerState extends State Center(heightFactor: 1, child: messageInput), + _ => StreamSafeArea.driven( + top: false, + listenable: _pickerAnimation, + minimum: .only(bottom: spacing.md), + child: Center(heightFactor: 1, child: messageInput), + ), }, - child: Center(heightFactor: 1, child: messageInput), ); - final composer = switch (effectiveComposerBehavior) { - .floating => composerBody, + final colorScheme = context.streamColorScheme; + final effectiveSurfaceStyle = _resolveSurfaceStyle(context); + + final composer = switch (effectiveSurfaceStyle) { .regular => DecoratedBox( - decoration: BoxDecoration(color: colorScheme.backgroundElevation1), - child: composerBody, + decoration: BoxDecoration( + color: colorScheme.backgroundElevation1, + ), + child: content, + ), + .floating => CustomPaint( + painter: _FloatingComposerBackdropPainter( + animation: _pickerAnimation, + restColor: colorScheme.backgroundElevation0, + raisedColor: colorScheme.backgroundElevation1, + fadeExtent: _pillHeight, + ), + child: content, ), }; @@ -1000,14 +956,15 @@ class DefaultStreamMessageComposerState extends State _pillHeight.value = height, child: pill) + _ReportHeight( + onHeightChanged: (height) => _pillHeight.value = height, + child: pill, + ) else pill, SizeTransition( @@ -1102,8 +1062,6 @@ class DefaultStreamMessageComposerState extends State animation; + + // The backdrop color at rest, with the picker closed. + final Color restColor; + + // The backdrop color with the picker fully open. + final Color raisedColor; - final Color color; final ValueNotifier fadeExtent; @override void paint(Canvas canvas, Size size) { if (size.isEmpty) return; + final color = Color.lerp(restColor, raisedColor, animation.value)!; + // The gradient runs bottom-to-top, so the solid run is measured from the // bottom and the fade occupies the top `extent` pixels. final extent = math.min(fadeExtent.value, size.height); @@ -1730,7 +1701,10 @@ class _FloatingComposerBackdropPainter extends CustomPainter { @override bool shouldRepaint(_FloatingComposerBackdropPainter oldDelegate) { - return oldDelegate.color != color || oldDelegate.fadeExtent != fadeExtent; + return oldDelegate.restColor != restColor || + oldDelegate.raisedColor != raisedColor || + oldDelegate.animation != animation || + oldDelegate.fadeExtent != fadeExtent; } } diff --git a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart index c8179c3adb..3d6973ce38 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart @@ -338,16 +338,16 @@ class _StreamMessageListViewState extends State { MessageListController get _messageListController => widget.messageListController ?? _defaultController; - /// The effective [StreamMessageListViewConfiguration] for this list. - /// - /// [StreamMessageListView.config] when explicitly provided, otherwise - /// [StreamChatConfigurationData.messageListViewConfiguration] from the nearest - /// [StreamChatConfiguration] ancestor. - /// - /// Resolved into a field rather than read through a getter because the - /// fallback is an inherited-widget lookup, which asserts the element is active - /// and so must not run from a stream callback — `_messageNewListener` reads - /// this. + // The effective StreamMessageListViewConfiguration for this list. + // + // StreamMessageListView.config when explicitly provided, otherwise + // StreamChatConfigurationData.messageListViewConfiguration from the nearest + // StreamChatConfiguration ancestor. + // + // Resolved into a field rather than read through a getter because the + // fallback is an inherited-widget lookup, which asserts the element is active + // and so must not run from a stream callback — _messageNewListener reads + // this. late StreamMessageListViewConfiguration _config; StreamMessageListViewConfiguration _resolveConfig() { if (widget.config case final config?) return config; @@ -666,10 +666,7 @@ class _StreamMessageListViewState extends State { }, child: ScrollablePositionedList.separated( key: Key('mlv-${streamChannel?.channel.cid}-${widget.parentMessage?.id}'), - padding: .only( - top: _scaffoldInsets.top + context.streamSpacing.sm, - bottom: _scaffoldInsets.bottom + context.streamSpacing.sm, - ), + padding: _scaffoldInsets + .symmetric(vertical: context.streamSpacing.sm), keyboardDismissBehavior: _config.keyboardDismissBehavior, itemPositionsListener: _itemPositionListener, initialScrollIndex: initialIndex, @@ -862,7 +859,7 @@ class _StreamMessageListViewState extends State { ), if (_config.showUnreadIndicator && !_isThreadConversation) Positioned( - top: _scaffoldInsets.top + context.streamSpacing.sm, + top: math.max(_scaffoldInsets.top, context.streamSpacing.sm), child: UnreadIndicatorButton( onJumpTap: scrollToUnreadDefaultTapAction, onDismissTap: _markMessagesAsRead, @@ -1139,8 +1136,8 @@ class _StreamMessageListViewState extends State { } return PositionedDirectional( - bottom: _scaffoldInsets.bottom + 16, - end: 16, + bottom: math.max(_scaffoldInsets.bottom, context.streamSpacing.md), + end: context.streamSpacing.md, child: button, ); }, diff --git a/packages/stream_chat_flutter/lib/src/misc/back_button.dart b/packages/stream_chat_flutter/lib/src/misc/back_button.dart index f259b83d3d..803d1163aa 100644 --- a/packages/stream_chat_flutter/lib/src/misc/back_button.dart +++ b/packages/stream_chat_flutter/lib/src/misc/back_button.dart @@ -57,10 +57,10 @@ class StreamBackButton extends StatelessWidget { _ => context.streamIcons.arrowLeft, }; - final appStyle = StreamTheme.of(context).appStyle; - final toolbarBehavior = StreamToolbarScope.maybeOf(context); + final surfaceStyle = StreamTheme.of(context).surfaceStyle; + final toolbarSurfaceStyle = StreamToolbarScope.maybeOf(context); - final effectiveIsFloating = toolbarBehavior?.isFloating ?? appStyle.isFloating; + final effectiveIsFloating = toolbarSurfaceStyle?.isFloating ?? surfaceStyle.isFloating; Widget button = StreamButton.icon( type: effectiveIsFloating ? .outline : .ghost, diff --git a/packages/stream_chat_flutter/lib/src/misc/thread_header.dart b/packages/stream_chat_flutter/lib/src/misc/thread_header.dart index 70ace2cf49..0d5734871c 100644 --- a/packages/stream_chat_flutter/lib/src/misc/thread_header.dart +++ b/packages/stream_chat_flutter/lib/src/misc/thread_header.dart @@ -105,7 +105,7 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget ); // Apply the per-header theme as a theme; the bar resolves `style` over it - // and republishes the resolved behaviour to its slots. + // and republishes the resolved behavior to its slots. return StreamAppBarTheme( data: headerTheme, child: StreamAppBar( diff --git a/packages/stream_chat_flutter/lib/src/pages/channel_page.dart b/packages/stream_chat_flutter/lib/src/pages/channel_page.dart index b50f16963b..da33fa1cf5 100644 --- a/packages/stream_chat_flutter/lib/src/pages/channel_page.dart +++ b/packages/stream_chat_flutter/lib/src/pages/channel_page.dart @@ -5,7 +5,7 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// /// Wires up a [StreamChannelHeader], a [StreamMessageListView] and a /// [StreamMessageComposer], laid out floating or regular according to the ambient -/// [StreamAppStyle]. Expects a [StreamChannel] ancestor. +/// [StreamSurfaceStyle]. Expects a [StreamChannel] ancestor. /// /// ## Customizing this page /// @@ -38,7 +38,7 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// `messageItem`, `messageComposer`, `quotedMessage`, `mentionItem`, the /// attachment builders, `mediaGallery` and `videoPlayer` all apply here. /// -/// Change list behaviour — `swipeToReply`, `highlightInitialMessage`, +/// Change list behavior — `swipeToReply`, `highlightInitialMessage`, /// `autoScrollPolicy` and the rest — through /// [StreamChatConfigurationData.messageListViewConfiguration] on /// [StreamChat.configData]. @@ -76,7 +76,7 @@ class StreamChannelPage extends StatefulWidget { /// default is kept. final VoidCallback? onBackPressed; - /// Called when the default channel-avatar trailing is pressed. + /// Called when the default channel-avatar in the trailing slot is pressed. final void Function(BuildContext context, Channel channel)? onChannelAvatarPressed; @override @@ -150,12 +150,12 @@ class _StreamChannelPageState extends State { } } -/// The body of [StreamChannelPage]. -/// -/// Positions the typing indicator just above the composer (floating or docked) -/// via a bottom [SafeArea] over the floating-bar insets in `MediaQuery.padding` -/// (injected by [StreamScaffold]). [StreamMessageListView] reads the same insets -/// directly to pad its scroll content. +// The body of a channel page. +// +// Positions the typing indicator just above the composer (floating or docked) +// via a bottom SafeArea over the floating-bar insets in MediaQuery.padding +// (injected by StreamScaffold). StreamMessageListView reads the same insets +// directly to pad its scroll content. class _ChannelPageBody extends StatelessWidget { const _ChannelPageBody({ required this.typingIndicator, diff --git a/packages/stream_chat_flutter/lib/src/pages/thread_page.dart b/packages/stream_chat_flutter/lib/src/pages/thread_page.dart index c7676fcf42..f32bc1e54e 100644 --- a/packages/stream_chat_flutter/lib/src/pages/thread_page.dart +++ b/packages/stream_chat_flutter/lib/src/pages/thread_page.dart @@ -5,7 +5,7 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// /// Wires up a [StreamThreadHeader], a [StreamMessageListView] scoped to [parent] /// and a [StreamMessageComposer] that addresses new messages to the thread, laid -/// out floating or regular according to the ambient [StreamAppStyle]. Expects a +/// out floating or regular according to the ambient [StreamSurfaceStyle]. Expects a /// [StreamChannel] ancestor. /// /// The composer is omitted when [parent] is deleted. @@ -19,7 +19,7 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// /// * Components (`messageItem`, `messageComposer`, attachments, …) — /// [streamChatComponentBuilders] on [StreamChat.componentBuilders]. -/// * List behaviour — [StreamChatConfigurationData.messageListViewConfiguration] +/// * List behavior — [StreamChatConfigurationData.messageListViewConfiguration] /// on [StreamChat.configData]. /// * Not reachable: [StreamMessageListViewBuilders] list-level slots and /// [StreamThreadHeader]'s title and actions. diff --git a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart index 9154ccd3f1..9ddbefafdf 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart @@ -268,6 +268,7 @@ class StreamChatConfigurationData { /// [StreamMessageListView] that does not provide its own explicit /// [StreamMessageListView.config]. /// - /// Defaults to [StreamMessageListViewConfiguration] with all defaults. + /// Defaults to a [StreamMessageListViewConfiguration] with all fields at their + /// defaults. final StreamMessageListViewConfiguration messageListViewConfiguration; } diff --git a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart index d42a612c88..b5dca7174a 100644 --- a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.dart @@ -1,38 +1,14 @@ import 'package:flutter/widgets.dart'; import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; +import 'package:stream_core_flutter/core.dart'; import 'package:theme_extensions_builder_annotation/theme_extensions_builder_annotation.dart'; part 'message_composer_theme.g.theme.dart'; -/// The message composer's visual/layout behavior — floating above the keyboard -/// or docked at the bottom edge of the screen. -/// -/// Mirrors [StreamToolbarBehavior] so every -/// component names its placement the same way. -/// -/// When null on [StreamMessageComposerThemeData], the ambient [StreamAppStyle] -/// is used as a fallback — [StreamAppStyle.floating] maps to [floating] and -/// [StreamAppStyle.regular] maps to [regular]. -/// -/// See also: -/// -/// * [StreamMessageComposerThemeData.behavior], which carries this -/// value. -/// * [StreamAppStyle], the global app-wide style that acts as fallback. -enum StreamMessageComposerBehavior { - /// The composer sits within the layout flow, docked at the bottom edge of - /// the screen. - regular, - - /// The composer floats above the on-screen keyboard with appropriate safe - /// area padding. - floating, -} - /// Applies a message composer theme to descendant composer widgets. /// /// Wrap a subtree with [StreamMessageComposerTheme] to override the composer -/// behavior. Access the merged theme using [StreamMessageComposerTheme.of]. +/// surface style. Access the merged theme using [StreamMessageComposerTheme.of]. /// /// {@tool snippet} /// @@ -41,7 +17,7 @@ enum StreamMessageComposerBehavior { /// ```dart /// StreamMessageComposerTheme( /// data: StreamMessageComposerThemeData( -/// behavior: StreamMessageComposerBehavior.floating, +/// surfaceStyle: StreamSurfaceStyle.floating, /// ), /// child: StreamChannel( /// channel: channel, @@ -54,7 +30,7 @@ enum StreamMessageComposerBehavior { /// See also: /// /// * [StreamMessageComposerThemeData], which describes the theme data. -/// * [StreamMessageComposerThemeData.behavior], the setting it holds. +/// * [StreamMessageComposerThemeData.surfaceStyle], the setting it holds. class StreamMessageComposerTheme extends InheritedTheme { /// Creates a message composer theme that controls descendant composers. const StreamMessageComposerTheme({ @@ -73,7 +49,7 @@ class StreamMessageComposerTheme extends InheritedTheme { /// precedence over global values from [StreamChatTheme.of]. /// /// This allows partial overrides — for example, overriding only - /// [StreamMessageComposerThemeData.behavior] in a subtree while + /// [StreamMessageComposerThemeData.surfaceStyle] in a subtree while /// inheriting other properties from the global theme. static StreamMessageComposerThemeData of(BuildContext context) { final localTheme = context.dependOnInheritedWidgetOfExactType(); @@ -90,7 +66,7 @@ class StreamMessageComposerTheme extends InheritedTheme { /// Theme data for customizing the message composer placement. /// /// All fields are nullable. When a field is null, the consuming widget falls -/// back to the ambient [StreamAppStyle]. +/// back to the ambient [StreamSurfaceStyle]. /// /// {@tool snippet} /// @@ -99,7 +75,7 @@ class StreamMessageComposerTheme extends InheritedTheme { /// ```dart /// StreamChatThemeData( /// messageComposerTheme: StreamMessageComposerThemeData( -/// behavior: StreamMessageComposerBehavior.floating, +/// surfaceStyle: StreamSurfaceStyle.floating, /// ), /// ) /// ``` @@ -107,23 +83,23 @@ class StreamMessageComposerTheme extends InheritedTheme { /// /// See also: /// -/// * [StreamMessageComposerBehavior], the enum that describes the placement options. +/// * [StreamSurfaceStyle], the enum that describes the placement options. /// * [StreamMessageComposerTheme], for overriding the theme in a subtree. @themeGen @immutable class StreamMessageComposerThemeData with _$StreamMessageComposerThemeData { /// Creates message composer theme data with optional overrides. - const StreamMessageComposerThemeData({this.behavior}); + const StreamMessageComposerThemeData({this.surfaceStyle}); - /// The visual/layout behavior of the message composer. + /// The visual/layout surface style of the message composer. /// - /// When null the value falls back to the ambient [StreamAppStyle]: - /// [StreamAppStyle.floating] → [StreamMessageComposerBehavior.floating], - /// [StreamAppStyle.regular] → [StreamMessageComposerBehavior.regular]. + /// When null the value falls back to the ambient [StreamSurfaceStyle]: + /// [StreamSurfaceStyle.floating] renders the composer floating, + /// [StreamSurfaceStyle.regular] renders it docked. /// - /// Set this to override the global style for the composer only, without - /// affecting other components. - final StreamMessageComposerBehavior? behavior; + /// Overrides the global style for the composer only, leaving other components + /// unaffected. + final StreamSurfaceStyle? surfaceStyle; /// Linearly interpolate between two [StreamMessageComposerThemeData] objects. static StreamMessageComposerThemeData? lerp( diff --git a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart index 25f94550a6..bea19cf48c 100644 --- a/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/message_composer_theme.g.theme.dart @@ -30,16 +30,16 @@ mixin _$StreamMessageComposerThemeData { } return StreamMessageComposerThemeData( - behavior: t < 0.5 ? a.behavior : b.behavior, + surfaceStyle: t < 0.5 ? a.surfaceStyle : b.surfaceStyle, ); } - StreamMessageComposerThemeData copyWith({ - StreamMessageComposerBehavior? behavior, - }) { + StreamMessageComposerThemeData copyWith({StreamSurfaceStyle? surfaceStyle}) { final _this = (this as StreamMessageComposerThemeData); - return StreamMessageComposerThemeData(behavior: behavior ?? _this.behavior); + return StreamMessageComposerThemeData( + surfaceStyle: surfaceStyle ?? _this.surfaceStyle, + ); } StreamMessageComposerThemeData merge(StreamMessageComposerThemeData? other) { @@ -53,7 +53,7 @@ mixin _$StreamMessageComposerThemeData { return other; } - return copyWith(behavior: other.behavior); + return copyWith(surfaceStyle: other.surfaceStyle); } @override @@ -69,13 +69,13 @@ mixin _$StreamMessageComposerThemeData { final _this = (this as StreamMessageComposerThemeData); final _other = (other as StreamMessageComposerThemeData); - return _other.behavior == _this.behavior; + return _other.surfaceStyle == _this.surfaceStyle; } @override int get hashCode { final _this = (this as StreamMessageComposerThemeData); - return Object.hash(runtimeType, _this.behavior); + return Object.hash(runtimeType, _this.surfaceStyle); } } diff --git a/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart b/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart index 389b0a672d..6b28f7fa7a 100644 --- a/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/channel_header_test.dart @@ -508,9 +508,9 @@ void main() { // avatar and back button can disagree with each other. Future pumpHeader( WidgetTester tester, { - StreamAppStyle appStyle = StreamAppStyle.regular, - StreamToolbarBehavior? themeBehavior, - StreamToolbarBehavior? styleBehavior, + StreamSurfaceStyle surfaceStyle = StreamSurfaceStyle.regular, + StreamSurfaceStyle? themeSurfaceStyle, + StreamSurfaceStyle? styleSurfaceStyle, }) async { final client = MockClient(); final clientState = MockClientState(); @@ -543,12 +543,12 @@ void main() { await tester.pumpWidget( MaterialApp( - theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), + theme: ThemeData(extensions: [StreamTheme(surfaceStyle: surfaceStyle)]), home: StreamChat( client: client, themeData: StreamChatThemeData( - channelHeaderTheme: switch (themeBehavior) { - final behavior? => StreamAppBarThemeData(style: StreamAppBarStyle(behavior: behavior)), + channelHeaderTheme: switch (themeSurfaceStyle) { + final surfaceStyle? => StreamAppBarThemeData(style: StreamAppBarStyle(surfaceStyle: surfaceStyle)), _ => null, }, ), @@ -556,8 +556,8 @@ void main() { channel: channel, child: Scaffold( body: StreamChannelHeader( - style: switch (styleBehavior) { - final behavior? => StreamAppBarStyle(behavior: behavior), + style: switch (styleSurfaceStyle) { + final surfaceStyle? => StreamAppBarStyle(surfaceStyle: surfaceStyle), _ => null, }, ), @@ -585,13 +585,13 @@ void main() { }); testWidgets('floats when the app style is floating', (tester) async { - await pumpHeader(tester, appStyle: StreamAppStyle.floating); + await pumpHeader(tester, surfaceStyle: StreamSurfaceStyle.floating); expect(avatarIsFloating(tester), isTrue); }); testWidgets('floats when the header theme says so, over a regular app style', (tester) async { - await pumpHeader(tester, themeBehavior: StreamToolbarBehavior.floating); + await pumpHeader(tester, themeSurfaceStyle: StreamSurfaceStyle.floating); expect(avatarIsFloating(tester), isTrue); }); @@ -599,16 +599,16 @@ void main() { testWidgets('the header style wins over both the header theme and the app style', (tester) async { await pumpHeader( tester, - appStyle: StreamAppStyle.floating, - themeBehavior: StreamToolbarBehavior.floating, - styleBehavior: StreamToolbarBehavior.regular, + surfaceStyle: StreamSurfaceStyle.floating, + themeSurfaceStyle: StreamSurfaceStyle.floating, + styleSurfaceStyle: StreamSurfaceStyle.regular, ); expect(avatarIsFloating(tester), isNot(isTrue)); }); testWidgets('the default back button agrees with the avatar under the header theme', (tester) async { - await pumpHeader(tester, themeBehavior: StreamToolbarBehavior.floating); + await pumpHeader(tester, themeSurfaceStyle: StreamSurfaceStyle.floating); expect(backButtonIsFloating(tester), isTrue); expect(backButtonIsFloating(tester), avatarIsFloating(tester)); @@ -617,8 +617,8 @@ void main() { testWidgets('the default back button agrees with the avatar under the header style', (tester) async { await pumpHeader( tester, - appStyle: StreamAppStyle.floating, - styleBehavior: StreamToolbarBehavior.regular, + surfaceStyle: StreamSurfaceStyle.floating, + styleSurfaceStyle: StreamSurfaceStyle.regular, ); expect(backButtonIsFloating(tester), isNot(isTrue)); diff --git a/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart b/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart index 519462f38a..60c2bbe8b4 100644 --- a/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/channel_list_header_test.dart @@ -162,9 +162,9 @@ void main() { // is invisible to the avatar while the bar honours it. Future pumpHeader( WidgetTester tester, { - StreamAppStyle appStyle = StreamAppStyle.regular, - StreamToolbarBehavior? themeBehavior, - StreamToolbarBehavior? styleBehavior, + StreamSurfaceStyle surfaceStyle = StreamSurfaceStyle.regular, + StreamSurfaceStyle? themeSurfaceStyle, + StreamSurfaceStyle? styleSurfaceStyle, }) async { final client = MockClient(); final clientState = MockClientState(); @@ -175,19 +175,19 @@ void main() { await tester.pumpWidget( MaterialApp( - theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), + theme: ThemeData(extensions: [StreamTheme(surfaceStyle: surfaceStyle)]), home: StreamChat( client: client, themeData: StreamChatThemeData( - channelListHeaderTheme: switch (themeBehavior) { - final behavior? => StreamAppBarThemeData(style: StreamAppBarStyle(behavior: behavior)), + channelListHeaderTheme: switch (themeSurfaceStyle) { + final surfaceStyle? => StreamAppBarThemeData(style: StreamAppBarStyle(surfaceStyle: surfaceStyle)), _ => null, }, ), child: Scaffold( body: StreamChannelListHeader( - style: switch (styleBehavior) { - final behavior? => StreamAppBarStyle(behavior: behavior), + style: switch (styleSurfaceStyle) { + final surfaceStyle? => StreamAppBarStyle(surfaceStyle: surfaceStyle), _ => null, }, ), @@ -209,13 +209,13 @@ void main() { }); testWidgets('floats when the app style is floating', (tester) async { - await pumpHeader(tester, appStyle: StreamAppStyle.floating); + await pumpHeader(tester, surfaceStyle: StreamSurfaceStyle.floating); expect(avatarIsFloating(tester), isTrue); }); testWidgets('floats when the header theme says so, over a regular app style', (tester) async { - await pumpHeader(tester, themeBehavior: StreamToolbarBehavior.floating); + await pumpHeader(tester, themeSurfaceStyle: StreamSurfaceStyle.floating); expect(avatarIsFloating(tester), isTrue); }); @@ -223,9 +223,9 @@ void main() { testWidgets('the header style wins over both the header theme and the app style', (tester) async { await pumpHeader( tester, - appStyle: StreamAppStyle.floating, - themeBehavior: StreamToolbarBehavior.floating, - styleBehavior: StreamToolbarBehavior.regular, + surfaceStyle: StreamSurfaceStyle.floating, + themeSurfaceStyle: StreamSurfaceStyle.floating, + styleSurfaceStyle: StreamSurfaceStyle.regular, ); expect(avatarIsFloating(tester), isNot(isTrue)); diff --git a/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart b/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart index bb7edfa5b9..a4e3fe5dbe 100644 --- a/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/channel_page_test.dart @@ -18,7 +18,7 @@ void main() { }); testWidgets('renders a typing indicator above the composer', (tester) async { - await _pumpChannelPage(tester, appStyle: StreamAppStyle.floating); + await _pumpChannelPage(tester, surfaceStyle: StreamSurfaceStyle.floating); final indicator = tester.getRect(_bodyTypingIndicator()); final composer = tester.getRect(find.byType(StreamMessageComposer)); @@ -115,21 +115,24 @@ void main() { }); testWidgets('insets the message list behind a floating app bar and composer', (tester) async { - await _pumpChannelPage(tester, appStyle: StreamAppStyle.floating); + await _pumpChannelPage(tester, surfaceStyle: StreamSurfaceStyle.floating); - final messageListView = _messageListView(tester); + // The floating scaffold injects the bar extents into MediaQuery.padding, + // which the message list consumes to inset its content behind the chrome. + final padding = MediaQuery.paddingOf(tester.element(find.byType(StreamMessageListView))); - expect(messageListView.topPadding, greaterThan(0)); - expect(messageListView.bottomPadding, greaterThan(0)); + expect(padding.top, greaterThan(0)); + expect(padding.bottom, greaterThan(0)); }); testWidgets('does not inset the message list when the app style is regular', (tester) async { await _pumpChannelPage(tester); - final messageListView = _messageListView(tester); + // Regular bars occupy their own space, so nothing is injected into padding. + final padding = MediaQuery.paddingOf(tester.element(find.byType(StreamMessageListView))); - expect(messageListView.topPadding, 0); - expect(messageListView.bottomPadding, 0); + expect(padding.top, 0); + expect(padding.bottom, 0); }); testWidgets('disposes its composer controller when removed from the tree', (tester) async { @@ -183,7 +186,7 @@ FocusNode _composerFocusNode(WidgetTester tester) { Future _pumpChannelPage( WidgetTester tester, { - StreamAppStyle appStyle = StreamAppStyle.regular, + StreamSurfaceStyle surfaceStyle = StreamSurfaceStyle.regular, void Function(BuildContext context, Channel channel)? onChannelAvatarPressed, VoidCallback? onBackPressed, bool pushOntoARoute = false, @@ -240,7 +243,7 @@ Future _pumpChannelPage( await tester.pumpWidget( MaterialApp( - theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), + theme: ThemeData(extensions: [StreamTheme(surfaceStyle: surfaceStyle)]), // Chat context lives above the navigator so it survives a pop. builder: (context, child) => StreamChat( client: client, diff --git a/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart b/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart index b8c7ae5196..ef38abe506 100644 --- a/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart +++ b/packages/stream_chat_flutter/test/src/channel/thread_page_test.dart @@ -101,21 +101,24 @@ void main() { }); testWidgets('insets the message list behind a floating app bar and composer', (tester) async { - await _pumpThreadPage(tester, appStyle: StreamAppStyle.floating); + await _pumpThreadPage(tester, surfaceStyle: StreamSurfaceStyle.floating); - final messageListView = _messageListView(tester); + // The floating scaffold injects the bar extents into MediaQuery.padding, + // which the message list consumes to inset its content behind the chrome. + final padding = MediaQuery.paddingOf(tester.element(find.byType(StreamMessageListView))); - expect(messageListView.topPadding, greaterThan(0)); - expect(messageListView.bottomPadding, greaterThan(0)); + expect(padding.top, greaterThan(0)); + expect(padding.bottom, greaterThan(0)); }); testWidgets('does not inset the message list when the app style is regular', (tester) async { await _pumpThreadPage(tester); - final messageListView = _messageListView(tester); + // Regular bars occupy their own space, so nothing is injected into padding. + final padding = MediaQuery.paddingOf(tester.element(find.byType(StreamMessageListView))); - expect(messageListView.topPadding, 0); - expect(messageListView.bottomPadding, 0); + expect(padding.top, 0); + expect(padding.bottom, 0); }); testWidgets('tapping back invokes onBackPressed', (tester) async { @@ -175,7 +178,7 @@ FocusNode _composerFocusNode(WidgetTester tester) { Future _pumpThreadPage( WidgetTester tester, { Message? parent, - StreamAppStyle appStyle = StreamAppStyle.regular, + StreamSurfaceStyle surfaceStyle = StreamSurfaceStyle.regular, void Function(Message message)? onViewInChannelTap, VoidCallback? onBackPressed, bool pushOntoARoute = false, @@ -248,7 +251,7 @@ Future _pumpThreadPage( await tester.pumpWidget( MaterialApp( - theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), + theme: ThemeData(extensions: [StreamTheme(surfaceStyle: surfaceStyle)]), // Chat context lives above the navigator so it survives a pop. builder: (context, child) => StreamChat( client: client, diff --git a/packages/stream_chat_flutter/test/src/message_input/message_composer_behavior_test.dart b/packages/stream_chat_flutter/test/src/message_input/message_composer_surface_style_test.dart similarity index 58% rename from packages/stream_chat_flutter/test/src/message_input/message_composer_behavior_test.dart rename to packages/stream_chat_flutter/test/src/message_input/message_composer_surface_style_test.dart index 1cf498e6b7..6752f268e0 100644 --- a/packages/stream_chat_flutter/test/src/message_input/message_composer_behavior_test.dart +++ b/packages/stream_chat_flutter/test/src/message_input/message_composer_surface_style_test.dart @@ -10,51 +10,51 @@ import '../mocks.dart'; void main() { testWidgets('composer is regular when the app style is regular', (tester) async { - await _pumpComposer(tester, appStyle: StreamAppStyle.regular); + await _pumpComposer(tester, surfaceStyle: StreamSurfaceStyle.regular); - expect(_resolvedBehavior(tester), StreamMessageComposerBehavior.regular); + expect(_resolvedSurfaceStyle(tester), StreamSurfaceStyle.regular); }); testWidgets('composer floats when the app style is floating', (tester) async { - await _pumpComposer(tester, appStyle: StreamAppStyle.floating); + await _pumpComposer(tester, surfaceStyle: StreamSurfaceStyle.floating); - expect(_resolvedBehavior(tester), StreamMessageComposerBehavior.floating); + expect(_resolvedSurfaceStyle(tester), StreamSurfaceStyle.floating); }); testWidgets('the global composer theme overrides the app style', (tester) async { await _pumpComposer( tester, - appStyle: StreamAppStyle.regular, - globalTheme: const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating), + surfaceStyle: StreamSurfaceStyle.regular, + globalTheme: const StreamMessageComposerThemeData(surfaceStyle: StreamSurfaceStyle.floating), ); - expect(_resolvedBehavior(tester), StreamMessageComposerBehavior.floating); + expect(_resolvedSurfaceStyle(tester), StreamSurfaceStyle.floating); }); testWidgets('a local composer theme overrides the global theme', (tester) async { await _pumpComposer( tester, - appStyle: StreamAppStyle.floating, - globalTheme: const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating), - localTheme: const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.regular), + surfaceStyle: StreamSurfaceStyle.floating, + globalTheme: const StreamMessageComposerThemeData(surfaceStyle: StreamSurfaceStyle.floating), + localTheme: const StreamMessageComposerThemeData(surfaceStyle: StreamSurfaceStyle.regular), ); - expect(_resolvedBehavior(tester), StreamMessageComposerBehavior.regular); + expect(_resolvedSurfaceStyle(tester), StreamSurfaceStyle.regular); }); - testWidgets('the behavior property overrides both the theme and the app style', (tester) async { + testWidgets('the surfaceStyle property overrides both the theme and the app style', (tester) async { await _pumpComposer( tester, - appStyle: StreamAppStyle.floating, - globalTheme: const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating), - behavior: StreamMessageComposerBehavior.regular, + surfaceStyle: StreamSurfaceStyle.floating, + globalTheme: const StreamMessageComposerThemeData(surfaceStyle: StreamSurfaceStyle.floating), + composerSurfaceStyle: StreamSurfaceStyle.regular, ); - expect(_resolvedBehavior(tester), StreamMessageComposerBehavior.regular); + expect(_resolvedSurfaceStyle(tester), StreamSurfaceStyle.regular); }); testWidgets('the regular composer fills its background with the elevation-1 color', (tester) async { - await _pumpComposer(tester, appStyle: StreamAppStyle.regular); + await _pumpComposer(tester, surfaceStyle: StreamSurfaceStyle.regular); expect(_backgroundFillFinder(tester), findsOneWidget); }); @@ -62,26 +62,30 @@ void main() { testWidgets('the floating composer does not fill its background', (tester) async { // Floating paints a fading backdrop instead of an opaque fill, so the // message list stays visible behind the composer. - await _pumpComposer(tester, appStyle: StreamAppStyle.floating); + await _pumpComposer(tester, surfaceStyle: StreamSurfaceStyle.floating); expect(_backgroundFillFinder(tester), findsNothing); }); testWidgets('the floating composer lifts the input above the bottom safe area', (tester) async { const bottomInset = 34.0; - await _pumpComposer(tester, appStyle: StreamAppStyle.floating, bottomPadding: bottomInset); + await _pumpComposer(tester, surfaceStyle: StreamSurfaceStyle.floating, bottomPadding: bottomInset); final gap = _gapBelowInput(tester); + // The inset (34) is larger than the spacing.md floor, so it is used as-is — + // the composer sits flush above it rather than lifting further. expect(gap, moreOrLessEquals(bottomInset)); }); - testWidgets('the floating composer keeps a minimum gap when there is no safe area', (tester) async { - await _pumpComposer(tester, appStyle: StreamAppStyle.floating); + testWidgets('the floating composer floors the bottom gap at spacing.md without an inset', (tester) async { + // With no injected inset the floor keeps the composer off the edge; a larger + // inset would absorb it, so the composer never stacks a fixed gap on top of + // a system bar drawn outside the window. + await _pumpComposer(tester, surfaceStyle: StreamSurfaceStyle.floating); final gap = _gapBelowInput(tester); - // Falls back to `spacing.md` so the pill never sits flush with the edge. final context = tester.element(find.byType(StreamChatMessageInput)); expect(gap, moreOrLessEquals(context.streamSpacing.md)); }); @@ -89,7 +93,7 @@ void main() { testWidgets('the floating composer leaves no gap when the safe area is disabled', (tester) async { await _pumpComposer( tester, - appStyle: StreamAppStyle.floating, + surfaceStyle: StreamSurfaceStyle.floating, bottomPadding: 34, enableSafeArea: false, ); @@ -98,12 +102,42 @@ void main() { expect(gap, moreOrLessEquals(0)); }); + + testWidgets('the floating composer collapses the bottom inset while the attachment picker is open', (tester) async { + // The inset lifts the pill above the system inset when the picker is closed, + // but must collapse to zero while it is open so the edge-to-edge attachment + // gallery can reach the screen bottom. + await _pumpComposer(tester, surfaceStyle: StreamSurfaceStyle.floating, bottomPadding: 34); + + double insetBottom() { + // The applied inset is the outermost Padding inside the composer's safe area. + final padding = tester.widget( + find.descendant(of: find.byType(StreamSafeArea), matching: find.byType(Padding)).first, + ); + return padding.padding.resolve(TextDirection.ltr).bottom; + } + + // Closed: the injected inset (34) exceeds the spacing.md floor, so it is used as-is. + expect(insetBottom(), moreOrLessEquals(34)); + + await tester.tap(_attachmentButtonFinder); + await tester.pumpAndSettle(); + + // Open: the inset has collapsed. + expect(insetBottom(), moreOrLessEquals(0)); + }); } -/// The behavior the composer resolved, read back from the input it built. -StreamMessageComposerBehavior _resolvedBehavior(WidgetTester tester) { +/// The composer's attachment (picker) button, in the leading slot. +final _attachmentButtonFinder = find.descendant( + of: find.byType(DefaultStreamMessageComposerLeading), + matching: find.byType(StreamButton), +); + +/// The surface style the composer resolved, read back from the input it built. +StreamSurfaceStyle _resolvedSurfaceStyle(WidgetTester tester) { final input = tester.widget(find.byType(StreamChatMessageInput)); - return input.isFloating ? StreamMessageComposerBehavior.floating : StreamMessageComposerBehavior.regular; + return input.isFloating ? StreamSurfaceStyle.floating : StreamSurfaceStyle.regular; } /// Finds the opaque background fill the regular composer paints behind itself. @@ -132,10 +166,10 @@ double _gapBelowInput(WidgetTester tester) { /// compared against the input pill's. Future _pumpComposer( WidgetTester tester, { - required StreamAppStyle appStyle, + required StreamSurfaceStyle surfaceStyle, StreamMessageComposerThemeData? globalTheme, StreamMessageComposerThemeData? localTheme, - StreamMessageComposerBehavior? behavior, + StreamSurfaceStyle? composerSurfaceStyle, bool? enableSafeArea, double bottomPadding = 0, }) async { @@ -149,6 +183,10 @@ Future _pumpComposer( final channelState = MockChannelState(); when(() => client.state).thenReturn(clientState); + // Read by the attachment validator when the picker opens. + when(() => client.appSettings).thenReturn( + const AppSettings(fileUploadConfig: UploadConfig(), imageUploadConfig: UploadConfig()), + ); when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); when(() => clientState.currentUserStream).thenAnswer((_) => Stream.value(OwnUser(id: 'user-id'))); when(() => channel.state).thenReturn(channelState); @@ -164,13 +202,13 @@ Future _pumpComposer( when(() => channelState.draft).thenReturn(null); final composer = StreamMessageComposer( - behavior: behavior, + surfaceStyle: composerSurfaceStyle, enableSafeArea: enableSafeArea, ); await tester.pumpWidget( MaterialApp( - theme: ThemeData(extensions: [StreamTheme(appStyle: appStyle)]), + theme: ThemeData(extensions: [StreamTheme(surfaceStyle: surfaceStyle)]), // Overrides only the padding, so the ambient size, text scale and platform // brightness the test binding provides are preserved. home: Builder( diff --git a/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart b/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart index 6faa545847..3f0c29a990 100644 --- a/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart +++ b/packages/stream_chat_flutter/test/src/theme/message_composer_theme_test.dart @@ -6,80 +6,80 @@ import '../mocks.dart'; void main() { test('copyWith with no arguments returns an equal MessageComposerThemeData', () { - const themeData = StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating); + const themeData = StreamMessageComposerThemeData(surfaceStyle: StreamSurfaceStyle.floating); expect(themeData.copyWith(), themeData); }); test('copyWith with no arguments preserves the hashCode', () { - const themeData = StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating); + const themeData = StreamMessageComposerThemeData(surfaceStyle: StreamSurfaceStyle.floating); expect(themeData.copyWith().hashCode, themeData.hashCode); }); - test('copyWith overrides the behavior', () { - const regular = StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.regular); + test('copyWith overrides the surfaceStyle', () { + const regular = StreamMessageComposerThemeData(surfaceStyle: StreamSurfaceStyle.regular); expect( - regular.copyWith(behavior: StreamMessageComposerBehavior.floating).behavior, - StreamMessageComposerBehavior.floating, + regular.copyWith(surfaceStyle: StreamSurfaceStyle.floating).surfaceStyle, + StreamSurfaceStyle.floating, ); }); test('MessageComposerThemeData instances with different behaviors are not equal', () { expect( - const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.regular), - isNot(const StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating)), + const StreamMessageComposerThemeData(surfaceStyle: StreamSurfaceStyle.regular), + isNot(const StreamMessageComposerThemeData(surfaceStyle: StreamSurfaceStyle.floating)), ); }); - test('lerp at t = 0 resolves to the start behavior', () { + test('lerp at t = 0 resolves to the start surfaceStyle', () { expect( - StreamMessageComposerThemeData.lerp(_regularTheme, _floatingTheme, 0)?.behavior, - StreamMessageComposerBehavior.regular, + StreamMessageComposerThemeData.lerp(_regularTheme, _floatingTheme, 0)?.surfaceStyle, + StreamSurfaceStyle.regular, ); }); - test('lerp below the halfway point resolves to the start behavior', () { + test('lerp below the halfway point resolves to the start surfaceStyle', () { expect( - StreamMessageComposerThemeData.lerp(_regularTheme, _floatingTheme, 0.49)?.behavior, - StreamMessageComposerBehavior.regular, + StreamMessageComposerThemeData.lerp(_regularTheme, _floatingTheme, 0.49)?.surfaceStyle, + StreamSurfaceStyle.regular, ); }); - test('lerp at or past the halfway point resolves to the end behavior', () { + test('lerp at or past the halfway point resolves to the end surfaceStyle', () { expect( - StreamMessageComposerThemeData.lerp(_regularTheme, _floatingTheme, 0.5)?.behavior, - StreamMessageComposerBehavior.floating, + StreamMessageComposerThemeData.lerp(_regularTheme, _floatingTheme, 0.5)?.surfaceStyle, + StreamSurfaceStyle.floating, ); }); - test('lerp at t = 1 resolves to the end behavior', () { + test('lerp at t = 1 resolves to the end surfaceStyle', () { expect(StreamMessageComposerThemeData.lerp(_regularTheme, _floatingTheme, 1), _floatingTheme); }); - test('merge with null keeps the original behavior', () { + test('merge with null keeps the original surfaceStyle', () { expect(_regularTheme.merge(null), _regularTheme); }); - test('merge overrides the behavior with the other theme', () { + test('merge overrides the surfaceStyle with the other theme', () { expect(_regularTheme.merge(_floatingTheme), _floatingTheme); }); - test('merge with an empty theme keeps the original behavior', () { + test('merge with an empty theme keeps the original surfaceStyle', () { expect(_floatingTheme.merge(const StreamMessageComposerThemeData()), _floatingTheme); }); - testWidgets('of returns a null behavior when no theme is configured', (tester) async { + testWidgets('of returns a null surfaceStyle when no theme is configured', (tester) async { final context = await _pumpAndCaptureContext(tester); - expect(StreamMessageComposerTheme.of(context).behavior, isNull); + expect(StreamMessageComposerTheme.of(context).surfaceStyle, isNull); }); - testWidgets('of returns the global theme behavior when no local theme is present', (tester) async { + testWidgets('of returns the global theme surfaceStyle when no local theme is present', (tester) async { final context = await _pumpAndCaptureContext(tester, globalTheme: _floatingTheme); - expect(StreamMessageComposerTheme.of(context).behavior, StreamMessageComposerBehavior.floating); + expect(StreamMessageComposerTheme.of(context).surfaceStyle, StreamSurfaceStyle.floating); }); testWidgets('of merges the local theme over the global theme', (tester) async { @@ -89,17 +89,17 @@ void main() { localTheme: _floatingTheme, ); - expect(StreamMessageComposerTheme.of(context).behavior, StreamMessageComposerBehavior.floating); + expect(StreamMessageComposerTheme.of(context).surfaceStyle, StreamSurfaceStyle.floating); }); - testWidgets('of falls back to the global theme when the local theme sets no behavior', (tester) async { + testWidgets('of falls back to the global theme when the local theme sets no surfaceStyle', (tester) async { final context = await _pumpAndCaptureContext( tester, globalTheme: _floatingTheme, localTheme: const StreamMessageComposerThemeData(), ); - expect(StreamMessageComposerTheme.of(context).behavior, StreamMessageComposerBehavior.floating); + expect(StreamMessageComposerTheme.of(context).surfaceStyle, StreamSurfaceStyle.floating); }); testWidgets('wrap re-establishes the theme in a detached subtree', (tester) async { @@ -126,7 +126,7 @@ void main() { ), ); - expect(StreamMessageComposerTheme.of(capturedContext).behavior, StreamMessageComposerBehavior.floating); + expect(StreamMessageComposerTheme.of(capturedContext).surfaceStyle, StreamSurfaceStyle.floating); }); testWidgets('updateShouldNotify is true when the data changes', (tester) async { @@ -144,8 +144,8 @@ void main() { }); } -const _regularTheme = StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.regular); -const _floatingTheme = StreamMessageComposerThemeData(behavior: StreamMessageComposerBehavior.floating); +const _regularTheme = StreamMessageComposerThemeData(surfaceStyle: StreamSurfaceStyle.regular); +const _floatingTheme = StreamMessageComposerThemeData(surfaceStyle: StreamSurfaceStyle.floating); /// Pumps a [StreamChat] configured with [globalTheme], optionally wrapped in a /// local [StreamMessageComposerTheme] carrying [localTheme], and returns a diff --git a/sample_app/lib/app.dart b/sample_app/lib/app.dart index 08d31d7762..facf81a47e 100644 --- a/sample_app/lib/app.dart +++ b/sample_app/lib/app.dart @@ -179,7 +179,7 @@ class _StreamChatSampleAppState extends State child: Builder( builder: (context) { final config = context.sampleAppConfig; - final appStyle = config.appStyle; + final surfaceStyle = config.surfaceStyle; return DynamicColorBuilder( builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) { @@ -187,12 +187,12 @@ class _StreamChatSampleAppState extends State theme: createTheme( dynamicColor: config.enableDynamicColor ? lightDynamic : null, brightness: Brightness.light, - appStyle: appStyle, + surfaceStyle: surfaceStyle, ), darkTheme: createTheme( dynamicColor: config.enableDynamicColor ? darkDynamic : null, brightness: Brightness.dark, - appStyle: appStyle, + surfaceStyle: surfaceStyle, ), themeMode: config.themeMode, locale: config.locale, @@ -256,7 +256,7 @@ class _StreamChatSampleAppState extends State ThemeData createTheme({ required ColorScheme? dynamicColor, required Brightness brightness, - required StreamAppStyle appStyle, + required StreamSurfaceStyle surfaceStyle, }) { return ThemeData( brightness: brightness, @@ -269,7 +269,7 @@ class _StreamChatSampleAppState extends State brightness: brightness, ), brightness: brightness, - appStyle: appStyle, + surfaceStyle: surfaceStyle, ), ], ); diff --git a/sample_app/lib/config/sample_app_config.dart b/sample_app/lib/config/sample_app_config.dart index 7b495968fd..bbe1e91ce6 100644 --- a/sample_app/lib/config/sample_app_config.dart +++ b/sample_app/lib/config/sample_app_config.dart @@ -8,7 +8,7 @@ import 'package:streaming_shared_preferences/streaming_shared_preferences.dart'; // --------------------------------------------------------------------------- const _kThemeMode = 'config.themeMode'; -const _kAppStyle = 'config.appStyle'; +const _kSurfaceStyle = 'config.surfaceStyle'; const _kForceRtl = 'config.forceRtl'; const _kEnableDynamicColor = 'config.enableDynamicColor'; const _kEnableReminderActions = 'config.enableReminderActions'; @@ -40,7 +40,7 @@ class SampleAppConfigData { factory SampleAppConfigData({ Locale? locale, ThemeMode themeMode = .system, - StreamAppStyle appStyle = .regular, + StreamSurfaceStyle surfaceStyle = .regular, bool forceRtl = false, bool enableDynamicColor = false, bool enableReminderActions = false, @@ -54,7 +54,7 @@ class SampleAppConfigData { }) { return SampleAppConfigData.raw( themeMode: themeMode, - appStyle: appStyle, + surfaceStyle: surfaceStyle, locale: locale, forceRtl: forceRtl, enableDynamicColor: enableDynamicColor, @@ -72,7 +72,7 @@ class SampleAppConfigData { /// Raw constructor used internally and by persistence. const SampleAppConfigData.raw({ required this.themeMode, - required this.appStyle, + required this.surfaceStyle, required this.locale, required this.forceRtl, required this.enableDynamicColor, @@ -89,10 +89,10 @@ class SampleAppConfigData { /// Loads config from [StreamingSharedPreferences], falling back to defaults. factory SampleAppConfigData.fromPreferences(StreamingSharedPreferences prefs) { final localeStr = prefs.getString(_kLocale, defaultValue: '').getValue(); - final appStyleIndex = prefs.getInt(_kAppStyle, defaultValue: StreamAppStyle.regular.index).getValue(); + final surfaceStyleIndex = prefs.getInt(_kSurfaceStyle, defaultValue: StreamSurfaceStyle.regular.index).getValue(); return SampleAppConfigData.raw( themeMode: ThemeMode.values[prefs.getInt(_kThemeMode, defaultValue: ThemeMode.system.index).getValue()], - appStyle: StreamAppStyle.values[appStyleIndex.clamp(0, StreamAppStyle.values.length - 1)], + surfaceStyle: StreamSurfaceStyle.values[surfaceStyleIndex.clamp(0, StreamSurfaceStyle.values.length - 1)], locale: localeStr.isEmpty ? null : Locale(localeStr), forceRtl: prefs.getBool(_kForceRtl, defaultValue: false).getValue(), enableDynamicColor: prefs.getBool(_kEnableDynamicColor, defaultValue: false).getValue(), @@ -113,7 +113,7 @@ class SampleAppConfigData { final ThemeMode themeMode; /// The visual style for the app chrome (app bar, composer, bottom bar). - final StreamAppStyle appStyle; + final StreamSurfaceStyle surfaceStyle; /// The locale override for the app. When null, the system locale is used. final Locale? locale; @@ -159,7 +159,7 @@ class SampleAppConfigData { /// pass explicitly as `null` to reset to default/system. SampleAppConfigData copyWith({ ThemeMode? themeMode, - StreamAppStyle? appStyle, + StreamSurfaceStyle? surfaceStyle, Object? locale = _sentinel, bool? forceRtl, bool? enableDynamicColor, @@ -174,7 +174,7 @@ class SampleAppConfigData { }) { return SampleAppConfigData.raw( themeMode: themeMode ?? this.themeMode, - appStyle: appStyle ?? this.appStyle, + surfaceStyle: surfaceStyle ?? this.surfaceStyle, locale: locale == _sentinel ? this.locale : locale as Locale?, forceRtl: forceRtl ?? this.forceRtl, enableDynamicColor: enableDynamicColor ?? this.enableDynamicColor, @@ -196,7 +196,7 @@ class SampleAppConfigData { /// Persists all fields to [StreamingSharedPreferences]. void saveToPreferences(StreamingSharedPreferences prefs) { prefs.setInt(_kThemeMode, themeMode.index); - prefs.setInt(_kAppStyle, appStyle.index); + prefs.setInt(_kSurfaceStyle, surfaceStyle.index); prefs.setString(_kLocale, locale?.languageCode ?? ''); prefs.setBool(_kForceRtl, forceRtl); prefs.setBool(_kEnableDynamicColor, enableDynamicColor); diff --git a/sample_app/lib/config/sample_app_config_screen.dart b/sample_app/lib/config/sample_app_config_screen.dart index 710b9cd241..6c429d19f8 100644 --- a/sample_app/lib/config/sample_app_config_screen.dart +++ b/sample_app/lib/config/sample_app_config_screen.dart @@ -55,18 +55,18 @@ class SampleAppConfigScreen extends StatelessWidget { }, onChanged: (v) => SampleAppConfig.update(context, config.copyWith(themeMode: v)), ), - _SegmentedRow( - title: 'App Style', - value: config.appStyle, + _SegmentedRow( + title: 'Surface Style', + value: config.surfaceStyle, segments: const { - StreamAppStyle.regular: 'Regular', - StreamAppStyle.floating: 'Floating', + StreamSurfaceStyle.regular: 'Regular', + StreamSurfaceStyle.floating: 'Floating', }, segmentIcons: const { - StreamAppStyle.regular: Icons.web_asset_outlined, - StreamAppStyle.floating: Icons.filter_none_outlined, + StreamSurfaceStyle.regular: Icons.web_asset_outlined, + StreamSurfaceStyle.floating: Icons.filter_none_outlined, }, - onChanged: (v) => SampleAppConfig.update(context, config.copyWith(appStyle: v)), + onChanged: (v) => SampleAppConfig.update(context, config.copyWith(surfaceStyle: v)), ), _SwitchRow( icon: Icons.palette_outlined, diff --git a/sample_app/lib/pages/channel_file_display_screen.dart b/sample_app/lib/pages/channel_file_display_screen.dart index 060853d122..21d4d3d7a5 100644 --- a/sample_app/lib/pages/channel_file_display_screen.dart +++ b/sample_app/lib/pages/channel_file_display_screen.dart @@ -44,50 +44,45 @@ class _ChannelFileDisplayScreenState extends State { appBar: StreamAppBar(title: const Text('Files')), body: ValueListenableBuilder>( valueListenable: _controller, - builder: (context, value, _) { - return value.when( - (items, nextPageKey, _) { - // Flatten messages → individual file attachments paired with - // the message timestamp we'll bucket on. - final entries = <_FileEntry>[ - for (final response in items) - for (final attachment in response.message.attachments) - if (attachment.type == 'file') - _FileEntry( - attachment: attachment, - sentAt: response.message.createdAt, - ), - ]; - - if (entries.isEmpty) return const Center(child: _EmptyState()); - - // Pre-build a flat row list — interleave a header row above - // each month bucket so a single ListView.builder can render - // both kinds of rows without a CustomScrollView + slivers. - final rows = _buildRows(entries); - - return LazyLoadScrollView( - onEndOfPage: () async { - if (nextPageKey != null) await _controller.loadMore(nextPageKey); - }, - // No `padding` — the ListView auto-insets from the - // MediaQuery.padding injected by StreamScaffold (floating bars - // and the system safe area). - child: ListView.builder( - itemCount: rows.length, - itemBuilder: (context, index) => rows[index].build(context), - ), - ); - }, - loading: () => const Center(child: StreamScrollViewLoadingWidget()), - error: (_) => Center( - child: StreamScrollViewErrorWidget( - errorTitle: const Text('Failed to load files'), - onRetryPressed: _controller.refresh, + builder: (context, value, _) => value.when( + (items, nextPageKey, _) { + // Flatten messages → individual file attachments paired with + // the message timestamp we'll bucket on. + final entries = <_FileEntry>[ + for (final response in items) + for (final attachment in response.message.attachments) + if (attachment.type == 'file') + _FileEntry( + attachment: attachment, + sentAt: response.message.createdAt, + ), + ]; + + if (entries.isEmpty) return const Center(child: _EmptyState()); + + // Pre-build a flat row list — interleave a header row above + // each month bucket so a single ListView.builder can render + // both kinds of rows without a CustomScrollView + slivers. + final rows = _buildRows(entries); + + return LazyLoadScrollView( + onEndOfPage: () async { + if (nextPageKey != null) await _controller.loadMore(nextPageKey); + }, + child: ListView.builder( + itemCount: rows.length, + itemBuilder: (context, index) => rows[index].build(context), ), + ); + }, + loading: () => const Center(child: StreamScrollViewLoadingWidget()), + error: (_) => Center( + child: StreamScrollViewErrorWidget( + errorTitle: const Text('Failed to load files'), + onRetryPressed: _controller.refresh, ), - ); - }, + ), + ), ), ); } diff --git a/sample_app/lib/pages/channel_media_display_screen.dart b/sample_app/lib/pages/channel_media_display_screen.dart index 2974c472b9..66f39d3b3f 100644 --- a/sample_app/lib/pages/channel_media_display_screen.dart +++ b/sample_app/lib/pages/channel_media_display_screen.dart @@ -44,8 +44,6 @@ class _ChannelMediaDisplayScreenState extends State { body: ValueListenableBuilder>( valueListenable: _controller, builder: (context, value, _) { - final topInset = MediaQuery.paddingOf(context).top; - final spacing = context.streamSpacing; return value.when( (items, nextPageKey, _) { // Flatten messages → individual image/video attachments. @@ -67,7 +65,6 @@ class _ChannelMediaDisplayScreenState extends State { }, child: StreamMediaGallery( attachments: attachments, - padding: EdgeInsets.all(spacing.xxxs) + EdgeInsets.only(top: topInset), onItemTap: (index) => _openPreview(context, attachments, index), ), ); diff --git a/sample_app/lib/pages/group_info_screen.dart b/sample_app/lib/pages/group_info_screen.dart index 48d48bd554..ebc6cb2226 100644 --- a/sample_app/lib/pages/group_info_screen.dart +++ b/sample_app/lib/pages/group_info_screen.dart @@ -24,25 +24,12 @@ class GroupInfoScreen extends StatelessWidget { final colorScheme = context.streamColorScheme; final channel = StreamChannel.of(context).channel; - // Mirrors how [StreamAppBar] resolves its own behavior — per-instance - // style, then the ambient app bar theme, then the global app style — so - // the trailing button floats exactly when the bar it sits in does. - final appStyle = context.streamTheme.appStyle; - final isFloatingStyle = switch (context.streamAppBarTheme.style?.behavior) { - .floating => true, - .regular => false, - _ => appStyle.isFloating, - }; - return StreamScaffold( backgroundColor: colorScheme.backgroundApp, appBar: StreamAppBar( title: const Text('Group Info'), trailing: switch (channel.canUpdateChannel) { - true => StreamButton( - type: .outline, - style: .secondary, - isFloating: isFloatingStyle, + true => StreamToolbarButton( onPressed: () => showEditGroupSheet(context, channel), child: const Text('Edit'), ), diff --git a/sample_app/lib/pages/new_group_chat_screen.dart b/sample_app/lib/pages/new_group_chat_screen.dart index 2ed56a2f33..d003f249ea 100644 --- a/sample_app/lib/pages/new_group_chat_screen.dart +++ b/sample_app/lib/pages/new_group_chat_screen.dart @@ -110,13 +110,14 @@ class _NewGroupChatScreenState extends State { child: NestedScrollView( floatHeaderSlivers: true, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { - final topInset = MediaQuery.paddingOf(context).top; return [ - if (topInset > 0) SliverToBoxAdapter(child: SizedBox(height: topInset)), - SliverToBoxAdapter( - child: SearchTextField( - controller: _controller, - hintText: 'Search', + SliverSafeArea( + bottom: false, + sliver: SliverToBoxAdapter( + child: SearchTextField( + controller: _controller, + hintText: 'Search', + ), ), ), if (state.users.isNotEmpty) @@ -203,52 +204,57 @@ class _NewGroupChatScreenState extends State { ), ]; }, - body: GestureDetector( - behavior: HitTestBehavior.opaque, - onPanDown: (_) => FocusScope.of(context).unfocus(), - child: StreamUserListView( - controller: userListController, - padding: EdgeInsets.only(bottom: MediaQuery.paddingOf(context).bottom), - itemBuilder: (context, items, index, defaultWidget) { - return defaultWidget.copyWith( - selected: state.users.contains(items[index]), - ); - }, - onUserTap: groupChatState.addOrRemoveUser, - emptyBuilder: (_) { - return LayoutBuilder( - builder: (context, viewportConstraints) { - return SingleChildScrollView( - physics: const AlwaysScrollableScrollPhysics(), - child: ConstrainedBox( - constraints: BoxConstraints( - minHeight: viewportConstraints.maxHeight, - ), - child: Center( - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(24), - child: Icon( - context.streamIcons.search, - size: 96, - color: context.streamColorScheme.textSecondary, + // Header handled the top inset; strip it so the body list + // (null padding) only re-adds the bottom. + body: MediaQuery.removePadding( + context: context, + removeTop: true, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onPanDown: (_) => FocusScope.of(context).unfocus(), + child: StreamUserListView( + controller: userListController, + itemBuilder: (context, items, index, defaultWidget) { + return defaultWidget.copyWith( + selected: state.users.contains(items[index]), + ); + }, + onUserTap: groupChatState.addOrRemoveUser, + emptyBuilder: (_) { + return LayoutBuilder( + builder: (context, viewportConstraints) { + return SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, + ), + child: Center( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(24), + child: Icon( + context.streamIcons.search, + size: 96, + color: context.streamColorScheme.textSecondary, + ), ), - ), - Text( - 'No user matches these keywords...', - style: context.streamTextTheme.captionDefault.copyWith( - color: context.streamColorScheme.textSecondary, + Text( + 'No user matches these keywords...', + style: context.streamTextTheme.captionDefault.copyWith( + color: context.streamColorScheme.textSecondary, + ), ), - ), - ], + ], + ), ), ), - ), - ); - }, - ); - }, + ); + }, + ); + }, + ), ), ), ), diff --git a/sample_app/lib/pages/pinned_messages_screen.dart b/sample_app/lib/pages/pinned_messages_screen.dart index 602ae144be..35efc42b4e 100644 --- a/sample_app/lib/pages/pinned_messages_screen.dart +++ b/sample_app/lib/pages/pinned_messages_screen.dart @@ -40,16 +40,10 @@ class _PinnedMessagesScreenState extends State { return StreamScaffold( backgroundColor: colorScheme.backgroundApp, appBar: StreamAppBar(title: const Text('Pinned Messages')), - body: Builder( - builder: (context) { - final topInset = MediaQuery.paddingOf(context).top; - return StreamMessageSearchListView( - controller: _controller, - padding: EdgeInsets.only(top: topInset), - emptyBuilder: (_) => const Center(child: _EmptyState()), - onMessageTap: _openMessage, - ); - }, + body: StreamMessageSearchListView( + controller: _controller, + emptyBuilder: (_) => const Center(child: _EmptyState()), + onMessageTap: _openMessage, ), ); } diff --git a/sample_app/lib/widgets/channel_list.dart b/sample_app/lib/widgets/channel_list.dart index fb43d15d8b..dce9fb6957 100644 --- a/sample_app/lib/widgets/channel_list.dart +++ b/sample_app/lib/widgets/channel_list.dart @@ -83,24 +83,28 @@ class _ChannelList extends State { }, child: NestedScrollView( controller: _scrollController, - headerSliverBuilder: (context, __) { - // When the app bar is floating it overlaps this scroll view from - // the top. Insert a spacer sliver so the search bar starts below - // the visible bottom edge of the floating bar. - final topInset = MediaQuery.paddingOf(context).top; - return [ - if (topInset > 0) SliverToBoxAdapter(child: SizedBox(height: topInset)), - SliverToBoxAdapter( + floatHeaderSlivers: true, + headerSliverBuilder: (context, __) => [ + SliverSafeArea( + bottom: false, + sliver: SliverToBoxAdapter( child: SearchTextField( controller: _controller, hintText: 'Search', ), ), - ]; - }, - body: _isSearchActive - ? _ChannelListSearch(_messageSearchListController) - : _ChannelListDefault(_channelListController), + ), + ], + // The header already handled the top inset; strip it so the body + // lists (null padding) only re-add the bottom, clearing the bottom bar. + body: MediaQuery.removePadding( + context: context, + removeTop: true, + child: switch (_isSearchActive) { + true => _ChannelListSearch(_messageSearchListController), + false => _ChannelListDefault(_channelListController), + }, + ), ), ), ); @@ -114,18 +118,11 @@ class _ChannelListDefault extends StatelessWidget { @override Widget build(BuildContext context) { - final bottomPadding = MediaQuery.paddingOf(context).bottom; - return SlidableAutoCloseBehavior( child: RefreshIndicator( onRefresh: channelListController.refresh, child: StreamChannelListView( controller: channelListController, - // Always explicit (never null) — the header already handles the top - // inset via a spacer sliver, so the list must NOT auto-consume the - // injected top padding a second time. A null padding would do exactly - // that whenever bottomPadding is 0 (e.g. a docked bottom bar). - padding: EdgeInsets.only(bottom: bottomPadding), itemBuilder: (context, channels, index, defaultWidget) { final channel = channels[index]; From 97f2cafe9cbdc47396c481b15edc4a17685d805a Mon Sep 17 00:00:00 2001 From: xsahil03x <25670178+xsahil03x@users.noreply.github.com> Date: Fri, 7 Aug 2026 07:32:10 +0000 Subject: [PATCH 80/87] chore: Update Goldens --- .../goldens/macos/localization_rtl_arabic.png | Bin 59127 -> 59493 bytes .../goldens/macos/message_list_view.png | Bin 48232 -> 48306 bytes .../theming/goldens/macos/theming_default.png | Bin 56792 -> 57689 bytes .../theming/goldens/macos/theming_red.png | Bin 57051 -> 57973 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/docs_screenshots/test/localization/goldens/macos/localization_rtl_arabic.png b/docs/docs_screenshots/test/localization/goldens/macos/localization_rtl_arabic.png index e2b174248b71254e1998b9f238a28c3ca04a61fd..fa60ed826e00eaa98bcb2bb125dfd19a377130b1 100644 GIT binary patch delta 43298 zcmce-byQu^7bXV5fL9ln8qc?a`F{FCZ^?8fcE?|IrK zmeOEl?*3(O2CI3yHH!EZyw)B$@~zd zLm+w(B#&KDaJp$d@jZ#(&N^ATISx8ye4{J+nxZ8FJ_SqkbtPp7O%PUR>1PLIikBte zf3f!e#}e=#L5jx{1K8A%St)|BmQCW;r0YMvrU;@B3CX*J@0b5F$M7O^UZ+5tYtQ}z zK(wit`+u^N|98^IU#vsuoT$GT>G;;#S{?zFt%N&p$oz{Th*%9;dGkAB$EDG+Sxr`Q&lmZGR-`>hW61T3MN&vQz^nG!p0darzrN9HcKM+Lkw-veDbub^9?_}GFJUAV z_>*fsR+A9kE6>O9hMnC8sqD^Vad9&ayd-5SRcS%p)W?m`x>pBx4?`!j zjn0@b<=WiM#j9RhweIX`QBikmLmVva!1JdNbn-9i>i962LcGQO6M^Qe)BpBNf^tt; zor)Dbvf_a#%1jXenKmH~d86HE8bW0Osl$WbkW+JVp2$2dob;``HQzlo$H}Ij3ZWBC zo8DK}e3p?xGF*P>;j+=pVHfckxUF6>tWMSXeHr`eV7AH#Rlxl?*SN3F6Nl9)>`o>y zXFYf)oBraQ95}~IVhUC&RUdi7Mzzxz#1juH1W=Ho?~@+B(cU!%A^0|2W&`7MVL;B0 zE92sVJ3~bULpWZ^15;fs1xt7{MZXN#zlLd)r;{&A`1TD(;qf|?q>bnbjwPKZSL%kf zr;d(~CaL{-S;It8wUTV0?npqWa>|8l`Fa zMNSZ~h=>B_4ns>yd`>&eH@EpcFV~(u2Nlumn8kb}oQpeWq`TgHJi-FSxVI2Jb6@R-wo^v`+B$uMiAjwB)6i5O>Cs%JFbJ zT;S++376bPV63qDPDQ)td3dPBL>>bSoqXokrw5uvUkD4${!$d_4d=~@I}gMF07!>4 z%6jd_bTr)Rl8hbCvYq78xjIca;xjV`3r7~lRiicZy$}ry$hSufUVY1{WE;u&K+C{a zuqlvB?}UWD7Hr}Wa?0QI#&3>Q_fHgguk24>=)V@e&7N1Sag0e!j+YiBcJ;)q`eXiZ z>@d?2qXHs7Es4luZzD!B>d$VC0nGQOA#K^FJoa;lf2R%1-akU-8kRf>F50fHkpyoJ zjdfRUnqD3C_xJy`;2JO6`@pPqj>Ks;N+%$Y5r|}5t!*otdWl-1L-X!$&Y~_|2gRrE zUb2p{F#@%zVx@fkiygL(9}tyVD?E%Il3cy!e_K^_pL$JS+f#$CAtrBA2q?)fzK{Tq zU>iEI0c$bW!VsBK2J=G<${iFOJXvYL)*GGES-%op;CVqioXQs~ozy7=M=T6|(D`RS z8>L^_XE^X*PV(5)%^xP;%rEwPpFfUq0mX>^hdCrPAZCXWLj7I2iWB z?OXt(WaUo?L&IV)5`-KmJ9~hJvf~InS7;ZY7#Za*dJUnIMDPv&-YV6s^TAtN%WZjH z#zI3Bg0Y6!20XyNF@J@%dfx`YCMA_{aY;1S{%8ne{m<^FbxI5XT8g8-PPX?o`~A(y zNOyR9m2aP&mmY*PV`-Fy2lI#gk%fA>c3;y~#_mih66t*XCnem@F0nh;d)}u9XQ34z zC{Au}2j~cc^&xKgVtsY+J2~ymv%d8Iv2Xo>9}qmxoltD@b{!ki%JzG~F_9Zyt+YAS z3KD(8vd!D>@Vi?bm#7J zvK$T?_?Q%VTeN(N``{gTXmi9!^EP^wN=oeVDz4_SiKyj)>>*~XGg}w zq&Ctj<5OiqS5T+*7x2bRxptKz$jPBfO4CT zw(EMX#2TYt)CDp5E>j-_NyyP(FEQlUcPvF=O<`0JeR!UZJ1>{8<6|MG4LAk)<*4DGmF(xCmKj!dUAiG<_Ig0`q^! zRsJthgpe-OH5yelF*P-=Cu4#_y-z48{H+z;m~40{plO0flktl*e@e`&+^CFeZ_bJfF_?;5m@G6s)M@wCxMEllQi~0{^ zA*aIfKNz_g81z!1K2C#52)5x_*N>FQRkoL0ij_)DjW5eG3Cf_~vv}NcqY18)7{(P5 z=)U6M6$=~c&Q6fgmaGf<2LvsY$9wTd>K0u{^K6w+39(WDtn6}uQ)zPzk-W_G75Zs& zZc)9u0S_!1O$-|7dydGC;a@C}i>Blxldq(CHcBWuXu4?1Q=ko(EM8`lU_xNugW zfC;uPC0~p#Nu!gWSf=TaSJDA5FMPMd$y#YTq&{BbO|DP$z$g_<);u}F5MO9HiPQd>qeL;xsj!5|u09je zl$mEWy&6oAv$Y$S4|=*b@Mr3EBQdc99t9a|wO|fKZyvL_$ib2l7x%@>i(g6U!}#8& z;p;mBn-mj+!?_C{Z?|W;gSv8yg}N(K%Y`0boXeqckr2(vJ^J_eb_|NaG?pTl4%6Cs z!t?tDmjfpj9`u%I)-128?XlW|663kwc#FO}&nU7Bjm897{4N)Z>Q>ifje_T=I0Yp) zU-?K(QO|zOMvyGI_kn-u}38NB-gQ(erqYK*qI#mX9H=tgP(S)TBaAua%Gh z);o4~?B*r?k~+PpvNC2e-&^Fir}Kr>u>Z{zF`;l3ya9txmTp=-)p|H1y)N0{hL7!L6gZnc(2-)Ma4rp9fA zKQG@}-{GyAnpX8!8sGcNrd@6WM(&KP?r!lIvPh=u?>RG88!5l0?yfUVU_Bnfr5aD3 zKEWd*;x|Q2Sae$mdS_d7-iDWH)x;PS%CYXSG;&Ep;iNLbyi}aesZqxLwhuURGp?Nv zi;B9Go!WDWdhmh&cZeD*yIAc@*A)tgj}#N(@i&yH{u*YRqQ$`_Q9bl5!6pX=TN+Ut zp8cQCR>f{`@bR^69=%%00z16hJECC?`P<+BB~HdE}KlsO^^*o@~Uw>CF%edTmSMJZvT zi49cp#$SySqY<|9HuSeIDqoaY5VC=?QmivQ_} zqBAZhc6BO_{A>-0YEbYN7QC`>Be9j8UShkgxX>KKLj}-vO9PA(za1UV7QM#;gGUwQ zrME`~j<;&!3{JPdyL;}G8%g}*Ic#;eSllGi2ae<j~I7)xe6s@{D6hp(SW&;r5cgVkgJ`g`W54;LY7SaBt=7qzDBo`d9jSTa#Y`c)6>7EUSlAet^ce> z^E>lQX3<&OQ-d8&=PUaABf7u;HLX0+ke>TWM?*D$LwGe)-&1E$1i|C&bEQDSAlb}C zBD-jj|MF$+X2mQIau6OJy#?x6rMhV}NMvNAtyygmsoVIc_W7G1T0^b~3~NfHTt?k{+kKbq(X6q> z#tYbny+VJqXTx33AzE76yeT}gNl@URqE}s08xk$7tsWPGihSi8vT2IP7aO$H6Z(F=6I<& zHm!ZktT#%_X0hSzxAAdBg|{g~JyQxoW8ZlUHjcfIFPYuNJ`D}wiqP5 zn!DGpTAq5D1kX0-mZ#h6V;=x#b4yFh;A~^gjFF(=P*44vy{X7gH_Jz!wj61@(~VT1 zIkHqO{_rMy$HkQhJth|qM7;7`?SS%nZCb<~wPGPx{Ej07t+C%D&Rx`Ep#q(DYOV{2 z$Qy5zF>ixjBmJvf`5cKqf{cmTXLAkr*Q^E`2WKdA?gGZ+I<12@3y@F$VBL9X**;OB zr=y@ZG4bJxjLb$)N9ETV?Y-GwaD04x-Mu7c2mg+K78Fe6nL7Is38dE@&Ewwn-*LJZ zf!+iE{_;rfYCkS02!7+>K*r9F6|B&j-A{7uPg-E9YY(Q));ej*bgSd<(f2uR=j~xy zuC|*^OiadWtqIT&0XQu!Es|N_dslTRs2W~z&=Rk!&zDU#Q0U@OjhXpWnJ1X-r=tH= zQ4o~U^dL-P32*_r^ic! zPk_e@({geBo`|RI#WPJcIOe};?OR_56Evk5TtMQJQXl9$5RLSjyMEcN z#{6E#zBOiO>+2SI>1?Ah1RNlkQCKO+s3pxQCKi+3FtFX1k(pcU55OZ04j( z0d*E+6cm$=hn7!t){rtb#ixqqlOL8-w88&U($c;_Mj>Cp+Pc*Yfi@vLCTo7GOiN|# z+IIPY06#JtaWHdqnRq z7%-|dhta%GvcBGQwSNgMwfRr3&;|%g9u~A5;e7P)AOtOlhOtD_f3Jh0!{=`1v$D!m zm;k<%n_JzE7dsFcY=u2jtS@xJU!`N;96VRE?Qm2pWI0<5>*wc}?F9zww*tpV7>6SL z@iarb^W~hM{69^XkRI`csuO`Bq$|^tlh^M79=YfZ2w~jb-C^UBh<|nf-c#gKWGew+ z44|f?t8wbFvTLXo0g(nNCES;HfhKA(QGx(tRzt3&q@-G^Ufb__;OYe)zOZmxc6M%i zyT}GzjL~x&9J5Ycz=4;Z%;UW)d&bD3U!N^=YWsIY^nDyMGI`Yz`hWnG_J+Hts3=){ z7G1EU^OYFcO@9D5T={QA9N4h2u>~&<6S}**zF$=THGMDQpkDk{r0QPF&@_1QTS8$SPv1=r+HOXGAdTiyL@y)Y09Vl3(PG=kcj z5B{-RiYNzcH;ULdcD;Scw}-Qbm?~RU_ff-Hp77Nl8-Z6@@(klT97NGvw*P_(N6x*h zK|cZ(zL77Qs33gh5xy_%v`O#Pn%(+*XnelOV6sE*hK7Q|{Qg$7XiBNwuT{BLClM1& zg9p>}E5(YYJnih5P|^iG8FilL2djZuCMDo3i6|QL3zFa$ces=)E@1 z06H=TrB*S0Aj21W?XCZOJ9R^|pA|kN6(AEP^KN`4b}H@s{Q&Bn%cc}H4XskEq$`=v zZkx=!b>mL90BErMSpx3No={lep6(7YUx2`{}Kd}N)FPEk*< zuC8>8-1snRUH2w`scz-xS>Y0z0Sv&vThM_WGz2w>5Bs(4Mi45q2GJA0B=y)5{;MAW z>gFJNgO~hTls`+<;TsS~aDhT0Ej9X*neSckiv~Un4A%{8%=gf2Rpn4}Iup3*(5icL zG*;+7Jan={gR!tQGk*M?j9o4Z0~Njj4OfDK{%-(FpZ~~l!{i9I27p~ZBz>5hMiTy* zm5?Ujkl+r;L@MBoBW?7v#~(~q@xK}Pd{Lx+rSD?r3^zmBa)Yn-B8{Y(0lAMHtqmXF zCU2%j6JKW}Sb%hs5_g^DTUT#)$ER>gm(u1Y{b&+hNZ*u4KCGqml6-Z5U)7hSh(HY!5=__gZl^8L zh5_1WiQQ7*&`8OvQTgG3+faD0>=M7bs-k*a0vfWIZ2I8X>=N3B_TR^%d0 zPlx1-!l^kYBpgr+EJO(P`FF)d>LAn;F9Oo65U$;jsb77o)*qdlJ`c<*eBDRpwn_CY z;HeP@RR$|Bz`2>@&U@v3rJR>x!tF6<+lYxNP%-Pk%hCPdz)kqWEh= zySRchlGH;iCbAYstpD|XklX=Un2?wlpfiK*>;b2w#*eiN1bshk((sx>1?!q1EIiG_ zHOJdjUx%jOr|er*A{EGuql&nJA~!-VLbmB#n@e=rKg>h7;WG|Xx$qKzPaR_rOsAUu zI=+u;XXw{r_FM^ZX@R3hA1g1`ddS8$oXj_RF>|Uu3PZ2x7_Umjw9|vXpE9*>1t)+l zl`xb;@pF-e8IlK|n1uXKwN-UN=|o0V|JGJ7?S7CWZw46b>HEmHMDPP-o6zdU!M4AsMY`pz8&fD~!kp z2{Qx={pF+-uv6@)X0tl<^oXaJb)`OP@)BcaQ3?q8_l3rqEryN(I9BX9ByR^2x^mwA zwBxnh+nX-6-o72Moi2quOP>Uwf*?7#O-7~*c)rnu*~whLe_gy>NG03w%?X!>Xq~cV zF`FNCL*g*7VQO^-|M`x)MiS>U7}!aqec8lM&sDW z&A8-*WB>d>l>8nb6-Gprk|+C_5u0YP?eo_fkE_9iw*_onDdIb`G`W&=JsCU9I-+F_ zg;PO-g?I>N%Fk~sqZ1mmsX@EE+zT@mCDyB!sSl567rv6CO=lg%I$PRMBpQP zL_G}Op+Dm7L&{^FT*zUuvl_~w2^PY+gqi#tzZJd-M<)Wqw@j^f!SP@UE2{ew>}r6K z9ro#IOS^Jvi;}t+wsKj7_)?N1fwTHVD4+uaA7|0=;0m5)JZ@DrTp+#Im7jdr$Vjy! z{ZqpcwTSRCaZZ&qJVLNBa%K3w3l=W^r|(`7`PLBZr8XSCIR-A%BMRzJtg9@1 zY1Me2YLR(bV7ae&I#+LDl0=#A{Z{KH7y0A@xZuJeT~d@tn*92==hobK(qaBfryf7Q z{SIDk%Arwr_sYwqsU=X`9o;KayEc#TY;B>SWMRu`-T0E??vJd`KG>vdCw%Ai3W`BO%S-=_ zJ;AKn6uLrVl`*un4q4ebKdw^Xb>bT31bnBqZ6EHTx=vZ9z+&XSx?}SaFG*uh@=}v6 z*cpKmMJAW6Uhc_m59}}Hg=vMQYa~STLi0kMp$aG_B9koNpQ%zU3G5&NWZlg8 z>w-22_4q6>h=skV5J%)BC28e#O-N!ldc991kjtZF*uRQXjlUVJi3J8$``X_L-%$&< zQQ&d>`3`EWM$rV0`FMpZj`9=-itMxNKjq`50?Z};y3Q@9i}|Wb%^F7mq2@nEcR3ka zEnkIJqC7|gKN*{F6A-H9vs6BTL+%C*k@3*_e)LH6uKW9>|h zU2CgjABgYFPhj)%N~ZF4q&hoADMTLdnYHC*hp|B(rcy#(L%C<)C`79JUzK z!_;LlxGr`{Kq7N+_a+>CNRc7(uYfn2c+Cp*UO6A55P6XOU~dm_A3pG~y0hA4M2@e1 zR!)dD8ktn#r2M0Lvb6P&kIqWV0W%eo%n)))p#>3_mAC7*ugNr*WS7Q};kS2=3u*zktt&y$lN4Ab4Q8+Md+feH0WJ}aAM}lsl~H0vybR)?eVZE!c3zZ3jm6p+ zF_}}l=xw*@a+^&Yjt75}&3Y^aMnvdr09noEKovKHP<9xR{BUW1;Xmwq{c>SFJiMrS zitum$aWV27N_Z)n{{1Fz51&GuG8!|tGMHk34p)?>{ekfqC!WbnMDev!aVpgrnx8Xu zPE>lo%!yCOukOT)!JrWMEFKni2D~i!(43q~b8QccDsxW}5d$ko6tmJ?&`;b>Q6Nz0 z;uYL^CnGywdG`YQ55V5b?PNGWVrZ_#)Z5>)+3mRtJlNZn9}BlvDeOM%PQ2=+(OS;< zd6q0E6wkkT&+2Q>oK3Fz4tKOwsUUF_vE1K_4kK; z;PAzN@uL~`!1tV9xsD?@??E7S#B6&sv%4Q#47OOShTqvtb~BBR{FUL#Qy{{AnTkNV z`?3%AH#)NB9Iy{M!eVK=_#-5yCt`x_Ds;5Emh6=FqsIq>Ouu5EFzI+f6;;|LLz z6jF8B8QV8SvwO!>?=|4ncZJX}y*2P=JOKBz2*mTIAB+{ws>=T~1HL=*2Og5pr7Oj5 zZzSB%58hpHzyv}l9!a^m6Vu|e;YaeyYiLQRSSrGn<3Pvvb;42 z{av5>C|z4#*>cGx0JuGljIZTPR@gF)U2^)5H>xZfZ|QK^gRRY-oK_@7Tm9UsMOTLeCH73a7=w}th$bj8aTm3A*^m#PDD4;S9~Go@07we!+diDZGW zPFanqE-3Ova8mNL^3B94RK(5}AIy%!Xs%qiVJ$8z_oWh=YJVxUB1-A9PO95e^re5Y ziO=r0n)%F|72L5II%@Gz1(z!;AP=toYuAzdPA!`q&7CU7wGF4O&Z647ZS&&KJ{oZZ zPGFCy?syTYE5F=%Btb555)&4 z{liK;c?uTVyhW(m(}GH@dXmf4X)-tHaD*=8Go=T0q&)UUBSCEAd;%)gKjQk^?$K=Q z^85FeWnD0)Z04LeH7|i}WruT>d2URo{jiHN%tcqkUnvAu3yidZO!PuS=-tzWMy z+!(FS+t&+{;_2GH?pbqkYI4FeBNHB|s%^ft>oFU~N8Q8VvE-%`xbAZj+~Uezo2lL@ z1}xIFc%8~Od6gZl`E}_xt+;W?lSYsDjjvG|QXU-`{!_PglPdhM+6r*zwVn70E1!Z| zIx^b5cj4*YZL#e0Of2amTIJIj~}@1 zUXarm=+3#7r&pbp1ACj#*neDnoo`SLXcbU#H zYT30ciPoI>bQJZ>+F#%Zr=Q$g zp<3Vrl7Rsye{0-k6p2$NQIV~ilUnrcPx#9S>2K|9!diT(XtYk5cB(1ihfyZOZJs%S zQsiWA6Gv@{FKjftasSl(=`ca>KotW6ocfhnRJp1CVUfeFjSaD^-Ou|oF^s<}oPk9V zr;`z%>mw7ycD^@R@_j6D6~I+lk>|!eLPZZ_iH(aYJRH<*J{@3?S%gYJ1~t9}fQ6n=Rds z{IQzj0t8S`dgz-j;I6g^a@LRBMa&+$4Fsp=|JaQNVrF`W$uiuM17kxM5ZCSRRxTq% ze=L_W%NN|vj&_lKpfgh0o&<~rZ`O>kNqBv5)i@2`BYkz+T&E-r?1(MyC;IVGv@Uvg z(CBubLXhj*-;Y2HZDGJ87as-^VKltfuuI9?pf3~oP0rO%HRQ(mz3}i*=gV$Z5{zgv zQZJ=?JLsGGBWe1o8^F5uBzRTH z^3;-sAQ`5(m5uk_yoH( zS%Esx-%tJi{c4Nh;DF-~$N?*FVjGtYw*YeZ7ja3|o}J7Spe@oh*ExxR>Vv5W^txyD zkJ(0*z!!ecpx!IuHFE9fA_Jdj9ApOZ5Tv-IWZAHu993_Ov}@fcGZ6=|ijlz$NNt|Z z+c!K(X3oiqIclijRkVrS`z+#3yZWni7$|8ylKmmlGFd};9;8m zxavJ-EhUd(3`j-~3;*`)NyF57%cejes>=Z;i!?MJvgCAbs@yg(I>iD#kE@#pS^mI? z2EYv!ly&@Q|Cx(`h3m3*mGgGguX@-_#0pZP#p;?>+VbikYJ9xu7E1b#b;7?g$A7;K zRx_sP{q{epU+O#o9vT=$Q%kd1tiM&JKG$yPiTkAvHMM2ByIpnk$ilz zAIf9SoVa~d$7CLNEdk%H+n_Ys7M6BOI@t8Xi^}_(#dEVZnz0oY%quhT*1}7U;Nkfp zeMyEVR{%>Ub5uNPMEd5|#wYJ#E~du z)_C>fE}%*vX@5p^*7fu?kL&}H*vO>bN52Bl>re!xjAwKeUv&>L>yBd@lx7)Us}6e^ zIB{_7y{(+&o{gOiGsGoFg7qraVEMLK#*CXl4x%jy%irVzr$2;_pU6vnfPUW`-0I~^ zcwc+qR=`u)ZK4YDMm?}w0j#k~O|c_^`@HQ2fW0wu8WpwIhC@;1iiV3RQvRxRyefiR zvIr-u9l2G%XGI})WVOqmVZq^8w%hKE;vGkj4i7Wcc%&#QSTqKm3P&t|Jek1paGSBQ zBN`_T)$gbXkU25g@fUaTqjkb1Xtcv?UH%r4O@*xPrm!59zDD^|9q*X%iq`#jHh`}Q zSWa5bR89~J2I-*%CGH0jS9Y!aUwB7+*D2Z{pH1uNlipz|B)7J zS@MN+`ri>bK>p|dEt1Fo@Yw(SRHIdPUqQ*LgZ~t|I+6vE#rJ0*`}wt_7K8Ltr~+)( zD-^?P*nBdd=(~$xtb+Bc4pZm9mc+&JfNb8Y$x$EH4-Pxe0#kl&ZTd(Q$t_qoqKQ!u zM2#36<(jd(uUMU^jcT6<1`j;dP+$@uPZB7OcOFYQ;U%B6-Sj~?vv!>8^B{aACVa*g zRvwnbS;?wX!#f(4QH}7@lo{AM-QqW|5g(K6qOtH2AW@9NuAhDfCEsF#4-LZuDNyNp z@vw*irhuWXQGqDRZlEXaH2#y6XyzDG0F#!e%mb38_A(4Lh4?2t;fAu9ny#>(83xuT z_yca6#>tW5?knUAEHPpEcIWXI>-QCLYY|M`l*5)In8oBF0Iy&BSdj6=j#bB2b2D(v-u#l zjF%j8*%ZX95ln`WqZA_R(7e>$lLK}GgMR$|CNsgDT&dedg}E#S=48B%jQ;no)&}uc z9!&Kmc@Vtk3=2qh>*0KBikq#@c$@8zOkH;Arx2DCA~q1sI(7u}%RMR8a;^Gs?kwnp z`|7)Sx8uI4G0cwa1eIgk$Vh?F&>WwURgKW!_RqN-kQ$FUM!Uv~wO3PM#1$LD@KwCP z6nhf3hP@GbSd^%5y|dizJp!O7O*$#MzVK0 zkb4Y|Dpp^AsdRueep~!lkw>ev`MqdWbX_MC?bpTq9Z3g_dUs&T>2di>qZpU0SL|j* zqMnshv)YOUEOShAhd}ToywH-GrT`ae+PZV%JA33w;jw}4tHouGGDYhY+0m0!26K;JvC@V|7lGp6=a$od*AX215hWI@Dx5@{=l&|5;@3$ozZbX z!5^E6&44Yi{pEQdOfjs}FwDuq1Nox+5dNmT@5qhQy+hgSsy*^X_&xxCgqT3`lkiuRwzsrp%K{qV3d7 z&wi^FEL05*o7Kd9PaTdkKI_2{25FE{WSrq{dPwih9#peE*FUMVWqip{A7Rs6{ths` zPB=RxH3dj+IN92`%lfY@(t9J+toPifo;?89ekhoErFe4Eo-e9k5;P4*&7tl&cP*v( z{#kDqVcHr1$@lQ8o6fogLT_#BcN7bpXdZlgg{CSF=7QN*d?SXAdM%hephxLSGmV~x z2FFd0k^zB%787Ns1}9hhGu!iIS&du0eg!MveHQ9YwzJl9-jJ#V`uTb#H)hL}TLDRf z!X z8;Y6hT58tAsv^K20lrL`L9k5qph|T=CdlzSZ;*$gy4VcFr+_S ziI@H&hqM}OPR62SA(wtG;J)&V>uM#%d0L00+2rH;>z_OO;6{xyVPj+nfaS?(=a6(R z?lMIiO?Z7h_dn~Xv-KeVDGDG;!ECogD985wcY~>IlF_1;5XZkUH(D4pIj2UzF!t9)}c!; zG9c_+qw0%bS!uJCsW_TQgMF;Xx8Au1`K?u|2TbLYZFB{X%*YfdB~=}2_<_ew!PWU9 z<~zs0t;c3P!uDgWEgeWumtg3)pah|-j#B`ApVx66w+7f|Wpvcp9@Y`f54nQrcjbS3 ze%#mce5T=YGLKD8t`dH5S3d$AtybDLpPsQ--&Kmz?E2>El+Y)U()x~Zt~K9p88Oz4&lYpXBaZ?d$q|a&IsK$qrj$z(-FGqU!)@q zc)$^W8orx@#cu_U+j+W;Ow&BJ`~cOzDbDRoAv!s z6ca4-WH{0!7hG|%`Agic<*4J;6b4DeRskf`GvtJzj$9g=ow!}&!s;oR@*nlq>;A1L zP`h))gGi97-l)vW^sKA!aF)=+`aA|K!|k9?RA|?7Y+??u#>gvyEQMi%KP~-T=2Ede z*uaB{KYv2J@@rJ|PelSy8sOX{!2GGPl}6%)lq0$&?Fom~DJs^m7t(flxV#6_azHvR zDnaF{=3;PYIFFTL$`=*C9aYgcHQTI|OadAFu6aTi3N+Lphi>ihX8h3|P^y>bf?{^# zHnq~`$9*ww-=5FbLt%j%FLZSVal4G?c_l-y(qy@}4~ND!OKp*mWgqgC($)9P4YxSd z)Z34%pXKD}KComB54Q}VgZRIc*ZrO-q|t1Nc7LW^%}_hR`W%Cu_1Rd?fA4u2Q=*m5 zJoCRCP8OI>E5-p*c=}PNr-~q|iy~{iQbz;ATQ33On_p`&nO1bwI2PCz_pG0;o*Sss zo;!zNj1g?FYAn-mGDUKi>zwwLxT=;bzXbr9>H`hj;A1`h)2n)8EimeoYjYJSdl2H+ zki)2FM2oRYy#yVYSdj}Nkefpwp1KdGHACj0dH^ZT|oVK9ylxbn|6 zLdlzM+VH+Lx#p#{JG>oIfB4dc=$gi1OAAxkdM8}O$+5Rwiz6AB4F=!qBN1`gL!~^x zN*uq*FH2r3OZ&r^xBXMOWBxtNi(cEcRf8DTWQD8qcA%KAqCUwLMr@N<=FZAsFd?S5>_^)?c-ZcASO)=B#f#^jU& zC!n;Pve|_0X%HadbMeLBiK4?l_#gXad5U9`F7vZ7`hxpmqhXqk{l0=Cpa_FQ`;77z z#LufWhg+`CIkP#k1ZoS^h6=L{9*MbauZElJq|C`$PFVT>SgRch!xk$yzNsmU1+8tx zcw#cCCpk7;XrB*KZ#m>P|Hn$+LGhjQ_6|Bf$Qd&BKfhV_MIFh|SF!LV=CR-KmooUF zF;?LtvTrW8R!HgV&F3cuiSZ^-IFP=yV_S03gw8-pk)ZMse+{E zl{}lTath+#58%WFe=Ggapj~GnZTPL7?$0QgAh649%WVOgi;iy+l&cn;9ZEezt%v>m z;BR$6PJM*A#mz?SL#!uivXkCe#dHOpgoDHPq6!`Z--`YTE6~CF+{{S*{8{LDIP3WP zca7r~InjB&W>{3Qbo4$p%%bPQN57ofZ_5z3jdaPYvkL*}6#w6qoSeSsuPaYt%(~}D zLQSre^zVUhAd4sYHgl;loy)F2-c#kp@2M2M8F1u1y||#F=KcPC)lgI{PzZViN*W)p zqFMJ9ooB^E2%UIZqKN)*0SH5gOrBx{ESh?33e8kqDNEECoR%bwm-~(uj}BIDw8@%I zDqd}YR3BK7aTqdlaqGE{_VCD}`b#(bv`P^G-9+%*VP8V*(wJ@i;@?3LNbU~@+t|^d z&|oL#W8S`X`SB`0QbrAooz+~;-!-;e_HHAdIiZ|f=xyXz>?0YtXiM$Sb7Nqq$40y6 z8%Se3@7s61+?&b&>!;bUi3yss#;!MbyDypw&WLnQ@6`~Fw-a1hNfF#KCj|ko2rCEM z)hVPa|2h_EA96?zn# zh3Zg+_SZY@KPnXa5V z){;E015bo1N%{Dq-hSYK_HW~vAE)aNGJWa+l-1q1jeF&CC9hsDmPk7}G1f26Vn!BR z);rSMq`9v^r=54p!L@9^b^k~^cS}=qowptfb5|k3K*;G}^v8~c zpwg~VJ~DHaKfpN%st%e6yw#JjC`;qluU~(h;wn?uNfRxlj}>|lDN(HupD9t>1#ekY zRN9@sTo4`s@f6&V=Hm_`ID7JC%q|P{Prl%F*G>+GDdf1d0HypL=Yv%CGNpL>BJG# zf1Uc5iawaX&=)@iBYjf}`HSjE20{RgKNL}KiDVQN!=B&qy&&8wd|0yQDGcJdn`2^O zD4pwY{(g#sJ2oh1IpChU@d_aWcgz%kG&mj-#`G8R+OM$Xc|dO^m_7@ISl5i)A?2K* zUqXrXT!~>zO(87>^5h#>ajrAAHP5qEOO}HI{Uwx>w~3G-KX9P+_VSIYsBRew6c0<7;a;~PyPMBo;v<-v%0|lG?Dz@)?QaC8`t;_9=u@aLt8f1B)S!b1C?j@?sNY$48ZD@xsWE0QR_kdl&~WPqj251cwq8C4_Ib;d6jRr_$<(x~9S*FLH*c|i*@ zZIAs0xppOqW-5E^os;3Pyt%U3fYd?%RO6oH|MF-I1PSsh$b^HVhK={+-df=7VdKV- z9g3ey1~v>pyxT*+-g+kW76%z-I=rGIQejypu<1i2i;m_act8LvX{AtKQe4_dN`BGz z)J(*`kM2t!`|3te5|Po7`R)1CW~$~7gR(f;n7L+g{6G@iY7lZ2aJcdG3mK!SH&Q24VjykojJN9^1U zxiZ_Cq*c^k0~Fm`N=BG?y(Hl~J1h9OsdcsxVOrUYKJyj1LW9cDMQ#FWwSzezxe1O7$X%<}NiT?gLqqLI0EBk+r;^k8?{C_N^L%HR^X&?|XQ+ zgqD8TbB+6o<2r4?eRhD2@zi*o>QRB1toVSN*=T5RY&CP}= z0laV0JzH#ys>L&mEv;x4Tvl9Gdq@vD)D7a{RRWnN>CTF{1%EOqyIIyKZ=xYdY^<3m zvo*h$OsB0r_zCOp{yCrYVj8GnvWr++qZXRdogcx{cVZzye#6Y z5-x#dn%SNaveLK9VVh|yJb%Bo;+c|3J7CmS0?||=ZjMx5d6JXnPf!D_gkxNMcKFgU z{ZZkfIw(h+rj6TMBHX;N$(r8-)$`KLZ|l*KS(Pl@LKB#s6KIrNso2_8>OY?o@X0=Po?$0GsE_dV}iX& zw>v@(4vvTqCc4VYp5By?_ZTLV-I#lx0J;17t(~nDedF2jxWgqV0XX^65pSFetbEdB zP6ld6c=G7a`H*`+h9t_S3%)PmpjEB%FDD6ApoHnh%=_!GF&Zgj?NCBfkMwOBfrrR*c(Rk1ot%jX4R zG(^cLl3qG;U^G8AniA~F70x@)0k@7guTfAoqj?Nis-lLr1}{RWsJVi)<7zGD%aFmT z^`Ayv_cW8q>lRB*c;!0vuME$nP7La87Tj!69(n`QAb$&zO)1 zt3u=ME@6Cpyyap81%K8tZS1BtXjQ8T{~K*@9aLrbwu>SPs30KShyh4SHwXv_(j_1v z9nu{OUTJ9%=@O9c?v4f0EV{e9oAdblzP)G8oIQK?nK@^Mzt%gv@x=Yyab4FfC$y5> zpA=YM0LUQAoiaOf75@E6eE+C0=e4{5YT|S!jpU*B4vi^^K2FerniRT!$jr=4!k#Zz zq%Dx6ROQ%sdcHmHZ`E{}Oi9SRSOTYfd&Z(&;JB;N8z&G3#b_sg*DgY9Ht%2aKBp;j z+Sf_sbE5d()ukbQF>hCHHv98C5@a+GhxtB%vq0((d6ukLiRCWp)<}U2Je2$?Y$*BU z&cJLeU-%yFn!tq;@F=9?FR0`M1pG8A%%b1t6@C2p@$2c9j(Wq@=kroIp@bceNLA&) zC6V-q1v)xnhz{?KRQk}to|_fRU5#-phaF~~hq|2%v6zDM+UB8wk&z;ODS_SkO*7Up zVeL3{w@G-iH5sPxigJB3t8>wMCCU91m<`Q(A}6KY6A&@+@Vpr)1)R)bMTBMb?vj`g z%iScQ+Cke(aRJtN5T2~4LpK*s#076+uWb|+aUdZkZ7=b3DmuDA$~9(#h3~2ShZjou zU#dLISd2mS);i|=^we-eR5X@HUo{{prsjGNGq!JXXYMx3OAvzXbJ`j_?dp`ct7;xLaABESZxylhC31cPJhy0cMGXOSaw>jU$ z%;&hH*Luu6R3@S0db*R66)NnF_LbAPOz)Dpy)&8q#0LM5W70>YXyz}Q+K>?|ib9R; zn_R!oi@Q$qE8bW%M;99sPcSk2%Pe3pu7$kCUothtA;s1OH zA|+%~%cB`Yv99RmXx%zT&#PD8O6(`~&PP_<_BKDBWH|Lgl>8r38XJf%yR5Zi56F`C zHoJ77T_>xA*zm{iTU8Lhw3rAFZEOJg2EW##!S!?{Raf-FZa^D~X4a8Bi8FCM-I7FP z%FGy^xHh;!F#=azCeqZnuf#F4Tu&cgo$j~g>Zq>2B_t%2laiA1YqGe*5!lI!0XW(gA$+Us-jh4XpNpUKgFvx^HW0ZK^qM@QTC+hb7(<1~dFWw3=uveg>~ zEud?YBbwfX>xZ*-^AhtO4W?uDZ%IO^t*-MViodq#!C>y(j~x)YETkg_=;<+uQ%CrkHo@a{Pr_bFyMJbTF%zi zx)B7X6DF|?1AvomSN<3N|L1;!~9P#7X-@VBlz;Dkx%sWPJTH~#+pK2t71%+(b& zicaOV;N4&JYyB_*N$cW(v)$<>S&O9b-|xsUC@!sq48TQ6Na;mp4$|4w*+PPe%UZ7S!hwFoe9 zuLWdnj%-?nlJQ76JC7oJSGCPLv3y%2<=8kP{Mgm?hrvJmTNof%nGQH{z za&v-JecQtZS8RNT_=AI7hD+18xbsk*d=om*@cC^MDUMQ@a(0Vh&Pi%xW20QC9Dq>B zs>wpQBb9%fk6!KhTng#7?T-}c6v@PkFafP~?39`y$XC|MDOJ?J&iUTkX|@Lf zR5~$q=nwd0@V*bCG-Un>Ss08wMw+U!`tm*+AiBcZfKOFGq(_O6o5=)rrPX}57bU@iudH!1 zy8!__J&jFg%gg!(E3W{hcX=wc7|=%#=h~|_UFRFdrFj+be8B)pB^xd-s$5zhUEdt_ z(5>}%?+Wh%xF{e*4G7$uds^&|=FuRs`c~?!vT9<)#K)FAwFNH0f=dkL?Mu$))Gm46fne0&G@hM0-Q(Tc z9zzkc`M28dX37W`YFmz4eGV@!hyeAt-+`H$D^9xp-6D@*{7rz{h7I~4Uk8PLR`_8+i-XC^o5D_Z zXn#L*d>a6x$e-P@_+Cwv=-bz3y-M-mtZCi_rT^B5HVGcr6Qcckfe24;igq~sBf>}~ z=W`V%;8kK!3jPAj?QlROtvj@9GV^tYoePTY!_RdSU(fvbJg{&tvc7*G;0@9yqSpkl1!wVU@bh37cxbp+z+5qDT; z%P~=T*;;%*!^5$`Ap&%GD8Cc48AV1W^(pDYtIxAW%_hrNxk4!i1el3PNTfb|;83Q+ zci0-sw3?s0sfP@B&h7U;Ce>CPo}Doj?}E2BpDFhQWW>mb2w~r&)qs30bnlkt2CY5a z{(Kj(Y*BTDgmP8To#g7|h;OBv76>Sm|Ks}+sRp@<3Ab!`! zfrY`vS76b4{`g_m4yVC(pbON9;CS-v+3HHS(hXE^K-}Oaw2&-(xl>&NT(4xXjg+(H z8=KF7!`c}F`AJZ^`5>|e!s8-9OxWy;9-q^9Q!LOq4H zm2wotMA}3oWo4G^`sL6E)h+%}p{M*suM@ zB=H*C)mRQ=5|R)f%yEGGhy9eSo1HQ? zMOGj-R~8r3j~LLgivGIoH|+|ZmjhQf`lcMOK^8uo5(BLN?zg!&gyPp{7A`wOEI_gc z71K2wOsunui*DIuwe{k^n2o)rpC>F~b$h#~cM?%NX^x{|_M z-R+10e)U`nT<8+;$hcPazrE&om52Q%NG=OeV%BHNdDj^5YsJ7!eC&_ix-3!Q)~yh` z`D38^lO;Plb+U)ZYesjr`Xkn}#?NZ@h%IyA@3}@=C^_E&KqgpiIa~fw%m}P1_fT*K zv;#T8gx+KUHy+r=J3yva4$2nKl66|%-`APy!@UfLz|;Q>WgngmN9xy9IF%J@*5Ck7 zvBom4M^|NLaB0|n8-y$wAWFNrT-PDvvHg{pNCskPQ7{CileuCg+XTtoU*B27$#-YU zzT7j~`sF!;oJA^81BP1uSwiEUL38unUXbpmFTnpY9j#q>yDIXdRFdgEfp3~(&f_EK zyk^r?qtcA3jalSJ!av_ura%=}4SDg6PxXh+r$IoZ5HCPAy#;T9p0eY`2lZ7&YaY8| zBbvxae1AmrlfrNNyPMrBWHGd?6&fLLn+fegQG!m-uDr2ZaWgW+pS#;q7%xFouV_%1 z-LbW6-zUN(C8CBMuN$yj+8}B?^g+iLBo+|hNGjd2jX;xcjOZvC2cl)b7>P5@j zs}fbR4I9?$uQu#a<~=j=!F{>J(iL#=7J`%%Kr&U$!ZA_y2@91aIpGr3$1!~i{&-)b>$kt+gk4OJLqk(rfU903V@?UMl+_y2Edrk)~4IO2% z!Xny%mcE@VpDN}YUQ0vw&j`~XLCu&bm+u=JIU6IYbiTPZwWTZ}_X$cl z%Gt`fGjT%Ww{`5ARvFk!lzIbw#`~U6c!pMNz4?X6ebj`3;N*cejA#Ac`D!u1`Px5Cb^Gbi&*3*^ zPkpglAFA2v@j%W7bi&lkUhW~;DsLxLCO1yJt#dT1HA82(LbB!YXm|+dd3XqR0=?Q6 zKV%FqC~K-E$>u6sdiCW9r;nyNa`V89@FjC36ZuOT%CXAi|3lafw&NbY++HAph0uB3 zo;aK0Dv;V*=lo4q9T(naT@dj_Y<^H6Td-ZU=CR?1$R^A=H3M-IW>K@{>k{pou5H+} z-w~az#1;_MBdgtQE1ywt2P5JYr~KVSS(RyhunjeLCc}y+f99z5qlf$qm4coJX?Zv8 zPgk2Wji6drYrdv7vVM6+Htj_Dg6eGmS>3ZNgzwOF%tA4?21lVpPrORN4-?O+t=8P^ zq2Iq1Ak#_ri_gi#EI%$*Ueo=;dY{2mhgkg&aTlZP3o|x;LwxfK4$My^X72o$9i#>Q zgi&lh&%T@=+^y^U9wKJhI3a@F47s?ZvpO$Y=N9uMackym=nvR!9Oz~m8K)}bTwcUU zTv}eDJtC>#&X3!0m|IaBz;&7<6-uXQYBtM&+&57ELosD#SliKLcYVgx;rA&)+|~%c zl!3}1{-Mk6E?hn})3IV}BwH~q)8SP%35m#Q?&_1nbFnb|x;8(Au4o8KOq*ooC?*r1 zS^WiUV%!7+m6Z%Lw39-2v2-$+h(CG7z#D)aM1Cys5Z=@9sPc)6GBCx2GT0$4sz7v0 z7MAd-^O5X^n*%PBj}1gU^Iyhr>lPnN%A(UTGxAno(k#g5O+Jt8D8VCjOb8Ne*f(79 zZs=CkUS0N!$&h43B#fpr#4}CFjJHeQ}@WDU+)nQzsR2Nk{`jql{mKz)H z^S79Hyh-hAebcd5ZBhhsF3%$0;x$;k*mf*hp19N+$sQsK8T+U=tU#xF=OmPpU;JMy zP)b%%#HgRAH(uE+RtPx+JqY3XH%e5)l{L%Jysc+Gruk^}i6TR`$~$Pk$V8P~HbbKr zOH1R!Fas-cNKb%jUY1w|(y%i8@Qg!Iy)5!!-5Fxnx#1`HB!pbegv4e@@{DIjUu$GzsOwAHd{I({b@hvkuq+P z87()45aBTf*30?OL&@61Vy?DGcJlG+fQbuMZs&4E#Zxv$8diG8=hnI1dI4j-usaQ*U z?e_+!8W^b0UVd@fl_*fOkx0l?&QUIG-YxptZ;o7opD zcYEbfovsDZpC17RsU8p*3?|`uR8Z;6EMs%{1cQ_%TH%%dJCpbOq|rhiF9U&~AdcG} zKdAO*tlw&7Yh)-!oNe0k5_9S?aC{R#I3=V6nr}eZ#Dtw>WNW6erI{)W7x1Da_Zw9I z)b3)^Ym4Jn&{oV5!LK0a= zBOJOYk*L93TGxjfDev*};+C`YvZr%N4heBgSua@dLXs91{DLViQFNqTo_cqLoqoys z8I`oz7-pjWPu9*-bdrZ4Q}#<&FABX{l}(nLi>3%`q+m)w+hVg`1&;1cZ1pTacl?U8-r=$MQmxdbg^Z9um2eTw5Im+hlhyb6L~2azR$BA z{xc^qgE-VhJtG?k^(K9{ar@W6gzDdb$n~gNeNfQE*qHU@Ag!#4Vb-V(?R@qUa&eZI zL+YL6VbHEj&Jut2f{r&@t|@MSEetEu(xBa;XNnvXPi%3qMPSG*5c2np(Qyl_VarNG zXu0Ws&Km_1seIh96>gC3U)!sj!XY#F`m}i7vvr!t>);oTjjP2wFVhjYIy((YuhC3j zWbCCGET+qU%WSWWk2Kj&njt|1y|;cK<9gIeCPE>xlr?YR$F)D zLw^%QE-^r7uE5{WOUe!W?r9*;1^^~YL#E=%-Pfi}s_*`nn0*@MXTQ{HEBla(`aACcJ2P&zVDya`ES2!xm)@O`O1|k#eLypW%s3 zOvGblRZ+%Z!#{_+_5eu2q9DT$8 zf9I8Q>2ip1eij62cmg3W^M0e%TnFjo6KWu13kcmkkcC#MJ$?g4by%(nUCBLi&(N@#IdvMnm#o_}6?+Qet9IBrfqwA&`X|JT>UtL1DL4{?GsHzu&X-xcPv$ z+T&Z}z1`l8sAoIGO^k8%eey(-|8AprTTqC%;lUSI)NC^DBvtcDWn~TKde{l~FAPl$ z-yH}8o%aiY0*!uv^bw%|aQGluo(h4ID*R`uZ`#Bl@12m<~v@Ci3F;RDY&EZuzCoe||-y87xJ@>sWmZ4^gw0XOUCn$@d~Cch`gYe-~7^5^Q_c31=!H*+FEKu_zq54N#OGMrMX|QIeF$bfavv?{LlrtsrWLuPc^Y6@{>JuDzIQo&H|+JMY4|Xdz`!6L za2lS^?l*V?G{I3%Eo1&n^S;bS3rVZ`b(vFVQ7mFGA@B<=^dUkSd_%($I zKo^mtp4K{94jfy-{%*3Z|HvoS-q3entf857TEMnyyrlvNYCGm8vd6pAtFm;a!_|Ty zl5dj;O$R~K+1XOUzLDLX2pL$YNNN_J`@eB~8^->Qdb*7i9yM^85s2SYb^?#vx!r#8 z&yMe2g)pd<HXfLQ*oP>(*O^elkjY853KN+bAyWlGlxm2#v^-86 z>$xOmGPkIBDVI|@k-~=lb(Lh;rys0Ft5bb9HTNHr4HKMhI@;xo4`vfnh|k-x_v*69 zQ>ldQYs(Cit!p9%7vA@4{csWzbfQWw9-Ofw4(QIQzdmGN!ue^XHnwN2$iyDoGr6^D z*gOD@f0WV?j|d%|o(>AwuMh4sGTyG#+FKPC_C)%VwLWHCp#kK-AEBYyEQ*lr*PlP3 ztB5D02{zowkbM3bp~<_Ssfd4rQ)RTfZ$4M*4d@_jXWbJ2b_Eg{FD(BfTs|D~K(4&X z<$AeAnmAn>FI?1VRQ8)2kAZ;ZED^)D6#8kcR%)G_NSpb%SN36JBPzyXl;pE_B?9o) zqO3F)6ck&QK53W~?{#SM3e1cEHRY?V`Flr9PJiMAMtl@}$CyA|!Zd3We6tTeN&@v3 z0sL51UME0ORlh$uDBZM;*Cm?6R6gO>KUCj|JGR354H9OZ_sEHKvfELr$oOogA@oYM zXkMx(^Asdhb)b3Kflo>kDs=c71)Z~qI_=3sGIXWJFU>&%!M`;|18*D-h&GAU#kMT8 zRI?lz#W5(`^Lfx`d*V4Qk(vp0Wc5#$vC52O_AnYMEi`^QzU`G3_9SX(n5@~J(rs>? zD0ktjJKtH3cutt}nQK_Uemq;Z0n!_Fnp_>!s=LE78x5{z^-PaNMs5obfROWKM2(Cv z1C>x{L26BJfD@NUZ%I>w+EaV3cLrCic2cAQ8+VcuO}v4mE=?@!n0nNldRZC|Yi1hX zyNcp-EwRiS4jxr>UhjbX9pzwDd?SvN?ZX3^ic3|H@JYkq^`PS&;84W0FlNcZkA|m}kW6M?{FHTC)Bc37_jD!0Sb`we zydoEWbF4;yQaWz6QPuRKnIabXHV7QSerLwhXIhE;4ygEabgB#k2}MoK5-G3_;7WZL zPuE@WZm2#_t^+U?PN*QE%wd|T(sEj?EVHJ~Ydj$}OHpU~*wy2PNZW1M-Kh7fr6FJJ zxHH(~S{L%3;$zRiTqTaB%;!1je(Qo=rUWftNm=m#`uiZ14ugpdN^Px%p^KUo>ymtHb3 z{0c-R6|cZdT6%qKz^=;}pZax0Z^i~MD~Mz?Z)n@|(AVsXY4`DtMEPDK$JONh<;Jtm zMyN9Gr;@`zaRW6E|2r%B^FO5BCacM|QWa8DL@CvC75e86)Y0V7UEd$Bl-xk`{QQ3W*HX276ZS1w)-a)%qa!Bp%9V4~ zD7;fm%3c=HG}%RQDUcE}Q>^vIshJbUsg;%TP*Tb?@Hz}`dAr!|9Jgm>C}f$5F~n^? zx^j+;jSy2b!X#m~dLJ^HD3(>L;<7VGKt!)h4e{}yr+2rfDLvuWY7%UE-LHRKGw<^4 z1odU^tP6ti&S6)>53}wrzx(EqpAXB~Y|%_u0Rj5FOkARa(Ku?;r=UO=ms;$l=uKyd zPXHY}dAUAsK3Nimt@J`ph_kp|BuE5RRTqFgNdEew#>nR#5n_i!%!S!X`{;V?u1W%F z(1vItmm;g@YGH`2E(bTMJ5JDOXlGB*@9$s#Ui-b&~Y={MLKRsV>) zhQU%O4_%#f-&+xvV1Lf$m}AdH#0vPULcjU!LVMrjsl~^)EUq}ajurY&>A>SoFl=`? zHR%X3>u{6O)=wh@DQ$lbjkJ1i?B$sIz2dcx%MY{kwJe`Ib4r5{+0X8n&0 z3}CLKsbsBck-O}M^s_5mhDRrbeA0ihYe3c@Ev|Rlz-=%RVbS+nGdn^Sa-dH)$VfX= zO-F1FBrFsz%}Qv`oc(cK53j?-iO?k)!CG zl6o9+em}L=n%qkXLce-i<4{vLbw;VO+SD6$Upd}YRO%H-AU}S3W|Mw9U+nH{vfQ_m z&J9-{Ia|He)rQI-rk?%t7fti{(B0v!5SMDs`-0k|x*S#SDop$M8OY3q?`^w-3(T4a zzpGMMT=u#4%v0L++Lq7Nj+B=wD)MZW6OFBv_q+~TR+L;*P-=2hLVh~;F8#?slnB3n z;Y|~B?*L2Fy!ZB9p{8+Df8IDxi&@i=d(;FuDmpMAi~$iQI7OJv;u~L)#jlyn|mTZ=<^-BDx?4XNDh9)Vf$2v z(i+K=RJA{XP%gtr3A)c@CD$aVyU`6?`f}H!p;5ly897j|IVDr`M)Q62No_kMAD4`o z@@Bjc@9(^SsA8G;qq#ZljM-nTZ8@|IS2ie!rc0uPK3Nb{=|Z|x8MFB~F%b_vj`Rud zSqvND4t22{PAqc#w`tdh^j7r)znHV;?HeFUUa6**u)~$IH;6oC+ z76{)&vH=&g!}HYiU>J=5-xPl`>4zm4FC}HBVal}|ZCztK@DTk_N72Ylvuc`h zxue=Se~i8il9rW7dGq@9Mdo&aN*=&nS<0oL)y~>$A|!f4Rl@f(&8ArxnU-uBk-P!8hHXN8z}V7 zQ?BDK&U*5-E+2wQca{r6d}iL52&6FH?i$U>8>tdJ^b>4p_D`m@-IwpT3%HMGCDp9b z%Pmq;u&h%zN|C+{l|2{uIG!x(ygeHhRK7bt-BYt>5zptyUghov(OOXaQL_+TqH;8A;I__^-(Yx=r*@ zI|hQijfo(Yrn~6*Vd|Jlevu*G5HfMsuMCPo6zKaj4k{o8F{_ce9K%G=1F@tx4vZe4d*?|n4N zB*?+2)dzQ{c*yil+P#^+Kqlk2_u13pI~>_~F73LG?=Ou;B6geNiNB*j>)c-KtMvExlKFY;>x$Xzxu-it7Z1SW1xiIri{* zXJ?bK=G+*e0lTD>;$rM*rsPEr*wTn8ELfaQg#qhd#_xpuB%2R|p#L`BNQMM?u+qV9 ztU$9FG0+6eO=EABlF%Q0e@8LisBq18^AGZn8lkc>W}*QU$F%()1<|ool0PkkNAVuF~>(fS)dQsOHC3* zx4Vpc{jc|E&MvJ8@L*P_J2{uFf3XFp)pQ4!4y-wUU+5K+U}`f}cdM(@@Or)$bPspv zVK-Gy5p1X}vA-m7+@16f3yYA#|GWO>?54vRR`_(-(L&>3I=YGr{;6Dk>%wl{5=e+^a58H z#8 zb(A_DX!m{RcC*Zuje_DZSa71C9p^kRm=IuJS9iIn-`QTgpK~_k=PQi&jY&#sLku)@ zzG_1o+T1%U|Az45o31iiOZ0Woe!skglPxcpKWL#-rHlJ~G*`2XAFf9QrY^Xbfwinx znuyEKp^0Io?HtkuIk`-!2TD2a!Qx~0jlMoUUNm}tGBfo#jg|I>eQPzeEdBZ4Uj8lK zT-{w>DmvK#Do~de%LF*Mk&~tFTp$brFZDtj+|XBuX~0PbbY7Ey*IUbUITK^p*VZ+- zb%DMbAgxLv=z9MQ^$hwhCkTtway!#v>lQB>KZM4S}V#~8S9!na@C0_JMjEL*Vdo^d?%@=$cn_a#_*v)0hk?dYq`{_v+najxXYkOJ4_V_85y_I8 zFp&uVCk+C|vVqud(t1%p+qi0a`-dzVj1Y5LT@VZD=umiU2va~?5SgHBtJYdeqkuJc z(jH-y5T}(>(R8s5I%y$^I2r$ME~*x4ik)fi8le?(3K+ES{T2ye$B1t?-mNjJwXQ2= zJs8Y475(e)Tk5*IkMxgVIu*fj)Z6~>>5gX(bAy`I{3Q+6*=~ff*1e!W^>!#HjLSXw z8s)e|!cVcu@-^sF2vA8YUyOIVNTglQ@u{IBjvx;Wg$28dMYp2oIG{iwYK`>_h%BId zI^y?-{u!?-#2Tx`m=|n&qSS)$OXY4FSft1UDTW3HYiIVXWe4XyZZ_7Jwz?}TE6o{C zh|ei>%X5zB=W^t7qq1{P|of`Dsq(c;Fm#+)RZ4F#UHhuq;YEMTu zb?a7X+JosNQ1R*;IPJRSE-}(WDNeDY=vBI$?oo!;?_UuvRjL?y=W*B9Hyp4MfpFCS z$6jL|d0kch(ttY}@YP$}=#}!sEv=S@o{IwY81fL(QBmKgA>tvRbz9HZW)tY76Ay1A z+5TYezM*|X!rx}+;%#Rr1bjaFqpmh@Py#sFbD*?4%=1iH|SZ z7_>`&&I!~h7Fil3%e$OH1B1oFv#>DH48@@gJ2Y)~I~-$Bi9b)WV2ML6ncU&Vr;!Lt zdVMy7(indvn8Y`yzOkMKSrzS_Y`IW^h4zwz1CV$8&Q^tZ%)1R+-tut$`w01aGTFi?siv#}$UpOOB>^~v)o%d0F?uY-GcPff! z;W!$s`7T9vv`9NADG!F^f!f z=U$~^9R-!=q{tYw?I#5Al8cVgMQx0v-ZtG05fKDM@d({~*iY61k;CJ-IQ1E5Uf|+N zo6n{V5$lDl&VT;}h@<@ACHGEA`G*y?*Lh|5ZbQAoo{7|BK6uG?2*|{Mg$Y1zj`X{e zFtaEO+`xP4CxzRI&zy4J53~WXHNoa`}L}RjM8mOEJyOoa%@=zXKAo5MyVB@2? z#1Y0M|bLa}u|Aa3)oj04a(U{%$Dl|lX)c-ZNHXV6$AE((-vwTyK z`!R!V?hxO&F3ntNLX=**hIIGbbsIgmX%PNX4#kDwR{wVNw6>`!w|CWWuPA1#y1uv1 zVKijq>DAqEm8-=bW5P)8j3gn%8zOB(nD!3bTqXRv2*}=b`LE9($O7&w^naSe`5$?j z|6Arq(Fjnde>(09d=QV0>nGQ!i|J_BHrOt_%~qk?GeP{Ki~5USeR~T1i7j&Td3H>oa0iqCvKS54yzujx$aa7(z|VS+fwls@P{G9e%i^!BY-KKPN9RDLA*OZcDfpr`3v$i> zS%-f!a0L1h7Y#lILRe>gXAJh>cI)lQrMFevuPP8ZF>NFU-$Heqm6e|e;8&fJ<@X0$#UdBzW53Y)^>@8Cx@l0l%ejy z3*tv<&R}Fn9JwmGH@KoXT5LCdhWdKU@)?Re5Dtz~T!Zx+`fa2iY$ao`R$=m( z5H~=8a$u$-&jgW1B@vclblaI!f7vwjD4}q+3gDj-K4*G=QqasUx_Uf8?uMDBke37D z61VVCy2~N_DqPH+b!3wQ3^#K_#vgt503=njig>c1(FO(@c%ZD?u98i9sfLB6|7i#z zMcerJ51^#pht;SHPkwl^;W{ou*#w^OEow5gRmoT{uI?g+zXw3q{sI8V#YPX0{q{_9 zDwboGqVKysa|F9w^Xx|x>lf=xPjoX*Dp@>`<-bu?o@ze#(N`q{U1RVeS$y@x`R>4%`3 zXB%8rsmSpZ2SyFJ(wYU*Sojot#4<6V7PDcDs`Ld3T)&Mz;N$#Md_bsC5PhWE!v0P3 zyw*W$_SN?Pqe@eW{GuJN>(f9egR(khI#-y`Ow6WTOo_p&6>XphoKIu;2Gs(z>{ft5 zAY1YBn=(*UbAa)Edvdxx_JWbo+kw=H)lAKbWIT*PQL7-Hql=9VEEbltAL4(Vo}czhC2#Z>R%D$a*x^m7y$~wl`vih#rie7%e@tSk55$T_G{!(d0sHd5dWI|f z!*z)`|3~Bzo8mt`!+j+Fzq7ZjRaJmUL>dMg z5k^)1-WLK*l~-oAyb$N!fB%kNq`e(I>fYnkGw?;u#AKr&7xa|*KpY(&>)f*yZTF9O z|9_lS|6f|<|79*7`d8I>9A?`iIQA#Ml#h&?OcpOD4-npcE(lFV%B>a2gbN~I*B_`wp`;GZvjD6Zuu8lp9?PT zq^FqvxLIkx$4!Se%P*YW7Qdae_WWkvU7HObHKIWzLf5=T{Ur;vborqFDvxTy^+o+N zS9@MY55c*ME9dk^8J!Kwx&l0!#1FfBYWTGBO>7+}Ox!njhYAvzNolM$5j zd@@LuW|BvhwU0;hA_h&^L0vUlQ*cFS)PX=m zGbN%cmFs_i38XSwe~;@9ZXX;UX2MLc2@;a>^UeFUrQ0_QUodcEduxBr-Ie|*`-*?f!bGHr!CWOV{}I6Qm6&kG;1!{HPvz^pPkFTs`#Zh2q9_Bo1EJ*_#~#V> zum(1}{=_JX{krvDo_&S4689_x%Cy*4Bj;#zRpV$`(?Lvm4^6wDyxXc+o`8-5aF0EE zHqX-1r%{o*KFWwB3KQ;9KNr#SQ7!P|?DqNN!)-sEnElOCqFy0vFSi+!W~-A4HVnwQCbY3lUWdsWxrSg%C`JVb%jZgKPOAr;4@j}NzKd4lNU z00oAgmmJ+bua(Gn868JB<0GKRIAm{2Jy+U33#~!Z(O8x@PMTZe*(zNdh$s2N*Yd9U*G+HG*@M?q26}Jt7+4i? zBe1RBr`O;TzYSQvf_=n(G{RXy#nH`9HIRzI%ZM?l!5+uAc#IbDlSpU}Iwzy|GqkB) z`g*^O4Hqs_4Ky11@i0a_HJ9J@pjGrMjrzh8%7c&s^4sMhAMBT01>zxTi5TpajxXAe zKL&IC^}rIwwyvxsRytz+ttzu)S25G8Y;Qk3Xkqt~hssi9UjQfC(B`O1aEPTroa*X< zOkp?}cSiK_xuVvMAr-m_ID{il8_4C*PuQo}7j)vPdfS z6mNk-4fI+ZQ!~;8uMnY!*2DTS-e4a4F%=h+s`RG=KPyF^t zTOkpRPxv98)kxc(eH*lW{OND$^QVW!6N$8Mdnsbh#OUU-Mcrba#hFSfSfDXKrcKnI zy60_2vDxe0Z1x@hfgFQ?qY!A;h-8ex4nOgf>Tmn7JJJe5NP-Zyx@qJ#=~Jqe9vZO7 z#xT(XZP_|CE7Pa_$_)_J<)1L09E#hk_dR~ZldUrJWr_ZPp8#U4YrL-*Ul#8eTHZr1 ziaXIFvdcork&HZ#k$HT1G-x&={}#WPXC}S+3f=PsTG&9Ck4>y9bJhu-5=5P5@+2jG zs4l|aq_X2rf8yfVMf0(jxoKi3g+OSG_S6qVl<_;OIkJ3B7sf)J3Sj^S%W=T^!%oHUQK3+CC!>)J5{+W znqPP5Sbsftot>N80@^%U?>AsAIW=8-Go0dzG?LkCa5TR=xO|viUF$!(_e-F~LQ6}4 z)7%-uqp7~^!6+SmB2!qtL#U*hgviFGZGcgT^p=CBY}IEddMi$OX;wyS!;M0SdW2hxZDT=i`8k=?Uu%3V0ZOP4zI(^aB4Q@!FJJ~;bF&$L2&>Lr0 zI!0PU>9lAh>BQ+mG^FCFTu-7$>C9rBffg{)h%D@-LmU|=>xzK*83DH6Dr<2cN5h*re zo0nmTU9o!Mc z^=GoDL=oZz_DZvjKwT~teEIYh)M z->}67i@Jr=OBQ#t2aT@FPYsMSyB+0{#Ge%jedk^sYpO!?L%y~RN@dJ0 ze735{6D*DCdj?Sj4^GSLzYerrJwI<7r84x|@#M+iVH2+sf`2_l;by|isKX+tj@6|x z#@MhCqqp`Ip`z8_`SO&iqksD91rC10LJB++zrYA{~c7u0)1wp>uRxrE|HKHhIES1kPQB0{jMlL_ZQ>~ z$c%QpS@En(jdbDC&-jVLr5Hxfe#BP1SYA=F%s20Xgt^|lvrA5%g!KKo@p|z0zQxvv z-py^t`kMl!5Th`9ST?p7(qn86>Koj6tdvxo0`hQ|n9Qe#KvqfF5glz4-7;P%>5i1$%2u&{yk&UDcPDifQu2rM(-`FJZRg z``6gFN9{ri4^j`fNDJotMOt3AA3uLH#+bxLIxTqdn4i*X$mCz=S?iuYuBE^9F~2J- zDVXaI^adO<$__U4o8VxxWmkzYnK7<8j&M{ifkBo~6ybN=y~eT?YurC=k>d)8I2m8sy%tCbTg{V`~ ztZKHzrSRtA#n%d+4{+p`7YwTK@83RaHawn;GrdS@Y79tn!_*%=dXruYH}Sa`{1M5d z=I6=f&>Ta1di557EJmuiH6t(Jd$M}@rPtmN~o;7B0d zC#~jE7qQd)M8tU^u>T^TOlwpOof!oQbW)}~9D#&Tk*bdit@N&fKUt5C=2@@x^1x2V z60H9?k&olYF#k+l^^w+wS;eeJaaAob7nyfvo(qD1Vd{c@4HDwvNFTnp8bJQPO1lcL zsGjJ*z!H+Hba%J(3JWYHsUlqx0t(V4u=40Gkx=OtX{19yVrc{=zI21qT?_o4zu%wm z+w;zzcXrR4H*;s^&i#Du%)JVC9_%N02`uQ&1^=>HYb7|K(JpzNlo4&G_bEP6ZXvJdv{OTqW(EKa(@tG@&rGRwYVNSIR zfI=?CLfyQU2A|_``n&F-BsMVH2ex8-SFiSL;;U#SwKU2iq6Y&G5)K7L96y#BWMy`D zXrEX8X-hcl1CuwZyCJ}xfA^VPLRHK0SUNVzI<`+&-*}k=uGd{ecY&juYKj(;q>Psg zkb{d~!mNme$Tem1hrgcRUz7eg3xDRe0uUQmu)lC2YHNFt=?yLe13WtJkx*(v6{md7 zFeF2&pG^`^rT)cJR&K4-j>4ybt89QPrZ4=(N_W(Ux4U&xRrcq_ji;qj%ksB(qgIj) z%OPY4FeKEv2p!4Wy{6)v?3d{+_a7$ZbB`>!&@c9Q4N|S9)(yI?cv9YCjvg6(2RvCp z%}SU7e;%@V_x;{rMI(jJTHBq z4!H_Hz2btN+}x4e!J0(^Wl?wYubj5K7jV=>3q|mI!kQjy!R~;@b9$-OD@S4ULI_&K z|B6COa3IW}R8iZB9CZsRqS#Q#H^~2s!a0Ep9(jnVtULbwY+3i{eTwLb&<1DE<;4xV zJkrsWTfhJx6(AqFFc(Y*#L@Y+QI+&Z-OvjEr8ljv#7GNeN|EC>efsGjVdOjfU`Ot0 zQ0$4`s|h}y6haPeP8MPA=O;sZ^bM7rzw=~y<&OeD({tv2)*uKyjKUQYS95fA{tink zw+6I-nL@muK43EBfhy4Wv8#&^gdPLgeLO!Ss^9t@~ zbBOr&QjBeb6F6^5sej;cPi8|I-Pz}iGEda*%(W(`U${JI{g3Im`ZEyfg$(V+ zfKY>!!!=7d8Rc0whxb-4QW1t({`Dwj^`eV5UZW5?C<4N{8tuW~4s|@4a^w(^@|S$L zg6_`<$TZm7vIv+e$(|st9e_K>6x}G7cQ^btU-Q40Q0hyNRLw9LHCmoY*XqKjXuK;T z#kPLhdi60irV6$^IG?}P*2+eRd{O(cNe0?k%1-X#x}3MI`{1z=W!gBEpct%GqJ1~s ziLqHNfsve$!QB)uxuE9rn{Jam5u|n0SPq)(yFWGJkwsK;0aT#5_CwpqeIPQlYgfhU z?4S*ez{{l4-Viznh8Xl}DdXZ^PFF3b)l5vORqPfN=$1(2O_`0>Vsde)A;Rb=oHPx} zwhr59v7DxIqW-8OIe?Fsw|AcjfbtuXW@(4O*b=~QxKWDG)y}3fzB~jCu3Wt;o6oI@ zuO5Q4g>6Cl@&oNPwjxl#sb>EX76Pqcp$>&ade;;0d%tb0Qn3fSnIp~w7rd@v&tDZ< z8dEJ^^qN0@k|wMv4g!??w!!e%Iu|nxxB)Egf{3NSn%@s*$zTplg z>MjKesB(}dWUe#tEmpR!b%Ns;aSof5tc<{T=WCt{j?hHlaQ)~c)`<4hX3+nO9*-s1 zpjkTy_nDblXE*Z~CCX4FjNxI(J1xy~GE*OI#NUiiC!JDv(U zFtS4Ev&t~rq`M#YSgG6Vb@(6Z7Vhe%q`pC_HE5qn_7~1>gz}EC%pL>n-84C4Q8qdq z`}pi4c@O}Wb=1!kAePxlz*`{cCsNYSZ|N(dvPG(lNO5mmmdopbgDM2nNcT(gPk^oLj|*aL3Km*7H{4nL3-)&uA79U zB%r}3m2t8L1(kz%14)+EXRxAcWYDqcnV_PPQ(t1 z-!xzOsjr`?x-A{Om0eOQ+fsT#(Krp8rDST1<$67j7PB7(i%r@&p*Uy_yxQ=lljI1E zrB6f0fcFL5-0_3Kb1N7Dkk#ni1y18u94_nXeUvIESa=l|Vwv9Y@$+-0#Aw3E(0*n@ zp}%1yby3*V=p(x))36t2$nk?m10>7chpRS1Vsrw7EW-Sh@JzfqZM)A^iUjY?(5=d>G6L*#up%@haIOBqjGu87zn(wH{pIlU=QtLK{FmvkR0sZ?t$;(yxsojG z-!jlE<=c#2rR~wj`IOXC-TS8s2iu{ml3rRRT(PbT;IiOIOHP$psu}xIQu1EUS>QJx z=h4IGV74ysEFn&vwo{eN{0Sxo_K@ubOQcQ=;{-`L3_`JK&!*Bl_r>PE{qJ09c_NcK zI`H?cdic_z#@!J!$cD(6y^{3l+;C;(X2%5upqqt>HD3QDmNXECrfZoXR3KQS_EbnR z4+PXwhR5F-`)yEP&lT8e&bAcoe0U<_I4PiRiyrtgl_xDsZqP#H9YJ5dJOA^w1gMZf zDi*|5`Sp|%tQ=QRMFo~VR@mCo*~OBpKMMhNtREv`&9A(AH|s{_5BH1TbXvjvk`m$Qu;ndN(H%^N zu>3#a>DuIFTbC3w$a|KzQ%}$6jJ) zpjf?CH!)7qzBr|C_`O92GlON-T%T7ax^(Pg($e!EZ?q=$V+UYpKMSR+D+785syE*+ z-WupO<HRbSgYA{~* zmNEBQ*L*_aeUlSZ>b5A!58aVA<;@xr-LB#1l=xa-L8_L(_(3lfhU{BwaGVnI^irQ~ zvN_8u%$qvhEX7(Px9rOK#1WpQ)Gy+qmn|a**8`;6C`{UFF$U-I2Z06dV8ghi6k!KB z-4ZR~(&U61b}{k#nKHQH_a#a6?fNUD zjpYu7J&yNyrohE0RKl6dxYe)auj$b?&mVJZSOd51}MvslYTZgS3l_7&td{CyIW#8IJNa`fa6(>)N z$9{``ZN11mJq-%oVJjcqHaC!UQoVCiLSdVE^AE+1hu@f(n08hPR5W7T)z`s25L#vU z%zgydXZvYp0sRA&mK)fI_O}%Y4V`w?7`4@0xe%@i60xg!baE{4H$mTC$IHh%QtFdg z!0~+2x7Uyk5c8-%Ujz4a;K?5Ee7jiGR^kGWk!JAT)0~>)g4;R2Mw)Bum*x;5n>SMnH3`b-Rq_vRH<{=0b@2N!J;5ulfBl@9p?f9=4qP@v z3yXM7Y7NappWO8Jn|v$})`9vP@=nWxi7O@B7PQIYN6>CpfbGfoUwQaH2a}o}Wb_!? z^acZ*Nncx^{%Q49<7?VyXoa;!|Ajr|iKz9_tzG%N=b zlnm#@t!O^V+=Yc^@66pIumjq+=4M*<)lk;a$qp(NFTUYbwjZkgZ(+1@pfcIANm$Nh zz7<(%*8O%=_4llb6*5_n>QkF-u9C}e%^7!p6%Ajl z1f}a1B0FpUyTJT(K0rNoIE4i6G6zHs3}}>@wovVC+3%5q6$UvA>z=Rr7n_si_ooUc z=nsao5rlC%i$LtAZ)?LJX4jcrphS4_vbOsxdkh}@-IgPX*Cu^DqYMW;3&=7JG~K&) zVawuH{w`M&;_jK<@q>CNCVqd>JUm|V zxL(3ah!W4l_-MjX)Gw1@$J|+ zmN-7?6D+Hce{nPMT5MCH+~7QWP%sM%L4mXx{`A-d2QvN5NBH)-q}cVp!n8av9>tN) zP$=xk7JV!WPIAFAqdG$FCt1nm3w7tRflZnf_Zh!=`dDwzx&YzQh}xptz7g{K3&C;H zu2_NPO?#eZCh-+bCAS0r9aBY)P-+RQbnGj6?8?YE<3iqEXZjp;Mli38;}RuirE;0J zg~Hsc$)Q;OXL~)Tj+2(hse(0=ZC4f7uKnZN%IH=LvijCTIuv3*;qRc&Z6$Go)%s42 zh)PVwtie-RFW_{>bdSch=FPFAbS?W4e!#LukxtL?s9eP5@y0WJ*FxcVsXkVsssMExLcSp4Y{IUY?hFp=9cK9OD(?v%vjpKDp+k@oMX#UE6kT-3!NW zM(#pGY-A7>u}vflDsEsn;H&9rDlmPK04!w=r$3Xm1qhFhj$Yxhv4)<2SYjHp*J4zU zl96=zkL?Z-NgR^?{S;@&xK+zjnu5@3d$uyayzsKE8B^f@)R=dQ$)M(}5dslQ6BP4n z8@MSvrXDi(o+rT>VVQ`yHf8C!G#l5hIq53;&n6|#%IML#>pXy2B6L>7H7qp?jSB#D1jh<;Ib| zBVI(i2*t*_z`<(F&=HrEST@tA)X9SQpN^zZUCy*6Z*>W29DU7w{gG*eo5{prA}s$R9h)HY}0gF-J*UJSEWHe9f*7 zuIptK8kEi#Gv}_uhI@1(SQYuhvBNH{gvDLon<`r0Wd8SN16|E~RJKYNUs%|iZEI3B zHf&m)RVpj-h`SPkXJdBf8*cR!w6dPt4XbIIQ_AY7%TR+$WbB6@e+nBtfE(dw6shZs zZM32bi%0DQ(02(FDf^gPsJPm#aab3xk>@O%D~Fb~2Har&(1{{Vh{iR3)0Y9`NgbccOrT)7SMjKIb@!gbyE=#Fq{iyRm|d*XRaz`CZHU`uI)nunXU?UC{%f5qC&Bz;tW zcg$E@SD$5{(^$86p!UAVjV>mN%nXv)ZmG{zO6(LJBW2!%xvJ~q=b<}k{`_36`X;Wu z)A>)vfh1_qr9CrH6rG&Ac~`JWLF{+?J1T#=y_7h}a!DU}dad9H^jv4%bGG)xHq6co z;|~xJdFwe-raM3GXn-u9B5PD#^3Aw?BTtGtVS<~`<&Eng37V!UhcjXZ4d+8a6FVfU z!MOQZ{X704!QtK3j=4qGx9Aq~g+8V+60m~)JzmCyI&Te1#};bVzB-1Z&cYU$rgIrh zp8-NgH`btC00BIxUc~iG%}3VmU=&9^7$S~t{9S7?3Xwqv83xo>UZbf7&&Y2&Cb)sa zqlvPP?}?wYJ^{l6^od!YB-ZM7hfk#s#{8w$0d7XrBAX!M3891%E{2O&TIhLA#9&K@=LH4#k-1kpHUC;iP%oc4z*$El82gz%dEF1o;qz%F-(6W7mOou zf*tI8MGW>zb?!`SRdh@gzv_&ZwTN2eF*=(Svm5QPO%qlzYkfWa5RpJ%mx6Y?J#ovZ zlqF4@hXYo-oS}*RJR`}WdBz^1wi~h(!x{J>O4&L6SNuW)KDbt9LXK;(2kt6(7ZLwa zP3esM6UXuZGJF{rhMa4q8-EqZ1b82Q^H9~FoSX)}$0^TReHph9Ff?_IJ&CV?>85>b}8-5;fYXqPg zhSI(J?cDJz5KV?=X@zT{*I09D8J|-v;QP8-nFw-|Oy?mlUo#zPflSvH272+3ryVgRK)gg zq*Bz_)9Om%iQ;$?X@m!GYdvIKE6(S{7K-wfVf6lOkgcS@&RhG*bPgg(L~KzZuUG$Q z#)&>;n#k;3G=Yj z6-$v`MG*G5fce{Orxmv+U)BBmL-O;_>A&mm$xjEb+GQ|fbB(14LG~0*_EbymY-^T2;yXAB7O@ zegH(k!Mi>VkiCZ?A8Y;VLROBVr%P-glzz_R`j0u_rDy~-RW}8p*}rE9afSY&#V~AY l*3iU{$p7zSM*siU-ID3yMZA!Fl?(azQCHDXu0UD_{||`TdT#&# delta 42912 zcmc$`bx>8|_b*JhfHYDfQqmzEf+8X%-G>h8jzesv8j0(%s$N&7tFNzIX1t z^UnO{&YgSTnDGxhXYYO1v!3;QR(;mq7)HJvKrZ?64iE~}$Xnh*KzNBD^Fcy&_h{|P zvx>fcC&2%w|CgLkM^qnBQ94dFOJ80*5Y}s!W@|pD7)6!Hy<~XVNS8JKMG|SpKX$=7 z&HDj^^}{E>cidOrX>GK^PFsTuJ!aybNApRGMNc< zB{67urF;Qd3|jx+pX@Pd{fCJ#*=haplV7#cgV+C0@A`l4Ccqy*>$6Izm@55$gzQ0j zZ(98h6p1N-RB8wFM@G_h-jm$HZ#X>q%HkLS-tI4%|HU%?w*>e~NJ)Bm-I!2f5O{;&5G z_`giyzZUTSW%+>rKaB246*zGV2(;`B0BkC3N@u31rh*8SNb2vt8HU5iC;O1T(0r(a zr>ZK9^ax-peUMTjat`&CfW6O)c}bXnhso}sbqsCYxL8)2=(YVEw*rTrxHr115;rOY zjr@`pGFo+fxmDx8>Cp(GWUuyD#}vsAZQFPlx|HnLknokYNS0PB72bGO%h~_|I9&5k z8ivI%*)z2uFw%rMm6?HI%7i&O2@YO)@Y49PgX^IIvO)}q-AXB;WC3`V8UE&zs>O{9 z={w%}$IIAb$~$_liwp$(G-j&!{JRZX{!Jf>AK-dmczrryVrJ&B5%=u6S;w};g7;>U zk%6JqdFHe7*yzq=CEY^33p?Prau`ZnFjMoDB0qohudxpFV&8RAERsgNwQ%MPv8G9% zBP%<5@K(^&j9NNx>^U_xbkT)q`k+6#@|&+O61CTIIzeB4KGyb-r@o{r3AhYFOL7Hk zo0%I%J3Ok7U%ucgO}t9H8so5@ZAcpmY{q`~`SXh*k=r*2hK96-`prNRophw*QllFJ zr|sR4T#8tbcBSRAy?|!DE#2R*J2*9aldo>C_rvV2&W6$uDr_h2e0}#i5|;j%aC7h8 zatvDCih5pfoiD7cZ)_kQxBRM?ZSV`cTrVB(>ClrjHu>|#LP5){eITtKBc`Xjrc|G2 zwZO2#ZYmkPD>_Bz>Ng;EIyd4jLfv$4CP3KfE!!3dPrB*DiKH1qGZ>r?;I$n8rnCgK zPLJpl;u{!_tS*J^8!yz!-(7Dh2)S5l)GQ+*FJHGR9`Ex+rCnaoc;C^3>;0pW=bBU< zJrf`q2JY8p>_+3o^;Wvc-LxI&?Je?;lmxtQk3C(tmozWM0I|qK?YE$w?Klu{DFtv^ z5^1E57lq#=*w^XS=(79z`g*}hrw_aYS3R|>EPB;M>*8nA!~0nu9z5MbB%TwhgcZ#_ zoQqz#i|o(W_L2TZU{44m=h=#mkN26ph!Wxb0c*Mowv2wBTeU^h!khOnvY*pXfYb&kSC&lP>^A1qLNzN<GH)i~OtkbdSynjo^br_W*zq@rixFX z-75+%rfv=Dwfl#t?2MOE`5n?Ad>gU&0Gl!{C%)=UyAc#vcZT)u!A~E8GETN4n?3GI z(Jf}m$PuKYesj7VzB;Tsi|2;hevG;f`F^?3;WDMyHfqYk%)~UW;nNh?PAAjkD4)XD zX##NnjE?RIjLPrzSEJwlv!r~E!OM&+~uU`Gz znY+~P3{PwCw);4iC8hFPKI46*Wpq=>vkV`;pOt%jSyOvlWas_*B`Du~ygf(i)SSYj za8D1crVbkmwHwp-it7V^%fHB&h%fMTHSeF6Y3fn|l2&fDU{gFcvy@9~S62d-6NTRa zQlK+DrGHD`Yfp#YNqwclGY07SG{sIec($GPdyM(CQBN}F3E{|{g;Fg~s@ZPtFV&hd znrYrHUOK_IEkH@1pv(aHClSx8*ZMP;B{&>stI;jcfRhL^RRJA96A+YGRYgG3o!WY_ zy0#V^6?MjjjfHD8u?u(Jn+-`!Og69F0F|Ao-wX+-dE}X^0vnk?a zofK-82EMi8w?C-V7%6?PLnKAZ&7G?MJ8~sTeDW0DO@oPtM=vClYy~@1=u$Yq5cPOC zl#I&6*M8kf&np9)%5)z$GT(W2yIrKb=f08qc+zZ6P0zuf@#jzXtG&(sWZlgw-HB{$ z4fwX>4?bSKKBFXbXz6f5n(!{&-2&=m|F&TDUm^44NP2#CtvKp`p#m*?DfT*)gqkE&Amk{x-y6tVIMfU?#1R*zDeUk+j?_xnKU-Wmku0>y$ zis1lib)U&_c8nIeWSdFhJBwrqSer@g;(M*6a47jJqGU#xL8b>Z4Ocu{;;>c&DJ^T+ zocC7(CiyD&%l84RWxvLluaa;;&s!}Wca$t7lc&PD?LwfrS_THO>?}~dm6VDp9rvv> zm2%ui7XBDf7rn{9Rtq_JZ`h>?bXUuAn1EjzM70zd_zAS+;$Up|zYq=;ZTR#c_t=zW~hAf<$4Zql!UDSA+Rs*n zpy|#spdlighM@rs(wsuM*cZzlC)aSU{BZTQBcP|pfNL0yAQ_y4w!%P zKfBuc{N1u?-{>%NGjJ2Y#Kt^dkXF_e*y+M@i1rY9)8+KK;-LUUoHap@(+E^z5U7L0 zKB+aDY;9_|@_e8_gVGA~ABmr_p^~P6Q9EhK6iX((0t*g@l_~#P*-KDbDI+%fZboY* z|NMLb6URZ+7+{%T^_9J+>OQVHc#SwCGjkGrk5AQ==X0z%+YdZm(*OL%OMd-8fA(B@ z+4zxiX}ffqJAxoQMs-)G&uTAeEZKwQf=IJ`Jw$dr2442{^w0|nr_|JFIyLCO2 z_jb8fTLqf%u3g88Qj;F;!@9M_SA7rjO@4z^^|yz^Tuz(u7?0j+ftGX1IBB(C78(&Bzb4K5ee1hu_}b zb6}~&p!F5>a;M`Pq8mOLSvQZOxJEH8Ec_hj^z<~8wNK0esbFH$Gc`W`qlAP+?W`*; z___O4YuD9o7_6^hAcRoR3*IqxUiX{kY>VxeRG(Q#y!UO9+x1;J2V%{Aq>jh^0Bwck z#LwinR_dQ_IjYL$AHSrg;1FXeeOHAq0hhKM3#l_s*Y?w%x`4Mn0>lR{b=YL}vOuGV zR;sCpt%383|Q(p(Ms7b)O3Tbq7R3OzoXPj0X^hrZ8dEBRac8Kohr9riJ%L^#z z=%n=#BNpvov`HOBA)KyOFnN3y8$x_1$BrA+Ci86`ceeqwHl^?L>8IYI7w&+FW)Yv| zME-`(@39@ShZ)Yo4!Ps$rUS)A@5}d=T^;H>%b}5xt6R*3n3&I);UW_yQDTOJ`yMzA zj}SCb&L6?S$I5$CdvG$GS#RtZI}`zcTb1bp>ZyCLTbElSM6vo%&%?Vrh4Pbt=--!o ze1RV$DAJu$@WihY{m^k8-#-F-95s!ktJ9^%^a^`}pN0%p{?W5)H4xP=K#cVM{{4!; z`_<7jNfP^=9jC##y}iWFk|4t%7?=lRIg2sQFL_+D$@%!)EwQ$ISTMc~cY>Qsr79sFw-dpm?yp2CKAU+Y#^}SVo@1=sr{~YR_H0v4K zwz58F=d*mFgKobhig$ccqBv9TX;-@|(6I+E^I1S^qCR1Jyer>p*kwBH$js^o!Qjuk ztusWSSFcht7$P?6fTl)|>)a`UpYA!`H?>ZiV^^bf&9ZgnfK`tY;eHVA5W)FsqxBNs6Nq!!`zGW#urrLxC}UVb{?ry%eJ(cQKDs zBFQ#Ma&bdmzl>WN*?877cs_!eT!xy-=tt0PJbmG|=mH2Ee~dD2PoR^vX;y%-I7aU2 zUK}oTAzzBGdZs2N_1HBlNW-R_mRk^g(naEgk7|OtXuLx~AaHnnf>B#r+jN?rU* zq#T)>s&;w)l?Mz2^T)DzB ze}4eEeIn8?#xAv|NBZQ9MI_{CYpcsY#Q054(S7kzADsUjx#hsM99-gWx%A%s8K)#s zPj&?Uh4BoxCE&KuW^8oy^IiN>qvz$>v@zaTzKg7OrEO1aM&8flpP%8oBlf4smHmZ< zujUfv7$Bba#74%(*WmW*E;ZA@_oi4}0h*85&l@w>sT0~(n7D<@)r*n~uhyJlu2aPe za*s9)W4{Ls?r$Oxz%cx__bG_>S_N=C4onYU*az9w#~L#?Tpk8BT#cSp91X`;FL@>G zjG3M8{z&+2J=82?pGLFe0G_owdHPF)&tMSe@#vSyYd11qEvH0;gv83KTLS!P=dW#V zr+dvv)8W*){sY9Fe{F5vgmmXnWacjAuyJoNN}%K9{LyV0ZGSp&dqZ(E(kNZ+bO?h+ z?6PXt_|r-M9IS0pYD1Gt=M5Mi=QSHjm-X=xbJ?3XDN>Y`rx)DW7OZXrp<%p8BLP$s z@vRpk!~-rx?Rn>Hx4Q%kMa66lg6Sq?Uyv`XL-K=(|B=Jd;*{g1sM|GliX4NG+fMtx zfUq!Yx65z0VDPoo^xbWQ$A#+fDvkBYstaqCsBi%(7${Rh-HM}i4})l?H3!`RM> zxRlcNXeIVi_+5IX)zny-DfTNmx>C)4glTI&0s>r4t4&ITbRWQy6U>-42U56QdSMlI zOM@C3US2k!JcCYt`v1%-NB=rW@4E`46X2Ga_VIzAEA*+eT{)b)Rah-mwR4DBPZd8y zxQ8_dEP6wqvaynqFJKDcAe1Jc$Nq3*#pn$sR(SbW2gZK3#bI<^w!v#L{f$}02Xz@f zwfKsWF$l0-s59au>+b6_K1%nd6tVv?J)KApr6woGc3wBub=$vXJ}{K$5wruK%8#)ij9a!k`AnB=_e_q2@jX4 zVaGode!~OqvW{751E|*V&AI%2_^Bwyb{Ew;BQWJlLpk?(~nde5%9!MUlu%Q4y4YU zCGvPugAxZeotgdZl2FCLWCv*9Br4>kPBmiD(a~8fWl}jfluE@11qPgUB((MP3JpfL z)2(l9-4>H#<6!*yIPjvqod|+{0aP#k>nAU-x!FzUwVcN91P{rGag#Z?jjY-g z{}(}P8J&@PkK-0iCACH&iS3QYA?WU=u|k@rJ`muj-kyWSS{rwC^RKBK@VCzsJZ5RjA%ZLYbFO-DLESy`~&jFB{+qR=-~^y&p(^>#@7jCG$z(ovSNf1O@+_6QiBgPeFTkPwu)EssCYJ zs}Hcseeu@ncy0SARFCHQbI9&n1u#Ka2_Vg2acvy2$oX2%z-u#^Gk+jVnx-JFtGlmd zcx#u}Tk&-)nJuOIbnOqj*qQ|5sk5+VZ{{kI4Hg?BLw8u9h%Wx7};MjbSu zBLm{3uoI5Ajq&3CF4DppS`QaIy`q4tlR0kqV0$iID~Kv8L>Qd6hHUn#t}6LCphy1% z)fVC^<-&n3H(_m864|wU6Aq4u$dpY`FtuCCqj}mfRuXK{;$4WPow6rF3=p?Q z#U;lOLI=R~%f*tEr$S+8w$iB<=4I)wq<)md+%5VKQqeu+lDbG{03oz7 za{kU~$wn_2J1(v%(BChnWLD*i8XaFfRZ3q-GcyVxF7E4_#kDgFjAqS5B+AW-J-&HL zCXBdW1YYD&gkY7ZnkC2&y|dKqQe?FJQ38|q*LEWr4*m<(j6Xm4$Z)vU z=eVc6w>iqn`MGUx$daeNwm+K^|13AKX*w-C0jjT^K8Fbl(G0k|mlL35$J*yMg~Voz zB`G+LGAWPxNFM>d!S>i1ypO@ZeobojJ0yl9x{EBIK<)oRaNN1baNOt7-S4vz_eC1w zD&N~>dDr8LxKD8+`L43uGRK91IY!(&*q9;LE%7JGU zCN&hFrZbaZPe&&<{mrOE^+JV(=LsW|Bw$^?rjS1(^_xz=yEFfrpH?(SP0I){mQMJN zL`TSmv}{DS8XTiL*N7Up&2rt|X1X_S6H&3Np~9%s7W>YkB31(2k_qu`B?ksuBV(2{ z?*B~y3wF}x7=`(`rrB~AO?kDZf9q7U&Fy6#GdF_5mD8M_!LE4hx3`d^zrSfFj-OCsY^-=*#o z&V__vwOUtX@oSwVr)u8W{afZ*RfGS@M~4CVtML4qdFnzwifeTWTxr7}9!g(u6zZz$ z31RtdlqT&PCE1t!CATfmc=iljNM%`u<=>|#XN8t)J#HF|s#>b?6K)^18hmcu7-+MG zlBhXkGhsm}$<9B5UTu)$CG*=DKWUX2w{^0h$lpI4UZDr|MaXcC)DApbzR0Qz2c~VP z&xMf1ho}P=@jpNYqkDboa(_C3-6^GxgSksgS_y;U`W86a(*Vi`hr#C(>j1GtUkF6>D`m&U@ZO>c#iMjw~6QSO>BYp=$B`AKRhup zp3%2Ze$bVZ_htJ&{^z;8{TKYo>{ovvY~coB(J#wGFaS{!fQ}uOfY4?$UNn)~-{5?~ zz+le_M<^$aTB)P<>;5GC4xX6r83EQu@Fi6Z(WCnRS#TP;{m#7How)!MRV>?4@ShX> zJ3$W8e0%7G)X3+Hgj{m9(>>U~yq$>>Nj2^3VvdDd5cc7mbvi+DZ&H4Hs-8!FkN=;g z)9}kWOnCl8rm?OkXR=mINg83Tj6X^sVUduMb1tA|Zu$f4_65J`-E;XF?}6dh8rV#a z8kI?%Mp4m{s82($GE@XmEl^HZ#TEg@UEU%Q-CuajV#u?#q9%6f*}7zcXWqTdPWx`- ztL5a5o&l6agnLn(xEQ(b^q^xz2BS67yn&eAiv`x(Qicy2yyoBHq&0l@<`zFS=07V{ zN+RDAbodtvREp}Zc+kKNm>}i818cuta-Yz(_!9XEZa3GHE>{lSiU{io86>oM9A_FXL#*9YLWr zU3JC}bp7pF zBjpVBN>;KW0Cj%0@C8&BLFf@-R|?JO_>zt(3$1nY3jq~_WCQ!5omNIap>#-{BR(Oc zXqXXJyW&}iw~!TGDPmDEVnzPvQY47ID7{?IAG|5Po!B|E$3J}pLkE_ ze$}ae{L83sX!R&!&!HxK`#9S(4>$bUkhjw6qaj>iI0?rebs}p>?V;wN7EIIewF}rk zKE4CO5l0NFf9foEa&U*Um2ZviJOnY@Zz|`x^6yUA{A;3089_~y5v(H5YuxogjXDP% zj$G{mH3^6QP$Y0ctkvYb1@TE0@Vk~(kBQMa&D;IiYqqt{<#zJs<0J1`p?7Ti+R1TS z6ronRtxEI;1;5Q&5Dnw1Yki;YRCDg{+%cfwh)V9>MLntaXu<8(SoDnfy*_4 zpUxHYx99F6^ZeUiA=IbT2v6;?zJUDnCghGZH}T#AShN0Nosz2RgkKikdl;USIY#G@ zN$bJepF67ETukS-FJ#B?8LQo_B|i*6HUC)=>Q^IjO;~8%vcN?jN ztzKf&MZI)dnc~WMlb7Tl6mUFMeDB3=BtosYLSZfOJukIvhl~|B7Dy(x`T}V^NFITvt03&IMl=zogg9ZAluJj3#7Z_OZy0+lJ{&=smtZ3i4;)b;bKMR5sc+vT2@-9HjoXksZlkY{If{+ z*jG8lYFQF*m_KM#1-os*eZy{Rc_U5oDrJ#dL|PAh;T`iHvUYWDmJxFYD;t^mWtR7R zP*y*U$`@jG2F>vg5w&0Ied7Yh3 zRM$Yi7PdfY;)lFQo1N**0WJ7YY9+!qW^r#tO-&~0pOL3P^A^PX;6{GDNGGL7Xu907;>`|Y8Wv#jj z+Ivv0Yw>73+&b@HGe{ymc`#zI081&OkonR1wU3Xv{%fJD(t1ohY{R=)!PFZ|*nX;r zt}Xw8HU#rq>#sbI7#4w_sYvf&)KnI;HDYLfK+||xhzxUu3jV15Daw)XC)z2Gfwcs_XoJ|x4Fx!F}P#=~SIhX=6IKogEXXvHV{r0|_^taSnf9d$&3>$&qQ8nvU> z<6k$AOHI(`ov>#RGu?@ig&JvuVCV^!bez+JRn2CZHEiu2yv%1uC(1FIlC-=GD_;ow z^eG0r=sM5tQZiydr>mZHT=JtlJ~!7qb8Lq*<=(sRRoi>-xs-v2@gltfIa5Goj3)#G z4_<_g`v#|=B7Du%hkELAPilx-FR|Ky83at0GF$L;msm|f4jXSll<*+RzynCZ+H1Jh z*$K4qy#DY-)6JcCXB2sB*pPTg*V+m!t=?;H3Z|b>%LA;ID+VH!7>-SrUpx*YyAe`S zwhyV8+ixvIIiA`0T{!^#uSKY%VBsA`h8O3UI5Zc02$fb{oK~~$>Cihw1lJ>Gs4Wb# z;J)Z}Ac#QiY4Vao>@mkK4FWTs9p~y#;(GqgWsg4r8h+ksFNa2@kcZtstr|t0*Y>^Z zt8`GPg!ya1soo3gIPvlW-Uy8K?>EnJLd%AEhWkQd+wPoL6B+?Vk=JwQlyV9k2TCP# zHUe;n2pV0eL{yMh!=kEkdDR!TNj#n6uqydOrZv0M(HQCke6{|+cH&}AWM6yFrOx+f z-yF z09hbl!?lU#?f2|1WzZ^-TUJE8Aq6gdW(d4CqZr@roKp4kwaSHf0E(_j8=w>fbrKG} z)>wTrFyZ&O=|M-du$R)qK|_9P^#OUfMB@IRjTJzQD_f^)n(;|FPr(LB@#3Sgk)=^( zyv<~~guXy*-W0O{B`ziEj6f0l`~{Np&C7Ud0R^*<42bDS#Ws`vSC%8|_{$RzsA_~Wl@^(;r% z2(p0CqE#0D zLGjMKamf>Oh|?ES)PaB~q8dD2y9z{~o~}`^y~y7=q=$56URzS2s>HnPFck8_z;^0Q zd{6-K#ipa9b-}mphCt10$SgX zhyIOd+X>wFnx{se^d!}FR0m5u9RMjNflr4p? zeZ$qbl9@zTV=Np3w~aD^bUB18x*5&&X(!mC)DHw*%0wCdnNEW_=f}Z?Iafm^DDWG*IylXGF#js=J6c}!h;VHD`|B4Dp zrKW0?KpZb3k-SfS+as{jzFSoeEK#4Hoe8EVL@nyQGqHb3tH42BfLxs~4Zn(sO9~&^ zrhh%&PlxC2)q2pB_~ifJSlInDG_sPqrM|sQsX6Gh0wHQWo$>;FN;brct@saxhLN7R zPYtl0o^tKH{sBO1=A%qg=wh4FKbTVtV|ZpUk|UAS+u1dd17sX}!P|&b)p9{Aj1sq> z^AKOUJ*uJXNMv{USc z`T2VQ^6#Hje63AfX7>neY-RSYE8SbLW!R|FISd8Tc|*h+JvHQ50n^#TeR&suYuZ()Wl(%YONS5E%2`a!UscKYy54J|`hi zr9BWz0PB9fetv^k4D}1&Au!=B)tl3j87$zFylkHO!0y$x+Whf!?VuV2qy7K`bUTPa z6hQ;>AJw@v#+!fc4*)z~H>y9Qw(u>u4fv9dh0;uBuV%yKUswkbo zny2MF!$H!~r+ZNC^iM(5a4nTB6y%IlzaHlckD*iT3U{u{d5zP;9w*F*@YS8mW&keg zI(-oSf=lFaxYINbVuJS6vFHGCJ+i;hn$LQsXBR#ff`hk_Bz;&|GK_?Q{jB&$8Jgci zRv^i{Pu;bbfThrFK$&L$c#%rI$)$ek=k7`m83)tp4lY7pe;_t(f2KE&@i6`{1RCxb1^ zvo4|bf@#}0->)d1CEne2m(|MLyU<7b|Hu`xaCB1CZo0+%Odc3ffR&`i1U^y)<_4hI z>PZL9-58zL{UxLdSo{TaDVm!s4Wc03Ig`O5=R&A{GvP+3Mx5l`pIm-$yJAD?5mg#F z5B0AIi^Q(vR5Am=3=m&31<7h+vr49U^enDu|6#>*l;4(7oFyn$j`2DavtCDPOG$|p zZQnIuVGhq&=2RJ`=&6lY69>H%Q=L&;X1L8;qieeucT?%>}sN2%w zf_F=dal#meRnt-++wYuj72+1=v1p$(l7RV`C{)pqtpM@_vSOYpL{I$X|5MWHf5|`X zHNCB5fN=a_e7yEiSL7gEH5y_5HI{bwxGpY**ytrklqIRl*Q&OR5=2oL`R^A&R=zS3 z#xXKrydqBf;o3q7tfzJNbKL1;6dglpmmpVoEjdBmzy3jz@w1$hao8uY$!nK?wh$yB z=Ai?TY2Wa%QLZ&yt^EJo@LrM+?F7bJW3oA1_msAdta1Ck{P2~RSl0vfM>@76maJ}Z z!#hjd>D0Id0@{4`0ThiUDo3n0^~938FS^cJ5A*lcF_hkZeO0s1E?`&y{>R~~=_WC5 z1U7AG{%Pw5oa6x!`$RuBT4#n0KWq2zX=@yyB=ufa4J?~#&kWSCQpyPRCcC7(sV7(a zN!lGp>qr~=XS8)gsbKR<&!RVaP5z~g^MMDUdO^5hIxIj|efY05kpANCMG!8{-~CNh ztyu}F z%4mvC|Gc^3)|J;0t|H+OyA(jjqoQ4DSqZDk==(l^D6!dV8-TC&KJKAls5}97m;aW+ zVlJ1%`({bLp55Ey6nM{6l2HDWTfp&k5}w#YXe&qKz@g~vP<=WmpnV?|9*I_!&8>pA z%YFpZk?gdZ{H*4v)ttR%U}METbqUbjuQGwstT2mK3zu(0w2tmP`B6~=Xx-PId24c70R$=xUVZZX z=ggjTkMv;PGT(6bsxLA_K*{8a>n$6VjzmY0orB}qX)P%9)p^)a?|-L!+;q4(*Kd-T z4e7`g#LEw9v9qwGFlJEwOTCswAhYipXtOZBxbEp#H+`}hcTuC_xI zM_&Coe|dT*K1Su2+4qE=ik8auo0Uf=$G2v-=O{B~fXt63fa2}H`alww~SYre4y6B6yg+r-d*E}{u z(8CtYX8W(tn^uZt#dg+~!1cU#3wxgRB~G+UZBcyG7fBdoXmZ|WG|kMt6|LvqO;H57 zr(_XQc5QlqFneIi?d8hgob78~UjO)ku*Y+s4q}(un|$_pN8_ba@#vT;+uJbyrF;LY z8qJ%FLytwcuJuHAcB0sZwB&m~SyABpP+FhU2`tStJhD^!EZe@K`zOl^n<7R_C{A5E zI_cVli(EI;g52fss6{Htl*s|vh2OSbl-{0~Iog29huRC5%r~o*%BdorD|#CNSFnOI zQFa|cMl*2#QY-iPc~(=n+(q(Kj=*Y1nEwnjLrk=ym{$zQ5na#SO8+(Wb^+u7FAYT< zH9sVZH5R|o&mQDF_Z#{oV4s+BlkqrgBqac4MYY2;E&(mDU#BJcdI@mg<`s zApaung*F13UuO5CX3Y*nv z6I+U7i_*QZF`n9;3-l|CtEs2Ghj`!n5$xR_r)hkhtl%1I6p0;by2%_j_RP;S9p393 zUsNgHb0LQBb)2o2zZY<4Djh$inyp;jEvU2iUb5Pr%te+@;e9jp&|3gBG{>Aa#VbV5 z6M**etoW=aq5h~LU}VX=GXuD9lWvnH(W>^?%K&!|M@s2)k@=#pX~Qi{hU$rDY<%I% zU2Qs3p6HXWF&@eod_K5Q8pYVRDFyY^~ls?&4A zhBckg?(tc#XnqE?OQ+&(mQL_M`QBWR$tB)VfW&yYq+>P?(MuHUgu-KxHRF>aR^6Qw z0TRU%xmR=!YxhWe$nFU;MpmtAYwD^d4B2g=@CVdf*N z9_d4NHWbyJWuc*iI=6!s3Yb`*K5+D=?9Srziw7T5VF{4J?l#G|Sy1QJX;~TfwJK3s zP3E)M=3GW|28{}%PuGq3CinjRR4?4?;h=NRv)p8nXj37hrTBn_{C*+t2^`7GNjbNp zTXlhn+estwfxO(@>{$Cn%b`V-bf`7HjW+*QH2P5{)R~Bx`D+uL(b2J|TL@x80h0LV zV9hO0padeuzN~%#`|#D6-+j#mKx@F=ykW=yDt82GD?9sP>a=3>&kv!=a^wadS=>`pP474F0Z zybqTJ^wmtRo1@;#G{>k6-lfHERXQ`IfqkAYapuI3;O=gFkenULx;I=*tX>ddb+gzC z_lD8`R(}RAtt9dO1c^@v@mifFh0pG?(GVA`6@o6!V(vFR&{@?7R&sXQngkgTL}@As=t6aI87kTFf+H#{8DcQ@Q19 zs@rYvigpos+UURu%WSKy3vfc^^=nF_v3T(wp>+8@^?^iz8y2AoJH6E}7D28>2-`0A zdgpsiZ%YBLw;)rwV`&L5Z!BPJV|A$cAyXRmi2Mt5f188)|9+YR!+#9D8RV02Tl!#) zT_LHuQ0Kkykzb7b92pCq7cutBoDQXxp$p9ldD)P(S@V0_ha#CZGz1)|2`B&3G^v`} z*QMX6UFC|Lb}PyVB&?9Z@9#sNJad2H8j2<>un)F9Xg)r+pRCOkE|idet6ro~=(@1c ztT7Qhn5%l@n$Z^z`>o^$m5NW2`?zY=bqaSg?&%p=vo|7e*=tX8p%kjHiYWTEoZ1|d zvu@lVc5YmCf6d>lkRdz9LQ!URzscPkKWHNM_}q+^oh8B4UKDiCu6LDTZ~M$M#RXXb zwQML+v%H|G-vCjx^ZJ9d@8jFauw;bJAmb=#NgyqxsQ=jU|)Eu+Hj0-w#rt*;uB~2CW(TO zR;{IX^y%fi3pQJ_o|d)u9>47dIPtMDo4#=6+AiI+@qDENeWp+l8!^$zF-!K{w}1{O z!0co+&P&XQ2rLaB$Jxx)q3To}Ebkq4{_9!RYjCCyODKN*N+evz?$B+}8(81iDz_X6 zBrr!(NWG&-trM2T>{?lBjxm#`IGYRi2u~3pR)E-b3qoW~4eMARwF8)%`%V=z)%wi9 zO7V^4UTpk8N{Pjw2|?8BnD}%ViSJZV+5)=9Tq&4XIKMtdSS*bng3)7w;2DXN{E+Q< z5uvn&MKG**3IhGzK4WPJ7}9#3Z3LN^Q899HB{kf6%`*lCA|WIFQ7acJ8F=iw_6mA}9>_GSZu9h{(DXjX#!n4*6_y+@ygh% z*2m8g!UAR;xW)^g>#a6LbpA`2OB#adXB2oWHwlNu>YQ{5fy}`|9l@Xs2E``?+x}zu z;iJEk)V+`<>sxac zBX_;!5WGCVz47=UILczA!eaa3eux^Ek)hOZLgZ&m)X8n{+w-Q2{8wFuAY$*#)_RvV z$9zM;elpg3%%DUO7qqF%`goSzPErrHxHu4s0z$)CCU)#?9*l>YC=G(AndhoMeyOU#u$ePW!>j%TAfUvm(1~ySYPxN^x1P(@|tR!bz?~`4F z{E$-8;1t!zH(-o=aDsy|)96!sE2` zmZN52BQC=(_pvDNlHxgaCuy7FQe^(C$hP*LG0i4NHsAmxVQp!WWNwI$OX^m=uKDm6 zq!lFbnG%64a`#3^q57OhfVvDd;BgGe%Fb76g!10s=*nwqUI&e`tA4V_7gxLri~|a@ zZ5L+G_ZM?N3BOqt@Ve-k+rP5XsFjqB4k4E$0`v0T_5S*5{qQ5f`YazR2-%%`z?2Te zMyHzTf}vHl#Q~gmOYqt$USP|S?^Ri$$H%gy=fnKOdJF8)q*n+U-{}~@PNlY4_4Y*W6{c{cGs%W zd^Yzf^Ij}d7u(A^@rkkjk|TgD6{0#XxpfoqiDZ&mlW*lJLpb=q5t=^=O>zE|0R3bT|$y9c&HFBmnJgM51XPppY0y+73LyP3Z%A^E-9MXNgDk%4J*(GFlgI5 zvagpv%M83^fF#%E^R#!*%1&dSXy_&9U3BHndA(FXoJ#)64YWVb@&R3O+8i%?L;&b!DFtE!N zkfD$_yli3-r+%Re2X$Lh1LQl~gY&Fuhv)pyikI$4p=psHK~Wd;#7FbB-cyrb0k0`P z8*SbZo1;$EZaZTMr9~puw^bMZYWY55f04fdLt(g+pgF=$Wms#7r79g z!X2d8ob+kQs@{I+;Qo&qU8pUU4l!oUsA?Dn{k3NDk;7>zZ&rQ)fczsmZs0Z}g5j-b z!FU;1RAO&@Gw1S2DEVW=cK543sIzUGxF_z9=%j((w>nqG3+f`acple$#f|y><^;#%nDatHTY784l`G&W|5Szq}-(m_C)$T!hjys>(7#wFwWHi;lU z`M>&%@#p>4EkIbS!7r#PN|6pPducI`r-?Vz_0@_20jx1A(%cP-qpu^9`&GSWx zDBb5up|A=G0f}|fsG3c72AKNKuKg`*RV(;74m_5-Ev+c2dXjZD&z0BzO+oS}uteBt z4EgjN#YB(B_J5EGB=S`yN@+u}upo1&FjS=mlKsyd%0yq0l!@5I0yjqid~o4H1v}>JbQFIw4{r`t=Sm;Zcq0ft~bG z1e0CKWS$z2uO1nUAs1HK*P;yw+{6MTzpH0|EK<%Kv;6Xge!!L=oEq=5c171BDL{#< zVew$6DVec100yhFzAzp0UxAl})?2xOqd^X1y6pU4lguz#X^U4++`DS^Mig&|`Pgdp|tnyVoT_lh7hgSn$<6Zl zstl7xF30fRtUn!Y?BLeHGH1qd$bQ8Oeys=2#_q}AMQatQD|Du}+a`#AQSt)&bvgi_ zo$1MF#$V09ulRI&1TbR!T6I9$Xz`v|=USdZl0rGdDGr9ZpYatgb-z!m-+D7w?IzBavcwo;YP-Cj zRNmf|@w=&WtyLTwkI|C_i z7xW;P-Qf7g_whn4KfC7Zbp3>)8XIpEf#;qCLmO!|eH#p759e&v9=ob{;yyO*My2-q z(T*E(yePJA=yC}e*Gtf^sTV!+81e828ww@xm<28!>P}> z&q(^sj(1e&;`;!sjZ!n6ov{LOb*r9agV$5F zw&^Gd-BSZN?`N#}dgH@BI82;Tr&B%ff=qLc)y0M6!a~+`FC#KNYOh4Zd$h5GOzKn- za<{&NhbqUnHrmzZll_7fUl-CR3Z_UbuY>AbJ59K`%m?Rn4*MPfmVJ2VG$G^8sR4h} z^^GUmIYoaEp&0wA7_sUWd)oHt7jvliXjo(#^)JhbH`kK~V|k=(+Pv9j11}yeXs~6? zNEStEH)6UI#?-EsEk|>n(h7xC6fKwm{4-XF&7BeD4H@4Ljxu+T8J~!Y{+)Skt zKQh`yw)2iMrMM5^TW&t6T^=)21G%e(3OB*F}d6PuE;Lia(!pve>G%l(NrFAp@qh-qH zxRm1=bkas-Zyj->@TmUD(n+tA%SlJIA79kC33}h~HbO6#H#9zO=DY2xijZ>r{sMzg z@g`>hBJJRe*7f>W6gbDAmze-}7b*O2q`hTO9znM)jD$cSNN^{F;1b*=!QI{6-F*nI zAvgqwV8PvjTX1)G=fPd>@Sg8feLqf}x>dI-fAS2|GdD$syzBz@idG+yVmV#K-kerOGvfZC^Q<8P83sltMsI) z3<4seaqkc{6sz4zjrhI8hA+UTQm~0Oeo6nHXtYs7$ls z^-EJy(qy-=iY!ml=c{uk}Eo$W z?Dv5BrQH`CY~r_Hm6hS_<_lwt+|PoNoSxnz4bXQ5ae#TUtwU21sWN365AQv+CfCEx z@!VNia()Nk6LxN!020oy88~FTXIq;qWOGJ+KUiE2-i!Y5jOh@1Tjg?iZIxf!*O%G5 z-r)Mn7X6%>pwn_FduB=Xw+;` z4kXYHM($TTO;^rar*UIJe01upKOfGNo38lJTh9Y^-y1K?#tY=W)Y&eNB&+G>YR&38 zLuM$|2%g|Cd#vj!ocqhuxSZ$$iubPhKA@V8XAoQro(AnyP3Z0K797=Xpq1#kYRr+4uNhwXkNC}eVEm9hO9(o zVgn<2Vxu7`{5GZ;J|K!Pjn8Yu%ha8$U_*Ah$rlF~R~($s4ffgk7}`UoNR+bOI}fc_ ze;~d#>TNNUnfL<}dVs;;%oS85F-y1(k6Wet_ykNT#L_YSa0gV8@m@ZtE$9etmHh@Nb`2w-UzWF#y=NJAsFP z8!wnr=^IV?DJaQ}m{ZQ5@O*gBCbiwd8_*BH#k+2JF4FKf;N>KwoQntuHVcW;pV-wq zJK@>%IF4d!T;O)QCVcne7Mz-#yhWtz+^C%v&a=%IAk&!K2^vEunUfU0LosmQ-zu#v z#{dn5S%`p;_v1b-kO}|4@^MF`;EMqFQ*rBZJ6dhYH@2#T#ivvTT-P> zwQGMAYnd%wPV|^kherT`=Xmg3YE-M~z?lYqk1#KY%{xD8V5<8-#fnO&33GjY{b;cn z+$8kGJT>uA3gR~VWT8%b4`1?~c4gBdd4dG9+pX*5^DMVvZjLv@G8w&QqMi58KZ4dc z%OLk{;WI>{R)t2*@MH-N_bDnZk}piR{N|*D(wi{`WNlSD_Rv7R8k2l^43PMFkueQo z?O?JEfY+$Z2Yky7=SMtnTF7}nT7chUE&Zl}(2<4EP-$ z0pZkab>-=`gPOGvgNHhzR}$}X^9_(QX%QAJFg&a0BL?!mC}q=rYfjS){o;c6bIkPp zW~j()S{+p0_LykI)TiFOg9`P0b&&eIpa26;qnC${^Kl->eD=f_^g0BUm4mzk>W80h zn0ywbXP(X|>9uMP-bh3My;hy*`ZxD3h}>0`o&~$pMa94h^rSkJ1dxPHUlZW-?Qc38!Sv& zg>+g@w}#yGwFwo#lQfu4ge@NL=#{s|6w`s-CXspc1M~o$k&+ZHGkG4@Bak(JdQSUg zd-3LExtYo2oVE4EwyK_vy9poF4bt0(A+T)aw<1%HakX$9Gdw`bZdh_Qw6Kdp)MMY z2Lz3q>n}{D%sw$U_8S{sCMVswZ&0pe_eFhudV95ZsV`>7mpkq!nQ(K$ur3J0X1T?u zuoIrbV!Er*YI31kXT2g>r1)X>$s;s}9Q0D93Z|E)Y%*&!=|NZZ_w|cRHoxa36-WWy zo*bpvXLlFBxxV`MwJ6Zk$kl{wX#b>o{=VP-%!zS+iNgANu=1Z26l2T(m z{b`ofHA-}N>8={=Q{pZ+yX{;zxT|V&)Ij}FE$u8H#BtdAr@(HrBn=VsRA}|)0)6bh z==6_#Wa*&V0jQ=Ro+;+Z?6ni^d~^vlK3#0Uh`VEUdqg0hgFqHct{ufeLe~P$ONp#q)Hqll+xmjn7sLg3K;#Xz6%CD>Pf> z2H|IBW~NeVVg(xq@xAU@MqZ|}nKFZ_!)K@nS)e}&sd>1(d@q~E`OW%BA`RtrO@Kca zrpfa-Czoo~jkf@OUBaS?q-1;n0U;>hq6(HwpovXR7Cs77|0ALXA}7)|`{cmq_gwCs zRk*#~2Ax6s>m#n592)t2>3#2qa!@sa>p&#K^ZuP|MkE;v8AeD~7(6OX9{LLu;13f} zs7{RtdMY9C3zY^>uQYx0`9E+f#j0n-?kW*w1O7nfZqDSk&oCV;T|BsJj00a+wYMuP zDWTQd4CsNf#jlCv5ev1J3gDi-{$c(1Z|zU~{KNq(U$5}TIb5k89`fy#}1v?$Hu5Q*JI;f3|N8o@$XY6uuJ3C z41n~b7o69o3ksZW$3B2Fo;go4!SH^lA9V3zV`FcxQ%T%?yX{+(FR{o(-`|X!(?rS% zq;&U0;CKMu9l^1-Aw^1NKW!>cA4AuBX5eFtp8sazzC4G#2Tt%7YV9Iai^+G)-(&FK zCf_3;YaPT2ypu2W?>TCI5ciAKGonONBC+8M&VDFb4fCUs+MY= zUMh8so3maXz91yfsDREjYV-2Q-35-glvKg9OPR;gAMnJq^TbIK(gpPUeSZRX?Rp!X zjb6{oqmke%g1enVh!e5`NPgFKKWj8RPW=a}sWg!0uAn+yAGeIAisl;J4Um^S81W@3 zDi-4FB%ly2WH%oiy^MFjS}ZkuV6#*$5F0(Y^ZkA!3cCH>7;^k0Q`D0ej|>WnbvC!w z6M&tCS6SccYNiDXKw(tBNM0iel`cC-nJHro3P%!hyN4bfS<|Tg5pQYTPUfmigY`NC1r24Y8xr0a36*x7=azt1_5Q+GLHi$$IafZ>LpUjefHlpQVG0=qW;l`mb` z_4&iU#%eU4l?H+umW>^Ihe6RwxEzJzaN~ccnVhK~1efNwM(}dl!S`XcRDrfcB<(&1 z&&Y`6RPCWFkdd@j+Q3s}PzMBYxbQ}(R58Y4Y76Rq3@>ak$>_P-Ib!vtM^|{-w!U?nQFEz^~yqBSrBV$x)UhhZg1Y6rfKr zJw%3V(FfiN)H9Zz8lK~iWTZ-nPIv&;8N!zaDn$zGq?W2)xB>aRt|92f%Rv|%lJ)3D ze*V9^SMgrv3DUTLw7fPSsabgViPm8R%z+$0{qPt>3fiV<=6(7+7TO03W_m)v@YBi9 zkgazPsh=r_NEvJqHS>Z)CvX_w{OHRo3{u>bOVkKi9F2nKK@37?Bj%OFF$E%0{ruS9 zz`+~1nf}c9*;&%FYR_uQK^8m=6$Fv~8@q-sBAWdVPjJeDP5<;Fv3Z%8mw0shV;m#K z2I8~~@5PDnkr`oh>bJ&Is2Unt*&r00S_K-%6XwmDW`{rN=C$~kk{psjhy{xQi`&pa zsr9-keQhf?GV;kJDf=2n{B=MES;(wXuBlZf*9G{n`gFx2D9qcDvotjF$ukT+hrKyB z<;eGfxg*_%Zdp^Vou&3Uiu>|^RH)?jtLNouoNV)US|2$I<^B3{+xHo>6$u<@hu!US zIQEiRH%(T&JV;4DU@6c@J?s4eMS=toNPapx(2GUO6jqz9Xe}Nth<4&^fWsgOu0;q$GkR8UkcXfzZi3K`Z&qy2VOQMNTi$MEX=5 z>>E?;&{wu&ygh^2TY%^eHBaj9gFaN$HH>W#TwWEWZ4fp&4KHW=@!KGHffnL)-RSYv z(3QeI^GhK}!M8kRAji3AZ^{!*G8!gNFoLTqO!K&}CbQR(fs{zhb)CfMO74|e5=gZ! z+v5|SIr7aO-0HoH=dYnY)-0G5|{_h@95nc`wC*BSbjS7yTnyR9lX~pf|bG4@yPOcr@|U zBH|S>V{2#wa0Cd!%0#Dqnoxgk{#2eiGbNh@c8mx~NUTABJdB2LEzY`?0eSY`8 z{#7DM5Qx{Wbf{*;b)GvaDrA$r?wt}k#0k_TX>R}ov7>Bb~X)J_~`57&K7zt0|Z3TqKS0}D^6!;mRifHzEb&E zn^wOS_52170lEJ?PcWrg_NO-!k*Pjj=;zA4&uJrKhC~503F0s(Q;XW4MS9f3_#-OlE$la+E z7ltPB)4t)S@#)C4P%XLig{O!IvVZ@f-p0$bTOqp6l2nrB$VCD|&;OyG%w z@S2yShEIgIukE2>HP|`EO$6thj_7Qo5*M%r^_>_0DdXMxZWE&r0enH4#qDT>;p6%r zc|ZD@12|3X@`}+!A|#3t9qD~pV{ie}QS*-2sVp&48oS|M7Z;$L8HiR-MamTRs;gr+ zyYKwLJkszocW{sE)J3wkDd~N{59>VW0MbC+W$xHxd3}_UuhPGW2xwqB2S2D})8)~J z{hcf0zNxp9F?YuT9{mS%$KebSXo6%*H%}L8h1pu8t)*ygmM);Ej*asRj9fm)rg#!o zlh^*MFDQIfA9kxCYDSHXG07K7HC?H?Wx<)N@gb26^7l&R$nu_7ykh`bnu=#_$PfRR zRavlEHn}!If_)qtwWTw-U&T%B?FRE#&X0MnE9_prWdMZSXtnn{t}^e!B;NaazmY>B z5`SssvsD+^QKu_bE#DlPcTz4<|89%w@>}q(DoC?naNF>7ldMp)7Jb$Gj1-Kk7fgmp z<_UV-=>|T%jyiyk53g49JH^NMNtz*IMKB4mIuAe4mYbL}{GbG_I0TCnvnSxs z?syjQo;=~>WnuM3h`$%VSyfdY0V%<-8das)f3bm+j}Oa&6`#mJ1`&Xb0=W+{eH)pJLP2(y|?v=)S*Du zYp~vCb@(weQQvLp@nU(2frB9lDRtPltEt%)Vs;yRh$JT|qv zdlV@yQsep6ckc$FhVT5Xn;7)~EKpbrvdZ zy5phy`#ke7^y``&f4J6-ynf!gWVIqeD8#5xKAZ4nb=H4uEG@lga(`dR(w^+n{a7y}nG zM9O7^J!y?d)M^aqNs~P*Pw*BiHKfP~v+D&xgCJulYZKO{P@zRr)+mW&KQ7)o#-y$6 z?b_&7D%0Lojg?oqTY75!k^aLEKCm5;8(UN`pH=p7XI^VLG|zt804B|XkdqXnG)V#{ zjfCu`vJ`K#JA+vUgITV49n4UHxI`17aukY_QzpT#Sfc^tpyHkqpY7v?%v@>2RfI3VKs% zG}@uPZ8k#ASRrQyIm}14IvXqppycxmJw*9n)@?omTf`_PE72dcJfwztOh$>`mX(T^U*Cgnhmh95)%{mq*K9WHkzjMV#|MtRw8n=+$S3H-V|h*4d& zGptKyoTn@W9^Y$P|8QQSflE|oNsNpj6nA8CJ@Z!X$P;&SAF}|Q194rJ?8Y{w`9pw0 zB$MEfhTGhDtJO@Y=MH!IT;+ZFhGovm4U+ib4URro0i@Xx!J|35lx@4aJ-X8_3gaLvXnb9Fo z#iYt}S@kgrcsonJ1}Z9ZcCU9a@p4yiTmX+5 zaulrr^VaK0J%b=a-r1vqFB3Q?o-B|yyc`@|cWmT5oi%`*gQr{5`5cYMo7{TnxjLg8 zwnM;i?<)u}ymeUla!GLep6{M_1Xam&*E6=h1JKv+@5GZ%V?^;QEOexM_TU~B;KB5J z9a_t3$?fpRhbRT8_gi2`vP<7VJ9$lm2c}&>~w3UlQYYu)| z0n0nxn^oDJ0gBlaJ%;P{`4L%EhPpy_*u9+miX`eA#pKw)oQrO6{3j0&<{{r83}6$|Ur;Vw_kC zY8$^^=`}X~b?12Q-NbAECF)>$Yj&DIqtTT`?)`ypmurF~oMc|Cb@8xPV!Dk`T%T|# z!89_;WdW$#P-8KV8wAtjY~Dj_B(Mz_FKOfyi(G(_v$+T{vp?~M!NW^|nmYpYW-Zm*P(ae~G}K4h=tHTP zm^_WkNmf?~S9{%YGYGULa@zgUX)I6H6D`%X~td5^Uz0Le4T}w;xj47|-Xw^Uk%B zuN#ooSS^26YgiI@H)k{(rS#OxMGs~m{r;d85tM-ib(TsH34BgTkHI_;oU2`y9YWfqR0EI12=iaL8 z+1&uWIe_drM9k(Il>yr)=fFUYtYrRqeqNT>LSyb2duRqz+ZKx<8eSj(Jz+$s@1Z$M z70Y(+CKEh&3cqu@w}#0h>vT+*F4rLnnGBnc9lrD!#N}BhSaH8W0(bwYA2z8t4aYk& z2UUi{6ca2};xdD4^#XNcIT9naBp^IOv-CUz*w-nyb*)Q~SRLJ-+P{E0;B7wHU2cDSUg!9YINdUCLSTD%s%IQ z_l{M+W=@_~c`kj;)l#A@K2&$N!~E1}Zjxl#vCWPWj|Ma6O*oeW&8%Dg<73UGM*}Qz zbV%f2moAu2rokFiEOiVztjkk=_HhPQi)@f&(|EhAAkr{dy2s`VwIg>7D#_Hzv%2`2 zSxs29!V`@`wEStT%MUtvq)$zTh$w%Hj)`~+QNaYr?rj(+CRJ!8-EadCy|XFTYI?Lt zlA~C(cO&jbYz~lsuEfqTekC~N*lkv1yWVnj`Ol_i7s%^+MLrJ{uK#7b24M4LU&gg& z8Wi}5fs)l}sh#J(hw}v&ojXDr(S!nU!W}KNWPWK&=}pRvx@k>Pd-6v>ir7#*a?mau zyM@cDoIj(Q95cU)ry&aK+HT)blyB7jELngokRA?ZmrUJgY$K3S*UHCp6dLx`$zZS$ zt=VZ$l8rtme|l%BoW5xWxEYOHpV~Kn3rzlmv{b+G^Ki0!szhj}B1xCc(gn!;bATc=FG=d6?FTKVVhl<>xX6IT-4}xVS++l?owPMO8-nc;ILrm%d~? z)mdT%yww9{jCK9HfKRw*E3+%J?8ONXN|~YX#a8w;$8i~7J{<&y#hRA-cQ{Il^L2+` z*lm}kz)69VaiV6NEdmW&{Ly9F5-YD$D56l!0|{~9fv&7V336e?xL2fIbSjj_p{V@b zB?!>R8VF2ZTkF7lFN(#cjlV?8!Mq&-3AIHVhD(Yo8Im3XRB4MeOqp#^YG~Lb3j+4g zVABZ_D5o+ar*nEe*XfFi-X-srP_TCR*Qtthx@vg1T|=nCKi0gWnMftUedPXnPkfb_ z*^tz+ShE_oNyV<(@Bp1I1v@s4cq0u(lSDF0C+{nJUaEsubtN?~Rhq4&1z$}$zASPa zOjKvMWHvy#Xx(diWAA##@6W(_8u6a=*&F6KaYX2YW>pA6`Kx{v0!g;~pF+k1qCdvm zoX_*D8>QI(%D!_prkc9)lb_^A@0wz8JHJ}gq8Gx4^aKlTMvInyE1vmz;u?2);Tma1 zXp9%HPAfcSF+N%-)QLD25c|y(3z0PNivpFq{u1!UvqbxA3JsP5&#^KpNYPNiC>e_( zcKgBnom=odBCD-Do=f4B?WHFho-6s8l3T8{{RZMy?sCKKUX^QmwLlH;F~J z=k~t}uKf2U;D5RHzg%jxBDUH%^LzO7a*F8|-K`@6Jy86tL>1mFBzRlKLje+CE4V(A z5on*JX`hR8z9Y$!_k)qACY49kbQyU;B0b-^=y0J%sv<%M6g%BKc)8#;ZE=1ZZ^u(( zX3hHbw>5ZC3ioeTcbK@e_Y7^E1fkW3^uc2Ds55*k6xgfnStcWuM9D;AsE0?NbP9$I zY9Ijb)yAPEO1mgWbK}Xxm#F7i_XdG(4G#@`Tx}2RVh%ULp&Pp_9VTvqilPoTf}tA; zX(=qy4Bf!;5T*a%ek_Q83y(-yv&VA#5=h0*|3O=V`JGUxb}X|oMQMXq!tEOKVmtk8 zO}C6=j1_apGfBcyB59#Zp8$j+>foM5ML-z_;`U zq=dcwQ|#uYl%kK%-0p#YRA{niA3(I8$08S;1-VbE^N-)6>=C?Ad7*G?Kya?TCAGldQ+dX+m&wDNbk2<>9A7# z3_5?{`G%LD5$WUg7Bz(rTTnvrtU{~yXRLvQ?c&j13}S4_{fYHAw@Hs)l;oc&4C;9b zo)O^kKoIa~jdn7iHNH3H7*2SZ6S06kfXfG}Q%^oVDyGQX%^o{1% z+N&0NNauPH4)so$TWca(RdQ%tc3YyWmZR{IYlbJuR;vI0_h|({sy*TW^@p>pMoB-D z>(QMui}0~}^knz|%Tp;jv${gJ`$>9uH@$<8jh>`Fp8SEDI)?D*=U8hHxmEsU_XaCU zLH_{6+LA_NLLr2+XzI!ilS(WbuX$D4o4VtX^Htx`izo1<*sT{vf@K!}4V*_6MN%5d zogJgHcvy5RfuQ;nlHD(W;p%rGIL#SQaeE&}08CQ<>P0@pa!*$arg#vTSk`jA{l}zx zHwz@+OrnpZ@#*ayt2cTQJ;9^y#*MboPB}8v6I9RpkDF(Gds^6YZe`I;R1=SOccm(i z#`~W06ZMeh4z^JcvlN{`TZC^=4YDhytjwjl^+6l-9=BUjTHFE4TUuT=Z&n@8_Y`*< zdD<=vdHI!~o5jpreQv#K*l&8`-y{8aNw6W8Nx!kOd)(g9<-9-jV>g6vB+za3;}m8r zq(c3?N6Pt#yS=%KRjW$l{=ylbqh!!6&J65^FE`Pu?-^-2al0vdH zrKCOXo2s1~02$7JOewi0jR^7A4Q(Kt4T>xU}STVo|)Lsq{0UAF)rS{xJyw z(%+FqQZVjk*P7W8IWJ(qzMG+e=|q>ftLvSPZPWBYXIJ;ntj+M4nP|+<(k9E!{pmy0F#|8~n z?!d)@*5>%#J{U0hxUFbeM)WWZE;*svKM8-uE?&R(>dPI1AJB5{ojtQyc?gyNa*7vY zA_+jF5fdLAj~3msK=BHkBZKgTaMV?RcGfICDKwN3n?Cu#$LFY9BJwS)37Hfun%ehf5;UQP=a5Zabh2s)_mBa>6Xc8h*B89X&Man&sMKFh0OJ9sG?-GmV) z=Nu#~g@9a>>wf#8k#3fEqj&@F@9P1pmu$Vv5D%XrB=FH7XExKR_SGi`tmpow+qK>P z+!yc`6*N?A6^ezsS_vH0sNESooGH?)$L4ExGaZjjuwHG%$sPYX&zyHr;&meUskhj_ z#^j>+vDFc}tz7$SABv5mT5AXKsq!Np;g2@RWs~ibX)qsK@^ssX$>>a4(IvPdI$*$%Rm8!KTo=q%lI&BvQA2k)zSz?~S>vtC>KYL^aH&~cwt zP)FC?uvIh+D5eS)Xu9%^3`uC6MCO8m=q8e4m<^EP*|Gw~ zp7Yswz)Y*u*w{2CCPf5Hc`=cNRNv2fcwatif#!W+mnC7roUvjjI_fj|w!jB6Ha4Q_ zdBLJVy(twdN7;X0@*nxEJx%TcyW2*OI=ck#e3nIHQL$u)5Bl}EyD4M-8RuV2otkjX#(P+1#qR>_)#zV#Wv?!ogi#+)-{^Qc5Q6< z;G+ZuM@~~E6D|&Y&R&9j(2il@4e2T#>8hOHllny+s4XrrX+ZAn}Uxl4%){H#0Cos8lppFZqxQG6S&-|g4@9L)q4b2 zvf2=}6+sOpoz8`tCmBZlIT?sbt%p4wax(hIoLU5O{y^KZISjNYuN{kvOLv;H>Rznu z&93y{+$%IcXpR37+2mcdTB=|GL0MjlH(B6{qSoQ|msdiN41!5ol+o1W9#k!XK0Qg! z9Y}&*%Ts%nQ4Vr6ufdm13x(AmI)qHrI(f-v^2zleZi5i^aMfeLk;3{_nLsbGM1Oig zph&4$G~N*Jfh7_hn~Zhy->$?R(9O| zz#du8HzBP-)>Mj%a8)v1B3}ZH`i!`Uy~4p(nEDLwY|rT!bRe8WBuGPw(1M;H? zwjQcA9{K=L$h?xL=i67Kmj3g6y-zRp*RLHSQ{5V4a;PMRJO|(q`*;3sn$Gj(U^&#~ z{vBEyoo@el@+R0RW-!zvE=_aEn7x(Qun5ven($!XqVBp|6B5ik3xZ1{n(rQAl=p=u z!l#?=WSyseD*@2{ZM<=l6zRcmIo9?z9z}C6!)*KX8HqzJcsm)u4m%qWsNI` zlhw30%Zq7{f}!gZ#!O#Bv|3Bi$vPQYWg3+X8`bEt&cK@${SC@h#+Ti^JKtcEmKOlq zAe*9r_sz|o-^x%%Gvllo=TT9IH-`syT*2sYbrd)~svRy|C6mJc-P~)4ikgn3$eLn* zhi+^m)NWFKGe19X?*Y>r7mcbvp{C@BoGyENE9GY;=)D2|GQvjmoVS~4JXLJBdtkL0 zd^J~VCZOjX=cH3=nGjy0c|ln`^9V?Q%$*g!rmgwiw3LFyzZgn&kfp(t>fIE!E2Qfq zzV-sW$98y(How7a=TF!1H#gQ#y`?Lzf5g;CL9vp|3tUm6>#f{)S}lsvtKGgV+OOoK zCm-FE?eF%VPAB)}X&i$?Puj}KdDt1uW>;X{mxyz61{6vqN9MbgqEU_a&w=TwVlPxg z%tB>J5HtoFhqnR5O5zo66CDpP9#P;J?3fR|6OHtYJKz4~u~GRvcZ}lc?Dg~K&yN{i zJ4`>i3E{Iq^(u2#%V2>ETqJCUT(NrDB_$SawZgx52N6?6IxM5d@>H14M`OVpeKKp8 zDNakPO>h)SjIPbFNsB!(KyDwG(>1T2+`S))jTX-B#r|{)(sDE3zwu;@-}(6l)$?a- z--_hX2?@m$Bo*Gk!R=_89uef?PPI`=C6#CUE_)UF$RT%j33(Wb12d(o(wd%cuMTH& zwC9<@;G+Z6HhRIvsQ%btkw&g&t5P$q${(oqa?lB?(37)k1i^s7jZ5lZ0ZIlr49HR? z{aL~2S5Dnj&aS458xeA+PW*PiT(0t}M^zbiM z{jaOU-Gl-Xen49c{&ew%W8>}Nn1X7##;8weDh4j@*MtFuy(h;LYLAmgxDh>Z`<_q$lc)*E9*gT>jx-PZWzDtFYv^dS7r&D8`;^UN`xs@ukWV z@vJ!ajp)*R&3oBAa|cyd3gbnb_D@b@j6ic@?aJc-I25F?Tk*dd37h>iD^o0Nuv`kA z=nvvuBGTf?A+<^LO;Uw+IAU?gHFHm7~ixkkZ`clVP=2(F69>^wxmjZB5heYCuRz*gOIAZRzV_bxEN^Wvcbjn%C-O?(0#%JD6FL zYGyBeJ`*znJKY&J#|b(M85cO{pfl$tYz_^&tQw5FJYY~Oln)Oq2_djODCXHlmN#jk z(Q1wjHsZIqnXM8*F;%Wr+|Ycif^K?oHyCH#tt0M#$PLng_m($-Y{TQOXV?(DtAoYM zy_ql{c$B!5l%8MP7pFIEuD#jih=_>44Fb45TGdJ|^Ry>Ndsg3Tjt%HlG$8et`@B;t zKjEX(WlR9)g@nvtyKVidLiY9`KF6QFrIc07!6qz3ghV}9hosoGbLg9?$hRMPhm@Ce zKB$G2c{)YMQX^&q&yF@yOD!jn5#(T0&;R{e0riP4f`T{5?mZ=i_C)vzmU?5L6bcf& z4V4GR9!ALe0vl|=i&X26tXy3I_>DrrXkcM6;r={D|9%AS#td>{1~4QOkA^5Ra#IEV z&FZ*fKbAS^xw2sZ?c+V_Fji*)H73{Oe1c@k41=%%03H!z*FS(HLywpakaPHd6Epc= z;v&?Q_1-j+Jgy|4$p)oE*oXg`oS89HSUm8@Bf{OV+kL&O$~)J2_H;>Sz-hiFHht*; zjNZJ#H3#&RB!fa$u5CcI_U36KpI(#xy7TQV59!qA`02wsk3o!B#pKgF)-+j4)ztKN znQ~-Y2HQmiNP_-pxz66(Ifem&M5ot%L zm2@3nkJXFyX>VWPl;(qx=2t>yHULYKZ|Y1A>QcadJt_i4{*DO^WxH1^PUbHptXC>C znZCTw_DXudyLPt&Q$`|&=Xr*6njmqP=hoX^M_e3qcxXp&h^=R1aWe7z#@CXHABP&> z{9-RT_F1kmpdU$-g36NYIgj*oMVl@bU9PZwOu2~vq80voOWAZttG7x8ATXb4Kw-rQ7}g5&MO{X9 z#CL`og-z+zWiNVNIMJPA*$(TNPNoe4f0gOfgG6pEwVZ&#_B$u*e61^6oxq3+D&7V3EOD9Sm&`1sW`>1j(vWb~_E%I^?MPh3E}Ym+6BvjG4;Z z%-+>izrIa_rI6JsmtEgiWJhAX9>}1sl{}JP4{Kl<(mb^)t6F}DX0$m`Zb7RLF}Nu zX3NWSe~O>F9MS>{z6GM)(N=c2>}Y=iGu_)XR+Cj9p!#u??wlqWdS!2eIaVKHW9+=8 z2lKBGms~F>Tr?_8G4}B^e&?HF zd4Z508Cw|#2@$7pAQ9G~7M)Mo{qmNYyUu3a$EJ4Pe5R0Hg*Jh5-;ieQTdArN_)@`F zmb&$&#iReYYi&Bh;>_HS(JXJnueSl})eq=b-^XU)ehhKyR0nXQ@aFI#t+iAorKb-7XZqRJ8u3&ymQGD^}Cgxz+CdWBh>b;C|Fi1e5d*>SE4CdvXGi;)XD_p1&7OqEe|HrV{{ljHCH-s zXCCq328?HckV6|pBF$N+mUbFxojgT}eS}7>U^Kx;3`uKyXjVJzke#SQOu&r;)H96# zNbU-%3kV{_;DB-M|5qdMzu1RHo6*gQeP>Rcvc>7Y;M7D1qzfjO>+0;Z>{SYt6XML! zZPhNoE=g7t4our>E!NXFz+7r}c6HhPe?R};+FG2c(|#>2{yztF|CfjVPnUrIDMTE< zcJFxD&;oJo7**(ixq}>AGvH>Bu3PmT8o6gaF0h8MU^U;lbh0`=sG}A=YK5!0w zZ<7``JFF{XP5OH+t2gZ%z!JvbWmZczL=lG@d4w}L`^F{CbOun4Tr&zkN;FCV64C~A zpbDhdH8i^ku{Q@uJB|1brP=g2si^PQ;8)qWLaz5+G+FW4Kn(4(DBl2&vzS{SoSLO4 zHl7Cd(7fuUFE>o2r$0=j`IIFH1a@$fLr{?B1;Gy?7|mT_^M>0)L9fK@=eKNLE`1fikdTO`Eb~&5&=3 z_5nY#tpmb-{g}CV(UD*=LP1TA>^HGa0TX$@aT1HxDRyhYcAMhQ2nYW&Hc?_}UKr*H zIWX1#`Rv0luyOQQrFR@~3N4C_pDZQ|Z@R#LrfxsonWEyS-hYxxLBt9skCD51_MRXg z!lqr%{`LkQH=>zG5I`WwQ>Fp$G(bfBc&ErsDW{jEox&J-5A3|(w(b-GA=Z|v)PUB) ztOc8L==;7jn{Dq6azP;&kg|UA&9`ig*?js}?t@#-y&fpHLoDWUg8Il)?W5LmW2#Z+ z*s%tK8_C4p%bpFA&TSDtLrWvxk#iio8QC(R{UiU56o?53I#JE)3rR;p4>qh(5H#v* z)sbuHXin2FwDN2}XZxF}xw!tG{&jP~>wA=*;AuQWQ*b@<-(Ui>5s&DD2s`{C z#?7Lbskw!B!O;0zX1X<~AK#H;NaY#E#QX{kOoP5Ic)llRvM~f7to@h{N3R~0Sgr}M~LD#IMc{%j|boo!|?RO zBz+7ww?4+jjiv}h%LAt;=C*NGWi9OAj~|&BM9;iJb3&_Yhm&KIpi4~+GmE!P^K)_+ zgKbk```=Y!ctT<-=py38t|flpxzO~ZnmYm_c?#whhoWiy;@=|Bn9HUtu@D`Z^$#67 z*Uzam>pvnC{;}(bq;A9@uDQ=6r}W$PsBzIGb9}LnBy6AuO3k&kGj_U0rbk70b>RfQnl622OTyYz$ekISR<#^~JD*usx->qUlC+|5ltvh-F zG3gnE`}t^st-{JQ*j#wj=FD#XyFnF)R?KdnSm+%lN@$10WdghQzb|e^I4gb`4a%v2yu`DqgfEl{pJF+(_3?<+S;Oli!aDp;*vFK# zb)?g!8Vx7bBe-frditms^CV%fdMrF@uqHqmE@j})GfW(#z~y!SzQec#lYm_~b!(J( zOw(wohfXXUqpw~`$SD>QA8bNChEt{Ka-aU%h2eDDsd?$N`uu%xeftrqOgnr0p!GJ7 zaK6$-5T6ILd=$0(i(g4i{}nR$iraC&Fr#Nskis2VdbR7o;i%cVb+AZ6N8d06#!T3{ zNY=8Zg>A#isSwm_j_$wD64xVPiA6Uv{573$GZ;$8{!JmXqQ_3UH7Ha*DVVF;F|&!^ zGp%gr5NuVaz|&3DtUfp#B!D$D+-qMBZLgX zMvtO){q9fu@`=-4=73l&dN9g8NRi8C@tSmI*_~&_2jZiwGOa(EPv3B}0)N)L`t&X4 z{vD|v%G(xfeOz~+X9ex$K}$EPjJ3M5GGYRD-nW@@^Yeb1QEyQSw8pvnJ_Chhq}Q&E zpQ}YFuDBUO26M&j26r#k*E1hspiVa;Msu@U(Mh~3;6y~=+)wV>)~1Ri;WVWXQjXqy zOS$56@ZpOaw{POzWR9q?-nD%^?oqSf8R8N-jAFyX)U)TK$i;;wV6u-gWtww8y?=yV zL<>AzYP1A5fhF%r?vmDLZlG}5awwgJ0JZdmA8PG11`$qETKuxG)J{}OjDx$mw6H8; zgwVB-&;52*Zr$2txxE(k`N+-az(AUvKa&JvyBH+!Xh8H;N96d%PB50_bn_TXPKMY)p`RT|8H^;weY3} zTrzE2)Ea}w$SuR}~l{!gTM6sD(-Z%>BZ6_PBjv=j5cq!``uE)Ixh z$n6|%1r4^&a^3eVtWr-xhVGtUZ=bQ>e0Ug$UT?8!2H%R&#}c~La}&|nET7s{EMylnV{)!?2H!adNMhlVcW%`cGQyY9k! zCQvTiL~YPNA`OU0D#GN;(SKDGB&=dlG&q#PPfh$4xO7zc1)CVTRuV3Q1iF=dVyN_j^i5OJ44RPLuEa5fTBSM~oiBTB9xupo1m)#d>Hp zAp+6ybWx8V3d;R*_7EBhZ=c%S=CCt+R5qt5k4V5{%@!APWmvt`v?FS2b3@GcEqhvB zovZgQ4{BE5hhHr%xw#ln_N#6r_?Im*>6(#kZMT0*T>iuyIl!S}31UKji0yp?2qJZ` zD1WMjt@;Qc7{LFG%gpTTjk4=B-y>>U1=fCUJ+6~wLPMd0g`j#tLs{t;j%x9lSAD!Bgi0j^zGZPuKhPGOQJHi z;B`u+yL4N&rLH4{#Lj!R`+e3k9s3Z{0$X3!j7<;hpzuBq4Tj%*R4zg6MEEX+*;6q= zS)@#JO6J{&@aFBREqU4(avH4Sf04Fa{*-2yEvWrpb+N% zp~ex9^ZUETlz&5e%i|s9jP2XkSw*$T9s%!{U0k)YiMHYM7LS9bXUMpAP~YfRUI%J7 zZybpH8) zK-@+9{}?d?uvmvGTgeH|-qC5whaVrmfCCeIcWJd6HV z?%f1gSg4v>H{^w~?m$lEbUR@!v71mxc3n2!vTE~|dQ#61@J5b*n$>vZLF(@P)>G`P z(dswq_DlaT{!RV)$483@-zRc1Pe=d|Hh6l~#!}H7J1`-pc5P1#rbEd;)O4R&T#s(wWF9R<#Ksmi-0irG9bVn;%K<@;f3>|KUaJb1d}z!c z{_+c4;%p@loVeJka+}6uZb+*@HVhL@ND*K%yiZiR`+7RFW^*bVk?96M-$zne=p=&B(cnFO zT1&}PjPYfIKR~4vmi&Vpi*%6L_O{TR77HsNUGfiQwR&V zj%N&vV}|qin9Z_nr-c6PGGv<$8xtwxXpkh?dy@5a+vGfeDrw}mKBff0c9XU~*vBk= zo@;(d-m3O{5u;3Dp=4MZ-M8+upzmTW`X9?|KJs&@otuJu?6q$H*qn!40(yttpY$5V z4kq}<&RYgz1o{GTW}R;io!Xdx*XIKpd(oHSIBAP^R*FaM z1lRZzw>AF^G!vc%Fzr&@fA9DGuE?CXY{5HZ?CSVj8Cq-lJj|yT^4~%w)wUx;FnJ|y1uc(VD#qon18XV_68vw z_D)!wT_Lht2Op!G5Iww~mNQPS;>aw5Zspqm3gsX4*;N?ikXLs{?))2sfWM*F-;P_L zBQhGeV_IKd|MpstnN(-?daYzH7cwD>n3rWPdU$X@jh=`^+g!UnQFbxoykd}uURuX*adVGdN_xuUr&TS-v(wsE2M_J}kV|Jd{F8N_opk*%Al>tgCopR_w&^SyBz z+GRDps?K9sgSc+%uC%5xZa&5=Hi5uCvcUt8gHz`f28UF8^P3SgS2=lzH$g{p2kiaj z+9|=PaV~DmKT&CT<1E0L|5b0ZN3Vmopr5bWKqFRw3Gh0|NHKV)LM6(ZXOW9i>kz93VwI{mGEDe>1Ms&ull zTL>@cZ;0)*5ZG`|-Dw;XqRE@BE*Ec378X9GTFV)>w9%V3-XRH`nu0lpW>ybFS^Jgl z&PoPa7>Fi@r{)5Ibf(;e-gr_*-*fPG>#w*NkQscfB-hKgTAGCnG&4PG;1@HjViAKW zRHp>5ToaJTr6%;HcJ+pwJ-SBDEDpGGP`C(n?VWSA6g*$L4ld#Iqhg+9>$Cq(*bzu6 zBV`%;z6|qeOGDbz31R?8C22VP+u>SZ(!J&*>6{S@B1K|ESau99?s=U}4?lTTZQ*}Q zYJ(pp_t|Q{uDrTYz=lE?;AxMbi5y;`yfSkU+f7h5PM+(#k7Z?4oq>162y>Xf7`}Xr z5Gcq9@aTs`-#Pnl^@sN#gq!xlU!BX_2I1vF3D<2o03o|tSs95e8EtW^>7EX+)BZv}+1nd(h~`e!|nF@8}9j_2qQEmJK@Va8Adi=8pYmdV6k&fr+Z7Nz?ePJ&_|bWuN!e65>N; zySnFq(x2Xe?0N1Yth`za_weO;rwQ^E$dU|^OP%npSwB52cr#~N?f-A^ebzuwiBHt-!<){Fg!`?ynrk4jSd9!;8XeU&>u_ z7p;Z%`!CxK^z{?If?gi&dQ3or2on`#S@-IJ;39Hf4Ly@$(Xm4B4~D%7`8sJ@|IZMN zXoAGABgSQ%oJ@Q$G@sF<-Q6ZRqD?+u)`;X_831xQdh}V!oNH(_LRa?hW2*BnQ$(v^ zdhG%c&X9ST2uSWlW#Rg%RASlh6vFB^cbkKPnQE#T98tSN~#6M8JNnVBtXXw8tDHBUh)&q{~m2dq=_fTCLHt(bYGy4&{NEaHnaBGcfD^L zdAzJDD9ug`VkSNxy?~!7QCqP)k`78ZCZ4l)?ys8#0)bmlT1D&f@xQ|=V?yIXC++)O z(e>1)SkImc(7*ms7QdM~C8PkQP0Y!mG1=;q2kW`>3zM6?8r*HTDgs?kV$tyh0I|IC z<|X#TtGd#bVse&{^*hZnt}I%gr?z%@Tw~*5mQ_kV3cM}V(jI}Ez|BqoS`!0j&Zx!b zONo@UlrThtJxnLK4{<(1ZL$?+m$>YV#q{Xp2~8?sPf7H`;maGVjDnk98Sz&O=T|k{ zx0|FRIiebd3w3dV`?`6VkE@m+2PQqKK3WFt+Za)55FSC(inWPcl$q^ZQ8xl)B*xWM zufWL-F9kBC?^O6)1KROF`eM65RUFj9Fmjh;wd3h63mFADFxG7oCMpfW-C!(nEa-HE z0B9ed`>(wTSS9oTXHI@kCB>{zK)LvLExLZ_!w#9Mr5T@vwQ+=E_e59k`fDR2>~aea zF22h8$wj0mYcOg;p?+v+_CbRZv+kO5_o}FUIPrN1cK@|oW3@q5=wsBJ98T=B0?IDW zXZ~^_hNV%;rBQ=LDwdA>WseQR)nbwWIr$(wOu3Mrt4*m z$yfg;2Rd*-dPuXQMLi}kq{I>HAF%-?KaS2*OI#Wx**<9aH5|Wo30EeQcMOQQLZYJ(%RgCQ_5!_3+Rz6Xz=IzDz25fK^SF_W-^Z~AE1VL%*zgZAL}{L99v zkB3;(>JBHPjTdP;_UWvkESGNTc<4ZQy)EUoul)S6m;f)rBHRLyeYr}~@JFk0cE`Wa zC`ZAi@27Gl@ z;+t3fUVA&sXCb|w#=y)dy0jlY$OATcvOiyHbfIi%**y9w7zl=R5B^-tLQWrlwwcf* zQ5Y|_&l3MMo|gg8@#I2f1Ws_DuvXtAc@?J$M7?*d zF?1pH``)gcnM=IU#6@m2kFfo!WHZo-(KY9tKE>Rp1kBf9u?jED-V@5;q)_}NksnY} zAj16F8QhMje_Hj;Vc1Xuo)7au4?$_)A1^Do>5F~ya@qbc%?VeBe`n_?wLg|ONkn|A z>BAQCHYS$G$qup%-XdQZZ*qKU%(5WyADL2~WH1@}>6FJ-6u!C7mXz-g*SW=(9G<~5 zcHT~wDj)^oG2VGkdl%e!cn%%`4s0+ntMLAAr+yf_KlQ@EY4y$TJQuECuw4;UFe^Kf zL@DLw{w&UGusg4WWHWPM{LkN9d|LZVFr`2U_Vaf6WC&_z-U6Zi8kuU>4>tH35a^`+ zco>sS4NJe6-Hv)|W~9=(i863;&zv=epbp}x`AeF_?A-;x&#t?Ey4J(R%bR8qypZUp zp4PoU0icCf!0GPvy`FX2Q=FHNy`Qy)AYY%^`nM~{1cGNuNbU0XZ|lp&#`<9$`m$yp zRF`FlO#zkGjqcVr@!hW#E@SzP3kZtAvxAd6f^Q4j7u#m;A55Y^A}L|Yb)A#*+Gjc$ z@F3bYmQwBVk6d3?R`20{9+OQhhwE^E2`t?`BkKnoMB&!W(Hg505 z59g;AaibhOd$%%&d33d5FSyBd~{2m zJdr7P6af&D-k(~(D6|Z2p68xqluz=I(u4X$G_CC1L2o?9n*lwf&pWlqS zrrK?1aLml=H^xPEU6fWk&HN9pk_KWPzTTD+vh`molNw_A-1hC$UjGaSD{Dp>V1tZv zc5&9vxFPFs+&FvE=Pr$zXefSaN~UypcWOmMy=~OPCqW=qeqWG=(L}j8GJ5Hxt*$4Y z4sDUNC;eR4vi_-Rf?L=D2lzLUo`FGR>v4w^LQHmdH^^B~N*o}sksLKik z#h~`~V|#B_CpwmisGi|iYkv9NM}~wHt)0UC+AYUBuQJ}T!5Dzdtb~J;Hb2Cyn(`mUAPil`hg;gT;lZ=5+=kgyew$}zySZ(GNaF`Vf#8-ky#SvzdzS5a|ooJE5 z+p6$<>3diX%|0NhU-AdrYyUkta(~FLNr4Qg_rAS7y$wqBb~))_^o-^9`jn0g9;Ipf z+eiDq+3bHS>V7Xxl8%ZFM)iC?P#+!Y`Lq-sg+nj>!|aL}QyJx`b#qm~{Dja>{{Z>O z&gG+&qvoLL#O$Pu>mq`m0r^pshDVB^snhluUaiN*^J%YycEqP|CmH1uUfg$pTx>3%UGeE4@N6` z>Gz9UXDyOHqzLyL~DF*DKQoxf|4}dkKSovzoVheX#YZY288FBuiI?&*oKq zKN}x9!i#PsCnpc}*w2*K|1m!I-+V!`nXv@`bo{BBb{q>etfH65G<$}DK3-b4t%+<# zgB&ijQa;?z=phfMG<09QU<%}Pl*hTLC&ff_@3^EeM3_dVaq93Go-773bp2$XSB0Cj zNYz~)i3ez}&d)F|1h9bZzimKU?z8B8K3r>9P(*yz3KqD6KKM0k@5AYB+shj1itj)* z1mfO#K_G)VRWNU{Mw^m+kmU`#;jZUa41_Y%%)f!w5Bbo4=XWztNW= zZW%s*aH9*7;K5*343TOrfzg^iGOgkBVwVud;C3WEk z@4)Q{kth)x%+C5Bp7o#Ax-RuyS~jm-r^%7(v~}L_%@o!`hs8ar{7zP?HxZJT$b{;x zrzYuT zDtbs8?>t*Q+CxPz`?S-t$Fz~cm|v6F`lu75LQ)(b{eu;9kSaZ{{SH8|nEvPUrv`W%uginL{uC zk6jXk-nc{+MN$ z`-~=!cTCJg$Kf>_1Jn<9jb*EtVtug8vx&U(E$*`GZHW42feW6c9^mJ2t=wSVaM!0OOZ-_!x9(7B zsmZAy6OV`=Ed7wLgGfiiJMeqaP<$lGAzCMyuSPsDMdR86w zr_*Jq8PI9!ZA=sPxE!`Z)+gIUSP6GYPdjFO(%7+z8#&C=O>gw^DQf>pupMREAUfZ( zXcM(Og#}$@y!IuPA5a9d!$Itn`_K8&l=qXAY@?XpKjqojlH5v{KM7ZO?xUPuzH)95 zCMqNjx??;@Ix+O0hW2V6cg^x&#~swqI}l{aj~>i_C&PaS4rIVF<6W@Tug-fMRA7>4Xv(yQARY!@MxrGd zbDX-XmI6+!p>rYyO*MgOK7n&}&B?Dnp`DGA(jqM#zybcm9^S-0{>1*}1g)L52++#{ z<;HrXHS=e>rhTzY7wzS?X)_V(gH!HCxk!PhxwaLTQY#) z!!Hg*p04W7k|e3A#I%&r?;GBfIXSWla>J%ZIU@NNx@aWj(wE4pQSN`UbarOTzF;%D!;DZ=anK*3q_c#he2E<{quf9#Z)ptrno^yNZ1ND*z2zLF$`JZaslRjI9&}>%+B8 z>#E;57#<$tM7e6kRMPXjFZG|?M?y#k49_$(ibw(=)>wkd_Su>-wvT!QFrLsV>T06( zl*v7(>0vU!Ohqe8+6oqYi;uTB(MaOPh@F|Fx2;7i52bK~SO6g}BL`w2OhPQl06FS-$`RU`I}uaY*7 zi~fm;(qia815ZgBr9cl3>{Cm+lt4EB^kS6-ROJo0JV47emWK@a&#OR=YyQs_fr|w` z0x;`FqEmuKNaa6T%d6@a|Gz!=|LZZH|J&;xu<<%ZvR~WfL_olwnv%9+jl6Z({{e1! Bw8sDd diff --git a/docs/docs_screenshots/test/message_list/goldens/macos/message_list_view.png b/docs/docs_screenshots/test/message_list/goldens/macos/message_list_view.png index e04384e5fe61dc63340ca5c70feb78aac697bdbe..a659c591cf421ad3d9e5b06e6493707d8b4cd878 100644 GIT binary patch literal 48306 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

Dmv#E?SD^ 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 literal 48232 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

^q&PZVzTFC6Uk)G~&E=(S^x#<`SgH5db9#}7} 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 z z%EvT+rxs!7z%{w|Z>C7hV_olKumWCJGwqkS^%=juKpv*b7qTQx3AkIJpIF+wtn^&Z zwOx~L!`Hc~r#1`Eu+&J_Az!|tKeBoL`GDgCZFV+V4ZNnA+oaQnVgr<&uV>#i_T7W; zP4AitewXhiDxb(DV;}29$Ye*63rrin1aPAFD*op)a-s|9tz0idwE&xD1{HGNi>!LV z^A*5*rKYnGZ>^e?IBS&QY*3uM49n0nkb}td3bmzYpV|elag&5 z{Aj`Z){P&!@0*Z=MOXsMYVn#FpK`K4KXB@kpL9fw)8n5h<*A8R;z$(04@W%i?i({u zQMr-$6wmf=8h8&C3tbo3`88gx_~??RQ1OhJ%!bbR6*x}V1;=i>PREpvTRPO*+o@Xc z>FRwLob8MC_R6|A4bwuyrDV@_pUr(LcCRvG)~#O%Ia;{5gBbM)f|2}65~%j%>UKh* z(gU~Pasq(Wz$B^`ASNqOP23#TgPxNN1h|FnFHRZ=%#GNS%4YWpQD0xN>8z45jTKqb zp>f;I??*R&8RO2y4l3>zjFkZ94baa=sDqEM7&%-wBS=6PlNa)4&wpt4azRl>hF+-7 zr5N>t=H0t@j+b(x^4@ABi@=pr%}E*{4xTiBPLeP#n0Gfj3KjMT{zM@bW{4tvGMm38#iKVN_A2gHvMpD4pE1tjJ9x37w6)nmi8-n~n zoIS^VCHR})Yc6rwlaRF4Sh1mBC2BFMB#Ng`9i;#Q!ocNuoD+53+%N|4SE8cuUA(Ox zKbxbga~49_@xpMw_Jnw2P^Z6@wg9YFs-(maXc{5=LM8JU?!vBDc`8%_seL+>G{@AuQZabjr7oIC8$ocBh505k{0*(&T2 z!72dl#~ZM8Ad!*)_x$-ou`hNMaLS@PZSxFhDEP!Kwg||Nb$e7JZ7Yeni%auy)SR z;{~*QzU|m!0(nM$$alkm0|bDKF<->6o=){H<~e;%2UsTht^vu%+H_8_+7*%cyYzdM z$TcxQv-ifb}tZ%|GPo|`KA9tdi*d;cVdvR-MPT}9QUe**QdMD<;M zlPCib7>Bahci)5|C+(KCsVH$X`fgXm`XK8Zaj(s}Vmo6KD{%rpwp=)5Y1Z4w2l&Z> zy80Ga$-SqsTZ;oOk;N{?h~!s|5Kck1k$kJhDYC7q9o0TPIr%aOO+Riz3U9)B z7%54BkZ+!8nAz|BIYRS1UGQ;R-BWbE2q8gpyiOhBDjAgh_yp&(>e->7n81(&j3zBA`o)Ek(<*yL0a32sT1nh?P4SsZ7tn zlDChvV(93g1>GltvA$W?X>JbKR;zs03~x#wlDIC{R#pzxE`q#ZQcfN*0ZqjO=1`T> zHkw7;mD&+v`VAodKLAnM_{*8h{1b6@ad|ao<$|I|4HPd#n&zt&Jlbm5WM-97j>Tfm*UsK_EE`M)-H1xnR;57EHh=X!?t4Dxs0t6w(0nYlY#~9;e|aB27UeWSdvlaQurwt74tN zeC_muUY)@5HX+yGW?HJ3U%9*Th*U`@7b=I#FWf(jG+9u|uqrBggC12Sjj3{;AKBl= zChgDjbFAhCvnKOxfY_&Wk;BcgQ4x8>wEfZpT=fFuCFKI3w|NeSKRQU9u+DnXSK(O> zfYxi{bMPnsWds5EVN~^6Ok$vNX4QhRuqur!w}Eguo$)i1G3}#|Dh@|FrP?~x9kepM za|Di$blJClAALsmtgjj!rC(yo;2;@5Lg??dB4^$_MI4D+enmuOQXe5kfiRh5&lf2 z=-u|l@=WP0w%96VI}r;(kzmVg)d3?2p`&e`6-S)szjFE{NgeZ%B|k}>(O#zGZR{$u zZ~{hxg#)OqvK^K^b$jf;^rj(PUow3DAUePq+-#cg?!786Cb@==ZcK{Kjc7f6M6&obgZk2PedVAcu$#c z`S_2zIwmVxR`zk1Atvm0bg+i%(Z@dfopJhvUbjpBK{RD0{YZH++yDDswW$gQtNE3a z<1?t`)!`V6x^~UY_IR8~BbV7+*({^Rr>efY;^4%GqPYfjIBd=HeY49?nPBsgJtjXD z>1@06lZL45Er(5hCJ2P{gW~#?Rgw=f8DesKnX1|rwM3zHiWNBihX-+~squvho_nc^ZA{cG#4Uon|)J_u_I7|b`D zZc003v~`R5&-`=Bdo~L~=KqOaOoAbR$#U!dV$|gNB+oaf>3KEpKbyVu*}Jg~4d35t zuV3qEwi>3Y0CF`JwcK6pHLArfMVhhc2?2PQH-2*d7;b!#sa924zbisRL#JTS5;@cR z5xg zagF-`LCDtDVO?%1T5M0E4-?zp!PtHm5VuYxQ%H*VTc7!$Yx&?+))h=ODZ4Me_J50V zi)S|2SFSyucNeH1>=lf_)j{;>+-31#8x5N93J1e$6RiChIXGh1UJ2+jFy5zr$jP{E z|I|$6I-5&C5bKBhC#w9f`6z2lVD)T!?QFr7-&vGcN(R=g{v*EM$;fpUeT2(Cg^TU; zGzF26Z(dGbmk2yvNQ7-qNLKLIzuE;apa_AfY}q2sGXEKb=Y7)YjyzC8;^rS{pJNI; z4}rMqDeHb~tS`JVS^56+>Uff@Mxg_x|E>Q@42vAg>GTEfT(&G2#?EGaZj;apl2?^9 zG6E`7rL-ed%(u?OV4P=5>$;C4KgVXudTNi3rfzTOB6k_jS+^U4!yILWPrww?YeQ77N}+SNkey#0^9VMi&@l75 zzlT%Nms=C@LkSWXxScjWg?DzQKDs}^%vQs-zUi<;m_44)SA|@Kp+V-Q+q>j2xD^P` zo}lgqXiI)OiWK%GZpG zbDR0Budbc?mY(R8f`1~r_c;;qaa#%>OWgDO?KUkZ0F|@{&tuKO5z|bwH7g9 zU9)*^y*;t z)P)2&UrJlXZ}H$Kf>Bz?xqjr}HY|xlPhYSGSy~py7@blirbRz(&K?0tEo#B9zyyTz zni_V)fn|)y>K9ohiQ%fNuOl3&?7&r7c7(vEG6XM|zPi>R$N~S(j3ak(kvUZK*4>`J z!Z9Wo|LGUO+e6MeXIv3Gec$6_Y~qreFpnI0(Hyuv3wLtrnqJ-~3K9R(e=RnO3!A0$ zZS#1niUg4TTMwhq|Ix#0%pp#Wj=KBU%I|*Sk_(Mc?HTs!f6$L7CLA-2JrHD6l6F!? z?mJ2!o#Xs=IuK=1V{iKH3tjYC%q|B4n!w>BlFn}lfrU4=e)tga6&=+G_maa76yJlzOtIzWBoN-sy;>*C;@A+xWC9UMDz96A8HRoL1wuEU zrn!32t82L}SdWDjC;;VmM8I`>5O8#$1jh_`TqO(Nst3$fBgNjQ`!#McDqZ@3qy#K( zgbpD+3v*U!&ChU-$dlp77jwa5Nqm4~8SB2qtDYPoECl1dMLmm+VcBxXnJHVl_!00k zA&x>paZdB#{YAxK^?5o|->8%agdegL`0wD8>m~(@#`*MSI<&SBWQygUy;zd#Olp$C zGE3PttKuW;*iwo>I2x2{X(#m z#Coy|Tz3T}2YMgdQ1kBQUadDYG9R;*)uYIGH5PgZB@ee6RBF$H3TnXb_izh26WEit z;YA+StY5mk>ji~e5gk(h$H{?q5$)IRX+MiW8dnQ2z3m4l+fH||3a+&z0ofAh+PHf% z#OGc)sH~+x=CxOZUs5q-5(DPCCB&Dax=!MR?3Q|`8s~l6>3U{gO=>(om?c2ui?vw!J-G9&fvctywH@Oai>v`XbaV=2{0LW}i-zA(jkF?+Rw z9bHgT_c&8(@*FPWhiU}mn`a{|e+G|?2_YOd(W`Sl4Ow-D6|;QyQx2lbho#(LPS9wU zHCBB?ipLzi_cdg}8>vS!_$gcAtny#XO0_?Y*U~4qoSAR)Qc>reFUE6nL=JOHN){Ji zS=J_P_q$(D_v#CgdU(vBo7$ZR^vVXejNbGz|lff%Ri>ja#!FHs_%gfDWF}=W%(# zVKh2`Z>g1(!{@f!{c?KXIIiMai9fmQ{YhdE57Ve-bSy`i)IlSBo1qGm)xZb;K*q7| zxN2{zETFmh!`1or>ap-W(g@o;<5@67`9CD7j7p|-OY#{{m0(Z-=d; z`z>RRjxHK{{EA(91^X!eJ~SK%P1X+6g9*(cp*ukY>I&h1P6doDXG8kNz-nJfQ{!(h zafzrm<<>vNW)@Oqh)C8brR6m5RE*Ezxy@Bhn+joi>Vkx173i@&4&0GFP~n|pcRllY zWHUy)&Gd@6f+!FnWz9-gwjsgm-G_T^^L@#WtLG5W>iYVUA8l|UAzi+b5rdRWR zNp$#bRkl1I4Ad8D#WsuK+uA(PdQS|Nt@sSMm1)mtHV8}v7VD+>xa-`*8uxVX^OvlR zH^&bT%y+0+pS*as5&aLct{fVQ?ISBUb?9b{oZJEozDaIJ6>t50462MhXW>R~_;yRi z(>2r7w<3&far5dr4Q6;?P(@3Co=%POJ+tLKm{u#|c{ad9QlIW;Tw>M?nskifXYU(B z9X}R7JA(%%b&)pomdg1R@SglxDEVrlzpdaRgO|_v^XJ<(biU)4fltGd*TbO7)p#ibXK6-O#`Ws;u(GKEp7c+; z=`)7QPWJTnN-ygnuxjk>^z`JhY`Lf=fjLzxuBUqL<*Zbgu=$Ohee|jHm{z-{+s@}2 zx_%|D(pq4%GiP8>R*>m_OH11kGPn8H3Awbtxgd(z&`$+*7+O_pB)zh-jdF5xQ(HRU z%(<-WCBNG4|C=3Cq)=Q;O<9VjASZ6YBd8I+G?K@{r!ZOD8j*i?dk+n-yw1)h!yAre z!IY$wZZBKx>=+$NpNDo$Xu+p7iFj*f=6lErVqpiWYiMo9!{~%~vvZt?Ip>|V5RbMu zZ`AY`xF&u)whfcb-dM}HC2@R&)^Em9Fj)wioW_BE2O$%H=JSzIMn--;QsBU5G-Rlx z;o5;;;tVP+0J%UbOP)-SR+l87dbxQuPDVmnlUr|^xJpLs#<_Pfl3eF}5GZ+q%uo69 z3ihRX8YHBa_>jwmpsB<0e4$q2fEniL!GS#!ki{0a+S=Os(_ThU`dndRYRWb3O}BXY zt|2(wL7I`N+jw9!kh@@>o1WQibpc1H^C1?C?@D-Vp1x>?EhyLvLhi1wQJF|Lr%%x?e?qkY!Z?Wark>I@(d=`YrUrMz3N52+UV(DYP; z|IbU@=Y^W@39?2G(<|E}!je~b<)77{g|aK!j$dIC^bYjwjMwTY27ldyA#IPBvL_MK zHI{@<8~x}qndVUxnGfFrd+R$lrz?E3MZNEHDEhCX6V!|RvfYenUlX7#BCIS_XS9y* z&v`EbJ@09cDB*@L|6;O7uc_KED=*~T3|(n$9gfti@jN(H~qT^8PDXHKL z6=24fnQeQPb8x7q;v$=3F|c%X?(!SOxZ#n5`MNN<=OplIpOO&`eLZuJ)+;U>P2rL} z0)*js_m4RzX) z1F`IDcKf9d;P{7p(J??beW%PnK+O6a_^AV42|%Ljjj_PAZbNfIq#nGhtuI)I!XqU5 zdnEogcR`#%0_)0YUM!hus*9ucr|`0t)S9i#|5$t>ZFHCPOdBA@2;Fly`? z8pyGjUHR_LNG(I(&(E(C2Z#F28-Eb2nhE;0w7wn~3=`O=ps1;>1#O{NEK`BHCI!_d zptsc4nL7gm!#ft1x3}Z;qhn)yE;~e)+uJ|m;`B!OtMJ3tCb|qd$GXa>4B1Jw8k~js zw6qX$sC?_l+oLWC%T(RUW(l=JW$jPNGyiZ7I4*;9hAk@bXYsDs?5Ia{zB;)g&(bp0BgbEntrX1sn3KSmVj&&|OUK;)|EYfhcA5duC#8M~T{dLfhJeNF^6KcR)$9S^Srz7jk4~vK<*K zgGkWNch?&QPwG8fBU9c!^ok#PMg~2ra=B_iW9aR>a2m0}-~A37hXZ%~Vp0Ww^u}XS zNj)bV*|@sF^YYPWD9wiOT@Ld|xp#JgNtOHlISy9gauhXat=EbcS)ZrlUEQv6DLvpO zGZK|0Jd0&N^=`_RJY=y?SlnI#EsBcx_=cZ-J2Ln&enc+Rqjy2C{VS-ZFhcd1j0m}# zZI+PyyU4`(MQfi52Mf$G4T093es?5eGZVDk-*-9gh6v;dtb8}94xQ^iHOtEZH%CP8 zdLM9kzF&I4P`Uj8#xUA6}F@&~rmS&CB#rB^D zL3{g8gX7SN;axvO;bDt09fL^+k6+8z)~@iTUrXFncpC#f($wDb49c;_td{@xxR0Ip zDNbKP9*(TOU0q*YG;E~CQVE%_PdhF@c75EDl~Bi8K$RfB^k9qEA#+0A#0@_w0VZ+g zK*s6(--2)>-Ud%{IQdMfwCt$50>w;}O|`-3)xD!lgdG@zFLX8RvGsxOQV@RPT9XxtPTROnHVEQg~}lXfR1cfHC&Z6!V{SL4C~8 zO<7e+O1YcWa*vwxa$H^WKmt-qdYN+#+L{VEQYZ~xtJ z&QQmScl7;TR%`~R?f?qt%32i>+cl|QVEuc`%M`=C_vSHvSUb<_?!03u{J$~f=2%HN zigD82cji3P!g8~ODxM>Z`dE=zxq|Bs6#Bq{3XLfpLb`k2q+TdL(nRXEwX)1W(r^4v=DfC^h zt6K-!Dn`0k=o!`y{fN#FrbF~g6yui2BJzzEfQKz7U|fQuExweWce}*+ciMCt^0?TR zY$8%Y&*RBR#+aKOEq8Eg85!@da+rcUvN2%$xlpFo4$Y(1CJimi$8?bt8{K|H0HvNa zJ8Bu(YPSX@ZWQYnSJpJUsCR9JEI_8&wc-=8!%uK5)}Innh+4p;Keka1TP6EgK6_dN zPEkQJ%P;(tlU+d#Mf7|v0R! z1`U_o2vzrMxwyhwTHli|_-*JvTiG!r^1HTx8R$?YBI30lPH$uVZv=Z~<=!zc{eI0l z`N&2h{@+xYor2;_O+zhWnn>GbDSz+cT>j{T;32m!xsa{Bx4x~^V~@n}amp8&s(Bx6 zCVHR$nHLf~Iz4V}8^eJTD9#B9ewGe(M;5`i?VXU#fI7_sg*w~rZ#moMs@^4z(LHLV zH7nD6Ps;F~6gQDf6HotN-wWJ09BK8R2`Wk%QU>}#aI3r-Tku9f#^I@S%11L8lML)R z&a%X#QkQf{Ll6Jo5AAv<#orPv2UP)zbqlMqlph866f)`|?A)NivPx z<%h^WzYlFBwf^eHtT83`zYHAk?#$#)yZ0}L3#*#Gq15~k$_Ve10a7&?nbf>E_``=A lVYU3Zz%>1T_u|aE!Ci$5Cr|39@ym*@Zh diff --git a/docs/docs_screenshots/test/theming/goldens/macos/theming_default.png b/docs/docs_screenshots/test/theming/goldens/macos/theming_default.png index 600e53a658e9fde71f04a28a56ba74eae4281f94..4cd6f3052171865e15948eddf6802b76d8975b08 100644 GIT binary patch delta 40001 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%0AEjCoy7fM?~z@x9Yyq72TJCHp(|&PI>p>wT2SM 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�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 diff --git a/docs/docs_screenshots/test/theming/goldens/macos/theming_red.png b/docs/docs_screenshots/test/theming/goldens/macos/theming_red.png index 30d11ee982aab45695d963e9f80ac8081401ca5e..f22015ea426c5b40e91cf9053b379271bd0bca14 100644 GIT binary patch delta 41349 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 literal 19878 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 diff --git a/docs/docs_screenshots/test/message_input/goldens/macos/autocomplete_trigger_emoji.png b/docs/docs_screenshots/test/message_input/goldens/macos/autocomplete_trigger_emoji.png index c7dead56fafca84c9e210cf6f2a4435eb1de57de..525b32b3ec26a4a002367b145b39b6d04cdfb528 100644 GIT binary patch literal 18460 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 literal 18454 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 xAcl#6v9HLNnQv93hab?!#F}3q%Ox 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 diff --git a/docs/docs_screenshots/test/message_input/goldens/macos/autocomplete_trigger_mention_types.png b/docs/docs_screenshots/test/message_input/goldens/macos/autocomplete_trigger_mention_types.png index 4d0082b9ed45da1a082c87d01941841b5b648160..b565a29182daaa95cdd0364665c12484da80095d 100644 GIT binary patch literal 25968 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ʣ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�w(Vx@_S+L81RTh@ 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 diff --git a/docs/docs_screenshots/test/message_input/goldens/macos/message_composer_input_header.png b/docs/docs_screenshots/test/message_input/goldens/macos/message_composer_input_header.png index 0d29871c8f9357ecbce5f4ca6bfc36b4d0c7f364..29b919b966ce903a40b4120fcf5317ed31816fe0 100644 GIT binary patch delta 8761 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 R89dxaO<7B+O3~`${{X4d-zfk9 delta 8777 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 diff --git a/docs/docs_screenshots/test/message_input/goldens/macos/message_input.png b/docs/docs_screenshots/test/message_input/goldens/macos/message_input.png index 65ce0b64e03860b730b367953f95fb062800eb48..fb8d13dac2f5c24aec5a2fbd8e61b3ce1a3161c5 100644 GIT binary patch literal 4919 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 IhMvj)2KI)!ivR!s literal 4920 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 TNAqV$UrdI2X1dint_lAEoIJ6F diff --git a/docs/docs_screenshots/test/message_input/goldens/macos/message_input_change_position.png b/docs/docs_screenshots/test/message_input/goldens/macos/message_input_change_position.png index ee7a9ba43dc0411e0b8fb40b14463ea4b79f69c6..a35f60b2cbae8d6d130da6af3539fcbb28738962 100644 GIT binary patch delta 6731 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 delta 6742 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 diff --git a/docs/docs_screenshots/test/message_input/goldens/macos/message_input_custom_buttons.png b/docs/docs_screenshots/test/message_input/goldens/macos/message_input_custom_buttons.png index 811e1a45801083209202f4ee11f300f3ff04611c..4b0f0b5a765f927c1b59fd6e90992465648d402c 100644 GIT binary patch delta 5455 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 FV1g+a?lb@Z delta 5435 zcmV-B6~yY#Ezd2G$&(-f7?U6tN)~tUSawVIK?os)%7Ww!RUw23JTfgKlNDdnYCqcg?=#vP26CvzZ@GZ93VI3})n@WontIdwJ z#(_R07?V*?NU#o_PDij#OR!FdMibN$f87&8_{ih&;&i!ix|D%ht<#0oX2)LZ#AFD? zWHb;FW<;mcwscqP@p$3OeemXHShFA8p7VRWRs*B^z@%X?vL^(!P=qymxVzmRipwe~ zud-k^88Dj+gc%KJwK78_#BYJy?ZINJq1sx5#a2U9xS80f@D|SiyA$TEgZb+rf3HHF zI@?9V!`HwQ*QrzA`DnIq_jtXOmRC_)QH|MTAU-;R;NV})tdJ0*1=KoS6qi*{ZM72{ z6;5=7xkX;BuSkKZA3#>Af9mfP5A*({jOd$7vxIxC(?wQZ5uqW$w2Fx&G$h#HO$s3{ zAa+MBMWq$gI$b2Ti6^9)27WnZe=zP%*qq)h%`vhUymvpunf>3E-^1Nj;~=M?nAWjT zM3_zfY)S}mfvc>xQczM(`-C`*`cS{N_5CrpVIGuP{Mt+d36ZdB3S5%p-*)^O?iE#5 z3QL>k7bS!U4AvSux%nluj`QDuaPhZr{}OPy{Zjooh3MejiE#U6{%gZ;f8kzHWu>^R zf(~t4HQP%pAw*zs)H=z|DH5*iXrVw-phi_598*Q!?UhBUZ$k!scXY~o^ApXQ&sRS$Qk%S}#xG3{E%O0Wwd znk+OVn6|BB$jL9pslxn8e`+q=^y>MqTlXio2X1){4&|v|x2oap@p#G3D39Mc7K z7n%^_*D1_sAUe`ac3u&_%pkixaMLSbb*S1sRaDg|0k8Ixj;i5aTwX~~P!KVZ;c8YZ zg!m1MjS5E-6hv`ZWs~c8bv@(JSL~D4rS@1+QJQB z3{k({MO(nB(%O4ff5N@WY9q{KkZlEo5DgqSaFC_TK4R_K4OlEqpLYli3C3j5Q)RU^ z`Y|8vQ1>G09Rs0qq4H*V12X=pd`>MDHu!XxI(4bCRpl@n2~CWji~UjMwMUmZIhZgf2*7N!Lmup$ER0jc8r6i ze}PIHtlqCqJBz=C+b;FJ9-l|J!g2xn8r;fW>BS)UwFJD%g6Y$xSuz`grC2iWD&3ue^P>TiLJul{?jI zXKkuF*9d$bf4Ns%YcS|T&}f?eJhAz^oqYJ|ItKLZ!9920c-Ar{Wfe^O`vL$K{;TQ# zIfM}Y<#xMy@^91l_~TFM)vE^|ez1gyhzRZiwr@`%C1p1jiEbaC4}%BkH^E)PfzEA4_45C4RaMmhg!piM z&TKMZ|CyZlv0a%>ZsM$hf|O;ImLH9(D{G+K25N6Xuf`LT&*AQLxzUHJciDLR?gI@z z=k_pA50 z{RfZ!;$v2?-^#XKsT7x#(=o9PR}URXzu$GMe^(|g{WvSW*g!#1DF%Hgy?b_H?3j^t zPZo|^C(Bl>A@$%u=jx#Y8Fpp= zdTkv#a)K|{earF8Tnze9#*7-yk>goZR95r&19#Pxv(?!7WYtFY9XLXb-ND6Oley^+ ze?w`Tpz>=xA^gni_454m*}V7Oa=LWs%*+|ja?ib!u~@9U^wKQ8ShbqB-d;j-auTy< zP4lTOtyY7}b9dcAz~ z**bRaJ=mbF?A!td_U}daE*<&c)34aQKb_LDGY2zzJYHUXb2;Dd*hlB&_6+Rbe~ZIM zGx_Ih?^0E*;%#a|_?g%1<@x7l*IhiFGyD0vVE_A^>11YR@#dS0Nls4UlTVfs73JIg zFj}pqQ6u-_YM+{EQAOu}uT}#-hr7$^Qte>dfdhJ>(P-HG-OjqtRaIL_Kbpzl%lkFB zXj@rjVeQx7)9d2SJoU%~ZXYv(e`!-EV$g@O{FAkH<@Tj1m&_+kxP=kJF6W**Z{*Ln z{(<&wTEVI5lS4;N(Cwm*-0{b288u=sPd+@JtA|{M)pllrt#y11V{abGgZGW)wwp%q z)RcRa`VXABB>&m!O?W&Wo_zRj?jCzR6UW`m$Xum_SZk-aMZGP<9Dk3JcaN#uh+}W7yiMb#qW`voW$IhW-9VX)pNHrdFfH)rfFcW5vk}H-mdI^hrG3cEd8Kr`s>@tdyNH z!uNJ78o!kPXZfDWLF&yde;f3A`u6I|wv<#{ZsnJ^b=w{Qh7P)6c%VbFz@Ah;aUR{qITc(6+9<8?GI~kSi{sxU`&%%v`c_^8qL;f3K|9r}k}I(eBg} z2SCs6oiP7oWx(-F<#ku<_}IF>pZ=bY9M4wg2P%Z0&7c1|Z@smc4vFoVJ9jpdCQqTH zq?G5UJw;Jr5&vEACLI#nvtZ#o9(eFEQd852iH`QUT`%Vjogfu1a>kjJi=`6=D=TDT z!XPo`%-56SAj+hCf9>u;O4*KazPGE!c-iMUcb!&?%k3saqt4##!v_yw*S16#}qk!*{IN&~UU{R#8c8bR_-zTugRu0UNjM;GOqB10cCW zTkgE|5435m{3af_?{?l<`Z?=1ZDZZ0ZG?t~aP?J});$3Lf9%+GfcHOMjq@k-eLvpJ z$ZD&huTgwuqm|u%9f^B ze*h*8gCX4@e?1?1wS%vw!k=DOzW%{v<^9n@7~EC)_^VXk+5|AGuw%OK;jU9&BB^yS zM{-g-q9V*}+_Hm+@Gz<^R>s~u@~mZJqLsP3N#k!JIjLcwhMCTcmTw+CoExqk!tu-; zw(U%1+s;(x&i^0t=1c{kZ9+WHPn}3vc_pcbjL1lT?EOc{?CmV66yZ&&VI z-FWbqYHXZ%6?RScIYmy7+|@Mn$^m5MB<>!2Jp=mof573W#bU8xvDn!1!){LI7ZDv5!H_F1 z;mL=U+tIRel&P1@9Aye<*x&*5>)oB`$Z)DGR%-0^H?HW>tuvKX7Cu?Eky@t{TaBG} zmVVY?&i!=XvvTt5^?iTZQ4Sx=QuXI4gg>OGE7zK$qoYVoP2-wthU4*gc=_e|BqX%v zfAxj)cx1|xWMpJA@xJk@1Usiz=;?Ilj;>zqd~OPh9iCsQd_4Cyn6nB#*{ST{XtBfg z<1lR{%(+D=^YjXEoO>b9IrV5bRy}X3jNI*xTEfHB+goPPWxea>zK0LK^k+x1@v$-V z=$6c;tvj(hYU$Fc1KGI+Y}%Sa=Z@_ee?C~*pdlmcB&*kNWq;aH23^*hippyCrXD6b zGMun5BehN^AAY(HtwzHwH(pI#Oca~8rU1~hTPFaL+ACqacH{Si1nY3R+^kyrO@ls- z89j_cM^CWfo9*@1=0`_{*SlqUK;Is$UjH4hFImCJ;g=I18_mwW2T4mm&JEWNe^Kpc zDTKeYYkwwzVq;@izy531um76Z*ccWrn8%}!JyjR%)2BbJO0Wai9Zq!Gb4S-DNy_#B zzM8WNM)!e%onYn|$SQ?z4l7^l*8%4IQTce|LHO4i-`fM|pX7TT+8Hxu%Viq%-*qFupoDz~j<9=wI+@vd^z7c5`^Vi(@TsYyjvd-iS!H48-h-s`_L(=9pUCMdiU(g_&cs=PwHW6Yn}Xl$YlV81P9Zn zXIGA$$YIysL+m?ngwnD~t{Hk6qel)=D9+r94)$1_hdV%R_;e@^XOS6*4oGqdK? zqgy8)yzlk~k8!!&SgbZ8!oyVkBM`#hCQY8gs#U8=NNCOI(br+KT3Nd6BLF4XpMOf# z|I;p)o1_dF!pkaB7O?g_+NB0QH#y) zAm%K0s-Mf>Z&9`l__b>l4l{02uRhhnU84yiHY$R`f8uhrsuV&901ArBiHnLr(}Yto zB8~9!9e(MSsutW0VJd7paGI)X7h@vLc!9FY3wWFpC@DJ`$UTBE{#n?i`+G^@={Sw%JN6MWxlartCuL2Z6E`$)jf27)4L*~gs;$k9+FsrvA;c0&w2#fB8 zkQN-lhv?wl`<1@h5R4zKr@ zloK%eKkA%UdOqUJu;y`P*Ghl#d$e13T-^iSod^ldaACJu!ktq)GL}_ZC@HVRWY7~I6RFzi zO+ttZQ?1iQVM#eQyMwr>2%;idW@pruyWsKVkXhoN`a8wLzsD*|9-B+Eh5Ko4kB5@- zD#|OX2{Rf9Ga4|P3@y4{un?m8xZNJAf2}qwHaiw;4bhQiVxz)a{CG*bQ`uHv{(5CZ zuZDKf@bES8#C7V_cRrdu+)s14+*DeuSZ#K!H4gM4!I+GCLV|VZbUK1{T7q@DCf$)H zglKslj|ZpAed^7H)9J!uv*W0BVlsqcG8%{o`}wmKT8hUDtM|d{n_$iU^WUpoZ>NP( zz2PrI;o4rb*ugt37VbY~vDv9Pbx?-O<;LlD<8rz1sJ#om5TaRVG(iOGbm+8NbUG~| z!8#23P{NEV-ed1))pppErM&IUh8-DjFt2`@UhR~NqkTIlOD+2(s=JLqQ~hefT?iqB ldSs$ok?}{9AQlo9^#3)r4MS=|9en@*002ovPDHLkV1l*O6?p&v diff --git a/docs/docs_screenshots/test/message_input/goldens/macos/message_input_custom_send_icon.png b/docs/docs_screenshots/test/message_input/goldens/macos/message_input_custom_send_icon.png index ca3617381d2b6ace518a13008057b86485bd4fda..cb4038d36e15992b15fe601bf2be64c2d4fb091f 100644 GIT binary patch delta 4294 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 delta 4273 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 delta 12644 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 IhMvj)2KI)!ivR!s literal 4920 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 TNAqV$UrdI2X1dint_lAEoIJ6F diff --git a/docs/docs_screenshots/test/voice_recording/goldens/macos/voice_recording_attachment.png b/docs/docs_screenshots/test/voice_recording/goldens/macos/voice_recording_attachment.png index 02f2a17c68ccfe824f0c65d71dbd5be9c085c21a..d01acabfcf257f68f3e89726ab88f30c5e2a9df0 100644 GIT binary patch literal 27220 zcmeFZRa9GF_$EvRcPZ`^E5Ub(?K|@2sS5;BaLqmJ!k9vQ?!a)6E_>pl4 zb$RJ6r)q$OdWB%Uk3-!*^VUh?tZBBA6%#Pn@Ax}u?n*nwkiLY>nCNRlb2z(&>V z*}Gh}G?RQC(WNy-;)l1oWKAnt2Y%-J${&bcEPo~Rhc!9664>P0hf^pXF!s<>5Omk} zCo(Cd;_Z15D%-pqOnc;sS$M{oAg9%ashJ7p)YgXGpZrc8SNtJe&}ume+`SVKPo^lg#> zFI|Q50ffh-C+s*NWlgD2(uit}@_X*{;zyncB2F6M`s!x3jK-8;mYwQZ5+xsoVh1}( zOiOd3B{5d?T{o88xA!_xcW=Qdrj0hN-aCB>)-5epeGix2Jx{Bc51^VuF!ZXJMZM4J zSM$@YcKO|ThMla%(&{i8pXh+pxcaU|%cHTyIxg#VF*9RPR36j8x;;`XxmCt zrbkRjAgvFVd^rntF4y2=Nlwj9j*cqTAydyROo<|uN3?0}DRm%t%S zx7IVsRaKIYLoEM-_GH>*R-Tm63d6QfqyeT!g)WPyuPkm8xdJ!c2^)6`yUXu;tRDB& zQbcVCY)6q9(~k+$!f7T!zWFKut*p_^Iq#^2RRQT0($IkTRR;Sb;p)LrZm3#}q5D46 z_6m~5qRi*D8JBU@zG#M&oV_@Ahz4rtL)eHUT9Td)SLhE9UFPc$S$XcZ^-@=ee=Mmx zA7$?2bt>$9CP4nH(B1NaUPFmvZjrT-n;lTbWoKPKk}b@CnQrW;|M8Y)LTX3OUTZCx zg+LDyycE$N%`gSKVY!jKKBFz<))9LU&AWx8q4wFEiuEzb>Y|Jo#!cie9JTf9?IeNRvR z=_!umgO1ov4Q`yG?MlGe#lcfL!`W}x(_dsaa&XtjYi3IMQ+Bqpr6s*GUFb^~L>v9@ zZu#Q`U4K7K(d4Kih1J`@Ky(T#AF4!(_6&YnoJRW#>bkx?YFYx!o%~?(lYj`+hG93V zHS0C}A}%q%Mjsj>anylX4jmiLwup1ey+^i5T#v3j&93j~3A??yLw1Xx{rB--Yv6W? z&WCCBx_1W)1=ov}?9D+J&O8spnPbA2x3?H`HI^@G#~oxOZhXiA*D>n6-BHaG(&>R` z+uq1Uir0B_OWU5tv&h+%=!G=9kme*OAKn$2n`;<>%Uo-#?_po~#z}caRn_)Z=VUWX z%NA`R@bopf`{F9(>_YBx?P(OP=V}%6plM$NZF}+#@53O0OpCdl%h}D2)pL*K!*;%) za}G57-}zdazWCtwJnspy^i=74$`7b7q-HWn$o`{LTK{|gmD6RKXV*8op zSF7hE`i|G|R{v&U_t8!VBIQT=mXm)C!(l6XLY06&vYIw*)7reX(<*Rw>;C*3DcXX= zT5soO3Do3zygi9ZunQi>l~w<(udmQNESP1KE?fiJ7~X7LHcLO9P)f-CrxP z|6(G^bT%GGXEqWW?7x3V5K9_syDwuI3tvUvrOMorp+sh2x=aR*&(#DQ4VuO6a0zY} z-S{~e_|PiSxwi+^HO%y13oOztRT2n1oqz*CiR-mHoe%#0UL#cHjnFzlvCU7B;-M1> zud2}~CH%_Y2R=JJJ-yz}i$1jfwes}gA^nL#xF%|SFt$vH+I}k`6D|L=xrmKH-!L;> zOF9iTzd4y)#{AydRGbWi@A?^z^6sDNY8kR}(|RsE1jZb3M@z^dTRDk$o~^K0d!@#w>z%hwmNhrL3E`bC5pd%dS*U z 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 NU^z9}YH9P3{{y(=0|Nj6 literal 27206 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 z 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 diff --git a/docs/docs_screenshots/test/voice_recording/goldens/macos/voice_recording_attachment_custom.png b/docs/docs_screenshots/test/voice_recording/goldens/macos/voice_recording_attachment_custom.png index 0d4fac648b4c138ad9576bb50ef58802ed935e2a..2cd165f6ca5046ae89403588e5f2c52b4557099a 100644 GIT binary patch literal 27445 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 HwfgWsJB*3} literal 27430 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 z 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 NU^z9}YH9P3{{y(=0|Nj6 literal 27206 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 z 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 diff --git a/docs/docs_screenshots/test/voice_recording/goldens/macos/voice_recording_enabled.png b/docs/docs_screenshots/test/voice_recording/goldens/macos/voice_recording_enabled.png index a3410502f9624cd4ef87bf500f615d3ea634eff9..93b7c24078f91c247fba337738865f37b82c5d26 100644 GIT binary patch delta 5969 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 delta 5970 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 diff --git a/docs/docs_screenshots/test/voice_recording/goldens/macos/voice_recording_finished.png b/docs/docs_screenshots/test/voice_recording/goldens/macos/voice_recording_finished.png index 070492a202a760b6a101bb734ba5a3d1f1f8a454..6e45ec392291027ddb2300f275d1c099f3e20ae3 100644 GIT binary patch delta 61 zcmcbab~9~*J>%wuj7#Mv2Pq`+6z-lV&%hw`-P6S}Wb+nw)}=gkU?N91^T_>Np*U=aH5>EakN`H6he<{*WBA+i7R^|_xo+c|ue PG5~?6tDnm{r-UW|u-_G7 diff --git a/docs/docs_screenshots/test/voice_recording/goldens/macos/voice_recording_idle.png b/docs/docs_screenshots/test/voice_recording/goldens/macos/voice_recording_idle.png index a3410502f9624cd4ef87bf500f615d3ea634eff9..93b7c24078f91c247fba337738865f37b82c5d26 100644 GIT binary patch delta 5969 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 delta 5970 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 diff --git a/packages/stream_chat_flutter/test/src/message_input/goldens/ci/composer_hold_to_record_snackbar.png b/packages/stream_chat_flutter/test/src/message_input/goldens/ci/composer_hold_to_record_snackbar.png index bbad6562b0e5514f481aa425d445a160fa068bc5..02a85bcc1b8b394487675d4bdc8796efc2db27a5 100644 GIT binary patch delta 4166 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 delta 4199 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 Xv`uWU)CFWJfDb(#W9?E+$H)HzmwH3H diff --git a/packages/stream_chat_flutter/test/src/message_input/goldens/ci/message_composer_slow_mode.png b/packages/stream_chat_flutter/test/src/message_input/goldens/ci/message_composer_slow_mode.png index 538a5d1be43ad65232a5604aa4227f168d7faf7b..42aae4206e2131c5c08c9bc9fbc6c5ed6eb28fd2 100644 GIT binary patch literal 2855 zcmbuB`B&2E9>>3^jf{=UR8x*EVwpLmW0_bcqL>?+St=?nm18bRxP}TM(lR=grIAaL zTVXbW!bqd0hFa#9545M~DwrF#ireQ-Xj^=`Vt-X_wR_6-#MQvvc8xC<+jpMdk;T|L1(Ez<9^Pn#FhS)A zbb;f$E5lS>E?%{hDR#WPu=Aqn1!s7UARvD<4FUi?*{Lg=0APMANCo)Ko(uqwbszxQ zSPcw7H2(XN=a*iETpWI06&TYBHCTY_0L`nquT%gB13LgX3)TVbwyCHAI==#-|GAVc zd1f|t!NOS3OWVWl`YJdzkkrThkBjwTHVLeS6HzGqs_x3`08cpIG6@BJNigqw>iok+g+I7b% zggeNcmx)BrqQ*~-sB6;tBPuJZ58kpzq3IopMSX+bqoM1`YUJo&Qv``g3s*+E{0<2V z=xlG)JiiI1C`g#_QYqDUs;q5kTr@-Z#)1xKIJNm{wnf4*gO)f6#>N+nn3*dH-i6A^ zq1Jn&a>T)4AWvd2%Wv#|btP?AT1Fi*F)fLiOU3g;_SVnt!fwidy=s=*PTM37)&>HEfNt|4d4T!_amif8u4-3@&dy3?MI?z zrxpB!Sc0WJ?tm6oAJn*}+KfXB|9qzv*MnK?3wpAf3bV5Z6VObkn9p!0X0}Cgrk7tN z^$j8}R}92e_n+jAOay*MKHqg%uhNpUUAvIZey|jH|C`^W=ghjQi*`sE+QQi$&Rgk+ zV0OHW*1zVOY789Dsq*RKCP>r;ohq;KEN&TZ;N-E^agUXH@$OQsdn60~Wpx{yguigW zbE_UahiOUmIBo_*l5glNtA{TNDKzNwYLfn7CanU; zUgyM|?~(?FRtZ$!4lZ|gB@{{t_<)(|M_yJhjXMoNl1bc?R!y6HeWSY6WWw{$ej~{# zXlC_;-l(vn+T`_%l>=q^P`&seF%XOZOL1;S zTcmEcBjcG;AbbF$64TA^9gSBRgRjbU6cMwI?UzKZQgrg4&g?n$Wm>;9g#W7}@?(T< z;!gz3_#+l`I_Az1OL@tuAICuusJy?`}R?2iI1py>YrAUpHlPUFA^~H(pu!u__-`Eaus|6PSZ@@9P?|JA}`C%%U+kEH&-`vVL>Rb4FRR_MOn&P&z|W zQI{2)nwo74is`*2_Z)Nkbge1Z*sg-Qwqn#{>*+g*-s(rII#zdBX+_*Y6y;mu6OF9l zb=dqv$^H5#yyi#3!^-@+;E!!1EnLbpmh}+r{_YA~mg_4l~$z!*=mG_6-pAGGZ2~ z-Pazt3nKKX;cPNcL(g~@o@rq)UD3h^F6s+j3-FFQi~UqehAk9_^W|j4YuJUM%jgH8 zcV$0NfCZZd(ex9~%cE{vAh=hOW?oFxrtz|a9zQFzfLfE#P0LqobV9_xv;=_>w5mwa zKtnVxsM9aebI}oaj_SexIMWlUAQ^7H=`Sbgh8FTp^2(0Czv%O@^37v!L4gbuRdc-} z-XC`5e$Y;GabEm6R`g8gCod^%VBlk5t9H!+6W^UVj*p^-O0B{vG?&PS{%wC7ZmKW) z@FMTX{Om$jDLSCb??Cb^YX@K~!13P9bSxaXEZN(enU;<_-FBjzf8rhf{s{6IM(J-q zY3C0Tjz)~M?vKt574e;B+>1BrfepP|dwJ4diY|UThd^&9oZC1KGrYu^=5|v{Sx;T` zAnCEy0f9r-dNh*(M>k#=wi0s5Is?hlY-a82HMcSQL`|G?%=t@dGH{Y7T8$-HY^#wo zyQ$D=g1)Pjx}@5Sb;xv21MOy#X%F6%w^Lq|q%#_&NWCYF6!>F<3I`t^ZWCb#W@=j(ORRW?pe@&wM(CMJJXZ?8lHEi?i;78ZiKatV zrlXb(N7}7TCsoF3bTLrsFt7Fy{PteoAe1r}Q24b4rKZZSXyY;HTZSr|uM8&z0q5Em+WwTdz-GFdRe5r|8_HbrFy1qsl{7~gq&!0&)($2bGyX?a^TP}=@8^*Ji!_MR)Go|kg zg`f9`6N6eWHy!*%WUB`dyZoPWYx1uBnKVVo#@K#}1U;6&co}B>JKeQ=E7MuaAc8X& znlbPKL-EefsG4)et|4%!(|XxJ%vix_b?Q+0LuhB7=t~Dmb)w{JAUC8X$WVnrKT6IF zh!&JFc-HzaugwOt^;s><524jf?QTQKs?9tiSg$=u5MF^242t+CR?UY);QQ^g()wpr zn}0WPgW}3heT9yqaPb|c3;|cei+{Lgp}P+=oD8^IA-8p{mjqjwC&<)){x>lEJt`Pq zuU3o!^UmO4*%vLbl3t|2=gr@gA9O=aGUW|zFX57V2S(jz1_tH(G%H$3CN}hVZBMcAvhm7@q e!`VN(I4NcjYHmAkcKHgx0MhZa1JnM(wSNH*O;Ydx delta 2441 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 From 0759c21d6c1569b79b4b267035ae4a4280a486f5 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 7 Aug 2026 09:45:43 +0200 Subject: [PATCH 81/87] test(ui): align thread-reply test with reverted replies-config gating Commit d07bcf5c4 intentionally reverted the channel replies-config gating so ThreadReply is governed solely by the send-reply capability, but this test was left asserting the old behavior and failed CI. Update it to assert the shipped behavior: the config flag alone does not hide the action when the capability is granted. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/message_action/message_actions_builder_test.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart b/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart index fade6cd1cb..0e9204aac2 100644 --- a/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart +++ b/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart @@ -464,11 +464,12 @@ void main() { ); testWidgets( - 'hides thread reply when channel replies are disabled', + 'keeps thread reply available when only the channel replies config is disabled', (tester) async { final context = await _getContext(tester); // The send-reply capability is granted; only the channel config says no. + // Thread reply is gated by the capability, not the channel replies config. final channelWithoutReplies = _getChannelWithCapabilities( allChannelCapabilities, enableReplies: false, @@ -481,8 +482,8 @@ void main() { currentUser: currentUser, ); - actions.notExpects( - reason: 'Thread reply unavailable when channel replies are disabled', + actions.expects( + reason: 'Thread reply is gated by the send-reply capability, not the config', ); actions.expects( From 26de77a75f3d004509c237c970b3d762c05e1680 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 7 Aug 2026 09:47:42 +0200 Subject: [PATCH 82/87] test(ui): drop replies-config thread-reply test The channel replies-config gating this covered was intentionally reverted (d07bcf5c4) and is not on master, so remove the test rather than keep it asserting a behavior the branch no longer implements. Thread reply remains covered by the send-reply capability cases. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../message_actions_builder_test.dart | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart b/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart index 0e9204aac2..41ab757639 100644 --- a/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart +++ b/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart @@ -463,35 +463,6 @@ void main() { }, ); - testWidgets( - 'keeps thread reply available when only the channel replies config is disabled', - (tester) async { - final context = await _getContext(tester); - - // The send-reply capability is granted; only the channel config says no. - // Thread reply is gated by the capability, not the channel replies config. - final channelWithoutReplies = _getChannelWithCapabilities( - allChannelCapabilities, - enableReplies: false, - ); - - final actions = StreamMessageActionsBuilder.buildActions( - context: context, - message: message, - channel: channelWithoutReplies, - currentUser: currentUser, - ); - - actions.expects( - reason: 'Thread reply is gated by the send-reply capability, not the config', - ); - - actions.expects( - reason: 'Quoted reply is independent of the replies config', - ); - }, - ); - testWidgets( 'handles thread and quote reply actions correctly', (tester) async { From 5b07f96b4e745bf81c1603330699a5a6e6249d16 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 7 Aug 2026 09:57:21 +0200 Subject: [PATCH 83/87] style(ui): dart format padding_scrollable_positioned_list_test Co-Authored-By: Claude Opus 4.8 (1M context) --- .../padding_scrollable_positioned_list_test.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/test/scrollable_positioned_list/padding_scrollable_positioned_list_test.dart b/packages/stream_chat_flutter/test/scrollable_positioned_list/padding_scrollable_positioned_list_test.dart index 4e7f5cd9be..c09aade169 100644 --- a/packages/stream_chat_flutter/test/scrollable_positioned_list/padding_scrollable_positioned_list_test.dart +++ b/packages/stream_chat_flutter/test/scrollable_positioned_list/padding_scrollable_positioned_list_test.dart @@ -155,7 +155,9 @@ void main() { ]); }); - testWidgets('aggregate (first sliver top + last sliver bottom) equals ListView single SliverPadding', (tester) async { + testWidgets('aggregate (first sliver top + last sliver bottom) equals ListView single SliverPadding', ( + tester, + ) async { // ListView oracle: one SliverPadding carrying the whole main-axis inset. tester.view ..devicePixelRatio = 1.0 From 0f5ff5adb4a547a9e5380b7a2331813f12fbb719 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 7 Aug 2026 16:43:10 +0200 Subject: [PATCH 84/87] feat(ui): implement transparent edge-to-edge system bars - Enable `SystemUiMode.edgeToEdge` in `main()` to allow content to flow under system bars. - Add `_EdgeToEdgeSystemBars` wrapper widget using `AnnotatedRegion` to configure `SystemUiOverlayStyle`. - Set `statusBarColor` and `systemNavigationBarColor` to transparent. - Disable `systemNavigationBarContrastEnforced` to allow full edge-to-edge content bleeding. - Ensure system bar icon brightness automatically updates based on the current `ThemeMode`. --- sample_app/lib/app.dart | 48 ++++++++++++++++++++++++++++++++++++---- sample_app/lib/main.dart | 4 ++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/sample_app/lib/app.dart b/sample_app/lib/app.dart index facf81a47e..6f29d4e87f 100644 --- a/sample_app/lib/app.dart +++ b/sample_app/lib/app.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'package:dynamic_color/dynamic_color.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart' hide Message; import 'package:go_router/go_router.dart'; import 'package:media_kit/media_kit.dart'; @@ -202,8 +203,9 @@ class _StreamChatSampleAppState extends State GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], - builder: (context, child) { - return ListenableBuilder( + builder: (context, child) => _EdgeToEdgeSystemBars( + themeMode: config.themeMode, + child: ListenableBuilder( listenable: authController, builder: (context, cachedChild) { final wrapped = Directionality( @@ -239,8 +241,8 @@ class _StreamChatSampleAppState extends State ); }, child: child, - ); - }, + ), + ), routerConfig: _setupRouter(), ); }, @@ -299,3 +301,41 @@ extension on SampleAppConfigData { ); } } + +/// Renders the app edge-to-edge with transparent, theme-aware system bars. +/// +/// Wrapped once below the theme so it re-resolves on theme changes. The +/// navigation bar keeps `systemNavigationBarContrastEnforced: false` so it stays +/// fully transparent (content bleeds behind it) instead of the OS painting an +/// opaque three-button-nav scrim; icon brightness carries legibility instead. +/// Pair with `SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge)` in +/// `main()`. +class _EdgeToEdgeSystemBars extends StatelessWidget { + const _EdgeToEdgeSystemBars({ + required this.themeMode, + required this.child, + }); + + final ThemeMode themeMode; + final Widget child; + + @override + Widget build(BuildContext context) { + final isDark = switch (themeMode) { + ThemeMode.light => false, + ThemeMode.dark => true, + ThemeMode.system => Theme.brightnessOf(context) == .dark, + }; + + return AnnotatedRegion( + value: SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarIconBrightness: isDark ? .light : .dark, + systemNavigationBarColor: Colors.transparent, + systemNavigationBarContrastEnforced: false, + systemNavigationBarIconBrightness: isDark ? .light : .dark, + ), + child: child, + ); + } +} diff --git a/sample_app/lib/main.dart b/sample_app/lib/main.dart index c6139449d1..1755178a92 100644 --- a/sample_app/lib/main.dart +++ b/sample_app/lib/main.dart @@ -2,12 +2,16 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:marionette_flutter/marionette_flutter.dart'; import 'package:sample_app/app.dart'; import 'package:sample_app/firebase_options.dart'; import 'package:sample_app/utils/platform_support.dart'; Future main() async { + // Set up edge-to-edge UI. + SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); + // In debug mode, initialize the Marionette binding so AI agents can drive // the running app over MCP (inspect widgets, tap, type, scroll, screenshot). // Falls back to the standard binding in release/profile builds. From 2af9b6bb5903cdc2bdc8b52531e0797bb28373cb Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 7 Aug 2026 16:43:30 +0200 Subject: [PATCH 85/87] fix(ui): adjust message composer bottom padding for keyboard visibility - Implement `WidgetsBindingObserver` in `DefaultStreamMessageComposerState` to trigger rebuilds on metric changes (keyboard opening/closing). - Update the `StreamSafeArea` bottom padding to dynamically switch between `spacing.safeAreaBottom()` when the keyboard is hidden and `spacing.md` when it is visible. --- .../src/message_input/stream_message_composer.dart | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart index 65f60ee0d8..78abe5f5bd 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_composer.dart @@ -565,7 +565,7 @@ class DefaultStreamMessageComposer extends StatefulWidget { /// State of [DefaultStreamMessageComposer]. class DefaultStreamMessageComposerState extends State - with RestorationMixin, SingleTickerProviderStateMixin { + with RestorationMixin, SingleTickerProviderStateMixin, WidgetsBindingObserver { bool get _commandEnabled => _effectiveController.message.command != null; bool get _isPickerVisible => _pickerController != null; @@ -620,6 +620,7 @@ class DefaultStreamMessageComposerState extends State setState(() {}); // Rebuilds when the keyboard opens/closes. + void _initializeState() { // Call the listener once to make sure the initial state is reflected // correctly in the UI. @@ -833,6 +837,8 @@ class DefaultStreamMessageComposerState extends State 0; + final content = Material( type: .transparency, child: switch (widget.props.enableSafeArea) { @@ -840,7 +846,7 @@ class DefaultStreamMessageComposerState extends State StreamSafeArea.driven( top: false, listenable: _pickerAnimation, - minimum: .only(bottom: spacing.md), + minimum: .only(bottom: keyboardVisible ? spacing.md : spacing.safeAreaBottom()), child: Center(heightFactor: 1, child: messageInput), ), }, @@ -1621,6 +1627,7 @@ class DefaultStreamMessageComposerState extends State Date: Fri, 7 Aug 2026 16:45:35 +0200 Subject: [PATCH 86/87] chore(deps): update stream_core_flutter dependency reference --- docs/docs_screenshots/pubspec.yaml | 2 +- melos.yaml | 2 +- packages/stream_chat_flutter/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs_screenshots/pubspec.yaml b/docs/docs_screenshots/pubspec.yaml index 8a4e1c916d..bd71853ce1 100644 --- a/docs/docs_screenshots/pubspec.yaml +++ b/docs/docs_screenshots/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter.git - ref: 8425a0f80ef9079a07605f96d775d8057f6ca58c + ref: c4308b3a2ea286483fc24c09c0168b10ad9de8a8 path: packages/stream_core_flutter dev_dependencies: diff --git a/melos.yaml b/melos.yaml index 5259ea78ad..dd79fb9ed5 100644 --- a/melos.yaml +++ b/melos.yaml @@ -107,7 +107,7 @@ command: stream_core_flutter: git: url: https://github.com/GetStream/stream-core-flutter.git - ref: 8425a0f80ef9079a07605f96d775d8057f6ca58c + ref: c4308b3a2ea286483fc24c09c0168b10ad9de8a8 path: packages/stream_core_flutter stream_thumbnail: ^0.1.0 synchronized: ^3.4.0 diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index f09f666d46..ef3fa2046e 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -66,7 +66,7 @@ dependencies: # ignore: invalid_dependency git: url: https://github.com/GetStream/stream-core-flutter.git - ref: 8425a0f80ef9079a07605f96d775d8057f6ca58c + ref: c4308b3a2ea286483fc24c09c0168b10ad9de8a8 path: packages/stream_core_flutter stream_thumbnail: ^0.1.0 svg_icon_widget: ^0.0.1 From 23055350ef616cf4459917bc967ec7b4660df3c0 Mon Sep 17 00:00:00 2001 From: xsahil03x <25670178+xsahil03x@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:52:21 +0000 Subject: [PATCH 87/87] chore: Update Goldens --- .../goldens/macos/localization_support.png | Bin 158873 -> 157127 bytes .../macos/autocomplete_trigger_commands.png | Bin 19878 -> 20436 bytes .../macos/autocomplete_trigger_emoji.png | Bin 18454 -> 18460 bytes .../macos/autocomplete_trigger_mention.png | Bin 24453 -> 24440 bytes .../autocomplete_trigger_mention_types.png | Bin 25963 -> 25968 bytes .../macos/message_composer_input_header.png | Bin 9231 -> 9227 bytes .../macos/message_composer_slow_mode.png | Bin 6781 -> 6781 bytes .../goldens/macos/message_input.png | Bin 4920 -> 4919 bytes .../macos/message_input_change_position.png | Bin 7113 -> 7113 bytes .../macos/message_input_custom_buttons.png | Bin 5839 -> 5839 bytes .../macos/message_input_custom_send_icon.png | Bin 4669 -> 4669 bytes .../macos/message_input_quoted_message.png | Bin 13067 -> 13062 bytes .../macos/stream_message_composer_default.png | Bin 4920 -> 4919 bytes .../macos/voice_recording_attachment.png | Bin 27206 -> 27220 bytes .../voice_recording_attachment_custom.png | Bin 27430 -> 27445 bytes .../voice_recording_attachment_playing.png | Bin 27206 -> 27220 bytes .../goldens/macos/voice_recording_enabled.png | Bin 6361 -> 6360 bytes .../macos/voice_recording_finished.png | Bin 13145 -> 13145 bytes .../goldens/macos/voice_recording_idle.png | Bin 6361 -> 6360 bytes .../ci/composer_hold_to_record_snackbar.png | Bin 5435 -> 5431 bytes .../goldens/ci/message_composer_slow_mode.png | Bin 2857 -> 2855 bytes 21 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/docs_screenshots/test/localization/goldens/macos/localization_support.png b/docs/docs_screenshots/test/localization/goldens/macos/localization_support.png index f6a61a05e0fb8758611f1abcbea04221c4d4515b..e6c978dba7740a0e0fdaa463745025ce074dd92a 100644 GIT binary patch delta 54825 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 a9a>4fP^?7 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 delta 56584 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