diff --git a/examples/flyer_chat/assets/pattern.png b/examples/flyer_chat/assets/pattern.png new file mode 100644 index 00000000..87657102 Binary files /dev/null and b/examples/flyer_chat/assets/pattern.png differ diff --git a/examples/flyer_chat/lib/api/api.dart b/examples/flyer_chat/lib/api/api.dart index 8d7a2bb5..63c07137 100644 --- a/examples/flyer_chat/lib/api/api.dart +++ b/examples/flyer_chat/lib/api/api.dart @@ -126,12 +126,11 @@ class ApiState extends State { chatController: _chatController, crossCache: _crossCache, currentUserId: widget.currentUserId, - darkTheme: ChatTheme.fromThemeData(theme), onAttachmentTap: _handleAttachmentTap, onMessageSend: _addItem, onMessageTap: _removeItem, - theme: ChatTheme.fromThemeData(theme), resolveUser: (id) => Future.value(users[id]), + theme: ChatTheme.fromThemeData(theme), ), Positioned( top: 16, diff --git a/examples/flyer_chat/lib/gemini.dart b/examples/flyer_chat/lib/gemini.dart index eced4763..93e66c6f 100644 --- a/examples/flyer_chat/lib/gemini.dart +++ b/examples/flyer_chat/lib/gemini.dart @@ -66,6 +66,8 @@ class GeminiState extends State { @override Widget build(BuildContext context) { + final theme = Theme.of(context); + return Scaffold( appBar: AppBar( title: const Text('Gemini'), @@ -105,6 +107,7 @@ class GeminiState extends State { _ => null, }, ), + theme: ChatTheme.fromThemeData(theme), ), ); } diff --git a/examples/flyer_chat/lib/local.dart b/examples/flyer_chat/lib/local.dart index bfa3fef7..ab1e5dd3 100644 --- a/examples/flyer_chat/lib/local.dart +++ b/examples/flyer_chat/lib/local.dart @@ -39,11 +39,14 @@ class LocalState extends State { @override Widget build(BuildContext context) { + final theme = Theme.of(context); + return Scaffold( appBar: AppBar( title: const Text('Local'), ), body: Chat( + backgroundColor: null, builders: Builders( customMessageBuilder: (context, message, index) => Container( padding: const EdgeInsets.symmetric( @@ -51,7 +54,9 @@ class LocalState extends State { vertical: 10, ), decoration: BoxDecoration( - color: Color(0xFFF0F0F0), + color: theme.brightness == Brightness.dark + ? ChatColors.dark().surfaceContainer + : ChatColors.light().surfaceContainer, borderRadius: const BorderRadius.all(Radius.circular(12)), ), child: IsTypingIndicator(), @@ -85,9 +90,19 @@ class LocalState extends State { ), chatController: _chatController, currentUserId: _currentUser.id, - darkTheme: ChatTheme.dark( - isTypingTheme: IsTypingTheme.dark( - color: Color(0xFF101010), + decoration: BoxDecoration( + color: theme.brightness == Brightness.dark + ? ChatColors.dark().surface + : ChatColors.light().surface, + image: DecorationImage( + image: AssetImage('assets/pattern.png'), + repeat: ImageRepeat.repeat, + colorFilter: ColorFilter.mode( + theme.brightness == Brightness.dark + ? ChatColors.dark().surfaceContainerLow + : ChatColors.light().surfaceContainerLow, + BlendMode.srcIn, + ), ), ), onAttachmentTap: _handleAttachmentTap, @@ -101,6 +116,9 @@ class LocalState extends State { _ => null, }, ), + theme: theme.brightness == Brightness.dark + ? ChatTheme.dark() + : ChatTheme.light(), ), ); } diff --git a/examples/flyer_chat/pubspec.yaml b/examples/flyer_chat/pubspec.yaml index e5420ea4..aabed74f 100644 --- a/examples/flyer_chat/pubspec.yaml +++ b/examples/flyer_chat/pubspec.yaml @@ -77,6 +77,7 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - .env + - assets/pattern.png # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images diff --git a/packages/flutter_chat_core/lib/flutter_chat_core.dart b/packages/flutter_chat_core/lib/flutter_chat_core.dart index b4d911fc..1e9eab0d 100644 --- a/packages/flutter_chat_core/lib/flutter_chat_core.dart +++ b/packages/flutter_chat_core/lib/flutter_chat_core.dart @@ -7,9 +7,6 @@ export 'src/models/link_preview.dart'; export 'src/models/message.dart'; export 'src/models/user.dart'; export 'src/theme/chat_theme.dart'; -export 'src/theme/input_theme.dart'; -export 'src/theme/is_typing_theme.dart'; -export 'src/theme/scroll_to_bottom_theme.dart'; -export 'src/theme/text_message_theme.dart'; +export 'src/theme/chat_theme_extension.dart'; export 'src/utils/is_only_emoji.dart'; export 'src/utils/typedefs.dart'; diff --git a/packages/flutter_chat_core/lib/src/theme/chat_theme.dart b/packages/flutter_chat_core/lib/src/theme/chat_theme.dart index 8f1bc600..373b09b4 100644 --- a/packages/flutter_chat_core/lib/src/theme/chat_theme.dart +++ b/packages/flutter_chat_core/lib/src/theme/chat_theme.dart @@ -1,127 +1,168 @@ import 'package:flutter/material.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'chat_theme_constants.dart'; -import 'image_message_theme.dart'; -import 'input_theme.dart'; -import 'is_typing_theme.dart'; -import 'scroll_to_bottom_theme.dart'; -import 'text_message_theme.dart'; part 'chat_theme.freezed.dart'; -@Freezed(fromJson: false, toJson: false, copyWith: false) +@freezed class ChatTheme with _$ChatTheme { - factory ChatTheme.light({ - Color? backgroundColor, - String? fontFamily, - ImageMessageTheme? imageMessageTheme, - InputTheme? inputTheme, - IsTypingTheme? isTypingTheme, - ScrollToBottomTheme? scrollToBottomTheme, - TextMessageTheme? textMessageTheme, - }) { - return ChatTheme( - backgroundColor: backgroundColor ?? defaultChatBackgroundColor.light, - fontFamily: fontFamily ?? defaultChatFontFamily, - imageMessageTheme: ImageMessageTheme.light().merge(imageMessageTheme), - inputTheme: - InputTheme.light(fontFamily: fontFamily ?? defaultChatFontFamily) - .merge(inputTheme), - isTypingTheme: IsTypingTheme.light().merge(isTypingTheme), - scrollToBottomTheme: - ScrollToBottomTheme.light().merge(scrollToBottomTheme), - textMessageTheme: TextMessageTheme.light( - fontFamily: fontFamily ?? defaultChatFontFamily, - ).merge(textMessageTheme), - ); - } + const factory ChatTheme({ + required ChatColors colors, + required ChatTypography typography, + required BorderRadiusGeometry shape, + }) = _ChatTheme; - factory ChatTheme.dark({ - Color? backgroundColor, - String? fontFamily, - ImageMessageTheme? imageMessageTheme, - InputTheme? inputTheme, - IsTypingTheme? isTypingTheme, - ScrollToBottomTheme? scrollToBottomTheme, - TextMessageTheme? textMessageTheme, - }) { - return ChatTheme( - backgroundColor: backgroundColor ?? defaultChatBackgroundColor.dark, - fontFamily: fontFamily ?? defaultChatFontFamily, - imageMessageTheme: ImageMessageTheme.dark().merge(imageMessageTheme), - inputTheme: - InputTheme.dark(fontFamily: fontFamily ?? defaultChatFontFamily) - .merge(inputTheme), - isTypingTheme: IsTypingTheme.dark().merge(isTypingTheme), - scrollToBottomTheme: - ScrollToBottomTheme.dark().merge(scrollToBottomTheme), - textMessageTheme: TextMessageTheme.dark( - fontFamily: fontFamily ?? defaultChatFontFamily, - ).merge(textMessageTheme), - ); - } + const ChatTheme._(); - factory ChatTheme.fromThemeData(ThemeData themeData, {String? fontFamily}) { - final family = fontFamily ?? - themeData.textTheme.bodyMedium?.fontFamily ?? - defaultChatFontFamily; - - return ChatTheme( - backgroundColor: themeData.colorScheme.surface, - fontFamily: family, - imageMessageTheme: ImageMessageTheme.fromThemeData(themeData), - inputTheme: InputTheme.fromThemeData(themeData, fontFamily: family), - isTypingTheme: IsTypingTheme.fromThemeData(themeData), - scrollToBottomTheme: ScrollToBottomTheme.fromThemeData(themeData), - textMessageTheme: TextMessageTheme.fromThemeData( - themeData, - fontFamily: family, - ), + factory ChatTheme.light({String? fontFamily}) => ChatTheme( + colors: ChatColors.light(), + typography: ChatTypography.standard(fontFamily: fontFamily), + shape: const BorderRadius.all(Radius.circular(12)), + ); + + factory ChatTheme.dark({String? fontFamily}) => ChatTheme( + colors: ChatColors.dark(), + typography: ChatTypography.standard(fontFamily: fontFamily), + shape: const BorderRadius.all(Radius.circular(12)), + ); + + factory ChatTheme.fromThemeData(ThemeData themeData) => ChatTheme( + colors: ChatColors.fromThemeData(themeData), + typography: ChatTypography.fromThemeData(themeData), + shape: const BorderRadius.all(Radius.circular(12)), + ); + + ChatTheme merge(ChatTheme? other) { + if (other == null) return this; + return copyWith( + colors: colors.merge(other.colors), + typography: typography.merge(other.typography), + shape: other.shape, ); } +} - const factory ChatTheme({ - required Color backgroundColor, - required String fontFamily, - required ImageMessageTheme imageMessageTheme, - required InputTheme inputTheme, - required IsTypingTheme isTypingTheme, - required ScrollToBottomTheme scrollToBottomTheme, - required TextMessageTheme textMessageTheme, - }) = _ChatTheme; +@freezed +class ChatColors with _$ChatColors { + const factory ChatColors({ + required Color primary, + required Color onPrimary, + required Color surface, + required Color onSurface, + required Color surfaceContainer, + required Color surfaceContainerLow, + required Color surfaceContainerHigh, + }) = _ChatColors; - const ChatTheme._(); + const ChatColors._(); + + factory ChatColors.light() => const ChatColors( + primary: Color(0xff4169e1), + onPrimary: Colors.white, + surface: Colors.white, + onSurface: Color(0xff101010), + surfaceContainerLow: Color(0xfffafafa), + surfaceContainer: Color(0xfff5f5f5), + surfaceContainerHigh: Color(0xffeeeeee), + ); - ChatTheme copyWith({ - Color? backgroundColor, - String? fontFamily, - ImageMessageTheme? imageMessageTheme, - InputTheme? inputTheme, - IsTypingTheme? isTypingTheme, - ScrollToBottomTheme? scrollToBottomTheme, - TextMessageTheme? textMessageTheme, - }) { - return ChatTheme( - backgroundColor: backgroundColor ?? this.backgroundColor, - fontFamily: fontFamily ?? this.fontFamily, - imageMessageTheme: this.imageMessageTheme.merge(imageMessageTheme), - inputTheme: this.inputTheme.merge(inputTheme), - isTypingTheme: this.isTypingTheme.merge(isTypingTheme), - scrollToBottomTheme: this.scrollToBottomTheme.merge(scrollToBottomTheme), - textMessageTheme: this.textMessageTheme.merge(textMessageTheme), + factory ChatColors.dark() => const ChatColors( + primary: Color(0xff4169e1), + onPrimary: Colors.white, + surface: Color(0xff101010), + onSurface: Colors.white, + surfaceContainerLow: Color(0xff121212), + surfaceContainer: Color(0xff1c1c1c), + surfaceContainerHigh: Color(0xff242424), + ); + + factory ChatColors.fromThemeData(ThemeData themeData) => ChatColors( + primary: themeData.colorScheme.primary, + onPrimary: themeData.colorScheme.onPrimary, + surface: themeData.colorScheme.surface, + onSurface: themeData.colorScheme.onSurface, + surfaceContainerLow: themeData.colorScheme.surfaceContainerLow, + surfaceContainer: themeData.colorScheme.surfaceContainer, + surfaceContainerHigh: themeData.colorScheme.surfaceContainerHigh, + ); + + ChatColors merge(ChatColors? other) { + if (other == null) return this; + return copyWith( + primary: other.primary, + onPrimary: other.onPrimary, + surface: other.surface, + onSurface: other.onSurface, + surfaceContainerLow: other.surfaceContainerLow, + surfaceContainer: other.surfaceContainer, + surfaceContainerHigh: other.surfaceContainerHigh, ); } +} - ChatTheme merge(ChatTheme? other) { +@freezed +class ChatTypography with _$ChatTypography { + const factory ChatTypography({ + required TextStyle bodyLarge, + required TextStyle bodyMedium, + required TextStyle bodySmall, + required TextStyle labelLarge, + required TextStyle labelMedium, + required TextStyle labelSmall, + }) = _ChatTypography; + + const ChatTypography._(); + + factory ChatTypography.standard({String? fontFamily}) => ChatTypography( + bodyLarge: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + fontFamily: fontFamily, + ), + bodyMedium: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + fontFamily: fontFamily, + ), + bodySmall: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w400, + fontFamily: fontFamily, + ), + labelLarge: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + fontFamily: fontFamily, + ), + labelMedium: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + fontFamily: fontFamily, + ), + labelSmall: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w500, + fontFamily: fontFamily, + ), + ); + + factory ChatTypography.fromThemeData(ThemeData themeData) => ChatTypography( + bodyLarge: themeData.textTheme.bodyLarge!, + bodyMedium: themeData.textTheme.bodyMedium!, + bodySmall: themeData.textTheme.bodySmall!, + labelLarge: themeData.textTheme.labelLarge!, + labelMedium: themeData.textTheme.labelMedium!, + labelSmall: themeData.textTheme.labelSmall!, + ); + + ChatTypography merge(ChatTypography? other) { if (other == null) return this; return copyWith( - backgroundColor: other.backgroundColor, - fontFamily: other.fontFamily, - imageMessageTheme: other.imageMessageTheme, - inputTheme: other.inputTheme, - isTypingTheme: other.isTypingTheme, - scrollToBottomTheme: other.scrollToBottomTheme, - textMessageTheme: other.textMessageTheme, + bodyLarge: other.bodyLarge, + bodyMedium: other.bodyMedium, + bodySmall: other.bodySmall, + labelLarge: other.labelLarge, + labelMedium: other.labelMedium, + labelSmall: other.labelSmall, ); } } diff --git a/packages/flutter_chat_core/lib/src/theme/chat_theme.freezed.dart b/packages/flutter_chat_core/lib/src/theme/chat_theme.freezed.dart index 7889c2c6..6837b2de 100644 --- a/packages/flutter_chat_core/lib/src/theme/chat_theme.freezed.dart +++ b/packages/flutter_chat_core/lib/src/theme/chat_theme.freezed.dart @@ -16,47 +16,157 @@ final _privateConstructorUsedError = UnsupportedError( /// @nodoc mixin _$ChatTheme { - Color get backgroundColor => throw _privateConstructorUsedError; - String get fontFamily => throw _privateConstructorUsedError; - ImageMessageTheme get imageMessageTheme => throw _privateConstructorUsedError; - InputTheme get inputTheme => throw _privateConstructorUsedError; - IsTypingTheme get isTypingTheme => throw _privateConstructorUsedError; - ScrollToBottomTheme get scrollToBottomTheme => + ChatColors get colors => throw _privateConstructorUsedError; + ChatTypography get typography => throw _privateConstructorUsedError; + BorderRadiusGeometry get shape => throw _privateConstructorUsedError; + + /// Create a copy of ChatTheme + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ChatThemeCopyWith get copyWith => throw _privateConstructorUsedError; - TextMessageTheme get textMessageTheme => throw _privateConstructorUsedError; } /// @nodoc +abstract class $ChatThemeCopyWith<$Res> { + factory $ChatThemeCopyWith(ChatTheme value, $Res Function(ChatTheme) then) = + _$ChatThemeCopyWithImpl<$Res, ChatTheme>; + @useResult + $Res call( + {ChatColors colors, + ChatTypography typography, + BorderRadiusGeometry shape}); -class _$ChatThemeImpl extends _ChatTheme { - const _$ChatThemeImpl( - {required this.backgroundColor, - required this.fontFamily, - required this.imageMessageTheme, - required this.inputTheme, - required this.isTypingTheme, - required this.scrollToBottomTheme, - required this.textMessageTheme}) - : super._(); + $ChatColorsCopyWith<$Res> get colors; + $ChatTypographyCopyWith<$Res> get typography; +} +/// @nodoc +class _$ChatThemeCopyWithImpl<$Res, $Val extends ChatTheme> + implements $ChatThemeCopyWith<$Res> { + _$ChatThemeCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ChatTheme + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') @override - final Color backgroundColor; + $Res call({ + Object? colors = null, + Object? typography = null, + Object? shape = null, + }) { + return _then(_value.copyWith( + colors: null == colors + ? _value.colors + : colors // ignore: cast_nullable_to_non_nullable + as ChatColors, + typography: null == typography + ? _value.typography + : typography // ignore: cast_nullable_to_non_nullable + as ChatTypography, + shape: null == shape + ? _value.shape + : shape // ignore: cast_nullable_to_non_nullable + as BorderRadiusGeometry, + ) as $Val); + } + + /// Create a copy of ChatTheme + /// with the given fields replaced by the non-null parameter values. @override - final String fontFamily; + @pragma('vm:prefer-inline') + $ChatColorsCopyWith<$Res> get colors { + return $ChatColorsCopyWith<$Res>(_value.colors, (value) { + return _then(_value.copyWith(colors: value) as $Val); + }); + } + + /// Create a copy of ChatTheme + /// with the given fields replaced by the non-null parameter values. @override - final ImageMessageTheme imageMessageTheme; + @pragma('vm:prefer-inline') + $ChatTypographyCopyWith<$Res> get typography { + return $ChatTypographyCopyWith<$Res>(_value.typography, (value) { + return _then(_value.copyWith(typography: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$ChatThemeImplCopyWith<$Res> + implements $ChatThemeCopyWith<$Res> { + factory _$$ChatThemeImplCopyWith( + _$ChatThemeImpl value, $Res Function(_$ChatThemeImpl) then) = + __$$ChatThemeImplCopyWithImpl<$Res>; @override - final InputTheme inputTheme; + @useResult + $Res call( + {ChatColors colors, + ChatTypography typography, + BorderRadiusGeometry shape}); + @override - final IsTypingTheme isTypingTheme; + $ChatColorsCopyWith<$Res> get colors; @override - final ScrollToBottomTheme scrollToBottomTheme; + $ChatTypographyCopyWith<$Res> get typography; +} + +/// @nodoc +class __$$ChatThemeImplCopyWithImpl<$Res> + extends _$ChatThemeCopyWithImpl<$Res, _$ChatThemeImpl> + implements _$$ChatThemeImplCopyWith<$Res> { + __$$ChatThemeImplCopyWithImpl( + _$ChatThemeImpl _value, $Res Function(_$ChatThemeImpl) _then) + : super(_value, _then); + + /// Create a copy of ChatTheme + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') @override - final TextMessageTheme textMessageTheme; + $Res call({ + Object? colors = null, + Object? typography = null, + Object? shape = null, + }) { + return _then(_$ChatThemeImpl( + colors: null == colors + ? _value.colors + : colors // ignore: cast_nullable_to_non_nullable + as ChatColors, + typography: null == typography + ? _value.typography + : typography // ignore: cast_nullable_to_non_nullable + as ChatTypography, + shape: null == shape + ? _value.shape + : shape // ignore: cast_nullable_to_non_nullable + as BorderRadiusGeometry, + )); + } +} + +/// @nodoc + +class _$ChatThemeImpl extends _ChatTheme { + const _$ChatThemeImpl( + {required this.colors, required this.typography, required this.shape}) + : super._(); + + @override + final ChatColors colors; + @override + final ChatTypography typography; + @override + final BorderRadiusGeometry shape; @override String toString() { - return 'ChatTheme(backgroundColor: $backgroundColor, fontFamily: $fontFamily, imageMessageTheme: $imageMessageTheme, inputTheme: $inputTheme, isTypingTheme: $isTypingTheme, scrollToBottomTheme: $scrollToBottomTheme, textMessageTheme: $textMessageTheme)'; + return 'ChatTheme(colors: $colors, typography: $typography, shape: $shape)'; } @override @@ -64,57 +174,544 @@ class _$ChatThemeImpl extends _ChatTheme { return identical(this, other) || (other.runtimeType == runtimeType && other is _$ChatThemeImpl && - (identical(other.backgroundColor, backgroundColor) || - other.backgroundColor == backgroundColor) && - (identical(other.fontFamily, fontFamily) || - other.fontFamily == fontFamily) && - (identical(other.imageMessageTheme, imageMessageTheme) || - other.imageMessageTheme == imageMessageTheme) && - (identical(other.inputTheme, inputTheme) || - other.inputTheme == inputTheme) && - (identical(other.isTypingTheme, isTypingTheme) || - other.isTypingTheme == isTypingTheme) && - (identical(other.scrollToBottomTheme, scrollToBottomTheme) || - other.scrollToBottomTheme == scrollToBottomTheme) && - (identical(other.textMessageTheme, textMessageTheme) || - other.textMessageTheme == textMessageTheme)); + (identical(other.colors, colors) || other.colors == colors) && + (identical(other.typography, typography) || + other.typography == typography) && + (identical(other.shape, shape) || other.shape == shape)); } @override - int get hashCode => Object.hash( - runtimeType, - backgroundColor, - fontFamily, - imageMessageTheme, - inputTheme, - isTypingTheme, - scrollToBottomTheme, - textMessageTheme); + int get hashCode => Object.hash(runtimeType, colors, typography, shape); + + /// Create a copy of ChatTheme + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ChatThemeImplCopyWith<_$ChatThemeImpl> get copyWith => + __$$ChatThemeImplCopyWithImpl<_$ChatThemeImpl>(this, _$identity); } abstract class _ChatTheme extends ChatTheme { const factory _ChatTheme( - {required final Color backgroundColor, - required final String fontFamily, - required final ImageMessageTheme imageMessageTheme, - required final InputTheme inputTheme, - required final IsTypingTheme isTypingTheme, - required final ScrollToBottomTheme scrollToBottomTheme, - required final TextMessageTheme textMessageTheme}) = _$ChatThemeImpl; + {required final ChatColors colors, + required final ChatTypography typography, + required final BorderRadiusGeometry shape}) = _$ChatThemeImpl; const _ChatTheme._() : super._(); @override - Color get backgroundColor; + ChatColors get colors; + @override + ChatTypography get typography; + @override + BorderRadiusGeometry get shape; + + /// Create a copy of ChatTheme + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ChatThemeImplCopyWith<_$ChatThemeImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$ChatColors { + Color get primary => throw _privateConstructorUsedError; + Color get onPrimary => throw _privateConstructorUsedError; + Color get surface => throw _privateConstructorUsedError; + Color get onSurface => throw _privateConstructorUsedError; + Color get surfaceContainer => throw _privateConstructorUsedError; + Color get surfaceContainerLow => throw _privateConstructorUsedError; + Color get surfaceContainerHigh => throw _privateConstructorUsedError; + + /// Create a copy of ChatColors + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ChatColorsCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ChatColorsCopyWith<$Res> { + factory $ChatColorsCopyWith( + ChatColors value, $Res Function(ChatColors) then) = + _$ChatColorsCopyWithImpl<$Res, ChatColors>; + @useResult + $Res call( + {Color primary, + Color onPrimary, + Color surface, + Color onSurface, + Color surfaceContainer, + Color surfaceContainerLow, + Color surfaceContainerHigh}); +} + +/// @nodoc +class _$ChatColorsCopyWithImpl<$Res, $Val extends ChatColors> + implements $ChatColorsCopyWith<$Res> { + _$ChatColorsCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ChatColors + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? primary = null, + Object? onPrimary = null, + Object? surface = null, + Object? onSurface = null, + Object? surfaceContainer = null, + Object? surfaceContainerLow = null, + Object? surfaceContainerHigh = null, + }) { + return _then(_value.copyWith( + primary: null == primary + ? _value.primary + : primary // ignore: cast_nullable_to_non_nullable + as Color, + onPrimary: null == onPrimary + ? _value.onPrimary + : onPrimary // ignore: cast_nullable_to_non_nullable + as Color, + surface: null == surface + ? _value.surface + : surface // ignore: cast_nullable_to_non_nullable + as Color, + onSurface: null == onSurface + ? _value.onSurface + : onSurface // ignore: cast_nullable_to_non_nullable + as Color, + surfaceContainer: null == surfaceContainer + ? _value.surfaceContainer + : surfaceContainer // ignore: cast_nullable_to_non_nullable + as Color, + surfaceContainerLow: null == surfaceContainerLow + ? _value.surfaceContainerLow + : surfaceContainerLow // ignore: cast_nullable_to_non_nullable + as Color, + surfaceContainerHigh: null == surfaceContainerHigh + ? _value.surfaceContainerHigh + : surfaceContainerHigh // ignore: cast_nullable_to_non_nullable + as Color, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$ChatColorsImplCopyWith<$Res> + implements $ChatColorsCopyWith<$Res> { + factory _$$ChatColorsImplCopyWith( + _$ChatColorsImpl value, $Res Function(_$ChatColorsImpl) then) = + __$$ChatColorsImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {Color primary, + Color onPrimary, + Color surface, + Color onSurface, + Color surfaceContainer, + Color surfaceContainerLow, + Color surfaceContainerHigh}); +} + +/// @nodoc +class __$$ChatColorsImplCopyWithImpl<$Res> + extends _$ChatColorsCopyWithImpl<$Res, _$ChatColorsImpl> + implements _$$ChatColorsImplCopyWith<$Res> { + __$$ChatColorsImplCopyWithImpl( + _$ChatColorsImpl _value, $Res Function(_$ChatColorsImpl) _then) + : super(_value, _then); + + /// Create a copy of ChatColors + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? primary = null, + Object? onPrimary = null, + Object? surface = null, + Object? onSurface = null, + Object? surfaceContainer = null, + Object? surfaceContainerLow = null, + Object? surfaceContainerHigh = null, + }) { + return _then(_$ChatColorsImpl( + primary: null == primary + ? _value.primary + : primary // ignore: cast_nullable_to_non_nullable + as Color, + onPrimary: null == onPrimary + ? _value.onPrimary + : onPrimary // ignore: cast_nullable_to_non_nullable + as Color, + surface: null == surface + ? _value.surface + : surface // ignore: cast_nullable_to_non_nullable + as Color, + onSurface: null == onSurface + ? _value.onSurface + : onSurface // ignore: cast_nullable_to_non_nullable + as Color, + surfaceContainer: null == surfaceContainer + ? _value.surfaceContainer + : surfaceContainer // ignore: cast_nullable_to_non_nullable + as Color, + surfaceContainerLow: null == surfaceContainerLow + ? _value.surfaceContainerLow + : surfaceContainerLow // ignore: cast_nullable_to_non_nullable + as Color, + surfaceContainerHigh: null == surfaceContainerHigh + ? _value.surfaceContainerHigh + : surfaceContainerHigh // ignore: cast_nullable_to_non_nullable + as Color, + )); + } +} + +/// @nodoc + +class _$ChatColorsImpl extends _ChatColors { + const _$ChatColorsImpl( + {required this.primary, + required this.onPrimary, + required this.surface, + required this.onSurface, + required this.surfaceContainer, + required this.surfaceContainerLow, + required this.surfaceContainerHigh}) + : super._(); + + @override + final Color primary; + @override + final Color onPrimary; + @override + final Color surface; + @override + final Color onSurface; + @override + final Color surfaceContainer; + @override + final Color surfaceContainerLow; + @override + final Color surfaceContainerHigh; + + @override + String toString() { + return 'ChatColors(primary: $primary, onPrimary: $onPrimary, surface: $surface, onSurface: $onSurface, surfaceContainer: $surfaceContainer, surfaceContainerLow: $surfaceContainerLow, surfaceContainerHigh: $surfaceContainerHigh)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ChatColorsImpl && + (identical(other.primary, primary) || other.primary == primary) && + (identical(other.onPrimary, onPrimary) || + other.onPrimary == onPrimary) && + (identical(other.surface, surface) || other.surface == surface) && + (identical(other.onSurface, onSurface) || + other.onSurface == onSurface) && + (identical(other.surfaceContainer, surfaceContainer) || + other.surfaceContainer == surfaceContainer) && + (identical(other.surfaceContainerLow, surfaceContainerLow) || + other.surfaceContainerLow == surfaceContainerLow) && + (identical(other.surfaceContainerHigh, surfaceContainerHigh) || + other.surfaceContainerHigh == surfaceContainerHigh)); + } + @override - String get fontFamily; + int get hashCode => Object.hash(runtimeType, primary, onPrimary, surface, + onSurface, surfaceContainer, surfaceContainerLow, surfaceContainerHigh); + + /// Create a copy of ChatColors + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override - ImageMessageTheme get imageMessageTheme; + @pragma('vm:prefer-inline') + _$$ChatColorsImplCopyWith<_$ChatColorsImpl> get copyWith => + __$$ChatColorsImplCopyWithImpl<_$ChatColorsImpl>(this, _$identity); +} + +abstract class _ChatColors extends ChatColors { + const factory _ChatColors( + {required final Color primary, + required final Color onPrimary, + required final Color surface, + required final Color onSurface, + required final Color surfaceContainer, + required final Color surfaceContainerLow, + required final Color surfaceContainerHigh}) = _$ChatColorsImpl; + const _ChatColors._() : super._(); + + @override + Color get primary; + @override + Color get onPrimary; + @override + Color get surface; + @override + Color get onSurface; @override - InputTheme get inputTheme; + Color get surfaceContainer; @override - IsTypingTheme get isTypingTheme; + Color get surfaceContainerLow; @override - ScrollToBottomTheme get scrollToBottomTheme; + Color get surfaceContainerHigh; + + /// Create a copy of ChatColors + /// with the given fields replaced by the non-null parameter values. @override - TextMessageTheme get textMessageTheme; + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ChatColorsImplCopyWith<_$ChatColorsImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$ChatTypography { + TextStyle get bodyLarge => throw _privateConstructorUsedError; + TextStyle get bodyMedium => throw _privateConstructorUsedError; + TextStyle get bodySmall => throw _privateConstructorUsedError; + TextStyle get labelLarge => throw _privateConstructorUsedError; + TextStyle get labelMedium => throw _privateConstructorUsedError; + TextStyle get labelSmall => throw _privateConstructorUsedError; + + /// Create a copy of ChatTypography + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ChatTypographyCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ChatTypographyCopyWith<$Res> { + factory $ChatTypographyCopyWith( + ChatTypography value, $Res Function(ChatTypography) then) = + _$ChatTypographyCopyWithImpl<$Res, ChatTypography>; + @useResult + $Res call( + {TextStyle bodyLarge, + TextStyle bodyMedium, + TextStyle bodySmall, + TextStyle labelLarge, + TextStyle labelMedium, + TextStyle labelSmall}); +} + +/// @nodoc +class _$ChatTypographyCopyWithImpl<$Res, $Val extends ChatTypography> + implements $ChatTypographyCopyWith<$Res> { + _$ChatTypographyCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ChatTypography + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? bodyLarge = null, + Object? bodyMedium = null, + Object? bodySmall = null, + Object? labelLarge = null, + Object? labelMedium = null, + Object? labelSmall = null, + }) { + return _then(_value.copyWith( + bodyLarge: null == bodyLarge + ? _value.bodyLarge + : bodyLarge // ignore: cast_nullable_to_non_nullable + as TextStyle, + bodyMedium: null == bodyMedium + ? _value.bodyMedium + : bodyMedium // ignore: cast_nullable_to_non_nullable + as TextStyle, + bodySmall: null == bodySmall + ? _value.bodySmall + : bodySmall // ignore: cast_nullable_to_non_nullable + as TextStyle, + labelLarge: null == labelLarge + ? _value.labelLarge + : labelLarge // ignore: cast_nullable_to_non_nullable + as TextStyle, + labelMedium: null == labelMedium + ? _value.labelMedium + : labelMedium // ignore: cast_nullable_to_non_nullable + as TextStyle, + labelSmall: null == labelSmall + ? _value.labelSmall + : labelSmall // ignore: cast_nullable_to_non_nullable + as TextStyle, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$ChatTypographyImplCopyWith<$Res> + implements $ChatTypographyCopyWith<$Res> { + factory _$$ChatTypographyImplCopyWith(_$ChatTypographyImpl value, + $Res Function(_$ChatTypographyImpl) then) = + __$$ChatTypographyImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {TextStyle bodyLarge, + TextStyle bodyMedium, + TextStyle bodySmall, + TextStyle labelLarge, + TextStyle labelMedium, + TextStyle labelSmall}); +} + +/// @nodoc +class __$$ChatTypographyImplCopyWithImpl<$Res> + extends _$ChatTypographyCopyWithImpl<$Res, _$ChatTypographyImpl> + implements _$$ChatTypographyImplCopyWith<$Res> { + __$$ChatTypographyImplCopyWithImpl( + _$ChatTypographyImpl _value, $Res Function(_$ChatTypographyImpl) _then) + : super(_value, _then); + + /// Create a copy of ChatTypography + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? bodyLarge = null, + Object? bodyMedium = null, + Object? bodySmall = null, + Object? labelLarge = null, + Object? labelMedium = null, + Object? labelSmall = null, + }) { + return _then(_$ChatTypographyImpl( + bodyLarge: null == bodyLarge + ? _value.bodyLarge + : bodyLarge // ignore: cast_nullable_to_non_nullable + as TextStyle, + bodyMedium: null == bodyMedium + ? _value.bodyMedium + : bodyMedium // ignore: cast_nullable_to_non_nullable + as TextStyle, + bodySmall: null == bodySmall + ? _value.bodySmall + : bodySmall // ignore: cast_nullable_to_non_nullable + as TextStyle, + labelLarge: null == labelLarge + ? _value.labelLarge + : labelLarge // ignore: cast_nullable_to_non_nullable + as TextStyle, + labelMedium: null == labelMedium + ? _value.labelMedium + : labelMedium // ignore: cast_nullable_to_non_nullable + as TextStyle, + labelSmall: null == labelSmall + ? _value.labelSmall + : labelSmall // ignore: cast_nullable_to_non_nullable + as TextStyle, + )); + } +} + +/// @nodoc + +class _$ChatTypographyImpl extends _ChatTypography { + const _$ChatTypographyImpl( + {required this.bodyLarge, + required this.bodyMedium, + required this.bodySmall, + required this.labelLarge, + required this.labelMedium, + required this.labelSmall}) + : super._(); + + @override + final TextStyle bodyLarge; + @override + final TextStyle bodyMedium; + @override + final TextStyle bodySmall; + @override + final TextStyle labelLarge; + @override + final TextStyle labelMedium; + @override + final TextStyle labelSmall; + + @override + String toString() { + return 'ChatTypography(bodyLarge: $bodyLarge, bodyMedium: $bodyMedium, bodySmall: $bodySmall, labelLarge: $labelLarge, labelMedium: $labelMedium, labelSmall: $labelSmall)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ChatTypographyImpl && + (identical(other.bodyLarge, bodyLarge) || + other.bodyLarge == bodyLarge) && + (identical(other.bodyMedium, bodyMedium) || + other.bodyMedium == bodyMedium) && + (identical(other.bodySmall, bodySmall) || + other.bodySmall == bodySmall) && + (identical(other.labelLarge, labelLarge) || + other.labelLarge == labelLarge) && + (identical(other.labelMedium, labelMedium) || + other.labelMedium == labelMedium) && + (identical(other.labelSmall, labelSmall) || + other.labelSmall == labelSmall)); + } + + @override + int get hashCode => Object.hash(runtimeType, bodyLarge, bodyMedium, bodySmall, + labelLarge, labelMedium, labelSmall); + + /// Create a copy of ChatTypography + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ChatTypographyImplCopyWith<_$ChatTypographyImpl> get copyWith => + __$$ChatTypographyImplCopyWithImpl<_$ChatTypographyImpl>( + this, _$identity); +} + +abstract class _ChatTypography extends ChatTypography { + const factory _ChatTypography( + {required final TextStyle bodyLarge, + required final TextStyle bodyMedium, + required final TextStyle bodySmall, + required final TextStyle labelLarge, + required final TextStyle labelMedium, + required final TextStyle labelSmall}) = _$ChatTypographyImpl; + const _ChatTypography._() : super._(); + + @override + TextStyle get bodyLarge; + @override + TextStyle get bodyMedium; + @override + TextStyle get bodySmall; + @override + TextStyle get labelLarge; + @override + TextStyle get labelMedium; + @override + TextStyle get labelSmall; + + /// Create a copy of ChatTypography + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ChatTypographyImplCopyWith<_$ChatTypographyImpl> get copyWith => + throw _privateConstructorUsedError; } diff --git a/packages/flutter_chat_core/lib/src/theme/chat_theme_constants.dart b/packages/flutter_chat_core/lib/src/theme/chat_theme_constants.dart deleted file mode 100644 index 93b4d2d5..00000000 --- a/packages/flutter_chat_core/lib/src/theme/chat_theme_constants.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'dart:ui'; - -const defaultChatFontFamily = 'Roboto'; - -const defaultChatBackgroundColor = ( - light: Color(0xFFFFFFFF), - dark: Color(0xFF101010), -); diff --git a/packages/flutter_chat_core/lib/src/theme/chat_theme_extension.dart b/packages/flutter_chat_core/lib/src/theme/chat_theme_extension.dart new file mode 100644 index 00000000..71bf31cb --- /dev/null +++ b/packages/flutter_chat_core/lib/src/theme/chat_theme_extension.dart @@ -0,0 +1,52 @@ +import 'dart:ui'; + +import 'chat_theme.dart'; + +extension ChatThemeExtensions on ChatTheme { + ChatTheme withLightColors({ + Color? primary, + Color? onPrimary, + Color? surface, + Color? onSurface, + Color? surfaceContainer, + Color? surfaceContainerLow, + Color? surfaceContainerHigh, + }) { + final light = ChatColors.light(); + return copyWith( + colors: light.copyWith( + primary: primary ?? light.primary, + onPrimary: onPrimary ?? light.onPrimary, + surface: surface ?? light.surface, + onSurface: onSurface ?? light.onSurface, + surfaceContainer: surfaceContainer ?? light.surfaceContainer, + surfaceContainerLow: surfaceContainerLow ?? light.surfaceContainerLow, + surfaceContainerHigh: + surfaceContainerHigh ?? light.surfaceContainerHigh, + ), + ); + } + + ChatTheme withDarkColors({ + Color? primary, + Color? onPrimary, + Color? surface, + Color? onSurface, + Color? surfaceContainer, + Color? surfaceContainerLow, + Color? surfaceContainerHigh, + }) { + final dark = ChatColors.dark(); + return copyWith( + colors: dark.copyWith( + primary: primary ?? dark.primary, + onPrimary: onPrimary ?? dark.onPrimary, + surface: surface ?? dark.surface, + onSurface: onSurface ?? dark.onSurface, + surfaceContainer: surfaceContainer ?? dark.surfaceContainer, + surfaceContainerLow: surfaceContainerLow ?? dark.surfaceContainerLow, + surfaceContainerHigh: surfaceContainerHigh ?? dark.surfaceContainerHigh, + ), + ); + } +} diff --git a/packages/flutter_chat_core/lib/src/theme/image_message_theme.dart b/packages/flutter_chat_core/lib/src/theme/image_message_theme.dart deleted file mode 100644 index 79905ce9..00000000 --- a/packages/flutter_chat_core/lib/src/theme/image_message_theme.dart +++ /dev/null @@ -1,90 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -import 'image_message_theme_constants.dart'; - -part 'image_message_theme.freezed.dart'; - -@Freezed(fromJson: false, toJson: false, copyWith: false) -class ImageMessageTheme with _$ImageMessageTheme { - factory ImageMessageTheme.light({ - Color? placeholderColor, - Color? downloadProgressIndicatorColor, - Color? uploadProgressIndicatorColor, - Color? uploadOverlayColor, - }) { - return ImageMessageTheme( - placeholderColor: placeholderColor ?? defaultImagePlaceholderColor.light, - downloadProgressIndicatorColor: downloadProgressIndicatorColor ?? - defaultImageDownloadProgressIndicatorColor.light, - uploadProgressIndicatorColor: uploadProgressIndicatorColor ?? - defaultImageUploadProgressIndicatorColor.light, - uploadOverlayColor: - uploadOverlayColor ?? defaultImageUploadOverlayColor.light, - ); - } - - factory ImageMessageTheme.dark({ - Color? placeholderColor, - Color? downloadProgressIndicatorColor, - Color? uploadProgressIndicatorColor, - Color? uploadOverlayColor, - }) { - return ImageMessageTheme( - placeholderColor: placeholderColor ?? defaultImagePlaceholderColor.dark, - downloadProgressIndicatorColor: downloadProgressIndicatorColor ?? - defaultImageDownloadProgressIndicatorColor.dark, - uploadProgressIndicatorColor: uploadProgressIndicatorColor ?? - defaultImageUploadProgressIndicatorColor.dark, - uploadOverlayColor: - uploadOverlayColor ?? defaultImageUploadOverlayColor.dark, - ); - } - - const factory ImageMessageTheme({ - Color? placeholderColor, - Color? downloadProgressIndicatorColor, - Color? uploadProgressIndicatorColor, - Color? uploadOverlayColor, - }) = _ImageMessageTheme; - - const ImageMessageTheme._(); - - factory ImageMessageTheme.fromThemeData(ThemeData themeData) { - return ImageMessageTheme( - placeholderColor: themeData.colorScheme.surfaceContainerLow, - downloadProgressIndicatorColor: themeData.colorScheme.primary, - uploadProgressIndicatorColor: themeData.colorScheme.primary, - uploadOverlayColor: - // This API is deprecated in Dart ^3.6 and we support Dart ^3.3 - // ignore: deprecated_member_use - themeData.colorScheme.surfaceContainerLow.withOpacity(0.5), - ); - } - - ImageMessageTheme copyWith({ - Color? placeholderColor, - Color? downloadProgressIndicatorColor, - Color? uploadProgressIndicatorColor, - Color? uploadOverlayColor, - }) { - return ImageMessageTheme( - placeholderColor: placeholderColor ?? this.placeholderColor, - downloadProgressIndicatorColor: - downloadProgressIndicatorColor ?? this.downloadProgressIndicatorColor, - uploadProgressIndicatorColor: - uploadProgressIndicatorColor ?? this.uploadProgressIndicatorColor, - uploadOverlayColor: uploadOverlayColor ?? this.uploadOverlayColor, - ); - } - - ImageMessageTheme merge(ImageMessageTheme? other) { - if (other == null) return this; - return copyWith( - placeholderColor: other.placeholderColor, - downloadProgressIndicatorColor: other.downloadProgressIndicatorColor, - uploadProgressIndicatorColor: other.uploadProgressIndicatorColor, - uploadOverlayColor: other.uploadOverlayColor, - ); - } -} diff --git a/packages/flutter_chat_core/lib/src/theme/image_message_theme.freezed.dart b/packages/flutter_chat_core/lib/src/theme/image_message_theme.freezed.dart deleted file mode 100644 index 10aa3f26..00000000 --- a/packages/flutter_chat_core/lib/src/theme/image_message_theme.freezed.dart +++ /dev/null @@ -1,94 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'image_message_theme.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -/// @nodoc -mixin _$ImageMessageTheme { - Color? get placeholderColor => throw _privateConstructorUsedError; - Color? get downloadProgressIndicatorColor => - throw _privateConstructorUsedError; - Color? get uploadProgressIndicatorColor => throw _privateConstructorUsedError; - Color? get uploadOverlayColor => throw _privateConstructorUsedError; -} - -/// @nodoc - -class _$ImageMessageThemeImpl extends _ImageMessageTheme { - const _$ImageMessageThemeImpl( - {this.placeholderColor, - this.downloadProgressIndicatorColor, - this.uploadProgressIndicatorColor, - this.uploadOverlayColor}) - : super._(); - - @override - final Color? placeholderColor; - @override - final Color? downloadProgressIndicatorColor; - @override - final Color? uploadProgressIndicatorColor; - @override - final Color? uploadOverlayColor; - - @override - String toString() { - return 'ImageMessageTheme(placeholderColor: $placeholderColor, downloadProgressIndicatorColor: $downloadProgressIndicatorColor, uploadProgressIndicatorColor: $uploadProgressIndicatorColor, uploadOverlayColor: $uploadOverlayColor)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$ImageMessageThemeImpl && - (identical(other.placeholderColor, placeholderColor) || - other.placeholderColor == placeholderColor) && - (identical(other.downloadProgressIndicatorColor, - downloadProgressIndicatorColor) || - other.downloadProgressIndicatorColor == - downloadProgressIndicatorColor) && - (identical(other.uploadProgressIndicatorColor, - uploadProgressIndicatorColor) || - other.uploadProgressIndicatorColor == - uploadProgressIndicatorColor) && - (identical(other.uploadOverlayColor, uploadOverlayColor) || - other.uploadOverlayColor == uploadOverlayColor)); - } - - @override - int get hashCode => Object.hash( - runtimeType, - placeholderColor, - downloadProgressIndicatorColor, - uploadProgressIndicatorColor, - uploadOverlayColor); -} - -abstract class _ImageMessageTheme extends ImageMessageTheme { - const factory _ImageMessageTheme( - {final Color? placeholderColor, - final Color? downloadProgressIndicatorColor, - final Color? uploadProgressIndicatorColor, - final Color? uploadOverlayColor}) = _$ImageMessageThemeImpl; - const _ImageMessageTheme._() : super._(); - - @override - Color? get placeholderColor; - @override - Color? get downloadProgressIndicatorColor; - @override - Color? get uploadProgressIndicatorColor; - @override - Color? get uploadOverlayColor; -} diff --git a/packages/flutter_chat_core/lib/src/theme/image_message_theme_constants.dart b/packages/flutter_chat_core/lib/src/theme/image_message_theme_constants.dart deleted file mode 100644 index 564e4883..00000000 --- a/packages/flutter_chat_core/lib/src/theme/image_message_theme_constants.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'dart:ui'; - -const defaultImagePlaceholderColor = ( - light: Color(0xFFEEEEEE), - dark: Color(0xFF111111), -); - -const defaultImageDownloadProgressIndicatorColor = ( - light: Color(0xCC101010), - dark: Color(0xCCEEEEEE), -); - -const defaultImageUploadProgressIndicatorColor = ( - light: Color(0xCC101010), - dark: Color(0xCCEEEEEE), -); - -const defaultImageUploadOverlayColor = ( - light: Color(0x80EEEEEE), - dark: Color(0x80111111), -); diff --git a/packages/flutter_chat_core/lib/src/theme/input_theme.dart b/packages/flutter_chat_core/lib/src/theme/input_theme.dart deleted file mode 100644 index 848a3741..00000000 --- a/packages/flutter_chat_core/lib/src/theme/input_theme.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -import 'chat_theme_constants.dart'; -import 'input_theme_constants.dart'; - -part 'input_theme.freezed.dart'; - -@Freezed(fromJson: false, toJson: false, copyWith: false) -class InputTheme with _$InputTheme { - factory InputTheme.light({ - Color? backgroundColor, - Color? textFieldColor, - String? fontFamily, - TextStyle? hintStyle, - TextStyle? textStyle, - }) { - return InputTheme( - backgroundColor: backgroundColor ?? defaultInputBackgroundColor.light, - textFieldColor: textFieldColor ?? defaultInputTextFieldColor.light, - hintStyle: TextStyle( - fontFamily: fontFamily ?? defaultChatFontFamily, - fontWeight: FontWeight.w400, - color: defaultInputHintColor.light, - ).merge(hintStyle), - textStyle: TextStyle( - fontFamily: fontFamily ?? defaultChatFontFamily, - color: defaultInputTextColor.light, - ).merge(textStyle), - ); - } - - factory InputTheme.dark({ - Color? backgroundColor, - Color? textFieldColor, - String? fontFamily, - TextStyle? hintStyle, - TextStyle? textStyle, - }) { - return InputTheme( - backgroundColor: backgroundColor ?? defaultInputBackgroundColor.dark, - textFieldColor: textFieldColor ?? defaultInputTextFieldColor.dark, - hintStyle: TextStyle( - fontFamily: fontFamily ?? defaultChatFontFamily, - fontWeight: FontWeight.w400, - color: defaultInputHintColor.dark, - ).merge(hintStyle), - textStyle: TextStyle( - fontFamily: fontFamily ?? defaultChatFontFamily, - color: defaultInputTextColor.dark, - ).merge(textStyle), - ); - } - - factory InputTheme.fromThemeData(ThemeData themeData, {String? fontFamily}) { - final family = fontFamily ?? - themeData.textTheme.bodyMedium?.fontFamily ?? - defaultChatFontFamily; - - return InputTheme( - // This API is deprecated in Dart ^3.6 and we support Dart ^3.3 - // ignore: deprecated_member_use - backgroundColor: themeData.colorScheme.surface.withOpacity(0.8), - textFieldColor: themeData.colorScheme.surfaceContainerHigh, - hintStyle: themeData.textTheme.bodyMedium?.copyWith( - fontFamily: family, - // This API is deprecated in Dart ^3.6 and we support Dart ^3.3 - // ignore: deprecated_member_use - color: themeData.textTheme.bodyMedium?.color?.withOpacity(0.6), - ), - textStyle: themeData.textTheme.bodyMedium?.copyWith( - fontFamily: family, - color: themeData.colorScheme.onSurface, - ), - ); - } - - const factory InputTheme({ - Color? backgroundColor, - Color? textFieldColor, - TextStyle? hintStyle, - TextStyle? textStyle, - }) = _InputTheme; - - const InputTheme._(); - - InputTheme copyWith({ - Color? backgroundColor, - Color? textFieldColor, - TextStyle? hintStyle, - TextStyle? textStyle, - }) { - return InputTheme( - backgroundColor: backgroundColor ?? this.backgroundColor, - textFieldColor: textFieldColor ?? this.textFieldColor, - hintStyle: this.hintStyle?.merge(hintStyle) ?? hintStyle, - textStyle: this.textStyle?.merge(textStyle) ?? textStyle, - ); - } - - InputTheme merge(InputTheme? other) { - if (other == null) return this; - return copyWith( - backgroundColor: other.backgroundColor, - textFieldColor: other.textFieldColor, - hintStyle: other.hintStyle, - textStyle: other.textStyle, - ); - } -} diff --git a/packages/flutter_chat_core/lib/src/theme/input_theme.freezed.dart b/packages/flutter_chat_core/lib/src/theme/input_theme.freezed.dart deleted file mode 100644 index a4aa3bc6..00000000 --- a/packages/flutter_chat_core/lib/src/theme/input_theme.freezed.dart +++ /dev/null @@ -1,85 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'input_theme.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -/// @nodoc -mixin _$InputTheme { - Color? get backgroundColor => throw _privateConstructorUsedError; - Color? get textFieldColor => throw _privateConstructorUsedError; - TextStyle? get hintStyle => throw _privateConstructorUsedError; - TextStyle? get textStyle => throw _privateConstructorUsedError; -} - -/// @nodoc - -class _$InputThemeImpl extends _InputTheme { - const _$InputThemeImpl( - {this.backgroundColor, - this.textFieldColor, - this.hintStyle, - this.textStyle}) - : super._(); - - @override - final Color? backgroundColor; - @override - final Color? textFieldColor; - @override - final TextStyle? hintStyle; - @override - final TextStyle? textStyle; - - @override - String toString() { - return 'InputTheme(backgroundColor: $backgroundColor, textFieldColor: $textFieldColor, hintStyle: $hintStyle, textStyle: $textStyle)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$InputThemeImpl && - (identical(other.backgroundColor, backgroundColor) || - other.backgroundColor == backgroundColor) && - (identical(other.textFieldColor, textFieldColor) || - other.textFieldColor == textFieldColor) && - (identical(other.hintStyle, hintStyle) || - other.hintStyle == hintStyle) && - (identical(other.textStyle, textStyle) || - other.textStyle == textStyle)); - } - - @override - int get hashCode => Object.hash( - runtimeType, backgroundColor, textFieldColor, hintStyle, textStyle); -} - -abstract class _InputTheme extends InputTheme { - const factory _InputTheme( - {final Color? backgroundColor, - final Color? textFieldColor, - final TextStyle? hintStyle, - final TextStyle? textStyle}) = _$InputThemeImpl; - const _InputTheme._() : super._(); - - @override - Color? get backgroundColor; - @override - Color? get textFieldColor; - @override - TextStyle? get hintStyle; - @override - TextStyle? get textStyle; -} diff --git a/packages/flutter_chat_core/lib/src/theme/input_theme_constants.dart b/packages/flutter_chat_core/lib/src/theme/input_theme_constants.dart deleted file mode 100644 index d2004372..00000000 --- a/packages/flutter_chat_core/lib/src/theme/input_theme_constants.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'dart:ui'; - -const defaultInputBackgroundColor = ( - light: Color(0xCCFFFFFF), - dark: Color(0xCC101010), -); - -const defaultInputTextFieldColor = ( - light: Color(0x66EEEEEE), - dark: Color(0x66585858), -); - -const defaultInputTextColor = ( - light: Color(0xFF101010), - dark: Color(0xFFFFFFFF), -); - -const defaultInputHintColor = ( - light: Color(0x99101010), - dark: Color(0x99FFFFFF), -); diff --git a/packages/flutter_chat_core/lib/src/theme/is_typing_theme.dart b/packages/flutter_chat_core/lib/src/theme/is_typing_theme.dart deleted file mode 100644 index 3b57b47a..00000000 --- a/packages/flutter_chat_core/lib/src/theme/is_typing_theme.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -import 'is_typing_theme_constants.dart'; - -part 'is_typing_theme.freezed.dart'; - -@Freezed(fromJson: false, toJson: false, copyWith: false) -class IsTypingTheme with _$IsTypingTheme { - factory IsTypingTheme.light({ - Color? color, - }) { - return IsTypingTheme( - color: color ?? defaultIsTypingColor.light, - ); - } - - factory IsTypingTheme.dark({ - Color? color, - }) { - return IsTypingTheme( - color: color ?? defaultIsTypingColor.dark, - ); - } - - const factory IsTypingTheme({ - Color? color, - }) = _IsTypingTheme; - - const IsTypingTheme._(); - - factory IsTypingTheme.fromThemeData(ThemeData themeData) { - return IsTypingTheme( - color: themeData.colorScheme.primary, - ); - } - - IsTypingTheme copyWith({ - Color? color, - }) { - return IsTypingTheme( - color: color ?? this.color, - ); - } - - IsTypingTheme merge(IsTypingTheme? other) { - if (other == null) return this; - return copyWith( - color: other.color, - ); - } -} diff --git a/packages/flutter_chat_core/lib/src/theme/is_typing_theme.freezed.dart b/packages/flutter_chat_core/lib/src/theme/is_typing_theme.freezed.dart deleted file mode 100644 index 79daa137..00000000 --- a/packages/flutter_chat_core/lib/src/theme/is_typing_theme.freezed.dart +++ /dev/null @@ -1,53 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'is_typing_theme.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -/// @nodoc -mixin _$IsTypingTheme { - Color? get color => throw _privateConstructorUsedError; -} - -/// @nodoc - -class _$IsTypingThemeImpl extends _IsTypingTheme { - const _$IsTypingThemeImpl({this.color}) : super._(); - - @override - final Color? color; - - @override - String toString() { - return 'IsTypingTheme(color: $color)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$IsTypingThemeImpl && - (identical(other.color, color) || other.color == color)); - } - - @override - int get hashCode => Object.hash(runtimeType, color); -} - -abstract class _IsTypingTheme extends IsTypingTheme { - const factory _IsTypingTheme({final Color? color}) = _$IsTypingThemeImpl; - const _IsTypingTheme._() : super._(); - - @override - Color? get color; -} diff --git a/packages/flutter_chat_core/lib/src/theme/is_typing_theme_constants.dart b/packages/flutter_chat_core/lib/src/theme/is_typing_theme_constants.dart deleted file mode 100644 index eb749639..00000000 --- a/packages/flutter_chat_core/lib/src/theme/is_typing_theme_constants.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'dart:ui'; - -const defaultIsTypingColor = ( - light: Color(0xFF101010), - dark: Color(0xFFFFFFFF), -); diff --git a/packages/flutter_chat_core/lib/src/theme/scroll_to_bottom_theme.dart b/packages/flutter_chat_core/lib/src/theme/scroll_to_bottom_theme.dart deleted file mode 100644 index dd5251c6..00000000 --- a/packages/flutter_chat_core/lib/src/theme/scroll_to_bottom_theme.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -import 'scroll_to_bottom_theme_constants.dart'; - -part 'scroll_to_bottom_theme.freezed.dart'; - -@Freezed(fromJson: false, toJson: false, copyWith: false) -class ScrollToBottomTheme with _$ScrollToBottomTheme { - factory ScrollToBottomTheme.light({ - Color? backgroundColor, - Color? foregroundColor, - }) { - return ScrollToBottomTheme( - backgroundColor: - backgroundColor ?? defaultScrollToBottomBackgroundColor.light, - foregroundColor: - foregroundColor ?? defaultScrollToBottomForegroundColor.light, - ); - } - - factory ScrollToBottomTheme.dark({ - Color? backgroundColor, - Color? foregroundColor, - }) { - return ScrollToBottomTheme( - backgroundColor: - backgroundColor ?? defaultScrollToBottomBackgroundColor.dark, - foregroundColor: - foregroundColor ?? defaultScrollToBottomForegroundColor.dark, - ); - } - - const factory ScrollToBottomTheme({ - Color? backgroundColor, - Color? foregroundColor, - }) = _ScrollToBottomTheme; - - const ScrollToBottomTheme._(); - - factory ScrollToBottomTheme.fromThemeData(ThemeData themeData) { - return ScrollToBottomTheme( - backgroundColor: themeData.colorScheme.surfaceContainerHigh, - foregroundColor: themeData.colorScheme.primary, - ); - } - - ScrollToBottomTheme copyWith({ - Color? backgroundColor, - Color? foregroundColor, - }) { - return ScrollToBottomTheme( - backgroundColor: backgroundColor ?? this.backgroundColor, - foregroundColor: foregroundColor ?? this.foregroundColor, - ); - } - - ScrollToBottomTheme merge(ScrollToBottomTheme? other) { - if (other == null) return this; - return copyWith( - backgroundColor: other.backgroundColor, - foregroundColor: other.foregroundColor, - ); - } -} diff --git a/packages/flutter_chat_core/lib/src/theme/scroll_to_bottom_theme.freezed.dart b/packages/flutter_chat_core/lib/src/theme/scroll_to_bottom_theme.freezed.dart deleted file mode 100644 index da6edd4f..00000000 --- a/packages/flutter_chat_core/lib/src/theme/scroll_to_bottom_theme.freezed.dart +++ /dev/null @@ -1,65 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'scroll_to_bottom_theme.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -/// @nodoc -mixin _$ScrollToBottomTheme { - Color? get backgroundColor => throw _privateConstructorUsedError; - Color? get foregroundColor => throw _privateConstructorUsedError; -} - -/// @nodoc - -class _$ScrollToBottomThemeImpl extends _ScrollToBottomTheme { - const _$ScrollToBottomThemeImpl({this.backgroundColor, this.foregroundColor}) - : super._(); - - @override - final Color? backgroundColor; - @override - final Color? foregroundColor; - - @override - String toString() { - return 'ScrollToBottomTheme(backgroundColor: $backgroundColor, foregroundColor: $foregroundColor)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$ScrollToBottomThemeImpl && - (identical(other.backgroundColor, backgroundColor) || - other.backgroundColor == backgroundColor) && - (identical(other.foregroundColor, foregroundColor) || - other.foregroundColor == foregroundColor)); - } - - @override - int get hashCode => - Object.hash(runtimeType, backgroundColor, foregroundColor); -} - -abstract class _ScrollToBottomTheme extends ScrollToBottomTheme { - const factory _ScrollToBottomTheme( - {final Color? backgroundColor, - final Color? foregroundColor}) = _$ScrollToBottomThemeImpl; - const _ScrollToBottomTheme._() : super._(); - - @override - Color? get backgroundColor; - @override - Color? get foregroundColor; -} diff --git a/packages/flutter_chat_core/lib/src/theme/scroll_to_bottom_theme_constants.dart b/packages/flutter_chat_core/lib/src/theme/scroll_to_bottom_theme_constants.dart deleted file mode 100644 index 4c0f575b..00000000 --- a/packages/flutter_chat_core/lib/src/theme/scroll_to_bottom_theme_constants.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'dart:ui'; - -const defaultScrollToBottomBackgroundColor = ( - light: Color(0xFFEEEEEE), - dark: Color(0xFFFFFFFF), -); - -const defaultScrollToBottomForegroundColor = ( - light: Color(0xFF101010), - dark: Color(0xFF101010), -); diff --git a/packages/flutter_chat_core/lib/src/theme/text_message_theme.dart b/packages/flutter_chat_core/lib/src/theme/text_message_theme.dart deleted file mode 100644 index cca3989f..00000000 --- a/packages/flutter_chat_core/lib/src/theme/text_message_theme.dart +++ /dev/null @@ -1,113 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -import 'chat_theme_constants.dart'; -import 'text_message_theme_constants.dart'; - -part 'text_message_theme.freezed.dart'; - -@Freezed(fromJson: false, toJson: false, copyWith: false) -class TextMessageTheme with _$TextMessageTheme { - factory TextMessageTheme.light({ - String? fontFamily, - Color? receivedBackgroundColor, - TextStyle? receivedTextStyle, - Color? sentBackgroundColor, - TextStyle? sentTextStyle, - }) { - return TextMessageTheme( - receivedBackgroundColor: - receivedBackgroundColor ?? defaultTextReceivedBackgroundColor.light, - receivedTextStyle: TextStyle( - fontFamily: fontFamily ?? defaultChatFontFamily, - color: defaultTextReceivedColor.light, - ).merge(receivedTextStyle), - sentBackgroundColor: - sentBackgroundColor ?? defaultTextSentBackgroundColor.light, - sentTextStyle: TextStyle( - fontFamily: fontFamily ?? defaultChatFontFamily, - color: defaultTextSentColor.light, - ).merge(sentTextStyle), - ); - } - - factory TextMessageTheme.dark({ - String? fontFamily, - Color? receivedBackgroundColor, - TextStyle? receivedTextStyle, - Color? sentBackgroundColor, - TextStyle? sentTextStyle, - }) { - return TextMessageTheme( - receivedBackgroundColor: - receivedBackgroundColor ?? defaultTextReceivedBackgroundColor.dark, - receivedTextStyle: TextStyle( - fontFamily: fontFamily ?? defaultChatFontFamily, - color: defaultTextReceivedColor.dark, - ).merge(receivedTextStyle), - sentBackgroundColor: - sentBackgroundColor ?? defaultTextSentBackgroundColor.dark, - sentTextStyle: TextStyle( - fontFamily: fontFamily ?? defaultChatFontFamily, - color: defaultTextSentColor.dark, - ).merge(sentTextStyle), - ); - } - - const factory TextMessageTheme({ - Color? receivedBackgroundColor, - TextStyle? receivedTextStyle, - Color? sentBackgroundColor, - TextStyle? sentTextStyle, - }) = _TextMessageTheme; - - const TextMessageTheme._(); - - factory TextMessageTheme.fromThemeData( - ThemeData themeData, { - String? fontFamily, - }) { - final family = fontFamily ?? - themeData.textTheme.bodyMedium?.fontFamily ?? - defaultChatFontFamily; - - return TextMessageTheme( - receivedBackgroundColor: themeData.colorScheme.surfaceContainerHigh, - receivedTextStyle: themeData.textTheme.bodyMedium?.copyWith( - fontFamily: family, - color: themeData.colorScheme.onSurface, - ), - sentBackgroundColor: themeData.colorScheme.primary, - sentTextStyle: themeData.textTheme.bodyMedium?.copyWith( - fontFamily: family, - color: themeData.colorScheme.onPrimary, - ), - ); - } - - TextMessageTheme copyWith({ - Color? receivedBackgroundColor, - TextStyle? receivedTextStyle, - Color? sentBackgroundColor, - TextStyle? sentTextStyle, - }) { - return TextMessageTheme( - receivedBackgroundColor: - receivedBackgroundColor ?? this.receivedBackgroundColor, - receivedTextStyle: - this.receivedTextStyle?.merge(receivedTextStyle) ?? receivedTextStyle, - sentBackgroundColor: sentBackgroundColor ?? this.sentBackgroundColor, - sentTextStyle: this.sentTextStyle?.merge(sentTextStyle) ?? sentTextStyle, - ); - } - - TextMessageTheme merge(TextMessageTheme? other) { - if (other == null) return this; - return copyWith( - receivedBackgroundColor: other.receivedBackgroundColor, - receivedTextStyle: other.receivedTextStyle, - sentBackgroundColor: other.sentBackgroundColor, - sentTextStyle: other.sentTextStyle, - ); - } -} diff --git a/packages/flutter_chat_core/lib/src/theme/text_message_theme.freezed.dart b/packages/flutter_chat_core/lib/src/theme/text_message_theme.freezed.dart deleted file mode 100644 index a0e031ac..00000000 --- a/packages/flutter_chat_core/lib/src/theme/text_message_theme.freezed.dart +++ /dev/null @@ -1,86 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'text_message_theme.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -/// @nodoc -mixin _$TextMessageTheme { - Color? get receivedBackgroundColor => throw _privateConstructorUsedError; - TextStyle? get receivedTextStyle => throw _privateConstructorUsedError; - Color? get sentBackgroundColor => throw _privateConstructorUsedError; - TextStyle? get sentTextStyle => throw _privateConstructorUsedError; -} - -/// @nodoc - -class _$TextMessageThemeImpl extends _TextMessageTheme { - const _$TextMessageThemeImpl( - {this.receivedBackgroundColor, - this.receivedTextStyle, - this.sentBackgroundColor, - this.sentTextStyle}) - : super._(); - - @override - final Color? receivedBackgroundColor; - @override - final TextStyle? receivedTextStyle; - @override - final Color? sentBackgroundColor; - @override - final TextStyle? sentTextStyle; - - @override - String toString() { - return 'TextMessageTheme(receivedBackgroundColor: $receivedBackgroundColor, receivedTextStyle: $receivedTextStyle, sentBackgroundColor: $sentBackgroundColor, sentTextStyle: $sentTextStyle)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$TextMessageThemeImpl && - (identical( - other.receivedBackgroundColor, receivedBackgroundColor) || - other.receivedBackgroundColor == receivedBackgroundColor) && - (identical(other.receivedTextStyle, receivedTextStyle) || - other.receivedTextStyle == receivedTextStyle) && - (identical(other.sentBackgroundColor, sentBackgroundColor) || - other.sentBackgroundColor == sentBackgroundColor) && - (identical(other.sentTextStyle, sentTextStyle) || - other.sentTextStyle == sentTextStyle)); - } - - @override - int get hashCode => Object.hash(runtimeType, receivedBackgroundColor, - receivedTextStyle, sentBackgroundColor, sentTextStyle); -} - -abstract class _TextMessageTheme extends TextMessageTheme { - const factory _TextMessageTheme( - {final Color? receivedBackgroundColor, - final TextStyle? receivedTextStyle, - final Color? sentBackgroundColor, - final TextStyle? sentTextStyle}) = _$TextMessageThemeImpl; - const _TextMessageTheme._() : super._(); - - @override - Color? get receivedBackgroundColor; - @override - TextStyle? get receivedTextStyle; - @override - Color? get sentBackgroundColor; - @override - TextStyle? get sentTextStyle; -} diff --git a/packages/flutter_chat_core/lib/src/theme/text_message_theme_constants.dart b/packages/flutter_chat_core/lib/src/theme/text_message_theme_constants.dart deleted file mode 100644 index 54ac5c1b..00000000 --- a/packages/flutter_chat_core/lib/src/theme/text_message_theme_constants.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'dart:ui'; - -const defaultTextSentBackgroundColor = ( - light: Color(0xFF4169E1), - dark: Color(0xFF4169E1), -); - -const defaultTextSentColor = ( - light: Color(0xFFFFFFFF), - dark: Color(0xFFFFFFFF), -); - -const defaultTextReceivedBackgroundColor = ( - light: Color(0xFFF0F0F0), - dark: Color(0xFFF0F0F0), -); - -const defaultTextReceivedColor = ( - light: Color(0xFF101010), - dark: Color(0xFF101010), -); diff --git a/packages/flutter_chat_ui/lib/src/chat.dart b/packages/flutter_chat_ui/lib/src/chat.dart index 53ea5638..7d438eec 100644 --- a/packages/flutter_chat_ui/lib/src/chat.dart +++ b/packages/flutter_chat_ui/lib/src/chat.dart @@ -1,5 +1,3 @@ -import 'dart:ui'; - import 'package:cross_cache/cross_cache.dart'; import 'package:flutter/material.dart'; import 'package:flutter_chat_core/flutter_chat_core.dart'; @@ -11,6 +9,8 @@ import 'utils/chat_input_height_notifier.dart'; import 'utils/typedefs.dart'; class Chat extends StatefulWidget { + static const Color _sentinelColor = Colors.transparent; + final String currentUserId; final ResolveUserCallback resolveUser; final ChatController chatController; @@ -18,11 +18,11 @@ class Chat extends StatefulWidget { final CrossCache? crossCache; final ScrollController? scrollController; final ChatTheme? theme; - final ChatTheme? darkTheme; - final ThemeMode themeMode; final OnMessageSendCallback? onMessageSend; final OnMessageTapCallback? onMessageTap; final OnAttachmentTapCallback? onAttachmentTap; + final Color? backgroundColor; + final Decoration? decoration; const Chat({ super.key, @@ -33,11 +33,11 @@ class Chat extends StatefulWidget { this.crossCache, this.scrollController, this.theme, - this.darkTheme, - this.themeMode = ThemeMode.system, this.onMessageSend, this.onMessageTap, this.onAttachmentTap, + this.backgroundColor = _sentinelColor, + this.decoration, }); @override @@ -45,7 +45,6 @@ class Chat extends StatefulWidget { } class _ChatState extends State with WidgetsBindingObserver { - // TODO: If theme is passed and then removed, it does not reset to default late ChatTheme _theme; late Builders _builders; late final CrossCache _crossCache; @@ -61,19 +60,12 @@ class _ChatState extends State with WidgetsBindingObserver { _scrollController = widget.scrollController ?? ScrollController(); } - @override - void didChangePlatformBrightness() { - super.didChangePlatformBrightness(); - setState(_updateTheme); - } - @override void didUpdateWidget(covariant Chat oldWidget) { super.didUpdateWidget(oldWidget); - if (oldWidget.theme != widget.theme || - oldWidget.darkTheme != widget.darkTheme) { - _updateTheme(theme: _theme, darkTheme: _theme); + if (oldWidget.theme != widget.theme) { + _updateTheme(); } if (oldWidget.builders != widget.builders) { @@ -112,7 +104,10 @@ class _ChatState extends State with WidgetsBindingObserver { ChangeNotifierProvider(create: (_) => ChatInputHeightNotifier()), ], child: Container( - color: _theme.backgroundColor, + color: widget.backgroundColor == Chat._sentinelColor + ? _theme.colors.surface + : widget.backgroundColor, + decoration: widget.decoration, child: Stack( children: [ _builders.chatAnimatedListBuilder?.call( @@ -147,21 +142,8 @@ class _ChatState extends State with WidgetsBindingObserver { ); } - void _updateTheme({ChatTheme? theme, ChatTheme? darkTheme}) { - switch (widget.themeMode) { - case ThemeMode.light: - _theme = (theme ?? ChatTheme.light()).merge(widget.theme); - break; - case ThemeMode.dark: - _theme = (darkTheme ?? ChatTheme.dark()).merge(widget.darkTheme); - break; - case ThemeMode.system: - _theme = - PlatformDispatcher.instance.platformBrightness == Brightness.dark - ? (darkTheme ?? ChatTheme.dark()).merge(widget.darkTheme) - : (theme ?? ChatTheme.light()).merge(widget.theme); - break; - } + void _updateTheme() { + _theme = widget.theme ?? ChatTheme.light(); } void _updateBuilders() { diff --git a/packages/flutter_chat_ui/lib/src/chat_input.dart b/packages/flutter_chat_ui/lib/src/chat_input.dart index bf79773b..97173351 100644 --- a/packages/flutter_chat_ui/lib/src/chat_input.dart +++ b/packages/flutter_chat_ui/lib/src/chat_input.dart @@ -8,6 +8,8 @@ import 'utils/chat_input_height_notifier.dart'; import 'utils/typedefs.dart'; class ChatInput extends StatefulWidget { + static const Color _sentinelColor = Colors.transparent; + final double? left; final double? right; final double? top; @@ -22,6 +24,12 @@ class ChatInput extends StatefulWidget { final bool? filled; final Widget? topWidget; final bool? handleSafeArea; + final Color? backgroundColor; + final Color? attachmentIconColor; + final Color? sendIconColor; + final Color? hintColor; + final Color? textColor; + final Color? inputFillColor; const ChatInput({ super.key, @@ -42,6 +50,12 @@ class ChatInput extends StatefulWidget { this.filled = true, this.topWidget, this.handleSafeArea = true, + this.backgroundColor = _sentinelColor, + this.attachmentIconColor, + this.sendIconColor, + this.hintColor, + this.textColor, + this.inputFillColor, }); @override @@ -75,7 +89,7 @@ class _ChatInputState extends State { final bottomSafeArea = widget.handleSafeArea == true ? MediaQuery.of(context).padding.bottom : 0.0; - final inputTheme = context.select((ChatTheme theme) => theme.inputTheme); + final theme = context.watch(); final onAttachmentTap = context.read(); return Positioned( @@ -92,7 +106,10 @@ class _ChatInputState extends State { ), child: Container( key: _inputKey, - color: inputTheme.backgroundColor, + color: widget.backgroundColor == ChatInput._sentinelColor + // ignore: deprecated_member_use + ? theme.colors.surfaceContainerLow.withOpacity(0.8) + : widget.backgroundColor, child: Column( children: [ if (widget.topWidget != null) widget.topWidget!, @@ -107,7 +124,9 @@ class _ChatInputState extends State { widget.attachmentIcon != null ? IconButton( icon: widget.attachmentIcon!, - color: inputTheme.hintStyle?.color, + color: widget.attachmentIconColor ?? + // ignore: deprecated_member_use + theme.colors.onSurface.withOpacity(0.5), onPressed: onAttachmentTap, ) : const SizedBox.shrink(), @@ -117,13 +136,22 @@ class _ChatInputState extends State { controller: _textController, decoration: InputDecoration( hintText: 'Type a message', - hintStyle: inputTheme.hintStyle, + hintStyle: theme.typography.bodyMedium.copyWith( + color: widget.hintColor ?? + // ignore: deprecated_member_use + theme.colors.onSurface.withOpacity(0.5), + ), border: widget.inputBorder, filled: widget.filled, - fillColor: inputTheme.textFieldColor, + fillColor: widget.inputFillColor ?? + theme.colors.surfaceContainerHigh + // ignore: deprecated_member_use + .withOpacity(0.8), hoverColor: Colors.transparent, ), - style: inputTheme.textStyle, + style: theme.typography.bodyMedium.copyWith( + color: widget.textColor ?? theme.colors.onSurface, + ), onSubmitted: _handleSubmitted, textInputAction: TextInputAction.send, ), @@ -132,7 +160,9 @@ class _ChatInputState extends State { widget.sendIcon != null ? IconButton( icon: widget.sendIcon!, - color: inputTheme.hintStyle?.color, + color: widget.sendIconColor ?? + // ignore: deprecated_member_use + theme.colors.onSurface.withOpacity(0.5), onPressed: () => _handleSubmitted(_textController.text), ) diff --git a/packages/flutter_chat_ui/lib/src/chat_message/chat_message.dart b/packages/flutter_chat_ui/lib/src/chat_message/chat_message.dart index 994a793a..1e199d3c 100644 --- a/packages/flutter_chat_ui/lib/src/chat_message/chat_message.dart +++ b/packages/flutter_chat_ui/lib/src/chat_message/chat_message.dart @@ -5,7 +5,7 @@ import 'package:provider/provider.dart'; import '../utils/typedefs.dart'; class ChatMessage extends StatelessWidget { - static const EdgeInsetsGeometry _sentinelValue = EdgeInsets.zero; + static const EdgeInsetsGeometry _sentinelPadding = EdgeInsets.zero; final Message message; final int index; @@ -21,6 +21,9 @@ class ChatMessage extends StatelessWidget { final Duration? paddingChangeAnimationDuration; final bool? isRemoved; final int? messageGroupingTimeoutInSeconds; + final double? horizontalPadding; + final double? verticalPadding; + final double? verticalGroupedPadding; const ChatMessage({ super.key, @@ -34,10 +37,13 @@ class ChatMessage extends StatelessWidget { this.receivedMessageAlignment = AlignmentDirectional.centerStart, this.scaleAnimationAlignment, this.alignment, - this.padding = _sentinelValue, + this.padding = _sentinelPadding, this.paddingChangeAnimationDuration = const Duration(milliseconds: 250), this.isRemoved, this.messageGroupingTimeoutInSeconds = 300, + this.horizontalPadding = 8, + this.verticalPadding = 12, + this.verticalGroupedPadding = 2, }); @override @@ -51,7 +57,7 @@ class ChatMessage extends StatelessWidget { ); final resolvedPadding = - padding == _sentinelValue ? _calculateDefaultPadding(context) : padding; + padding == _sentinelPadding ? _resolveDefaultPadding(context) : padding; return GestureDetector( onTap: () => onMessageTap?.call(message), @@ -87,14 +93,14 @@ class ChatMessage extends StatelessWidget { ); } - EdgeInsetsGeometry _calculateDefaultPadding(BuildContext context) { + EdgeInsetsGeometry _resolveDefaultPadding(BuildContext context) { if (message is TextMessage && (message as TextMessage).isOnlyEmoji == true) { return EdgeInsets.zero; } if (index == 0) { - return const EdgeInsets.symmetric(horizontal: 8); + return EdgeInsets.symmetric(horizontal: horizontalPadding ?? 0); } try { @@ -106,10 +112,25 @@ class ChatMessage extends StatelessWidget { (messageGroupingTimeoutInSeconds ?? 0); return isGrouped || isRemoved == true - ? const EdgeInsets.fromLTRB(8, 2, 8, 0) - : const EdgeInsets.fromLTRB(8, 12, 8, 0); + ? EdgeInsets.fromLTRB( + horizontalPadding ?? 0, + verticalGroupedPadding ?? 0, + horizontalPadding ?? 0, + 0, + ) + : EdgeInsets.fromLTRB( + horizontalPadding ?? 0, + verticalPadding ?? 0, + horizontalPadding ?? 0, + 0, + ); } catch (e) { - return const EdgeInsets.fromLTRB(8, 2, 8, 0); + return EdgeInsets.fromLTRB( + horizontalPadding ?? 0, + verticalPadding ?? 0, + horizontalPadding ?? 0, + 0, + ); } } } diff --git a/packages/flutter_chat_ui/lib/src/is_typing.dart b/packages/flutter_chat_ui/lib/src/is_typing.dart index fa62d267..a7788dd5 100644 --- a/packages/flutter_chat_ui/lib/src/is_typing.dart +++ b/packages/flutter_chat_ui/lib/src/is_typing.dart @@ -72,7 +72,7 @@ class _IsTypingIndicatorState extends State @override Widget build(BuildContext context) { - final dotColor = _getDotColor(context); + final dotColor = _resolveDotColor(context); return Padding( padding: EdgeInsets.symmetric(vertical: widget.size / 2), @@ -105,11 +105,13 @@ class _IsTypingIndicatorState extends State ); } - Color? _getDotColor(BuildContext context) { + Color? _resolveDotColor(BuildContext context) { if (widget.color != null) return widget.color; try { - return context.select((ChatTheme theme) => theme.isTypingTheme).color; + return context.select( + (ChatTheme theme) => theme.colors.onSurface, + ); } catch (_) { return null; } diff --git a/packages/flutter_chat_ui/lib/src/scroll_to_bottom.dart b/packages/flutter_chat_ui/lib/src/scroll_to_bottom.dart index 2a8f7ddb..9445f530 100644 --- a/packages/flutter_chat_ui/lib/src/scroll_to_bottom.dart +++ b/packages/flutter_chat_ui/lib/src/scroll_to_bottom.dart @@ -16,6 +16,8 @@ class ScrollToBottom extends StatelessWidget { final ShapeBorder? shape; final Widget? icon; final bool? handleSafeArea; + final Color? backgroundColor; + final Color? foregroundColor; const ScrollToBottom({ super.key, @@ -30,13 +32,19 @@ class ScrollToBottom extends StatelessWidget { this.shape = const CircleBorder(), this.icon = const Icon(Icons.keyboard_arrow_down), this.handleSafeArea = true, + this.backgroundColor, + this.foregroundColor, }); @override Widget build(BuildContext context) { final bottomSafeArea = MediaQuery.of(context).padding.bottom; - final scrollToBottomTheme = - context.select((ChatTheme theme) => theme.scrollToBottomTheme); + final colors = context.select( + (ChatTheme theme) => ( + onSurface: theme.colors.onSurface, + surfaceContainer: theme.colors.surfaceContainer, + ), + ); return Consumer( builder: (context, heightNotifier, child) { @@ -52,8 +60,8 @@ class ScrollToBottom extends StatelessWidget { child: ScaleTransition( scale: animation, child: FloatingActionButton( - backgroundColor: scrollToBottomTheme.backgroundColor, - foregroundColor: scrollToBottomTheme.foregroundColor, + backgroundColor: backgroundColor ?? colors.surfaceContainer, + foregroundColor: foregroundColor ?? colors.onSurface, heroTag: null, mini: mini ?? false, shape: shape, diff --git a/packages/flutter_chat_ui/lib/src/simple_text_message.dart b/packages/flutter_chat_ui/lib/src/simple_text_message.dart index 60ef38d0..71ec89fb 100644 --- a/packages/flutter_chat_ui/lib/src/simple_text_message.dart +++ b/packages/flutter_chat_ui/lib/src/simple_text_message.dart @@ -3,11 +3,19 @@ import 'package:flutter_chat_core/flutter_chat_core.dart'; import 'package:provider/provider.dart'; class SimpleTextMessage extends StatelessWidget { + static const BorderRadiusGeometry _sentinelBorderRadius = BorderRadius.zero; + static const Color _sentinelColor = Colors.transparent; + static const TextStyle _sentinelTextStyle = TextStyle(); + final TextMessage message; final int index; final EdgeInsetsGeometry? padding; final BorderRadiusGeometry? borderRadius; final double? onlyEmojiFontSize; + final Color? sentBackgroundColor; + final Color? receivedBackgroundColor; + final TextStyle? sentTextStyle; + final TextStyle? receivedTextStyle; const SimpleTextMessage({ super.key, @@ -17,35 +25,61 @@ class SimpleTextMessage extends StatelessWidget { horizontal: 16, vertical: 10, ), - this.borderRadius = const BorderRadius.all(Radius.circular(12)), + this.borderRadius = _sentinelBorderRadius, this.onlyEmojiFontSize = 48, + this.sentBackgroundColor = _sentinelColor, + this.receivedBackgroundColor = _sentinelColor, + this.sentTextStyle = _sentinelTextStyle, + this.receivedTextStyle = _sentinelTextStyle, }); + bool get _isOnlyEmoji => message.isOnlyEmoji == true; + @override Widget build(BuildContext context) { - final textMessageTheme = - context.select((ChatTheme theme) => theme.textMessageTheme); + final theme = context.watch(); final isSentByMe = context.watch() == message.authorId; - final textStyle = isSentByMe - ? textMessageTheme.sentTextStyle - : textMessageTheme.receivedTextStyle; + final backgroundColor = _resolveBackgroundColor(isSentByMe, theme); + final textStyle = _resolveTextStyle(isSentByMe, theme); return Container( padding: padding, - decoration: message.isOnlyEmoji == true + decoration: _isOnlyEmoji ? null : BoxDecoration( - color: isSentByMe - ? textMessageTheme.sentBackgroundColor - : textMessageTheme.receivedBackgroundColor, - borderRadius: borderRadius, + color: backgroundColor, + borderRadius: borderRadius == _sentinelBorderRadius + ? theme.shape + : borderRadius, ), child: Text( message.text, - style: message.isOnlyEmoji == true + style: _isOnlyEmoji ? textStyle?.copyWith(fontSize: onlyEmojiFontSize) : textStyle, ), ); } + + Color? _resolveBackgroundColor(bool isSentByMe, ChatTheme theme) { + if (isSentByMe) { + return sentBackgroundColor == _sentinelColor + ? theme.colors.primary + : sentBackgroundColor; + } + return receivedBackgroundColor == _sentinelColor + ? theme.colors.surfaceContainer + : receivedBackgroundColor; + } + + TextStyle? _resolveTextStyle(bool isSentByMe, ChatTheme theme) { + if (isSentByMe) { + return sentTextStyle == _sentinelTextStyle + ? theme.typography.bodyMedium.copyWith(color: theme.colors.onPrimary) + : sentTextStyle; + } + return receivedTextStyle == _sentinelTextStyle + ? theme.typography.bodyMedium.copyWith(color: theme.colors.onSurface) + : receivedTextStyle; + } } diff --git a/packages/flyer_chat_image_message/lib/src/flyer_chat_image_message.dart b/packages/flyer_chat_image_message/lib/src/flyer_chat_image_message.dart index c9c41ff3..3a23ca9e 100644 --- a/packages/flyer_chat_image_message/lib/src/flyer_chat_image_message.dart +++ b/packages/flyer_chat_image_message/lib/src/flyer_chat_image_message.dart @@ -12,19 +12,32 @@ import 'package:thumbhash/thumbhash.dart' import 'get_image_dimensions.dart'; class FlyerChatImageMessage extends StatefulWidget { + static const BorderRadiusGeometry _sentinelBorderRadius = BorderRadius.zero; + static const Color _sentinelColor = Colors.transparent; + final ImageMessage message; final int index; final BorderRadiusGeometry? borderRadius; final BoxConstraints? constraints; final Widget? overlay; + final Color? placeholderColor; + final Color? loadingOverlayColor; + final Color? loadingIndicatorColor; + final Color? uploadOverlayColor; + final Color? uploadIndicatorColor; const FlyerChatImageMessage({ super.key, required this.message, required this.index, - this.borderRadius = const BorderRadius.all(Radius.circular(12)), + this.borderRadius = _sentinelBorderRadius, this.constraints = const BoxConstraints(maxHeight: 300), this.overlay, + this.placeholderColor = _sentinelColor, + this.loadingOverlayColor = _sentinelColor, + this.loadingIndicatorColor = _sentinelColor, + this.uploadOverlayColor = _sentinelColor, + this.uploadIndicatorColor = _sentinelColor, }); @override @@ -113,11 +126,13 @@ class FlyerChatImageMessageState extends State @override Widget build(BuildContext context) { - final imageMessageTheme = - context.select((ChatTheme theme) => theme.imageMessageTheme); + final theme = context.watch(); return ClipRRect( - borderRadius: widget.borderRadius ?? BorderRadius.zero, + borderRadius: + widget.borderRadius == FlyerChatImageMessage._sentinelBorderRadius + ? theme.shape + : (widget.borderRadius ?? BorderRadius.zero), child: Container( constraints: widget.constraints, child: AspectRatio( @@ -131,7 +146,10 @@ class FlyerChatImageMessageState extends State fit: BoxFit.fill, ) : Container( - color: imageMessageTheme.placeholderColor, + color: widget.placeholderColor == + FlyerChatImageMessage._sentinelColor + ? theme.colors.surfaceContainerLow + : widget.placeholderColor, ), Image( image: _cachedNetworkImage, @@ -141,14 +159,25 @@ class FlyerChatImageMessageState extends State return child; } - return Center( - child: CircularProgressIndicator( - color: imageMessageTheme.downloadProgressIndicatorColor, - strokeCap: StrokeCap.round, - value: loadingProgress.expectedTotalBytes != null - ? loadingProgress.cumulativeBytesLoaded / - loadingProgress.expectedTotalBytes! - : null, + return Container( + color: widget.loadingOverlayColor == + FlyerChatImageMessage._sentinelColor + // ignore: deprecated_member_use + ? theme.colors.surfaceContainerLow.withOpacity(0.5) + : widget.loadingOverlayColor, + child: Center( + child: CircularProgressIndicator( + color: widget.loadingIndicatorColor == + FlyerChatImageMessage._sentinelColor + // ignore: deprecated_member_use + ? theme.colors.onSurface.withOpacity(0.8) + : widget.loadingIndicatorColor, + strokeCap: StrokeCap.round, + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null, + ), ), ); }, @@ -186,10 +215,18 @@ class FlyerChatImageMessageState extends State } return Container( - color: imageMessageTheme.uploadOverlayColor, + color: widget.uploadOverlayColor == + FlyerChatImageMessage._sentinelColor + // ignore: deprecated_member_use + ? theme.colors.surfaceContainerLow.withOpacity(0.5) + : widget.uploadOverlayColor, child: Center( child: CircularProgressIndicator( - color: imageMessageTheme.uploadProgressIndicatorColor, + color: widget.uploadIndicatorColor == + FlyerChatImageMessage._sentinelColor + // ignore: deprecated_member_use + ? theme.colors.onSurface.withOpacity(0.8) + : widget.uploadIndicatorColor, strokeCap: StrokeCap.round, value: snapshot.data, ), diff --git a/packages/flyer_chat_text_message/lib/src/flyer_chat_text_message.dart b/packages/flyer_chat_text_message/lib/src/flyer_chat_text_message.dart index 4e8ce505..2bff8981 100644 --- a/packages/flyer_chat_text_message/lib/src/flyer_chat_text_message.dart +++ b/packages/flyer_chat_text_message/lib/src/flyer_chat_text_message.dart @@ -4,11 +4,19 @@ import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:provider/provider.dart'; class FlyerChatTextMessage extends StatelessWidget { + static const BorderRadiusGeometry _sentinelBorderRadius = BorderRadius.zero; + static const Color _sentinelColor = Colors.transparent; + static const TextStyle _sentinelTextStyle = TextStyle(); + final TextMessage message; final int index; final EdgeInsetsGeometry? padding; final BorderRadiusGeometry? borderRadius; final double? onlyEmojiFontSize; + final Color? sentBackgroundColor; + final Color? receivedBackgroundColor; + final TextStyle? sentTextStyle; + final TextStyle? receivedTextStyle; const FlyerChatTextMessage({ super.key, @@ -18,37 +26,63 @@ class FlyerChatTextMessage extends StatelessWidget { horizontal: 16, vertical: 10, ), - this.borderRadius = const BorderRadius.all(Radius.circular(12)), + this.borderRadius = _sentinelBorderRadius, this.onlyEmojiFontSize = 48, + this.sentBackgroundColor = _sentinelColor, + this.receivedBackgroundColor = _sentinelColor, + this.sentTextStyle = _sentinelTextStyle, + this.receivedTextStyle = _sentinelTextStyle, }); + bool get _isOnlyEmoji => message.isOnlyEmoji == true; + @override Widget build(BuildContext context) { - final textMessageTheme = - context.select((ChatTheme theme) => theme.textMessageTheme); + final theme = context.watch(); final isSentByMe = context.watch() == message.authorId; - final paragraphStyle = isSentByMe - ? textMessageTheme.sentTextStyle - : textMessageTheme.receivedTextStyle; + final backgroundColor = _resolveBackgroundColor(isSentByMe, theme); + final paragraphStyle = _resolveParagraphStyle(isSentByMe, theme); return Container( padding: padding, - decoration: message.isOnlyEmoji == true + decoration: _isOnlyEmoji ? null : BoxDecoration( - color: isSentByMe - ? textMessageTheme.sentBackgroundColor - : textMessageTheme.receivedBackgroundColor, - borderRadius: borderRadius, + color: backgroundColor, + borderRadius: borderRadius == _sentinelBorderRadius + ? theme.shape + : borderRadius, ), child: MarkdownBody( data: message.text, styleSheet: MarkdownStyleSheet( - p: message.isOnlyEmoji == true + p: _isOnlyEmoji ? paragraphStyle?.copyWith(fontSize: onlyEmojiFontSize) : paragraphStyle, ), ), ); } + + Color? _resolveBackgroundColor(bool isSentByMe, ChatTheme theme) { + if (isSentByMe) { + return sentBackgroundColor == _sentinelColor + ? theme.colors.primary + : sentBackgroundColor; + } + return receivedBackgroundColor == _sentinelColor + ? theme.colors.surfaceContainer + : receivedBackgroundColor; + } + + TextStyle? _resolveParagraphStyle(bool isSentByMe, ChatTheme theme) { + if (isSentByMe) { + return sentTextStyle == _sentinelTextStyle + ? theme.typography.bodyMedium.copyWith(color: theme.colors.onPrimary) + : sentTextStyle; + } + return receivedTextStyle == _sentinelTextStyle + ? theme.typography.bodyMedium.copyWith(color: theme.colors.onSurface) + : receivedTextStyle; + } }