From 0c2804336510d08cea7ae3f8c3eb5f938d6dbfa9 Mon Sep 17 00:00:00 2001 From: S-ecki <75510543+S-ecki@users.noreply.github.com> Date: Tue, 1 Mar 2022 17:27:03 +0100 Subject: [PATCH 01/29] add centerTitle and elevation to ChannelHeader --- .../stream_chat_flutter/lib/src/channel_header.dart | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel_header.dart index 954aa758..df615cfd 100644 --- a/packages/stream_chat_flutter/lib/src/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_header.dart @@ -61,9 +61,11 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { this.showConnectionStateTile = false, this.title, this.subtitle, + this.centerTitle, this.leading, this.actions, this.backgroundColor, + this.elevation, }) : preferredSize = const Size.fromHeight(kToolbarHeight), super(key: key); @@ -92,6 +94,9 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { /// Subtitle widget final Widget? subtitle; + // Whether the title should be centered + final bool? centerTitle; + /// Leading widget final Widget? leading; @@ -102,6 +107,9 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { /// The background color for this [ChannelHeader]. final Color? backgroundColor; + /// The elevation for this [ChannelHeader]. + final double? elevation; + @override Widget build(BuildContext context) { final channel = StreamChannel.of(context).channel; @@ -144,7 +152,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { systemOverlayStyle: theme.brightness == Brightness.dark ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark, - elevation: 1, + elevation: elevation ?? 1, leading: leadingWidget, backgroundColor: backgroundColor ?? channelHeaderTheme.color, actions: actions ?? @@ -162,7 +170,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { ), ), ], - centerTitle: true, + centerTitle: centerTitle ?? true, title: InkWell( onTap: onTitleTap, child: SizedBox( From 6ffaca6699d55b41d00b9530c3f47249232bb273 Mon Sep 17 00:00:00 2001 From: S-ecki <75510543+S-ecki@users.noreply.github.com> Date: Tue, 1 Mar 2022 17:28:28 +0100 Subject: [PATCH 02/29] Update CHANGELOG.md --- packages/stream_chat_flutter/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 4bc77514..b798b839 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -6,6 +6,11 @@ - [[#805]](https://github.com/GetStream/stream-chat-flutter/issues/805) Updated chewie dependency version to 1.3.0 - Fix `showScrollToBottom` in `MessageListView` not respecting false value. +✅ Added + +- `centerTitle` and `elevation` properties to `ChannelHeader`. + + ## 3.4.0 - Updated `stream_chat_flutter_core` dependency to [`3.4.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog). From 43d50a6b94d6a016869dc69a3d60811b49c1b488 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Mon, 7 Mar 2022 10:55:36 +0100 Subject: [PATCH 03/29] fix analysis --- packages/stream_chat_flutter/lib/src/channel_header.dart | 2 +- packages/stream_chat_flutter/lib/src/message_list_view.dart | 1 + .../lib/src/stream_chat_localizations.dart | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel_header.dart index df615cfd..e15e7c62 100644 --- a/packages/stream_chat_flutter/lib/src/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_header.dart @@ -94,7 +94,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { /// Subtitle widget final Widget? subtitle; - // Whether the title should be centered + /// Whether the title should be centered final bool? centerTitle; /// Leading widget diff --git a/packages/stream_chat_flutter/lib/src/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view.dart index c6e269b9..02b258db 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view.dart @@ -529,6 +529,7 @@ class _MessageListViewState extends State { return ((index + 2) * 2) - 1; } } + return null; }, // Item Count -> 8 (1 parent, 2 header+footer, 2 top+bottom, 3 messages) diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations.dart index 0c7ce68e..16838cf5 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations.dart @@ -74,6 +74,8 @@ GlobalStreamChatLocalizations? getStreamChatTranslation(Locale locale) { return const StreamChatLocalizationsKo(); case 'pt': return const StreamChatLocalizationsPt(); + default: + return null; } } From b8307503c7c8a5449dab8ded20a3ec11a9b1c2a7 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Mon, 7 Mar 2022 11:09:20 +0100 Subject: [PATCH 04/29] chore(ui): update changelog --- packages/stream_chat_flutter/CHANGELOG.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 8adeab5f..0a76ca1e 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,9 @@ +## Upcoming + +✅ Added + +- `centerTitle` and `elevation` properties to `ChannelHeader`. + ## 3.5.0 🐞 Fixed @@ -7,11 +13,6 @@ - Fix `showScrollToBottom` in `MessageListView` not respecting false value. - Fix default `Channel` route not opening from `ChannelListView` when `ChannelAvatar` is tapped -✅ Added - -- `centerTitle` and `elevation` properties to `ChannelHeader`. - - ## 3.4.0 - Updated `stream_chat_flutter_core` dependency to [`3.4.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog). From 00d29489300ca3fbdb9f3c1128a8e4662d7069f7 Mon Sep 17 00:00:00 2001 From: S-ecki <75510543+S-ecki@users.noreply.github.com> Date: Wed, 9 Mar 2022 17:10:49 +0100 Subject: [PATCH 05/29] feat: align channel_header center title with AppBar --- .../lib/src/channel_header.dart | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel_header.dart index e15e7c62..6cb26434 100644 --- a/packages/stream_chat_flutter/lib/src/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_header.dart @@ -170,7 +170,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { ), ), ], - centerTitle: centerTitle ?? true, + centerTitle: _getEffectiveCenterTitle(theme), title: InkWell( onTap: onTitleTap, child: SizedBox( @@ -202,4 +202,24 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { @override final Size preferredSize; + + /// Returns the effective center title for the current theme and platform. + /// + /// This code is aligned with the [AppBar]'s [AppBar.centerTitle]. + bool _getEffectiveCenterTitle(ThemeData theme) { + if (centerTitle != null) return centerTitle!; + if (theme.appBarTheme.centerTitle != null) { + return theme.appBarTheme.centerTitle!; + } + switch (theme.platform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + return false; + case TargetPlatform.iOS: + case TargetPlatform.macOS: + return actions == null || actions!.length < 2; + } + } } From a7eaee29d66fdb75ade8d7e1fe6a8611be2eb60b Mon Sep 17 00:00:00 2001 From: S-ecki <75510543+S-ecki@users.noreply.github.com> Date: Wed, 9 Mar 2022 17:18:09 +0100 Subject: [PATCH 06/29] feat: add elevation and centerTitle to ThreadHeader and ChannelListHeader --- .../lib/src/channel_header.dart | 22 +------------------ .../lib/src/channel_list_header.dart | 12 ++++++++-- .../lib/src/thread_header.dart | 12 ++++++++-- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel_header.dart index 6cb26434..0731a933 100644 --- a/packages/stream_chat_flutter/lib/src/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_header.dart @@ -170,7 +170,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { ), ), ], - centerTitle: _getEffectiveCenterTitle(theme), + centerTitle: centerTitle, title: InkWell( onTap: onTitleTap, child: SizedBox( @@ -202,24 +202,4 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { @override final Size preferredSize; - - /// Returns the effective center title for the current theme and platform. - /// - /// This code is aligned with the [AppBar]'s [AppBar.centerTitle]. - bool _getEffectiveCenterTitle(ThemeData theme) { - if (centerTitle != null) return centerTitle!; - if (theme.appBarTheme.centerTitle != null) { - return theme.appBarTheme.centerTitle!; - } - switch (theme.platform) { - case TargetPlatform.android: - case TargetPlatform.fuchsia: - case TargetPlatform.linux: - case TargetPlatform.windows: - return false; - case TargetPlatform.iOS: - case TargetPlatform.macOS: - return actions == null || actions!.length < 2; - } - } } diff --git a/packages/stream_chat_flutter/lib/src/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel_list_header.dart index 6c54ad89..ba31fc16 100644 --- a/packages/stream_chat_flutter/lib/src/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_list_header.dart @@ -56,9 +56,11 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { this.showConnectionStateTile = false, this.preNavigationCallback, this.subtitle, + this.centerTitle, this.leading, this.actions, this.backgroundColor, + this.elevation, }) : super(key: key); /// Pass this if you don't have a [StreamChatClient] in your widget tree. @@ -83,6 +85,9 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { /// Subtitle widget final Widget? subtitle; + /// Whether the title should be centered + final bool? centerTitle; + /// Leading widget /// By default it shows the logged in user avatar final Widget? leading; @@ -94,6 +99,9 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { /// The background color for this [ChannelListHeader]. final Color? backgroundColor; + /// The elevation for this [ChannelListHeader]. + final double? elevation; + @override Widget build(BuildContext context) { final _client = client ?? StreamChat.of(context).client; @@ -128,10 +136,10 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { systemOverlayStyle: theme.brightness == Brightness.dark ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark, - elevation: 1, + elevation: elevation ?? 1, backgroundColor: backgroundColor ?? channelListHeaderThemeData.color, - centerTitle: true, + centerTitle: centerTitle, leading: leading ?? Center( child: user != null diff --git a/packages/stream_chat_flutter/lib/src/thread_header.dart b/packages/stream_chat_flutter/lib/src/thread_header.dart index aae1d8f9..d92c9305 100644 --- a/packages/stream_chat_flutter/lib/src/thread_header.dart +++ b/packages/stream_chat_flutter/lib/src/thread_header.dart @@ -65,11 +65,13 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { this.onBackPressed, this.title, this.subtitle, + this.centerTitle, this.leading, this.actions, this.onTitleTap, this.showTypingIndicator = true, this.backgroundColor, + this.elevation, }) : preferredSize = const Size.fromHeight(kToolbarHeight), super(key: key); @@ -92,6 +94,9 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { /// Subtitle widget final Widget? subtitle; + /// Whether the title should be centered + final bool? centerTitle; + /// Leading widget final Widget? leading; @@ -105,6 +110,9 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { /// The background color of this [ThreadHeader]. final Color? backgroundColor; + /// The elevation for this [ThreadHeader]. + final double? elevation; + @override Widget build(BuildContext context) { final channelHeaderTheme = ChannelHeaderTheme.of(context); @@ -134,7 +142,7 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { systemOverlayStyle: theme.brightness == Brightness.dark ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark, - elevation: 1, + elevation: elevation ?? 1, leading: leading ?? (showBackButton ? StreamBackButton( @@ -144,7 +152,7 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { ) : const SizedBox()), backgroundColor: backgroundColor ?? channelHeaderTheme.color, - centerTitle: true, + centerTitle: centerTitle, actions: actions, title: InkWell( onTap: onTitleTap, From 9c2c494797cf2503f22da5d28e0806b258344eb8 Mon Sep 17 00:00:00 2001 From: S-ecki <75510543+S-ecki@users.noreply.github.com> Date: Wed, 9 Mar 2022 17:20:19 +0100 Subject: [PATCH 07/29] chore: edit changelog --- 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 0a76ca1e..7d978867 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -2,7 +2,7 @@ ✅ Added -- `centerTitle` and `elevation` properties to `ChannelHeader`. +- `centerTitle` and `elevation` properties to `ChannelHeader`, `ThreadHeader` and `ChannelListHeader`. ## 3.5.0 From 7056fa6280077ef09f0f55969cce5c798c205528 Mon Sep 17 00:00:00 2001 From: Ayush Shekhar Date: Fri, 15 Apr 2022 10:31:08 +0530 Subject: [PATCH 08/29] Fixed code in the overlapping chat with transparency docs --- .../adding_chat_to_video_livestreams.mdx | 98 +++++++++++++------ 1 file changed, 70 insertions(+), 28 deletions(-) diff --git a/docusaurus/docs/Flutter/guides/adding_chat_to_video_livestreams.mdx b/docusaurus/docs/Flutter/guides/adding_chat_to_video_livestreams.mdx index 9e2afb44..72eddc2a 100644 --- a/docusaurus/docs/Flutter/guides/adding_chat_to_video_livestreams.mdx +++ b/docusaurus/docs/Flutter/guides/adding_chat_to_video_livestreams.mdx @@ -61,33 +61,75 @@ The second type looks like this: ![](../assets/live_stream_2.jpg) -We can use a `Stack` for achieving this: +We can use a `Stack` for achieving this, here's a complete working implementation: ```dart -Scaffold( - body: Stack( - children: [ - // Add your video implementation here - ShaderMask( - shaderCallback: (rect) { - return LinearGradient( - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - colors: [Colors.black, Colors.transparent], - stops: [0.4, 0.65] - ).createShader(Rect.fromLTRB(0, 0, rect.width, rect.height)); - }, - blendMode: BlendMode.dstIn, - child: Column( - children: [ - Expanded( - child: MessageListView(), - ), - MessageInput(), - ], - ), - ), - ], - ), - ) -``` +class MyApp extends StatelessWidget { + const MyApp({ + Key? key, + required this.client, + required this.channel, + }) : super(key: key); + + final StreamChatClient client; + + final Channel channel; + + @override + Widget build(BuildContext context) => MaterialApp( + theme: ThemeData.light(), + darkTheme: ThemeData.dark(), + builder: (context, widget) => StreamChat( + client: client, + child: widget, + streamChatThemeData: StreamChatThemeData().copyWith( + messageListViewTheme: const MessageListViewThemeData( + backgroundColor: Colors.transparent, + ), + ), + ), + home: StreamChannel( + channel: channel, + child: const ChannelPage(), + ), + ); +} + +class ChannelPage extends StatelessWidget { + const ChannelPage({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.transparent, + body: Stack( + children: [ + // Add your video implementation here + ShaderMask( + shaderCallback: (rect) { + return const LinearGradient( + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + colors: [Colors.black, Colors.transparent], + stops: [0.4, 0.8]).createShader( + Rect.fromLTRB(0, 0, rect.width, rect.height), + ); + }, + blendMode: BlendMode.dstIn, + child: Column( + children: const [ + Expanded( + child: MessageListView(), + ), + MessageInput(), + ], + ), + ), + ], + ), + ); + } +} +``` \ No newline at end of file From 778b8aad1376e54e76de09492dca632c06650709 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 15 Apr 2022 13:39:25 +0200 Subject: [PATCH 09/29] fix(ui): show date divider for first message --- .../lib/src/message_list_view.dart | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view.dart index 0b432caa..0ff31e0f 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view.dart @@ -559,6 +559,9 @@ class _MessageListViewState extends State { if (widget.reverse ? widget.headerBuilder == null : widget.footerBuilder == null) { + if (messages.isNotEmpty) { + return _buildDateDivider(messages.last); + } if (_isThreadConversation) return const Offstage(); return const SizedBox(height: 52); } @@ -583,21 +586,12 @@ class _MessageListViewState extends State { message = messages[i - 2]; nextMessage = messages[i - 1]; } + if (!Jiffy(message.createdAt.toLocal()).isSame( nextMessage.createdAt.toLocal(), Units.DAY, )) { - final divider = widget.dateDividerBuilder != null - ? widget.dateDividerBuilder!( - nextMessage.createdAt.toLocal(), - ) - : Padding( - padding: const EdgeInsets.symmetric(vertical: 12), - child: DateDivider( - dateTime: nextMessage.createdAt.toLocal(), - ), - ); - return divider; + return _buildDateDivider(nextMessage); } final timeDiff = Jiffy(nextMessage.createdAt.toLocal()).diff( @@ -747,6 +741,20 @@ class _MessageListViewState extends State { return child; } + Widget _buildDateDivider(Message message) { + final divider = widget.dateDividerBuilder != null + ? widget.dateDividerBuilder!( + message.createdAt.toLocal(), + ) + : Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: DateDivider( + dateTime: message.createdAt.toLocal(), + ), + ); + return divider; + } + Widget _buildThreadSeparator() { if (widget.threadSeparatorBuilder != null) { return widget.threadSeparatorBuilder!.call(context); @@ -803,7 +811,11 @@ class _MessageListViewState extends State { index = _getBottomElementIndex(values); } - if (index == null) return const Offstage(); + if ((index == null) || + (!_isThreadConversation && index == itemCount - 2) || + (_isThreadConversation && index == itemCount - 1)) { + return const Offstage(); + } if (index <= 2 || index >= itemCount - 3) { if (widget.reverse) { From d70b2e5931d07e46786c66aca45e7e1cfc41c53e Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 15 Apr 2022 13:41:04 +0200 Subject: [PATCH 10/29] chore(ui): update changelog --- packages/stream_chat_flutter/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 5d3d1406..d3217fa5 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,9 @@ +## Upcoming + +🐞 Fixed +- [[#842]](https://github.com/GetStream/stream-chat-flutter/issues/842): show date divider for first message. + + ## 3.6.1 - Updated `stream_chat_flutter_core` dependency to [`3.6.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog). From 5fbb568b4cf27863ccbff30f6bfb16c1df2cd9a3 Mon Sep 17 00:00:00 2001 From: Ayush Shekhar Date: Fri, 15 Apr 2022 17:20:01 +0530 Subject: [PATCH 11/29] Reduced the code --- .../adding_chat_to_video_livestreams.mdx | 92 ++++++------------- 1 file changed, 27 insertions(+), 65 deletions(-) diff --git a/docusaurus/docs/Flutter/guides/adding_chat_to_video_livestreams.mdx b/docusaurus/docs/Flutter/guides/adding_chat_to_video_livestreams.mdx index 72eddc2a..96d24a05 100644 --- a/docusaurus/docs/Flutter/guides/adding_chat_to_video_livestreams.mdx +++ b/docusaurus/docs/Flutter/guides/adding_chat_to_video_livestreams.mdx @@ -61,75 +61,37 @@ The second type looks like this: ![](../assets/live_stream_2.jpg) -We can use a `Stack` for achieving this, here's a complete working implementation: +We can use a `Stack` for achieving this: ```dart -class MyApp extends StatelessWidget { - const MyApp({ - Key? key, - required this.client, - required this.channel, - }) : super(key: key); - - final StreamChatClient client; - - final Channel channel; - - @override - Widget build(BuildContext context) => MaterialApp( - theme: ThemeData.light(), - darkTheme: ThemeData.dark(), - builder: (context, widget) => StreamChat( - client: client, - child: widget, - streamChatThemeData: StreamChatThemeData().copyWith( - messageListViewTheme: const MessageListViewThemeData( - backgroundColor: Colors.transparent, - ), - ), - ), - home: StreamChannel( - channel: channel, - child: const ChannelPage(), - ), - ); -} - -class ChannelPage extends StatelessWidget { - const ChannelPage({ - Key? key, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.transparent, - body: Stack( - children: [ - // Add your video implementation here - ShaderMask( - shaderCallback: (rect) { - return const LinearGradient( - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - colors: [Colors.black, Colors.transparent], - stops: [0.4, 0.8]).createShader( - Rect.fromLTRB(0, 0, rect.width, rect.height), - ); - }, - blendMode: BlendMode.dstIn, - child: Column( - children: const [ - Expanded( - child: MessageListView(), - ), - MessageInput(), - ], +Stack( + children: [ + // Add your video implementation here + ShaderMask( + shaderCallback: (rect) { + return const LinearGradient( + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + colors: [Colors.black, Colors.transparent], + stops: [0.4, 0.8]).createShader( + Rect.fromLTRB(0, 0, rect.width, rect.height), + ); + }, + blendMode: BlendMode.dstIn, + child: Column( + children: const [ + Expanded( + child: MessageListViewTheme( + data: MessageListViewThemeData( + backgroundColor: Colors.transparent, + ), + child: MessageListView(), ), ), + MessageInput(), ], ), - ); - } -} + ), + ], +), ``` \ No newline at end of file From ef2689c4d5aff7b2f3de26d70d133a89abe17c82 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Thu, 21 Apr 2022 09:24:05 +0200 Subject: [PATCH 12/29] chore(ui): update changelog --- 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 5d3d1406..441edc1a 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -6,7 +6,7 @@ 🐞 Fixed --[[#892]](https://github.com/GetStream/stream-chat-flutter/issues/892): Fix default `initialAlignment` in `MessageListView`. +- [[#892]](https://github.com/GetStream/stream-chat-flutter/issues/892): Fix default `initialAlignment` in `MessageListView`. - Fix `MessageInputTheme.inputBackgroundColor` color not being used in some widgets of `MessageInput` - Removed dependency on `visibility_detector` From 477bda5e89b2d809338725498ff2d2cb44ea3bbe Mon Sep 17 00:00:00 2001 From: Ayush Shekhar Date: Thu, 21 Apr 2022 18:21:53 +0530 Subject: [PATCH 13/29] fixed reaction card name text overflow issue --- .../stream_chat_flutter/lib/src/message_reactions_modal.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/stream_chat_flutter/lib/src/message_reactions_modal.dart b/packages/stream_chat_flutter/lib/src/message_reactions_modal.dart index 98e64c25..2127a98d 100644 --- a/packages/stream_chat_flutter/lib/src/message_reactions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_reactions_modal.dart @@ -236,6 +236,8 @@ class MessageReactionsModal extends StatelessWidget { reaction.user!.name.split(' ')[0], style: chatThemeData.textTheme.footnoteBold, textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + maxLines: 1, ), ], ), From 01341d7296facf53b76d3c12ed5180a34073905b Mon Sep 17 00:00:00 2001 From: Ayush Shekhar Date: Thu, 21 Apr 2022 18:23:34 +0530 Subject: [PATCH 14/29] Updated changelog --- packages/stream_chat_flutter/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 441edc1a..7f607d5c 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,9 @@ +## Upcoming + +🐞 Fixed + +- [[#1067]](https://github.com/GetStream/stream-chat-flutter/issues/1067): Fix name text overflow in reaction card. + ## 3.6.1 - Updated `stream_chat_flutter_core` dependency to [`3.6.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog). From fbeb656567544907e4c7d1f3c3b9a11dd29fed0d Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 22 Apr 2022 16:22:45 +0530 Subject: [PATCH 15/29] chore(llc): export defaultLogHandler, LogRecord Signed-off-by: xsahil03x --- .../stream_chat/lib/src/client/client.dart | 28 ++++----- packages/stream_chat/lib/stream_chat.dart | 59 +++++++++---------- 2 files changed, 43 insertions(+), 44 deletions(-) diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index f61560ef..18254389 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -64,7 +64,7 @@ class StreamChatClient { StreamChatClient( String apiKey, { this.logLevel = Level.WARNING, - LogHandlerFunction? logHandlerFunction, + this.logHandlerFunction = StreamChatClient.defaultLogHandler, RetryPolicy? retryPolicy, @Deprecated(''' Location is now deprecated in favor of the new edge server. Will be removed in v4.0.0. @@ -77,7 +77,6 @@ class StreamChatClient { WebSocket? ws, AttachmentFileUploader? attachmentFileUploader, }) { - this.logHandlerFunction = logHandlerFunction ?? _defaultLogHandler; logger.info('Initiating new StreamChatClient'); final options = StreamHttpClientOptions( @@ -134,7 +133,7 @@ class StreamChatClient { '${CurrentPlatform.name}-' '${PACKAGE_VERSION.split('+')[0]}'; - /// Additionals headers for all requests + /// Additional headers for all requests static Map additionalHeaders = {}; ChatPersistenceClient? _originalChatPersistenceClient; @@ -189,7 +188,7 @@ class StreamChatClient { /// final client = StreamChatClient("stream-chat-api-key", /// logHandlerFunction: myLogHandlerFunction); ///``` - late LogHandlerFunction logHandlerFunction; + final LogHandlerFunction logHandlerFunction; StreamSubscription? _connectionStatusSubscription; @@ -214,17 +213,18 @@ class StreamChatClient { Stream get wsConnectionStatusStream => _wsConnectionStatusController.stream.distinct(); - LogHandlerFunction get _defaultLogHandler => (LogRecord record) { - print( - '${record.time} ' - '${_levelEmojiMapper[record.level] ?? record.level.name} ' - '${record.loggerName} ${record.message} ', - ); - if (record.error != null) print(record.error); - if (record.stackTrace != null) print(record.stackTrace); - }; + /// Default log handler function for the [StreamChatClient] logger. + static void defaultLogHandler(LogRecord record) { + print( + '${record.time} ' + '${_levelEmojiMapper[record.level] ?? record.level.name} ' + '${record.loggerName} ${record.message} ', + ); + if (record.error != null) print(record.error); + if (record.stackTrace != null) print(record.stackTrace); + } - /// + /// Default logger for the [StreamChatClient]. Logger detachedLogger(String name) => Logger.detached(name) ..level = logLevel ..onRecord.listen(logHandlerFunction); diff --git a/packages/stream_chat/lib/stream_chat.dart b/packages/stream_chat/lib/stream_chat.dart index 571d78f5..794d7505 100644 --- a/packages/stream_chat/lib/stream_chat.dart +++ b/packages/stream_chat/lib/stream_chat.dart @@ -5,37 +5,36 @@ export 'package:dio/src/dio_error.dart'; export 'package:dio/src/multipart_file.dart'; export 'package:dio/src/options.dart'; export 'package:dio/src/options.dart' show ProgressCallback; -export 'package:logging/logging.dart' show Logger, Level; +export 'package:logging/logging.dart' show Logger, Level, LogRecord; export 'package:rate_limiter/rate_limiter.dart'; -export './src/core/api/attachment_file_uploader.dart' - show AttachmentFileUploader; -export './src/core/api/requests.dart'; -export './src/core/api/requests.dart'; -export './src/core/api/responses.dart'; -export './src/core/api/stream_chat_api.dart' show PushProvider; -export './src/core/error/error.dart'; -export './src/core/models/action.dart'; -export './src/core/models/attachment.dart'; -export './src/core/models/attachment_file.dart'; -export './src/core/models/channel_config.dart'; -export './src/core/models/channel_model.dart'; -export './src/core/models/channel_state.dart'; -export './src/core/models/command.dart'; -export './src/core/models/device.dart'; -export './src/core/models/event.dart'; -export './src/core/models/filter.dart' show Filter; -export './src/core/models/member.dart'; -export './src/core/models/message.dart'; -export './src/core/models/mute.dart'; -export './src/core/models/own_user.dart'; -export './src/core/models/reaction.dart'; -export './src/core/models/read.dart'; -export './src/core/models/user.dart'; -export './src/core/util/extension.dart'; -export './src/db/chat_persistence_client.dart'; -export './src/event_type.dart'; -export './src/location.dart'; -export './src/ws/connection_status.dart'; export 'src/client/channel.dart'; export 'src/client/client.dart'; +export 'src/core/api/attachment_file_uploader.dart' show AttachmentFileUploader; +export 'src/core/api/requests.dart'; +export 'src/core/api/requests.dart'; +export 'src/core/api/responses.dart'; +export 'src/core/api/stream_chat_api.dart' show PushProvider; +export 'src/core/error/error.dart'; +export 'src/core/models/action.dart'; +export 'src/core/models/attachment.dart'; +export 'src/core/models/attachment_file.dart'; +export 'src/core/models/channel_config.dart'; +export 'src/core/models/channel_model.dart'; +export 'src/core/models/channel_state.dart'; +export 'src/core/models/command.dart'; +export 'src/core/models/device.dart'; +export 'src/core/models/event.dart'; +export 'src/core/models/filter.dart' show Filter; +export 'src/core/models/member.dart'; +export 'src/core/models/message.dart'; +export 'src/core/models/mute.dart'; +export 'src/core/models/own_user.dart'; +export 'src/core/models/reaction.dart'; +export 'src/core/models/read.dart'; +export 'src/core/models/user.dart'; +export 'src/core/util/extension.dart'; +export 'src/db/chat_persistence_client.dart'; +export 'src/event_type.dart'; +export 'src/location.dart'; +export 'src/ws/connection_status.dart'; From 701559fcdddf5f287ec663c9a52e47e3d8f7beef Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Mon, 25 Apr 2022 11:57:42 +0200 Subject: [PATCH 16/29] fix(ui): remove check for launchUrl --- .../lib/src/attachment/file_attachment.dart | 1 + packages/stream_chat_flutter/lib/src/utils.dart | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart index 0b5d580f..a6ed3ed8 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart @@ -259,6 +259,7 @@ class FileAttachment extends AttachmentWidget { splashRadius: 16, onPressed: () { final assetUrl = attachment.assetUrl; + print('assetUrl: $assetUrl'); if (assetUrl != null) launchURL(context, assetUrl); }, ); diff --git a/packages/stream_chat_flutter/lib/src/utils.dart b/packages/stream_chat_flutter/lib/src/utils.dart index 2d661fbc..af2ac0c0 100644 --- a/packages/stream_chat_flutter/lib/src/utils.dart +++ b/packages/stream_chat_flutter/lib/src/utils.dart @@ -8,9 +8,9 @@ import 'package:url_launcher/url_launcher.dart'; /// Launch URL Future launchURL(BuildContext context, String url) async { - if (await canLaunch(url)) { + try { await launch(url); - } else { + } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(context.translations.launchUrlError)), ); From 277c5a37b143910d6530dd58ddee0378ef438ed4 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Mon, 25 Apr 2022 11:58:47 +0200 Subject: [PATCH 17/29] chore(ui): update changelog --- 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 16650f88..f7ff2d6c 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -4,6 +4,7 @@ - [[#1067]](https://github.com/GetStream/stream-chat-flutter/issues/1067): Fix name text overflow in reaction card. - [[#842]](https://github.com/GetStream/stream-chat-flutter/issues/842): show date divider for first message. +- Loosen up url check for attachment download. ## 3.6.1 From 76f6ce6d0f1b972ccb831757a0cbb8da2a00b156 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Mon, 25 Apr 2022 12:09:50 +0200 Subject: [PATCH 18/29] remove print --- .../stream_chat_flutter/lib/src/attachment/file_attachment.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart index a6ed3ed8..0b5d580f 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/file_attachment.dart @@ -259,7 +259,6 @@ class FileAttachment extends AttachmentWidget { splashRadius: 16, onPressed: () { final assetUrl = attachment.assetUrl; - print('assetUrl: $assetUrl'); if (assetUrl != null) launchURL(context, assetUrl); }, ); From ff028948cf5a157f8f2df12c21a1f5599343cc65 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 26 Apr 2022 11:53:58 +0200 Subject: [PATCH 19/29] fix(ui): use ogScrapeUrl for link attachments --- .../lib/src/attachment/attachment_title.dart | 13 +++++-------- .../lib/src/attachment/url_attachment.dart | 8 ++++---- packages/stream_chat_flutter/lib/src/extension.dart | 9 +++++++++ .../stream_chat_flutter/lib/src/message_input.dart | 2 +- .../lib/src/message_list_view.dart | 2 +- .../stream_chat_flutter/lib/src/message_widget.dart | 10 +++++----- .../lib/src/quoted_message_widget.dart | 4 ++-- packages/stream_chat_flutter/lib/src/utils.dart | 2 +- 8 files changed, 28 insertions(+), 22 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/attachment/attachment_title.dart b/packages/stream_chat_flutter/lib/src/attachment/attachment_title.dart index f1369d49..4a85f2bb 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/attachment_title.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/attachment_title.dart @@ -18,14 +18,11 @@ class AttachmentTitle extends StatelessWidget { @override Widget build(BuildContext context) { - final normalizedTitleLink = attachment.titleLink?.replaceFirst( - RegExp(r'https?://(www\.)?'), - '', - ); + final ogScrapeUrl = attachment.ogScrapeUrl; return GestureDetector( onTap: () { - final titleLink = attachment.titleLink; - if (titleLink != null) launchURL(context, titleLink); + final ogScrapeUrl = attachment.ogScrapeUrl; + if (ogScrapeUrl != null) launchURL(context, ogScrapeUrl); }, child: Padding( padding: const EdgeInsets.all(8), @@ -42,8 +39,8 @@ class AttachmentTitle extends StatelessWidget { fontWeight: FontWeight.bold, ), ), - if (normalizedTitleLink != null) - Text(normalizedTitleLink, style: messageTheme.messageTextStyle), + if (ogScrapeUrl != null) + Text(ogScrapeUrl, style: messageTheme.messageTextStyle), ], ), ), diff --git a/packages/stream_chat_flutter/lib/src/attachment/url_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/url_attachment.dart index df05ba5e..8d4dfbfb 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/url_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/url_attachment.dart @@ -37,11 +37,11 @@ class UrlAttachment extends StatelessWidget { final chatThemeData = StreamChatTheme.of(context); return GestureDetector( onTap: () { - final titleLink = urlAttachment.titleLink; - if (titleLink != null) { + final ogScrapeUrl = urlAttachment.ogScrapeUrl; + if (ogScrapeUrl != null) { onLinkTap != null - ? onLinkTap!(titleLink) - : launchURL(context, titleLink); + ? onLinkTap!(ogScrapeUrl) + : launchURL(context, ogScrapeUrl); } }, child: Column( diff --git a/packages/stream_chat_flutter/lib/src/extension.dart b/packages/stream_chat_flutter/lib/src/extension.dart index f955ca99..cc41614c 100644 --- a/packages/stream_chat_flutter/lib/src/extension.dart +++ b/packages/stream_chat_flutter/lib/src/extension.dart @@ -225,3 +225,12 @@ extension UserListX on List { return entries.map((e) => e.key).toList(growable: false); } } + +/// Extensions on [Uri] +extension UriX on Uri { + /// Return the URI adding the http scheme if it is missing + Uri get withScheme { + if (hasScheme) return this; + return Uri.parse('http://${toString()}'); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index bb82386f..673c8f6c 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -1274,7 +1274,7 @@ class MessageInputState extends State { Widget _buildReplyToMessage() { if (!_hasQuotedMessage) return const Offstage(); final containsUrl = widget.quotedMessage!.attachments - .any((element) => element.titleLink != null); + .any((element) => element.ogScrapeUrl!= null); return QuotedMessageWidget( reverse: true, showBorder: !containsUrl, diff --git a/packages/stream_chat_flutter/lib/src/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view.dart index 0ff31e0f..cf4b1cd0 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view.dart @@ -1091,7 +1091,7 @@ class _MessageListViewState extends State { final isOnlyEmoji = message.text?.isOnlyEmoji ?? false; final hasUrlAttachment = - message.attachments.any((it) => it.titleLink != null); + message.attachments.any((it) => it.ogScrapeUrl != null); final borderSide = isOnlyEmoji || hasUrlAttachment || (isMyMessage && !hasFileAttachment) diff --git a/packages/stream_chat_flutter/lib/src/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget.dart index 3ffca84a..812a7595 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget.dart @@ -574,11 +574,11 @@ class _MessageWidgetState extends State bool get isOnlyEmoji => widget.message.text?.isOnlyEmoji == true; bool get hasNonUrlAttachments => widget.message.attachments - .where((it) => it.titleLink == null || it.type == 'giphy') + .where((it) => it.ogScrapeUrl == null || it.type == 'giphy') .isNotEmpty; bool get hasUrlAttachments => widget.message.attachments - .any((it) => it.titleLink != null && it.type != 'giphy'); + .any((it) => it.ogScrapeUrl != null && it.type != 'giphy'); bool get showBottomRow => showThreadReplyIndicator || @@ -999,9 +999,9 @@ class _MessageWidgetState extends State Widget _buildUrlAttachment() { final urlAttachment = widget.message.attachments - .firstWhere((element) => element.titleLink != null); + .firstWhere((element) => element.ogScrapeUrl != null); - final host = Uri.parse(urlAttachment.titleLink!).host; + final host = Uri.parse(urlAttachment.ogScrapeUrl!).withScheme.host; final splitList = host.split('.'); final hostName = splitList.length == 3 ? splitList[1] : splitList[0]; final hostDisplayName = urlAttachment.authorName?.capitalize() ?? @@ -1173,7 +1173,7 @@ class _MessageWidgetState extends State widget.message.attachments .where((element) => - (element.titleLink == null && element.type != null) || + (element.ogScrapeUrl == null && element.type != null) || element.type == 'giphy') .forEach((e) { if (attachmentGroups[e.type] == null) { diff --git a/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart b/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart index 131ca60b..8994eece 100644 --- a/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/quoted_message_widget.dart @@ -97,7 +97,7 @@ class QuotedMessageWidget extends StatelessWidget { bool get _hasAttachments => message.attachments.isNotEmpty; bool get _containsLinkAttachment => - message.attachments.any((element) => element.titleLink != null); + message.attachments.any((element) => element.ogScrapeUrl != null); bool get _containsText => message.text?.isNotEmpty == true; @@ -201,7 +201,7 @@ class QuotedMessageWidget extends StatelessWidget { Attachment attachment; if (_containsLinkAttachment) { attachment = message.attachments.firstWhere( - (element) => element.titleLink != null, + (element) => element.ogScrapeUrl != null, ); child = _buildUrlAttachment(attachment); } else { diff --git a/packages/stream_chat_flutter/lib/src/utils.dart b/packages/stream_chat_flutter/lib/src/utils.dart index af2ac0c0..3825263d 100644 --- a/packages/stream_chat_flutter/lib/src/utils.dart +++ b/packages/stream_chat_flutter/lib/src/utils.dart @@ -9,7 +9,7 @@ import 'package:url_launcher/url_launcher.dart'; /// Launch URL Future launchURL(BuildContext context, String url) async { try { - await launch(url); + await launch(Uri.parse(url).withScheme.toString()); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(context.translations.launchUrlError)), From e06d841b93ccf8505d208dc0848f47498692c443 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 26 Apr 2022 11:54:47 +0200 Subject: [PATCH 20/29] chore(ui): update changelog --- 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 f7ff2d6c..81f69a0c 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -5,6 +5,7 @@ - [[#1067]](https://github.com/GetStream/stream-chat-flutter/issues/1067): Fix name text overflow in reaction card. - [[#842]](https://github.com/GetStream/stream-chat-flutter/issues/842): show date divider for first message. - Loosen up url check for attachment download. +- Use `ogScrapeUrl` for LinkAttachments. ## 3.6.1 From f8d25879af1b68210759ade8823ca62648eccd47 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 26 Apr 2022 12:23:47 +0200 Subject: [PATCH 21/29] format --- packages/stream_chat_flutter/lib/src/message_input.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index 673c8f6c..e3d6747f 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -1274,7 +1274,7 @@ class MessageInputState extends State { Widget _buildReplyToMessage() { if (!_hasQuotedMessage) return const Offstage(); final containsUrl = widget.quotedMessage!.attachments - .any((element) => element.ogScrapeUrl!= null); + .any((element) => element.ogScrapeUrl != null); return QuotedMessageWidget( reverse: true, showBorder: !containsUrl, From c05743692762b27d9bd828980bd20321a4000389 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 26 Apr 2022 12:24:14 +0200 Subject: [PATCH 22/29] fix analysis --- .../lib/src/stream_chat_persistence_client.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/stream_chat_persistence/lib/src/stream_chat_persistence_client.dart b/packages/stream_chat_persistence/lib/src/stream_chat_persistence_client.dart index 2dc61f18..f8dfe9e5 100644 --- a/packages/stream_chat_persistence/lib/src/stream_chat_persistence_client.dart +++ b/packages/stream_chat_persistence/lib/src/stream_chat_persistence_client.dart @@ -1,5 +1,4 @@ import 'package:flutter/foundation.dart'; -import 'package:logging/logging.dart' show LogRecord; import 'package:mutex/mutex.dart'; import 'package:stream_chat/stream_chat.dart'; From cfad4bfc87399ff57cbb7c41990ac2888ba7b7f0 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 27 Apr 2022 10:44:43 +0200 Subject: [PATCH 23/29] fix(ui): fix centerTitle for ChannelHeader --- .../lib/src/channel_header.dart | 22 ++++++++++++++++++- .../lib/src/typing_indicator.dart | 6 +++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel_header.dart index 0731a933..d4558fd6 100644 --- a/packages/stream_chat_flutter/lib/src/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_header.dart @@ -112,6 +112,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { + final effectiveCenterTitle = _getEffectiveCenterTitle(Theme.of(context)); final channel = StreamChannel.of(context).channel; final channelHeaderTheme = ChannelHeaderTheme.of(context); @@ -175,9 +176,11 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { onTap: onTitleTap, child: SizedBox( height: preferredSize.height, - width: preferredSize.width, child: Column( mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: effectiveCenterTitle + ? CrossAxisAlignment.center + : CrossAxisAlignment.stretch, children: [ title ?? ChannelName( @@ -202,4 +205,21 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { @override final Size preferredSize; + + bool _getEffectiveCenterTitle(ThemeData theme) { + if (centerTitle != null) return centerTitle!; + if (theme.appBarTheme.centerTitle != null) { + return theme.appBarTheme.centerTitle!; + } + switch (theme.platform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + return false; + case TargetPlatform.iOS: + case TargetPlatform.macOS: + return actions == null || actions!.length < 2; + } + } } diff --git a/packages/stream_chat_flutter/lib/src/typing_indicator.dart b/packages/stream_chat_flutter/lib/src/typing_indicator.dart index d961a8ff..5bf7358a 100644 --- a/packages/stream_chat_flutter/lib/src/typing_indicator.dart +++ b/packages/stream_chat_flutter/lib/src/typing_indicator.dart @@ -47,6 +47,12 @@ class TypingIndicator extends StatelessWidget { .where((element) => element.value.parentId == parentId) .map((e) => e.key)), builder: (context, data) => AnimatedSwitcher( + layoutBuilder: (currentChild, previousChildren) => Stack( + children: [ + ...previousChildren, + if (currentChild != null) currentChild, + ], + ), duration: const Duration(milliseconds: 300), child: data.isNotEmpty ? Padding( From 681cee09f5a8a11afce0213f35ce5996db4e63a2 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 27 Apr 2022 10:51:00 +0200 Subject: [PATCH 24/29] fix(ui): fix centerTitle for ThreadHeader --- .../lib/src/thread_header.dart | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/stream_chat_flutter/lib/src/thread_header.dart b/packages/stream_chat_flutter/lib/src/thread_header.dart index d92c9305..fd6138fe 100644 --- a/packages/stream_chat_flutter/lib/src/thread_header.dart +++ b/packages/stream_chat_flutter/lib/src/thread_header.dart @@ -115,6 +115,7 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { + final effectiveCenterTitle = _getEffectiveCenterTitle(Theme.of(context)); final channelHeaderTheme = ChannelHeaderTheme.of(context); final defaultSubtitle = subtitle ?? @@ -161,6 +162,9 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { width: 250, child: Column( mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: effectiveCenterTitle + ? CrossAxisAlignment.center + : CrossAxisAlignment.stretch, children: [ title ?? Text( @@ -187,4 +191,21 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { @override final Size preferredSize; + + bool _getEffectiveCenterTitle(ThemeData theme) { + if (centerTitle != null) return centerTitle!; + if (theme.appBarTheme.centerTitle != null) { + return theme.appBarTheme.centerTitle!; + } + switch (theme.platform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + return false; + case TargetPlatform.iOS: + case TargetPlatform.macOS: + return actions == null || actions!.length < 2; + } + } } From 81c4207b047fd70a67387029db9819fcca0bf0e7 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 27 Apr 2022 11:15:51 +0200 Subject: [PATCH 25/29] fix elevation --- packages/stream_chat_flutter/lib/src/channel_header.dart | 6 +++--- .../stream_chat_flutter/lib/src/channel_list_header.dart | 6 +++--- packages/stream_chat_flutter/lib/src/thread_header.dart | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel_header.dart index d4558fd6..05799fdf 100644 --- a/packages/stream_chat_flutter/lib/src/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_header.dart @@ -65,7 +65,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { this.leading, this.actions, this.backgroundColor, - this.elevation, + this.elevation = 1, }) : preferredSize = const Size.fromHeight(kToolbarHeight), super(key: key); @@ -108,7 +108,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { final Color? backgroundColor; /// The elevation for this [ChannelHeader]. - final double? elevation; + final double elevation; @override Widget build(BuildContext context) { @@ -153,7 +153,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { systemOverlayStyle: theme.brightness == Brightness.dark ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark, - elevation: elevation ?? 1, + elevation: elevation, leading: leadingWidget, backgroundColor: backgroundColor ?? channelHeaderTheme.color, actions: actions ?? diff --git a/packages/stream_chat_flutter/lib/src/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel_list_header.dart index ba31fc16..fbe71ff7 100644 --- a/packages/stream_chat_flutter/lib/src/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_list_header.dart @@ -60,7 +60,7 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { this.leading, this.actions, this.backgroundColor, - this.elevation, + this.elevation = 1, }) : super(key: key); /// Pass this if you don't have a [StreamChatClient] in your widget tree. @@ -100,7 +100,7 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { final Color? backgroundColor; /// The elevation for this [ChannelListHeader]. - final double? elevation; + final double elevation; @override Widget build(BuildContext context) { @@ -136,7 +136,7 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { systemOverlayStyle: theme.brightness == Brightness.dark ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark, - elevation: elevation ?? 1, + elevation: elevation, backgroundColor: backgroundColor ?? channelListHeaderThemeData.color, centerTitle: centerTitle, diff --git a/packages/stream_chat_flutter/lib/src/thread_header.dart b/packages/stream_chat_flutter/lib/src/thread_header.dart index fd6138fe..53aaa37e 100644 --- a/packages/stream_chat_flutter/lib/src/thread_header.dart +++ b/packages/stream_chat_flutter/lib/src/thread_header.dart @@ -71,7 +71,7 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { this.onTitleTap, this.showTypingIndicator = true, this.backgroundColor, - this.elevation, + this.elevation = 1, }) : preferredSize = const Size.fromHeight(kToolbarHeight), super(key: key); @@ -111,7 +111,7 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { final Color? backgroundColor; /// The elevation for this [ThreadHeader]. - final double? elevation; + final double elevation; @override Widget build(BuildContext context) { @@ -143,7 +143,7 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { systemOverlayStyle: theme.brightness == Brightness.dark ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark, - elevation: elevation ?? 1, + elevation: elevation, leading: leading ?? (showBackButton ? StreamBackButton( From 622efa7ba27e2eeb25ea079fbfdf99fa01d8ce16 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 27 Apr 2022 11:52:07 +0200 Subject: [PATCH 26/29] extract getEffectiveCenterTitle --- .../lib/src/channel_header.dart | 23 ++++-------------- .../lib/src/thread_header.dart | 24 +++++-------------- .../stream_chat_flutter/lib/src/utils.dart | 22 +++++++++++++++++ 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/channel_header.dart b/packages/stream_chat_flutter/lib/src/channel_header.dart index 05799fdf..2716ea00 100644 --- a/packages/stream_chat_flutter/lib/src/channel_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_header.dart @@ -112,7 +112,11 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { - final effectiveCenterTitle = _getEffectiveCenterTitle(Theme.of(context)); + final effectiveCenterTitle = getEffectiveCenterTitle( + Theme.of(context), + actions: actions, + centerTitle: centerTitle, + ); final channel = StreamChannel.of(context).channel; final channelHeaderTheme = ChannelHeaderTheme.of(context); @@ -205,21 +209,4 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { @override final Size preferredSize; - - bool _getEffectiveCenterTitle(ThemeData theme) { - if (centerTitle != null) return centerTitle!; - if (theme.appBarTheme.centerTitle != null) { - return theme.appBarTheme.centerTitle!; - } - switch (theme.platform) { - case TargetPlatform.android: - case TargetPlatform.fuchsia: - case TargetPlatform.linux: - case TargetPlatform.windows: - return false; - case TargetPlatform.iOS: - case TargetPlatform.macOS: - return actions == null || actions!.length < 2; - } - } } diff --git a/packages/stream_chat_flutter/lib/src/thread_header.dart b/packages/stream_chat_flutter/lib/src/thread_header.dart index 53aaa37e..199b8a44 100644 --- a/packages/stream_chat_flutter/lib/src/thread_header.dart +++ b/packages/stream_chat_flutter/lib/src/thread_header.dart @@ -115,7 +115,12 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { - final effectiveCenterTitle = _getEffectiveCenterTitle(Theme.of(context)); + final effectiveCenterTitle = getEffectiveCenterTitle( + Theme.of(context), + actions: actions, + centerTitle: centerTitle, + ); + final channelHeaderTheme = ChannelHeaderTheme.of(context); final defaultSubtitle = subtitle ?? @@ -191,21 +196,4 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { @override final Size preferredSize; - - bool _getEffectiveCenterTitle(ThemeData theme) { - if (centerTitle != null) return centerTitle!; - if (theme.appBarTheme.centerTitle != null) { - return theme.appBarTheme.centerTitle!; - } - switch (theme.platform) { - case TargetPlatform.android: - case TargetPlatform.fuchsia: - case TargetPlatform.linux: - case TargetPlatform.windows: - return false; - case TargetPlatform.iOS: - case TargetPlatform.macOS: - return actions == null || actions!.length < 2; - } - } } diff --git a/packages/stream_chat_flutter/lib/src/utils.dart b/packages/stream_chat_flutter/lib/src/utils.dart index 3825263d..3d012194 100644 --- a/packages/stream_chat_flutter/lib/src/utils.dart +++ b/packages/stream_chat_flutter/lib/src/utils.dart @@ -17,6 +17,28 @@ Future launchURL(BuildContext context, String url) async { } } +/// Get centerTitle considering a default and platform specific behaviour +bool getEffectiveCenterTitle( + ThemeData theme, { + bool? centerTitle, + List? actions, +}) { + if (centerTitle != null) return centerTitle; + if (theme.appBarTheme.centerTitle != null) { + return theme.appBarTheme.centerTitle!; + } + switch (theme.platform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + return false; + case TargetPlatform.iOS: + case TargetPlatform.macOS: + return actions == null || actions.length < 2; + } +} + /// Shows confirmation dialog Future showConfirmationDialog( BuildContext context, { From 28649107ee2d4a20105867f92ae56c1c2dedee62 Mon Sep 17 00:00:00 2001 From: Ayush Shekhar Date: Wed, 27 Apr 2022 18:23:17 +0530 Subject: [PATCH 27/29] Added a new field called push provider name in addDevice api call --- .../guides/adding_push_notifications_v2.mdx | 8 +++++ .../stream_chat/lib/src/client/client.dart | 12 +++++-- .../lib/src/core/api/device_api.dart | 7 ++-- .../test/src/client/client_test.dart | 30 ++++++++++++++++- .../test/src/core/api/device_api_test.dart | 32 ++++++++++++++++++- 5 files changed, 83 insertions(+), 6 deletions(-) diff --git a/docusaurus/docs/Flutter/guides/adding_push_notifications_v2.mdx b/docusaurus/docs/Flutter/guides/adding_push_notifications_v2.mdx index 285c2205..c65b9136 100644 --- a/docusaurus/docs/Flutter/guides/adding_push_notifications_v2.mdx +++ b/docusaurus/docs/Flutter/guides/adding_push_notifications_v2.mdx @@ -86,6 +86,14 @@ firebaseMessaging.onTokenRefresh.listen((token) { }); ``` +Push Notifications v2 also supports specifying a name to the push tokens you register. By setting the optional `pushProviderName` param in the `addDevice` call you can support different configurations between and the device and the `PushProvider`. + +```dart +firebaseMessaging.onTokenRefresh.listen((token) { + client.addDevice(token, PushProvider.firebase, pushProviderName: 'my-custom-config'); +}); +``` + ### Receiving Notifications Push notifications behave a bit differently depending on whether you are using iOS or Android. diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index 18254389..69fd3180 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -818,8 +818,16 @@ class StreamChatClient { ); /// Add a device for Push Notifications. - Future addDevice(String id, PushProvider pushProvider) => - _chatApi.device.addDevice(id, pushProvider); + Future addDevice( + String id, + PushProvider pushProvider, { + String? pushProviderName, + }) => + _chatApi.device.addDevice( + id, + pushProvider, + pushProviderName: pushProviderName, + ); /// Gets a list of user devices. Future getDevices() => _chatApi.device.getDevices(); diff --git a/packages/stream_chat/lib/src/core/api/device_api.dart b/packages/stream_chat/lib/src/core/api/device_api.dart index f4b7f0b1..df137cdc 100644 --- a/packages/stream_chat/lib/src/core/api/device_api.dart +++ b/packages/stream_chat/lib/src/core/api/device_api.dart @@ -29,13 +29,16 @@ class DeviceApi { /// Add a device for Push Notifications. Future addDevice( String deviceId, - PushProvider pushProvider, - ) async { + PushProvider pushProvider, { + String? pushProviderName, + }) async { final response = await _client.post( '/devices', data: { 'id': deviceId, 'push_provider': pushProvider.name, + if (pushProviderName != null && pushProviderName.isNotEmpty) + 'push_provider_name': pushProviderName, }, ); return EmptyResponse.fromJson(response.data); diff --git a/packages/stream_chat/test/src/client/client_test.dart b/packages/stream_chat/test/src/client/client_test.dart index 5ec2bfeb..4947bc72 100644 --- a/packages/stream_chat/test/src/client/client_test.dart +++ b/packages/stream_chat/test/src/client/client_test.dart @@ -1171,7 +1171,7 @@ void main() { verifyNoMoreInteractions(api.channel); }); - test('`.addDevice`', () async { + test('`.addDevice should work`', () async { const id = 'test-device-id'; const provider = PushProvider.firebase; @@ -1185,6 +1185,34 @@ void main() { verifyNoMoreInteractions(api.device); }); + test('`.addDevice should work with pushProviderName`', () async { + const id = 'test-device-id'; + const provider = PushProvider.firebase; + const pushProviderName = 'my-custom-config'; + + when( + () => api.device.addDevice( + id, + provider, + pushProviderName: pushProviderName, + ), + ).thenAnswer((_) async => EmptyResponse()); + + final res = await client.addDevice( + id, + provider, + pushProviderName: pushProviderName, + ); + expect(res, isNotNull); + + verify(() => api.device.addDevice( + id, + provider, + pushProviderName: pushProviderName, + )).called(1); + verifyNoMoreInteractions(api.device); + }); + test('`.getDevices`', () async { final devices = List.generate( 3, diff --git a/packages/stream_chat/test/src/core/api/device_api_test.dart b/packages/stream_chat/test/src/core/api/device_api_test.dart index 7d4f59fd..13cfe4dc 100644 --- a/packages/stream_chat/test/src/core/api/device_api_test.dart +++ b/packages/stream_chat/test/src/core/api/device_api_test.dart @@ -20,7 +20,7 @@ void main() { deviceApi = DeviceApi(client); }); - test('addDevice', () async { + test('addDevice should work', () async { const deviceId = 'test-device-id'; const pushProvider = PushProvider.firebase; @@ -44,6 +44,36 @@ void main() { verifyNoMoreInteractions(client); }); + test('addDevice should work with pushProviderName', () async { + const deviceId = 'test-device-id'; + const pushProvider = PushProvider.firebase; + const pushProviderName = 'my-custom-config'; + + const path = '/devices'; + + when(() => client.post( + path, + data: { + 'id': deviceId, + 'push_provider': pushProvider.name, + 'push_provider_name': pushProviderName, + }, + )) + .thenAnswer( + (_) async => successResponse(path, data: {})); + + final res = await deviceApi.addDevice( + deviceId, + pushProvider, + pushProviderName: pushProviderName, + ); + + expect(res, isNotNull); + + verify(() => client.post(path, data: any(named: 'data'))).called(1); + verifyNoMoreInteractions(client); + }); + test('getDevices', () async { const path = '/devices'; From 707e6989ecb5087dca0865f93880897b79e8fa4c Mon Sep 17 00:00:00 2001 From: Ayush Shekhar Date: Wed, 27 Apr 2022 18:26:14 +0530 Subject: [PATCH 28/29] Updated changelog --- packages/stream_chat/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index f0707cdb..0680109c 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,3 +1,9 @@ +## Upcoming + +✅ Added + +- Added `push_provider_name` to `addDevice` API call + ## 3.6.1 🐞 Fixed From a370cb13252710751b2babc7f69c6b490d1323af Mon Sep 17 00:00:00 2001 From: Ayush Shekhar Date: Wed, 27 Apr 2022 18:34:24 +0530 Subject: [PATCH 29/29] Fixed typo in docs change --- docusaurus/docs/Flutter/guides/adding_push_notifications_v2.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/Flutter/guides/adding_push_notifications_v2.mdx b/docusaurus/docs/Flutter/guides/adding_push_notifications_v2.mdx index c65b9136..917d9216 100644 --- a/docusaurus/docs/Flutter/guides/adding_push_notifications_v2.mdx +++ b/docusaurus/docs/Flutter/guides/adding_push_notifications_v2.mdx @@ -86,7 +86,7 @@ firebaseMessaging.onTokenRefresh.listen((token) { }); ``` -Push Notifications v2 also supports specifying a name to the push tokens you register. By setting the optional `pushProviderName` param in the `addDevice` call you can support different configurations between and the device and the `PushProvider`. +Push Notifications v2 also supports specifying a name to the push device tokens you register. By setting the optional `pushProviderName` param in the `addDevice` call you can support different configurations between the device and the `PushProvider`. ```dart firebaseMessaging.onTokenRefresh.listen((token) {