From 06b2929c37c256dea3e907c3e7e7c7a3bec72d09 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 2 Dec 2020 13:19:31 +0100 Subject: [PATCH] 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)), ), ),