mirror of
https://github.com/Iconica-Development/flutter_chat.git
synced 2025-05-18 18:33:49 +02:00
feat: remove chatService and chatOptions from widget parameters to use ChatScope instead
This commit is contained in:
parent
b1909689f2
commit
a9eb1a8df4
8 changed files with 128 additions and 211 deletions
|
@ -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,
|
||||
),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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!,
|
||||
)
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
],
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue