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 00d772729..69971937b 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,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.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} /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/packages/stream_chat_flutter/screenshots/channel_header.png) @@ -63,7 +63,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget this.showConnectionStateTile = false, this.title, this.subtitle, - this.centerTitle, + this.centerTitle = true, this.leading, this.actions, this.bottom, @@ -104,7 +104,7 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget final Widget? subtitle; /// Whether the title should be centered - final bool? centerTitle; + final bool centerTitle; /// Leading widget final Widget? leading; @@ -173,75 +173,89 @@ class StreamChannelHeader extends StatelessWidget implements PreferredSizeWidget break; } - final theme = Theme.of(context); - final colorScheme = context.streamColorScheme; - return StreamInfoTile( showMessage: showConnectionStateTile && showStatus, message: statusString, - child: AppBar( - toolbarTextStyle: theme.textTheme.bodyMedium, - titleTextStyle: theme.textTheme.titleLarge, - systemOverlayStyle: theme.brightness == Brightness.dark - ? SystemUiOverlayStyle.light - : SystemUiOverlayStyle.dark, + child: StreamAppBar( + titleTextStyle: Theme.of(context).textTheme.titleLarge, elevation: elevation, scrolledUnderElevation: scrolledUnderElevation, - leading: leadingWidget, + leading: Padding( + padding: EdgeInsets.only(left: context.streamSpacing.sm), + child: leadingWidget, + ), + leadingWidth: StreamAvatarSize.lg.value, + titleSpacing: context.streamSpacing.sm, bottom: bottom, bottomOpacity: bottomOpacity, - shape: LinearBorder( - side: BorderSide( - color: colorScheme.borderDefault, - width: 1, - ), - bottom: const LinearBorderEdge(), - ), backgroundColor: backgroundColor ?? channelHeaderTheme.color, actions: actions ?? [ - Padding( - padding: const EdgeInsets.only(right: 10), - child: Center( - child: GestureDetector( - onTap: onImageTap, - child: StreamChannelAvatar( - size: .lg, - channel: channel, + if (effectiveCenterTitle) + Padding( + padding: EdgeInsets.only(right: context.streamSpacing.sm), + child: Center( + child: GestureDetector( + onTap: onImageTap, + child: StreamChannelAvatar( + size: .lg, + channel: channel, + ), ), ), ), - ), ], centerTitle: centerTitle, - title: InkWell( - onTap: onTitleTap, - child: SizedBox( - height: preferredSize.height, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: effectiveCenterTitle ? CrossAxisAlignment.center : CrossAxisAlignment.stretch, - children: [ - title ?? - StreamChannelName( - channel: channel, - textStyle: - channelHeaderTheme.titleStyle ?? - context.streamTextTheme.headingSm.copyWith( - color: context.streamColorScheme.textPrimary, + title: Row( + spacing: context.streamSpacing.sm, + children: [ + if (!effectiveCenterTitle) ...[ + GestureDetector( + onTap: onImageTap, + child: StreamChannelAvatar( + size: .lg, + channel: channel, + ), + ), + ], + Expanded( + child: InkWell( + onTap: onTitleTap, + child: SizedBox( + height: preferredSize.height, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: effectiveCenterTitle + ? CrossAxisAlignment.center + : CrossAxisAlignment.stretch, + children: [ + title ?? + StreamChannelName( + channel: channel, + textStyle: + channelHeaderTheme.titleStyle ?? + context.streamTextTheme.headingSm.copyWith( + color: context.streamColorScheme.textPrimary, + ), ), - ), - const SizedBox(height: 2), - subtitle ?? - StreamChannelInfo( - showTypingIndicator: showTypingIndicator, - channel: channel, - textStyle: channelHeaderTheme.subtitleStyle, - ), - ], + const SizedBox(height: 2), + subtitle ?? + StreamChannelInfo( + showTypingIndicator: showTypingIndicator, + channel: channel, + textStyle: + channelHeaderTheme.subtitleStyle ?? + context.streamTextTheme.captionDefault.copyWith( + color: context.streamColorScheme.textSecondary, + ), + ), + ], + ), + ), + ), ), - ), + ], ), ), ); 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 bf7c50ca6..148d25c46 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,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -50,7 +49,7 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi this.showConnectionStateTile = false, this.preNavigationCallback, this.subtitle, - this.centerTitle, + this.centerTitle = true, this.leading, this.actions, this.backgroundColor, @@ -82,7 +81,7 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi final Widget? subtitle; /// Whether the title should be centered - final bool? centerTitle; + final bool centerTitle; /// Leading widget /// @@ -130,49 +129,39 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi } final channelListHeaderThemeData = StreamChannelListHeaderTheme.of(context); - final theme = Theme.of(context); - final colorScheme = context.streamColorScheme; return StreamInfoTile( showMessage: showConnectionStateTile && showStatus, message: statusString, - child: AppBar( - toolbarTextStyle: theme.textTheme.bodyMedium, - titleTextStyle: theme.textTheme.titleLarge, - systemOverlayStyle: theme.brightness == Brightness.dark - ? SystemUiOverlayStyle.light - : SystemUiOverlayStyle.dark, + child: StreamAppBar( elevation: elevation, scrolledUnderElevation: scrolledUnderElevation, backgroundColor: backgroundColor ?? channelListHeaderThemeData.color, centerTitle: centerTitle, - shape: LinearBorder( - side: BorderSide( - color: colorScheme.borderDefault, - width: 1, - ), - bottom: const LinearBorderEdge(), - ), leading: switch ((leading, user)) { (final leading?, _) => leading, - (_, final user?) => Center( - child: GestureDetector( - onTap: switch (onUserAvatarTap) { - final onTap? => () => onTap(user), - _ => () { - preNavigationCallback?.call(); - Scaffold.of(context).openDrawer(); + (_, final user?) => Padding( + padding: EdgeInsets.only(left: context.streamSpacing.sm), + child: Center( + child: GestureDetector( + onTap: switch (onUserAvatarTap) { + final onTap? => () => onTap(user), + _ => () { + preNavigationCallback?.call(); + Scaffold.of(context).openDrawer(); + }, }, - }, - child: StreamUserAvatar( - size: .lg, - user: user, - showOnlineIndicator: false, + child: StreamUserAvatar( + size: .lg, + user: user, + showOnlineIndicator: false, + ), ), ), ), _ => const Empty(), }, + actionsPadding: EdgeInsets.only(right: context.streamSpacing.sm), actions: actions ?? [ @@ -222,12 +211,10 @@ class StreamChannelListHeader extends StatelessWidget implements PreferredSizeWi class _ConnectedTitleState extends StatelessWidget { @override Widget build(BuildContext context) { - final chatThemeData = StreamChatTheme.of(context); + final textTheme = context.streamTextTheme; return Text( context.translations.streamChatLabel, - style: chatThemeData.textTheme.headlineBold.copyWith( - color: chatThemeData.colorTheme.textHighEmphasis, - ), + style: textTheme.headingSm, ); } } diff --git a/packages/stream_chat_flutter/lib/src/gallery/gallery_header.dart b/packages/stream_chat_flutter/lib/src/gallery/gallery_header.dart index 3291f4ac7..32c922c6f 100644 --- a/packages/stream_chat_flutter/lib/src/gallery/gallery_header.dart +++ b/packages/stream_chat_flutter/lib/src/gallery/gallery_header.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:stream_chat_flutter/src/attachment_actions_modal/attachment_actions_modal.dart'; import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; @@ -78,18 +77,16 @@ class StreamGalleryHeader extends StatelessWidget implements PreferredSizeWidget @override Widget build(BuildContext context) { final galleryHeaderThemeData = StreamGalleryHeaderTheme.of(context); - final theme = Theme.of(context); - return AppBar( - toolbarTextStyle: theme.textTheme.bodyMedium, - titleTextStyle: theme.textTheme.titleLarge, - systemOverlayStyle: theme.brightness == Brightness.dark ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark, + final textTheme = context.streamTextTheme; + + return StreamAppBar( elevation: elevation, leading: showBackButton ? IconButton( icon: Icon( - context.streamIcons.crossMedium, + context.streamIcons.arrowLeft, color: galleryHeaderThemeData.closeButtonColor, - size: 24, + size: 20, ), onPressed: onBackPressed, ) @@ -100,7 +97,7 @@ class StreamGalleryHeader extends StatelessWidget implements PreferredSizeWidget if (!message.isEphemeral) IconButton( icon: Icon( - context.streamIcons.dotsGrid1x3Vertical, + context.streamIcons.dotGrid1x3Horizontal, color: galleryHeaderThemeData.iconMenuPointColor, ), onPressed: () => _showMessageActionModalBottomSheet(context), @@ -119,11 +116,13 @@ class StreamGalleryHeader extends StatelessWidget implements PreferredSizeWidget children: [ Text( userName, - style: galleryHeaderThemeData.titleTextStyle, + style: galleryHeaderThemeData.titleTextStyle ?? textTheme.headingSm, ), Text( sentAt, - style: galleryHeaderThemeData.subtitleTextStyle, + style: + galleryHeaderThemeData.subtitleTextStyle ?? + textTheme.captionDefault.copyWith(color: context.streamColorScheme.textSecondary), ), ], ), diff --git a/packages/stream_chat_flutter/lib/src/localization/translations.dart b/packages/stream_chat_flutter/lib/src/localization/translations.dart index d147e25c2..430341058 100644 --- a/packages/stream_chat_flutter/lib/src/localization/translations.dart +++ b/packages/stream_chat_flutter/lib/src/localization/translations.dart @@ -597,6 +597,24 @@ abstract class Translations { /// The text displaying the reminder time (e.g. "Today at 3:00 PM"). String reminderAtText(String time); + + /// The label for "Create a poll and let everyone vote!" + String get createPollPromptLabel; + + /// The label for "Take a photo and share" + String get takePhotoAndShareLabel; + + /// The label for "Take a video and share" + String get takeVideoAndShareLabel; + + /// The label for "Open camera" + String get openCameraLabel; + + /// The label for "Select files to share" + String get selectFilesToShareLabel; + + /// The label for "Open files" + String get openFilesLabel; } /// Default implementation of Translation strings for the stream chat widgets @@ -1308,4 +1326,22 @@ Attachment limit exceeded: it's not possible to add more than $limit attachments @override String reminderAtText(String time) => 'Today at $time'; + + @override + String get createPollPromptLabel => 'Create a poll and let everyone vote!'; + + @override + String get takePhotoAndShareLabel => 'Take a photo and share'; + + @override + String get takeVideoAndShareLabel => 'Take a video and share'; + + @override + String get openCameraLabel => 'Open camera'; + + @override + String get selectFilesToShareLabel => 'Select files to share'; + + @override + String get openFilesLabel => 'Open files'; } diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_file_picker.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_file_picker.dart index 69a0a3b60..3640fdbe6 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_file_picker.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_file_picker.dart @@ -80,30 +80,33 @@ class StreamFilePicker extends StatelessWidget { return OptionDrawer( child: EndOfFrameCallbackWidget( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - size: 32, - context.streamIcons.fileBend, - color: colorScheme.textTertiary, - ), - SizedBox(height: spacing.xs), - Text( - 'Select files to share', - style: textTheme.bodyDefault.copyWith( - color: colorScheme.textSecondary, + child: Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + size: 32, + context.streamIcons.fileBend, + color: colorScheme.textTertiary, ), - textAlign: TextAlign.center, - ), - SizedBox(height: spacing.md), - StreamButton( - type: .outline, - style: .secondary, - onTap: onPickFile, - label: 'Open files', - ), - ], + SizedBox(height: spacing.xs), + Text( + context.translations.selectFilesToShareLabel, + style: textTheme.bodyDefault.copyWith( + color: colorScheme.textSecondary, + ), + textAlign: TextAlign.center, + ), + SizedBox(height: spacing.md), + StreamButton( + type: .outline, + style: .secondary, + onTap: onPickFile, + label: context.translations.openFilesLabel, + ), + ], + ), ), onEndOfFrame: (_) => onPickFile(), errorBuilder: (context, error, stacktrace) { diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_image_picker.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_image_picker.dart index 35968f2a3..0a47c6a4a 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_image_picker.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_image_picker.dart @@ -57,28 +57,31 @@ class StreamImagePicker extends StatelessWidget { return OptionDrawer( child: EndOfFrameCallbackWidget( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - size: 32, - context.streamIcons.camera1, - color: colorScheme.textTertiary, - ), - SizedBox(height: spacing.xs), - Text( - 'Take a photo and share', - style: textTheme.bodyDefault.copyWith(color: colorScheme.textSecondary), - textAlign: TextAlign.center, - ), - SizedBox(height: spacing.md), - StreamButton( - type: .outline, - style: .secondary, - onTap: onPickImage, - label: 'Open camera', - ), - ], + child: Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + size: 32, + context.streamIcons.camera1, + color: colorScheme.textTertiary, + ), + SizedBox(height: spacing.xs), + Text( + context.translations.takePhotoAndShareLabel, + style: textTheme.bodyDefault.copyWith(color: colorScheme.textSecondary), + textAlign: TextAlign.center, + ), + SizedBox(height: spacing.md), + StreamButton( + type: .outline, + style: .secondary, + onTap: onPickImage, + label: context.translations.openCameraLabel, + ), + ], + ), ), onEndOfFrame: (_) => onPickImage(), errorBuilder: (context, error, stacktrace) { diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_poll_creator.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_poll_creator.dart index 4f1703e67..c7e525520 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_poll_creator.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_poll_creator.dart @@ -39,28 +39,31 @@ class StreamPollCreator extends StatelessWidget { return OptionDrawer( child: EndOfFrameCallbackWidget( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - size: 32, - context.streamIcons.chart5, - color: colorScheme.textTertiary, - ), - SizedBox(height: spacing.xs), - Text( - 'Create a poll and let everyone vote!', - style: textTheme.bodyDefault.copyWith(color: colorScheme.textSecondary), - textAlign: TextAlign.center, - ), - SizedBox(height: spacing.md), - StreamButton( - type: .outline, - style: .secondary, - onTap: _openCreatePollFlow, - label: context.translations.createPollLabel(), - ), - ], + child: Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + size: 32, + context.streamIcons.chart5, + color: colorScheme.textTertiary, + ), + SizedBox(height: spacing.xs), + Text( + context.translations.createPollPromptLabel, + style: textTheme.bodyDefault.copyWith(color: colorScheme.textSecondary), + textAlign: TextAlign.center, + ), + SizedBox(height: spacing.md), + StreamButton( + type: .outline, + style: .secondary, + onTap: _openCreatePollFlow, + label: context.translations.createPollLabel(), + ), + ], + ), ), onEndOfFrame: (_) => _openCreatePollFlow(), errorBuilder: (context, error, stacktrace) { diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_video_picker.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_video_picker.dart index ee67cadcc..409b19fb3 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_video_picker.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_video_picker.dart @@ -47,28 +47,31 @@ class StreamVideoPicker extends StatelessWidget { return OptionDrawer( child: EndOfFrameCallbackWidget( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - size: 32, - context.streamIcons.video, - color: colorScheme.textTertiary, - ), - SizedBox(height: spacing.xs), - Text( - 'Take a video and share', - style: textTheme.bodyDefault.copyWith(color: colorScheme.textSecondary), - textAlign: TextAlign.center, - ), - SizedBox(height: spacing.md), - StreamButton( - type: .outline, - style: .secondary, - onTap: onPickVideo, - label: 'Open camera', - ), - ], + child: Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + size: 32, + context.streamIcons.video, + color: colorScheme.textTertiary, + ), + SizedBox(height: spacing.xs), + Text( + context.translations.takeVideoAndShareLabel, + style: textTheme.bodyDefault.copyWith(color: colorScheme.textSecondary), + textAlign: TextAlign.center, + ), + SizedBox(height: spacing.md), + StreamButton( + type: .outline, + style: .secondary, + onTap: onPickVideo, + label: context.translations.openCameraLabel, + ), + ], + ), ), onEndOfFrame: (_) => onPickVideo(), errorBuilder: (context, error, stacktrace) { 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 8f8f31c02..ee377dcf0 100644 --- a/packages/stream_chat_flutter/lib/src/misc/back_button.dart +++ b/packages/stream_chat_flutter/lib/src/misc/back_button.dart @@ -27,8 +27,8 @@ class StreamBackButton extends StatelessWidget { final theme = StreamChatTheme.of(context); Widget icon = Icon( - context.streamIcons.chevronLeft, - size: 24, + context.streamIcons.arrowLeft, + size: 20, color: theme.colorTheme.textHighEmphasis, ); 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 9f7eb4ebd..73badc2f1 100644 --- a/packages/stream_chat_flutter/lib/src/misc/thread_header.dart +++ b/packages/stream_chat_flutter/lib/src/misc/thread_header.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; +import 'package:stream_core_flutter/stream_core_flutter.dart'; /// {@template streamThreadHeader} /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/packages/stream_chat_flutter/screenshots/thread_header.png) @@ -66,7 +66,7 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget this.onBackPressed, this.title, this.subtitle, - this.centerTitle, + this.centerTitle = true, this.leading, this.actions, this.onTitleTap, @@ -99,7 +99,7 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget final Widget? subtitle; /// Whether the title should be centered - final bool? centerTitle; + final bool centerTitle; /// Leading widget final Widget? leading; @@ -152,12 +152,8 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget ) : const SizedBox.shrink()); - final theme = Theme.of(context); - return AppBar( + return StreamAppBar( automaticallyImplyLeading: false, - toolbarTextStyle: theme.textTheme.bodyMedium, - titleTextStyle: theme.textTheme.titleLarge, - systemOverlayStyle: theme.brightness == Brightness.dark ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark, elevation: elevation, scrolledUnderElevation: scrolledUnderElevation, leading: @@ -172,13 +168,6 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget backgroundColor: backgroundColor ?? channelHeaderTheme.color, centerTitle: centerTitle, actions: actions, - shape: LinearBorder( - side: BorderSide( - color: colorScheme.borderDefault, - width: 1, - ), - bottom: const LinearBorderEdge(), - ), title: InkWell( onTap: onTitleTap, child: SizedBox( @@ -197,7 +186,9 @@ class StreamThreadHeader extends StatelessWidget implements PreferredSizeWidget if (showTypingIndicator) StreamTypingIndicator( channel: StreamChannel.of(context).channel, - style: channelHeaderTheme.subtitleStyle, + style: + channelHeaderTheme.subtitleStyle ?? + textTheme.captionDefault.copyWith(color: colorScheme.textSecondary), parentId: parent.id, alternativeWidget: defaultSubtitle, ) diff --git a/packages/stream_chat_flutter/lib/src/utils/message_preview_formatter.dart b/packages/stream_chat_flutter/lib/src/utils/message_preview_formatter.dart index 0145ebffd..08cf4937c 100644 --- a/packages/stream_chat_flutter/lib/src/utils/message_preview_formatter.dart +++ b/packages/stream_chat_flutter/lib/src/utils/message_preview_formatter.dart @@ -1,5 +1,6 @@ import 'package:flutter/widgets.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; +import 'package:stream_core_flutter/stream_core_flutter.dart'; /// {@template messagePreviewFormatter} /// Formats message previews for display. @@ -236,7 +237,7 @@ class StreamMessagePreviewFormatter implements MessagePreviewFormatter { ); } - TextSpan _textSpanWithMentions(String text, List mentionedUsers) { + TextSpan _textSpanWithMentions(String text, List mentionedUsers, StreamColorScheme colorScheme) { if (mentionedUsers.isEmpty) return TextSpan(text: text); final mentionRegex = RegExp( @@ -251,7 +252,7 @@ class StreamMessagePreviewFormatter implements MessagePreviewFormatter { if (mentionedUsers.any((it) => '@${it.name}' == part)) { return TextSpan( text: part, - style: const TextStyle(fontWeight: FontWeight.bold), + style: TextStyle(fontWeight: FontWeight.bold, color: colorScheme.accentPrimary), ); } return TextSpan(text: part); @@ -296,9 +297,10 @@ class StreamMessagePreviewFormatter implements MessagePreviewFormatter { final attachments = message.attachments; final mentionedUsers = message.mentionedUsers; + final colorScheme = context.streamColorScheme; if (attachments.isEmpty) { - return messageText != null ? _textSpanWithMentions(messageText, mentionedUsers) : null; + return messageText != null ? _textSpanWithMentions(messageText, mentionedUsers, colorScheme) : null; } return formatMessageAttachments( @@ -452,9 +454,10 @@ class StreamMessagePreviewFormatter implements MessagePreviewFormatter { List mentionedUsers = const [], bool showCaption = true, }) { + final colorScheme = context.streamColorScheme; final attachment = attachments.firstOrNull; if (attachment == null) { - return messageText != null ? _textSpanWithMentions(messageText, mentionedUsers) : null; + return messageText != null ? _textSpanWithMentions(messageText, mentionedUsers, colorScheme) : null; } final mixedTypes = attachments.any((it) => it.type != attachment.type); @@ -465,7 +468,7 @@ class StreamMessagePreviewFormatter implements MessagePreviewFormatter { children: [ prefix, WidgetSpan(child: SizedBox(width: context.streamSpacing.xxs)), - _textSpanWithMentions(messageText, mentionedUsers), + _textSpanWithMentions(messageText, mentionedUsers, colorScheme), ], ); } @@ -608,6 +611,7 @@ class StreamMessagePreviewFormatter implements MessagePreviewFormatter { Location location, { bool showCaption = true, }) { + final colorScheme = context.streamColorScheme; return TextSpan( children: [ WidgetSpan(child: Icon(context.streamIcons.mapPin, size: 16)), @@ -615,7 +619,7 @@ class StreamMessagePreviewFormatter implements MessagePreviewFormatter { child: SizedBox(width: context.streamSpacing.xxs), ), if (message.text?.trim() case final messageText? when messageText.isNotEmpty && showCaption) ...[ - _textSpanWithMentions(messageText, message.mentionedUsers), + _textSpanWithMentions(messageText, message.mentionedUsers, colorScheme), ] else ...[ TextSpan(text: context.translations.locationLabel(isLive: location.isLive)), ], diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 86de68bf3..b4c46aa4d 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -137,6 +137,7 @@ export 'src/misc/info_tile.dart'; export 'src/misc/markdown_message.dart'; export 'src/misc/option_list_tile.dart'; export 'src/misc/reaction_icon_resolver.dart'; + export 'src/misc/stream_modal.dart'; export 'src/misc/stream_neumorphic_button.dart'; export 'src/misc/swipeable.dart'; 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 fbdc6b4d8..3f1653c09 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 @@ -268,6 +268,7 @@ void main() { channel: channel, child: const Scaffold( body: StreamChannelHeader( + centerTitle: true, leading: Text('leading'), subtitle: Text('subtitle'), actions: [ diff --git a/packages/stream_chat_flutter/test/src/channel/goldens/ci/channel_header_bottom_widget.png b/packages/stream_chat_flutter/test/src/channel/goldens/ci/channel_header_bottom_widget.png index 24901d102..f587d9b85 100644 Binary files a/packages/stream_chat_flutter/test/src/channel/goldens/ci/channel_header_bottom_widget.png and b/packages/stream_chat_flutter/test/src/channel/goldens/ci/channel_header_bottom_widget.png differ diff --git a/packages/stream_chat_flutter/test/src/gallery/goldens/ci/gallery_header_0.png b/packages/stream_chat_flutter/test/src/gallery/goldens/ci/gallery_header_0.png index f1be7db16..dbb90007e 100644 Binary files a/packages/stream_chat_flutter/test/src/gallery/goldens/ci/gallery_header_0.png and b/packages/stream_chat_flutter/test/src/gallery/goldens/ci/gallery_header_0.png differ diff --git a/packages/stream_chat_localizations/example/lib/add_new_lang.dart b/packages/stream_chat_localizations/example/lib/add_new_lang.dart index d1f714049..027fa4823 100644 --- a/packages/stream_chat_localizations/example/lib/add_new_lang.dart +++ b/packages/stream_chat_localizations/example/lib/add_new_lang.dart @@ -733,6 +733,24 @@ class NnStreamChatLocalizations extends GlobalStreamChatLocalizations { @override String reminderAtText(String time) => 'Today at $time'; + + @override + String get createPollPromptLabel => 'Create a poll and let everyone vote!'; + + @override + String get takePhotoAndShareLabel => 'Take a photo and share'; + + @override + String get takeVideoAndShareLabel => 'Take a video and share'; + + @override + String get openCameraLabel => 'Open camera'; + + @override + String get selectFilesToShareLabel => 'Select files to share'; + + @override + String get openFilesLabel => 'Open files'; } void main() async { diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart index c3270bdbb..928d3a069 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart @@ -707,4 +707,22 @@ class StreamChatLocalizationsCa extends GlobalStreamChatLocalizations { @override String reminderAtText(String time) => 'Avui a les $time'; + + @override + String get createPollPromptLabel => 'Crea una enquesta i deixa que tothom voti!'; + + @override + String get takePhotoAndShareLabel => 'Fes una foto i comparteix'; + + @override + String get takeVideoAndShareLabel => 'Grava un vídeo i comparteix'; + + @override + String get openCameraLabel => 'Obrir càmera'; + + @override + String get selectFilesToShareLabel => 'Seleccioneu fitxers per compartir'; + + @override + String get openFilesLabel => 'Obrir fitxers'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart index 0a0223c41..51a6edd03 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart @@ -705,4 +705,22 @@ class StreamChatLocalizationsDe extends GlobalStreamChatLocalizations { @override String reminderAtText(String time) => 'Heute um $time'; + + @override + String get createPollPromptLabel => 'Erstelle eine Umfrage und lass alle abstimmen!'; + + @override + String get takePhotoAndShareLabel => 'Foto aufnehmen und teilen'; + + @override + String get takeVideoAndShareLabel => 'Video aufnehmen und teilen'; + + @override + String get openCameraLabel => 'Kamera öffnen'; + + @override + String get selectFilesToShareLabel => 'Dateien zum Teilen auswählen'; + + @override + String get openFilesLabel => 'Dateien öffnen'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart index 8bc543fee..85cc7f795 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart @@ -705,4 +705,22 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations { @override String reminderAtText(String time) => 'Today at $time'; + + @override + String get createPollPromptLabel => 'Create a poll and let everyone vote!'; + + @override + String get takePhotoAndShareLabel => 'Take a photo and share'; + + @override + String get takeVideoAndShareLabel => 'Take a video and share'; + + @override + String get openCameraLabel => 'Open camera'; + + @override + String get selectFilesToShareLabel => 'Select files to share'; + + @override + String get openFilesLabel => 'Open files'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart index 837f02bec..387d7c4cd 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart @@ -709,4 +709,22 @@ No es posible añadir más de $limit archivos adjuntos @override String reminderAtText(String time) => 'Hoy a las $time'; + + @override + String get createPollPromptLabel => '¡Crea una encuesta y deja que todos voten!'; + + @override + String get takePhotoAndShareLabel => 'Toma una foto y comparte'; + + @override + String get takeVideoAndShareLabel => 'Graba un video y comparte'; + + @override + String get openCameraLabel => 'Abrir cámara'; + + @override + String get selectFilesToShareLabel => 'Selecciona archivos para compartir'; + + @override + String get openFilesLabel => 'Abrir archivos'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart index 9e4b6c3eb..c67308f15 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart @@ -711,4 +711,22 @@ Limite de pièces jointes dépassée : il n'est pas possible d'ajouter plus de $ @override String reminderAtText(String time) => "Aujourd'hui à $time"; + + @override + String get createPollPromptLabel => 'Créez un sondage et laissez tout le monde voter !'; + + @override + String get takePhotoAndShareLabel => 'Prendre une photo et partager'; + + @override + String get takeVideoAndShareLabel => 'Prendre une vidéo et partager'; + + @override + String get openCameraLabel => 'Ouvrir la caméra'; + + @override + String get selectFilesToShareLabel => 'Sélectionnez des fichiers à partager'; + + @override + String get openFilesLabel => 'Ouvrir des fichiers'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart index d0eb2402f..5829f937d 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart @@ -709,4 +709,22 @@ class StreamChatLocalizationsHi extends GlobalStreamChatLocalizations { @override String reminderAtText(String time) => 'आज $time पर'; + + @override + String get createPollPromptLabel => 'पोल बनाएं और सबको वोट करने दें!'; + + @override + String get takePhotoAndShareLabel => 'फ़ोटो लें और साझा करें'; + + @override + String get takeVideoAndShareLabel => 'वीडियो लें और साझा करें'; + + @override + String get openCameraLabel => 'कैमरा खोलें'; + + @override + String get selectFilesToShareLabel => 'साझा करने के लिए फ़ाइलें चुनें'; + + @override + String get openFilesLabel => 'फ़ाइलें खोलें'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart index 8eb53ec34..c39086d7e 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart @@ -714,4 +714,22 @@ Attenzione: il limite massimo di $limit file è stato superato. @override String reminderAtText(String time) => 'Oggi alle $time'; + + @override + String get createPollPromptLabel => 'Crea un sondaggio e fai votare tutti!'; + + @override + String get takePhotoAndShareLabel => 'Scatta una foto e condividi'; + + @override + String get takeVideoAndShareLabel => 'Registra un video e condividi'; + + @override + String get openCameraLabel => 'Apri fotocamera'; + + @override + String get selectFilesToShareLabel => 'Seleziona i file da condividere'; + + @override + String get openFilesLabel => 'Apri file'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart index ebff58dd4..e889aace5 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart @@ -691,4 +691,22 @@ class StreamChatLocalizationsJa extends GlobalStreamChatLocalizations { @override String reminderAtText(String time) => '今日 $time'; + + @override + String get createPollPromptLabel => '投票を作成してみんなに投票してもらおう!'; + + @override + String get takePhotoAndShareLabel => '写真を撮って共有'; + + @override + String get takeVideoAndShareLabel => '動画を撮って共有'; + + @override + String get openCameraLabel => 'カメラを開く'; + + @override + String get selectFilesToShareLabel => '共有するファイルを選択'; + + @override + String get openFilesLabel => 'ファイルを開く'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart index a376d43d0..bdb83d04c 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart @@ -694,4 +694,22 @@ class StreamChatLocalizationsKo extends GlobalStreamChatLocalizations { @override String reminderAtText(String time) => '오늘 $time'; + + @override + String get createPollPromptLabel => '투표를 만들고 모두에게 투표하게 하세요!'; + + @override + String get takePhotoAndShareLabel => '사진을 찍고 공유'; + + @override + String get takeVideoAndShareLabel => '동영상을 찍고 공유'; + + @override + String get openCameraLabel => '카메라 열기'; + + @override + String get selectFilesToShareLabel => '공유할 파일 선택'; + + @override + String get openFilesLabel => '파일 열기'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart index b37f8fbd4..404657694 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart @@ -693,4 +693,22 @@ class StreamChatLocalizationsNo extends GlobalStreamChatLocalizations { @override String reminderAtText(String time) => 'I dag kl. $time'; + + @override + String get createPollPromptLabel => 'Lag en avstemning og la alle stemme!'; + + @override + String get takePhotoAndShareLabel => 'Ta et bilde og del'; + + @override + String get takeVideoAndShareLabel => 'Ta en video og del'; + + @override + String get openCameraLabel => 'Åpne kamera'; + + @override + String get selectFilesToShareLabel => 'Velg filer å dele'; + + @override + String get openFilesLabel => 'Åpne filer'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart index 3bc904e14..f8e314915 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart @@ -708,4 +708,22 @@ Não é possível adicionar mais de $limit arquivos de uma vez @override String reminderAtText(String time) => 'Hoje às $time'; + + @override + String get createPollPromptLabel => 'Crie uma enquete e deixe todos votarem!'; + + @override + String get takePhotoAndShareLabel => 'Tire uma foto e compartilhe'; + + @override + String get takeVideoAndShareLabel => 'Grave um vídeo e compartilhe'; + + @override + String get openCameraLabel => 'Abrir câmera'; + + @override + String get selectFilesToShareLabel => 'Selecione arquivos para compartilhar'; + + @override + String get openFilesLabel => 'Abrir arquivos'; } diff --git a/packages/stream_chat_localizations/test/translations_test.dart b/packages/stream_chat_localizations/test/translations_test.dart index bab00b5ec..f43cf3ddf 100644 --- a/packages/stream_chat_localizations/test/translations_test.dart +++ b/packages/stream_chat_localizations/test/translations_test.dart @@ -321,6 +321,12 @@ void main() { expect(localizations.viewLabel, isNotNull); expect(localizations.reminderSetLabel, isNotNull); expect(localizations.reminderAtText('3:00 PM'), isNotNull); + expect(localizations.createPollPromptLabel, isNotNull); + expect(localizations.takePhotoAndShareLabel, isNotNull); + expect(localizations.takeVideoAndShareLabel, isNotNull); + expect(localizations.openCameraLabel, isNotNull); + expect(localizations.selectFilesToShareLabel, isNotNull); + expect(localizations.openFilesLabel, isNotNull); }); } diff --git a/sample_app/lib/widgets/location/location_picker_option.dart b/sample_app/lib/widgets/location/location_picker_option.dart index e32ba43ee..d1aaecb95 100644 --- a/sample_app/lib/widgets/location/location_picker_option.dart +++ b/sample_app/lib/widgets/location/location_picker_option.dart @@ -27,10 +27,12 @@ class LocationPicker extends StatelessWidget { return OptionDrawer( child: EndOfFrameCallbackWidget( - child: Icon( - size: 148, - Icons.near_me_rounded, - color: colorTheme.disabled, + child: Center( + child: Icon( + size: 148, + Icons.near_me_rounded, + color: colorTheme.disabled, + ), ), onEndOfFrame: (context) async { final result = await runInPermissionRequestLock(() {