From 06b2929c37c256dea3e907c3e7e7c7a3bec72d09 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 2 Dec 2020 13:19:31 +0100 Subject: [PATCH 01/31] wip --- example/lib/advanced_options_page.dart | 8 +- example/lib/chips_input_text_field.dart | 17 ++-- example/lib/choose_user_page.dart | 36 +++++--- example/lib/main.dart | 3 + example/lib/new_chat_screen.dart | 36 ++++---- example/lib/new_group_chat_screen.dart | 9 +- example/lib/search_text_field.dart | 9 +- example/pubspec.yaml | 2 +- lib/src/channel_list_header.dart | 9 +- lib/src/channel_list_view.dart | 28 +++--- lib/src/channel_preview.dart | 3 + lib/src/message_list_view.dart | 8 +- lib/src/message_search_item.dart | 2 - lib/src/stream_chat_theme.dart | 118 +++++++++++++++++++----- lib/src/user_item.dart | 10 +- lib/src/user_list_view.dart | 2 +- 16 files changed, 203 insertions(+), 97 deletions(-) diff --git a/example/lib/advanced_options_page.dart b/example/lib/advanced_options_page.dart index e07afefd..6c922e3d 100644 --- a/example/lib/advanced_options_page.dart +++ b/example/lib/advanced_options_page.dart @@ -39,11 +39,13 @@ class _AdvancedOptionsPageState extends State { backgroundColor: StreamChatTheme.of(context).primaryColor, elevation: 1, centerTitle: true, + brightness: Theme.of(context).brightness, title: Text( 'Advanced Options', - style: Theme.of(context).textTheme.subtitle1.copyWith( - fontWeight: FontWeight.bold, - ), + style: StreamChatTheme.of(context) + .textTheme + .headlineBold + .copyWith(color: Colors.black), ), leading: IconButton( icon: StreamSvgIcon.left( diff --git a/example/lib/chips_input_text_field.dart b/example/lib/chips_input_text_field.dart index 2ef308f8..efa3b10e 100644 --- a/example/lib/chips_input_text_field.dart +++ b/example/lib/chips_input_text_field.dart @@ -78,10 +78,10 @@ class ChipInputTextFieldState extends State> { padding: const EdgeInsets.symmetric(vertical: 4.0), child: Text( 'TO:', - style: TextStyle( - fontSize: 12, - color: Colors.black.withOpacity(0.5), - ), + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith(color: Colors.black.withOpacity(.5)), ), ), SizedBox(width: 12), @@ -111,10 +111,11 @@ class ChipInputTextFieldState extends State> { disabledBorder: InputBorder.none, contentPadding: const EdgeInsets.only(top: 4.0), hintText: widget.hint, - hintStyle: TextStyle( - color: Colors.black.withOpacity(0.5), - fontSize: 14, - ), + hintStyle: StreamChatTheme.of(context) + .textTheme + .body + .copyWith( + color: Colors.black.withOpacity(.5)), ), ), ], diff --git a/example/lib/choose_user_page.dart b/example/lib/choose_user_page.dart index c728a193..9c732145 100644 --- a/example/lib/choose_user_page.dart +++ b/example/lib/choose_user_page.dart @@ -80,19 +80,12 @@ class ChooseUserPage extends StatelessWidget { padding: const EdgeInsets.only(bottom: 13.0), child: Text( 'Welcome to Stream Chat', - style: TextStyle( - fontSize: 22, - color: Colors.black, - fontWeight: FontWeight.bold, - ), + style: StreamChatTheme.of(context).textTheme.title, ), ), Text( 'Select a user to try the Flutter SDK:', - style: TextStyle( - fontSize: 14.5, - color: Colors.black, - ), + style: StreamChatTheme.of(context).textTheme.body, ), Expanded( child: Padding( @@ -169,9 +162,18 @@ class ChooseUserPage extends StatelessWidget { ), title: Text( user.name, - style: TextStyle(fontWeight: FontWeight.bold), + style: + StreamChatTheme.of(context).textTheme.bodyBold, + ), + subtitle: Text( + 'Stream test account', + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith( + color: Color(0xff7A7A7A), + ), ), - subtitle: Text('Stream test account'), trailing: SvgPicture.asset( 'assets/icon_arrow_right.svg', height: 24, @@ -192,9 +194,17 @@ class ChooseUserPage extends StatelessWidget { ), title: Text( 'Advanced Options', - style: TextStyle(fontWeight: FontWeight.bold), + style: StreamChatTheme.of(context).textTheme.bodyBold, + ), + subtitle: Text( + 'Custom settings', + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith( + color: Color(0xff7A7A7A), + ), ), - subtitle: Text('Custom settings'), trailing: SvgPicture.asset( 'assets/icon_arrow_right.svg', height: 24, diff --git a/example/lib/main.dart b/example/lib/main.dart index 4b529e23..8749a2cf 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -123,6 +123,9 @@ class _HomePageState extends State { bottomNavigationBar: BottomNavigationBar( currentIndex: _currentIndex, items: _navBarItems, + selectedLabelStyle: StreamChatTheme.of(context).textTheme.footnoteBold, + unselectedLabelStyle: + StreamChatTheme.of(context).textTheme.footnoteBold, type: BottomNavigationBarType.fixed, selectedItemColor: Colors.black, unselectedItemColor: Colors.grey, diff --git a/example/lib/new_chat_screen.dart b/example/lib/new_chat_screen.dart index 5fbfbf07..5caa4c6f 100644 --- a/example/lib/new_chat_screen.dart +++ b/example/lib/new_chat_screen.dart @@ -113,10 +113,10 @@ class _NewChatScreenState extends State { leading: const StreamBackButton(), title: Text( 'New Chat', - style: TextStyle( - color: Colors.black, - fontSize: 16, - ), + style: StreamChatTheme.of(context) + .textTheme + .headlineBold + .copyWith(color: Colors.black), ), centerTitle: true, ), @@ -203,10 +203,7 @@ class _NewChatScreenState extends State { SizedBox(width: 8), Text( 'Create a Group', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, - ), + style: StreamChatTheme.of(context).textTheme.bodyBold, ), ], ), @@ -233,13 +230,13 @@ class _NewChatScreenState extends State { horizontal: 8, ), child: Text( - _isSearchActive - ? "Matches for \"$_userNameQuery\"" - : 'On the platform', - style: TextStyle( - color: Colors.black.withOpacity(0.5), - ), - ), + _isSearchActive + ? "Matches for \"$_userNameQuery\"" + : 'On the platform', + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith(color: Colors.black.withOpacity(.5))), ), ), Expanded( @@ -299,7 +296,14 @@ class _NewChatScreenState extends State { ), ), Text( - 'No user matches these keywords...'), + 'No user matches these keywords...', + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith( + color: Colors.black + .withOpacity(.5)), + ), ], ), ), diff --git a/example/lib/new_group_chat_screen.dart b/example/lib/new_group_chat_screen.dart index ff77e44d..ba477a73 100644 --- a/example/lib/new_group_chat_screen.dart +++ b/example/lib/new_group_chat_screen.dart @@ -261,7 +261,14 @@ class _NewGroupChatScreenState extends State { color: Colors.grey, ), ), - Text('No user matches these keywords...'), + Text( + 'No user matches these keywords...', + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith( + color: Colors.black.withOpacity(.5)), + ), ], ), ), diff --git a/example/lib/search_text_field.dart b/example/lib/search_text_field.dart index e32bb88b..00859b59 100644 --- a/example/lib/search_text_field.dart +++ b/example/lib/search_text_field.dart @@ -40,6 +40,7 @@ class SearchTextField extends StatelessWidget { controller: controller, onChanged: onChanged, decoration: InputDecoration( + prefixText: ' ', prefixIconConstraints: BoxConstraints.tight(Size(40, 24)), prefixIcon: Padding( padding: const EdgeInsets.only( @@ -52,10 +53,10 @@ class SearchTextField extends StatelessWidget { ), ), hintText: hintText, - hintStyle: TextStyle( - color: Colors.black.withOpacity(0.5), - fontSize: 14, - ), + hintStyle: StreamChatTheme.of(context) + .textTheme + .body + .copyWith(color: Colors.black.withOpacity(.5)), contentPadding: const EdgeInsets.all(0), border: OutlineInputBorder( borderSide: BorderSide.none, diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 6ae2ab54..c5bfa14f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.87+89 +version: 1.0.88+90 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/channel_list_header.dart b/lib/src/channel_list_header.dart index 0a01733b..41b283f5 100644 --- a/lib/src/channel_list_header.dart +++ b/lib/src/channel_list_header.dart @@ -144,13 +144,8 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { Widget _buildConnectedTitleState(BuildContext context) => Text( 'Stream Chat', - style: StreamChatTheme.of(context) - .channelTheme - .channelHeaderTheme - .title - .copyWith( - fontSize: 16, - fontWeight: FontWeight.bold, + style: StreamChatTheme.of(context).textTheme.headlineBold.copyWith( + color: Colors.black, ), ); diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index 1a431672..8301f339 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -210,9 +210,9 @@ class _ChannelListViewState extends State padding: const EdgeInsets.all(8.0), child: Text( 'Let’s start chatting!', - style: TextStyle( - fontSize: 16, - ), + style: StreamChatTheme.of(context) + .textTheme + .headline, ), ), Padding( @@ -223,10 +223,12 @@ class _ChannelListViewState extends State child: Text( 'How about sending your first message to a friend?', textAlign: TextAlign.center, - style: TextStyle( - fontSize: 14, - color: Color(0xff7A7A7A), - ), + style: StreamChatTheme.of(context) + .textTheme + .body + .copyWith( + color: Color(0xff7A7A7A), + ), ), ), ], @@ -242,11 +244,13 @@ class _ChannelListViewState extends State onPressed: widget.onStartChatPressed, child: Text( 'Start a chat', - style: TextStyle( - color: - StreamChatTheme.of(context).accentColor, - fontWeight: FontWeight.bold, - ), + style: StreamChatTheme.of(context) + .textTheme + .bodyBold + .copyWith( + color: StreamChatTheme.of(context) + .accentColor, + ), ), ), ), diff --git a/lib/src/channel_preview.dart b/lib/src/channel_preview.dart index 26f68812..fb0a95c7 100644 --- a/lib/src/channel_preview.dart +++ b/lib/src/channel_preview.dart @@ -49,6 +49,9 @@ class ChannelPreview extends StatelessWidget { return Opacity( opacity: snapshot.data ? 0.5 : 1, child: ListTile( + contentPadding: const EdgeInsets.symmetric( + horizontal: 8, + ), onTap: () { if (onTap != null) { onTap(channel); diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 3feda8ce..8a4ac9c3 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -195,10 +195,10 @@ class _MessageListViewState extends State { return Center( child: Text( 'No chats here yet...', - style: TextStyle( - fontSize: 12, - color: Colors.black.withOpacity(.5), - ), + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith(color: Colors.black.withOpacity(.5)), ), ); } diff --git a/lib/src/message_search_item.dart b/lib/src/message_search_item.dart index 3e786b9a..0fba5d45 100644 --- a/lib/src/message_search_item.dart +++ b/lib/src/message_search_item.dart @@ -126,8 +126,6 @@ class MessageSearchItem extends StatelessWidget { maxLines: 1, overflow: TextOverflow.ellipsis, style: StreamChatTheme.of(context).channelPreviewTheme.subtitle.copyWith( - color: - StreamChatTheme.of(context).channelPreviewTheme.subtitle.color, fontStyle: (message.isSystem || message.isDeleted) ? FontStyle.italic : FontStyle.normal, diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index 54b096d1..3693f3d8 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -42,6 +42,9 @@ class StreamChatTheme extends InheritedWidget { /// Theme data class StreamChatThemeData { + /// The text themes used in the widgets + final TextTheme textTheme; + /// Primary color of the chat widgets final Color primaryColor; @@ -80,6 +83,7 @@ class StreamChatThemeData { /// Create a theme from scratch StreamChatThemeData({ + this.textTheme, this.primaryColor, this.secondaryColor, this.accentColor, @@ -131,6 +135,7 @@ class StreamChatThemeData { /// Creates a copy of [StreamChatThemeData] with specified attributes overridden. StreamChatThemeData copyWith({ + TextTheme textTheme, Color primaryColor, Color secondaryColor, Color accentColor, @@ -145,6 +150,16 @@ class StreamChatThemeData { List reactionIcons, }) => StreamChatThemeData( + textTheme: this.textTheme?.copyWith( + title: textTheme?.title, + body: textTheme?.body, + bodyBold: textTheme?.bodyBold, + captionBold: textTheme?.captionBold, + footnote: textTheme?.footnote, + footnoteBold: textTheme?.footnoteBold, + headline: textTheme?.headline, + headlineBold: textTheme?.headlineBold, + ), primaryColor: primaryColor ?? this.primaryColor, secondaryColor: secondaryColor ?? this.secondaryColor, primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme, @@ -152,17 +167,12 @@ class StreamChatThemeData { defaultChannelImage: defaultChannelImage ?? this.defaultChannelImage, defaultUserImage: defaultUserImage ?? this.defaultUserImage, backgroundColor: backgroundColor ?? this.backgroundColor, - channelPreviewTheme: channelPreviewTheme?.copyWith( - title: - channelPreviewTheme.title ?? this.channelPreviewTheme.title, - subtitle: channelPreviewTheme.subtitle ?? - this.channelPreviewTheme.subtitle, - lastMessageAt: channelPreviewTheme.lastMessageAt ?? - this.channelPreviewTheme.lastMessageAt, - avatarTheme: channelPreviewTheme.avatarTheme ?? - this.channelPreviewTheme.avatarTheme, - ) ?? - this.channelPreviewTheme, + channelPreviewTheme: this.channelPreviewTheme?.copyWith( + title: channelPreviewTheme.title, + subtitle: channelPreviewTheme.subtitle, + lastMessageAt: channelPreviewTheme.lastMessageAt, + avatarTheme: channelPreviewTheme.avatarTheme, + ), channelTheme: channelTheme?.copyWith( channelHeaderTheme: channelTheme.channelHeaderTheme ?? this.channelTheme.channelHeaderTheme, @@ -218,7 +228,9 @@ class StreamChatThemeData { static StreamChatThemeData getDefaultTheme(ThemeData theme) { final accentColor = Color(0xff006cff); final isDark = theme.brightness == Brightness.dark; + final textTheme = TextTheme(); return StreamChatThemeData( + textTheme: textTheme, secondaryColor: Color(0xffEAEAEA), accentColor: accentColor, primaryColor: isDark ? Colors.black : Colors.white, @@ -242,19 +254,12 @@ class StreamChatThemeData { width: 40, ), ), - title: TextStyle( - fontSize: 14, - color: isDark ? Colors.white : Colors.black, - fontWeight: FontWeight.bold), - subtitle: TextStyle( - fontSize: 12.5, - color: (isDark ? Colors.white : Colors.black).withOpacity(0.5), + title: textTheme.bodyBold, + subtitle: textTheme.footnote.copyWith( + color: Color(0xff7A7A7A), ), - lastMessageAt: TextStyle( - fontSize: 11, - color: isDark - ? Colors.white.withOpacity(.5) - : Colors.black.withOpacity(.5), + lastMessageAt: textTheme.footnote.copyWith( + color: Colors.black.withOpacity(.5), ), ), channelTheme: ChannelTheme( @@ -375,6 +380,73 @@ class StreamChatThemeData { } } +class TextTheme { + final TextStyle title; + final TextStyle headlineBold; + final TextStyle headline; + final TextStyle bodyBold; + final TextStyle body; + final TextStyle footnoteBold; + final TextStyle footnote; + final TextStyle captionBold; + + TextTheme({ + this.title = const TextStyle( + fontSize: 22, + fontWeight: FontWeight.bold, + ), + this.headlineBold = const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + this.headline = const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + ), + this.bodyBold = const TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), + this.body = const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + ), + this.footnoteBold = const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + ), + this.footnote = const TextStyle( + fontSize: 12, + ), + this.captionBold = const TextStyle( + fontSize: 10, + fontWeight: FontWeight.bold, + ), + }); + + TextTheme copyWith({ + TextStyle body, + TextStyle title, + TextStyle headlineBold, + TextStyle headline, + TextStyle bodyBold, + TextStyle footnoteBold, + TextStyle footnote, + TextStyle captionBold, + }) { + return TextTheme( + body: body ?? this.body, + title: title ?? this.title, + headlineBold: headlineBold ?? this.headlineBold, + headline: headline ?? this.headline, + bodyBold: bodyBold ?? this.bodyBold, + footnoteBold: footnoteBold ?? this.footnoteBold, + footnote: footnote ?? this.footnote, + captionBold: captionBold ?? this.captionBold, + ); + } +} + /// Channel theme data class ChannelTheme { /// Theme of the [ChannelHeader] widget diff --git a/lib/src/user_item.dart b/lib/src/user_item.dart index f12e3e61..5a394865 100644 --- a/lib/src/user_item.dart +++ b/lib/src/user_item.dart @@ -83,13 +83,19 @@ class UserItem extends StatelessWidget { : null, title: Text( user.name, - style: TextStyle(fontWeight: FontWeight.bold), + style: StreamChatTheme.of(context).textTheme.bodyBold, ), subtitle: showLastOnline ? _buildLastActive(context) : null, ); } Widget _buildLastActive(context) { - return Text('Last online ${Jiffy(user.lastActive).fromNow()}'); + return Text( + 'Last online ${Jiffy(user.lastActive).fromNow()}', + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith(color: Colors.black.withOpacity(.5)), + ); } } diff --git a/lib/src/user_list_view.dart b/lib/src/user_list_view.dart index b57e2d55..e05bd49f 100644 --- a/lib/src/user_list_view.dart +++ b/lib/src/user_list_view.dart @@ -361,7 +361,7 @@ class _UserListViewState extends State header, style: TextStyle( fontWeight: FontWeight.bold, - fontSize: 12, + fontSize: 14.5, color: Colors.black.withOpacity(0.3)), ), ), From 4aa2a8946a8906dc5455b8992ea84b36af512e75 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Tue, 22 Dec 2020 17:45:08 +0530 Subject: [PATCH 02/31] feat: Added gridview for channel list view and changed implementation for image sharing --- lib/src/channel_image.dart | 6 ++ lib/src/channel_list_view.dart | 91 +++++++++++++++++---- lib/src/group_image.dart | 41 ++++++++-- lib/src/image_footer.dart | 143 ++++++++++++++++----------------- lib/src/user_avatar.dart | 3 + 5 files changed, 192 insertions(+), 92 deletions(-) diff --git a/lib/src/channel_image.dart b/lib/src/channel_image.dart index c3d76202..d79b2efa 100644 --- a/lib/src/channel_image.dart +++ b/lib/src/channel_image.dart @@ -52,6 +52,7 @@ class ChannelImage extends StatelessWidget { this.onTap, this.showOnlineStatus = true, this.borderRadius, + this.selected = false, }) : super(key: key); final BorderRadius borderRadius; @@ -67,6 +68,8 @@ class ChannelImage extends StatelessWidget { final bool showOnlineStatus; + final bool selected; + @override Widget build(BuildContext context) { final streamChat = StreamChat.of(context); @@ -99,6 +102,7 @@ class ChannelImage extends StatelessWidget { onTap(); } : null, + selected: selected, ); }); } else { @@ -111,12 +115,14 @@ class ChannelImage extends StatelessWidget { .toList(); return GroupImage( images: images, + borderRadius: borderRadius, constraints: constraints ?? StreamChatTheme.of(context) .channelPreviewTheme .avatarTheme .constraints, onTap: onTap, + selected: selected, ); } diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index 5dbc9f90..d5278f5e 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -74,6 +74,8 @@ class ChannelListView extends StatefulWidget { this.onStartChatPressed, this.swipeToAction = false, this.pullToRefresh = true, + this.crossAxisCount = 1, + this.selectedChannels = const [], }) : super(key: key); /// The builder that will be used in case of error @@ -134,6 +136,11 @@ class ChannelListView extends StatefulWidget { /// Callback used in the default empty list widget final VoidCallback onStartChatPressed; + /// The number of children in the cross axis. + final int crossAxisCount; + + final List selectedChannels; + @override _ChannelListViewState createState() => _ChannelListViewState(); } @@ -259,22 +266,35 @@ class _ChannelListViewState extends State } if (channels.isNotEmpty) { - child = ListView.custom( - physics: AlwaysScrollableScrollPhysics(), - controller: _scrollController, - childrenDelegate: SliverChildBuilderDelegate( - (context, i) { - return _itemBuilder(context, i, channels); + if (widget.crossAxisCount > 1) { + child = GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: widget.crossAxisCount), + itemCount: channels.length, + physics: AlwaysScrollableScrollPhysics(), + controller: _scrollController, + itemBuilder: (context, index) { + return _gridItemBuilder(context, index, channels); }, - childCount: (channels.length * 2) + 1, - findChildIndexCallback: (key) { - final ValueKey valueKey = key; - final index = channels.indexWhere( - (channel) => 'CHANNEL-${channel.id}' == valueKey.value); - return index != -1 ? (index * 2) : null; - }, - ), - ); + ); + } else { + child = ListView.custom( + physics: AlwaysScrollableScrollPhysics(), + controller: _scrollController, + childrenDelegate: SliverChildBuilderDelegate( + (context, i) { + return _itemBuilder(context, i, channels); + }, + childCount: (channels.length * 2) + 1, + findChildIndexCallback: (key) { + final ValueKey valueKey = key; + final index = channels.indexWhere( + (channel) => 'CHANNEL-${channel.id}' == valueKey.value); + return index != -1 ? (index * 2) : null; + }, + ), + ); + } } } @@ -581,6 +601,47 @@ class _ChannelListViewState extends State } } + Widget _gridItemBuilder(BuildContext context, int i, List channels) { + var channel = channels[i]; + + var selected = widget.selectedChannels.contains(channel); + + return Container( + key: ValueKey('CHANNEL-${channel.id}'), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ChannelImage( + channel: channel, + borderRadius: BorderRadius.circular(32), + selected: selected, + constraints: BoxConstraints.tightFor( + width: 64, + height: 64, + ), + onTap: () { + widget.onChannelTap(channel, null); + }, + ), + SizedBox(height: 7), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: StreamChannel( + child: ChannelName( + textStyle: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + ), + ), + channel: channel, + ), + ), + ], + ), + ); + } + Widget _buildQueryProgressIndicator( context, ChannelsBlocState channelsProvider, diff --git a/lib/src/group_image.dart b/lib/src/group_image.dart index 96e25f74..5f54377d 100644 --- a/lib/src/group_image.dart +++ b/lib/src/group_image.dart @@ -9,21 +9,33 @@ class GroupImage extends StatelessWidget { @required this.images, this.constraints, this.onTap, + this.borderRadius, + this.selected = false, + this.selectionColor = const Color(0xFF006CFF), + this.selectionThickness = 4, }) : super(key: key); final List images; final BoxConstraints constraints; final VoidCallback onTap; + final bool selected; + final BorderRadius borderRadius; + final Color selectionColor; + final double selectionThickness; @override Widget build(BuildContext context) { - return GestureDetector( + var avatar; + final streamChatTheme = StreamChatTheme.of(context); + + avatar = GestureDetector( onTap: onTap, child: ClipRRect( - borderRadius: StreamChatTheme.of(context) - .ownMessageTheme - .avatarTheme - .borderRadius, + borderRadius: borderRadius ?? + StreamChatTheme.of(context) + .ownMessageTheme + .avatarTheme + .borderRadius, child: Container( constraints: constraints ?? StreamChatTheme.of(context) @@ -91,5 +103,24 @@ class GroupImage extends StatelessWidget { ), ), ); + + if (selected) { + avatar = ClipRRect( + borderRadius: (borderRadius ?? + streamChatTheme.ownMessageTheme.avatarTheme.borderRadius) + + BorderRadius.circular(selectionThickness), + child: Container( + color: selectionColor, + height: 64.0, + width: 64.0, + child: Padding( + padding: EdgeInsets.all(selectionThickness), + child: avatar, + ), + ), + ); + } + + return avatar; } } diff --git a/lib/src/image_footer.dart b/lib/src/image_footer.dart index 3c37a66a..79c1f501 100644 --- a/lib/src/image_footer.dart +++ b/lib/src/image_footer.dart @@ -68,7 +68,7 @@ class _ImageFooterState extends State { String _userNameQuery; bool _isSearchActive = false; - Set _selectedUsers = {}; + List _selectedChannels = []; bool _loading = false; Timer _debounce; @@ -278,78 +278,86 @@ class _ImageFooterState extends State { ), clipBehavior: Clip.antiAlias, child: Scaffold( + resizeToAvoidBottomInset: false, body: UsersBloc( child: Column( children: [ _buildTextInputSection(modalSetState), + if (_userSearchMode) + SizedBox( + height: 22.0, + ), Expanded( - child: UserListView( - selectedUsers: _selectedUsers, - onUserTap: (user, _) { - _searchController.clear(); - if (!_selectedUsers.contains(user)) { - modalSetState(() { - _selectedUsers.add(user); - }); - } else { - modalSetState(() { - _selectedUsers.remove(user); - }); - } - }, - crossAxisCount: 4, - pagination: PaginationParams( - limit: 25, - ), - filter: { - if (_searchController.text.isNotEmpty) - 'name': { - r'$autocomplete': _userNameQuery, - }, - 'id': { - r'$ne': StreamChat.of(context).user.id, + child: ChannelsBloc( + child: ChannelListView( + selectedChannels: _selectedChannels, + onChannelTap: (user, _) { + _searchController.clear(); + if (!_selectedChannels.contains(user)) { + modalSetState(() { + _selectedChannels.add(user); + }); + } else { + modalSetState(() { + _selectedChannels.remove(user); + }); + } }, - }, - sort: [ - SortOption( - 'name', - direction: 1, + crossAxisCount: 4, + pagination: PaginationParams( + limit: 25, ), - ], - emptyBuilder: (_) { - return LayoutBuilder( - builder: (context, viewportConstraints) { - return SingleChildScrollView( - physics: AlwaysScrollableScrollPhysics(), - child: ConstrainedBox( - constraints: BoxConstraints( - minHeight: viewportConstraints.maxHeight, - ), - child: Center( - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(24), - child: StreamSvgIcon.search( - size: 96, - color: Colors.grey, + filter: { + if (_searchController.text.isNotEmpty) + 'name': { + r'$autocomplete': _userNameQuery, + }, + 'id': { + r'$ne': StreamChat.of(context).user.id, + }, + }, + sort: [ + SortOption( + 'name', + direction: 1, + ), + ], + emptyBuilder: (_) { + return LayoutBuilder( + builder: (context, viewportConstraints) { + return SingleChildScrollView( + physics: AlwaysScrollableScrollPhysics(), + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: + viewportConstraints.maxHeight, + ), + child: Center( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(24), + child: StreamSvgIcon.search( + size: 96, + color: Colors.grey, + ), ), - ), - Text( - 'No user matches these keywords...'), - ], + Text( + 'No user matches these keywords...'), + ], + ), ), ), - ), - ); - }, - ); - }, + ); + }, + ); + }, + ), ), ), - if (_selectedUsers.isNotEmpty) + if (_selectedChannels.isNotEmpty) _buildShareTextInputSection(modalSetState), - if (!_userSearchMode && _selectedUsers.isEmpty) + if (!_userSearchMode && _selectedChannels.isEmpty) Align( alignment: Alignment.bottomCenter, child: Container( @@ -614,25 +622,16 @@ class _ImageFooterState extends State { final client = StreamChat.of(context).client; - for (var user in _selectedUsers) { - var c = client.channel('messaging', extraData: { - 'members': [ - user.id, - StreamChat.of(context).user.id, - ], - }); - - await c.watch(); - + for (var channel in _selectedChannels) { final message = Message( text: text, attachments: [attachments[widget.currentPage]], ); - await c.sendMessage(message); + await channel.sendMessage(message); } - _selectedUsers.clear(); + _selectedChannels.clear(); Navigator.pop(context); } diff --git a/lib/src/user_avatar.dart b/lib/src/user_avatar.dart index 756252cc..e698d773 100644 --- a/lib/src/user_avatar.dart +++ b/lib/src/user_avatar.dart @@ -61,12 +61,15 @@ class UserAvatar extends StatelessWidget { : streamChatTheme.defaultUserImage(context, user), ), ); + if (selected) { avatar = ClipRRect( borderRadius: (borderRadius ?? streamChatTheme.ownMessageTheme.avatarTheme.borderRadius) + BorderRadius.circular(selectionThickness), child: Container( + constraints: constraints ?? + streamChatTheme.ownMessageTheme.avatarTheme.constraints, color: selectionColor, child: Padding( padding: EdgeInsets.all(selectionThickness), From d0a9ee7fae30e27ec2e134b35e94563aaad3d485 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 23 Dec 2020 16:53:04 +0530 Subject: [PATCH 03/31] fix: Corrected shimmer --- lib/src/channel_list_view.dart | 125 +++++++++++++++++++++------------ 1 file changed, 80 insertions(+), 45 deletions(-) diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index d5278f5e..66ec09f7 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -312,11 +312,13 @@ class _ChannelListViewState extends State children: List.generate( 25, (i) { - if (i % 2 != 0) { - if (widget.separatorBuilder != null) { - return widget.separatorBuilder(context, i); + if (widget.crossAxisCount == 1) { + if (i % 2 != 0) { + if (widget.separatorBuilder != null) { + return widget.separatorBuilder(context, i); + } + return _separatorBuilder(context, i); } - return _separatorBuilder(context, i); } return _buildLoadingItem(); }, @@ -325,63 +327,96 @@ class _ChannelListViewState extends State } Shimmer _buildLoadingItem() { - return Shimmer.fromColors( - baseColor: Color(0xffE5E5E5), - highlightColor: Color(0xffffffff), - child: ListTile( - leading: Container( - decoration: BoxDecoration( - color: Colors.white, - shape: BoxShape.circle, - ), - constraints: BoxConstraints.tightFor( - height: 40, - width: 40, - ), + if (widget.crossAxisCount > 1) { + return Shimmer.fromColors( + baseColor: Color(0xffE5E5E5), + highlightColor: Color(0xffffffff), + child: Column( + children: [ + SizedBox( + height: 4.0, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + for (int i = 0; i < widget.crossAxisCount; i++) + Container( + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + ), + constraints: BoxConstraints.tightFor( + height: 70, + width: 70, + ), + ), + ], + ), + SizedBox( + height: 16.0, + ), + ], ), - title: Align( - alignment: Alignment.centerLeft, - child: Container( + ); + } else { + return Shimmer.fromColors( + baseColor: Color(0xffE5E5E5), + highlightColor: Color(0xffffffff), + child: ListTile( + leading: Container( decoration: BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.circular(11), + shape: BoxShape.circle, ), constraints: BoxConstraints.tightFor( - height: 16, - width: 82, + height: 40, + width: 40, ), ), - ), - subtitle: Row( - children: [ - Align( - alignment: Alignment.centerLeft, - child: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(11), - ), - constraints: BoxConstraints.tightFor( - height: 16, - width: 238, - ), - ), - ), - Container( - margin: const EdgeInsets.only(left: 16), + title: Align( + alignment: Alignment.centerLeft, + child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(11), ), constraints: BoxConstraints.tightFor( height: 16, - width: 42, + width: 82, ), ), - ], + ), + subtitle: Row( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(11), + ), + constraints: BoxConstraints.tightFor( + height: 16, + width: 238, + ), + ), + ), + Container( + margin: const EdgeInsets.only(left: 16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(11), + ), + constraints: BoxConstraints.tightFor( + height: 16, + width: 42, + ), + ), + ], + ), ), - ), - ); + ); + } } Widget _buildErrorWidget( From 25342266a06dc1eeaa404992eb732dd5705c4ed4 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 25 Dec 2020 23:36:16 +0530 Subject: [PATCH 04/31] fix: Corrected keyboard --- lib/src/image_footer.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/src/image_footer.dart b/lib/src/image_footer.dart index 79c1f501..b1496de3 100644 --- a/lib/src/image_footer.dart +++ b/lib/src/image_footer.dart @@ -64,6 +64,7 @@ class _ImageFooterState extends State { bool _userSearchMode = false; TextEditingController _searchController; TextEditingController _messageController = TextEditingController(); + FocusNode _messageFocusNode = FocusNode(); String _userNameQuery; bool _isSearchActive = false; @@ -91,6 +92,7 @@ class _ImageFooterState extends State { void initState() { super.initState(); _searchController = TextEditingController()..addListener(_userNameListener); + _messageFocusNode.addListener(() {setState(() {});}); } @override @@ -258,7 +260,7 @@ class _ImageFooterState extends State { ); } - Widget _buildShareModal(context) { + void _buildShareModal(context) { showDialog( context: context, builder: (context) { @@ -266,7 +268,7 @@ class _ImageFooterState extends State { modalSetStateCallback = modalSetState; return Padding( padding: EdgeInsets.only( - top: _userSearchMode + top: _userSearchMode || _messageFocusNode.hasFocus ? 16.0 : MediaQuery.of(context).size.height / 2, left: 8.0, @@ -278,7 +280,6 @@ class _ImageFooterState extends State { ), clipBehavior: Clip.antiAlias, child: Scaffold( - resizeToAvoidBottomInset: false, body: UsersBloc( child: Column( children: [ @@ -552,6 +553,7 @@ class _ImageFooterState extends State { padding: const EdgeInsets.only(left: 8.0), child: TextField( controller: _messageController, + focusNode: _messageFocusNode, onChanged: (val) { modalSetState(() {}); }, From 0f36fdcf4f89a821cc0964edbdf8418f8cefb455 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 25 Dec 2020 23:36:35 +0530 Subject: [PATCH 05/31] fmt --- lib/src/image_footer.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/src/image_footer.dart b/lib/src/image_footer.dart index b1496de3..c071bb30 100644 --- a/lib/src/image_footer.dart +++ b/lib/src/image_footer.dart @@ -92,7 +92,9 @@ class _ImageFooterState extends State { void initState() { super.initState(); _searchController = TextEditingController()..addListener(_userNameListener); - _messageFocusNode.addListener(() {setState(() {});}); + _messageFocusNode.addListener(() { + setState(() {}); + }); } @override From b58d00a5f0a6c8107e4eda928df8445aec75f36c Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 28 Dec 2020 15:29:29 +0530 Subject: [PATCH 06/31] feat: Added text theme instead of hardcoded styles --- lib/src/date_divider.dart | 10 +++++----- lib/src/file_attachment.dart | 13 +++++-------- lib/src/giphy_attachment.dart | 17 ++++++++++------- lib/src/image_actions_modal.dart | 9 ++++----- lib/src/image_footer.dart | 19 ++++--------------- lib/src/image_header.dart | 6 +----- lib/src/message_input.dart | 17 ++++++++++------- lib/src/message_widget.dart | 8 ++++---- lib/src/url_attachment.dart | 26 ++++++++++++++------------ lib/src/utils.dart | 2 +- 10 files changed, 58 insertions(+), 69 deletions(-) diff --git a/lib/src/date_divider.dart b/lib/src/date_divider.dart index 8fbe5f77..3b8c36c1 100644 --- a/lib/src/date_divider.dart +++ b/lib/src/date_divider.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:jiffy/jiffy.dart'; +import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; /// It shows a date divider depending on the date difference class DateDivider extends StatelessWidget { @@ -49,11 +50,10 @@ class DateDivider extends StatelessWidget { ), child: Text( dayInfo, - style: TextStyle( - fontSize: 12, - color: Colors.white, - fontWeight: FontWeight.bold, - ), + style: StreamChatTheme.of(context).textTheme.footnoteBold.copyWith( + color: Colors.white, + fontWeight: FontWeight.bold, + ), ), ), ); diff --git a/lib/src/file_attachment.dart b/lib/src/file_attachment.dart index 4bba7779..c5e6c92f 100644 --- a/lib/src/file_attachment.dart +++ b/lib/src/file_attachment.dart @@ -88,10 +88,7 @@ class _FileAttachmentState extends State { children: [ Text( widget.attachment?.title ?? 'File', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14.0, - ), + style: StreamChatTheme.of(context).textTheme.bodyBold, maxLines: 1, overflow: TextOverflow.ellipsis, ), @@ -100,10 +97,10 @@ class _FileAttachmentState extends State { ), Text( '${_getSizeText(widget.attachment.extraData['file_size'])}', - style: TextStyle( - color: Colors.black.withOpacity(0.5), - fontSize: 14.0, - ), + style: StreamChatTheme.of(context) + .textTheme + .body + .copyWith(color: Colors.black.withOpacity(0.5)), ), ], ), diff --git a/lib/src/giphy_attachment.dart b/lib/src/giphy_attachment.dart index 3e29b2f1..74dfeeb4 100644 --- a/lib/src/giphy_attachment.dart +++ b/lib/src/giphy_attachment.dart @@ -220,9 +220,12 @@ class GiphyAttachment extends StatelessWidget { }, child: Text( 'Cancel', - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.black.withOpacity(0.5)), + style: StreamChatTheme.of(context) + .textTheme + .bodyBold + .copyWith( + color: Colors.black.withOpacity(0.5), + ), ), ), ), @@ -271,10 +274,10 @@ class GiphyAttachment extends StatelessWidget { ), Text( 'Only visible to you', - style: TextStyle( - color: Colors.black.withOpacity(0.5), - fontSize: 12.0, - ), + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith(color: Colors.black.withOpacity(0.5)), ), ], ), diff --git a/lib/src/image_actions_modal.dart b/lib/src/image_actions_modal.dart index fc81635c..2b2aa05e 100644 --- a/lib/src/image_actions_modal.dart +++ b/lib/src/image_actions_modal.dart @@ -66,11 +66,10 @@ class ImageActionsModal extends StatelessWidget { padding: const EdgeInsets.only(top: 8.0), child: Text( userName, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.w700, - color: Colors.white, - ), + style: StreamChatTheme.of(context) + .textTheme + .headlineBold + .copyWith(color: Colors.white), ), ), Text( diff --git a/lib/src/image_footer.dart b/lib/src/image_footer.dart index 3c37a66a..f16be87d 100644 --- a/lib/src/image_footer.dart +++ b/lib/src/image_footer.dart @@ -130,11 +130,7 @@ class _ImageFooterState extends State { children: [ Text( '${widget.currentPage + 1} of ${widget.totalPages}', - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.w700, - color: Colors.black, - ), + style: StreamChatTheme.of(context).textTheme.headlineBold, ), ], ), @@ -182,11 +178,8 @@ class _ImageFooterState extends State { padding: const EdgeInsets.all(16.0), child: Text( 'Photos', - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.w700, - color: Colors.black, - ), + style: + StreamChatTheme.of(context).textTheme.headlineBold, ), ), ), @@ -490,11 +483,7 @@ class _ImageFooterState extends State { padding: const EdgeInsets.all(16.0), child: Text( 'Select a Chat to Share', - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.w700, - color: Colors.black, - ), + style: StreamChatTheme.of(context).textTheme.headlineBold, ), ), Padding( diff --git a/lib/src/image_header.dart b/lib/src/image_header.dart index 62c3f8ec..aae73057 100644 --- a/lib/src/image_header.dart +++ b/lib/src/image_header.dart @@ -81,11 +81,7 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget { children: [ Text( userName, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.w700, - color: Colors.black, - ), + style: StreamChatTheme.of(context).textTheme.headlineBold, ), Text( sentAt, diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 8436d526..e0f290fc 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -423,8 +423,10 @@ class MessageInputState extends State { ), Text( _chosenCommand?.name?.toUpperCase() ?? "", - style: TextStyle( - color: Colors.white, fontSize: 12.0), + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith(color: Colors.white), ), ], ), @@ -899,11 +901,12 @@ class MessageInputState extends State { Center( child: Text( 'Allow access to your gallery', - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, - color: StreamChatTheme.of(context).accentColor, - ), + style: StreamChatTheme.of(context) + .textTheme + .bodyBold + .copyWith( + color: StreamChatTheme.of(context).accentColor, + ), ), ), ], diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 9d81d679..3eb52e45 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -420,10 +420,10 @@ class _MessageWidgetState extends State { SizedBox(width: 8.0), Text( 'Only visible to you', - style: TextStyle( - color: Colors.black.withOpacity(0.5), - fontSize: 12.0, - ), + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith(color: Colors.black.withOpacity(0.5)), ), ], ), diff --git a/lib/src/url_attachment.dart b/lib/src/url_attachment.dart index ad314455..5ecaa1cc 100644 --- a/lib/src/url_attachment.dart +++ b/lib/src/url_attachment.dart @@ -51,10 +51,12 @@ class UrlAttachment extends StatelessWidget { ), child: Text( hostDisplayName, - style: TextStyle( - fontWeight: FontWeight.w700, - color: Color(0xFF006CFF), - ), + style: StreamChatTheme.of(context) + .textTheme + .bodyBold + .copyWith( + color: Color(0xFF006CFF), + ), ), ), decoration: BoxDecoration( @@ -81,18 +83,18 @@ class UrlAttachment extends StatelessWidget { urlAttachment.title.trim(), maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle( - fontWeight: FontWeight.w700, - fontSize: 12.0, - ), + style: StreamChatTheme.of(context) + .textTheme + .body + .copyWith(fontWeight: FontWeight.w700), ), if (urlAttachment.text != null) Text( urlAttachment.text, - style: TextStyle( - fontWeight: FontWeight.w400, - fontSize: 12.0, - ), + style: StreamChatTheme.of(context) + .textTheme + .body + .copyWith(fontWeight: FontWeight.w400), ), ], ), diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 681a28aa..60eca678 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -45,7 +45,7 @@ Future showConfirmationDialog( ), Text( title, - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0), + style: StreamChatTheme.of(context).textTheme.headlineBold, ), SizedBox( height: 7.0, From 08d2b32eff29f4d22c10486c4471a40dc45d2db7 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 28 Dec 2020 19:24:42 +0530 Subject: [PATCH 07/31] feat: Added color themes --- example/lib/choose_user_page.dart | 7 ++- lib/src/channel_bottom_sheet.dart | 2 +- lib/src/channel_list_view.dart | 10 ++-- lib/src/message_input.dart | 9 ++-- lib/src/message_list_view.dart | 4 +- lib/src/message_widget.dart | 8 +-- lib/src/stream_chat_theme.dart | 89 +++++++++++++++++++++++++++++++ lib/src/url_attachment.dart | 2 +- 8 files changed, 116 insertions(+), 15 deletions(-) diff --git a/example/lib/choose_user_page.dart b/example/lib/choose_user_page.dart index 8d88cb1b..205f2581 100644 --- a/example/lib/choose_user_page.dart +++ b/example/lib/choose_user_page.dart @@ -171,7 +171,9 @@ class ChooseUserPage extends StatelessWidget { .textTheme .footnote .copyWith( - color: Color(0xff7A7A7A), + color: StreamChatTheme.of(context) + .colorTheme + .grey, ), ), trailing: SvgPicture.asset( @@ -202,7 +204,8 @@ class ChooseUserPage extends StatelessWidget { .textTheme .footnote .copyWith( - color: Color(0xff7A7A7A), + color: + StreamChatTheme.of(context).colorTheme.grey, ), ), trailing: SvgPicture.asset( diff --git a/lib/src/channel_bottom_sheet.dart b/lib/src/channel_bottom_sheet.dart index 2d16bf6d..8e65c24d 100644 --- a/lib/src/channel_bottom_sheet.dart +++ b/lib/src/channel_bottom_sheet.dart @@ -73,7 +73,7 @@ class ChannelBottomSheet extends StatelessWidget { ListTile( leading: StreamSvgIcon.userRemove( size: 24, - color: Color(0xff7A7A7A), + color: StreamChatTheme.of(context).colorTheme.grey, ), title: Text( 'Leave Group', diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index b18fb39c..c04f80ed 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -203,7 +203,9 @@ class _ChannelListViewState extends State padding: const EdgeInsets.all(8.0), child: StreamSvgIcon.message( size: 136, - color: Color(0xffDBDBDB), + color: StreamChatTheme.of(context) + .colorTheme + .greyGainsboro, ), ), Padding( @@ -227,7 +229,9 @@ class _ChannelListViewState extends State .textTheme .body .copyWith( - color: Color(0xff7A7A7A), + color: StreamChatTheme.of(context) + .colorTheme + .grey, ), ), ), @@ -311,7 +315,7 @@ class _ChannelListViewState extends State Shimmer _buildLoadingItem() { return Shimmer.fromColors( baseColor: Color(0xffE5E5E5), - highlightColor: Color(0xffffffff), + highlightColor: StreamChatTheme.of(context).colorTheme.white, child: ListTile( leading: Container( decoration: BoxDecoration( diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index e0f290fc..79189d1d 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -724,7 +724,7 @@ class MessageInputState extends State { duration: _animateContainer ? Duration(milliseconds: 300) : Duration.zero, height: _openFilePickerSection ? _filePickerSize : 0, child: Material( - color: Color(0xFFF2F2F2), + color: StreamChatTheme.of(context).colorTheme.whiteSmoke, child: Column( children: [ Row( @@ -806,7 +806,8 @@ class MessageInputState extends State { width: 40.0, height: 4.0, decoration: BoxDecoration( - color: Color(0xFFF2F2F2), + color: + StreamChatTheme.of(context).colorTheme.whiteSmoke, borderRadius: BorderRadius.circular(4.0), ), ), @@ -854,7 +855,7 @@ class MessageInputState extends State { }, child: Container( constraints: BoxConstraints.expand(), - color: Color(0xfff2f2f2), + color: StreamChatTheme.of(context).colorTheme.whiteSmoke, child: Text( 'Add more files', style: TextStyle( @@ -887,7 +888,7 @@ class MessageInputState extends State { PhotoManager.openSetting(); }, child: Container( - color: Color(0xFFF2F2F2), + color: StreamChatTheme.of(context).colorTheme.whiteSmoke, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index d0743027..7452fd6d 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -342,7 +342,9 @@ class _MessageListViewState extends State { end: Alignment.bottomCenter, colors: [ Color(0XFFF7F7F7), - Color(0XFFFCFCFC), + StreamChatTheme.of(context) + .colorTheme + .whiteSmoke, ], ), ), diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 3eb52e45..f3e5b108 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -502,6 +502,7 @@ class _MessageWidgetState extends State { child: CustomPaint( size: const Size(16, 32), painter: _ThreadReplyPainter( + context: context, color: widget.messageTheme.replyThreadColor, ), ), @@ -916,7 +917,7 @@ class _MessageWidgetState extends State { if (widget.message.attachments ?.any((element) => element.ogScrapeUrl != null) == true) { - return Color(0xFFE9F2FF); + return StreamChatTheme.of(context).colorTheme.blueAlice; } if (isOnlyEmoji) { @@ -997,13 +998,14 @@ class _MessageWidgetState extends State { class _ThreadReplyPainter extends CustomPainter { final Color color; + final BuildContext context; - const _ThreadReplyPainter({@required this.color}); + const _ThreadReplyPainter({this.context, @required this.color}); @override void paint(Canvas canvas, Size size) { final paint = Paint() - ..color = color ?? Color(0XFFDBDBDB) + ..color = color ?? StreamChatTheme.of(context).colorTheme.greyGainsboro ..style = PaintingStyle.stroke ..strokeWidth = 1 ..strokeCap = StrokeCap.round; diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index 4739f122..d4237270 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -45,6 +45,9 @@ class StreamChatThemeData { /// The text themes used in the widgets final TextTheme textTheme; + /// The text themes used in the widgets + final ColorTheme colorTheme; + /// Primary color of the chat widgets final Color primaryColor; @@ -84,6 +87,7 @@ class StreamChatThemeData { /// Create a theme from scratch StreamChatThemeData({ this.textTheme, + this.colorTheme, this.primaryColor, this.secondaryColor, this.accentColor, @@ -136,6 +140,7 @@ class StreamChatThemeData { /// Creates a copy of [StreamChatThemeData] with specified attributes overridden. StreamChatThemeData copyWith({ TextTheme textTheme, + ColorTheme colorTheme, Color primaryColor, Color secondaryColor, Color accentColor, @@ -160,6 +165,16 @@ class StreamChatThemeData { headline: textTheme?.headline, headlineBold: textTheme?.headlineBold, ), + colorTheme: this.colorTheme?.copyWith( + black: colorTheme?.black, + grey: colorTheme?.grey, + greyGainsboro: colorTheme?.greyGainsboro, + greyWhisper: colorTheme?.greyWhisper, + whiteSmoke: colorTheme?.whiteSmoke, + whiteSnow: colorTheme?.whiteSnow, + white: colorTheme?.white, + blueAlice: colorTheme?.blueAlice, + ), primaryColor: primaryColor ?? this.primaryColor, secondaryColor: secondaryColor ?? this.secondaryColor, primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme, @@ -233,8 +248,10 @@ class StreamChatThemeData { final accentColor = Color(0xff006cff); final isDark = theme.brightness == Brightness.dark; final textTheme = TextTheme(); + final colorTheme = isDark ? ColorTheme.dark() : ColorTheme.light(); return StreamChatThemeData( textTheme: textTheme, + colorTheme: colorTheme, secondaryColor: Color(0xffEAEAEA), accentColor: accentColor, primaryColor: isDark ? Colors.black : Colors.white, @@ -454,6 +471,78 @@ class TextTheme { } } +enum ColorThemeType { + light, + dark, +} + +class ColorTheme { + final Color black; + final Color grey; + final Color greyGainsboro; + final Color greyWhisper; + final Color whiteSmoke; + final Color whiteSnow; + final Color white; + final Color blueAlice; + + ColorTheme.light({ + this.black = const Color(0xff000000), + this.grey = const Color(0xff7a7a7a), + this.greyGainsboro = const Color(0xffdbdbdb), + this.greyWhisper = const Color(0xffecebeb), + this.whiteSmoke = const Color(0xfff2f2f2), + this.whiteSnow = const Color(0xfffcfcfc), + this.white = const Color(0xffffffff), + this.blueAlice = const Color(0xffe9f2ff), + }); + + ColorTheme.dark({ + this.black = const Color(0xffffffff), + this.grey = const Color(0xff7a7a7a), + this.greyGainsboro = const Color(0xff2d2f2f), + this.greyWhisper = const Color(0xff1c1e22), + this.whiteSmoke = const Color(0xff13151b), + this.whiteSnow = const Color(0xff070A0D), + this.white = const Color(0xff101418), + this.blueAlice = const Color(0xff00193D), + }); + + ColorTheme copyWith({ + ColorThemeType type = ColorThemeType.light, + Color black, + Color grey, + Color greyGainsboro, + Color greyWhisper, + Color whiteSmoke, + Color whiteSnow, + Color white, + Color blueAlice, + }) { + return type == ColorThemeType.light + ? ColorTheme.light( + black: black ?? this.black, + grey: grey ?? this.grey, + greyGainsboro: greyGainsboro ?? this.greyGainsboro, + greyWhisper: greyWhisper ?? this.greyWhisper, + whiteSmoke: whiteSmoke ?? this.whiteSmoke, + whiteSnow: whiteSnow ?? this.whiteSnow, + white: white ?? this.white, + blueAlice: blueAlice ?? this.blueAlice, + ) + : ColorTheme.dark( + black: black ?? this.black, + grey: grey ?? this.grey, + greyGainsboro: greyGainsboro ?? this.greyGainsboro, + greyWhisper: greyWhisper ?? this.greyWhisper, + whiteSmoke: whiteSmoke ?? this.whiteSmoke, + whiteSnow: whiteSnow ?? this.whiteSnow, + white: white ?? this.white, + blueAlice: blueAlice ?? this.blueAlice, + ); + } +} + /// Channel theme data class ChannelTheme { /// Theme of the [ChannelHeader] widget diff --git a/lib/src/url_attachment.dart b/lib/src/url_attachment.dart index 5ecaa1cc..c655880d 100644 --- a/lib/src/url_attachment.dart +++ b/lib/src/url_attachment.dart @@ -63,7 +63,7 @@ class UrlAttachment extends StatelessWidget { borderRadius: BorderRadius.only( topRight: Radius.circular(16.0), ), - color: Color(0xFFE9F2FF), + color: StreamChatTheme.of(context).colorTheme.blueAlice, ), ), ), From 38d3140ab10c49327b591578a5673ba6eb5bdb6e Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Mon, 28 Dec 2020 23:30:35 +0530 Subject: [PATCH 08/31] [ChannelListView] Convert listView.custom into listView.separated Signed-off-by: Sahil Kumar --- lib/src/channel_list_view.dart | 38 ++++++++++++---------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index 66ec09f7..5efa1e29 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -278,21 +278,19 @@ class _ChannelListViewState extends State }, ); } else { - child = ListView.custom( + child = ListView.separated( physics: AlwaysScrollableScrollPhysics(), - controller: _scrollController, - childrenDelegate: SliverChildBuilderDelegate( - (context, i) { - return _itemBuilder(context, i, channels); - }, - childCount: (channels.length * 2) + 1, - findChildIndexCallback: (key) { - final ValueKey valueKey = key; - final index = channels.indexWhere( - (channel) => 'CHANNEL-${channel.id}' == valueKey.value); - return index != -1 ? (index * 2) : null; - }, - ), + itemCount: + channels.isNotEmpty ? channels.length + 1 : channels.length, + separatorBuilder: (_, index) { + if (widget.separatorBuilder != null) { + return widget.separatorBuilder(context, index); + } + return _separatorBuilder(context, index); + }, + itemBuilder: (context, index) { + return _listItemBuilder(context, index, channels); + }, ); } } @@ -483,20 +481,10 @@ class _ChannelListViewState extends State ); } - Widget _itemBuilder(context, int i, List channels) { - if (i % 2 != 0) { - if (widget.separatorBuilder != null) { - return widget.separatorBuilder(context, i); - } - return _separatorBuilder(context, i); - } - - i = i ~/ 2; - + Widget _listItemBuilder(BuildContext context, int i, List channels) { final channelsProvider = ChannelsBloc.of(context); if (i < channels.length) { final channel = channels[i]; - ChannelTapCallback onTap; if (widget.onChannelTap != null) { onTap = widget.onChannelTap; From 38e3d541bbd410b492cb4e9e4e07bc7f035f7e06 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Mon, 28 Dec 2020 23:31:02 +0530 Subject: [PATCH 09/31] [Channel Image] Fix selection state Signed-off-by: Sahil Kumar --- lib/src/channel_image.dart | 41 ++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/src/channel_image.dart b/lib/src/channel_image.dart index d79b2efa..ad3e930a 100644 --- a/lib/src/channel_image.dart +++ b/lib/src/channel_image.dart @@ -53,6 +53,8 @@ class ChannelImage extends StatelessWidget { this.showOnlineStatus = true, this.borderRadius, this.selected = false, + this.selectionColor = const Color(0xFF006CFF), + this.selectionThickness = 4, }) : super(key: key); final BorderRadius borderRadius; @@ -70,6 +72,10 @@ class ChannelImage extends StatelessWidget { final bool selected; + final Color selectionColor; + + final double selectionThickness; + @override Widget build(BuildContext context) { final streamChat = StreamChat.of(context); @@ -97,12 +103,10 @@ class ChannelImage extends StatelessWidget { .channelPreviewTheme .avatarTheme .constraints, - onTap: onTap != null - ? (_) { - onTap(); - } - : null, + onTap: onTap != null ? (_) => onTap() : null, selected: selected, + selectionColor: selectionColor, + selectionThickness: selectionThickness, ); }); } else { @@ -123,10 +127,12 @@ class ChannelImage extends StatelessWidget { .constraints, onTap: onTap, selected: selected, + selectionColor: selectionColor, + selectionThickness: selectionThickness, ); } - return ClipRRect( + Widget child = ClipRRect( borderRadius: borderRadius ?? StreamChatTheme.of(context) .channelPreviewTheme @@ -175,6 +181,29 @@ class ChannelImage extends StatelessWidget { ), ), ); + if (selected) { + child = ClipRRect( + borderRadius: (borderRadius ?? + StreamChatTheme.of(context) + .ownMessageTheme + .avatarTheme + .borderRadius) + + BorderRadius.circular(selectionThickness), + child: Container( + constraints: constraints ?? + StreamChatTheme.of(context) + .ownMessageTheme + .avatarTheme + .constraints, + color: selectionColor, + child: Padding( + padding: EdgeInsets.all(selectionThickness), + child: child, + ), + ), + ); + } + return child; }); } } From 27a83e77918279ee4d2f26c8b9c6a68842e69421 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Mon, 28 Dec 2020 23:32:57 +0530 Subject: [PATCH 10/31] Minor refactoring Signed-off-by: Sahil Kumar --- lib/src/image_footer.dart | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/lib/src/image_footer.dart b/lib/src/image_footer.dart index c071bb30..00b38a90 100644 --- a/lib/src/image_footer.dart +++ b/lib/src/image_footer.dart @@ -16,8 +16,6 @@ import 'package:stream_chat_flutter/src/stream_chat.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; -import 'stream_channel.dart'; - class ImageFooter extends StatefulWidget { /// Callback to call when pressing the back button. /// By default it calls [Navigator.pop] @@ -66,8 +64,7 @@ class _ImageFooterState extends State { TextEditingController _messageController = TextEditingController(); FocusNode _messageFocusNode = FocusNode(); - String _userNameQuery; - bool _isSearchActive = false; + String _channelNameQuery; List _selectedChannels = []; bool _loading = false; @@ -81,8 +78,7 @@ class _ImageFooterState extends State { _debounce = Timer(const Duration(milliseconds: 350), () { if (mounted && modalSetStateCallback != null) { modalSetStateCallback(() { - _userNameQuery = _searchController.text; - _isSearchActive = _userNameQuery.isNotEmpty; + _channelNameQuery = _searchController.text; }); } }); @@ -294,15 +290,15 @@ class _ImageFooterState extends State { child: ChannelsBloc( child: ChannelListView( selectedChannels: _selectedChannels, - onChannelTap: (user, _) { + onChannelTap: (channel, _) { _searchController.clear(); - if (!_selectedChannels.contains(user)) { + if (!_selectedChannels.contains(channel)) { modalSetState(() { - _selectedChannels.add(user); + _selectedChannels.add(channel); }); } else { modalSetState(() { - _selectedChannels.remove(user); + _selectedChannels.remove(channel); }); } }, @@ -313,7 +309,7 @@ class _ImageFooterState extends State { filter: { if (_searchController.text.isNotEmpty) 'name': { - r'$autocomplete': _userNameQuery, + r'$autocomplete': _channelNameQuery, }, 'id': { r'$ne': StreamChat.of(context).user.id, @@ -346,7 +342,7 @@ class _ImageFooterState extends State { ), ), Text( - 'No user matches these keywords...'), + 'No chat matches these keywords...'), ], ), ), @@ -624,8 +620,6 @@ class _ImageFooterState extends State { _messageController.clear(); - final client = StreamChat.of(context).client; - for (var channel in _selectedChannels) { final message = Message( text: text, From 7fd8a1ed57266718ea3e281426ffa009240f4d01 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Tue, 29 Dec 2020 23:10:41 +0530 Subject: [PATCH 11/31] feat: Added color theme implementations --- example/ios/Flutter/.last_build_id | 2 +- example/ios/Podfile.lock | 2 +- example/lib/advanced_options_page.dart | 36 +++++++---- example/lib/chips_input_text_field.dart | 23 +++++-- example/lib/choose_user_page.dart | 6 +- example/lib/custom_theme.dart | 5 +- example/lib/customize_channel_preview.dart | 5 +- example/lib/group_chat_details_screen.dart | 37 ++++++++--- example/lib/main.dart | 29 ++++++--- example/lib/new_chat_screen.dart | 42 +++++++++--- example/lib/new_group_chat_screen.dart | 34 +++++++--- example/lib/search_text_field.dart | 13 ++-- example/lib/stream_version.dart | 4 +- lib/src/attachment_error.dart | 4 +- lib/src/back_button.dart | 6 +- lib/src/channel_image.dart | 4 +- lib/src/channel_list_header.dart | 2 +- lib/src/channel_list_view.dart | 12 ++-- lib/src/channel_unread_indicator.dart | 2 +- lib/src/chat_info_screen.dart | 72 ++++++++++++++------- lib/src/date_divider.dart | 6 +- lib/src/deleted_message.dart | 14 ++-- lib/src/file_attachment.dart | 17 ++--- lib/src/full_screen_media.dart | 4 +- lib/src/giphy_attachment.dart | 47 ++++++++++---- lib/src/image_actions_modal.dart | 29 ++++++--- lib/src/image_footer.dart | 51 +++++++++------ lib/src/image_group.dart | 4 +- lib/src/image_header.dart | 4 +- lib/src/media_list_view.dart | 15 +++-- lib/src/message_actions_modal.dart | 5 +- lib/src/message_input.dart | 74 +++++++++++++++------- lib/src/message_list_view.dart | 10 ++- lib/src/message_reactions_modal.dart | 5 +- lib/src/message_search_list_view.dart | 20 ++++-- lib/src/message_widget.dart | 40 +++++++----- lib/src/reaction_bubble.dart | 10 ++- lib/src/stream_chat_theme.dart | 2 +- lib/src/unread_indicator.dart | 2 +- lib/src/user_avatar.dart | 2 +- lib/src/user_item.dart | 8 +-- lib/src/user_list_view.dart | 12 ++-- lib/src/utils.dart | 7 +- 43 files changed, 504 insertions(+), 224 deletions(-) diff --git a/example/ios/Flutter/.last_build_id b/example/ios/Flutter/.last_build_id index e72273c3..a2e31d3e 100644 --- a/example/ios/Flutter/.last_build_id +++ b/example/ios/Flutter/.last_build_id @@ -1 +1 @@ -13a41b8138c4868054e44b5158f3bdd6 \ No newline at end of file +209b1a40522bc1cb0ea3596a28cded5e \ No newline at end of file diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index f266b656..af57742c 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -296,4 +296,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: eb001256612a59f8f9e4d083ad8b9671e69dd184 -COCOAPODS: 1.10.0 +COCOAPODS: 1.8.3 diff --git a/example/lib/advanced_options_page.dart b/example/lib/advanced_options_page.dart index 6c922e3d..803c3e72 100644 --- a/example/lib/advanced_options_page.dart +++ b/example/lib/advanced_options_page.dart @@ -45,11 +45,11 @@ class _AdvancedOptionsPageState extends State { style: StreamChatTheme.of(context) .textTheme .headlineBold - .copyWith(color: Colors.black), + .copyWith(color: StreamChatTheme.of(context).colorTheme.black), ), leading: IconButton( icon: StreamSvgIcon.left( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), onPressed: () { Navigator.pop(context); @@ -89,7 +89,7 @@ class _AdvancedOptionsPageState extends State { }, style: TextStyle( fontSize: 14, - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), decoration: InputDecoration( errorStyle: TextStyle(fontSize: 0), @@ -98,7 +98,10 @@ class _AdvancedOptionsPageState extends State { fontWeight: FontWeight.bold, color: _apiKeyError != null ? Color(0xffff3742) - : Colors.black.withOpacity(.5), + : StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ), border: UnderlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -133,7 +136,7 @@ class _AdvancedOptionsPageState extends State { }, style: TextStyle( fontSize: 14, - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), textInputAction: TextInputAction.next, decoration: InputDecoration( @@ -143,7 +146,10 @@ class _AdvancedOptionsPageState extends State { fontSize: 14, color: _userIdError != null ? Color(0xffff3742) - : Colors.black.withOpacity(.5), + : StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ), border: UnderlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -178,7 +184,7 @@ class _AdvancedOptionsPageState extends State { }, style: TextStyle( fontSize: 14, - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), textInputAction: TextInputAction.next, decoration: InputDecoration( @@ -188,7 +194,10 @@ class _AdvancedOptionsPageState extends State { fontSize: 14, color: _userTokenError != null ? Color(0xffff3742) - : Colors.black.withOpacity(.5), + : StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ), border: UnderlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -210,7 +219,10 @@ class _AdvancedOptionsPageState extends State { labelStyle: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, - color: Colors.black.withOpacity(.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ), border: UnderlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -232,7 +244,7 @@ class _AdvancedOptionsPageState extends State { child: Text( 'Login', style: TextStyle( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, fontSize: 16, ), ), @@ -257,7 +269,9 @@ class _AdvancedOptionsPageState extends State { child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), - color: Colors.white, + color: StreamChatTheme.of(context) + .colorTheme + .white, ), height: 100, width: 100, diff --git a/example/lib/chips_input_text_field.dart b/example/lib/chips_input_text_field.dart index efa3b10e..7291ef03 100644 --- a/example/lib/chips_input_text_field.dart +++ b/example/lib/chips_input_text_field.dart @@ -66,7 +66,7 @@ class ChipInputTextFieldState extends State> { onTap: _pauseItemAddition ? resumeItemAddition : null, child: Material( elevation: 1, - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, child: Container( child: Padding( padding: const EdgeInsets.fromLTRB(16, 16, 16, 16), @@ -81,7 +81,11 @@ class ChipInputTextFieldState extends State> { style: StreamChatTheme.of(context) .textTheme .footnote - .copyWith(color: Colors.black.withOpacity(.5)), + .copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5)), ), ), SizedBox(width: 12), @@ -115,7 +119,10 @@ class ChipInputTextFieldState extends State> { .textTheme .body .copyWith( - color: Colors.black.withOpacity(.5)), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5)), ), ), ], @@ -127,11 +134,17 @@ class ChipInputTextFieldState extends State> { child: IconButton( icon: _chips.isEmpty ? StreamSvgIcon.user( - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), size: 24, ) : StreamSvgIcon.userAdd( - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), size: 24, ), onPressed: resumeItemAddition, diff --git a/example/lib/choose_user_page.dart b/example/lib/choose_user_page.dart index 205f2581..18212253 100644 --- a/example/lib/choose_user_page.dart +++ b/example/lib/choose_user_page.dart @@ -113,7 +113,9 @@ class ChooseUserPage extends StatelessWidget { child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), - color: Colors.white, + color: StreamChatTheme.of(context) + .colorTheme + .white, ), height: 100, width: 100, @@ -189,7 +191,7 @@ class ChooseUserPage extends StatelessWidget { }, leading: CircleAvatar( child: StreamSvgIcon.settings( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), backgroundColor: StreamChatTheme.of(context).secondaryColor, diff --git a/example/lib/custom_theme.dart b/example/lib/custom_theme.dart index 21db1c6c..90635993 100644 --- a/example/lib/custom_theme.dart +++ b/example/lib/custom_theme.dart @@ -50,9 +50,10 @@ class MyApp extends StatelessWidget { client: client, streamChatThemeData: StreamChatThemeData.fromTheme(theme).copyWith( ownMessageTheme: MessageTheme( - messageBackgroundColor: Colors.black, + messageBackgroundColor: + StreamChatTheme.of(context).colorTheme.black, messageText: TextStyle( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), avatarTheme: AvatarTheme( borderRadius: BorderRadius.circular(8), diff --git a/example/lib/customize_channel_preview.dart b/example/lib/customize_channel_preview.dart index 3809f780..d06cdba7 100644 --- a/example/lib/customize_channel_preview.dart +++ b/example/lib/customize_channel_preview.dart @@ -87,7 +87,10 @@ class ChannelListPage extends StatelessWidget { channel: channel, textStyle: StreamChatTheme.of(context).channelPreviewTheme.title.copyWith( - color: Colors.black.withOpacity(opacity), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(opacity), ), ), subtitle: Text(subtitle), diff --git a/example/lib/group_chat_details_screen.dart b/example/lib/group_chat_details_screen.dart index c6d4331d..0c49c523 100644 --- a/example/lib/group_chat_details_screen.dart +++ b/example/lib/group_chat_details_screen.dart @@ -62,12 +62,12 @@ class _GroupChatDetailsScreenState extends State { backgroundColor: Color.fromRGBO(252, 252, 252, 1), appBar: AppBar( elevation: 1, - backgroundColor: Colors.white, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, leading: const StreamBackButton(), title: Text( 'Name of Group Chat', style: TextStyle( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, fontSize: 16, ), ), @@ -82,7 +82,10 @@ class _GroupChatDetailsScreenState extends State { 'NAME', style: TextStyle( fontSize: 12, - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), ), ), SizedBox(width: 16), @@ -99,7 +102,11 @@ class _GroupChatDetailsScreenState extends State { contentPadding: const EdgeInsets.all(0), hintText: 'Choose a group chat name', hintStyle: TextStyle( - fontSize: 14, color: Colors.black.withOpacity(.5)), + fontSize: 14, + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5)), ), ), ), @@ -167,16 +174,28 @@ class _GroupChatDetailsScreenState extends State { separatorBuilder: (_, __) => Container( height: 1, color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(0.1) - : Colors.black.withOpacity(0.1), + ? StreamChatTheme.of(context) + .colorTheme + .white + .withOpacity(0.1) + : StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.1), ), itemBuilder: (_, index) { if (index == _selectedUsers.length) { return Container( height: 1, color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(0.1) - : Colors.black.withOpacity(0.1), + ? StreamChatTheme.of(context) + .colorTheme + .white + .withOpacity(0.1) + : StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.1), ); } final user = _selectedUsers[index]; @@ -200,7 +219,7 @@ class _GroupChatDetailsScreenState extends State { trailing: IconButton( icon: Icon( Icons.clear_rounded, - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), padding: const EdgeInsets.all(0), splashRadius: 24, diff --git a/example/lib/main.dart b/example/lib/main.dart index a79a6fb4..6f4562b6 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -55,10 +55,10 @@ class MyApp extends StatelessWidget { client: client, child: MaterialApp( debugShowCheckedModeBanner: false, - theme: ThemeData.light(), + theme: ThemeData.dark(), darkTheme: ThemeData.dark(), //TODO change to system once dark theme is implemented - themeMode: ThemeMode.light, + themeMode: ThemeMode.dark, onGenerateRoute: AppRoutes.generateRoute, initialRoute: client.state.user == null ? Routes.CHOOSE_USER : Routes.HOME, @@ -84,7 +84,9 @@ class _HomePageState extends State { overflow: Overflow.visible, children: [ StreamSvgIcon.message( - color: _isSelected(0) ? Colors.black : Colors.grey, + color: _isSelected(0) + ? StreamChatTheme.of(context).colorTheme.black + : Colors.grey, ), Positioned( top: -3, @@ -100,7 +102,9 @@ class _HomePageState extends State { overflow: Overflow.visible, children: [ StreamSvgIcon.mentions( - color: _isSelected(1) ? Colors.black : Colors.grey, + color: _isSelected(1) + ? StreamChatTheme.of(context).colorTheme.black + : Colors.grey, ), ], ), @@ -127,7 +131,7 @@ class _HomePageState extends State { unselectedLabelStyle: StreamChatTheme.of(context).textTheme.footnoteBold, type: BottomNavigationBarType.fixed, - selectedItemColor: Colors.black, + selectedItemColor: StreamChatTheme.of(context).colorTheme.black, unselectedItemColor: Colors.grey, onTap: (index) { setState(() => _currentIndex = index); @@ -179,7 +183,10 @@ class _HomePageState extends State { ), ListTile( leading: StreamSvgIcon.penWrite( - color: Colors.black.withOpacity(.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ), onTap: () { Navigator.popAndPushNamed( @@ -196,7 +203,10 @@ class _HomePageState extends State { ), ListTile( leading: StreamSvgIcon.contacts( - color: Colors.black.withOpacity(.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ), onTap: () { Navigator.popAndPushNamed( @@ -231,7 +241,10 @@ class _HomePageState extends State { ); }, leading: StreamSvgIcon.user( - color: Colors.black.withOpacity(.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ), title: Text( 'Sign out', diff --git a/example/lib/new_chat_screen.dart b/example/lib/new_chat_screen.dart index b89bdee1..0d8b9821 100644 --- a/example/lib/new_chat_screen.dart +++ b/example/lib/new_chat_screen.dart @@ -125,14 +125,14 @@ class _NewChatScreenState extends State { backgroundColor: Color.fromRGBO(252, 252, 252, 1), appBar: AppBar( elevation: 0, - backgroundColor: Colors.white, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, leading: const StreamBackButton(), title: Text( 'New Chat', style: StreamChatTheme.of(context) .textTheme .headlineBold - .copyWith(color: Colors.black), + .copyWith(color: StreamChatTheme.of(context).colorTheme.black), ), centerTitle: true, ), @@ -157,7 +157,10 @@ class _NewChatScreenState extends State { children: [ Container( decoration: BoxDecoration( - color: Colors.black.withOpacity(0.05), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.05), borderRadius: BorderRadius.circular(12), ), padding: const EdgeInsets.only(left: 24), @@ -165,7 +168,10 @@ class _NewChatScreenState extends State { padding: const EdgeInsets.fromLTRB(8, 4, 12, 4), child: Text( user.name, - style: TextStyle(color: Colors.black), + style: TextStyle( + color: StreamChatTheme.of(context) + .colorTheme + .black), ), ), ), @@ -182,7 +188,7 @@ class _NewChatScreenState extends State { ), Positioned( child: StreamSvgIcon.close( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), ), ], @@ -235,8 +241,14 @@ class _NewChatScreenState extends State { begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ - Colors.black.withOpacity(0.02), - Colors.white.withOpacity(0.05), + StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.02), + StreamChatTheme.of(context) + .colorTheme + .white + .withOpacity(0.05), ], stops: [0, 1], ), @@ -253,7 +265,11 @@ class _NewChatScreenState extends State { style: StreamChatTheme.of(context) .textTheme .footnote - .copyWith(color: Colors.black.withOpacity(.5))), + .copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5))), ), ), Expanded( @@ -318,7 +334,10 @@ class _NewChatScreenState extends State { .textTheme .footnote .copyWith( - color: Colors.black + color: StreamChatTheme.of( + context) + .colorTheme + .black .withOpacity(.5)), ), ], @@ -344,7 +363,10 @@ class _NewChatScreenState extends State { 'No chats here yet...', style: TextStyle( fontSize: 12, - color: Colors.black.withOpacity(.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ), ), ); diff --git a/example/lib/new_group_chat_screen.dart b/example/lib/new_group_chat_screen.dart index ba477a73..a00dbc07 100644 --- a/example/lib/new_group_chat_screen.dart +++ b/example/lib/new_group_chat_screen.dart @@ -62,12 +62,12 @@ class _NewGroupChatScreenState extends State { pinned: true, forceElevated: true, elevation: 1, - backgroundColor: Colors.white, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, leading: const StreamBackButton(), title: Text( 'Add Group Members', style: TextStyle( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, fontSize: 16, ), ), @@ -137,7 +137,9 @@ class _NewGroupChatScreenState extends State { }, child: Container( decoration: BoxDecoration( - color: Colors.white, + color: StreamChatTheme.of(context) + .colorTheme + .white, shape: BoxShape.circle, border: Border.all( color: Colors.grey.shade100, @@ -146,7 +148,9 @@ class _NewGroupChatScreenState extends State { child: Padding( padding: const EdgeInsets.all(0.0), child: StreamSvgIcon.close( - color: Colors.black, + color: StreamChatTheme.of(context) + .colorTheme + .black, size: 24, ), ), @@ -180,8 +184,14 @@ class _NewGroupChatScreenState extends State { begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ - Colors.black.withOpacity(0.02), - Colors.white.withOpacity(0.05), + StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.02), + StreamChatTheme.of(context) + .colorTheme + .white + .withOpacity(0.05), ], stops: [0, 1], ), @@ -196,7 +206,10 @@ class _NewGroupChatScreenState extends State { ? 'Matches for \"$_userNameQuery\"' : 'On the platform', style: TextStyle( - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), ), ), ), @@ -267,7 +280,10 @@ class _NewGroupChatScreenState extends State { .textTheme .footnote .copyWith( - color: Colors.black.withOpacity(.5)), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5)), ), ], ), @@ -299,7 +315,7 @@ class _HeaderDelegate extends SliverPersistentHeaderDelegate { Widget build( BuildContext context, double shrinkOffset, bool overlapsContent) { return Container( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, child: child, ); } diff --git a/example/lib/search_text_field.dart b/example/lib/search_text_field.dart index 00859b59..1054446f 100644 --- a/example/lib/search_text_field.dart +++ b/example/lib/search_text_field.dart @@ -22,7 +22,7 @@ class SearchTextField extends StatelessWidget { return Container( height: 36, decoration: BoxDecoration( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, border: Border.all( color: Colors.grey.shade300, ), @@ -48,15 +48,16 @@ class SearchTextField extends StatelessWidget { right: 8, ), child: StreamSvgIcon.search( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, size: 24, ), ), hintText: hintText, - hintStyle: StreamChatTheme.of(context) - .textTheme - .body - .copyWith(color: Colors.black.withOpacity(.5)), + hintStyle: StreamChatTheme.of(context).textTheme.body.copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5)), contentPadding: const EdgeInsets.all(0), border: OutlineInputBorder( borderSide: BorderSide.none, diff --git a/example/lib/stream_version.dart b/example/lib/stream_version.dart index 113e36c0..a3d52ab6 100644 --- a/example/lib/stream_version.dart +++ b/example/lib/stream_version.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:yaml/yaml.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; class StreamVersion extends StatelessWidget { const StreamVersion({ @@ -28,7 +29,8 @@ class StreamVersion extends StatelessWidget { 'Stream SDK v ${streamChatDep}', style: TextStyle( fontSize: 14.5, - color: Colors.black.withOpacity(.13), + color: + StreamChatTheme.of(context).colorTheme.black.withOpacity(.13), ), ); }, diff --git a/lib/src/attachment_error.dart b/lib/src/attachment_error.dart index e08867b8..0b51e59c 100644 --- a/lib/src/attachment_error.dart +++ b/lib/src/attachment_error.dart @@ -3,6 +3,8 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:stream_chat/stream_chat.dart'; +import '../stream_chat_flutter.dart'; + class AttachmentError extends StatelessWidget { final Attachment attachment; final Size size; @@ -28,7 +30,7 @@ class AttachmentError extends StatelessWidget { child: Center( child: Icon( Icons.error_outline, - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), ), ), diff --git a/lib/src/back_button.dart b/lib/src/back_button.dart index 10b177d2..d4d7c53c 100644 --- a/lib/src/back_button.dart +++ b/lib/src/back_button.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter/src/unread_indicator.dart'; +import '../stream_chat_flutter.dart'; + class StreamBackButton extends StatelessWidget { const StreamBackButton({ Key key, @@ -36,8 +38,8 @@ class StreamBackButton extends StatelessWidget { child: StreamSvgIcon.left( size: 24, color: Theme.of(context).brightness == Brightness.dark - ? Colors.white - : Colors.black, + ? StreamChatTheme.of(context).colorTheme.white + : StreamChatTheme.of(context).colorTheme.black, ), ), ), diff --git a/lib/src/channel_image.dart b/lib/src/channel_image.dart index c3d76202..b577a442 100644 --- a/lib/src/channel_image.dart +++ b/lib/src/channel_image.dart @@ -149,7 +149,9 @@ class ChannelImage extends StatelessWidget { ? snapshot.data['name'][0] : '', style: TextStyle( - color: Colors.white, + color: StreamChatTheme.of(context) + .colorTheme + .white, fontWeight: FontWeight.bold, ), ), diff --git a/lib/src/channel_list_header.dart b/lib/src/channel_list_header.dart index 41b283f5..09156d4c 100644 --- a/lib/src/channel_list_header.dart +++ b/lib/src/channel_list_header.dart @@ -145,7 +145,7 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { Widget _buildConnectedTitleState(BuildContext context) => Text( 'Stream Chat', style: StreamChatTheme.of(context).textTheme.headlineBold.copyWith( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), ); diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index c04f80ed..701158e1 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -319,7 +319,7 @@ class _ChannelListViewState extends State child: ListTile( leading: Container( decoration: BoxDecoration( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, shape: BoxShape.circle, ), constraints: BoxConstraints.tightFor( @@ -331,7 +331,7 @@ class _ChannelListViewState extends State alignment: Alignment.centerLeft, child: Container( decoration: BoxDecoration( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, borderRadius: BorderRadius.circular(11), ), constraints: BoxConstraints.tightFor( @@ -346,7 +346,7 @@ class _ChannelListViewState extends State alignment: Alignment.centerLeft, child: Container( decoration: BoxDecoration( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, borderRadius: BorderRadius.circular(11), ), constraints: BoxConstraints.tightFor( @@ -358,7 +358,7 @@ class _ChannelListViewState extends State Container( margin: const EdgeInsets.only(left: 16), decoration: BoxDecoration( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, borderRadius: BorderRadius.circular(11), ), constraints: BoxConstraints.tightFor( @@ -622,8 +622,8 @@ class _ChannelListViewState extends State return Container( height: 1, color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(0.1) - : Colors.black.withOpacity(0.1), + ? StreamChatTheme.of(context).colorTheme.white.withOpacity(0.1) + : StreamChatTheme.of(context).colorTheme.black.withOpacity(0.1), ); } diff --git a/lib/src/channel_unread_indicator.dart b/lib/src/channel_unread_indicator.dart index 8080b1e9..10a2aa48 100644 --- a/lib/src/channel_unread_indicator.dart +++ b/lib/src/channel_unread_indicator.dart @@ -36,7 +36,7 @@ class ChannelUnreadIndicator extends StatelessWidget { '${snapshot.data}', style: TextStyle( fontSize: 11, - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), ), ), diff --git a/lib/src/chat_info_screen.dart b/lib/src/chat_info_screen.dart index 8d291f38..132f3ea3 100644 --- a/lib/src/chat_info_screen.dart +++ b/lib/src/chat_info_screen.dart @@ -47,7 +47,7 @@ class _ChatInfoScreenState extends State { Widget _buildUserHeader() { return Material( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, child: SafeArea( child: Stack( children: [ @@ -81,7 +81,11 @@ class _ChatInfoScreenState extends State { child: Text( widget.user.name, style: TextStyle( - color: Colors.black.withOpacity(0.5), fontSize: 16.0), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), + fontSize: 16.0), ), ), onTap: () {}, @@ -113,7 +117,7 @@ class _ChatInfoScreenState extends State { // title: 'Notifications', // leading: StreamSvgIcon.Icon_notification( // size: 24.0, - // color: Colors.black.withOpacity(0.5), + // color: StreamChatTheme.of(context).colorTheme.black.withOpacity(0.5), // ), // trailing: CupertinoSwitch( // value: true, @@ -128,7 +132,10 @@ class _ChatInfoScreenState extends State { title: 'Mute user', leading: StreamSvgIcon.mute( size: 23.0, - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), ), trailing: snapshot.data == null ? CircularProgressIndicator() @@ -149,7 +156,7 @@ class _ChatInfoScreenState extends State { // title: 'Block User', // leading: StreamSvgIcon.Icon_user_delete( // size: 24.0, - // color: Colors.black.withOpacity(0.5), + // color: StreamChatTheme.of(context).colorTheme.black.withOpacity(0.5), // ), // trailing: CupertinoSwitch( // value: widget.user.banned, @@ -167,7 +174,8 @@ class _ChatInfoScreenState extends State { title: 'Photos & Videos', leading: StreamSvgIcon.pictures( size: 32.0, - color: Colors.black.withOpacity(0.5), + color: + StreamChatTheme.of(context).colorTheme.black.withOpacity(0.5), ), trailing: StreamSvgIcon.right(), onTap: () { @@ -179,7 +187,8 @@ class _ChatInfoScreenState extends State { title: 'Files', leading: StreamSvgIcon.files( size: 32.0, - color: Colors.black.withOpacity(0.5), + color: + StreamChatTheme.of(context).colorTheme.black.withOpacity(0.5), ), trailing: StreamSvgIcon.right(), onTap: () { @@ -191,7 +200,8 @@ class _ChatInfoScreenState extends State { title: 'Shared groups', leading: StreamSvgIcon.Icon_group( size: 24.0, - color: Colors.black.withOpacity(0.5), + color: + StreamChatTheme.of(context).colorTheme.black.withOpacity(0.5), ), trailing: StreamSvgIcon.right(), onTap: () { @@ -248,12 +258,20 @@ class _ChatInfoScreenState extends State { if (otherMember.online) { alternativeWidget = Text( 'Online', - style: TextStyle(color: Colors.black.withOpacity(0.5)), + style: TextStyle( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5)), ); } else { alternativeWidget = Text( 'Last seen ${Jiffy(otherMember.lastActive).fromNow()}', - style: TextStyle(color: Colors.black.withOpacity(0.5)), + style: TextStyle( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5)), ); } } @@ -275,7 +293,7 @@ class _ChatInfoScreenState extends State { color: Color(0xff20E070), ), ), - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), alternativeWidget, ], @@ -307,7 +325,7 @@ class _OptionListTile extends StatelessWidget { height: 2.0, ), Material( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, child: Container( height: 56.0, child: InkWell( @@ -365,14 +383,16 @@ class __SharedGroupsScreenState extends State<_SharedGroupsScreen> { var chat = StreamChat.of(context); return Scaffold( - backgroundColor: Colors.white, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, appBar: AppBar( brightness: Theme.of(context).brightness, elevation: 1, centerTitle: true, title: Text( 'Shared Groups', - style: TextStyle(color: Colors.black, fontSize: 16.0), + style: TextStyle( + color: StreamChatTheme.of(context).colorTheme.black, + fontSize: 16.0), ), leading: Center( child: InkWell( @@ -381,7 +401,7 @@ class __SharedGroupsScreenState extends State<_SharedGroupsScreen> { }, child: Container( child: StreamSvgIcon.left( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, size: 24.0, ), width: 24.0, @@ -488,7 +508,11 @@ class __SharedGroupsScreenState extends State<_SharedGroupsScreen> { padding: const EdgeInsets.all(8.0), child: Text( '${channel.memberCount} members', - style: TextStyle(color: Colors.black.withOpacity(0.5)), + style: TextStyle( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5)), ), ) ], @@ -509,14 +533,16 @@ class _MediaDisplayScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Colors.white, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, appBar: AppBar( brightness: Theme.of(context).brightness, elevation: 1, centerTitle: true, title: Text( 'Photos & Videos', - style: TextStyle(color: Colors.black, fontSize: 16.0), + style: TextStyle( + color: StreamChatTheme.of(context).colorTheme.black, + fontSize: 16.0), ), leading: Center( child: InkWell( @@ -525,7 +551,7 @@ class _MediaDisplayScreen extends StatelessWidget { }, child: Container( child: StreamSvgIcon.left( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, size: 24.0, ), width: 24.0, @@ -543,14 +569,16 @@ class _FileDisplayScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Colors.white, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, appBar: AppBar( brightness: Theme.of(context).brightness, elevation: 1, centerTitle: true, title: Text( 'Files', - style: TextStyle(color: Colors.black, fontSize: 16.0), + style: TextStyle( + color: StreamChatTheme.of(context).colorTheme.black, + fontSize: 16.0), ), leading: Center( child: InkWell( @@ -559,7 +587,7 @@ class _FileDisplayScreen extends StatelessWidget { }, child: Container( child: StreamSvgIcon.left( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, size: 24.0, ), width: 24.0, diff --git a/lib/src/date_divider.dart b/lib/src/date_divider.dart index 3b8c36c1..9b1ba435 100644 --- a/lib/src/date_divider.dart +++ b/lib/src/date_divider.dart @@ -41,8 +41,8 @@ class DateDivider extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( color: (Theme.of(context).brightness == Brightness.light - ? Colors.black - : Colors.white) + ? StreamChatTheme.of(context).colorTheme.black + : StreamChatTheme.of(context).colorTheme.white) .withOpacity(0.5), borderRadius: BorderRadius.circular( 8, @@ -51,7 +51,7 @@ class DateDivider extends StatelessWidget { child: Text( dayInfo, style: StreamChatTheme.of(context).textTheme.footnoteBold.copyWith( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, fontWeight: FontWeight.bold, ), ), diff --git a/lib/src/deleted_message.dart b/lib/src/deleted_message.dart index 9181d985..5921df43 100644 --- a/lib/src/deleted_message.dart +++ b/lib/src/deleted_message.dart @@ -41,8 +41,14 @@ class DeletedMessage extends StatelessWidget { side: borderSide ?? BorderSide( color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withAlpha(24) - : Colors.black.withAlpha(24), + ? StreamChatTheme.of(context) + .colorTheme + .white + .withAlpha(24) + : StreamChatTheme.of(context) + .colorTheme + .black + .withAlpha(24), ), ), child: Padding( @@ -58,8 +64,8 @@ class DeletedMessage extends StatelessWidget { style: messageTheme.messageText.copyWith( fontStyle: FontStyle.italic, color: (Theme.of(context).brightness == Brightness.dark - ? Colors.white - : Colors.black) + ? StreamChatTheme.of(context).colorTheme.white + : StreamChatTheme.of(context).colorTheme.black) .withOpacity(.5), ), ), diff --git a/lib/src/file_attachment.dart b/lib/src/file_attachment.dart index c5e6c92f..597add86 100644 --- a/lib/src/file_attachment.dart +++ b/lib/src/file_attachment.dart @@ -63,7 +63,7 @@ class _FileAttachmentState extends State { height: 56.0, margin: widget.trailing != null ? EdgeInsets.only(top: 4.0) : null, decoration: BoxDecoration( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, borderRadius: widget.trailing != null ? BorderRadius.circular(16.0) : null, border: widget.trailing != null @@ -97,10 +97,11 @@ class _FileAttachmentState extends State { ), Text( '${_getSizeText(widget.attachment.extraData['file_size'])}', - style: StreamChatTheme.of(context) - .textTheme - .body - .copyWith(color: Colors.black.withOpacity(0.5)), + style: StreamChatTheme.of(context).textTheme.body.copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5)), ), ], ), @@ -110,7 +111,7 @@ class _FileAttachmentState extends State { widget.trailing ?? IconButton( icon: StreamSvgIcon.cloud_download( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), onPressed: () { launchURL(context, widget.attachment.assetUrl); @@ -138,13 +139,13 @@ class _FileAttachmentState extends State { // subtitle: Text( // '${attachment.extraData['file_size'] ?? 'N/A'} bytes', // style: TextStyle( - // color: Colors.black.withOpacity(0.5), + // color: StreamChatTheme.of(context).colorTheme.black.withOpacity(0.5), // ), // ), // trailing: trailing ?? // IconButton( // icon: StreamSvgIcon.cloud_download( - // color: Colors.black, + // color: StreamChatTheme.of(context).colorTheme.black, // ), // onPressed: () { // launchURL(context, attachment.assetUrl); diff --git a/lib/src/full_screen_media.dart b/lib/src/full_screen_media.dart index 7e3f3d7d..e6ecb64f 100644 --- a/lib/src/full_screen_media.dart +++ b/lib/src/full_screen_media.dart @@ -100,7 +100,9 @@ class _FullScreenMediaState extends State .channelTheme .channelHeaderTheme .color, - end: Colors.black) + end: StreamChatTheme.of(context) + .colorTheme + .black) .lerp(_controller.value), ), onTapUp: (a, b, c) { diff --git a/lib/src/giphy_attachment.dart b/lib/src/giphy_attachment.dart index 74dfeeb4..1f3bf9e6 100644 --- a/lib/src/giphy_attachment.dart +++ b/lib/src/giphy_attachment.dart @@ -112,7 +112,10 @@ class GiphyAttachment extends StatelessWidget { bottom: 16, left: 16, child: Material( - color: Colors.black.withOpacity(.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), @@ -124,13 +127,16 @@ class GiphyAttachment extends StatelessWidget { child: Row( children: [ StreamSvgIcon.lightning( - color: Colors.white, + color: + StreamChatTheme.of(context).colorTheme.white, size: 16, ), Text( 'GIPHY', style: TextStyle( - color: Colors.white, + color: StreamChatTheme.of(context) + .colorTheme + .white, fontWeight: FontWeight.bold, fontSize: 11, ), @@ -202,7 +208,10 @@ class GiphyAttachment extends StatelessWidget { height: 4.0, ), Container( - color: Colors.black.withOpacity(0.2), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.2), width: double.infinity, height: 0.5, ), @@ -224,14 +233,20 @@ class GiphyAttachment extends StatelessWidget { .textTheme .bodyBold .copyWith( - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), ), ), ), ), Container( width: 0.5, - color: Colors.black.withOpacity(0.2), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.2), height: 50.0, ), Expanded( @@ -266,7 +281,10 @@ class GiphyAttachment extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ StreamSvgIcon.eye( - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), size: 16.0, ), SizedBox( @@ -277,7 +295,11 @@ class GiphyAttachment extends StatelessWidget { style: StreamChatTheme.of(context) .textTheme .footnote - .copyWith(color: Colors.black.withOpacity(0.5)), + .copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5)), ), ], ), @@ -334,7 +356,10 @@ class GiphyAttachment extends StatelessWidget { bottom: 8, left: 8, child: Material( - color: Colors.black.withOpacity(.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), @@ -346,13 +371,13 @@ class GiphyAttachment extends StatelessWidget { child: Row( children: [ StreamSvgIcon.lightning( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, size: 16, ), Text( 'GIPHY', style: TextStyle( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, fontWeight: FontWeight.bold, fontSize: 11, ), diff --git a/lib/src/image_actions_modal.dart b/lib/src/image_actions_modal.dart index 2b2aa05e..45a60d60 100644 --- a/lib/src/image_actions_modal.dart +++ b/lib/src/image_actions_modal.dart @@ -34,7 +34,7 @@ class ImageActionsModal extends StatelessWidget { begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ - Colors.black.withOpacity(0.8), + StreamChatTheme.of(context).colorTheme.black.withOpacity(0.8), Colors.transparent, ], stops: [0.0, 0.4], @@ -69,7 +69,9 @@ class ImageActionsModal extends StatelessWidget { style: StreamChatTheme.of(context) .textTheme .headlineBold - .copyWith(color: Colors.white), + .copyWith( + color: + StreamChatTheme.of(context).colorTheme.white), ), ), Text( @@ -77,14 +79,18 @@ class ImageActionsModal extends StatelessWidget { style: StreamChatTheme.of(context) .channelPreviewTheme .subtitle - .copyWith(color: Colors.white.withOpacity(0.5)), + .copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .white + .withOpacity(0.5)), ), ], ), IconButton( icon: StreamSvgIcon.close( size: 24.0, - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), onPressed: () { Navigator.pop(context); @@ -114,7 +120,10 @@ class ImageActionsModal extends StatelessWidget { 'Reply', StreamSvgIcon.Icon_curve_line_left_up( size: 24.0, - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), ), () {}), _buildButton( @@ -122,7 +131,8 @@ class ImageActionsModal extends StatelessWidget { 'Show in Chat', StreamSvgIcon.eye( size: 24.0, - color: Colors.black, + color: + StreamChatTheme.of(context).colorTheme.black, ), () { Navigator.pop(context); Navigator.pop(context); @@ -132,7 +142,10 @@ class ImageActionsModal extends StatelessWidget { 'Save ${urls[currentIndex].type == 'video' ? 'Video' : 'Image'}', StreamSvgIcon.Icon_save( size: 24.0, - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), ), () async { var url = urls[currentIndex].imageUrl ?? urls[currentIndex].assetUrl ?? @@ -181,7 +194,7 @@ class ImageActionsModal extends StatelessWidget { {Color color}) { var titleStyle = TextStyle( fontSize: 14.5, - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ); return Material( diff --git a/lib/src/image_footer.dart b/lib/src/image_footer.dart index f16be87d..762bd737 100644 --- a/lib/src/image_footer.dart +++ b/lib/src/image_footer.dart @@ -114,7 +114,7 @@ class _ImageFooterState extends State { IconButton( icon: StreamSvgIcon.icon_SHARE( size: 24.0, - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), onPressed: () { _buildShareModal(context); @@ -138,7 +138,7 @@ class _ImageFooterState extends State { ), IconButton( icon: StreamSvgIcon.Icon_grid( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), onPressed: () { _buildPhotosModal(context); @@ -166,7 +166,7 @@ class _ImageFooterState extends State { children: [ Container( decoration: BoxDecoration( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, borderRadius: BorderRadius.only( topRight: Radius.circular(16.0), topLeft: Radius.circular(16.0), @@ -187,7 +187,7 @@ class _ImageFooterState extends State { alignment: Alignment.centerRight, child: IconButton( icon: StreamSvgIcon.close( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), onPressed: () { Navigator.pop(context); @@ -198,7 +198,7 @@ class _ImageFooterState extends State { ), ), Container( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, child: GridView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), @@ -346,7 +346,7 @@ class _ImageFooterState extends State { Align( alignment: Alignment.bottomCenter, child: Container( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, height: 48.0, child: Material( child: InkWell( @@ -415,7 +415,7 @@ class _ImageFooterState extends State { Expanded( child: TextField( controller: _searchController, - cursorColor: Colors.black, + cursorColor: StreamChatTheme.of(context).colorTheme.black, autofocus: true, decoration: InputDecoration( isDense: true, @@ -425,19 +425,25 @@ class _ImageFooterState extends State { padding: const EdgeInsets.symmetric( vertical: 2.0, horizontal: 6.0), child: StreamSvgIcon.search( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), ), hintText: 'Search', border: OutlineInputBorder( borderRadius: BorderRadius.circular(32.0), - borderSide: - BorderSide(color: Colors.black.withOpacity(0.08)), + borderSide: BorderSide( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.08)), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(32.0), - borderSide: - BorderSide(color: Colors.black.withOpacity(0.08)), + borderSide: BorderSide( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.08)), ), contentPadding: EdgeInsets.zero, ), @@ -448,7 +454,10 @@ class _ImageFooterState extends State { ), IconButton( icon: StreamSvgIcon.close_small( - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), ), onPressed: () { modalSetState(() { @@ -469,7 +478,7 @@ class _ImageFooterState extends State { padding: const EdgeInsets.symmetric(horizontal: 6.0), child: IconButton( icon: StreamSvgIcon.search( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), iconSize: 24.0, onPressed: () { @@ -490,7 +499,7 @@ class _ImageFooterState extends State { padding: const EdgeInsets.symmetric(horizontal: 6.0), child: IconButton( icon: StreamSvgIcon.share_arrow( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), onPressed: () async { var url = @@ -517,7 +526,7 @@ class _ImageFooterState extends State { return Align( alignment: Alignment.bottomCenter, child: Container( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, height: 56.0, child: _loading ? Center( @@ -547,13 +556,19 @@ class _ImageFooterState extends State { border: OutlineInputBorder( borderRadius: BorderRadius.circular(32.0), borderSide: BorderSide( - color: Colors.black.withOpacity(0.16), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.16), ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(32.0), borderSide: BorderSide( - color: Colors.black.withOpacity(0.16), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.16), )), contentPadding: EdgeInsets.symmetric(vertical: 12.0), ), diff --git a/lib/src/image_group.dart b/lib/src/image_group.dart index 44c15623..7bce22f9 100644 --- a/lib/src/image_group.dart +++ b/lib/src/image_group.dart @@ -83,7 +83,9 @@ class ImageGroup extends StatelessWidget { child: Text( '${images.length - 4} +', style: TextStyle( - color: Colors.white, + color: StreamChatTheme.of(context) + .colorTheme + .white, fontSize: 28, ), ), diff --git a/lib/src/image_header.dart b/lib/src/image_header.dart index aae73057..a9f1173f 100644 --- a/lib/src/image_header.dart +++ b/lib/src/image_header.dart @@ -50,7 +50,7 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget { leading: showBackButton ? IconButton( icon: StreamSvgIcon.close( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, size: 24.0, ), onPressed: onBackPressed, @@ -61,7 +61,7 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget { actions: [ IconButton( icon: StreamSvgIcon.Icon_menu_point_v( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), onPressed: () { _showMessageActionModalBottomSheet(context); diff --git a/lib/src/media_list_view.dart b/lib/src/media_list_view.dart index 5f52e9b5..d2b7ba69 100644 --- a/lib/src/media_list_view.dart +++ b/lib/src/media_list_view.dart @@ -6,6 +6,8 @@ import 'package:stream_chat_flutter/src/lazy_load_scroll_view.dart'; import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'dart:ui' as ui; +import '../stream_chat_flutter.dart'; + extension on Duration { String format() { final s = '$this'.split('.')[0].padLeft(8, '0'); @@ -80,7 +82,10 @@ class _MediaListViewState extends State { ? 1.0 : 0.0, child: Container( - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), alignment: Alignment.topRight, padding: const EdgeInsets.only( top: 8, @@ -88,10 +93,12 @@ class _MediaListViewState extends State { ), child: CircleAvatar( radius: 12, - backgroundColor: Colors.white, + backgroundColor: + StreamChatTheme.of(context).colorTheme.white, child: StreamSvgIcon.check( size: 24, - color: Colors.black, + color: + StreamChatTheme.of(context).colorTheme.black, ), ), ), @@ -113,7 +120,7 @@ class _MediaListViewState extends State { child: Text( media.videoDuration.format(), style: TextStyle( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), ), ), diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 8013a8b3..17b9a79e 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -69,7 +69,10 @@ class MessageActionsModal extends StatelessWidget { sigmaY: 10.8731, ), child: Container( - color: Colors.black.withOpacity(0.1), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.1), ), ), ), diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 79189d1d..73f98754 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -263,7 +263,10 @@ class MessageInputState extends State { border: _sendAsDm ? null : Border.all( - color: Colors.black.withOpacity(.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), width: 2, ), borderRadius: BorderRadius.circular(3), @@ -273,7 +276,7 @@ class MessageInputState extends State { borderRadius: BorderRadius.circular(3), color: _sendAsDm ? StreamChatTheme.of(context).accentColor - : Colors.white, + : StreamChatTheme.of(context).colorTheme.white, child: InkWell( onTap: () { setState(() { @@ -288,7 +291,7 @@ class MessageInputState extends State { : CrossFadeState.showSecond, firstChild: StreamSvgIcon.check( size: 16.0, - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), secondChild: SizedBox( height: 16, @@ -418,7 +421,9 @@ class MessageInputState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ StreamSvgIcon.lightning( - color: Colors.white, + color: StreamChatTheme.of(context) + .colorTheme + .white, size: 16.0, ), Text( @@ -426,7 +431,10 @@ class MessageInputState extends State { style: StreamChatTheme.of(context) .textTheme .footnote - .copyWith(color: Colors.white), + .copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .white), ), ], ), @@ -633,7 +641,10 @@ class MessageInputState extends State { Text( 'Instant Commands', style: TextStyle( - color: Colors.black.withOpacity(.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ), ) ], @@ -664,7 +675,9 @@ class MessageInputState extends State { backgroundColor: StreamChatTheme.of(context).accentColor, child: StreamSvgIcon.lightning( - color: Colors.white, + color: StreamChatTheme.of(context) + .colorTheme + .white, size: 12.5, ), maxRadius: 12, @@ -698,24 +711,33 @@ class MessageInputState extends State { ? StreamChatTheme.of(context).accentColor : (!_attachmentContainsFile ? StreamChatTheme.of(context).accentColor - : Colors.black.withOpacity(0.2)); + : StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.2)); break; case 1: return _attachmentContainsFile ? StreamChatTheme.of(context).accentColor : (_attachments.isEmpty - ? Colors.black.withOpacity(0.5) - : Colors.black.withOpacity(0.2)); + ? StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5) + : StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.2)); break; case 2: return _attachmentContainsFile && _attachments.isNotEmpty - ? Colors.black.withOpacity(0.2) - : Colors.black.withOpacity(0.5); + ? StreamChatTheme.of(context).colorTheme.black.withOpacity(0.2) + : StreamChatTheme.of(context).colorTheme.black.withOpacity(0.5); break; case 3: return _attachmentContainsFile && _attachments.isNotEmpty - ? Colors.black.withOpacity(0.2) - : Colors.black.withOpacity(0.5); + ? StreamChatTheme.of(context).colorTheme.black.withOpacity(0.2) + : StreamChatTheme.of(context).colorTheme.black.withOpacity(0.5); break; } } @@ -791,7 +813,7 @@ class MessageInputState extends State { }, child: Container( decoration: BoxDecoration( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0), @@ -820,7 +842,7 @@ class MessageInputState extends State { Expanded( child: Container( decoration: BoxDecoration( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, borderRadius: BorderRadius.circular(8.0), ), child: _buildPickerSection(), @@ -1023,7 +1045,7 @@ class MessageInputState extends State { CircleAvatar _buildGiphyIcon() { if (kIsWeb) { return CircleAvatar( - backgroundColor: Colors.black, + backgroundColor: StreamChatTheme.of(context).colorTheme.black, child: Image.asset( 'images/giphy_icon.png', package: 'stream_chat_flutter', @@ -1223,7 +1245,10 @@ class MessageInputState extends State { child: Text( 'Emoji matching "$query"', style: TextStyle( - color: Colors.black.withOpacity(.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ), ), ) @@ -1317,10 +1342,15 @@ class MessageInputState extends State { child: InkWell( child: CircleAvatar( backgroundColor: - Colors.black.withOpacity(0.2), + StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.2), maxRadius: 12.0, child: StreamSvgIcon.close( - color: Colors.white, + color: StreamChatTheme.of(context) + .colorTheme + .white, ), ), onTap: () { @@ -1405,11 +1435,11 @@ class MessageInputState extends State { _attachments.remove(attachment); }); }, - fillColor: Colors.black.withOpacity(.5), + fillColor: StreamChatTheme.of(context).colorTheme.black.withOpacity(.5), child: Center( child: StreamSvgIcon.close( size: 24, - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), ), ), diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 7452fd6d..fd31b996 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -254,7 +254,11 @@ class _MessageListViewState extends State { style: StreamChatTheme.of(context) .textTheme .footnote - .copyWith(color: Colors.black.withOpacity(.5)), + .copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5)), ), ); } @@ -524,9 +528,9 @@ class _MessageListViewState extends State { clipBehavior: Clip.none, children: [ FloatingActionButton( - backgroundColor: Colors.white, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, child: StreamSvgIcon.down( - color: Colors.black, + color: StreamChatTheme.of(context).colorTheme.black, ), onPressed: () { if (unreadCount > 0) { diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index e5043e62..a6a7e54c 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -60,7 +60,10 @@ class MessageReactionsModal extends StatelessWidget { sigmaY: 10.8731, ), child: Container( - color: Colors.black.withOpacity(0.1), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.1), ), ), ), diff --git a/lib/src/message_search_list_view.dart b/lib/src/message_search_list_view.dart index 087ae839..989234b3 100644 --- a/lib/src/message_search_list_view.dart +++ b/lib/src/message_search_list_view.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat_flutter/src/message_search_item.dart'; +import '../stream_chat_flutter.dart'; import 'lazy_load_scroll_view.dart'; import 'message_search_bloc.dart'; @@ -127,8 +128,8 @@ class _MessageSearchListViewState extends State { return Container( height: 1, color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(0.1) - : Colors.black.withOpacity(0.1), + ? StreamChatTheme.of(context).colorTheme.white.withOpacity(0.1) + : StreamChatTheme.of(context).colorTheme.black.withOpacity(0.1), ); } @@ -313,8 +314,14 @@ class _MessageSearchListViewState extends State { begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ - Colors.black.withOpacity(0.02), - Colors.white.withOpacity(0.05), + StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.02), + StreamChatTheme.of(context) + .colorTheme + .white + .withOpacity(0.05), ], stops: [0, 1], ), @@ -327,7 +334,10 @@ class _MessageSearchListViewState extends State { child: Text( '${items.length} results', style: TextStyle( - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), ), ), ), diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index f3e5b108..7b185f97 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -327,10 +327,16 @@ class _MessageWidgetState extends State { .brightness == Brightness .dark - ? Colors.white + ? StreamChatTheme.of( + context) + .colorTheme + .white .withAlpha( 24) - : Colors.black + : StreamChatTheme.of( + context) + .colorTheme + .black .withAlpha( 24), ), @@ -414,16 +420,18 @@ class _MessageWidgetState extends State { mainAxisSize: MainAxisSize.min, children: [ StreamSvgIcon.eye( - color: Colors.black.withOpacity(0.5), + color: + StreamChatTheme.of(context).colorTheme.black.withOpacity(0.5), size: 16.0, ), SizedBox(width: 8.0), Text( 'Only visible to you', - style: StreamChatTheme.of(context) - .textTheme - .footnote - .copyWith(color: Colors.black.withOpacity(0.5)), + style: StreamChatTheme.of(context).textTheme.footnote.copyWith( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5)), ), ], ), @@ -551,7 +559,7 @@ class _MessageWidgetState extends State { bottom: 0, top: 0, child: Material( - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, clipBehavior: Clip.antiAlias, shape: CircleBorder(), child: Padding( @@ -664,8 +672,8 @@ class _MessageWidgetState extends State { widget.borderSide ?? BorderSide( color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withAlpha(24) - : Colors.black.withAlpha(24), + ? StreamChatTheme.of(context).colorTheme.white.withAlpha(24) + : StreamChatTheme.of(context).colorTheme.black.withAlpha(24), ), borderRadius: widget.attachmentBorderRadiusGeometry ?? widget.borderRadiusGeometry ?? @@ -820,8 +828,8 @@ class _MessageWidgetState extends State { 'MESSAGE FAILED · CLICK TO TRY AGAIN', style: widget.messageTheme.messageText.copyWith( color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(.5) - : Colors.black.withOpacity(.5), + ? StreamChatTheme.of(context).colorTheme.white.withOpacity(.5) + : StreamChatTheme.of(context).colorTheme.black.withOpacity(.5), fontSize: 11, ), ); @@ -831,8 +839,8 @@ class _MessageWidgetState extends State { 'MESSAGE UPDATE FAILED · CLICK TO TRY AGAIN', style: widget.messageTheme.messageText.copyWith( color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(.5) - : Colors.black.withOpacity(.5), + ? StreamChatTheme.of(context).colorTheme.white.withOpacity(.5) + : StreamChatTheme.of(context).colorTheme.black.withOpacity(.5), fontSize: 11, ), ); @@ -842,8 +850,8 @@ class _MessageWidgetState extends State { 'MESSAGE DELETE FAILED · CLICK TO TRY AGAIN', style: widget.messageTheme.messageText.copyWith( color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(.5) - : Colors.black.withOpacity(.5), + ? StreamChatTheme.of(context).colorTheme.white.withOpacity(.5) + : StreamChatTheme.of(context).colorTheme.black.withOpacity(.5), fontSize: 11, ), ); diff --git a/lib/src/reaction_bubble.dart b/lib/src/reaction_bubble.dart index 87dc7a92..f7c9c142 100644 --- a/lib/src/reaction_bubble.dart +++ b/lib/src/reaction_bubble.dart @@ -108,7 +108,10 @@ class ReactionBubble extends StatelessWidget { color: (!highlightOwnReactions || reaction.user.id == StreamChat.of(context).user.id) ? StreamChatTheme.of(context).accentColor - : Colors.black.withOpacity(.5), + : StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ) : Icon( Icons.help_outline_rounded, @@ -116,7 +119,10 @@ class ReactionBubble extends StatelessWidget { color: (!highlightOwnReactions || reaction.user.id == StreamChat.of(context).user.id) ? StreamChatTheme.of(context).accentColor - : Colors.black.withOpacity(.5), + : StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), ), ); } diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index d4237270..573e646b 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -254,7 +254,7 @@ class StreamChatThemeData { colorTheme: colorTheme, secondaryColor: Color(0xffEAEAEA), accentColor: accentColor, - primaryColor: isDark ? Colors.black : Colors.white, + primaryColor: isDark ? colorTheme.black : colorTheme.white, primaryIconTheme: IconThemeData( color: isDark ? Colors.white : Colors.black.withOpacity(.5)), defaultChannelImage: (context, channel) => SizedBox(), diff --git a/lib/src/unread_indicator.dart b/lib/src/unread_indicator.dart index c9f42fad..42e6c78d 100644 --- a/lib/src/unread_indicator.dart +++ b/lib/src/unread_indicator.dart @@ -34,7 +34,7 @@ class UnreadIndicator extends StatelessWidget { '${snapshot.data}', style: TextStyle( fontSize: 11, - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), ), ), diff --git a/lib/src/user_avatar.dart b/lib/src/user_avatar.dart index 756252cc..c0b2a712 100644 --- a/lib/src/user_avatar.dart +++ b/lib/src/user_avatar.dart @@ -99,7 +99,7 @@ class UserAvatar extends StatelessWidget { color: Color(0xff20E070), ), ), - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), ), ), diff --git a/lib/src/user_item.dart b/lib/src/user_item.dart index 0c6c196d..49a6d5e3 100644 --- a/lib/src/user_item.dart +++ b/lib/src/user_item.dart @@ -76,7 +76,7 @@ class UserItem extends StatelessWidget { ? CircleAvatar( child: StreamSvgIcon.check( size: 20, - color: Colors.white, + color: StreamChatTheme.of(context).colorTheme.white, ), radius: 10, ) @@ -94,10 +94,8 @@ class UserItem extends StatelessWidget { user.online == true ? 'Online' : 'Last online ${Jiffy(user.lastActive).fromNow()}', - style: StreamChatTheme.of(context) - .textTheme - .footnote - .copyWith(color: Colors.black.withOpacity(.5)), + style: StreamChatTheme.of(context).textTheme.footnote.copyWith( + color: StreamChatTheme.of(context).colorTheme.black.withOpacity(.5)), ); } } diff --git a/lib/src/user_list_view.dart b/lib/src/user_list_view.dart index cc3c1125..1108c24d 100644 --- a/lib/src/user_list_view.dart +++ b/lib/src/user_list_view.dart @@ -356,7 +356,8 @@ class _UserListViewState extends State headerItem: (header) { return Container( key: ValueKey('HEADER-$header'), - color: Colors.black.withOpacity(0.05), + color: + StreamChatTheme.of(context).colorTheme.black.withOpacity(0.05), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 6), child: Text( @@ -364,7 +365,10 @@ class _UserListViewState extends State style: TextStyle( fontWeight: FontWeight.bold, fontSize: 14.5, - color: Colors.black.withOpacity(0.3)), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.3)), ), ), ); @@ -472,8 +476,8 @@ class _UserListViewState extends State return Container( height: 1, color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(0.1) - : Colors.black.withOpacity(0.1), + ? StreamChatTheme.of(context).colorTheme.white.withOpacity(0.1) + : StreamChatTheme.of(context).colorTheme.black.withOpacity(0.1), ); } diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 60eca678..f1f1b68a 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -25,7 +25,7 @@ Future showConfirmationDialog( String cancelText, }) { return showModalBottomSheet( - backgroundColor: Colors.white, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, context: context, shape: RoundedRectangleBorder( borderRadius: BorderRadius.only( @@ -65,7 +65,10 @@ Future showConfirmationDialog( child: Text( cancelText, style: TextStyle( - color: Colors.black.withOpacity(0.5), + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.5), fontWeight: FontWeight.w400), ), onPressed: () { From 23fef38f2c3d264542257d81df8b8fa5625836aa Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Tue, 29 Dec 2020 23:16:17 +0530 Subject: [PATCH 12/31] fix --- example/ios/Flutter/.last_build_id | 2 +- example/ios/Podfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/ios/Flutter/.last_build_id b/example/ios/Flutter/.last_build_id index a2e31d3e..e72273c3 100644 --- a/example/ios/Flutter/.last_build_id +++ b/example/ios/Flutter/.last_build_id @@ -1 +1 @@ -209b1a40522bc1cb0ea3596a28cded5e \ No newline at end of file +13a41b8138c4868054e44b5158f3bdd6 \ No newline at end of file diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index af57742c..f266b656 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -296,4 +296,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: eb001256612a59f8f9e4d083ad8b9671e69dd184 -COCOAPODS: 1.8.3 +COCOAPODS: 1.10.0 From bf839e9bceae53552715a0b1ce8ab35a9793cc4b Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 30 Dec 2020 13:49:25 +0530 Subject: [PATCH 13/31] Added theme to main app --- example/lib/main.dart | 7 +- lib/src/stream_chat_theme.dart | 126 +++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 39 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 6f4562b6..ef281eac 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -52,10 +52,13 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return StreamChat( + streamChatThemeData: StreamChatThemeData.getDefaultTheme( + ThemeData.dark(), + ), client: client, child: MaterialApp( debugShowCheckedModeBanner: false, - theme: ThemeData.dark(), + theme: ThemeData.light(), darkTheme: ThemeData.dark(), //TODO change to system once dark theme is implemented themeMode: ThemeMode.dark, @@ -426,7 +429,7 @@ class ChannelPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color.fromRGBO(252, 252, 252, 1), + backgroundColor: StreamChatTheme.of(context).backgroundColor, appBar: ChannelHeader( showTypingIndicator: false, ), diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index 573e646b..5e6a0398 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -247,18 +247,17 @@ class StreamChatThemeData { static StreamChatThemeData getDefaultTheme(ThemeData theme) { final accentColor = Color(0xff006cff); final isDark = theme.brightness == Brightness.dark; - final textTheme = TextTheme(); + final textTheme = isDark ? TextTheme.dark() : TextTheme.light(); final colorTheme = isDark ? ColorTheme.dark() : ColorTheme.light(); return StreamChatThemeData( textTheme: textTheme, colorTheme: colorTheme, secondaryColor: Color(0xffEAEAEA), accentColor: accentColor, - primaryColor: isDark ? colorTheme.black : colorTheme.white, - primaryIconTheme: IconThemeData( - color: isDark ? Colors.white : Colors.black.withOpacity(.5)), + primaryColor: colorTheme.white, + primaryIconTheme: IconThemeData(color: colorTheme.black.withOpacity(.5)), defaultChannelImage: (context, channel) => SizedBox(), - backgroundColor: isDark ? Colors.black : Colors.white, + backgroundColor: colorTheme.white, defaultUserImage: (context, user) => Center( child: CachedNetworkImage( filterQuality: FilterQuality.high, @@ -280,7 +279,7 @@ class StreamChatThemeData { color: Color(0xff7A7A7A), ), lastMessageAt: textTheme.footnote.copyWith( - color: Colors.black.withOpacity(.5), + color: colorTheme.black.withOpacity(.5), ), ), channelTheme: ChannelTheme( @@ -295,20 +294,17 @@ class StreamChatThemeData { width: 40, ), ), - color: isDark ? Colors.black : Colors.white, + color: colorTheme.white, title: TextStyle( fontSize: 14, - color: isDark ? Colors.white : Colors.black, + color: colorTheme.black, ), lastMessageAt: TextStyle( fontSize: 11, - color: isDark - ? Colors.white.withOpacity(.5) - : Colors.black.withOpacity(.5), + color: colorTheme.black.withOpacity(.5), ), ), - inputBackground: - isDark ? Colors.black.withAlpha(12) : Colors.white.withAlpha(12), + inputBackground: colorTheme.white.withAlpha(12), inputGradient: LinearGradient(colors: [ Color(0xFF00AEFF), Color(0xFF0076FF), @@ -317,12 +313,10 @@ class StreamChatThemeData { ownMessageTheme: MessageTheme( messageText: TextStyle( fontSize: 14.5, - color: isDark ? Colors.white : Colors.black, + color: colorTheme.black, ), createdAt: TextStyle( - color: isDark - ? Colors.white.withOpacity(.5) - : Colors.black.withOpacity(.5), + color: colorTheme.black.withOpacity(.5), fontSize: 12, ), replies: TextStyle( @@ -331,7 +325,7 @@ class StreamChatThemeData { fontSize: 12, ), messageBackgroundColor: isDark ? Color(0xff191919) : Color(0xffEAEAEA), - reactionsBackgroundColor: isDark ? Colors.black : Colors.white, + reactionsBackgroundColor: colorTheme.white, reactionsBorderColor: isDark ? Color(0xff191919) : Color(0xffEAEAEA), replyThreadColor: isDark ? Color(0xff191919) : Color(0xffEAEAEA), avatarTheme: AvatarTheme( @@ -348,15 +342,13 @@ class StreamChatThemeData { otherMessageTheme: MessageTheme( reactionsBackgroundColor: isDark ? Color(0xff191919) : Color(0xffEAEAEA), - reactionsBorderColor: isDark ? Colors.black : Colors.white, + reactionsBorderColor: colorTheme.white, messageText: TextStyle( fontSize: 14.5, - color: isDark ? Colors.white : Colors.black, + color: colorTheme.black, ), createdAt: TextStyle( - color: isDark - ? Colors.white.withOpacity(.5) - : Colors.black.withOpacity(.5), + color: colorTheme.black.withOpacity(.5), fontSize: 12, ), replies: TextStyle( @@ -367,9 +359,8 @@ class StreamChatThemeData { messageLinks: TextStyle( color: accentColor, ), - messageBackgroundColor: isDark ? Colors.black : Colors.white, - replyThreadColor: - isDark ? Colors.white.withAlpha(24) : Colors.black.withAlpha(24), + messageBackgroundColor: colorTheme.white, + replyThreadColor: colorTheme.black.withAlpha(24), avatarTheme: AvatarTheme( borderRadius: BorderRadius.circular(20), constraints: BoxConstraints.tightFor( @@ -404,7 +395,13 @@ class StreamChatThemeData { } } +enum TextThemeType { + light, + dark, +} + class TextTheme { + final TextThemeType type; final TextStyle title; final TextStyle headlineBold; final TextStyle headline; @@ -414,7 +411,8 @@ class TextTheme { final TextStyle footnote; final TextStyle captionBold; - TextTheme({ + TextTheme.light({ + this.type = TextThemeType.light, this.title = const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, @@ -448,6 +446,49 @@ class TextTheme { ), }); + TextTheme.dark({ + this.type = TextThemeType.dark, + this.title = const TextStyle( + fontSize: 22, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + this.headlineBold = const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + this.headline = const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.white, + ), + this.bodyBold = const TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + this.body = const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.white, + ), + this.footnoteBold = const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + color: Colors.white, + ), + this.footnote = const TextStyle( + fontSize: 12, + color: Colors.white, + ), + this.captionBold = const TextStyle( + fontSize: 10, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + }); + TextTheme copyWith({ TextStyle body, TextStyle title, @@ -458,16 +499,27 @@ class TextTheme { TextStyle footnote, TextStyle captionBold, }) { - return TextTheme( - body: body ?? this.body, - title: title ?? this.title, - headlineBold: headlineBold ?? this.headlineBold, - headline: headline ?? this.headline, - bodyBold: bodyBold ?? this.bodyBold, - footnoteBold: footnoteBold ?? this.footnoteBold, - footnote: footnote ?? this.footnote, - captionBold: captionBold ?? this.captionBold, - ); + return type == TextThemeType.light + ? TextTheme.light( + body: body ?? this.body, + title: title ?? this.title, + headlineBold: headlineBold ?? this.headlineBold, + headline: headline ?? this.headline, + bodyBold: bodyBold ?? this.bodyBold, + footnoteBold: footnoteBold ?? this.footnoteBold, + footnote: footnote ?? this.footnote, + captionBold: captionBold ?? this.captionBold, + ) + : TextTheme.dark( + body: body ?? this.body, + title: title ?? this.title, + headlineBold: headlineBold ?? this.headlineBold, + headline: headline ?? this.headline, + bodyBold: bodyBold ?? this.bodyBold, + footnoteBold: footnoteBold ?? this.footnoteBold, + footnote: footnote ?? this.footnote, + captionBold: captionBold ?? this.captionBold, + ); } } From e8afb3e9a9858ff9f373b497d040498e099e38c7 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 30 Dec 2020 14:00:42 +0530 Subject: [PATCH 14/31] Removed type --- lib/src/stream_chat_theme.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index 5e6a0398..2b6a74ae 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -401,7 +401,6 @@ enum TextThemeType { } class TextTheme { - final TextThemeType type; final TextStyle title; final TextStyle headlineBold; final TextStyle headline; @@ -412,7 +411,6 @@ class TextTheme { final TextStyle captionBold; TextTheme.light({ - this.type = TextThemeType.light, this.title = const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, @@ -447,7 +445,6 @@ class TextTheme { }); TextTheme.dark({ - this.type = TextThemeType.dark, this.title = const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, @@ -490,6 +487,7 @@ class TextTheme { }); TextTheme copyWith({ + TextThemeType type = TextThemeType.light, TextStyle body, TextStyle title, TextStyle headlineBold, From d794a40b4be70616d2db10f48d627e87238dac7c Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 30 Dec 2020 14:22:40 +0530 Subject: [PATCH 15/31] fix bg --- lib/src/stream_chat_theme.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index 2b6a74ae..407a4fcd 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -257,7 +257,7 @@ class StreamChatThemeData { primaryColor: colorTheme.white, primaryIconTheme: IconThemeData(color: colorTheme.black.withOpacity(.5)), defaultChannelImage: (context, channel) => SizedBox(), - backgroundColor: colorTheme.white, + backgroundColor: colorTheme.whiteSnow, defaultUserImage: (context, user) => Center( child: CachedNetworkImage( filterQuality: FilterQuality.high, From cb518db1a2519330f9fdb79f854e6c2675266417 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 30 Dec 2020 16:22:14 +0100 Subject: [PATCH 16/31] apply colors and ui fixes --- analysis_options.yaml | 122 ++++++++++----------- example/lib/advanced_options_page.dart | 15 +-- example/lib/choose_user_page.dart | 4 +- example/lib/customize_channel_preview.dart | 1 - example/lib/customize_message_widget.dart | 1 - example/lib/main.dart | 37 +++---- example/lib/new_chat_screen.dart | 3 - example/lib/search_text_field.dart | 2 +- example/pubspec.yaml | 2 +- lib/src/attachment_title.dart | 2 +- lib/src/back_button.dart | 4 +- lib/src/channel_bottom_sheet.dart | 6 +- lib/src/channel_image.dart | 2 +- lib/src/channel_list_view.dart | 19 ++-- lib/src/channel_preview.dart | 2 +- lib/src/chat_info_screen.dart | 23 ++-- lib/src/date_divider.dart | 5 +- lib/src/file_attachment.dart | 5 +- lib/src/giphy_attachment.dart | 4 +- lib/src/group_image.dart | 2 +- lib/src/image_actions_modal.dart | 13 ++- lib/src/image_footer.dart | 7 +- lib/src/media_list_view.dart | 13 ++- lib/src/message_actions_modal.dart | 8 +- lib/src/message_input.dart | 72 ++++++------ lib/src/message_reactions_modal.dart | 6 +- lib/src/reaction_bubble.dart | 4 +- lib/src/reaction_picker.dart | 4 +- lib/src/sending_indicator.dart | 2 +- lib/src/stream_chat.dart | 8 +- lib/src/stream_chat_theme.dart | 61 ++++------- lib/src/user_avatar.dart | 4 +- 32 files changed, 225 insertions(+), 238 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 8d6f9064..42965ec7 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,63 +1,63 @@ -include: package:pedantic/analysis_options.yaml - -analyzer: - enable-experiment: - - extension-methods - exclude: - - lib/**/*.g.dart - - example/** - -linter: - rules: - # these rules are documented on and in the same order as - # the Dart Lint rules page to make maintenance easier - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - # - always_declare_return_types - # - always_specify_types - # - annotate_overrides - # - avoid_as - - avoid_empty_else - - avoid_init_to_null - - avoid_return_types_on_setters - - avoid_web_libraries_in_flutter - - await_only_futures - - camel_case_types - - cancel_subscriptions - - close_sinks - # - comment_references # we do not presume as to what people want to reference in their dartdocs - # - constant_identifier_names # https://github.com/dart-lang/linter/issues/204 - - control_flow_in_finally - - empty_constructor_bodies - - empty_statements - - hash_and_equals - - implementation_imports - # - invariant_booleans - # - iterable_contains_unrelated_type - - library_names - # - library_prefixes - # - list_remove_unrelated_type - # - literal_only_boolean_expressions - - non_constant_identifier_names - # - one_member_abstracts - # - only_throw_errors - # - overridden_fields -# - package_api_docs - - package_names - - package_prefixed_library_names - - prefer_is_not_empty - # - prefer_mixin # https://github.com/dart-lang/language/issues/32 - - public_member_api_docs - - slash_for_doc_comments - # - sort_constructors_first - # - sort_unnamed_constructors_first - # - super_goes_last # no longer needed w/ Dart 2 - - test_types_in_equals - - throw_in_finally - # - type_annotate_public_apis # subset of always_specify_types - - type_init_formals - # - unawaited_futures - - unnecessary_brace_in_string_interps - - unnecessary_getters_setters - - unnecessary_statements +#include: package:pedantic/analysis_options.yaml +# +#analyzer: +# enable-experiment: +# - extension-methods +# exclude: +# - lib/**/*.g.dart +# - example/** +# +#linter: +# rules: +# # these rules are documented on and in the same order as +# # the Dart Lint rules page to make maintenance easier +# # https://github.com/dart-lang/linter/blob/master/example/all.yaml +# # - always_declare_return_types +# # - always_specify_types +# # - annotate_overrides +# # - avoid_as +# - avoid_empty_else +# - avoid_init_to_null +# - avoid_return_types_on_setters +# - avoid_web_libraries_in_flutter +# - await_only_futures +# - camel_case_types +# - cancel_subscriptions +# - close_sinks +# # - comment_references # we do not presume as to what people want to reference in their dartdocs +# # - constant_identifier_names # https://github.com/dart-lang/linter/issues/204 +# - control_flow_in_finally +# - empty_constructor_bodies +# - empty_statements +# - hash_and_equals +# - implementation_imports +# # - invariant_booleans +# # - iterable_contains_unrelated_type +# - library_names +# # - library_prefixes +# # - list_remove_unrelated_type +# # - literal_only_boolean_expressions +# - non_constant_identifier_names +# # - one_member_abstracts +# # - only_throw_errors +# # - overridden_fields +## - package_api_docs +# - package_names +# - package_prefixed_library_names +# - prefer_is_not_empty +# # - prefer_mixin # https://github.com/dart-lang/language/issues/32 +# - public_member_api_docs +# - slash_for_doc_comments +# # - sort_constructors_first +# # - sort_unnamed_constructors_first +# # - super_goes_last # no longer needed w/ Dart 2 +# - test_types_in_equals +# - throw_in_finally +# # - type_annotate_public_apis # subset of always_specify_types +# - type_init_formals +# # - unawaited_futures +# - unnecessary_brace_in_string_interps +# - unnecessary_getters_setters +# - unnecessary_statements - unrelated_type_equality_checks - valid_regexps diff --git a/example/lib/advanced_options_page.dart b/example/lib/advanced_options_page.dart index 803c3e72..d94514f3 100644 --- a/example/lib/advanced_options_page.dart +++ b/example/lib/advanced_options_page.dart @@ -3,12 +3,12 @@ import 'dart:io'; import 'package:example/stream_version.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; +import 'choose_user_page.dart'; import 'main.dart'; import 'notifications_service.dart'; -import 'choose_user_page.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; class AdvancedOptionsPage extends StatefulWidget { @override @@ -36,7 +36,7 @@ class _AdvancedOptionsPageState extends State { return Scaffold( resizeToAvoidBottomPadding: false, appBar: AppBar( - backgroundColor: StreamChatTheme.of(context).primaryColor, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, elevation: 1, centerTitle: true, brightness: Theme.of(context).brightness, @@ -97,7 +97,7 @@ class _AdvancedOptionsPageState extends State { fontSize: 14, fontWeight: FontWeight.bold, color: _apiKeyError != null - ? Color(0xffff3742) + ? StreamChatTheme.of(context).colorTheme.accentRed : StreamChatTheme.of(context) .colorTheme .black @@ -145,7 +145,7 @@ class _AdvancedOptionsPageState extends State { fontWeight: FontWeight.bold, fontSize: 14, color: _userIdError != null - ? Color(0xffff3742) + ? StreamChatTheme.of(context).colorTheme.accentRed : StreamChatTheme.of(context) .colorTheme .black @@ -193,7 +193,7 @@ class _AdvancedOptionsPageState extends State { fontWeight: FontWeight.bold, fontSize: 14, color: _userTokenError != null - ? Color(0xffff3742) + ? StreamChatTheme.of(context).colorTheme.accentRed : StreamChatTheme.of(context) .colorTheme .black @@ -238,7 +238,8 @@ class _AdvancedOptionsPageState extends State { child: Align( alignment: Alignment.bottomCenter, child: FlatButton( - color: StreamChatTheme.of(context).accentColor, + color: + StreamChatTheme.of(context).colorTheme.accentBlue, minWidth: double.infinity, height: 48, child: Text( diff --git a/example/lib/choose_user_page.dart b/example/lib/choose_user_page.dart index 18212253..543c944d 100644 --- a/example/lib/choose_user_page.dart +++ b/example/lib/choose_user_page.dart @@ -1,5 +1,3 @@ -import 'package:example/advanced_options_page.dart'; -import 'package:example/main.dart'; import 'package:example/stream_version.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -194,7 +192,7 @@ class ChooseUserPage extends StatelessWidget { color: StreamChatTheme.of(context).colorTheme.black, ), backgroundColor: - StreamChatTheme.of(context).secondaryColor, + StreamChatTheme.of(context).colorTheme.accentBlue, ), title: Text( 'Advanced Options', diff --git a/example/lib/customize_channel_preview.dart b/example/lib/customize_channel_preview.dart index d06cdba7..29d22a82 100644 --- a/example/lib/customize_channel_preview.dart +++ b/example/lib/customize_channel_preview.dart @@ -84,7 +84,6 @@ class ChannelListPage extends StatelessWidget { channel: channel, ), title: ChannelName( - channel: channel, textStyle: StreamChatTheme.of(context).channelPreviewTheme.title.copyWith( color: StreamChatTheme.of(context) diff --git a/example/lib/customize_message_widget.dart b/example/lib/customize_message_widget.dart index fc614125..a3713b69 100644 --- a/example/lib/customize_message_widget.dart +++ b/example/lib/customize_message_widget.dart @@ -127,7 +127,6 @@ class ChannelPage extends StatelessWidget { showTimestamp: !details.isNextUser, showUsername: !details.isNextUser, showReactions: false, - showReplyIndicator: false, ); } } diff --git a/example/lib/main.dart b/example/lib/main.dart index ef281eac..9831f29f 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,8 +1,7 @@ +import 'dart:async'; import 'dart:io'; import 'package:example/choose_user_page.dart'; -import 'package:example/new_chat_screen.dart'; -import 'package:example/new_group_chat_screen.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -13,7 +12,6 @@ import 'notifications_service.dart'; import 'routes/app_routes.dart'; import 'routes/routes.dart'; import 'search_text_field.dart'; -import 'dart:async'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -51,21 +49,20 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return StreamChat( - streamChatThemeData: StreamChatThemeData.getDefaultTheme( - ThemeData.dark(), - ), - client: client, - child: MaterialApp( - debugShowCheckedModeBanner: false, - theme: ThemeData.light(), - darkTheme: ThemeData.dark(), - //TODO change to system once dark theme is implemented - themeMode: ThemeMode.dark, - onGenerateRoute: AppRoutes.generateRoute, - initialRoute: - client.state.user == null ? Routes.CHOOSE_USER : Routes.HOME, - ), + return MaterialApp( + builder: (context, child) { + return StreamChat( + client: client, + child: child, + ); + }, + debugShowCheckedModeBanner: false, + theme: ThemeData.light(), + darkTheme: ThemeData.dark(), + themeMode: ThemeMode.dark, + onGenerateRoute: AppRoutes.generateRoute, + initialRoute: + client.state.user == null ? Routes.CHOOSE_USER : Routes.HOME, ); } } @@ -120,6 +117,7 @@ class _HomePageState extends State { Widget build(BuildContext context) { final user = StreamChat.of(context).user; return Scaffold( + backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, appBar: ChannelListHeader( onNewChatButtonTap: () { Navigator.pushNamed(context, Routes.NEW_CHAT); @@ -128,6 +126,7 @@ class _HomePageState extends State { drawer: _buildDrawer(context, user), drawerEdgeDragWidth: 50, bottomNavigationBar: BottomNavigationBar( + backgroundColor: StreamChatTheme.of(context).colorTheme.white, currentIndex: _currentIndex, items: _navBarItems, selectedLabelStyle: StreamChatTheme.of(context).textTheme.footnoteBold, @@ -429,7 +428,7 @@ class ChannelPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: StreamChatTheme.of(context).backgroundColor, + backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, appBar: ChannelHeader( showTypingIndicator: false, ), diff --git a/example/lib/new_chat_screen.dart b/example/lib/new_chat_screen.dart index 0d8b9821..fa922a81 100644 --- a/example/lib/new_chat_screen.dart +++ b/example/lib/new_chat_screen.dart @@ -5,7 +5,6 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'chips_input_text_field.dart'; import 'main.dart'; -import 'new_group_chat_screen.dart'; import 'routes/routes.dart'; class NewChatScreen extends StatefulWidget { @@ -37,8 +36,6 @@ class _NewChatScreenState extends State { bool _showUserList = true; - bool _channelExisted = false; - void _userNameListener() { if (_debounce?.isActive ?? false) _debounce.cancel(); _debounce = Timer(const Duration(milliseconds: 350), () { diff --git a/example/lib/search_text_field.dart b/example/lib/search_text_field.dart index 1054446f..8f943f11 100644 --- a/example/lib/search_text_field.dart +++ b/example/lib/search_text_field.dart @@ -24,7 +24,7 @@ class SearchTextField extends StatelessWidget { decoration: BoxDecoration( color: StreamChatTheme.of(context).colorTheme.white, border: Border.all( - color: Colors.grey.shade300, + color: StreamChatTheme.of(context).colorTheme.white, ), borderRadius: BorderRadius.circular(24), ), diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 4c5a590b..38362b26 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.95+98 +version: 1.0.97+100 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/attachment_title.dart b/lib/src/attachment_title.dart index ab9cd2da..7ed42a59 100644 --- a/lib/src/attachment_title.dart +++ b/lib/src/attachment_title.dart @@ -32,7 +32,7 @@ class AttachmentTitle extends StatelessWidget { attachment.title, overflow: TextOverflow.ellipsis, style: messageTheme.messageText.copyWith( - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context).colorTheme.accentBlue, fontWeight: FontWeight.bold, ), ), diff --git a/lib/src/back_button.dart b/lib/src/back_button.dart index d4d7c53c..52adeade 100644 --- a/lib/src/back_button.dart +++ b/lib/src/back_button.dart @@ -37,9 +37,7 @@ class StreamBackButton extends StatelessWidget { }, child: StreamSvgIcon.left( size: 24, - color: Theme.of(context).brightness == Brightness.dark - ? StreamChatTheme.of(context).colorTheme.white - : StreamChatTheme.of(context).colorTheme.black, + color: StreamChatTheme.of(context).colorTheme.black, ), ), ), diff --git a/lib/src/channel_bottom_sheet.dart b/lib/src/channel_bottom_sheet.dart index 8e65c24d..f4894b02 100644 --- a/lib/src/channel_bottom_sheet.dart +++ b/lib/src/channel_bottom_sheet.dart @@ -106,13 +106,13 @@ class ChannelBottomSheet extends StatelessWidget { ?.role)) ListTile( leading: StreamSvgIcon.delete( - color: Color(0xFFFF3742), + color: StreamChatTheme.of(context).colorTheme.accentRed, size: 24, ), title: Text( 'Delete chat', style: TextStyle( - color: Color(0xFFFF3742), + color: StreamChatTheme.of(context).colorTheme.accentRed, ), ), onTap: () async { @@ -124,7 +124,7 @@ class ChannelBottomSheet extends StatelessWidget { 'Are you sure you want to delete this conversation?', cancelText: 'CANCEL', icon: StreamSvgIcon.delete( - color: Colors.red, + color: StreamChatTheme.of(context).colorTheme.accentRed, ), ); var channel = StreamChannel.of(context).channel; diff --git a/lib/src/channel_image.dart b/lib/src/channel_image.dart index b577a442..3e436ee8 100644 --- a/lib/src/channel_image.dart +++ b/lib/src/channel_image.dart @@ -133,7 +133,7 @@ class ChannelImage extends StatelessWidget { .avatarTheme .constraints, decoration: BoxDecoration( - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context).colorTheme.accentBlue, ), child: Stack( alignment: Alignment.center, diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index 701158e1..fcbe4452 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -253,7 +253,8 @@ class _ChannelListViewState extends State .bodyBold .copyWith( color: StreamChatTheme.of(context) - .accentColor, + .colorTheme + .accentBlue, ), ), ), @@ -501,9 +502,7 @@ class _ChannelListViewState extends State ); } else { final backgroundColor = - Theme.of(context).brightness == Brightness.light - ? Color(0xffEBEBEB) - : Color(0xff141414); + StreamChatTheme.of(context).colorTheme.whiteSmoke; child = Slidable( enabled: widget.swipeToAction, actionPane: SlidableBehindActionPane(), @@ -543,7 +542,7 @@ class _ChannelListViewState extends State IconSlideAction( color: backgroundColor, iconWidget: StreamSvgIcon.delete( - color: Color(0xFFFF3742), + color: StreamChatTheme.of(context).colorTheme.accentRed, ), onTap: () async { final res = await showConfirmationDialog( @@ -554,7 +553,9 @@ class _ChannelListViewState extends State 'Are you sure you want to delete this conversation?', cancelText: 'CANCEL', icon: StreamSvgIcon.delete( - color: Color(0xFFFF3742), + color: StreamChatTheme.of(context) + .colorTheme + .accentRed, ), ); if (res == true) { @@ -564,7 +565,7 @@ class _ChannelListViewState extends State ), ], child: Container( - color: StreamChatTheme.of(context).backgroundColor, + color: StreamChatTheme.of(context).colorTheme.whiteSnow, child: ChannelPreview( onLongPress: widget.onChannelLongPress, channel: channel, @@ -621,9 +622,7 @@ class _ChannelListViewState extends State Widget _separatorBuilder(context, i) { return Container( height: 1, - color: Theme.of(context).brightness == Brightness.dark - ? StreamChatTheme.of(context).colorTheme.white.withOpacity(0.1) - : StreamChatTheme.of(context).colorTheme.black.withOpacity(0.1), + color: StreamChatTheme.of(context).colorTheme.black.withOpacity(0.08), ); } diff --git a/lib/src/channel_preview.dart b/lib/src/channel_preview.dart index 05dab603..ee01d95d 100644 --- a/lib/src/channel_preview.dart +++ b/lib/src/channel_preview.dart @@ -130,7 +130,7 @@ class ChannelPreview extends StatelessWidget { .isAfter(channel .state.lastMessage.createdAt)) .length == - (channel.memberCount ?? 0), + ((channel.memberCount ?? 0) - 1), ), ); } diff --git a/lib/src/chat_info_screen.dart b/lib/src/chat_info_screen.dart index 132f3ea3..8017cb5b 100644 --- a/lib/src/chat_info_screen.dart +++ b/lib/src/chat_info_screen.dart @@ -1,4 +1,3 @@ -import 'package:emojis/emojis.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:jiffy/jiffy.dart'; @@ -21,7 +20,7 @@ class _ChatInfoScreenState extends State { Widget build(BuildContext context) { final channel = StreamChannel.of(context).channel; return Scaffold( - backgroundColor: Color(0xFFe6e6e6), + backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, body: ListView( children: [ _buildUserHeader(), @@ -47,7 +46,7 @@ class _ChatInfoScreenState extends State { Widget _buildUserHeader() { return Material( - color: StreamChatTheme.of(context).colorTheme.white, + color: StreamChatTheme.of(context).colorTheme.whiteSnow, child: SafeArea( child: Stack( children: [ @@ -96,7 +95,9 @@ class _ChatInfoScreenState extends State { top: 21, left: 16, child: InkWell( - child: StreamSvgIcon.left(), + child: StreamSvgIcon.left( + color: StreamChatTheme.of(context).colorTheme.black, + ), onTap: () { Navigator.of(context).pop(); }, @@ -218,7 +219,7 @@ class _ChatInfoScreenState extends State { Widget _buildDeleteListTile() { return _OptionListTile( - title: 'Delete', + title: 'Delete conversation', leading: StreamSvgIcon.delete( color: Colors.red, size: 24.0, @@ -290,7 +291,7 @@ class _ChatInfoScreenState extends State { ), child: Material( shape: CircleBorder(), - color: Color(0xff20E070), + color: StreamChatTheme.of(context).colorTheme.accentGreen, ), ), color: StreamChatTheme.of(context).colorTheme.white, @@ -321,11 +322,11 @@ class _OptionListTile extends StatelessWidget { return Column( children: [ Container( - color: Color(0xffe6e6e6), + color: StreamChatTheme.of(context).colorTheme.white, height: 2.0, ), Material( - color: StreamChatTheme.of(context).colorTheme.white, + color: StreamChatTheme.of(context).colorTheme.whiteSnow, child: Container( height: 56.0, child: InkWell( @@ -409,7 +410,7 @@ class __SharedGroupsScreenState extends State<_SharedGroupsScreen> { ), ), ), - backgroundColor: StreamChatTheme.of(context).primaryColor, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, ), body: FutureBuilder>( future: chat.client.queryChannels( @@ -559,7 +560,7 @@ class _MediaDisplayScreen extends StatelessWidget { ), ), ), - backgroundColor: StreamChatTheme.of(context).primaryColor, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, ), ); } @@ -595,7 +596,7 @@ class _FileDisplayScreen extends StatelessWidget { ), ), ), - backgroundColor: StreamChatTheme.of(context).primaryColor, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, ), ); } diff --git a/lib/src/date_divider.dart b/lib/src/date_divider.dart index 9b1ba435..12070e51 100644 --- a/lib/src/date_divider.dart +++ b/lib/src/date_divider.dart @@ -40,10 +40,7 @@ class DateDivider extends StatelessWidget { child: Container( padding: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( - color: (Theme.of(context).brightness == Brightness.light - ? StreamChatTheme.of(context).colorTheme.black - : StreamChatTheme.of(context).colorTheme.white) - .withOpacity(0.5), + color: StreamChatTheme.of(context).colorTheme.black.withOpacity(0.5), borderRadius: BorderRadius.circular( 8, ), diff --git a/lib/src/file_attachment.dart b/lib/src/file_attachment.dart index 597add86..273cddf2 100644 --- a/lib/src/file_attachment.dart +++ b/lib/src/file_attachment.dart @@ -9,6 +9,7 @@ import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter/src/utils.dart'; import 'package:video_compress/video_compress.dart'; import 'package:video_player/video_player.dart'; + import 'media_utils.dart'; enum FileAttachmentType { local, online } @@ -61,7 +62,6 @@ class _FileAttachmentState extends State { child: Container( width: widget.size?.width ?? 100, height: 56.0, - margin: widget.trailing != null ? EdgeInsets.only(top: 4.0) : null, decoration: BoxDecoration( color: StreamChatTheme.of(context).colorTheme.white, borderRadius: @@ -177,7 +177,8 @@ class _FileAttachmentState extends State { width: 20.0, height: 20.0, child: CircularProgressIndicator( - backgroundColor: StreamChatTheme.of(context).accentColor, + backgroundColor: + StreamChatTheme.of(context).colorTheme.accentBlue, ), ), ); diff --git a/lib/src/giphy_attachment.dart b/lib/src/giphy_attachment.dart index 1f3bf9e6..cc1a319f 100644 --- a/lib/src/giphy_attachment.dart +++ b/lib/src/giphy_attachment.dart @@ -260,7 +260,9 @@ class GiphyAttachment extends StatelessWidget { child: Text( 'Send', style: TextStyle( - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context) + .colorTheme + .accentBlue, fontWeight: FontWeight.bold), ), ), diff --git a/lib/src/group_image.dart b/lib/src/group_image.dart index 96e25f74..f4f21b90 100644 --- a/lib/src/group_image.dart +++ b/lib/src/group_image.dart @@ -31,7 +31,7 @@ class GroupImage extends StatelessWidget { .avatarTheme .constraints, decoration: BoxDecoration( - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context).colorTheme.accentBlue, ), child: Flex( direction: Axis.vertical, diff --git a/lib/src/image_actions_modal.dart b/lib/src/image_actions_modal.dart index 45a60d60..a80dd6e7 100644 --- a/lib/src/image_actions_modal.dart +++ b/lib/src/image_actions_modal.dart @@ -1,13 +1,14 @@ import 'dart:typed_data'; import 'dart:ui'; +import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:dio/dio.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart'; -import '../stream_chat_flutter.dart'; import 'package:path_provider/path_provider.dart'; +import '../stream_chat_flutter.dart'; + class ImageActionsModal extends StatelessWidget { final Message message; final String userName; @@ -165,7 +166,9 @@ class ImageActionsModal extends StatelessWidget { 'Delete', StreamSvgIcon.delete( size: 24.0, - color: Color(0xffFF3742), + color: StreamChatTheme.of(context) + .colorTheme + .accentRed, ), () { Navigator.pop(context); @@ -175,7 +178,9 @@ class ImageActionsModal extends StatelessWidget { StreamChannel.of(context).channel.cid, ); }, - color: Color(0xffFF3742), + color: StreamChatTheme.of(context) + .colorTheme + .accentRed, ), ], ).toList(), diff --git a/lib/src/image_footer.dart b/lib/src/image_footer.dart index 762bd737..36b3d042 100644 --- a/lib/src/image_footer.dart +++ b/lib/src/image_footer.dart @@ -378,7 +378,8 @@ class _ImageFooterState extends State { 'Save to Photos', style: TextStyle( color: StreamChatTheme.of(context) - .accentColor, + .colorTheme + .accentBlue, fontWeight: FontWeight.bold, ), ), @@ -595,7 +596,9 @@ class _ImageFooterState extends State { child: Transform.rotate( angle: -pi / 2, child: StreamSvgIcon.Icon_send_message( - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context) + .colorTheme + .accentBlue, ), ), ), diff --git a/lib/src/media_list_view.dart b/lib/src/media_list_view.dart index d2b7ba69..08ebfcc7 100644 --- a/lib/src/media_list_view.dart +++ b/lib/src/media_list_view.dart @@ -1,10 +1,11 @@ +import 'dart:ui' as ui; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:photo_manager/photo_manager.dart'; import 'package:stream_chat_flutter/src/lazy_load_scroll_view.dart'; import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; -import 'dart:ui' as ui; import '../stream_chat_flutter.dart'; @@ -148,7 +149,15 @@ class _MediaListViewState extends State { void _getMedia() async { final assetList = await PhotoManager.getAssetPathList( hasAll: true, - ).then((value) => value.singleWhere((element) => element.isAll)); + ).then((value) { + if (value?.isNotEmpty == true) { + return value.singleWhere((element) => element.isAll); + } + }); + + if (assetList == null) { + return; + } final media = await assetList.getAssetListPaged(_currentPage, 50); diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 17b9a79e..3660bfec 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -69,10 +69,7 @@ class MessageActionsModal extends StatelessWidget { sigmaY: 10.8731, ), child: Container( - color: StreamChatTheme.of(context) - .colorTheme - .black - .withOpacity(0.1), + color: Colors.black.withOpacity(.2), ), ), ), @@ -146,6 +143,9 @@ class MessageActionsModal extends StatelessWidget { horizontal: 48.0, ), child: Material( + color: StreamChatTheme.of(context) + .colorTheme + .whiteSnow, clipBehavior: Clip.hardEdge, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 73f98754..47e60992 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -275,7 +275,7 @@ class MessageInputState extends State { child: Material( borderRadius: BorderRadius.circular(3), color: _sendAsDm - ? StreamChatTheme.of(context).accentColor + ? StreamChatTheme.of(context).colorTheme.accentBlue : StreamChatTheme.of(context).colorTheme.white, child: InkWell( onTap: () { @@ -337,7 +337,7 @@ class MessageInputState extends State { child: Padding( padding: const EdgeInsets.all(8.0) + EdgeInsets.only(bottom: 3.0), child: StreamSvgIcon.emptyCircleLeft( - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context).colorTheme.accentBlue, ), ), ), @@ -364,7 +364,7 @@ class MessageInputState extends State { decoration: BoxDecoration( borderRadius: BorderRadius.circular(24.0), border: Border.all( - color: Colors.grey, + color: StreamChatTheme.of(context).colorTheme.white, ), ), padding: _attachments.isEmpty ? null : EdgeInsets.all(6.0), @@ -411,8 +411,9 @@ class MessageInputState extends State { padding: const EdgeInsets.symmetric(horizontal: 8.0), child: Chip( - backgroundColor: - StreamChatTheme.of(context).accentColor, + backgroundColor: StreamChatTheme.of(context) + .colorTheme + .accentBlue, padding: EdgeInsets.zero, labelPadding: EdgeInsets.symmetric(horizontal: 9.0), @@ -612,12 +613,12 @@ class MessageInputState extends State { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), ), - color: StreamChatTheme.of(context).primaryColor, + color: StreamChatTheme.of(context).colorTheme.white, clipBehavior: Clip.antiAlias, child: Container( constraints: BoxConstraints.loose(Size.fromHeight(400)), decoration: BoxDecoration( - color: StreamChatTheme.of(context).primaryColor, + color: StreamChatTheme.of(context).colorTheme.white, borderRadius: BorderRadius.circular(8.0)), child: ListView( padding: const EdgeInsets.all(0), @@ -635,7 +636,8 @@ class MessageInputState extends State { ), child: StreamSvgIcon.lightning( color: StreamChatTheme.of(context) - .accentColor, + .colorTheme + .accentBlue, ), ), Text( @@ -671,17 +673,6 @@ class MessageInputState extends State { ], ), ), - trailing: CircleAvatar( - backgroundColor: - StreamChatTheme.of(context).accentColor, - child: StreamSvgIcon.lightning( - color: StreamChatTheme.of(context) - .colorTheme - .white, - size: 12.5, - ), - maxRadius: 12, - ), //subtitle: Text(c.description), onTap: () { _setCommand(c); @@ -708,9 +699,9 @@ class MessageInputState extends State { switch (index) { case 0: return _attachments.isEmpty - ? StreamChatTheme.of(context).accentColor + ? StreamChatTheme.of(context).colorTheme.accentBlue : (!_attachmentContainsFile - ? StreamChatTheme.of(context).accentColor + ? StreamChatTheme.of(context).colorTheme.accentBlue : StreamChatTheme.of(context) .colorTheme .black @@ -718,7 +709,7 @@ class MessageInputState extends State { break; case 1: return _attachmentContainsFile - ? StreamChatTheme.of(context).accentColor + ? StreamChatTheme.of(context).colorTheme.accentBlue : (_attachments.isEmpty ? StreamChatTheme.of(context) .colorTheme @@ -881,7 +872,8 @@ class MessageInputState extends State { child: Text( 'Add more files', style: TextStyle( - color: StreamChatTheme.of(context).accentColor, + color: + StreamChatTheme.of(context).colorTheme.accentBlue, fontWeight: FontWeight.bold, ), ), @@ -919,7 +911,8 @@ class MessageInputState extends State { 'svgs/icon_picture_empty_state.svg', package: 'stream_chat_flutter', height: 140, - color: StreamChatTheme.of(context).accentColor, + color: + StreamChatTheme.of(context).colorTheme.accentBlue, ), Center( child: Text( @@ -928,7 +921,9 @@ class MessageInputState extends State { .textTheme .bodyBold .copyWith( - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context) + .colorTheme + .accentBlue, ), ), ), @@ -1106,7 +1101,7 @@ class MessageInputState extends State { child: Card( margin: EdgeInsets.all(8.0), elevation: 2.0, - color: StreamChatTheme.of(context).primaryColor, + color: StreamChatTheme.of(context).colorTheme.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), ), @@ -1114,7 +1109,7 @@ class MessageInputState extends State { child: Container( constraints: BoxConstraints.loose(Size.fromHeight(400)), decoration: BoxDecoration( - color: StreamChatTheme.of(context).primaryColor, + color: StreamChatTheme.of(context).colorTheme.white, ), child: FutureBuilder>( future: queryMembers ?? Future.value(members), @@ -1142,7 +1137,8 @@ class MessageInputState extends State { subtitle: Text('@${m.userId}'), trailing: StreamSvgIcon.mentions( color: StreamChatTheme.of(context) - .accentColor, + .colorTheme + .accentBlue, ), onTap: () { _mentionedUsers.add(m.user); @@ -1207,7 +1203,7 @@ class MessageInputState extends State { child: Card( margin: EdgeInsets.all(8.0), elevation: 2.0, - color: StreamChatTheme.of(context).primaryColor, + color: StreamChatTheme.of(context).colorTheme.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), ), @@ -1222,7 +1218,7 @@ class MessageInputState extends State { offset: Offset(0, -4), ), ], - color: StreamChatTheme.of(context).primaryColor, + color: StreamChatTheme.of(context).colorTheme.white, ), child: ListView.builder( padding: const EdgeInsets.all(0), @@ -1238,7 +1234,9 @@ class MessageInputState extends State { padding: const EdgeInsets.symmetric(horizontal: 8.0), child: StreamSvgIcon.smile( - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context) + .colorTheme + .accentBlue, ), ), Flexible( @@ -1528,8 +1526,8 @@ class MessageInputState extends State { const EdgeInsets.only(left: 4.0, right: 8.0, top: 8.0, bottom: 8.0), child: StreamSvgIcon.lightning( color: _commandsOverlay != null - ? StreamChatTheme.of(context).accentColor - : Color(0xFF000000).withAlpha(128), + ? StreamChatTheme.of(context).colorTheme.accentBlue + : StreamChatTheme.of(context).colorTheme.grey, ), ), onTap: () async { @@ -1566,8 +1564,8 @@ class MessageInputState extends State { EdgeInsets.only(left: 8.0, right: padding, top: 8.0, bottom: 8.0), child: StreamSvgIcon.attach( color: _openFilePickerSection - ? StreamChatTheme.of(context).accentColor - : Color(0xFF000000).withAlpha(128), + ? StreamChatTheme.of(context).colorTheme.accentBlue + : StreamChatTheme.of(context).colorTheme.grey, ), ), onTap: () async { @@ -1896,7 +1894,7 @@ class MessageInputState extends State { }, child: StreamSvgIcon( assetName: _getIdleSendIcon(), - color: Colors.grey, + color: StreamChatTheme.of(context).colorTheme.greyGainsboro, height: 24.0, width: 24.0, ), @@ -1914,7 +1912,7 @@ class MessageInputState extends State { }, child: StreamSvgIcon( assetName: _getSendIcon(), - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context).colorTheme.accentBlue, height: 24.0, width: 24.0, ), diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index a6a7e54c..ba583728 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -60,10 +60,7 @@ class MessageReactionsModal extends StatelessWidget { sigmaY: 10.8731, ), child: Container( - color: StreamChatTheme.of(context) - .colorTheme - .black - .withOpacity(0.1), + color: Colors.black.withOpacity(0.2), ), ), ), @@ -140,6 +137,7 @@ class MessageReactionsModal extends StatelessWidget { horizontal: 8.0, ), child: Card( + color: StreamChatTheme.of(context).colorTheme.white, clipBehavior: Clip.hardEdge, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), diff --git a/lib/src/reaction_bubble.dart b/lib/src/reaction_bubble.dart index f7c9c142..d8f8c623 100644 --- a/lib/src/reaction_bubble.dart +++ b/lib/src/reaction_bubble.dart @@ -107,7 +107,7 @@ class ReactionBubble extends StatelessWidget { height: 16, color: (!highlightOwnReactions || reaction.user.id == StreamChat.of(context).user.id) - ? StreamChatTheme.of(context).accentColor + ? StreamChatTheme.of(context).colorTheme.accentBlue : StreamChatTheme.of(context) .colorTheme .black @@ -118,7 +118,7 @@ class ReactionBubble extends StatelessWidget { size: 16, color: (!highlightOwnReactions || reaction.user.id == StreamChat.of(context).user.id) - ? StreamChatTheme.of(context).accentColor + ? StreamChatTheme.of(context).colorTheme.accentBlue : StreamChatTheme.of(context) .colorTheme .black diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index b019ee79..5892a66d 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -89,7 +89,9 @@ class _ReactionPickerState extends State height: animations[index].value * 24.0, width: animations[index].value * 24.0, color: ownReactionIndex != -1 - ? StreamChatTheme.of(context).accentColor + ? StreamChatTheme.of(context) + .colorTheme + .accentBlue : Theme.of(context) .iconTheme .color diff --git a/lib/src/sending_indicator.dart b/lib/src/sending_indicator.dart index ce8915c3..5ec8a8a4 100644 --- a/lib/src/sending_indicator.dart +++ b/lib/src/sending_indicator.dart @@ -18,7 +18,7 @@ class SendingIndicator extends StatelessWidget { return Icon( Icons.done_all, size: 8, - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context).colorTheme.accentBlue, ); } if (message.status == MessageSendingStatus.SENT || message.status == null) { diff --git a/lib/src/stream_chat.dart b/lib/src/stream_chat.dart index 2763db37..6866b0dd 100644 --- a/lib/src/stream_chat.dart +++ b/lib/src/stream_chat.dart @@ -76,8 +76,8 @@ class StreamChatState extends State with WidgetsBindingObserver { return Theme( data: materialTheme.copyWith( primaryIconTheme: streamTheme.primaryIconTheme, - accentColor: streamTheme.accentColor, - scaffoldBackgroundColor: streamTheme.backgroundColor, + accentColor: streamTheme.colorTheme.accentBlue, + scaffoldBackgroundColor: streamTheme.colorTheme.white, ), child: widget.child, ); @@ -92,11 +92,9 @@ class StreamChatState extends State with WidgetsBindingObserver { ) { final defaultTheme = StreamChatThemeData.getDefaultTheme(Theme.of(context)); final theme = defaultTheme.copyWith( - primaryColor: themeData?.primaryColor, defaultChannelImage: themeData?.defaultChannelImage, primaryIconTheme: themeData?.primaryIconTheme, defaultUserImage: themeData?.defaultUserImage, - backgroundColor: themeData?.backgroundColor, channelTheme: defaultTheme.channelTheme.copyWith( channelHeaderTheme: defaultTheme.channelTheme.channelHeaderTheme.copyWith( @@ -151,8 +149,6 @@ class StreamChatState extends State with WidgetsBindingObserver { reactionsBackgroundColor: themeData?.otherMessageTheme?.reactionsBackgroundColor, ), - accentColor: themeData?.accentColor, - secondaryColor: themeData?.secondaryColor, channelPreviewTheme: defaultTheme.channelPreviewTheme.copyWith( avatarTheme: defaultTheme.channelPreviewTheme.avatarTheme.copyWith( constraints: themeData?.channelPreviewTheme?.avatarTheme?.constraints, diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index 407a4fcd..f6b00ef8 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -48,18 +48,6 @@ class StreamChatThemeData { /// The text themes used in the widgets final ColorTheme colorTheme; - /// Primary color of the chat widgets - final Color primaryColor; - - /// Secondary color of the chat widgets - final Color secondaryColor; - - /// Accent color of the chat widgets - final Color accentColor; - - /// Background color of the chat widgets - final Color backgroundColor; - /// Theme of the [ChannelPreview] final ChannelPreviewTheme channelPreviewTheme; @@ -88,10 +76,6 @@ class StreamChatThemeData { StreamChatThemeData({ this.textTheme, this.colorTheme, - this.primaryColor, - this.secondaryColor, - this.accentColor, - this.backgroundColor, this.channelPreviewTheme, this.channelTheme, this.otherMessageTheme, @@ -107,11 +91,7 @@ class StreamChatThemeData { final defaultTheme = getDefaultTheme(theme); return defaultTheme.copyWith( - accentColor: theme.accentColor, primaryIconTheme: theme.primaryIconTheme, - primaryColor: theme.colorScheme.primary, - secondaryColor: theme.colorScheme.secondary, - backgroundColor: theme.scaffoldBackgroundColor, channelTheme: defaultTheme.channelTheme.copyWith( inputGradient: LinearGradient(colors: [ theme.accentColor.withOpacity(.5), @@ -141,10 +121,6 @@ class StreamChatThemeData { StreamChatThemeData copyWith({ TextTheme textTheme, ColorTheme colorTheme, - Color primaryColor, - Color secondaryColor, - Color accentColor, - Color backgroundColor, ChannelPreviewTheme channelPreviewTheme, ChannelTheme channelTheme, MessageTheme ownMessageTheme, @@ -175,13 +151,9 @@ class StreamChatThemeData { white: colorTheme?.white, blueAlice: colorTheme?.blueAlice, ), - primaryColor: primaryColor ?? this.primaryColor, - secondaryColor: secondaryColor ?? this.secondaryColor, primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme, - accentColor: accentColor ?? this.accentColor, defaultChannelImage: defaultChannelImage ?? this.defaultChannelImage, defaultUserImage: defaultUserImage ?? this.defaultUserImage, - backgroundColor: backgroundColor ?? this.backgroundColor, channelPreviewTheme: this.channelPreviewTheme?.copyWith( title: channelPreviewTheme.title, subtitle: channelPreviewTheme.subtitle, @@ -252,12 +224,8 @@ class StreamChatThemeData { return StreamChatThemeData( textTheme: textTheme, colorTheme: colorTheme, - secondaryColor: Color(0xffEAEAEA), - accentColor: accentColor, - primaryColor: colorTheme.white, primaryIconTheme: IconThemeData(color: colorTheme.black.withOpacity(.5)), defaultChannelImage: (context, channel) => SizedBox(), - backgroundColor: colorTheme.whiteSnow, defaultUserImage: (context, user) => Center( child: CachedNetworkImage( filterQuality: FilterQuality.high, @@ -266,7 +234,7 @@ class StreamChatThemeData { ), ), channelPreviewTheme: ChannelPreviewTheme( - unreadCounterColor: Color(0xffff3742), + unreadCounterColor: colorTheme.accentRed, avatarTheme: AvatarTheme( borderRadius: BorderRadius.circular(20), constraints: BoxConstraints.tightFor( @@ -324,10 +292,10 @@ class StreamChatThemeData { fontWeight: FontWeight.w600, fontSize: 12, ), - messageBackgroundColor: isDark ? Color(0xff191919) : Color(0xffEAEAEA), + messageBackgroundColor: colorTheme.greyGainsboro, reactionsBackgroundColor: colorTheme.white, - reactionsBorderColor: isDark ? Color(0xff191919) : Color(0xffEAEAEA), - replyThreadColor: isDark ? Color(0xff191919) : Color(0xffEAEAEA), + reactionsBorderColor: colorTheme.greyWhisper, + replyThreadColor: colorTheme.greyWhisper, avatarTheme: AvatarTheme( borderRadius: BorderRadius.circular(20), constraints: BoxConstraints.tightFor( @@ -340,8 +308,7 @@ class StreamChatThemeData { ), ), otherMessageTheme: MessageTheme( - reactionsBackgroundColor: - isDark ? Color(0xff191919) : Color(0xffEAEAEA), + reactionsBackgroundColor: colorTheme.greyGainsboro, reactionsBorderColor: colorTheme.white, messageText: TextStyle( fontSize: 14.5, @@ -535,6 +502,9 @@ class ColorTheme { final Color whiteSnow; final Color white; final Color blueAlice; + final Color accentBlue; + final Color accentRed; + final Color accentGreen; ColorTheme.light({ this.black = const Color(0xff000000), @@ -545,6 +515,9 @@ class ColorTheme { this.whiteSnow = const Color(0xfffcfcfc), this.white = const Color(0xffffffff), this.blueAlice = const Color(0xffe9f2ff), + this.accentBlue = const Color(0xff005FFF), + this.accentRed = const Color(0xffFF3742), + this.accentGreen = const Color(0xff20E070), }); ColorTheme.dark({ @@ -556,6 +529,9 @@ class ColorTheme { this.whiteSnow = const Color(0xff070A0D), this.white = const Color(0xff101418), this.blueAlice = const Color(0xff00193D), + this.accentBlue = const Color(0xff005FFF), + this.accentRed = const Color(0xffFF3742), + this.accentGreen = const Color(0xff20E070), }); ColorTheme copyWith({ @@ -568,6 +544,9 @@ class ColorTheme { Color whiteSnow, Color white, Color blueAlice, + Color accentBlue, + Color accentRed, + Color accentGreen, }) { return type == ColorThemeType.light ? ColorTheme.light( @@ -579,6 +558,9 @@ class ColorTheme { whiteSnow: whiteSnow ?? this.whiteSnow, white: white ?? this.white, blueAlice: blueAlice ?? this.blueAlice, + accentBlue: accentBlue ?? this.accentBlue, + accentRed: accentRed ?? this.accentRed, + accentGreen: accentGreen ?? this.accentGreen, ) : ColorTheme.dark( black: black ?? this.black, @@ -589,6 +571,9 @@ class ColorTheme { whiteSnow: whiteSnow ?? this.whiteSnow, white: white ?? this.white, blueAlice: blueAlice ?? this.blueAlice, + accentBlue: accentBlue ?? this.accentBlue, + accentRed: accentRed ?? this.accentRed, + accentGreen: accentGreen ?? this.accentGreen, ); } } diff --git a/lib/src/user_avatar.dart b/lib/src/user_avatar.dart index c0b2a712..7411c994 100644 --- a/lib/src/user_avatar.dart +++ b/lib/src/user_avatar.dart @@ -47,7 +47,7 @@ class UserAvatar extends StatelessWidget { constraints: constraints ?? streamChatTheme.ownMessageTheme.avatarTheme.constraints, decoration: BoxDecoration( - color: streamChatTheme.accentColor, + color: streamChatTheme.colorTheme.accentBlue, ), child: hasImage ? CachedNetworkImage( @@ -96,7 +96,7 @@ class UserAvatar extends StatelessWidget { ), child: Material( shape: CircleBorder(), - color: Color(0xff20E070), + color: streamChatTheme.colorTheme.accentGreen, ), ), color: StreamChatTheme.of(context).colorTheme.white, From 60d9abe8fe99c6d6022baec4151cbaf7ee6568fd Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 30 Dec 2020 16:23:33 +0100 Subject: [PATCH 17/31] fix messageinput color --- example/lib/main.dart | 2 +- example/pubspec.yaml | 2 +- lib/src/message_input.dart | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 9831f29f..7c292f64 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -59,7 +59,7 @@ class MyApp extends StatelessWidget { debugShowCheckedModeBanner: false, theme: ThemeData.light(), darkTheme: ThemeData.dark(), - themeMode: ThemeMode.dark, + themeMode: ThemeMode.light, onGenerateRoute: AppRoutes.generateRoute, initialRoute: client.state.user == null ? Routes.CHOOSE_USER : Routes.HOME, diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 38362b26..268d93ce 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.97+100 +version: 1.0.98+101 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 47e60992..92d09f4b 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -364,7 +364,7 @@ class MessageInputState extends State { decoration: BoxDecoration( borderRadius: BorderRadius.circular(24.0), border: Border.all( - color: StreamChatTheme.of(context).colorTheme.white, + color: StreamChatTheme.of(context).colorTheme.greyGainsboro, ), ), padding: _attachments.isEmpty ? null : EdgeInsets.all(6.0), From 911581e0947a42e5c58958b6d439912305945403 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 30 Dec 2020 18:26:24 +0100 Subject: [PATCH 18/31] apply theme to new chat screens --- example/lib/advanced_options_page.dart | 13 +- example/lib/choose_user_page.dart | 6 +- example/lib/group_chat_details_screen.dart | 13 +- example/lib/main.dart | 203 +++++++++++---------- example/lib/new_chat_screen.dart | 6 +- example/lib/new_group_chat_screen.dart | 20 +- example/lib/search_text_field.dart | 2 +- example/pubspec.yaml | 2 +- lib/src/channel_list_view.dart | 8 +- lib/src/channel_unread_indicator.dart | 2 +- lib/src/full_screen_media.dart | 4 +- lib/src/image_actions_modal.dart | 5 +- lib/src/image_footer.dart | 8 +- lib/src/message_input.dart | 2 +- lib/src/message_list_view.dart | 6 +- lib/src/stream_chat_theme.dart | 8 + lib/src/unread_indicator.dart | 2 +- lib/src/user_item.dart | 2 + 18 files changed, 172 insertions(+), 140 deletions(-) diff --git a/example/lib/advanced_options_page.dart b/example/lib/advanced_options_page.dart index d94514f3..483e0902 100644 --- a/example/lib/advanced_options_page.dart +++ b/example/lib/advanced_options_page.dart @@ -34,6 +34,7 @@ class _AdvancedOptionsPageState extends State { @override Widget build(BuildContext context) { return Scaffold( + backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, resizeToAvoidBottomPadding: false, appBar: AppBar( backgroundColor: StreamChatTheme.of(context).colorTheme.white, @@ -107,7 +108,8 @@ class _AdvancedOptionsPageState extends State { borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), - fillColor: Color(0xffF5F5F5), + fillColor: + StreamChatTheme.of(context).colorTheme.whiteSmoke, filled: true, labelText: 'Chat API Key ${_apiKeyError != null ? ':$_apiKeyError' : ''}', @@ -155,7 +157,8 @@ class _AdvancedOptionsPageState extends State { borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), - fillColor: Color(0xffF5F5F5), + fillColor: + StreamChatTheme.of(context).colorTheme.whiteSmoke, filled: true, labelText: 'User ID ${_userIdError != null ? ':$_userIdError' : ''}', @@ -203,7 +206,8 @@ class _AdvancedOptionsPageState extends State { borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), - fillColor: Color(0xffF5F5F5), + fillColor: + StreamChatTheme.of(context).colorTheme.whiteSmoke, filled: true, labelText: 'User Token ${_userTokenError != null ? ':$_userTokenError' : ''}', @@ -228,7 +232,8 @@ class _AdvancedOptionsPageState extends State { borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), - fillColor: Color(0xffF5F5F5), + fillColor: + StreamChatTheme.of(context).colorTheme.whiteSmoke, filled: true, labelText: 'Username (optional)', ), diff --git a/example/lib/choose_user_page.dart b/example/lib/choose_user_page.dart index 543c944d..55bfa36c 100644 --- a/example/lib/choose_user_page.dart +++ b/example/lib/choose_user_page.dart @@ -58,6 +58,7 @@ class ChooseUserPage extends StatelessWidget { (_, value) => value..extraData['image'] = getRandomPicUrl(value)); return Scaffold( + backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, body: SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -191,8 +192,9 @@ class ChooseUserPage extends StatelessWidget { child: StreamSvgIcon.settings( color: StreamChatTheme.of(context).colorTheme.black, ), - backgroundColor: - StreamChatTheme.of(context).colorTheme.accentBlue, + backgroundColor: StreamChatTheme.of(context) + .colorTheme + .greyWhisper, ), title: Text( 'Advanced Options', diff --git a/example/lib/group_chat_details_screen.dart b/example/lib/group_chat_details_screen.dart index 0c49c523..b186684f 100644 --- a/example/lib/group_chat_details_screen.dart +++ b/example/lib/group_chat_details_screen.dart @@ -59,7 +59,7 @@ class _GroupChatDetailsScreenState extends State { return false; }, child: Scaffold( - backgroundColor: Color.fromRGBO(252, 252, 252, 1), + backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, appBar: AppBar( elevation: 1, backgroundColor: StreamChatTheme.of(context).colorTheme.white, @@ -151,7 +151,16 @@ class _GroupChatDetailsScreenState extends State { children: [ Container( width: double.maxFinite, - color: Colors.grey.shade50, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + StreamChatTheme.of(context).colorTheme.whiteSmoke, + StreamChatTheme.of(context).colorTheme.whiteSnow, + ], + ), + ), child: Padding( padding: const EdgeInsets.symmetric( vertical: 8, diff --git a/example/lib/main.dart b/example/lib/main.dart index 7c292f64..c51a8a4c 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -151,113 +151,116 @@ class _HomePageState extends State { Drawer _buildDrawer(BuildContext context, User user) { return Drawer( - child: SafeArea( - child: Padding( - padding: EdgeInsets.only( - top: MediaQuery.of(context).viewPadding.top + 8, - ), - child: Column( - children: [ - Padding( - padding: const EdgeInsets.only( - bottom: 20.0, - left: 8, + child: Container( + color: StreamChatTheme.of(context).colorTheme.white, + child: SafeArea( + child: Padding( + padding: EdgeInsets.only( + top: MediaQuery.of(context).viewPadding.top + 8, + ), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only( + bottom: 20.0, + left: 8, + ), + child: Row( + children: [ + UserAvatar( + user: user, + showOnlineStatus: false, + constraints: BoxConstraints.tight(Size.fromRadius(20)), + ), + Padding( + padding: const EdgeInsets.only(left: 16.0), + child: Text( + user.name, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), ), - child: Row( - children: [ - UserAvatar( - user: user, - showOnlineStatus: false, - constraints: BoxConstraints.tight(Size.fromRadius(20)), + ListTile( + leading: StreamSvgIcon.penWrite( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), + ), + onTap: () { + Navigator.popAndPushNamed( + context, + Routes.NEW_CHAT, + ); + }, + title: Text( + 'New direct message', + style: TextStyle( + fontSize: 14.5, ), - Padding( - padding: const EdgeInsets.only(left: 16.0), - child: Text( - user.name, + ), + ), + ListTile( + leading: StreamSvgIcon.contacts( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), + ), + onTap: () { + Navigator.popAndPushNamed( + context, + Routes.NEW_GROUP_CHAT, + ); + }, + title: Text( + 'New group', + style: TextStyle( + fontSize: 14.5, + ), + ), + ), + Expanded( + child: Container( + alignment: Alignment.bottomCenter, + child: ListTile( + onTap: () async { + Navigator.pop(context); + + final secureStorage = FlutterSecureStorage(); + await secureStorage.deleteAll(); + + StreamChat.of(context).client.disconnect( + clearUser: true, + ); + + await Navigator.pushReplacementNamed( + context, + Routes.CHOOSE_USER, + ); + }, + leading: StreamSvgIcon.user( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), + ), + title: Text( + 'Sign out', style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, + fontSize: 14.5, ), ), ), - ], - ), - ), - ListTile( - leading: StreamSvgIcon.penWrite( - color: StreamChatTheme.of(context) - .colorTheme - .black - .withOpacity(.5), - ), - onTap: () { - Navigator.popAndPushNamed( - context, - Routes.NEW_CHAT, - ); - }, - title: Text( - 'New direct message', - style: TextStyle( - fontSize: 14.5, ), ), - ), - ListTile( - leading: StreamSvgIcon.contacts( - color: StreamChatTheme.of(context) - .colorTheme - .black - .withOpacity(.5), - ), - onTap: () { - Navigator.popAndPushNamed( - context, - Routes.NEW_GROUP_CHAT, - ); - }, - title: Text( - 'New group', - style: TextStyle( - fontSize: 14.5, - ), - ), - ), - Expanded( - child: Container( - alignment: Alignment.bottomCenter, - child: ListTile( - onTap: () async { - Navigator.pop(context); - - final secureStorage = FlutterSecureStorage(); - await secureStorage.deleteAll(); - - StreamChat.of(context).client.disconnect( - clearUser: true, - ); - - await Navigator.pushReplacementNamed( - context, - Routes.CHOOSE_USER, - ); - }, - leading: StreamSvgIcon.user( - color: StreamChatTheme.of(context) - .colorTheme - .black - .withOpacity(.5), - ), - title: Text( - 'Sign out', - style: TextStyle( - fontSize: 14.5, - ), - ), - ), - ), - ), - ], + ], + ), ), ), ), @@ -488,7 +491,7 @@ class ThreadPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color.fromRGBO(252, 252, 252, 1), + backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, appBar: ThreadHeader( parent: parent, ), diff --git a/example/lib/new_chat_screen.dart b/example/lib/new_chat_screen.dart index fa922a81..4cebb564 100644 --- a/example/lib/new_chat_screen.dart +++ b/example/lib/new_chat_screen.dart @@ -119,7 +119,7 @@ class _NewChatScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color.fromRGBO(252, 252, 252, 1), + backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, appBar: AppBar( elevation: 0, backgroundColor: StreamChatTheme.of(context).colorTheme.white, @@ -215,7 +215,9 @@ class _NewChatScreenState extends State { StreamNeumorphicButton( child: Center( child: StreamSvgIcon.contacts( - color: Color(0xFF006CFF), + color: StreamChatTheme.of(context) + .colorTheme + .accentBlue, size: 24, ), ), diff --git a/example/lib/new_group_chat_screen.dart b/example/lib/new_group_chat_screen.dart index a00dbc07..d094f5c0 100644 --- a/example/lib/new_group_chat_screen.dart +++ b/example/lib/new_group_chat_screen.dart @@ -3,9 +3,8 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; -import 'group_chat_details_screen.dart'; -import 'search_text_field.dart'; import 'routes/routes.dart'; +import 'search_text_field.dart'; class NewGroupChatScreen extends StatefulWidget { @override @@ -53,7 +52,7 @@ class _NewGroupChatScreenState extends State { Widget build(BuildContext context) { return SafeArea( child: Scaffold( - backgroundColor: Color.fromRGBO(252, 252, 252, 1), + backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, body: NestedScrollView( floatHeaderSlivers: true, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { @@ -142,18 +141,17 @@ class _NewGroupChatScreenState extends State { .white, shape: BoxShape.circle, border: Border.all( - color: Colors.grey.shade100, - ), - ), - child: Padding( - padding: const EdgeInsets.all(0.0), - child: StreamSvgIcon.close( color: StreamChatTheme.of(context) .colorTheme - .black, - size: 24, + .whiteSnow, ), ), + child: StreamSvgIcon.close( + color: StreamChatTheme.of(context) + .colorTheme + .black, + size: 24, + ), ), ), ) diff --git a/example/lib/search_text_field.dart b/example/lib/search_text_field.dart index 8f943f11..ff34e8a9 100644 --- a/example/lib/search_text_field.dart +++ b/example/lib/search_text_field.dart @@ -24,7 +24,7 @@ class SearchTextField extends StatelessWidget { decoration: BoxDecoration( color: StreamChatTheme.of(context).colorTheme.white, border: Border.all( - color: StreamChatTheme.of(context).colorTheme.white, + color: StreamChatTheme.of(context).colorTheme.greyWhisper, ), borderRadius: BorderRadius.circular(24), ), diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 268d93ce..c5162d86 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.98+101 +version: 1.0.99+102 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index 95d60f9c..e33f7e1f 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -336,8 +336,8 @@ class _ChannelListViewState extends State Shimmer _buildLoadingItem() { if (widget.crossAxisCount > 1) { return Shimmer.fromColors( - baseColor: Color(0xffE5E5E5), - highlightColor: Color(0xffffffff), + baseColor: StreamChatTheme.of(context).colorTheme.greyGainsboro, + highlightColor: StreamChatTheme.of(context).colorTheme.whiteSmoke, child: Column( children: [ SizedBox( @@ -367,8 +367,8 @@ class _ChannelListViewState extends State ); } else { return Shimmer.fromColors( - baseColor: Color(0xffE5E5E5), - highlightColor: StreamChatTheme.of(context).colorTheme.white, + baseColor: StreamChatTheme.of(context).colorTheme.greyGainsboro, + highlightColor: StreamChatTheme.of(context).colorTheme.whiteSmoke, child: ListTile( leading: Container( decoration: BoxDecoration( diff --git a/lib/src/channel_unread_indicator.dart b/lib/src/channel_unread_indicator.dart index 10a2aa48..8080b1e9 100644 --- a/lib/src/channel_unread_indicator.dart +++ b/lib/src/channel_unread_indicator.dart @@ -36,7 +36,7 @@ class ChannelUnreadIndicator extends StatelessWidget { '${snapshot.data}', style: TextStyle( fontSize: 11, - color: StreamChatTheme.of(context).colorTheme.white, + color: Colors.white, ), ), ), diff --git a/lib/src/full_screen_media.dart b/lib/src/full_screen_media.dart index e6ecb64f..7e3f3d7d 100644 --- a/lib/src/full_screen_media.dart +++ b/lib/src/full_screen_media.dart @@ -100,9 +100,7 @@ class _FullScreenMediaState extends State .channelTheme .channelHeaderTheme .color, - end: StreamChatTheme.of(context) - .colorTheme - .black) + end: Colors.black) .lerp(_controller.value), ), onTapUp: (a, b, c) { diff --git a/lib/src/image_actions_modal.dart b/lib/src/image_actions_modal.dart index a80dd6e7..168581c0 100644 --- a/lib/src/image_actions_modal.dart +++ b/lib/src/image_actions_modal.dart @@ -35,7 +35,7 @@ class ImageActionsModal extends StatelessWidget { begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ - StreamChatTheme.of(context).colorTheme.black.withOpacity(0.8), + Colors.black.withOpacity(0.8), Colors.transparent, ], stops: [0.0, 0.4], @@ -110,10 +110,10 @@ class ImageActionsModal extends StatelessWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), - color: Color(0xffe5e5e5), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: ListTile.divideTiles( + color: StreamChatTheme.of(context).colorTheme.greyWhisper, context: context, tiles: [ _buildButton( @@ -203,6 +203,7 @@ class ImageActionsModal extends StatelessWidget { ); return Material( + color: StreamChatTheme.of(context).colorTheme.white, child: InkWell( onTap: onTap, child: ListTile( diff --git a/lib/src/image_footer.dart b/lib/src/image_footer.dart index fa74ff9d..eff6110a 100644 --- a/lib/src/image_footer.dart +++ b/lib/src/image_footer.dart @@ -5,10 +5,10 @@ import 'dart:typed_data'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:chewie/chewie.dart'; +import 'package:dio/dio.dart'; import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:dio/dio.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart'; import 'package:path_provider/path_provider.dart'; import 'package:stream_chat/stream_chat.dart'; @@ -300,7 +300,7 @@ class _ImageFooterState extends State { limit: 25, ), filter: { - if (_searchController.text.isNotEmpty) + if (_channelNameQuery?.trim()?.isNotEmpty == true) 'name': { r'$autocomplete': _channelNameQuery, }, @@ -311,7 +311,7 @@ class _ImageFooterState extends State { sort: [ SortOption( 'name', - direction: 1, + direction: SortOption.ASC, ), ], emptyBuilder: (_) { @@ -356,6 +356,8 @@ class _ImageFooterState extends State { color: StreamChatTheme.of(context).colorTheme.white, height: 48.0, child: Material( + color: + StreamChatTheme.of(context).colorTheme.white, child: InkWell( onTap: () async { var url = widget diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 92d09f4b..c6f1d297 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -1343,7 +1343,7 @@ class MessageInputState extends State { StreamChatTheme.of(context) .colorTheme .black - .withOpacity(0.2), + .withOpacity(0.6), maxRadius: 12.0, child: StreamSvgIcon.close( color: StreamChatTheme.of(context) diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index fd31b996..3c6484dc 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -345,10 +345,12 @@ class _MessageListViewState extends State { begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ - Color(0XFFF7F7F7), StreamChatTheme.of(context) .colorTheme .whiteSmoke, + StreamChatTheme.of(context) + .colorTheme + .whiteSnow, ], ), ), @@ -844,7 +846,7 @@ class _MessageListViewState extends State { } if (event.message.user.id == streamChannel.channel.client.state.user.id) { WidgetsBinding.instance.addPostFrameCallback((_) { - _scrollController.jumpTo( + _scrollController?.jumpTo( index: 0, ); }); diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index f6b00ef8..60e37b80 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -381,33 +381,41 @@ class TextTheme { this.title = const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, + color: Colors.black, ), this.headlineBold = const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, + color: Colors.black, ), this.headline = const TextStyle( fontSize: 16, fontWeight: FontWeight.w500, + color: Colors.black, ), this.bodyBold = const TextStyle( fontSize: 14, fontWeight: FontWeight.bold, + color: Colors.black, ), this.body = const TextStyle( fontSize: 14, fontWeight: FontWeight.w500, + color: Colors.black, ), this.footnoteBold = const TextStyle( fontSize: 12, fontWeight: FontWeight.w500, + color: Colors.black, ), this.footnote = const TextStyle( fontSize: 12, + color: Colors.black, ), this.captionBold = const TextStyle( fontSize: 10, fontWeight: FontWeight.bold, + color: Colors.black, ), }); diff --git a/lib/src/unread_indicator.dart b/lib/src/unread_indicator.dart index 42e6c78d..c9f42fad 100644 --- a/lib/src/unread_indicator.dart +++ b/lib/src/unread_indicator.dart @@ -34,7 +34,7 @@ class UnreadIndicator extends StatelessWidget { '${snapshot.data}', style: TextStyle( fontSize: 11, - color: StreamChatTheme.of(context).colorTheme.white, + color: Colors.white, ), ), ), diff --git a/lib/src/user_item.dart b/lib/src/user_item.dart index 49a6d5e3..50a8b7a7 100644 --- a/lib/src/user_item.dart +++ b/lib/src/user_item.dart @@ -74,6 +74,8 @@ class UserItem extends StatelessWidget { ), trailing: selected ? CircleAvatar( + backgroundColor: + StreamChatTheme.of(context).colorTheme.accentBlue, child: StreamSvgIcon.check( size: 20, color: StreamChatTheme.of(context).colorTheme.white, From 4f9b75392f8342368d670aab40a4cfdb42aafeb5 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 30 Dec 2020 18:30:52 +0100 Subject: [PATCH 19/31] apply theme to group info screen --- lib/src/chat_info_screen.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/chat_info_screen.dart b/lib/src/chat_info_screen.dart index 8017cb5b..3a9c25ee 100644 --- a/lib/src/chat_info_screen.dart +++ b/lib/src/chat_info_screen.dart @@ -384,7 +384,7 @@ class __SharedGroupsScreenState extends State<_SharedGroupsScreen> { var chat = StreamChat.of(context); return Scaffold( - backgroundColor: StreamChatTheme.of(context).colorTheme.white, + backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, appBar: AppBar( brightness: Theme.of(context).brightness, elevation: 1, @@ -521,7 +521,8 @@ class __SharedGroupsScreenState extends State<_SharedGroupsScreen> { ), Container( height: 1.0, - color: Color(0xffe6e6e6), + color: + StreamChatTheme.of(context).colorTheme.black.withOpacity(.08), ), ], ); From 7f696236c446b4038d2e06eae08318bbc9af9ac0 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 31 Dec 2020 13:05:32 +0530 Subject: [PATCH 20/31] [Message Widget] Add message error state Signed-off-by: Sahil Kumar --- lib/src/message_actions_modal.dart | 30 +++++- lib/src/message_widget.dart | 147 +++++++++++------------------ lib/src/sending_indicator.dart | 9 -- lib/src/stream_svg_icon.dart | 25 +++++ 4 files changed, 107 insertions(+), 104 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 8013a8b3..2d482c0e 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -22,6 +22,7 @@ class MessageActionsModal extends StatelessWidget { final bool showDeleteMessage; final bool showCopyMessage; final bool showEditMessage; + final bool showResendMessage; final bool showReply; final bool reverse; final ShapeBorder messageShape; @@ -37,6 +38,7 @@ class MessageActionsModal extends StatelessWidget { this.onThreadTap, this.showCopyMessage = true, this.showReply = true, + this.showResendMessage = true, this.showUserAvatar = DisplayWidget.show, this.editMessageInputBuilder, this.messageShape, @@ -159,6 +161,8 @@ class MessageActionsModal extends StatelessWidget { message.status == null) && message.parentId == null) _buildReplyButton(context), + if (showResendMessage) + _buildResendMessage(context), if (showEditMessage) _buildEditMessage(context), if (showDeleteMessage) @@ -183,9 +187,10 @@ class MessageActionsModal extends StatelessWidget { } Widget _buildDeleteButton(BuildContext context) { + final isDeleteFailed = message.status == MessageSendingStatus.FAILED_DELETE; return ListTile( title: Text( - 'Delete message', + isDeleteFailed ? 'Retry deleting message' : 'Delete message', style: Theme.of(context).textTheme.headline6.copyWith(color: Colors.red), ), @@ -234,6 +239,29 @@ class MessageActionsModal extends StatelessWidget { ); } + Widget _buildResendMessage(BuildContext context) { + final isUpdateFailed = message.status == MessageSendingStatus.FAILED_UPDATE; + return ListTile( + title: Text( + isUpdateFailed ? 'Resend edited message' : 'Resend', + style: Theme.of(context).textTheme.headline6, + ), + leading: StreamSvgIcon.circle_up( + color: StreamChatTheme.of(context).accentColor, + ), + onTap: () { + Navigator.pop(context); + final client = StreamChat.of(context).client; + final channel = StreamChannel.of(context).channel; + if (isUpdateFailed) { + client.updateMessage(message, channel.cid); + } else { + channel.sendMessage(message); + } + }, + ); + } + void _showEditBottomSheet(BuildContext context) { final channel = StreamChannel.of(context).channel; showModalBottomSheet( diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 9d81d679..ee165057 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -114,6 +114,9 @@ class MessageWidget extends StatefulWidget { /// Used in [MessageReactionsModal] and [MessageActionsModal] final bool showReactionPickerIndicator; + /// If true the widget will show the resendMessage indicator + final bool showResendMessage; + final List readList; /// If true show the users username next to the timestamp of the message @@ -157,6 +160,7 @@ class MessageWidget extends StatefulWidget { this.editMessageInputBuilder, this.textBuilder, Map customAttachmentBuilders, + this.showResendMessage = true, this.readList, this.padding, this.textPadding = const EdgeInsets.symmetric( @@ -229,6 +233,16 @@ class _MessageWidgetState extends State { bool get showInChannel => widget.showInChannelIndicator && widget.message?.showInChannel == true; + bool get isSendFailed => widget.message.status == MessageSendingStatus.FAILED; + + bool get isUpdateFailed => + widget.message.status == MessageSendingStatus.FAILED_UPDATE; + + bool get isDeleteFailed => + widget.message.status == MessageSendingStatus.FAILED_DELETE; + + bool get isFailedState => isSendFailed || isUpdateFailed || isDeleteFailed; + @override Widget build(BuildContext context) { var leftPadding = widget.showUserAvatar != DisplayWidget.gone @@ -298,9 +312,7 @@ class _MessageWidgetState extends State { ) : EdgeInsets.zero, child: (widget.message.isDeleted && - widget.message.status != - MessageSendingStatus - .FAILED_DELETE) + !isFailedState) ? Transform( alignment: Alignment.center, transform: Matrix4.rotationY( @@ -377,6 +389,21 @@ class _MessageWidgetState extends State { ), ), ), + if (isFailedState) + Positioned( + left: widget.reverse ? -6 : null, + right: widget.reverse ? null : -6, + bottom: 0, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + ), + child: StreamSvgIcon.error( + size: 20, + ), + ), + ), ], ), ), @@ -619,14 +646,19 @@ class _MessageWidgetState extends State { message: widget.message, editMessageInputBuilder: widget.editMessageInputBuilder, onThreadTap: widget.onThreadTap, - showCopyMessage: widget.message.text?.trim()?.isNotEmpty == true, + showResendMessage: + widget.showResendMessage && (isSendFailed || isUpdateFailed), + showCopyMessage: !isFailedState && + widget.message.text?.trim()?.isNotEmpty == true, showEditMessage: widget.showEditMessage && + !isDeleteFailed && widget.message.attachments ?.any((element) => element.type == 'giphy') != true, showReactions: widget.showReactions, - showReply: - widget.showThreadReplyIndicator && widget.onThreadTap != null, + showReply: widget.showThreadReplyIndicator && + !isFailedState && + widget.onThreadTap != null, ), ); }); @@ -729,7 +761,6 @@ class _MessageWidgetState extends State { final attachmentShape = widget.attachmentShape ?? widget.shape ?? _getDefaultShape(context); return GestureDetector( - onTap: () => retryMessage(context), onLongPress: () => onLongPress(context), child: Material( color: _getBackgroundColor(), @@ -744,17 +775,7 @@ class _MessageWidgetState extends State { child: Transform( transform: Matrix4.rotationY(widget.reverse ? pi : 0), alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - getFailedMessageWidget( - context, - padding: const EdgeInsets.all(8.0), - ), - attachmentWidget, - ], - ), + child: attachmentWidget, ), ), ), @@ -809,55 +830,6 @@ class _MessageWidgetState extends State { ), ); - Widget getFailedMessageWidget( - BuildContext context, { - EdgeInsetsGeometry padding, - }) { - Widget failedWidget; - if (widget.message.status == MessageSendingStatus.FAILED) { - failedWidget = Text( - 'MESSAGE FAILED · CLICK TO TRY AGAIN', - style: widget.messageTheme.messageText.copyWith( - color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(.5) - : Colors.black.withOpacity(.5), - fontSize: 11, - ), - ); - } - if (widget.message.status == MessageSendingStatus.FAILED_UPDATE) { - failedWidget = Text( - 'MESSAGE UPDATE FAILED · CLICK TO TRY AGAIN', - style: widget.messageTheme.messageText.copyWith( - color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(.5) - : Colors.black.withOpacity(.5), - fontSize: 11, - ), - ); - } - if (widget.message.status == MessageSendingStatus.FAILED_DELETE) { - failedWidget = Text( - 'MESSAGE DELETE FAILED · CLICK TO TRY AGAIN', - style: widget.messageTheme.messageText.copyWith( - color: Theme.of(context).brightness == Brightness.dark - ? Colors.white.withOpacity(.5) - : Colors.black.withOpacity(.5), - fontSize: 11, - ), - ); - } - - if (failedWidget != null) { - return Padding( - padding: padding ?? EdgeInsets.zero, - child: failedWidget, - ); - } - - return SizedBox(); - } - Widget _buildTextBubble(BuildContext context) { Widget child = Transform( transform: Matrix4.rotationY(widget.reverse ? pi : 0), @@ -867,26 +839,20 @@ class _MessageWidgetState extends State { children: [ Padding( padding: widget.textPadding, - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - getFailedMessageWidget(context), - widget.textBuilder != null - ? widget.textBuilder(context, widget.message) - : MessageText( - onLinkTap: widget.onLinkTap, - message: widget.message, - onMentionTap: widget.onMentionTap, - messageTheme: isOnlyEmoji - ? widget.messageTheme.copyWith( - messageText: - widget.messageTheme.messageText.copyWith( - fontSize: 40, - )) - : widget.messageTheme, - ), - ], - ), + child: widget.textBuilder != null + ? widget.textBuilder(context, widget.message) + : MessageText( + onLinkTap: widget.onLinkTap, + message: widget.message, + onMentionTap: widget.onMentionTap, + messageTheme: isOnlyEmoji + ? widget.messageTheme.copyWith( + messageText: + widget.messageTheme.messageText.copyWith( + fontSize: 40, + )) + : widget.messageTheme, + ), ), if (widget.message.attachments ?.any((element) => element.ogScrapeUrl != null) == @@ -896,7 +862,6 @@ class _MessageWidgetState extends State { ), ); return GestureDetector( - onTap: () => retryMessage(context), onLongPress: () => onLongPress(context), child: child, ); @@ -907,12 +872,6 @@ class _MessageWidgetState extends State { widget.message.text.characters.every((c) => Emoji.byChar(c) != null); Color _getBackgroundColor() { - if ((widget.message.status == MessageSendingStatus.FAILED || - widget.message.status == MessageSendingStatus.FAILED_UPDATE || - widget.message.status == MessageSendingStatus.FAILED_DELETE)) { - return Color(0xffd0021B).withOpacity(.1); - } - if (widget.message.attachments ?.any((element) => element.ogScrapeUrl != null) == true) { diff --git a/lib/src/sending_indicator.dart b/lib/src/sending_indicator.dart index ce8915c3..6006f62d 100644 --- a/lib/src/sending_indicator.dart +++ b/lib/src/sending_indicator.dart @@ -35,15 +35,6 @@ class SendingIndicator extends StatelessWidget { size: 8, ); } - if (message.status == MessageSendingStatus.FAILED || - message.status == MessageSendingStatus.FAILED_UPDATE || - message.status == MessageSendingStatus.FAILED_DELETE) { - return Icon( - Icons.error_outline, - size: 8, - ); - } - return SizedBox(); } } diff --git a/lib/src/stream_svg_icon.dart b/lib/src/stream_svg_icon.dart index 98ce0f8e..c75e9327 100644 --- a/lib/src/stream_svg_icon.dart +++ b/lib/src/stream_svg_icon.dart @@ -757,4 +757,29 @@ class StreamSvgIcon extends StatelessWidget { height: size, ); } + + factory StreamSvgIcon.error({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_error.svg', + color: color, + width: size, + height: size, + ); + } + + + factory StreamSvgIcon.circle_up({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_circle_up.svg', + color: color, + width: size, + height: size, + ); + } } From 168630fcade71ecf7f457bb038e46a478eae5222 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 31 Dec 2020 13:11:05 +0530 Subject: [PATCH 21/31] flutter format Signed-off-by: Sahil Kumar --- lib/src/stream_svg_icon.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/stream_svg_icon.dart b/lib/src/stream_svg_icon.dart index c75e9327..63eef658 100644 --- a/lib/src/stream_svg_icon.dart +++ b/lib/src/stream_svg_icon.dart @@ -770,7 +770,6 @@ class StreamSvgIcon extends StatelessWidget { ); } - factory StreamSvgIcon.circle_up({ double size, Color color, From ef0bad11929623a533efc4dff5ca29bd42d80506 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 31 Dec 2020 14:18:12 +0530 Subject: [PATCH 22/31] [Message Widget] Modify read indicator as per new design v2 Signed-off-by: Sahil Kumar --- lib/src/channel_preview.dart | 6 ++++- lib/src/message_widget.dart | 45 ++++++++++++++++++++++------------ lib/src/sending_indicator.dart | 16 ++++++------ 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/lib/src/channel_preview.dart b/lib/src/channel_preview.dart index 5f58e254..d6623544 100644 --- a/lib/src/channel_preview.dart +++ b/lib/src/channel_preview.dart @@ -122,7 +122,11 @@ class ChannelPreview extends StatelessWidget { padding: const EdgeInsets.only(right: 4.0), child: SendingIndicator( message: channel.state.lastMessage, - allRead: channel.state.read + size: StreamChatTheme.of(context) + .channelPreviewTheme + .lastMessageAt + .fontSize, + isMessageRead: channel.state.read .where((element) => element.lastRead .isAfter(channel .state.lastMessage.createdAt)) diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index ee165057..226e98c0 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -228,7 +228,7 @@ class _MessageWidgetState extends State { bool get showTimeStamp => widget.message.createdAt != null && widget.showTimestamp; - bool get showReadList => widget.readList?.isNotEmpty == true; + bool get isMessageRead => widget.readList?.isNotEmpty == true; bool get showInChannel => widget.showInChannelIndicator && widget.message?.showInChannel == true; @@ -488,14 +488,14 @@ class _MessageWidgetState extends State { children.addAll([ if (showSendingIndicator) _buildSendingIndicator(), - if (showReadList) - SizedBox.fromSize( - size: Size((widget.readList.length * 10.0) + 10, 17), - child: Padding( - padding: const EdgeInsets.only(left: 4.0), - child: _buildReadIndicator(), - ), - ), + // if (showReadList) + // SizedBox.fromSize( + // size: Size((widget.readList.length * 10.0) + 10, 17), + // child: Padding( + // padding: const EdgeInsets.only(left: 4.0), + // child: _buildReadIndicator(), + // ), + // ), if (showThreadReplyIndicator) InkWell( onTap: widget.onThreadTap != null ? onThreadTap : null, @@ -798,14 +798,27 @@ class _MessageWidgetState extends State { } Widget _buildSendingIndicator() { - return Container( - height: widget.messageTheme.createdAt.fontSize + 2, - width: widget.messageTheme.createdAt.fontSize + 2, - child: SendingIndicator( - message: widget.message, - allRead: widget.allRead, - ), + final style = widget.messageTheme.createdAt; + Widget child = SendingIndicator( + message: widget.message, + isMessageRead: isMessageRead, + size: style.fontSize, ); + if (isMessageRead) { + child = Row( + children: [ + Text( + widget.readList.length.toString(), + style: style.copyWith( + color: StreamChatTheme.of(context).accentColor, + ), + ), + SizedBox(width: 2), + child, + ], + ); + } + return child; } Widget _buildUserAvatar() => Transform( diff --git a/lib/src/sending_indicator.dart b/lib/src/sending_indicator.dart index 6006f62d..34492167 100644 --- a/lib/src/sending_indicator.dart +++ b/lib/src/sending_indicator.dart @@ -4,27 +4,29 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Used to show the sending status of the message class SendingIndicator extends StatelessWidget { final Message message; - final bool allRead; + final bool isMessageRead; + final double size; const SendingIndicator({ Key key, this.message, - this.allRead = false, + this.isMessageRead = false, + this.size = 12, }) : super(key: key); @override Widget build(BuildContext context) { - if (allRead) { + if (isMessageRead) { return Icon( - Icons.done_all, - size: 8, + Icons.done_all_rounded, + size: size, color: StreamChatTheme.of(context).accentColor, ); } if (message.status == MessageSendingStatus.SENT || message.status == null) { return Icon( Icons.done, - size: 8, + size: size, color: IconTheme.of(context).color.withOpacity(0.5), ); } @@ -32,7 +34,7 @@ class SendingIndicator extends StatelessWidget { message.status == MessageSendingStatus.UPDATING) { return Icon( Icons.access_time, - size: 8, + size: size, ); } return SizedBox(); From db932d4e32210681a652e61488b03260a34a60a6 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Thu, 31 Dec 2020 09:51:30 +0100 Subject: [PATCH 23/31] use system theme --- example/ios/Flutter/.last_build_id | 2 +- example/lib/main.dart | 2 +- example/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/example/ios/Flutter/.last_build_id b/example/ios/Flutter/.last_build_id index e72273c3..f57e1e1f 100644 --- a/example/ios/Flutter/.last_build_id +++ b/example/ios/Flutter/.last_build_id @@ -1 +1 @@ -13a41b8138c4868054e44b5158f3bdd6 \ No newline at end of file +c770358a10272b4ee1cdc2eb432445f6 \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index c51a8a4c..0de1fbe1 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -59,7 +59,7 @@ class MyApp extends StatelessWidget { debugShowCheckedModeBanner: false, theme: ThemeData.light(), darkTheme: ThemeData.dark(), - themeMode: ThemeMode.light, + themeMode: ThemeMode.system, onGenerateRoute: AppRoutes.generateRoute, initialRoute: client.state.user == null ? Routes.CHOOSE_USER : Routes.HOME, diff --git a/example/pubspec.yaml b/example/pubspec.yaml index c5162d86..481bdd37 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.99+102 +version: 1.0.100+103 environment: sdk: ">=2.2.2 <3.0.0" From a8171f7314116ba6bd1f0334afa57dc965e1a332 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Thu, 31 Dec 2020 09:57:21 +0100 Subject: [PATCH 24/31] ui fixes --- example/lib/group_chat_details_screen.dart | 1 + example/lib/new_chat_screen.dart | 1 + example/lib/new_group_chat_screen.dart | 9 +++++---- example/pubspec.yaml | 2 +- lib/src/attachment_error.dart | 6 +++--- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/example/lib/group_chat_details_screen.dart b/example/lib/group_chat_details_screen.dart index b186684f..19674332 100644 --- a/example/lib/group_chat_details_screen.dart +++ b/example/lib/group_chat_details_screen.dart @@ -61,6 +61,7 @@ class _GroupChatDetailsScreenState extends State { child: Scaffold( backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, appBar: AppBar( + brightness: Theme.of(context).brightness, elevation: 1, backgroundColor: StreamChatTheme.of(context).colorTheme.white, leading: const StreamBackButton(), diff --git a/example/lib/new_chat_screen.dart b/example/lib/new_chat_screen.dart index 4cebb564..ddebe848 100644 --- a/example/lib/new_chat_screen.dart +++ b/example/lib/new_chat_screen.dart @@ -121,6 +121,7 @@ class _NewChatScreenState extends State { return Scaffold( backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, appBar: AppBar( + brightness: Theme.of(context).brightness, elevation: 0, backgroundColor: StreamChatTheme.of(context).colorTheme.white, leading: const StreamBackButton(), diff --git a/example/lib/new_group_chat_screen.dart b/example/lib/new_group_chat_screen.dart index d094f5c0..a81f2f51 100644 --- a/example/lib/new_group_chat_screen.dart +++ b/example/lib/new_group_chat_screen.dart @@ -50,14 +50,15 @@ class _NewGroupChatScreenState extends State { @override Widget build(BuildContext context) { - return SafeArea( - child: Scaffold( - backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, - body: NestedScrollView( + return Scaffold( + backgroundColor: StreamChatTheme.of(context).colorTheme.whiteSnow, + body: SafeArea( + child: NestedScrollView( floatHeaderSlivers: true, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return [ SliverAppBar( + brightness: Theme.of(context).brightness, pinned: true, forceElevated: true, elevation: 1, diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 481bdd37..0fca32a4 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.100+103 +version: 1.0.101+104 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/attachment_error.dart b/lib/src/attachment_error.dart index 0b51e59c..d24423c4 100644 --- a/lib/src/attachment_error.dart +++ b/lib/src/attachment_error.dart @@ -25,12 +25,12 @@ class AttachmentError extends StatelessWidget { return Center( child: Container( width: size?.width, - height: size?.height, - color: Color(0xffd0021B).withOpacity(.1), + height: size?.height ?? 200, + color: StreamChatTheme.of(context).colorTheme.accentRed.withOpacity(.1), child: Center( child: Icon( Icons.error_outline, - color: StreamChatTheme.of(context).colorTheme.white, + color: StreamChatTheme.of(context).colorTheme.black, ), ), ), From f011bf32fc46b917c06e9ef51280d754147e1aec Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Thu, 31 Dec 2020 10:24:25 +0100 Subject: [PATCH 25/31] apply theme to rest of the sdk --- example/lib/group_chat_details_screen.dart | 4 +++- example/lib/main.dart | 7 +++++-- example/lib/new_group_chat_screen.dart | 3 ++- example/pubspec.yaml | 2 +- lib/src/channel_image.dart | 11 +++++++---- lib/src/channel_info.dart | 2 +- lib/src/channel_list_header.dart | 4 ++-- lib/src/channel_list_view.dart | 5 ++++- lib/src/file_attachment.dart | 3 ++- lib/src/group_image.dart | 5 +++-- lib/src/message_list_view.dart | 5 ++++- lib/src/message_search_list_view.dart | 5 ++++- lib/src/message_widget.dart | 2 +- lib/src/url_attachment.dart | 4 +++- lib/src/user_avatar.dart | 5 +++-- lib/src/user_list_view.dart | 5 ++++- lib/src/utils.dart | 3 ++- 17 files changed, 51 insertions(+), 24 deletions(-) diff --git a/example/lib/group_chat_details_screen.dart b/example/lib/group_chat_details_screen.dart index 19674332..03b4877b 100644 --- a/example/lib/group_chat_details_screen.dart +++ b/example/lib/group_chat_details_screen.dart @@ -121,7 +121,9 @@ class _GroupChatDetailsScreenState extends State { padding: const EdgeInsets.all(0), icon: StreamSvgIcon.check( size: 24, - color: _isGroupNameEmpty ? Colors.grey : Color(0xFF006CFF), + color: _isGroupNameEmpty + ? Colors.grey + : StreamChatTheme.of(context).colorTheme.accentBlue, ), onPressed: _isGroupNameEmpty ? null diff --git a/example/lib/main.dart b/example/lib/main.dart index 0de1fbe1..8d436614 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -25,7 +25,7 @@ void main() async { logLevel: Level.INFO, showLocalNotification: (!kIsWeb && Platform.isAndroid) ? showLocalNotification : null, - persistenceEnabled: true, + persistenceEnabled: false, ); if (userId != null) { @@ -456,7 +456,10 @@ class ChannelPage extends StatelessWidget { right: 0, child: Container( alignment: Alignment.centerLeft, - color: Color(0xffFCFCFC).withOpacity(.9), + color: StreamChatTheme.of(context) + .colorTheme + .whiteSnow + .withOpacity(.9), child: TypingIndicator( alignment: Alignment.centerLeft, padding: const EdgeInsets.symmetric( diff --git a/example/lib/new_group_chat_screen.dart b/example/lib/new_group_chat_screen.dart index a81f2f51..505db69c 100644 --- a/example/lib/new_group_chat_screen.dart +++ b/example/lib/new_group_chat_screen.dart @@ -76,7 +76,8 @@ class _NewGroupChatScreenState extends State { if (_selectedUsers.isNotEmpty) IconButton( icon: StreamSvgIcon.arrow_right( - color: Color(0xFF006CFF), + color: + StreamChatTheme.of(context).colorTheme.accentBlue, ), onPressed: () async { final updatedList = await Navigator.pushNamed( diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 0fca32a4..944be796 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.101+104 +version: 1.0.102+105 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/channel_image.dart b/lib/src/channel_image.dart index efd8700e..2f5862f3 100644 --- a/lib/src/channel_image.dart +++ b/lib/src/channel_image.dart @@ -53,7 +53,7 @@ class ChannelImage extends StatelessWidget { this.showOnlineStatus = true, this.borderRadius, this.selected = false, - this.selectionColor = const Color(0xFF006CFF), + this.selectionColor, this.selectionThickness = 4, }) : super(key: key); @@ -105,7 +105,8 @@ class ChannelImage extends StatelessWidget { .constraints, onTap: onTap != null ? (_) => onTap() : null, selected: selected, - selectionColor: selectionColor, + selectionColor: selectionColor ?? + StreamChatTheme.of(context).colorTheme.accentBlue, selectionThickness: selectionThickness, ); }); @@ -127,7 +128,8 @@ class ChannelImage extends StatelessWidget { .constraints, onTap: onTap, selected: selected, - selectionColor: selectionColor, + selectionColor: selectionColor ?? + StreamChatTheme.of(context).colorTheme.accentBlue, selectionThickness: selectionThickness, ); } @@ -197,7 +199,8 @@ class ChannelImage extends StatelessWidget { .ownMessageTheme .avatarTheme .constraints, - color: selectionColor, + color: selectionColor ?? + StreamChatTheme.of(context).colorTheme.accentBlue, child: Padding( padding: EdgeInsets.all(selectionThickness), child: child, diff --git a/lib/src/channel_info.dart b/lib/src/channel_info.dart index eda58f43..b1ab568d 100644 --- a/lib/src/channel_info.dart +++ b/lib/src/channel_info.dart @@ -134,7 +134,7 @@ class ChannelInfo extends StatelessWidget { child: Text( 'Try Again', style: textStyle.copyWith( - color: Color(0xFF006CFF), + color: StreamChatTheme.of(context).colorTheme.accentBlue, ), ), ), diff --git a/lib/src/channel_list_header.dart b/lib/src/channel_list_header.dart index 09156d4c..34f3cc76 100644 --- a/lib/src/channel_list_header.dart +++ b/lib/src/channel_list_header.dart @@ -99,7 +99,7 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { var color; switch (status) { case ConnectionStatus.connected: - color = Color(0xFF006CFF); + color = StreamChatTheme.of(context).colorTheme.accentBlue; break; case ConnectionStatus.connecting: color = Colors.grey; @@ -205,7 +205,7 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { .copyWith( fontSize: 16, fontWeight: FontWeight.bold, - color: Color(0xFF006CFF), + color: StreamChatTheme.of(context).colorTheme.accentBlue, ), ), ), diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index e33f7e1f..777fae57 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -684,7 +684,10 @@ class _ChannelListViewState extends State builder: (context, snapshot) { if (snapshot.hasError) { return Container( - color: Color(0xffd0021B).withAlpha(26), + color: StreamChatTheme.of(context) + .colorTheme + .accentRed + .withOpacity(.2), child: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: Center( diff --git a/lib/src/file_attachment.dart b/lib/src/file_attachment.dart index 273cddf2..92139530 100644 --- a/lib/src/file_attachment.dart +++ b/lib/src/file_attachment.dart @@ -67,7 +67,8 @@ class _FileAttachmentState extends State { borderRadius: widget.trailing != null ? BorderRadius.circular(16.0) : null, border: widget.trailing != null - ? Border.fromBorderSide(BorderSide(color: Color(0xFFE6E6E6))) + ? Border.fromBorderSide(BorderSide( + color: StreamChatTheme.of(context).colorTheme.greyWhisper)) : null, ), child: Row( diff --git a/lib/src/group_image.dart b/lib/src/group_image.dart index fc45aa59..4cfd655a 100644 --- a/lib/src/group_image.dart +++ b/lib/src/group_image.dart @@ -11,7 +11,7 @@ class GroupImage extends StatelessWidget { this.onTap, this.borderRadius, this.selected = false, - this.selectionColor = const Color(0xFF006CFF), + this.selectionColor, this.selectionThickness = 4, }) : super(key: key); @@ -110,7 +110,8 @@ class GroupImage extends StatelessWidget { streamChatTheme.ownMessageTheme.avatarTheme.borderRadius) + BorderRadius.circular(selectionThickness), child: Container( - color: selectionColor, + color: selectionColor ?? + StreamChatTheme.of(context).colorTheme.accentBlue, height: 64.0, width: 64.0, child: Padding( diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 3c6484dc..a85beb0a 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -592,7 +592,10 @@ class _MessageListViewState extends State { builder: (context, snapshot) { if (snapshot.hasError) { return Container( - color: Color(0xffd0021B).withAlpha(26), + color: StreamChatTheme.of(context) + .colorTheme + .accentRed + .withOpacity(.2), child: Center( child: Text('Error loading messages'), ), diff --git a/lib/src/message_search_list_view.dart b/lib/src/message_search_list_view.dart index 989234b3..d59ae4a0 100644 --- a/lib/src/message_search_list_view.dart +++ b/lib/src/message_search_list_view.dart @@ -152,7 +152,10 @@ class _MessageSearchListViewState extends State { builder: (context, snapshot) { if (snapshot.hasError) { return Container( - color: Color(0xffd0021B).withAlpha(26), + color: StreamChatTheme.of(context) + .colorTheme + .accentRed + .withOpacity(.2), child: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: Center( diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 7b185f97..acc8f03d 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -919,7 +919,7 @@ class _MessageWidgetState extends State { if ((widget.message.status == MessageSendingStatus.FAILED || widget.message.status == MessageSendingStatus.FAILED_UPDATE || widget.message.status == MessageSendingStatus.FAILED_DELETE)) { - return Color(0xffd0021B).withOpacity(.1); + return StreamChatTheme.of(context).colorTheme.accentRed.withOpacity(.1); } if (widget.message.attachments diff --git a/lib/src/url_attachment.dart b/lib/src/url_attachment.dart index c655880d..1909fc33 100644 --- a/lib/src/url_attachment.dart +++ b/lib/src/url_attachment.dart @@ -55,7 +55,9 @@ class UrlAttachment extends StatelessWidget { .textTheme .bodyBold .copyWith( - color: Color(0xFF006CFF), + color: StreamChatTheme.of(context) + .colorTheme + .accentBlue, ), ), ), diff --git a/lib/src/user_avatar.dart b/lib/src/user_avatar.dart index fb9a832a..688eff77 100644 --- a/lib/src/user_avatar.dart +++ b/lib/src/user_avatar.dart @@ -16,7 +16,7 @@ class UserAvatar extends StatelessWidget { this.borderRadius, this.onlineIndicatorAlignment = Alignment.topRight, this.selected = false, - this.selectionColor = const Color(0xFF006CFF), + this.selectionColor, this.selectionThickness = 4, }) : super(key: key); @@ -70,7 +70,8 @@ class UserAvatar extends StatelessWidget { child: Container( constraints: constraints ?? streamChatTheme.ownMessageTheme.avatarTheme.constraints, - color: selectionColor, + color: selectionColor ?? + StreamChatTheme.of(context).colorTheme.accentBlue, child: Padding( padding: EdgeInsets.all(selectionThickness), child: avatar, diff --git a/lib/src/user_list_view.dart b/lib/src/user_list_view.dart index 1108c24d..35692841 100644 --- a/lib/src/user_list_view.dart +++ b/lib/src/user_list_view.dart @@ -453,7 +453,10 @@ class _UserListViewState extends State builder: (context, snapshot) { if (snapshot.hasError) { return Container( - color: Color(0xffd0021B).withAlpha(26), + color: StreamChatTheme.of(context) + .colorTheme + .accentRed + .withOpacity(.2), child: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: Center( diff --git a/lib/src/utils.dart b/lib/src/utils.dart index f1f1b68a..32681d6e 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -55,7 +55,8 @@ Future showConfirmationDialog( height: 36.0, ), Container( - color: Color(0xffe6e6e6), + color: + StreamChatTheme.of(context).colorTheme.black.withOpacity(.08), height: 1.0, ), Row( From cf31f704d41d02381a9387b42240535712324ac8 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Thu, 31 Dec 2020 10:53:56 +0100 Subject: [PATCH 26/31] hide bubbles --- lib/src/message_actions_modal.dart | 5 ++++- lib/src/message_reactions_modal.dart | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 2d482c0e..2cd66807 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -119,7 +119,10 @@ class MessageActionsModal extends StatelessWidget { showUserAvatar: showUserAvatar, showTimestamp: false, translateUserAvatar: false, - showReactionPickerIndicator: true, + showReactionPickerIndicator: showReactions && + (message.status == + MessageSendingStatus.SENT || + message.status == null), showInChannelIndicator: false, showSendingIndicator: DisplayWidget.gone, shape: messageShape, diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index e5043e62..ed3038fd 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -110,7 +110,10 @@ class MessageReactionsModal extends StatelessWidget { translateUserAvatar: false, showSendingIndicator: DisplayWidget.gone, shape: messageShape, - showReactionPickerIndicator: true, + showReactionPickerIndicator: showReactions && + (message.status == + MessageSendingStatus.SENT || + message.status == null), ), ), ); From dde32437c82d1339c5b1a085ec62fd0200aafbb9 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Thu, 31 Dec 2020 11:10:03 +0100 Subject: [PATCH 27/31] fix messageinput send --- lib/src/message_actions_modal.dart | 3 ++- lib/src/message_input.dart | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 2cd66807..d2d25333 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -332,9 +332,10 @@ class MessageActionsModal extends StatelessWidget { ? editMessageInputBuilder(context, message) : MessageInput( editMessage: message, - onMessageSent: (_) { + preMessageSending: (m) { FocusScope.of(context).unfocus(); Navigator.pop(context); + return m; }, ), ), diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 8436d526..654aa068 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -1976,10 +1976,6 @@ class MessageInputState extends State { return sendingFuture.then((resp) { if (widget.onMessageSent != null) { widget.onMessageSent(resp.message); - } else { - if (widget.editMessage != null) { - Navigator.pop(context); - } } }); } From ab6a741183dfb6f14600019219f7b568a45f5cb1 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 31 Dec 2020 15:59:51 +0530 Subject: [PATCH 28/31] [Message Widget] fix error icon stack position Signed-off-by: Sahil Kumar --- lib/src/message_widget.dart | 47 +++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 226e98c0..9834e097 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -243,6 +243,12 @@ class _MessageWidgetState extends State { bool get isFailedState => isSendFailed || isUpdateFailed || isDeleteFailed; + bool get showBottomRow => + showThreadReplyIndicator || + showUsername || + showTimeStamp || + showInChannel; + @override Widget build(BuildContext context) { var leftPadding = widget.showUserAvatar != DisplayWidget.gone @@ -267,6 +273,7 @@ class _MessageWidgetState extends State { mainAxisSize: MainAxisSize.min, children: [ Stack( + clipBehavior: Clip.none, alignment: AlignmentDirectional.bottomStart, children: [ Column( @@ -389,39 +396,29 @@ class _MessageWidgetState extends State { ), ), ), - if (isFailedState) - Positioned( - left: widget.reverse ? -6 : null, - right: widget.reverse ? null : -6, - bottom: 0, - child: Container( - decoration: BoxDecoration( - color: Colors.white, - shape: BoxShape.circle, - ), - child: StreamSvgIcon.error( - size: 20, - ), - ), - ), ], ), ), ), ], ), - if (showThreadReplyIndicator || - showUsername || - showTimeStamp || - showInChannel) - SizedBox(height: 20.0), + if (showBottomRow) SizedBox(height: 20.0), ], ), - if (showThreadReplyIndicator || - showUsername || - showTimeStamp || - showInChannel) - _buildBottomRow(leftPadding) + if (showBottomRow) _buildBottomRow(leftPadding), + if (isFailedState) + Positioned( + left: widget.reverse ? -3 : null, + right: widget.reverse ? null : -9, + bottom: showBottomRow ? 20 : 0, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + ), + child: StreamSvgIcon.error(size: 20), + ), + ), ], ), ], From f59db043c1c05c80b2ea6de493104d0c37e4150a Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 31 Dec 2020 16:15:16 +0530 Subject: [PATCH 29/31] minor ui fixes Signed-off-by: Sahil Kumar --- lib/src/message_actions_modal.dart | 4 +--- lib/src/message_reactions_modal.dart | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index d2d25333..fad73d93 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -130,9 +130,7 @@ class MessageActionsModal extends StatelessWidget { ), ); }), - SizedBox( - height: 8, - ), + SizedBox(height: 8), TweenAnimationBuilder( tween: Tween(begin: 0.0, end: 1.0), duration: Duration(milliseconds: 300), diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index ed3038fd..a8701f4d 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -110,6 +110,7 @@ class MessageReactionsModal extends StatelessWidget { translateUserAvatar: false, showSendingIndicator: DisplayWidget.gone, shape: messageShape, + showInChannelIndicator: false, showReactionPickerIndicator: showReactions && (message.status == MessageSendingStatus.SENT || @@ -118,9 +119,7 @@ class MessageReactionsModal extends StatelessWidget { ), ); }), - SizedBox( - height: 16, - ), + SizedBox(height: 8), if (message.latestReactions?.isNotEmpty == true) _buildReactionCard(context), ], From 88ba902ee381aedab092fb7526b1e692398d97b7 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 31 Dec 2020 16:38:20 +0530 Subject: [PATCH 30/31] merge fixes Signed-off-by: Sahil Kumar --- lib/src/message_actions_modal.dart | 2 +- lib/src/message_widget.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index c5903ce3..adfe3cdd 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -251,7 +251,7 @@ class MessageActionsModal extends StatelessWidget { style: Theme.of(context).textTheme.headline6, ), leading: StreamSvgIcon.circle_up( - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context).colorTheme.accentBlue, ), onTap: () { Navigator.pop(context); diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index afb3261d..61c6bf5c 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -816,7 +816,7 @@ class _MessageWidgetState extends State { Text( widget.readList.length.toString(), style: style.copyWith( - color: StreamChatTheme.of(context).accentColor, + color: StreamChatTheme.of(context).colorTheme.accentBlue, ), ), SizedBox(width: 2), From da3f9e7daeb225dcf80d8cdde38988d6de8bdea5 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Thu, 31 Dec 2020 12:11:57 +0100 Subject: [PATCH 31/31] apply theme to edit message --- example/lib/main.dart | 2 +- lib/src/message_actions_modal.dart | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 8d436614..018b2cab 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -59,7 +59,7 @@ class MyApp extends StatelessWidget { debugShowCheckedModeBanner: false, theme: ThemeData.light(), darkTheme: ThemeData.dark(), - themeMode: ThemeMode.system, + themeMode: ThemeMode.dark, onGenerateRoute: AppRoutes.generateRoute, initialRoute: client.state.user == null ? Routes.CHOOSE_USER : Routes.HOME, diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index adfe3cdd..3bdce507 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -273,6 +273,7 @@ class MessageActionsModal extends StatelessWidget { elevation: 2, clipBehavior: Clip.hardEdge, isScrollControlled: true, + backgroundColor: StreamChatTheme.of(context).colorTheme.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(32),