mirror of
https://github.com/Iconica-Development/flutter_chat.git
synced 2025-05-18 18:33:49 +02:00
feat: updated readme, ui colors and null values
This commit is contained in:
parent
ac163a28f8
commit
cb423c582c
6 changed files with 154 additions and 75 deletions
102
README.md
102
README.md
|
@ -1,4 +1,5 @@
|
||||||
# Flutter Community Chat
|
# Flutter Community Chat
|
||||||
|
|
||||||
Flutter Community Chat is a package which gives the possibility to add a (personal or group) chat to your Flutter-application. Default this package adds support for a Firebase back-end. You can add your custom back-end (like a Websocket-API) by extending the `CommunityChatInterface` interface from the `flutter_community_chat_interface` package.
|
Flutter Community Chat is a package which gives the possibility to add a (personal or group) chat to your Flutter-application. Default this package adds support for a Firebase back-end. You can add your custom back-end (like a Websocket-API) by extending the `CommunityChatInterface` interface from the `flutter_community_chat_interface` package.
|
||||||
|
|
||||||

|

|
||||||
|
@ -7,11 +8,12 @@ Figma Design that defines this component (only accessible for Iconica developers
|
||||||
Figma clickable prototype that demonstrates this component (only accessible for Iconica developers): https://www.figma.com/proto/PRJoVXQ5aOjAICfkQdAq2A/Iconica-User-Stories?page-id=1%3A2&type=design&node-id=56-6837&viewport=279%2C2452%2C0.2&t=E7Al3Xng2WXnbCEQ-1&scaling=scale-down&starting-point-node-id=56%3A6837&mode=design
|
Figma clickable prototype that demonstrates this component (only accessible for Iconica developers): https://www.figma.com/proto/PRJoVXQ5aOjAICfkQdAq2A/Iconica-User-Stories?page-id=1%3A2&type=design&node-id=56-6837&viewport=279%2C2452%2C0.2&t=E7Al3Xng2WXnbCEQ-1&scaling=scale-down&starting-point-node-id=56%3A6837&mode=design
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
To use this package, add flutter_community_chat as a dependency in your pubspec.yaml file:
|
To use this package, add flutter_community_chat as a dependency in your pubspec.yaml file:
|
||||||
|
|
||||||
```
|
```
|
||||||
flutter_community_chat:
|
flutter_community_chat:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_community_chat.git
|
url: https://github.com/Iconica-Development/flutter_community_chat.git
|
||||||
path: packages/flutter_community_chat
|
path: packages/flutter_community_chat
|
||||||
```
|
```
|
||||||
|
@ -20,43 +22,102 @@ If you are going to use Firebase as the back-end of the Community Chat, you shou
|
||||||
|
|
||||||
```
|
```
|
||||||
flutter_community_chat_firebase:
|
flutter_community_chat_firebase:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_community_chat.git
|
url: https://github.com/Iconica-Development/flutter_community_chat.git
|
||||||
path: packages/flutter_community_chat_firebase
|
path: packages/flutter_community_chat_firebase
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Create a Firebase project for your application and add firebase firestore and storage.
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
To use the module within your Flutter-application you should add the following code to the build-method of a chosen widget.
|
|
||||||
|
To use the module within your Flutter-application with predefined `Go_router` routes you should add the following:
|
||||||
|
|
||||||
|
Add go_router as dependency to your project.
|
||||||
|
Add the following configuration to your flutter_application:
|
||||||
|
|
||||||
```
|
```
|
||||||
CommunityChat(
|
List<GoRoute> getCommunityChatRoutes() => getCommunityChatStoryRoutes(
|
||||||
dataProvider: FirebaseCommunityChatDataProvider(),
|
CommunityChatUserStoryConfiguration(
|
||||||
)
|
service: FirebaseChatService(userService: FirebaseUserService()),
|
||||||
|
userService: FirebaseUserService(),
|
||||||
|
messageService:
|
||||||
|
FirebaseMessageService(userService: FirebaseUserService()),
|
||||||
|
chatOptionsBuilder: (ctx) => const ChatOptions(),
|
||||||
|
),
|
||||||
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
In this example we provide a `FirebaseCommunityChatDataProvider` as a data provider. You can also specify your own implementation here of the `CommunityChatInterface` interface.
|
Add the `getCommunityChatRoutes()` to your go_router routes like so:
|
||||||
|
|
||||||
You can also include your custom configuration for both the Community Chat itself as the Image Picker which is included in this package. You can specify those configurations as a parameter:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
CommunityChat(
|
final GoRouter _router = GoRouter(
|
||||||
dataProvider: FirebaseCommunityChatDataProvider(),
|
routes: <RouteBase>[
|
||||||
imagePickerTheme: ImagePickerTheme(),
|
GoRoute(
|
||||||
chatOptions: ChatOptions(),
|
path: '/',
|
||||||
)
|
builder: (BuildContext context, GoRouterState state) {
|
||||||
|
return const MyHomePage(
|
||||||
|
title: "home",
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
...getCommunityChatRoutes()
|
||||||
|
],
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
To use the module within your Flutter-application without predefined `Go_router` routes add the following code to the build-method of a chosen widget:
|
||||||
|
|
||||||
|
To add the `ChatScreen` add the following code:
|
||||||
|
|
||||||
|
````
|
||||||
|
ChatScreen(
|
||||||
|
options: options,
|
||||||
|
onPressStartChat: onPressStartChat,
|
||||||
|
onPressChat: onPressChat,
|
||||||
|
onDeleteChat: onDeleteChat,
|
||||||
|
service: service,
|
||||||
|
pageSize: pageSize,
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
To add the `ChatDetailScreen` add the following code:
|
||||||
|
|
||||||
|
```
|
||||||
|
ChatDetailScreen(
|
||||||
|
options: options,
|
||||||
|
onMessageSubmit: onMessageSubmit,
|
||||||
|
onUploadImage: onUploadImage,
|
||||||
|
onReadChat: onReadChat,
|
||||||
|
service: service,
|
||||||
|
chatUserService: chatUserService,
|
||||||
|
messageService: messageService,
|
||||||
|
pageSize: pageSize,
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
To add the `NewChatScreen` add the following code:
|
||||||
|
|
||||||
|
```
|
||||||
|
NewChatScreen(
|
||||||
|
options: options,
|
||||||
|
onPressCreateChat: onPressCreateChat,
|
||||||
|
service: service,
|
||||||
|
userService: userService,
|
||||||
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
The `ChatOptions` has its own parameters, as specified below:
|
The `ChatOptions` has its own parameters, as specified below:
|
||||||
| Parameter | Explanation |
|
| Parameter | Explanation |
|
||||||
|-----------|-------------|
|
|-----------|-------------|
|
||||||
| newChatButtonBuilder | Builds the 'New Chat' button, to initiate a new chat session. This button is displayed on the chat overview. |
|
| newChatButtonBuilder | Builds the 'New Chat' button, to initiate a new chat session. This button is displayed on the chat overview. |
|
||||||
| messageInputBuilder | Builds the text input which is displayed within the chat view, responsible for sending text messages. |
|
| messageInputBuilder | Builds the text input which is displayed within the chat view, responsible for sending text messages. |
|
||||||
| chatRowContainerBuilder | Builds a chat row. A row with the users' avatar, name and eventually the last massage sended in the chat. This builder is used both in the *chat overview screen* as in the *new chat screen*. |
|
| chatRowContainerBuilder | Builds a chat row. A row with the users' avatar, name and eventually the last massage sended in the chat. This builder is used both in the _chat overview screen_ as in the _new chat screen_. |
|
||||||
| imagePickerContainerBuilder | Builds the container around the ImagePicker. |
|
| imagePickerContainerBuilder | Builds the container around the ImagePicker. |
|
||||||
| closeImagePickerButtonBuilder | Builds the close button for the Image Picker pop-up window. |
|
| closeImagePickerButtonBuilder | Builds the close button for the Image Picker pop-up window. |
|
||||||
| scaffoldBuilder | Builds the default Scaffold-widget around the Community Chat. The chat title is displayed within the Scaffolds' title for example. |
|
| scaffoldBuilder | Builds the default Scaffold-widget around the Community Chat. The chat title is displayed within the Scaffolds' title for example. |
|
||||||
|
|
||||||
The `ImagePickerTheme` also has its own parameters, how to use these parameters can be found in [the documentation of the flutter_image_picker package](https://github.com/Iconica-Development/flutter_image_picker).
|
The `ImagePickerTheme` also has its own parameters, how to use these parameters can be found in [the documentation of the flutter_image_picker package](https://github.com/Iconica-Development/flutter_image_picker).
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
|
|
||||||
|
@ -69,3 +130,4 @@ If you would like to contribute to the plugin (e.g. by improving the documentati
|
||||||
## Author
|
## Author
|
||||||
|
|
||||||
This `flutter_community_chat` for Flutter is developed by [Iconica](https://iconica.nl). You can contact us at <support@iconica.nl>
|
This `flutter_community_chat` for Flutter is developed by [Iconica](https://iconica.nl). You can contact us at <support@iconica.nl>
|
||||||
|
````
|
||||||
|
|
|
@ -267,13 +267,16 @@ class FirebaseChatService implements ChatService {
|
||||||
var startIndex = (pageNumber - 1) * pageSize;
|
var startIndex = (pageNumber - 1) * pageSize;
|
||||||
var endIndex = startIndex + pageSize;
|
var endIndex = startIndex + pageSize;
|
||||||
|
|
||||||
if (startIndex >= groupChatIds.length) {
|
if (groupChatIds != null) {
|
||||||
return [];
|
if (startIndex >= groupChatIds.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
var groupIds = groupChatIds.sublist(
|
||||||
|
startIndex, endIndex.clamp(0, groupChatIds.length));
|
||||||
|
lastGroupId = groupIds.last;
|
||||||
|
return groupIds;
|
||||||
}
|
}
|
||||||
var groupIds = groupChatIds.sublist(
|
return [];
|
||||||
startIndex, endIndex.clamp(0, groupChatIds.length));
|
|
||||||
lastGroupId = groupIds.last;
|
|
||||||
return groupIds;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (userSnapshot.docs.isNotEmpty) {
|
if (userSnapshot.docs.isNotEmpty) {
|
||||||
|
|
|
@ -37,7 +37,6 @@ class _ChatDetailRowState extends State<ChatDetailRow> {
|
||||||
widget.message.timestamp.day != widget.previousMessage?.timestamp.day;
|
widget.message.timestamp.day != widget.previousMessage?.timestamp.day;
|
||||||
var isSameSender = widget.previousMessage == null ||
|
var isSameSender = widget.previousMessage == null ||
|
||||||
widget.previousMessage?.sender.id != widget.message.sender.id;
|
widget.previousMessage?.sender.id != widget.message.sender.id;
|
||||||
print(isNewDate);
|
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
|
@ -79,9 +78,13 @@ class _ChatDetailRowState extends State<ChatDetailRow> {
|
||||||
Text(
|
Text(
|
||||||
widget.message.sender.fullName?.toUpperCase() ??
|
widget.message.sender.fullName?.toUpperCase() ??
|
||||||
widget.translations.anonymousUser,
|
widget.translations.anonymousUser,
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.labelMedium
|
||||||
|
?.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
|
@ -106,7 +109,13 @@ class _ChatDetailRowState extends State<ChatDetailRow> {
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
text: (widget.message as ChatTextMessageModel)
|
text: (widget.message as ChatTextMessageModel)
|
||||||
.text,
|
.text,
|
||||||
style: const TextStyle(fontSize: 16),
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.labelMedium
|
||||||
|
?.color,
|
||||||
|
),
|
||||||
children: <TextSpan>[
|
children: <TextSpan>[
|
||||||
if (widget.showTime)
|
if (widget.showTime)
|
||||||
TextSpan(
|
TextSpan(
|
||||||
|
|
|
@ -24,9 +24,11 @@ class ChatImage extends StatelessWidget {
|
||||||
),
|
),
|
||||||
width: size,
|
width: size,
|
||||||
height: size,
|
height: size,
|
||||||
child: CachedNetworkImage(
|
child: image != ''
|
||||||
imageUrl: image,
|
? CachedNetworkImage(
|
||||||
fit: BoxFit.cover,
|
imageUrl: image,
|
||||||
),
|
fit: BoxFit.cover,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ Widget _createImagePickerContainer(
|
||||||
) =>
|
) =>
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
color: Colors.black,
|
color: Colors.white,
|
||||||
child: ImagePicker(
|
child: ImagePicker(
|
||||||
customButton: ElevatedButton(
|
customButton: ElevatedButton(
|
||||||
onPressed: onClose,
|
onPressed: onClose,
|
||||||
|
|
|
@ -316,48 +316,51 @@ class ChatListItem extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => widget.onPressChat(chat),
|
onTap: () => widget.onPressChat(chat),
|
||||||
child: widget.options.chatRowContainerBuilder(
|
child: Container(
|
||||||
(chat is PersonalChatModel)
|
color: Colors.transparent,
|
||||||
? ChatRow(
|
child: widget.options.chatRowContainerBuilder(
|
||||||
unreadMessages: chat.unreadMessages ?? 0,
|
(chat is PersonalChatModel)
|
||||||
avatar: widget.options.userAvatarBuilder(
|
? ChatRow(
|
||||||
(chat as PersonalChatModel).user,
|
unreadMessages: chat.unreadMessages ?? 0,
|
||||||
40.0,
|
avatar: widget.options.userAvatarBuilder(
|
||||||
|
(chat as PersonalChatModel).user,
|
||||||
|
40.0,
|
||||||
|
),
|
||||||
|
title: (chat as PersonalChatModel).user.fullName ??
|
||||||
|
translations.anonymousUser,
|
||||||
|
subTitle: chat.lastMessage != null
|
||||||
|
? chat.lastMessage is ChatTextMessageModel
|
||||||
|
? (chat.lastMessage! as ChatTextMessageModel).text
|
||||||
|
: '📷 '
|
||||||
|
'${translations.image}'
|
||||||
|
: '',
|
||||||
|
lastUsed: chat.lastUsed != null
|
||||||
|
? _dateFormatter.format(
|
||||||
|
date: chat.lastUsed!,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
)
|
||||||
|
: ChatRow(
|
||||||
|
title: (chat as GroupChatModel).title,
|
||||||
|
unreadMessages: chat.unreadMessages ?? 0,
|
||||||
|
subTitle: chat.lastMessage != null
|
||||||
|
? chat.lastMessage is ChatTextMessageModel
|
||||||
|
? (chat.lastMessage! as ChatTextMessageModel).text
|
||||||
|
: '📷 '
|
||||||
|
'${translations.image}'
|
||||||
|
: '',
|
||||||
|
avatar: widget.options.groupAvatarBuilder(
|
||||||
|
(chat as GroupChatModel).title,
|
||||||
|
(chat as GroupChatModel).imageUrl,
|
||||||
|
40.0,
|
||||||
|
),
|
||||||
|
lastUsed: chat.lastUsed != null
|
||||||
|
? _dateFormatter.format(
|
||||||
|
date: chat.lastUsed!,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
),
|
),
|
||||||
title: (chat as PersonalChatModel).user.fullName ??
|
),
|
||||||
translations.anonymousUser,
|
|
||||||
subTitle: chat.lastMessage != null
|
|
||||||
? chat.lastMessage is ChatTextMessageModel
|
|
||||||
? (chat.lastMessage! as ChatTextMessageModel).text
|
|
||||||
: '📷 '
|
|
||||||
'${translations.image}'
|
|
||||||
: '',
|
|
||||||
lastUsed: chat.lastUsed != null
|
|
||||||
? _dateFormatter.format(
|
|
||||||
date: chat.lastUsed!,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
)
|
|
||||||
: ChatRow(
|
|
||||||
title: (chat as GroupChatModel).title,
|
|
||||||
unreadMessages: chat.unreadMessages ?? 0,
|
|
||||||
subTitle: chat.lastMessage != null
|
|
||||||
? chat.lastMessage is ChatTextMessageModel
|
|
||||||
? (chat.lastMessage! as ChatTextMessageModel).text
|
|
||||||
: '📷 '
|
|
||||||
'${translations.image}'
|
|
||||||
: '',
|
|
||||||
avatar: widget.options.groupAvatarBuilder(
|
|
||||||
(chat as GroupChatModel).title,
|
|
||||||
(chat as GroupChatModel).imageUrl,
|
|
||||||
40.0,
|
|
||||||
),
|
|
||||||
lastUsed: chat.lastUsed != null
|
|
||||||
? _dateFormatter.format(
|
|
||||||
date: chat.lastUsed!,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue