From cc52c78487f38f2705f49964525db86951e00fcf Mon Sep 17 00:00:00 2001 From: Freek van de Ven Date: Wed, 12 Feb 2025 22:38:02 +0100 Subject: [PATCH] feat: remove chatService and chatOptions from widget parameters to use ChatScope instead --- .../chat_detail/chat_detail_screen.dart | 25 +++-- .../lib/src/screens/chat_profile_screen.dart | 21 ++-- .../lib/src/screens/chat_screen.dart | 83 +++++----------- .../src/screens/creation/new_chat_screen.dart | 37 +++---- .../creation/new_group_chat_overview.dart | 98 +++++++++---------- .../creation/new_group_chat_screen.dart | 48 +++------ .../creation/widgets/search_field.dart | 10 +- .../screens/creation/widgets/user_list.dart | 17 ++-- 8 files changed, 128 insertions(+), 211 deletions(-) diff --git a/packages/flutter_chat/lib/src/screens/chat_detail/chat_detail_screen.dart b/packages/flutter_chat/lib/src/screens/chat_detail/chat_detail_screen.dart index 74db28b..92d8479 100644 --- a/packages/flutter_chat/lib/src/screens/chat_detail/chat_detail_screen.dart +++ b/packages/flutter_chat/lib/src/screens/chat_detail/chat_detail_screen.dart @@ -3,7 +3,6 @@ import "dart:typed_data"; import "package:chat_repository_interface/chat_repository_interface.dart"; import "package:flutter/material.dart"; -import "package:flutter_chat/src/config/chat_options.dart"; import "package:flutter_chat/src/config/screen_types.dart"; import "package:flutter_chat/src/screens/chat_detail/widgets/default_message_builder.dart"; import "package:flutter_chat/src/screens/creation/widgets/image_picker.dart"; @@ -91,7 +90,7 @@ class _ChatDetailScreenState extends State { @override Widget build(BuildContext context) { var chatScope = ChatScope.of(context); - var chatOptions = chatScope.options; + var options = chatScope.options; var appBar = _AppBar( chatTitle: chatTitle, onPressChatTitle: widget.onPressChatTitle, @@ -113,14 +112,14 @@ class _ChatDetailScreenState extends State { return () => chatScope.popHandler.remove(widget.onExit!); }); - if (chatOptions.builders.baseScreenBuilder == null) { + if (options.builders.baseScreenBuilder == null) { return Scaffold( appBar: appBar, body: body, ); } - return chatOptions.builders.baseScreenBuilder!.call( + return options.builders.baseScreenBuilder!.call( context, widget.mapScreenType, appBar, @@ -305,7 +304,6 @@ class _BodyState extends State<_Body> { widget.onUploadImage, ), onMessageSubmit: widget.onMessageSubmit, - options: options, ), ], ), @@ -347,7 +345,6 @@ class _ChatBottom extends StatefulWidget { const _ChatBottom({ required this.chat, required this.onMessageSubmit, - required this.options, this.onPressSelectImage, }); @@ -360,8 +357,6 @@ class _ChatBottom extends StatefulWidget { /// The chat model. final ChatModel chat; - final ChatOptions options; - @override State<_ChatBottom> createState() => _ChatBottomState(); } @@ -373,6 +368,8 @@ class _ChatBottomState extends State<_ChatBottom> { @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; var theme = Theme.of(context); _textEditingController.addListener(() { @@ -409,12 +406,12 @@ class _ChatBottomState extends State<_ChatBottom> { onPressed: widget.onPressSelectImage, icon: Icon( Icons.image_outlined, - color: widget.options.iconEnabledColor, + color: options.iconEnabledColor, ), ), IconButton( - disabledColor: widget.options.iconDisabledColor, - color: widget.options.iconEnabledColor, + disabledColor: options.iconDisabledColor, + color: options.iconEnabledColor, onPressed: onClickSendMessage, icon: const Icon( Icons.send_rounded, @@ -446,7 +443,7 @@ class _ChatBottomState extends State<_ChatBottom> { vertical: 0, horizontal: 30, ), - hintText: widget.options.translations.messagePlaceholder, + hintText: options.translations.messagePlaceholder, hintStyle: theme.textTheme.bodyMedium, fillColor: Colors.white, filled: true, @@ -467,11 +464,11 @@ class _ChatBottomState extends State<_ChatBottom> { ), child: SizedBox( height: 45, - child: widget.options.builders.messageInputBuilder?.call( + child: options.builders.messageInputBuilder?.call( context, _textEditingController, messageSendButtons, - widget.options.translations, + options.translations, ) ?? defaultInputField, ), diff --git a/packages/flutter_chat/lib/src/screens/chat_profile_screen.dart b/packages/flutter_chat/lib/src/screens/chat_profile_screen.dart index 9bd130e..a651b82 100644 --- a/packages/flutter_chat/lib/src/screens/chat_profile_screen.dart +++ b/packages/flutter_chat/lib/src/screens/chat_profile_screen.dart @@ -1,6 +1,5 @@ import "package:chat_repository_interface/chat_repository_interface.dart"; import "package:flutter/material.dart"; -import "package:flutter_chat/src/config/chat_options.dart"; import "package:flutter_chat/src/config/screen_types.dart"; import "package:flutter_chat/src/util/scope.dart"; import "package:flutter_hooks/flutter_hooks.dart"; @@ -39,8 +38,6 @@ class ChatProfileScreen extends HookWidget { Widget build(BuildContext context) { var chatScope = ChatScope.of(context); var options = chatScope.options; - var service = chatScope.service; - var userId = chatScope.userId; useEffect(() { chatScope.popHandler.add(onExit); @@ -50,13 +47,9 @@ class ChatProfileScreen extends HookWidget { var appBar = _AppBar( user: userModel, chat: chatModel, - options: options, ); var body = _Body( - currentUser: userId, - options: options, - service: service, user: userModel, chat: chatModel, onTapUser: onTapUser, @@ -83,15 +76,15 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget { const _AppBar({ required this.user, required this.chat, - required this.options, }); final UserModel? user; final ChatModel? chat; - final ChatOptions options; @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; var theme = Theme.of(context); return AppBar( iconTheme: theme.appBarTheme.iconTheme, @@ -111,25 +104,23 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget { class _Body extends StatelessWidget { const _Body({ - required this.options, - required this.service, required this.user, required this.chat, required this.onPressStartChat, required this.onTapUser, - required this.currentUser, }); - final ChatOptions options; - final ChatService service; final UserModel? user; final ChatModel? chat; final Function(String)? onTapUser; final Function(String)? onPressStartChat; - final String currentUser; @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; + var service = chatScope.service; + var currentUser = chatScope.userId; var theme = Theme.of(context); var chatUserDisplay = Wrap( diff --git a/packages/flutter_chat/lib/src/screens/chat_screen.dart b/packages/flutter_chat/lib/src/screens/chat_screen.dart index b01fd8e..1a346b0 100644 --- a/packages/flutter_chat/lib/src/screens/chat_screen.dart +++ b/packages/flutter_chat/lib/src/screens/chat_screen.dart @@ -1,6 +1,5 @@ import "package:chat_repository_interface/chat_repository_interface.dart"; import "package:flutter/material.dart"; -import "package:flutter_chat/src/config/chat_options.dart"; import "package:flutter_chat/src/config/chat_translations.dart"; import "package:flutter_chat/src/config/screen_types.dart"; import "package:flutter_chat/src/services/date_formatter.dart"; @@ -36,7 +35,6 @@ class ChatScreen extends HookWidget { Widget build(BuildContext context) { var chatScope = ChatScope.of(context); var options = chatScope.options; - var service = chatScope.service; useEffect(() { if (onExit == null) return null; @@ -46,13 +44,8 @@ class ChatScreen extends HookWidget { if (options.builders.baseScreenBuilder == null) { return Scaffold( - appBar: _AppBar( - chatOptions: options, - chatService: service, - ), + appBar: const _AppBar(), body: _Body( - chatOptions: options, - chatService: service, onPressChat: onPressChat, onPressStartChat: onPressStartChat, onDeleteChat: onDeleteChat, @@ -63,13 +56,8 @@ class ChatScreen extends HookWidget { return options.builders.baseScreenBuilder!.call( context, mapScreenType, - _AppBar( - chatOptions: options, - chatService: service, - ), + const _AppBar(), _Body( - chatOptions: options, - chatService: service, onPressChat: onPressChat, onPressStartChat: onPressStartChat, onDeleteChat: onDeleteChat, @@ -79,17 +67,14 @@ class ChatScreen extends HookWidget { } class _AppBar extends StatelessWidget implements PreferredSizeWidget { - const _AppBar({ - required this.chatOptions, - required this.chatService, - }); - - final ChatOptions chatOptions; - final ChatService chatService; + const _AppBar(); @override Widget build(BuildContext context) { - var translations = chatOptions.translations; + var chatScope = ChatScope.of(context); + var service = chatScope.service; + var options = chatScope.options; + var translations = options.translations; var theme = Theme.of(context); return AppBar( @@ -98,7 +83,7 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget { ), actions: [ StreamBuilder( - stream: chatService.getUnreadMessagesCount(), + stream: service.getUnreadMessagesCount(), builder: (BuildContext context, snapshot) => Align( alignment: Alignment.centerRight, child: Visibility( @@ -125,15 +110,11 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget { class _Body extends StatefulWidget { const _Body({ - required this.chatOptions, - required this.chatService, required this.onPressChat, required this.onDeleteChat, this.onPressStartChat, }); - final ChatOptions chatOptions; - final ChatService chatService; final Function(ChatModel chat) onPressChat; final Function()? onPressStartChat; final Function(ChatModel) onDeleteChat; @@ -148,7 +129,10 @@ class _BodyState extends State<_Body> { @override Widget build(BuildContext context) { - var translations = widget.chatOptions.translations; + var chatScope = ChatScope.of(context); + var options = chatScope.options; + var service = chatScope.service; + var translations = options.translations; var theme = Theme.of(context); return Column( children: [ @@ -159,17 +143,16 @@ class _BodyState extends State<_Body> { padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 28), children: [ StreamBuilder?>( - stream: widget.chatService.getChats(), + stream: service.getChats(), builder: (BuildContext context, snapshot) { if (snapshot.connectionState == ConnectionState.done && (snapshot.data?.isEmpty ?? true) || (snapshot.data != null && snapshot.data!.isEmpty)) { - if (widget.chatOptions.onNoChats != null && - !_hasCalledOnNoChats) { + if (options.onNoChats != null && !_hasCalledOnNoChats) { _hasCalledOnNoChats = true; // Set the flag to true WidgetsBinding.instance.addPostFrameCallback((_) async { // ignore: avoid_dynamic_calls - await widget.chatOptions.onNoChats!.call(); + await options.onNoChats!.call(); }); } return Center( @@ -195,8 +178,8 @@ class _BodyState extends State<_Body> { builder: (context) => !chat.canBeDeleted ? Dismissible( confirmDismiss: (_) async { - await widget.chatOptions.builders - .deleteChatDialogBuilder + await options + .builders.deleteChatDialogBuilder ?.call(context, chat) ?? _deleteDialog( chat, @@ -244,16 +227,12 @@ class _BodyState extends State<_Body> { chat.id, ), child: _ChatItem( - service: widget.chatService, chat: chat, - chatOptions: widget.chatOptions, onPressChat: widget.onPressChat, ), ) : _ChatItem( - service: widget.chatService, chat: chat, - chatOptions: widget.chatOptions, onPressChat: widget.onPressChat, ), ), @@ -267,7 +246,7 @@ class _BodyState extends State<_Body> { ), ), if (widget.onPressStartChat != null) - widget.chatOptions.builders.newChatButtonBuilder?.call( + options.builders.newChatButtonBuilder?.call( context, widget.onPressStartChat!, translations, @@ -300,33 +279,29 @@ class _BodyState extends State<_Body> { class _ChatItem extends StatelessWidget { const _ChatItem({ required this.chat, - required this.chatOptions, - required this.service, required this.onPressChat, }); final ChatModel chat; - final ChatOptions chatOptions; - final ChatService service; final Function(ChatModel chat) onPressChat; @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; var dateFormatter = DateFormatter( - options: chatOptions, + options: options, ); var theme = Theme.of(context); return InkWell( onTap: () { onPressChat(chat); }, - child: chatOptions.builders.chatRowContainerBuilder?.call( + child: options.builders.chatRowContainerBuilder?.call( context, _ChatListItem( chat: chat, - options: chatOptions, dateFormatter: dateFormatter, - chatService: service, ), ) ?? DecoratedBox( @@ -343,9 +318,7 @@ class _ChatItem extends StatelessWidget { padding: const EdgeInsets.all(12), child: _ChatListItem( chat: chat, - options: chatOptions, dateFormatter: dateFormatter, - chatService: service, ), ), ), @@ -356,25 +329,23 @@ class _ChatItem extends StatelessWidget { class _ChatListItem extends StatelessWidget { const _ChatListItem({ required this.chat, - required this.options, required this.dateFormatter, - required this.chatService, }); final ChatModel chat; - final ChatOptions options; final DateFormatter dateFormatter; - final ChatService chatService; @override Widget build(BuildContext context) { var scope = ChatScope.of(context); + var service = scope.service; + var options = scope.options; var currentUserId = scope.userId; var translations = options.translations; if (chat.isGroupChat) { return StreamBuilder( stream: chat.lastMessage != null - ? chatService.getMessage( + ? service.getMessage( chatId: chat.id, messageId: chat.lastMessage!, ) @@ -432,7 +403,7 @@ class _ChatListItem extends StatelessWidget { ); return StreamBuilder( - stream: chatService.getUser(userId: otherUser), + stream: service.getUser(userId: otherUser), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center( @@ -448,7 +419,7 @@ class _ChatListItem extends StatelessWidget { return StreamBuilder( stream: chat.lastMessage != null - ? chatService.getMessage( + ? service.getMessage( chatId: chat.id, messageId: chat.lastMessage!, ) diff --git a/packages/flutter_chat/lib/src/screens/creation/new_chat_screen.dart b/packages/flutter_chat/lib/src/screens/creation/new_chat_screen.dart index ea4e014..3d77dcf 100644 --- a/packages/flutter_chat/lib/src/screens/creation/new_chat_screen.dart +++ b/packages/flutter_chat/lib/src/screens/creation/new_chat_screen.dart @@ -1,6 +1,5 @@ import "package:chat_repository_interface/chat_repository_interface.dart"; import "package:flutter/material.dart"; -import "package:flutter_chat/src/config/chat_options.dart"; import "package:flutter_chat/src/config/screen_types.dart"; import "package:flutter_chat/src/screens/creation/widgets/search_field.dart"; import "package:flutter_chat/src/screens/creation/widgets/search_icon.dart"; @@ -41,8 +40,6 @@ class _NewChatScreenState extends State { Widget build(BuildContext context) { var chatScope = ChatScope.of(context); var options = chatScope.options; - var service = chatScope.service; - var userId = chatScope.userId; useEffect(() { chatScope.popHandler.add(widget.onExit); @@ -52,7 +49,6 @@ class _NewChatScreenState extends State { if (options.builders.baseScreenBuilder == null) { return Scaffold( appBar: _AppBar( - chatOptions: options, isSearching: _isSearching, onSearch: (query) { setState(() { @@ -73,12 +69,9 @@ class _NewChatScreenState extends State { focusNode: _textFieldFocusNode, ), body: _Body( - chatOptions: options, - chatService: service, isSearching: _isSearching, onPressCreateGroupChat: widget.onPressCreateGroupChat, onPressCreateChat: widget.onPressCreateChat, - userId: userId, query: query, ), ); @@ -88,7 +81,6 @@ class _NewChatScreenState extends State { context, widget.mapScreenType, _AppBar( - chatOptions: options, isSearching: _isSearching, onSearch: (query) { setState(() { @@ -109,12 +101,9 @@ class _NewChatScreenState extends State { focusNode: _textFieldFocusNode, ), _Body( - chatOptions: options, - chatService: service, isSearching: _isSearching, onPressCreateGroupChat: widget.onPressCreateGroupChat, onPressCreateChat: widget.onPressCreateChat, - userId: userId, query: query, ), ); @@ -123,14 +112,12 @@ class _NewChatScreenState extends State { class _AppBar extends StatelessWidget implements PreferredSizeWidget { const _AppBar({ - required this.chatOptions, required this.isSearching, required this.onSearch, required this.onPressedSearchIcon, required this.focusNode, }); - final ChatOptions chatOptions; final bool isSearching; final Function(String) onSearch; final VoidCallback onPressedSearchIcon; @@ -138,17 +125,18 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; var theme = Theme.of(context); return AppBar( iconTheme: theme.appBarTheme.iconTheme ?? const IconThemeData(color: Colors.white), title: SearchField( - chatOptions: chatOptions, isSearching: isSearching, onSearch: onSearch, focusNode: focusNode, - text: chatOptions.translations.newChatTitle, + text: options.translations.newChatTitle, ), actions: [ SearchIcon( @@ -165,20 +153,14 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget { class _Body extends StatelessWidget { const _Body({ - required this.chatOptions, - required this.chatService, required this.isSearching, required this.onPressCreateGroupChat, required this.onPressCreateChat, - required this.userId, required this.query, }); - final ChatOptions chatOptions; - final ChatService chatService; final bool isSearching; - final String userId; final String query; final VoidCallback onPressCreateGroupChat; @@ -186,12 +168,16 @@ class _Body extends StatelessWidget { @override Widget build(BuildContext context) { - var translations = chatOptions.translations; + var chatScope = ChatScope.of(context); + var service = chatScope.service; + var options = chatScope.options; + var userId = chatScope.userId; + var translations = options.translations; var theme = Theme.of(context); return Column( children: [ - if (chatOptions.groupChatEnabled && !isSearching) ...[ + if (options.groupChatEnabled && !isSearching) ...[ Padding( padding: const EdgeInsets.only( left: 32, @@ -222,7 +208,7 @@ class _Body extends StatelessWidget { Expanded( child: StreamBuilder>( // ignore: discarded_futures - stream: chatService.getAllUsers(), + stream: service.getAllUsers(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); @@ -233,11 +219,10 @@ class _Body extends StatelessWidget { users: snapshot.data!, currentUser: userId, query: query, - options: chatOptions, onPressCreateChat: onPressCreateChat, ); } else { - return chatOptions.builders.noUsersPlaceholderBuilder + return options.builders.noUsersPlaceholderBuilder ?.call(context, translations) ?? Padding( padding: const EdgeInsets.symmetric(vertical: 20), diff --git a/packages/flutter_chat/lib/src/screens/creation/new_group_chat_overview.dart b/packages/flutter_chat/lib/src/screens/creation/new_group_chat_overview.dart index cfec82b..2203a55 100644 --- a/packages/flutter_chat/lib/src/screens/creation/new_group_chat_overview.dart +++ b/packages/flutter_chat/lib/src/screens/creation/new_group_chat_overview.dart @@ -2,7 +2,6 @@ import "dart:typed_data"; import "package:chat_repository_interface/chat_repository_interface.dart"; import "package:flutter/material.dart"; -import "package:flutter_chat/src/config/chat_options.dart"; import "package:flutter_chat/src/config/screen_types.dart"; import "package:flutter_chat/src/screens/creation/widgets/image_picker.dart"; import "package:flutter_chat/src/util/scope.dart"; @@ -47,11 +46,8 @@ class NewGroupChatOverview extends HookWidget { if (options.builders.baseScreenBuilder == null) { return Scaffold( - appBar: _AppBar( - options: options, - ), + appBar: const _AppBar(), body: _Body( - options: options, users: users, onComplete: onComplete, ), @@ -61,11 +57,8 @@ class NewGroupChatOverview extends HookWidget { return options.builders.baseScreenBuilder!.call( context, mapScreenType, - _AppBar( - options: options, - ), + const _AppBar(), _Body( - options: options, users: users, onComplete: onComplete, ), @@ -74,14 +67,12 @@ class NewGroupChatOverview extends HookWidget { } class _AppBar extends StatelessWidget implements PreferredSizeWidget { - const _AppBar({ - required this.options, - }); - - final ChatOptions options; + const _AppBar(); @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; var theme = Theme.of(context); return AppBar( iconTheme: theme.appBarTheme.iconTheme ?? @@ -99,12 +90,10 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget { class _Body extends StatefulWidget { const _Body({ - required this.options, required this.users, required this.onComplete, }); - final ChatOptions options; final List users; final Function( List users, @@ -147,8 +136,10 @@ class _BodyState extends State<_Body> { @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; var theme = Theme.of(context); - var translations = widget.options.translations; + var translations = options.translations; return Stack( children: [ SingleChildScrollView( @@ -168,7 +159,7 @@ class _BodyState extends State<_Body> { InkWell( onTap: () async => onPressSelectImage( context, - widget.options, + options, (image) { setState(() { this.image = image; @@ -322,7 +313,6 @@ class _BodyState extends State<_Body> { ...users.map( (e) => _SelectedUser( user: e, - options: widget.options, onRemove: (user) { setState(() { users.remove(user); @@ -387,47 +377,49 @@ class _BodyState extends State<_Body> { class _SelectedUser extends StatelessWidget { const _SelectedUser({ required this.user, - required this.options, required this.onRemove, }); final UserModel user; - final ChatOptions options; final Function(UserModel) onRemove; @override - Widget build(BuildContext context) => InkWell( - onTap: () { - onRemove(user); - }, - child: Stack( - children: [ - Padding( - padding: const EdgeInsets.all(8), - child: options.builders.userAvatarBuilder?.call( - context, - user, - 40, - ) ?? - Avatar( - boxfit: BoxFit.cover, - user: User( - firstName: user.firstName, - lastName: user.lastName, - imageUrl: user.imageUrl != "" ? user.imageUrl : null, - ), - size: 40, + Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; + return InkWell( + onTap: () { + onRemove(user); + }, + child: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(8), + child: options.builders.userAvatarBuilder?.call( + context, + user, + 40, + ) ?? + Avatar( + boxfit: BoxFit.cover, + user: User( + firstName: user.firstName, + lastName: user.lastName, + imageUrl: user.imageUrl != "" ? user.imageUrl : null, ), + size: 40, + ), + ), + Positioned.directional( + textDirection: Directionality.of(context), + end: 0, + child: const Icon( + Icons.cancel, + size: 20, ), - Positioned.directional( - textDirection: Directionality.of(context), - end: 0, - child: const Icon( - Icons.cancel, - size: 20, - ), - ), - ], - ), - ); + ), + ], + ), + ); + } } diff --git a/packages/flutter_chat/lib/src/screens/creation/new_group_chat_screen.dart b/packages/flutter_chat/lib/src/screens/creation/new_group_chat_screen.dart index ab66272..3a892e0 100644 --- a/packages/flutter_chat/lib/src/screens/creation/new_group_chat_screen.dart +++ b/packages/flutter_chat/lib/src/screens/creation/new_group_chat_screen.dart @@ -1,6 +1,5 @@ import "package:chat_repository_interface/chat_repository_interface.dart"; import "package:flutter/material.dart"; -import "package:flutter_chat/src/config/chat_options.dart"; import "package:flutter_chat/src/config/screen_types.dart"; import "package:flutter_chat/src/screens/creation/widgets/search_field.dart"; import "package:flutter_chat/src/screens/creation/widgets/search_icon.dart"; @@ -38,18 +37,15 @@ class _NewGroupChatScreenState extends State { @override Widget build(BuildContext context) { var chatScope = ChatScope.of(context); - var chatOptions = chatScope.options; - var chatService = chatScope.service; - var userId = chatScope.userId; + var options = chatScope.options; useEffect(() { chatScope.popHandler.add(widget.onExit); return () => chatScope.popHandler.remove(widget.onExit); }); - if (chatOptions.builders.baseScreenBuilder == null) { + if (options.builders.baseScreenBuilder == null) { return Scaffold( appBar: _AppBar( - chatOptions: chatOptions, isSearching: _isSearching, onSearch: (query) { setState(() { @@ -73,20 +69,16 @@ class _NewGroupChatScreenState extends State { onSelectedUser: handleUserTap, selectedUsers: selectedUsers, onPressGroupChatOverview: widget.onContinue, - chatOptions: chatOptions, - chatService: chatService, isSearching: _isSearching, - userId: userId, query: query, ), ); } - return chatOptions.builders.baseScreenBuilder!.call( + return options.builders.baseScreenBuilder!.call( context, widget.mapScreenType, _AppBar( - chatOptions: chatOptions, isSearching: _isSearching, onSearch: (query) { setState(() { @@ -110,10 +102,7 @@ class _NewGroupChatScreenState extends State { onSelectedUser: handleUserTap, selectedUsers: selectedUsers, onPressGroupChatOverview: widget.onContinue, - chatOptions: chatOptions, - chatService: chatService, isSearching: _isSearching, - userId: userId, query: query, ), ); @@ -134,14 +123,12 @@ class _NewGroupChatScreenState extends State { class _AppBar extends StatelessWidget implements PreferredSizeWidget { const _AppBar({ - required this.chatOptions, required this.isSearching, required this.onSearch, required this.onPressedSearchIcon, required this.focusNode, }); - final ChatOptions chatOptions; final bool isSearching; final Function(String) onSearch; final VoidCallback onPressedSearchIcon; @@ -149,17 +136,18 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; var theme = Theme.of(context); return AppBar( iconTheme: theme.appBarTheme.iconTheme ?? const IconThemeData(color: Colors.white), title: SearchField( - chatOptions: chatOptions, isSearching: isSearching, onSearch: onSearch, focusNode: focusNode, - text: chatOptions.translations.newGroupChatTitle, + text: options.translations.newGroupChatTitle, ), actions: [ SearchIcon( @@ -176,21 +164,15 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget { class _Body extends StatelessWidget { const _Body({ - required this.chatOptions, - required this.chatService, required this.isSearching, - required this.userId, required this.query, required this.selectedUsers, required this.onSelectedUser, required this.onPressGroupChatOverview, }); - final ChatOptions chatOptions; - final ChatService chatService; final bool isSearching; - final String userId; final String query; final List selectedUsers; @@ -199,7 +181,11 @@ class _Body extends StatelessWidget { @override Widget build(BuildContext context) { - var translations = chatOptions.translations; + var chatScope = ChatScope.of(context); + var service = chatScope.service; + var options = chatScope.options; + var userId = chatScope.userId; + var translations = options.translations; var theme = Theme.of(context); return Column( @@ -207,7 +193,7 @@ class _Body extends StatelessWidget { Expanded( child: StreamBuilder>( // ignore: discarded_futures - stream: chatService.getAllUsers(), + stream: service.getAllUsers(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); @@ -220,7 +206,6 @@ class _Body extends StatelessWidget { users: snapshot.data!, currentUser: userId, query: query, - options: chatOptions, onPressCreateChat: null, creatingGroup: true, selectedUsers: selectedUsers, @@ -229,12 +214,11 @@ class _Body extends StatelessWidget { _NextButton( selectedUsers: selectedUsers, onPressGroupChatOverview: onPressGroupChatOverview, - chatOptions: chatOptions, ), ], ); } else { - return chatOptions.builders.noUsersPlaceholderBuilder + return options.builders.noUsersPlaceholderBuilder ?.call(context, translations) ?? Padding( padding: const EdgeInsets.symmetric(vertical: 20), @@ -260,15 +244,15 @@ class _NextButton extends StatelessWidget { const _NextButton({ required this.onPressGroupChatOverview, required this.selectedUsers, - required this.chatOptions, }); final Function(List) onPressGroupChatOverview; final List selectedUsers; - final ChatOptions chatOptions; @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; var theme = Theme.of(context); return Align( alignment: Alignment.bottomCenter, @@ -287,7 +271,7 @@ class _NextButton extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - chatOptions.translations.next, + options.translations.next, style: theme.textTheme.displayLarge, ), ], diff --git a/packages/flutter_chat/lib/src/screens/creation/widgets/search_field.dart b/packages/flutter_chat/lib/src/screens/creation/widgets/search_field.dart index d01d4b8..48dc703 100644 --- a/packages/flutter_chat/lib/src/screens/creation/widgets/search_field.dart +++ b/packages/flutter_chat/lib/src/screens/creation/widgets/search_field.dart @@ -1,11 +1,10 @@ import "package:flutter/material.dart"; -import "package:flutter_chat/src/config/chat_options.dart"; +import "package:flutter_chat/src/util/scope.dart"; /// The search field widget class SearchField extends StatelessWidget { /// Constructs a [SearchField] const SearchField({ - required this.chatOptions, required this.isSearching, required this.onSearch, required this.focusNode, @@ -13,9 +12,6 @@ class SearchField extends StatelessWidget { super.key, }); - /// The chat options - final ChatOptions chatOptions; - /// Whether the search field is currently in use final bool isSearching; @@ -30,8 +26,10 @@ class SearchField extends StatelessWidget { @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; var theme = Theme.of(context); - var translations = chatOptions.translations; + var translations = options.translations; if (isSearching) { return TextField( diff --git a/packages/flutter_chat/lib/src/screens/creation/widgets/user_list.dart b/packages/flutter_chat/lib/src/screens/creation/widgets/user_list.dart index 750b46e..52eb72a 100644 --- a/packages/flutter_chat/lib/src/screens/creation/widgets/user_list.dart +++ b/packages/flutter_chat/lib/src/screens/creation/widgets/user_list.dart @@ -1,6 +1,6 @@ import "package:chat_repository_interface/chat_repository_interface.dart"; import "package:flutter/material.dart"; -import "package:flutter_chat/src/config/chat_options.dart"; +import "package:flutter_chat/src/util/scope.dart"; import "package:flutter_profile/flutter_profile.dart"; /// The user list widget @@ -10,7 +10,6 @@ class UserList extends StatefulWidget { required this.users, required this.currentUser, required this.query, - required this.options, required this.onPressCreateChat, this.creatingGroup = false, this.selectedUsers = const [], @@ -27,9 +26,6 @@ class UserList extends StatefulWidget { /// The current user final String currentUser; - /// The chat options - final ChatOptions options; - /// Whether the user is creating a group final bool creatingGroup; @@ -60,8 +56,11 @@ class _UserListState extends State { @override Widget build(BuildContext context) { + var chatScope = ChatScope.of(context); + var options = chatScope.options; var theme = Theme.of(context); - var translations = widget.options.translations; + + var translations = options.translations; filteredUsers = widget.query.isNotEmpty ? users .where( @@ -88,11 +87,11 @@ class _UserListState extends State { return handlePersonalChatTap(user); } }, - child: widget.options.builders.chatRowContainerBuilder?.call( + child: options.builders.chatRowContainerBuilder?.call( context, Row( children: [ - widget.options.builders.userAvatarBuilder + options.builders.userAvatarBuilder ?.call(context, user, 44) ?? Avatar( boxfit: BoxFit.cover, @@ -140,7 +139,7 @@ class _UserListState extends State { padding: const EdgeInsets.all(12), child: Row( children: [ - widget.options.builders.userAvatarBuilder + options.builders.userAvatarBuilder ?.call(context, user, 44) ?? Avatar( boxfit: BoxFit.cover,