feat: remove chatService and chatOptions from widget parameters to use ChatScope instead

This commit is contained in:
Freek van de Ven 2025-02-12 22:38:02 +01:00 committed by FlutterJoey
parent b1909689f2
commit a9eb1a8df4
8 changed files with 128 additions and 211 deletions

View file

@ -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<ChatDetailScreen> {
@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<ChatDetailScreen> {
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,
),

View file

@ -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(

View file

@ -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<int>(
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<List<ChatModel>?>(
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<MessageModel?>(
stream: chat.lastMessage != null
? chatService.getMessage(
? service.getMessage(
chatId: chat.id,
messageId: chat.lastMessage!,
)
@ -432,7 +403,7 @@ class _ChatListItem extends StatelessWidget {
);
return StreamBuilder<UserModel>(
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<MessageModel?>(
stream: chat.lastMessage != null
? chatService.getMessage(
? service.getMessage(
chatId: chat.id,
messageId: chat.lastMessage!,
)

View file

@ -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<NewChatScreen> {
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<NewChatScreen> {
if (options.builders.baseScreenBuilder == null) {
return Scaffold(
appBar: _AppBar(
chatOptions: options,
isSearching: _isSearching,
onSearch: (query) {
setState(() {
@ -73,12 +69,9 @@ class _NewChatScreenState extends State<NewChatScreen> {
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<NewChatScreen> {
context,
widget.mapScreenType,
_AppBar(
chatOptions: options,
isSearching: _isSearching,
onSearch: (query) {
setState(() {
@ -109,12 +101,9 @@ class _NewChatScreenState extends State<NewChatScreen> {
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<NewChatScreen> {
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<List<UserModel>>(
// 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),

View file

@ -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<UserModel> users;
final Function(
List<UserModel> 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,
),
),
],
),
);
),
],
),
);
}
}

View file

@ -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<NewGroupChatScreen> {
@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<NewGroupChatScreen> {
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<NewGroupChatScreen> {
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<NewGroupChatScreen> {
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<UserModel> 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<List<UserModel>>(
// 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<UserModel>) onPressGroupChatOverview;
final List<UserModel> 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,
),
],

View file

@ -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(

View file

@ -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<UserList> {
@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<UserList> {
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<UserList> {
padding: const EdgeInsets.all(12),
child: Row(
children: [
widget.options.builders.userAvatarBuilder
options.builders.userAvatarBuilder
?.call(context, user, 44) ??
Avatar(
boxfit: BoxFit.cover,