Merge pull request #68 from Iconica-Development/2.0.0

Improve flutter_chat for usage in safino
This commit is contained in:
Gorter-dev 2024-05-29 15:37:26 +02:00 committed by GitHub
commit 3d3153d2ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 263 additions and 99 deletions

View file

@ -11,4 +11,5 @@ jobs:
secrets: inherit
permissions: write-all
with:
subfolder: '.' # add optional subfolder to run workflow in
subfolder: '.' # add optional subfolder to run workflow in
flutter_version: 3.19.6

View file

@ -1,3 +1,14 @@
## 2.0.0
- Add a serviceBuilder to the userstory configuration
- Add a translationsBuilder to the userstory configuration
- Change onPressUserProfile callback to use a ChatUserModel instead of a String
- Add a enableGroupChatCreation boolean to the userstory configuration to enable or disable group chat creation
- Change the ChatTranslations constructor to require all translations or use the ChatTranslations.empty constructor if you don't want to specify all translations
- Remove the Divider between the users on the new chat screen
- Add option to set a custom padding around the list of chats
- Fix nullpointer when firstWhere returns null because there is only 1 person in a groupchat
## 1.4.3
- Added default styling.

View file

@ -4,7 +4,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_chat/flutter_chat.dart';
import 'package:uuid/uuid.dart';
/// Navigates to the chat user story screen.
///
@ -96,9 +95,9 @@ Widget _chatDetailScreenRoute(
service: configuration.chatService,
chatId: chatId,
textfieldBottomPadding: configuration.textfieldBottomPadding ?? 0,
onPressUserProfile: (userId) async {
onPressUserProfile: (user) async {
if (configuration.onPressUserProfile != null) {
return configuration.onPressUserProfile?.call();
return configuration.onPressUserProfile?.call(context, user);
}
return Navigator.of(context).push(
MaterialPageRoute(
@ -106,7 +105,7 @@ Widget _chatDetailScreenRoute(
configuration,
context,
chatId,
userId,
user.id,
),
),
);
@ -172,7 +171,7 @@ Widget _chatProfileScreenRoute(
userId: userId,
onTapUser: (user) async {
if (configuration.onPressUserProfile != null) {
return configuration.onPressUserProfile!.call();
return configuration.onPressUserProfile!.call(context, user);
}
return Navigator.of(context).push(
@ -200,6 +199,7 @@ Widget _newChatScreenRoute(
options: configuration.chatOptionsBuilder(context),
translations: configuration.translations,
service: configuration.chatService,
showGroupChatButton: configuration.enableGroupChatCreation,
onPressCreateGroupChat: () async {
configuration.onPressCreateGroupChat?.call();
if (context.mounted) {

View file

@ -14,9 +14,11 @@ List<GoRoute> getChatStoryRoutes(
GoRoute(
path: ChatUserStoryRoutes.chatScreen,
pageBuilder: (context, state) {
var service = configuration.chatServiceBuilder?.call(context) ??
configuration.chatService;
var chatScreen = ChatScreen(
unreadMessageTextStyle: configuration.unreadMessageTextStyle,
service: configuration.chatService,
service: service,
options: configuration.chatOptionsBuilder(context),
onNoChats: () async =>
context.push(ChatUserStoryRoutes.newChatScreen),
@ -34,7 +36,8 @@ List<GoRoute> getChatStoryRoutes(
configuration.onDeleteChat?.call(context, chat) ??
configuration.chatService.chatOverviewService.deleteChat(chat),
deleteChatDialog: configuration.deleteChatDialog,
translations: configuration.translations,
translations: configuration.translationsBuilder?.call(context) ??
configuration.translations,
);
return buildScreenWithoutTransition(
context: context,
@ -53,6 +56,8 @@ List<GoRoute> getChatStoryRoutes(
path: ChatUserStoryRoutes.chatDetailScreen,
pageBuilder: (context, state) {
var chatId = state.pathParameters['id'];
var service = configuration.chatServiceBuilder?.call(context) ??
configuration.chatService;
var chatDetailScreen = ChatDetailScreen(
chatTitleBuilder: configuration.chatTitleBuilder,
usernameBuilder: configuration.usernameBuilder,
@ -60,16 +65,17 @@ List<GoRoute> getChatStoryRoutes(
iconDisabledColor: configuration.iconDisabledColor,
pageSize: configuration.messagePageSize,
options: configuration.chatOptionsBuilder(context),
translations: configuration.translations,
service: configuration.chatService,
translations: configuration.translationsBuilder?.call(context) ??
configuration.translations,
service: service,
chatId: chatId!,
textfieldBottomPadding: configuration.textfieldBottomPadding ?? 0,
onPressUserProfile: (userId) async {
onPressUserProfile: (user) async {
if (configuration.onPressUserProfile != null) {
return configuration.onPressUserProfile?.call();
return configuration.onPressUserProfile?.call(context, user);
}
return context.push(
ChatUserStoryRoutes.chatProfileScreenPath(chatId, userId),
ChatUserStoryRoutes.chatProfileScreenPath(chatId, user.id),
);
},
onMessageSubmit: (message) async {
@ -120,10 +126,14 @@ List<GoRoute> getChatStoryRoutes(
GoRoute(
path: ChatUserStoryRoutes.newChatScreen,
pageBuilder: (context, state) {
var service = configuration.chatServiceBuilder?.call(context) ??
configuration.chatService;
var newChatScreen = NewChatScreen(
options: configuration.chatOptionsBuilder(context),
translations: configuration.translations,
service: configuration.chatService,
translations: configuration.translationsBuilder?.call(context) ??
configuration.translations,
service: service,
showGroupChatButton: configuration.enableGroupChatCreation,
onPressCreateChat: (user) async {
configuration.onPressCreateChat?.call(user);
if (configuration.onPressCreateChat != null) return;
@ -163,10 +173,13 @@ List<GoRoute> getChatStoryRoutes(
GoRoute(
path: ChatUserStoryRoutes.newGroupChatScreen,
pageBuilder: (context, state) {
var service = configuration.chatServiceBuilder?.call(context) ??
configuration.chatService;
var newGroupChatScreen = NewGroupChatScreen(
options: configuration.chatOptionsBuilder(context),
translations: configuration.translations,
service: configuration.chatService,
translations: configuration.translationsBuilder?.call(context) ??
configuration.translations,
service: service,
onPressGroupChatOverview: (users) async => context.push(
ChatUserStoryRoutes.newGroupChatOverviewScreen,
extra: users,
@ -188,11 +201,14 @@ List<GoRoute> getChatStoryRoutes(
GoRoute(
path: ChatUserStoryRoutes.newGroupChatOverviewScreen,
pageBuilder: (context, state) {
var service = configuration.chatServiceBuilder?.call(context) ??
configuration.chatService;
var users = state.extra! as List<ChatUserModel>;
var newGroupChatOverviewScreen = NewGroupChatOverviewScreen(
options: configuration.chatOptionsBuilder(context),
translations: configuration.translations,
service: configuration.chatService,
translations: configuration.translationsBuilder?.call(context) ??
configuration.translations,
service: service,
users: users,
onPressCompleteGroupChatCreation: (users, groupChatName) async {
configuration.onPressCompleteGroupChatCreation
@ -232,18 +248,21 @@ List<GoRoute> getChatStoryRoutes(
var chatId = state.pathParameters['id'];
var userId = state.pathParameters['userId'];
var id = userId == 'null' ? null : userId;
var service = configuration.chatServiceBuilder?.call(context) ??
configuration.chatService;
var profileScreen = ChatProfileScreen(
translations: configuration.translations,
chatService: configuration.chatService,
translations: configuration.translationsBuilder?.call(context) ??
configuration.translations,
chatService: service,
chatId: chatId!,
userId: id,
onTapUser: (user) async {
if (configuration.onPressUserProfile != null) {
return configuration.onPressUserProfile!.call();
return configuration.onPressUserProfile!.call(context, user);
}
return context.push(
ChatUserStoryRoutes.chatProfileScreenPath(chatId, user),
ChatUserStoryRoutes.chatProfileScreenPath(chatId, user.id),
);
},
);

View file

@ -14,6 +14,7 @@ class ChatUserStoryConfiguration {
const ChatUserStoryConfiguration({
required this.chatService,
required this.chatOptionsBuilder,
this.chatServiceBuilder,
this.onPressStartChat,
this.onPressChat,
this.onDeleteChat,
@ -27,7 +28,9 @@ class ChatUserStoryConfiguration {
this.deleteChatDialog,
this.disableDismissForPermanentChats = false,
this.routeToNewChatIfEmpty = true,
this.translations = const ChatTranslations(),
this.enableGroupChatCreation = true,
this.translations = const ChatTranslations.empty(),
this.translationsBuilder,
this.chatPageBuilder,
this.onPressChatTitle,
this.afterMessageSent,
@ -44,6 +47,9 @@ class ChatUserStoryConfiguration {
/// The service responsible for handling chat-related functionalities.
final ChatService chatService;
/// A method to get the chat service only when needed and with a context.
final ChatService Function(BuildContext context)? chatServiceBuilder;
/// Callback function triggered when a chat is pressed.
final Function(BuildContext, ChatModel)? onPressChat;
@ -53,6 +59,9 @@ class ChatUserStoryConfiguration {
/// Translations for internationalization/localization support.
final ChatTranslations translations;
/// Translations builder because context might be needed for translations.
final ChatTranslations Function(BuildContext context)? translationsBuilder;
/// Determines whether dismissing is disabled for permanent chats.
final bool disableDismissForPermanentChats;
@ -74,7 +83,10 @@ class ChatUserStoryConfiguration {
/// Builder for chat options based on context.
final Function(List<ChatUserModel>, String)? onPressCompleteGroupChatCreation;
final Function()? onPressCreateGroupChat;
/// Builder for the chat options which can be used to style the UI of the chat
final ChatOptions Function(BuildContext context) chatOptionsBuilder;
/// If true, the user will be routed to the new chat screen if there are
@ -84,6 +96,10 @@ class ChatUserStoryConfiguration {
/// The size of each page of messages.
final int messagePageSize;
/// Whether to enable group chat creation for the user. If false,
/// the button will be hidden
final bool enableGroupChatCreation;
/// Dialog for confirming chat deletion.
final Future<bool?> Function(BuildContext, ChatModel)? deleteChatDialog;
@ -100,11 +116,18 @@ class ChatUserStoryConfiguration {
final Function()? onPressStartChat;
/// Callback function triggered when user profile is pressed.
final Function()? onPressUserProfile;
final Function(BuildContext context, ChatUserModel user)? onPressUserProfile;
final double? textfieldBottomPadding;
final Color? iconDisabledColor;
/// The text style used for the unread message counter.
final TextStyle? unreadMessageTextStyle;
final Widget? Function(BuildContext context)? loadingWidgetBuilder;
final Widget Function(String userFullName)? usernameBuilder;
final Widget Function(String chatTitle)? chatTitleBuilder;
}

View file

@ -4,7 +4,7 @@
name: flutter_chat
description: A new Flutter package project.
version: 1.4.3
version: 2.0.0
publish_to: none
@ -20,17 +20,17 @@ dependencies:
git:
url: https://github.com/Iconica-Development/flutter_chat
path: packages/flutter_chat_view
ref: 1.4.3
ref: 2.0.0
flutter_chat_interface:
git:
url: https://github.com/Iconica-Development/flutter_chat
path: packages/flutter_chat_interface
ref: 1.4.3
ref: 2.0.0
flutter_chat_local:
git:
url: https://github.com/Iconica-Development/flutter_chat
path: packages/flutter_chat_local
ref: 1.4.3
ref: 2.0.0
uuid: ^4.3.3
dev_dependencies:

View file

@ -91,11 +91,15 @@ class FirebaseChatOverviewService implements ChatOverviewService {
var chat = element.doc.data();
if (chat == null) return;
var otherUser = await _userService.getUser(
chat.users.firstWhere(
(element) => element != currentUser?.id,
),
);
var otherUser = chat.users.any(
(element) => element != currentUser?.id,
)
? await _userService.getUser(
chat.users.firstWhere(
(element) => element != currentUser?.id,
),
)
: null;
var unread =
await _addUnreadChatSubscription(chat.id!, currentUser!.id!);
@ -144,10 +148,10 @@ class FirebaseChatOverviewService implements ChatOverviewService {
imageUrl: chat.imageUrl ?? '',
unreadMessages: unread,
users: users,
lastMessage: chat.lastMessage != null
lastMessage: chat.lastMessage != null && otherUser != null
? chat.lastMessage!.imageUrl == null
? ChatTextMessageModel(
sender: otherUser!,
sender: otherUser,
text: chat.lastMessage!.text!,
timestamp: DateTime.fromMillisecondsSinceEpoch(
chat.lastMessage!.timestamp
@ -155,7 +159,7 @@ class FirebaseChatOverviewService implements ChatOverviewService {
),
)
: ChatImageMessageModel(
sender: otherUser!,
sender: otherUser,
imageUrl: chat.lastMessage!.imageUrl!,
timestamp: DateTime.fromMillisecondsSinceEpoch(
chat.lastMessage!.timestamp

View file

@ -4,7 +4,7 @@
name: flutter_chat_firebase
description: A new Flutter package project.
version: 1.4.3
version: 2.0.0
publish_to: none
environment:
@ -23,7 +23,7 @@ dependencies:
git:
url: https://github.com/Iconica-Development/flutter_chat
path: packages/flutter_chat_interface
ref: 1.4.3
ref: 2.0.0
dev_dependencies:
flutter_iconica_analysis:

View file

@ -4,7 +4,7 @@
name: flutter_chat_interface
description: A new Flutter package project.
version: 1.4.3
version: 2.0.0
publish_to: none
environment:

View file

@ -1,8 +1,7 @@
name: flutter_chat_local
description: "A new Flutter package project."
version: 1.4.3
version: 2.0.0
publish_to: none
homepage:
environment:
sdk: ">=3.2.5 <4.0.0"
@ -15,7 +14,7 @@ dependencies:
git:
url: https://github.com/Iconica-Development/flutter_chat
path: packages/flutter_chat_interface
ref: 1.4.3
ref: 2.0.0
dev_dependencies:
flutter_test:

View file

@ -31,7 +31,7 @@ class ChatDetailRow extends StatefulWidget {
/// The previous chat message model.
final ChatMessageModel? previousMessage;
final Function(String? userId) onPressUserProfile;
final Function(ChatUserModel user) onPressUserProfile;
final Widget Function(String userFullName)? usernameBuilder;
/// Flag indicating whether to show the time.
@ -65,7 +65,7 @@ class _ChatDetailRowState extends State<ChatDetailRow> {
if (isNewDate || isSameSender) ...[
GestureDetector(
onTap: () => widget.onPressUserProfile(
widget.message.sender.id,
widget.message.sender,
),
child: Padding(
padding: const EdgeInsets.only(left: 10.0),

View file

@ -19,6 +19,7 @@ class ChatOptions {
this.groupAvatarBuilder = _createGroupAvatar,
this.noChatsPlaceholderBuilder = _createNoChatsPlaceholder,
this.noUsersPlaceholderBuilder = _createNoUsersPlaceholder,
this.paddingAroundChatList,
});
/// Builder function for the new chat button.
@ -47,6 +48,9 @@ class ChatOptions {
/// Builder function for the placeholder shown when no users are available.
final NoUsersPlaceholderBuilder noUsersPlaceholderBuilder;
/// The padding around the chat list.
final EdgeInsets? paddingAroundChatList;
}
Widget _createNewChatButton(

View file

@ -2,12 +2,48 @@
//
// SPDX-License-Identifier: BSD-3-Clause
/// Class that holds all the translations for the chat component view and
/// the corresponding userstory
class ChatTranslations {
/// ChatTranslations constructor where everything is required use this
/// if you want to be sure to have all translations specified
/// If you just want the default values use the empty constructor
/// and optionally override the values with the copyWith method
const ChatTranslations({
required this.chatsTitle,
required this.chatsUnread,
required this.newChatButton,
required this.newGroupChatButton,
required this.newChatTitle,
required this.deleteChatButton,
required this.image,
required this.searchPlaceholder,
required this.startTyping,
required this.cancelImagePickerBtn,
required this.messagePlaceholder,
required this.writeMessageToStartChat,
required this.writeFirstMessageInGroupChat,
required this.imageUploading,
required this.deleteChatModalTitle,
required this.deleteChatModalDescription,
required this.deleteChatModalCancel,
required this.deleteChatModalConfirm,
required this.noUsersFound,
required this.noChatsFound,
required this.chatCantBeDeleted,
required this.chatProfileUsers,
required this.imagePickerTitle,
required this.uploadFile,
required this.takePicture,
required this.anonymousUser,
});
/// Default translations for the chat component view
const ChatTranslations.empty({
this.chatsTitle = 'Chats',
this.chatsUnread = 'unread',
this.newChatButton = 'Start a chat',
this.newGroupChatButton = 'Start group chat',
this.newGroupChatButton = 'Create a group chat',
this.newChatTitle = 'Start a chat',
this.image = 'Image',
this.searchPlaceholder = 'Search...',
@ -62,4 +98,67 @@ class ChatTranslations {
/// Shown when the user has no name
final String anonymousUser;
// copyWith method to override the default values
ChatTranslations copyWith({
String? chatsTitle,
String? chatsUnread,
String? newChatButton,
String? newGroupChatButton,
String? newChatTitle,
String? deleteChatButton,
String? image,
String? searchPlaceholder,
String? startTyping,
String? cancelImagePickerBtn,
String? messagePlaceholder,
String? writeMessageToStartChat,
String? writeFirstMessageInGroupChat,
String? imageUploading,
String? deleteChatModalTitle,
String? deleteChatModalDescription,
String? deleteChatModalCancel,
String? deleteChatModalConfirm,
String? noUsersFound,
String? noChatsFound,
String? chatCantBeDeleted,
String? chatProfileUsers,
String? imagePickerTitle,
String? uploadFile,
String? takePicture,
String? anonymousUser,
}) =>
ChatTranslations(
chatsTitle: chatsTitle ?? this.chatsTitle,
chatsUnread: chatsUnread ?? this.chatsUnread,
newChatButton: newChatButton ?? this.newChatButton,
newGroupChatButton: newGroupChatButton ?? this.newGroupChatButton,
newChatTitle: newChatTitle ?? this.newChatTitle,
deleteChatButton: deleteChatButton ?? this.deleteChatButton,
image: image ?? this.image,
searchPlaceholder: searchPlaceholder ?? this.searchPlaceholder,
startTyping: startTyping ?? this.startTyping,
cancelImagePickerBtn: cancelImagePickerBtn ?? this.cancelImagePickerBtn,
messagePlaceholder: messagePlaceholder ?? this.messagePlaceholder,
writeMessageToStartChat:
writeMessageToStartChat ?? this.writeMessageToStartChat,
writeFirstMessageInGroupChat:
writeFirstMessageInGroupChat ?? this.writeFirstMessageInGroupChat,
imageUploading: imageUploading ?? this.imageUploading,
deleteChatModalTitle: deleteChatModalTitle ?? this.deleteChatModalTitle,
deleteChatModalDescription:
deleteChatModalDescription ?? this.deleteChatModalDescription,
deleteChatModalCancel:
deleteChatModalCancel ?? this.deleteChatModalCancel,
deleteChatModalConfirm:
deleteChatModalConfirm ?? this.deleteChatModalConfirm,
noUsersFound: noUsersFound ?? this.noUsersFound,
noChatsFound: noChatsFound ?? this.noChatsFound,
chatCantBeDeleted: chatCantBeDeleted ?? this.chatCantBeDeleted,
chatProfileUsers: chatProfileUsers ?? this.chatProfileUsers,
imagePickerTitle: imagePickerTitle ?? this.imagePickerTitle,
uploadFile: uploadFile ?? this.uploadFile,
takePicture: takePicture ?? this.takePicture,
anonymousUser: anonymousUser ?? this.anonymousUser,
);
}

View file

@ -26,7 +26,7 @@ class ChatDetailScreen extends StatefulWidget {
this.chatTitleBuilder,
this.usernameBuilder,
this.loadingWidgetBuilder,
this.translations = const ChatTranslations(),
this.translations = const ChatTranslations.empty(),
this.iconColor,
this.iconDisabledColor,
this.showTime = false,
@ -53,7 +53,7 @@ class ChatDetailScreen extends StatefulWidget {
final int pageSize;
final double textfieldBottomPadding;
final Color? iconDisabledColor;
final Function(String? userId) onPressUserProfile;
final Function(ChatUserModel user) onPressUserProfile;
// ignore: avoid_positional_boolean_parameters
final Widget? Function(BuildContext context)? loadingWidgetBuilder;
final Widget Function(String userFullName)? usernameBuilder;

View file

@ -26,7 +26,7 @@ class ChatProfileScreen extends StatefulWidget {
final String? userId;
/// Callback function for tapping on a user.
final Function(String userId) onTapUser;
final Function(ChatUserModel user) onTapUser;
@override
State<ChatProfileScreen> createState() => _ProfileScreenState();
@ -124,7 +124,7 @@ class _ProfileScreenState extends State<ChatProfileScreen> {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: GestureDetector(
onTap: () => widget.onTapUser.call(e.id!),
onTap: () => widget.onTapUser.call(e),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,

View file

@ -20,7 +20,7 @@ class ChatScreen extends StatefulWidget {
this.unreadMessageTextStyle,
this.onNoChats,
this.deleteChatDialog,
this.translations = const ChatTranslations(),
this.translations = const ChatTranslations.empty(),
this.disableDismissForPermanentChats = false,
super.key,
});
@ -119,7 +119,8 @@ class _ChatScreenState extends State<ChatScreen> {
child: ListView(
controller: controller,
physics: const AlwaysScrollableScrollPhysics(),
padding: const EdgeInsets.fromLTRB(28, 16, 28, 0),
padding: widget.options.paddingAroundChatList ??
const EdgeInsets.fromLTRB(28, 16, 28, 0),
children: [
StreamBuilder<List<ChatModel>>(
stream: widget.service.chatOverviewService.getChatsStream(),
@ -384,7 +385,6 @@ class ChatListItem extends StatelessWidget {
),
),
),
const Divider(),
],
);
}

View file

@ -11,7 +11,8 @@ class NewChatScreen extends StatefulWidget {
required this.onPressCreateChat,
required this.service,
required this.onPressCreateGroupChat,
this.translations = const ChatTranslations(),
this.showGroupChatButton = true,
this.translations = const ChatTranslations.empty(),
super.key,
});
@ -23,8 +24,13 @@ class NewChatScreen extends StatefulWidget {
/// Callback function for creating a new chat with a user.
final Function(ChatUserModel) onPressCreateChat;
/// Callback function for creating a new group chat.
final Function() onPressCreateGroupChat;
/// Option to enable the group chat creation button.
final bool showGroupChatButton;
/// Translations for the chat.
final ChatTranslations translations;
@ -52,48 +58,50 @@ class _NewChatScreenState extends State<NewChatScreen> {
),
body: Column(
children: [
GestureDetector(
onTap: () async {
await widget.onPressCreateGroupChat();
},
child: Container(
color: Colors.grey[900],
child: SizedBox(
height: 60.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(
left: 16.0,
),
child: IconButton(
icon: const Icon(
Icons.group,
color: Colors.white,
if (widget.showGroupChatButton) ...[
GestureDetector(
onTap: () async {
await widget.onPressCreateGroupChat();
},
child: Container(
color: Colors.grey[900],
child: SizedBox(
height: 60.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(
left: 16.0,
),
child: IconButton(
icon: const Icon(
Icons.group,
color: Colors.white,
),
onPressed: () {
// Handle group chat creation
},
),
onPressed: () {
// Handle group chat creation
},
),
),
const Text(
'Create group chat',
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
Text(
widget.translations.newGroupChatButton,
style: const TextStyle(
color: Colors.white,
fontSize: 16.0,
),
),
),
],
),
],
],
),
],
),
),
),
),
),
],
Expanded(
child: FutureBuilder<List<ChatUserModel>>(
// ignore: discarded_futures
@ -213,12 +221,8 @@ class _NewChatScreenState extends State<NewChatScreen> {
return widget.options.noChatsPlaceholderBuilder(widget.translations);
}
return ListView.separated(
return ListView.builder(
itemCount: filteredUsers.length,
separatorBuilder: (context, index) => const Padding(
padding: EdgeInsets.symmetric(horizontal: 28.0),
child: Divider(),
),
itemBuilder: (context, index) {
var user = filteredUsers[index];
return GestureDetector(

View file

@ -11,7 +11,7 @@ class NewGroupChatOverviewScreen extends StatefulWidget {
required this.onPressCompleteGroupChatCreation,
required this.service,
required this.users,
this.translations = const ChatTranslations(),
this.translations = const ChatTranslations.empty(),
super.key,
});

View file

@ -8,7 +8,7 @@ class NewGroupChatScreen extends StatefulWidget {
required this.options,
required this.onPressGroupChatOverview,
required this.service,
this.translations = const ChatTranslations(),
this.translations = const ChatTranslations.empty(),
super.key,
});

View file

@ -4,7 +4,7 @@
name: flutter_chat_view
description: A standard flutter package.
version: 1.4.3
version: 2.0.0
publish_to: none
@ -20,7 +20,7 @@ dependencies:
git:
url: https://github.com/Iconica-Development/flutter_chat
path: packages/flutter_chat_interface
ref: 1.4.3
ref: 2.0.0
cached_network_image: ^3.2.2
flutter_image_picker:
git: