Merge pull request #65 from Iconica-Development/1.4.1

refactor/match with Figma
This commit is contained in:
Gorter-dev 2024-04-19 15:44:53 +02:00 committed by GitHub
commit 3b443ee1fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 374 additions and 204 deletions

View file

@ -1,3 +1,6 @@
## 1.4.1
- Made UI changes to match the Figma design
## 1.4.0 ## 1.4.0
- Add way to create group chats - Add way to create group chats
- Update flutter_profile to 1.3.0 - Update flutter_profile to 1.3.0

View file

@ -24,7 +24,12 @@ class Home extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Center( return Center(
child: chatNavigatorUserStory(context), child: chatNavigatorUserStory(context,
); configuration: ChatUserStoryConfiguration(
chatService: LocalChatService(),
chatOptionsBuilder: (ctx) => ChatOptions(
noChatsPlaceholderBuilder: (translations) =>
Text(translations.noUsersFound),
))));
} }
} }

View file

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

View file

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

View file

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

View file

@ -68,7 +68,7 @@ class LocalChatDetailService with ChangeNotifier implements ChatDetailService {
.chats .chats
.firstWhere((element) => element.id == chatId); .firstWhere((element) => element.id == chatId);
var message = ChatImageMessageModel( var message = ChatImageMessageModel(
sender: ChatUserModel( sender: const ChatUserModel(
id: '3', id: '3',
firstName: 'ico', firstName: 'ico',
lastName: 'nica', lastName: 'nica',
@ -101,7 +101,7 @@ class LocalChatDetailService with ChangeNotifier implements ChatDetailService {
.chats .chats
.firstWhere((element) => element.id == chatId); .firstWhere((element) => element.id == chatId);
var message = ChatTextMessageModel( var message = ChatTextMessageModel(
sender: ChatUserModel( sender: const ChatUserModel(
id: '3', id: '3',
firstName: 'ico', firstName: 'ico',
lastName: 'nica', lastName: 'nica',

View file

@ -4,19 +4,19 @@ import 'package:flutter_chat_interface/flutter_chat_interface.dart';
class LocalChatUserService implements ChatUserService { class LocalChatUserService implements ChatUserService {
/// List of predefined chat users. /// List of predefined chat users.
List<ChatUserModel> users = [ List<ChatUserModel> users = [
ChatUserModel( const ChatUserModel(
id: '1', id: '1',
firstName: 'John', firstName: 'John',
lastName: 'Doe', lastName: 'Doe',
imageUrl: 'https://picsum.photos/200/300', imageUrl: 'https://picsum.photos/200/300',
), ),
ChatUserModel( const ChatUserModel(
id: '2', id: '2',
firstName: 'Jane', firstName: 'Jane',
lastName: 'Doe', lastName: 'Doe',
imageUrl: 'https://picsum.photos/200/300', imageUrl: 'https://picsum.photos/200/300',
), ),
ChatUserModel( const ChatUserModel(
id: '3', id: '3',
firstName: 'ico', firstName: 'ico',
lastName: 'nica', lastName: 'nica',
@ -29,7 +29,8 @@ class LocalChatUserService implements ChatUserService {
Future.value(users.where((element) => element.id != '3').toList()); Future.value(users.where((element) => element.id != '3').toList());
@override @override
Future<ChatUserModel?> getCurrentUser() => Future.value(ChatUserModel()); Future<ChatUserModel?> getCurrentUser() =>
Future.value(const ChatUserModel());
@override @override
Future<ChatUserModel?> getUser(String id) { Future<ChatUserModel?> getUser(String id) {

View file

@ -1,6 +1,6 @@
name: flutter_chat_local name: flutter_chat_local
description: "A new Flutter package project." description: "A new Flutter package project."
version: 1.4.0 version: 1.4.1
publish_to: none publish_to: none
homepage: homepage:
@ -15,7 +15,7 @@ dependencies:
git: git:
url: https://github.com/Iconica-Development/flutter_chat url: https://github.com/Iconica-Development/flutter_chat
path: packages/flutter_chat_interface path: packages/flutter_chat_interface
ref: 1.4.0 ref: 1.4.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View file

@ -102,11 +102,11 @@ class _ChatDetailRowState extends State<ChatDetailRow> {
) )
else else
Text( Text(
widget.message.sender.fullName?.toUpperCase() ?? widget.message.sender.fullName ??
widget.translations.anonymousUser, widget.translations.anonymousUser,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w800,
color: Theme.of(context) color: Theme.of(context)
.textTheme .textTheme
.labelMedium .labelMedium
@ -121,7 +121,8 @@ class _ChatDetailRowState extends State<ChatDetailRow> {
showFullDate: true, showFullDate: true,
), ),
style: const TextStyle( style: const TextStyle(
fontSize: 12, fontSize: 16,
fontWeight: FontWeight.w300,
color: Color(0xFFBBBBBB), color: Color(0xFFBBBBBB),
), ),
), ),

View file

@ -31,7 +31,7 @@ class ChatRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) => Row( Widget build(BuildContext context) => Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.only(left: 10.0), padding: const EdgeInsets.only(left: 10.0),
@ -39,7 +39,7 @@ class ChatRow extends StatelessWidget {
), ),
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 22.0), padding: const EdgeInsets.only(left: 16.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -48,10 +48,10 @@ class ChatRow extends StatelessWidget {
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle( style: TextStyle(
fontSize: 18, fontSize: 16,
fontWeight: unreadMessages > 0 fontWeight: unreadMessages > 0
? FontWeight.w600 ? FontWeight.w900
: FontWeight.w400, : FontWeight.w500,
), ),
), ),
if (subTitle != null) if (subTitle != null)
@ -62,11 +62,11 @@ class ChatRow extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: unreadMessages > 0 fontWeight: unreadMessages > 0
? FontWeight.w600 ? FontWeight.w500
: FontWeight.w400, : FontWeight.w300,
), ),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 1, maxLines: 2,
), ),
), ),
], ],
@ -77,17 +77,19 @@ class ChatRow extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
Text( if (lastUsed != null) // Check if lastUsed is not null
lastUsed ?? '', Padding(
padding: const EdgeInsets.only(bottom: 4.0),
child: Text(
lastUsed!,
style: const TextStyle( style: const TextStyle(
color: Color(0xFFBBBBBB), color: Color(0xFFBBBBBB),
fontSize: 14, fontSize: 14,
), ),
), ),
),
if (unreadMessages > 0) ...[ if (unreadMessages > 0) ...[
Padding( Container(
padding: const EdgeInsets.only(top: 4.0),
child: Container(
width: 20, width: 20,
height: 20, height: 20,
decoration: BoxDecoration( decoration: BoxDecoration(
@ -103,7 +105,6 @@ class ChatRow extends StatelessWidget {
), ),
), ),
), ),
),
], ],
], ],
), ),

View file

@ -18,6 +18,7 @@ class ChatOptions {
this.userAvatarBuilder = _createUserAvatar, this.userAvatarBuilder = _createUserAvatar,
this.groupAvatarBuilder = _createGroupAvatar, this.groupAvatarBuilder = _createGroupAvatar,
this.noChatsPlaceholderBuilder = _createNoChatsPlaceholder, this.noChatsPlaceholderBuilder = _createNoChatsPlaceholder,
this.noUsersPlaceholderBuilder = _createNoUsersPlaceholder,
}); });
/// Builder function for the new chat button. /// Builder function for the new chat button.
@ -43,6 +44,9 @@ class ChatOptions {
/// Builder function for the placeholder shown when no chats are available. /// Builder function for the placeholder shown when no chats are available.
final NoChatsPlaceholderBuilder noChatsPlaceholderBuilder; final NoChatsPlaceholderBuilder noChatsPlaceholderBuilder;
/// Builder function for the placeholder shown when no users are available.
final NoUsersPlaceholderBuilder noUsersPlaceholderBuilder;
} }
Widget _createNewChatButton( Widget _createNewChatButton(
@ -51,16 +55,23 @@ Widget _createNewChatButton(
ChatTranslations translations, ChatTranslations translations,
) => ) =>
Padding( Padding(
padding: const EdgeInsets.all(24.0), padding: const EdgeInsets.fromLTRB(5, 24, 5, 24),
child: ElevatedButton( child: ElevatedButton(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: Colors.black, backgroundColor: const Color.fromRGBO(113, 198, 209, 1),
minimumSize: const Size.fromHeight(50), fixedSize: const Size(254, 44),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(56),
),
), ),
onPressed: onPressed, onPressed: onPressed,
child: Text( child: Text(
translations.newChatButton, translations.newChatButton,
style: const TextStyle(color: Colors.white), style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.w800,
fontSize: 18,
),
), ),
), ),
); );
@ -112,7 +123,7 @@ Widget _createChatRowContainer(
) => ) =>
Padding( Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
vertical: 15.0, vertical: 12.0,
horizontal: 10.0, horizontal: 10.0,
), ),
child: chatRow, child: chatRow,
@ -126,9 +137,17 @@ Widget _createImagePickerContainer(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
color: Colors.white, color: Colors.white,
child: ImagePicker( child: ImagePicker(
imagePickerTheme: ImagePickerTheme(
title: translations.imagePickerTitle,
titleTextSize: 16,
titleAlignment: TextAlign.center,
iconSize: 60.0,
makePhotoText: translations.takePicture,
selectImageText: translations.uploadFile,
),
customButton: ElevatedButton( customButton: ElevatedButton(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: Colors.black, backgroundColor: const Color.fromRGBO(113, 198, 209, 1),
), ),
onPressed: onClose, onPressed: onClose,
child: Text( child: Text(
@ -172,6 +191,20 @@ Widget _createGroupAvatar(
Widget _createNoChatsPlaceholder( Widget _createNoChatsPlaceholder(
ChatTranslations translations, ChatTranslations translations,
) =>
Center(
child: Text(
translations.noChatsFound,
textAlign: TextAlign.center,
style: const TextStyle(
color: Colors.white,
fontSize: 18,
),
),
);
Widget _createNoUsersPlaceholder(
ChatTranslations translations,
) => ) =>
Center( Center(
child: Text( child: Text(
@ -224,3 +257,7 @@ typedef GroupAvatarBuilder = Widget Function(
typedef NoChatsPlaceholderBuilder = Widget Function( typedef NoChatsPlaceholderBuilder = Widget Function(
ChatTranslations translations, ChatTranslations translations,
); );
typedef NoUsersPlaceholderBuilder = Widget Function(
ChatTranslations translations,
);

View file

@ -6,13 +6,17 @@ class ChatTranslations {
const ChatTranslations({ const ChatTranslations({
this.chatsTitle = 'Chats', this.chatsTitle = 'Chats',
this.chatsUnread = 'unread', this.chatsUnread = 'unread',
this.newChatButton = 'Start chat', this.newChatButton = 'Start a chat',
this.newGroupChatButton = 'Start group chat', this.newGroupChatButton = 'Start group chat',
this.newChatTitle = 'Start chat', this.newChatTitle = 'Start chat',
this.image = 'Image', this.image = 'Image',
this.searchPlaceholder = 'Search...', this.searchPlaceholder = 'Search...',
this.startTyping = 'Start typing to find a user to chat with.',
this.cancelImagePickerBtn = 'Cancel', this.cancelImagePickerBtn = 'Cancel',
this.messagePlaceholder = 'Write your message here...', this.messagePlaceholder = 'Write your message here...',
this.writeMessageToStartChat = 'Write a message to start the chat.',
this.writeFirstMessageInGroupChat =
'Write the first message in this group chat.',
this.imageUploading = 'Image is uploading...', this.imageUploading = 'Image is uploading...',
this.deleteChatButton = 'Delete', this.deleteChatButton = 'Delete',
this.deleteChatModalTitle = 'Delete chat', this.deleteChatModalTitle = 'Delete chat',
@ -20,10 +24,14 @@ class ChatTranslations {
'Are you sure you want to delete this chat?', 'Are you sure you want to delete this chat?',
this.deleteChatModalCancel = 'Cancel', this.deleteChatModalCancel = 'Cancel',
this.deleteChatModalConfirm = 'Delete', this.deleteChatModalConfirm = 'Delete',
this.noUsersFound = 'No users found', this.noUsersFound = 'No users were found to start a chat with.',
this.noChatsFound = 'Click on \'Start a chat\' to create a new chat.',
this.anonymousUser = 'Anonymous user', this.anonymousUser = 'Anonymous user',
this.chatCantBeDeleted = 'This chat can\'t be deleted', this.chatCantBeDeleted = 'This chat can\'t be deleted',
this.chatProfileUsers = 'Users:', this.chatProfileUsers = 'Users:',
this.imagePickerTitle = 'Do you want to upload a file or take a picture?',
this.uploadFile = 'UPLOAD FILE',
this.takePicture = 'TAKE PICTURE',
}); });
final String chatsTitle; final String chatsTitle;
@ -34,16 +42,23 @@ class ChatTranslations {
final String deleteChatButton; final String deleteChatButton;
final String image; final String image;
final String searchPlaceholder; final String searchPlaceholder;
final String startTyping;
final String cancelImagePickerBtn; final String cancelImagePickerBtn;
final String messagePlaceholder; final String messagePlaceholder;
final String writeMessageToStartChat;
final String writeFirstMessageInGroupChat;
final String imageUploading; final String imageUploading;
final String deleteChatModalTitle; final String deleteChatModalTitle;
final String deleteChatModalDescription; final String deleteChatModalDescription;
final String deleteChatModalCancel; final String deleteChatModalCancel;
final String deleteChatModalConfirm; final String deleteChatModalConfirm;
final String noUsersFound; final String noUsersFound;
final String noChatsFound;
final String chatCantBeDeleted; final String chatCantBeDeleted;
final String chatProfileUsers; final String chatProfileUsers;
final String imagePickerTitle;
final String uploadFile;
final String takePicture;
/// Shown when the user has no name /// Shown when the user has no name
final String anonymousUser; final String anonymousUser;

View file

@ -172,16 +172,14 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
iconTheme: theme.appBarTheme.iconTheme ?? iconTheme: theme.appBarTheme.iconTheme ??
const IconThemeData(color: Colors.white), const IconThemeData(color: Colors.white),
centerTitle: true, centerTitle: true,
leading: (chatModel is GroupChatModel) leading: GestureDetector(
? GestureDetector(
onTap: () { onTap: () {
Navigator.popUntil(context, (route) => route.isFirst); Navigator.popUntil(context, (route) => route.isFirst);
}, },
child: const Icon( child: const Icon(
Icons.arrow_back, Icons.arrow_back,
), ),
) ),
: null,
title: GestureDetector( title: GestureDetector(
onTap: () => widget.onPressChatTitle.call(context, chatModel!), onTap: () => widget.onPressChatTitle.call(context, chatModel!),
child: Row( child: Row(
@ -195,41 +193,36 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
chatModel.imageUrl, chatModel.imageUrl,
36.0, 36.0,
), ),
] else if (chatModel is PersonalChatModel) ...[
widget.options.userAvatarBuilder(
chatModel.user,
36.0,
),
] else ] else
...[], ...[],
Expanded( Padding(
child: Padding( padding: (chatModel is GroupChatModel)
padding: const EdgeInsets.only(left: 15.5), ? const EdgeInsets.only(left: 15.5)
: EdgeInsets.zero,
child: widget.chatTitleBuilder != null child: widget.chatTitleBuilder != null
? widget.chatTitleBuilder!.call( ? widget.chatTitleBuilder!.call(
(chatModel is GroupChatModel) (chatModel is GroupChatModel)
? chatModel.title ? chatModel.title
: (chatModel is PersonalChatModel) : (chatModel is PersonalChatModel)
? chatModel.user.fullName ?? ? chatModel.user.firstName ??
widget widget.translations.anonymousUser
.translations.anonymousUser
: '', : '',
) )
: Text( : Text(
(chatModel is GroupChatModel) (chatModel is GroupChatModel)
? chatModel.title ? chatModel.title
: (chatModel is PersonalChatModel) : (chatModel is PersonalChatModel)
? chatModel.user.fullName ?? ? chatModel.user.firstName ??
widget widget.translations.anonymousUser
.translations.anonymousUser
: '', : '',
style: theme.appBarTheme.titleTextStyle ?? style: theme.appBarTheme.titleTextStyle ??
const TextStyle( const TextStyle(
fontWeight: FontWeight.w800,
fontSize: 18.0,
color: Colors.white, color: Colors.white,
), ),
), ),
), ),
),
], ],
), ),
), ),
@ -269,6 +262,21 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
reverse: true, reverse: true,
padding: const EdgeInsets.only(top: 24.0), padding: const EdgeInsets.only(top: 24.0),
children: [ children: [
if (detailRows.isEmpty)
Center(
child: Text(
(chatModel is GroupChatModel)
? widget.translations
.writeFirstMessageInGroupChat
: widget
.translations.writeMessageToStartChat,
style: const TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w400,
color: Color.fromRGBO(33, 33, 33, 1),
),
),
),
...detailRows, ...detailRows,
], ],
), ),

View file

@ -92,6 +92,8 @@ class _ChatScreenState extends State<ChatScreen> {
widget.service.chatOverviewService.getUnreadChatsCountStream(), widget.service.chatOverviewService.getUnreadChatsCountStream(),
builder: (BuildContext context, snapshot) => Align( builder: (BuildContext context, snapshot) => Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: Visibility(
visible: (snapshot.data ?? 0) > 0,
child: Padding( child: Padding(
padding: const EdgeInsets.only(right: 22.0), padding: const EdgeInsets.only(right: 22.0),
child: Text( child: Text(
@ -105,6 +107,7 @@ class _ChatScreenState extends State<ChatScreen> {
), ),
), ),
), ),
),
], ],
), ),
Column( Column(
@ -113,7 +116,7 @@ class _ChatScreenState extends State<ChatScreen> {
child: ListView( child: ListView(
controller: controller, controller: controller,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 15.0), padding: const EdgeInsets.fromLTRB(28, 16, 28, 0),
children: [ children: [
StreamBuilder<List<ChatModel>>( StreamBuilder<List<ChatModel>>(
stream: widget.service.chatOverviewService.getChatsStream(), stream: widget.service.chatOverviewService.getChatsStream(),
@ -127,6 +130,15 @@ class _ChatScreenState extends State<ChatScreen> {
await widget.onNoChats!.call(); await widget.onNoChats!.call();
}); });
} }
return Center(
child: Text(
translations.noChatsFound,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400,
),
),
);
} else { } else {
_hasCalledOnNoChats = _hasCalledOnNoChats =
false; // Reset the flag if there are chats false; // Reset the flag if there are chats
@ -151,6 +163,8 @@ class _ChatScreenState extends State<ChatScreen> {
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: [ children: [
Text( Text(
chat.canBeDeleted chat.canBeDeleted
@ -158,50 +172,80 @@ class _ChatScreenState extends State<ChatScreen> {
.deleteChatModalTitle .deleteChatModalTitle
: translations : translations
.chatCantBeDeleted, .chatCantBeDeleted,
textAlign: TextAlign.center,
style: const TextStyle( style: const TextStyle(
fontSize: 20, fontSize: 24,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 24),
if (chat.canBeDeleted) if (chat.canBeDeleted)
Text( Padding(
padding: const EdgeInsets
.symmetric(
horizontal: 16,
),
child: Text(
translations translations
.deleteChatModalDescription, .deleteChatModalDescription,
textAlign:
TextAlign.center,
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 18,
), ),
), ),
const SizedBox(height: 16), ),
const SizedBox(
height: 24,
),
Row( Row(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.center, MainAxisAlignment.center,
children: [ children: [
TextButton(
child: Text(
translations
.deleteChatModalCancel,
style: const TextStyle(
fontSize: 16,
),
),
onPressed: () =>
Navigator.of(
context,
).pop(false),
),
if (chat.canBeDeleted)
ElevatedButton( ElevatedButton(
onPressed: () => onPressed: () =>
Navigator.of( Navigator.of(
context, context,
).pop(true), ).pop(false),
child: Text(
translations
.deleteChatModalCancel,
style: const TextStyle(
color: Colors.black,
fontSize: 18,
),
),
),
if (chat.canBeDeleted)
const SizedBox(
width: 16,
),
if (chat.canBeDeleted)
ElevatedButton(
style: ElevatedButton
.styleFrom(
backgroundColor:
const Color
.fromRGBO(
113,
198,
209,
1,
),
),
onPressed: () =>
Navigator.of(
context,
).pop(
true,
),
child: Text( child: Text(
translations translations
.deleteChatModalConfirm, .deleteChatModalConfirm,
style: style:
const TextStyle( const TextStyle(
fontSize: 16, color: Colors.white,
fontSize: 18,
), ),
), ),
), ),
@ -283,7 +327,9 @@ class ChatListItem extends StatelessWidget {
final DateFormatter _dateFormatter; final DateFormatter _dateFormatter;
@override @override
Widget build(BuildContext context) => GestureDetector( Widget build(BuildContext context) => Column(
children: [
GestureDetector(
onTap: () => widget.onPressChat(chat), onTap: () => widget.onPressChat(chat),
child: Container( child: Container(
color: Colors.transparent, color: Colors.transparent,
@ -299,7 +345,8 @@ class ChatListItem extends StatelessWidget {
translations.anonymousUser, translations.anonymousUser,
subTitle: chat.lastMessage != null subTitle: chat.lastMessage != null
? chat.lastMessage is ChatTextMessageModel ? chat.lastMessage is ChatTextMessageModel
? (chat.lastMessage! as ChatTextMessageModel).text ? (chat.lastMessage! as ChatTextMessageModel)
.text
: '📷 ' : '📷 '
'${translations.image}' '${translations.image}'
: '', : '',
@ -314,7 +361,8 @@ class ChatListItem extends StatelessWidget {
unreadMessages: chat.unreadMessages ?? 0, unreadMessages: chat.unreadMessages ?? 0,
subTitle: chat.lastMessage != null subTitle: chat.lastMessage != null
? chat.lastMessage is ChatTextMessageModel ? chat.lastMessage is ChatTextMessageModel
? (chat.lastMessage! as ChatTextMessageModel).text ? (chat.lastMessage! as ChatTextMessageModel)
.text
: '📷 ' : '📷 '
'${translations.image}' '${translations.image}'
: '', : '',
@ -331,5 +379,8 @@ class ChatListItem extends StatelessWidget {
), ),
), ),
), ),
),
const Divider(),
],
); );
} }

View file

@ -106,8 +106,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
} else if (snapshot.hasData) { } else if (snapshot.hasData) {
return _buildUserList(snapshot.data!); return _buildUserList(snapshot.data!);
} else { } else {
return widget.options return Text(widget.translations.noUsersFound);
.noChatsPlaceholderBuilder(widget.translations);
} }
}, },
), ),
@ -152,7 +151,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
), ),
) )
: Text( : Text(
widget.translations.newChatButton, widget.translations.newChatTitle,
style: theme.appBarTheme.titleTextStyle ?? style: theme.appBarTheme.titleTextStyle ??
const TextStyle( const TextStyle(
color: Colors.white, color: Colors.white,
@ -192,24 +191,61 @@ class _NewChatScreenState extends State<NewChatScreen> {
) )
.toList(); .toList();
if (_textFieldFocusNode.hasFocus && query.isEmpty) {
return Padding(
padding: const EdgeInsets.only(top: 20.0),
child: Center(
child: Text(
widget.translations.startTyping,
style: const TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.grey,
),
),
),
);
}
if (filteredUsers.isEmpty) { if (filteredUsers.isEmpty) {
return widget.options.noChatsPlaceholderBuilder(widget.translations); return widget.options.noChatsPlaceholderBuilder(widget.translations);
} }
return ListView.builder( return ListView.separated(
itemCount: filteredUsers.length, itemCount: filteredUsers.length,
separatorBuilder: (context, index) => const Padding(
padding: EdgeInsets.symmetric(horizontal: 28.0),
child: Divider(),
),
itemBuilder: (context, index) { itemBuilder: (context, index) {
var user = filteredUsers[index]; var user = filteredUsers[index];
return GestureDetector( return GestureDetector(
child: widget.options.chatRowContainerBuilder( child: widget.options.chatRowContainerBuilder(
Container( Container(
color: Colors.transparent, color: Colors.transparent,
child: ChatRow( child: Padding(
avatar: widget.options.userAvatarBuilder( padding: const EdgeInsets.symmetric(horizontal: 20.0),
user, child: Row(
40.0, children: [
Padding(
padding: const EdgeInsets.only(left: 12.0, right: 12),
child: widget.options.userAvatarBuilder(user, 40.0),
),
Expanded(
child: Container(
height: 40.0,
alignment: Alignment.centerLeft,
child: Text(
user.fullName ?? widget.translations.anonymousUser,
style: const TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w800,
),
),
),
),
],
), ),
title: user.fullName ?? widget.translations.anonymousUser,
), ),
), ),
), ),

View file

@ -146,8 +146,12 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
return widget.options.noChatsPlaceholderBuilder(widget.translations); return widget.options.noChatsPlaceholderBuilder(widget.translations);
} }
return ListView.builder( return ListView.separated(
itemCount: filteredUsers.length, itemCount: filteredUsers.length,
separatorBuilder: (context, index) => const Padding(
padding: EdgeInsets.symmetric(horizontal: 28.0),
child: Divider(),
), // Add Divider here
itemBuilder: (context, index) { itemBuilder: (context, index) {
var user = filteredUsers[index]; var user = filteredUsers[index];
var isSelected = var isSelected =
@ -166,17 +170,24 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
}, },
child: Container( child: Container(
color: isSelected ? Colors.amber.shade200 : Colors.white, color: isSelected ? Colors.amber.shade200 : Colors.white,
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 12.0, horizontal: 30),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded( Padding(
child: widget.options.chatRowContainerBuilder( padding: const EdgeInsets.only(left: 12.0, right: 12),
ChatRow( child: widget.options.userAvatarBuilder(user, 40.0),
avatar: widget.options.userAvatarBuilder( ),
user, Expanded(
40.0, child: Container(
height: 40.0, // Adjust the height as needed
alignment: Alignment.centerLeft,
child: Text(
user.fullName ?? widget.translations.anonymousUser,
style: const TextStyle(
fontWeight: FontWeight.w800,
), ),
title: user.fullName ?? widget.translations.anonymousUser,
), ),
), ),
), ),
@ -188,6 +199,7 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
], ],
), ),
), ),
),
); );
}, },
); );

View file

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