diff --git a/.gitignore b/.gitignore index 28b825a6..457042a0 100644 --- a/.gitignore +++ b/.gitignore @@ -59,4 +59,5 @@ doc/api/ *.js.deps *.js.map -fvm \ No newline at end of file +fvm +google-services.json \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index 567f9e00..32af2bd3 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -23,6 +23,9 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( + theme: ThemeData.light(), + darkTheme: ThemeData.dark(), + themeMode: ThemeMode.system, home: Container( child: StreamChat( client: client, diff --git a/lib/src/channel_header.dart b/lib/src/channel_header.dart index f2059c42..ae68bcb7 100644 --- a/lib/src/channel_header.dart +++ b/lib/src/channel_header.dart @@ -136,12 +136,16 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { Navigator.of(context).pop(); } }, - fillColor: Colors.black.withOpacity(.1), + fillColor: Theme.of(context).brightness == Brightness.dark + ? Colors.white.withOpacity(.1) + : Colors.black.withOpacity(.1), padding: EdgeInsets.all(4), child: Icon( Icons.arrow_back_ios, size: 15, - color: Colors.black, + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, ), ), ); diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index e9114403..e968e6c0 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -298,7 +298,9 @@ class _ChannelListViewState extends State { Widget _separatorBuilder(context, i) { return Container( height: 1, - color: Colors.black.withOpacity(0.1), + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white.withOpacity(0.1) + : Colors.black.withOpacity(0.1), margin: EdgeInsets.symmetric(horizontal: 16), ); } diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index f1025385..e1b3cfc1 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -205,7 +205,10 @@ class _MessageInputState extends State { ), child: Container( decoration: BoxDecoration( - color: Colors.white, + color: StreamChatTheme.of(context) + .channelTheme + .inputBackground + .withAlpha(255), borderRadius: BorderRadius.circular(10.0), ), child: Container( @@ -215,7 +218,9 @@ class _MessageInputState extends State { border: Border.all( color: _typingStarted ? Colors.transparent - : Colors.black.withOpacity(.2)), + : Theme.of(context).brightness == Brightness.dark + ? Colors.white.withOpacity(.2) + : Colors.black.withOpacity(.2)), ), ), ), @@ -761,7 +766,10 @@ class _MessageInputState extends State { if (attachment.type == 'image') { _attachments.add(_SendingAttachment( type: FileType.image, - url: attachment.imageUrl, + url: attachment.imageUrl ?? + attachment.assetUrl ?? + attachment.thumbUrl ?? + attachment.ogScrapeUrl, uploaded: true, )); } else if (attachment.type == 'video') { diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index a0bf35f4..a102ede0 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -146,7 +146,7 @@ class _MessageListViewState extends State { 'Start of thread', textAlign: TextAlign.center, ), - color: Theme.of(context).primaryColorLight, + color: Theme.of(context).accentColor.withAlpha(50), ), ), ], diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 10b787da..62c41148 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -157,8 +157,10 @@ class _MessageWidgetState extends State ), child: CircleAvatar( radius: 4, + backgroundColor: Theme.of(context).accentColor, child: Icon( Icons.done, + color: Colors.white, size: 4, ), ), @@ -187,7 +189,7 @@ class _MessageWidgetState extends State ), child: CircleAvatar( radius: 4, - backgroundColor: Color(0xffd0021B).withAlpha(125), + backgroundColor: Color(0xffd0021B).withOpacity(.1), child: Icon( Icons.error_outline, size: 4, @@ -229,7 +231,9 @@ class _MessageWidgetState extends State 'This message was deleted...', style: _messageTheme.messageText.copyWith( fontStyle: FontStyle.italic, - color: Colors.black, + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, ), ), ), @@ -247,7 +251,9 @@ class _MessageWidgetState extends State alignment: Alignment.center, child: Icon( Icons.subdirectory_arrow_left, - color: Colors.black12, + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white12 + : Colors.black12, ), ), ]; @@ -396,9 +402,7 @@ class _MessageWidgetState extends State int nOfAttachmentWidgets, BuildContext context, ) { - final boxDecoration = _buildBoxDecoration(_isLastUser).copyWith( - color: Color(0xffebebeb), - ); + final boxDecoration = _buildBoxDecoration(_isLastUser); return Padding( padding: const EdgeInsets.only(bottom: 2.0), child: Column( @@ -409,7 +413,8 @@ class _MessageWidgetState extends State child: Container( decoration: boxDecoration, constraints: BoxConstraints.loose( - Size.fromWidth(MediaQuery.of(context).size.width * 0.7)), + Size.fromWidth(MediaQuery.of(context).size.width * 0.7), + ), child: Stack( children: [ Column( @@ -462,7 +467,9 @@ class _MessageWidgetState extends State Text( 'MESSAGE FAILED ยท CLICK TO TRY AGAIN', style: _messageTheme.messageText.copyWith( - color: Colors.black.withOpacity(.5), + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white.withOpacity(.5) + : Colors.black.withOpacity(.5), fontSize: 11, ), ), @@ -614,7 +621,6 @@ class _MessageWidgetState extends State ], ), ), - color: Color(0xffebebeb), ), ); } @@ -626,7 +632,11 @@ class _MessageWidgetState extends State right: !_isMyMessage ? 8 : null, top: -6, child: CustomPaint( - painter: _ReactionBubblePainter(), + painter: _ReactionBubblePainter( + Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, + ), ), ) : SizedBox(); @@ -775,12 +785,18 @@ class _MessageWidgetState extends State onPressed: () { Navigator.of(context).pop(); }, - fillColor: Colors.black.withOpacity(.1), + fillColor: + Theme.of(context).brightness == Brightness.dark + ? Colors.white.withOpacity(.1) + : Colors.black.withOpacity(.1), padding: EdgeInsets.all(4), child: Icon( Icons.close, size: 15, - color: Colors.black, + color: + Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, ), ), ), @@ -833,7 +849,9 @@ class _MessageWidgetState extends State ? const EdgeInsets.all(8) : EdgeInsets.zero, decoration: BoxDecoration( - color: Colors.black, + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, borderRadius: BorderRadius.all(Radius.circular(14))), child: AnimatedSwitcher( duration: Duration(milliseconds: 300), @@ -864,7 +882,11 @@ class _MessageWidgetState extends State widget.message.reactionCounts.values .fold(0, (t, v) => v + t) .toString(), - style: TextStyle(color: Colors.white), + style: TextStyle( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.black + : Colors.white, + ), ), ), ], @@ -886,7 +908,7 @@ class _MessageWidgetState extends State final errorWidget = Container( width: 200, height: 140, - color: Color(0xffd0021B).withAlpha(26), + color: Color(0xffd0021B).withOpacity(.1), child: Center( child: Icon( Icons.error_outline, @@ -1006,8 +1028,12 @@ class _MessageWidgetState extends State BoxDecoration _buildBoxDecoration(bool rectBorders) { return BoxDecoration( - border: - _isMyMessage ? null : Border.all(color: Colors.black.withAlpha(8)), + border: _isMyMessage + ? null + : Border.all( + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white.withAlpha(24) + : Colors.black.withAlpha(24)), borderRadius: BorderRadius.only( topLeft: Radius.circular((_isMyMessage || !rectBorders) ? 16 : 2), bottomLeft: Radius.circular(_isMyMessage ? 16 : 2), @@ -1015,7 +1041,7 @@ class _MessageWidgetState extends State bottomRight: Radius.circular(_isMyMessage ? 2 : 16), ), color: widget.message.status == MessageSendingStatus.FAILED - ? Color(0xffd0021B).withAlpha(26) + ? Color(0xffd0021B).withOpacity(.1) : _messageTheme.messageBackgroundColor, ); } @@ -1027,9 +1053,13 @@ class _MessageWidgetState extends State } class _ReactionBubblePainter extends CustomPainter { + final Color color; + + _ReactionBubblePainter(this.color); + @override void paint(Canvas canvas, Size size) { - final paint = Paint()..color = Colors.black; + final paint = Paint()..color = color; final path = Path(); path.arcToPoint(Offset(-6, -6)); path.arcToPoint(Offset(0, 10)); diff --git a/lib/src/stream_chat.dart b/lib/src/stream_chat.dart index 11c41a71..19d1608d 100644 --- a/lib/src/stream_chat.dart +++ b/lib/src/stream_chat.dart @@ -72,33 +72,37 @@ class StreamChatState extends State return StreamChatTheme( data: theme, child: Builder( - builder: (context) => Theme( - data: Theme.of(context).copyWith( - accentColor: StreamChatTheme.of(context).accentColor, - scaffoldBackgroundColor: Colors.white, - backgroundColor: Colors.white, - ), - child: WillPopScope( - onWillPop: () async { - if (_navigatorKey.currentState.canPop()) { - _navigatorKey.currentState.pop(); - return false; - } else { - return true; - } - }, - child: Navigator( - initialRoute: '/', - key: _navigatorKey, - onGenerateRoute: (settings) { - return MaterialPageRoute( - settings: settings, - builder: (_) => widget.child, - ); - }, + builder: (context) { + final materialTheme = Theme.of(context); + final isDark = materialTheme.brightness == Brightness.dark; + return Theme( + data: materialTheme.copyWith( + accentColor: StreamChatTheme.of(context).accentColor, + scaffoldBackgroundColor: isDark ? Colors.black : Colors.white, + backgroundColor: isDark ? Colors.black : Colors.white, ), - ), - ), + child: WillPopScope( + onWillPop: () async { + if (_navigatorKey.currentState.canPop()) { + _navigatorKey.currentState.pop(); + return false; + } else { + return true; + } + }, + child: Navigator( + initialRoute: '/', + key: _navigatorKey, + onGenerateRoute: (settings) { + return MaterialPageRoute( + settings: settings, + builder: (_) => widget.child, + ); + }, + ), + ), + ); + }, ), ); } diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index eedc499b..e6053939 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -166,9 +166,10 @@ class StreamChatThemeData { /// Get the default Stream Chat theme static StreamChatThemeData getDefaultTheme(ThemeData theme) { final accentColor = Color(0xff006cff); + final isDark = theme.brightness == Brightness.dark; return StreamChatThemeData( accentColor: accentColor, - primaryColor: Colors.white, + primaryColor: isDark ? Colors.black : Colors.white, channelPreviewTheme: ChannelPreviewTheme( avatarTheme: AvatarTheme( borderRadius: BorderRadius.circular(20), @@ -179,15 +180,17 @@ class StreamChatThemeData { ), title: TextStyle( fontSize: 14, - color: Colors.black, + color: isDark ? Colors.white : Colors.black, ), subtitle: TextStyle( fontSize: 13, - color: Colors.black, + color: isDark ? Colors.white : Colors.black, ), lastMessageAt: TextStyle( fontSize: 11, - color: Colors.black.withOpacity(.5), + color: isDark + ? Colors.white.withOpacity(.5) + : Colors.black.withOpacity(.5), ), ), channelTheme: ChannelTheme( @@ -202,17 +205,20 @@ class StreamChatThemeData { width: 40, ), ), - color: Colors.white, + color: isDark ? Colors.black : Colors.white, title: TextStyle( fontSize: 14, - color: Colors.black, + color: isDark ? Colors.white : Colors.black, ), lastMessageAt: TextStyle( fontSize: 11, - color: Colors.black.withOpacity(.5), + color: isDark + ? Colors.white.withOpacity(.5) + : Colors.black.withOpacity(.5), ), ), - inputBackground: Colors.black.withAlpha(12), + inputBackground: + isDark ? Colors.black.withAlpha(12) : Colors.white.withAlpha(12), inputGradient: LinearGradient(colors: [ Color(0xFF00AEFF), Color(0xFF0076FF), @@ -221,10 +227,12 @@ class StreamChatThemeData { ownMessageTheme: MessageTheme( messageText: TextStyle( fontSize: 15, - color: Colors.black, + color: isDark ? Colors.white : Colors.black, ), createdAt: TextStyle( - color: Colors.black.withOpacity(.5), + color: isDark + ? Colors.white.withOpacity(.5) + : Colors.black.withOpacity(.5), fontSize: 11, ), replies: TextStyle( @@ -232,7 +240,7 @@ class StreamChatThemeData { fontWeight: FontWeight.bold, fontSize: 12, ), - messageBackgroundColor: Color(0xffebebeb), + messageBackgroundColor: Color(0x33ebebeb), avatarTheme: AvatarTheme( borderRadius: BorderRadius.circular(20), constraints: BoxConstraints.tightFor( @@ -244,10 +252,12 @@ class StreamChatThemeData { otherMessageTheme: MessageTheme( messageText: TextStyle( fontSize: 15, - color: Colors.black, + color: isDark ? Colors.white : Colors.black, ), createdAt: TextStyle( - color: Colors.black.withOpacity(.5), + color: isDark + ? Colors.white.withOpacity(.5) + : Colors.black.withOpacity(.5), fontSize: 11, ), replies: TextStyle( @@ -255,7 +265,7 @@ class StreamChatThemeData { fontWeight: FontWeight.bold, fontSize: 12, ), - messageBackgroundColor: Colors.white, + messageBackgroundColor: isDark ? Colors.black : Colors.white, avatarTheme: AvatarTheme( borderRadius: BorderRadius.circular(20), constraints: BoxConstraints.tightFor( diff --git a/lib/src/thread_header.dart b/lib/src/thread_header.dart index fc45fde8..07f10e60 100644 --- a/lib/src/thread_header.dart +++ b/lib/src/thread_header.dart @@ -122,12 +122,16 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { Navigator.of(context).pop(); } }, - fillColor: Colors.black.withOpacity(.1), + fillColor: Theme.of(context).brightness == Brightness.dark + ? Colors.white.withOpacity(.1) + : Colors.black.withOpacity(.1), padding: EdgeInsets.all(4), child: Icon( Icons.close, size: 15, - color: Colors.black, + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, ), ), ),