mirror of
https://github.com/Iconica-Development/flutter_chat.git
synced 2025-05-18 18:33:49 +02:00
feat: add firebase repo implementation, remove scaffold builders and add basescreenbuilder
This commit is contained in:
parent
1f3dc09f44
commit
61de7ae44a
24 changed files with 699 additions and 347 deletions
|
@ -80,6 +80,36 @@ class ChatModel {
|
||||||
lastMessage: lastMessage ?? this.lastMessage,
|
lastMessage: lastMessage ?? this.lastMessage,
|
||||||
unreadMessageCount: unreadMessageCount ?? this.unreadMessageCount,
|
unreadMessageCount: unreadMessageCount ?? this.unreadMessageCount,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// The factory chat model that creates a chat model from a map
|
||||||
|
factory ChatModel.fromMap(String id, Map<String, dynamic> data) {
|
||||||
|
return ChatModel(
|
||||||
|
id: id,
|
||||||
|
users: List<String>.from(data['users']),
|
||||||
|
isGroupChat: data['isGroupChat'],
|
||||||
|
chatName: data['chatName'],
|
||||||
|
description: data['description'],
|
||||||
|
imageUrl: data['imageUrl'],
|
||||||
|
canBeDeleted: data['canBeDeleted'] ?? true,
|
||||||
|
lastUsed: data['lastUsed'] != null
|
||||||
|
? DateTime.fromMillisecondsSinceEpoch(data['lastUsed'])
|
||||||
|
: null,
|
||||||
|
lastMessage: data['lastMessage'],
|
||||||
|
unreadMessageCount: data['unreadMessageCount'] ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() => {
|
||||||
|
'users': users,
|
||||||
|
'isGroupChat': isGroupChat,
|
||||||
|
'chatName': chatName,
|
||||||
|
'description': description,
|
||||||
|
'imageUrl': imageUrl,
|
||||||
|
'canBeDeleted': canBeDeleted,
|
||||||
|
'lastUsed': lastUsed?.millisecondsSinceEpoch,
|
||||||
|
'lastMessage': lastMessage,
|
||||||
|
'unreadMessageCount': unreadMessageCount,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The chat model extension
|
/// The chat model extension
|
||||||
|
|
|
@ -15,7 +15,7 @@ class MessageModel {
|
||||||
required this.timestamp,
|
required this.timestamp,
|
||||||
required this.senderId,
|
required this.senderId,
|
||||||
});
|
});
|
||||||
|
/// The chat id
|
||||||
final String chatId;
|
final String chatId;
|
||||||
|
|
||||||
/// The message id
|
/// The message id
|
||||||
|
@ -50,6 +50,27 @@ class MessageModel {
|
||||||
timestamp: timestamp ?? this.timestamp,
|
timestamp: timestamp ?? this.timestamp,
|
||||||
senderId: senderId ?? this.senderId,
|
senderId: senderId ?? this.senderId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
factory MessageModel.fromMap(String id, Map<String, dynamic> map) {
|
||||||
|
return MessageModel(
|
||||||
|
chatId: map['chatId'],
|
||||||
|
id: id,
|
||||||
|
text: map['text'],
|
||||||
|
imageUrl: map['imageUrl'],
|
||||||
|
timestamp: DateTime.fromMillisecondsSinceEpoch(map['timestamp']),
|
||||||
|
senderId: map['senderId'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'chatId': chatId,
|
||||||
|
'text': text,
|
||||||
|
'imageUrl': imageUrl,
|
||||||
|
'timestamp': timestamp.millisecondsSinceEpoch,
|
||||||
|
'senderId': senderId,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension on [MessageModel] to check the message type
|
/// Extension on [MessageModel] to check the message type
|
||||||
|
|
|
@ -25,6 +25,15 @@ class UserModel {
|
||||||
|
|
||||||
/// The user image url
|
/// The user image url
|
||||||
final String? imageUrl;
|
final String? imageUrl;
|
||||||
|
|
||||||
|
factory UserModel.fromMap(String id, Map<String, dynamic> data) {
|
||||||
|
return UserModel(
|
||||||
|
id: id,
|
||||||
|
firstName: data['firstName'],
|
||||||
|
lastName: data['lastName'],
|
||||||
|
imageUrl: data['imageUrl'],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension on [UserModel] to get the user full name
|
/// Extension on [UserModel] to get the user full name
|
||||||
|
|
|
@ -188,16 +188,8 @@ class ChatService {
|
||||||
/// Returns a [Stream] of [int].
|
/// Returns a [Stream] of [int].
|
||||||
Stream<int> getUnreadMessagesCount({
|
Stream<int> getUnreadMessagesCount({
|
||||||
required String userId,
|
required String userId,
|
||||||
String? chatId,
|
|
||||||
}) {
|
}) {
|
||||||
if (chatId == null) {
|
return chatRepository.getUnreadMessagesCount(userId: userId);
|
||||||
return chatRepository.getUnreadMessagesCount(userId: userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return chatRepository.getUnreadMessagesCount(
|
|
||||||
userId: userId,
|
|
||||||
chatId: chatId,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Upload an image with the given parameters.
|
/// Upload an image with the given parameters.
|
||||||
|
@ -218,9 +210,18 @@ class ChatService {
|
||||||
/// Returns a [Future] of [void].
|
/// Returns a [Future] of [void].
|
||||||
Future<void> markAsRead({
|
Future<void> markAsRead({
|
||||||
required String chatId,
|
required String chatId,
|
||||||
|
required String userId,
|
||||||
}) async {
|
}) async {
|
||||||
var chat = await chatRepository.getChat(chatId: chatId).first;
|
var chat = await chatRepository.getChat(chatId: chatId).first;
|
||||||
|
|
||||||
|
if (chat.lastMessage == null) return;
|
||||||
|
|
||||||
|
var lastMessage = await chatRepository
|
||||||
|
.getMessage(chatId: chatId, messageId: chat.lastMessage!)
|
||||||
|
.first;
|
||||||
|
|
||||||
|
if (lastMessage != null && lastMessage.senderId == userId) return;
|
||||||
|
|
||||||
var newChat = chat.copyWith(
|
var newChat = chat.copyWith(
|
||||||
lastUsed: DateTime.now(),
|
lastUsed: DateTime.now(),
|
||||||
unreadMessageCount: 0,
|
unreadMessageCount: 0,
|
||||||
|
|
|
@ -1,39 +1,16 @@
|
||||||
<!--
|
# Firebase chat repository
|
||||||
This README describes the package. If you publish this package to pub.dev,
|
The firebase implementation of the chat_repository_interface
|
||||||
this README's contents appear on the landing page for your package.
|
|
||||||
|
|
||||||
For information about how to write a good package README, see the guide for
|
|
||||||
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
|
|
||||||
|
|
||||||
For general information about developing packages, see the Dart guide for
|
|
||||||
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
|
|
||||||
and the Flutter guide for
|
|
||||||
[developing packages and plugins](https://flutter.dev/developing-packages).
|
|
||||||
-->
|
|
||||||
|
|
||||||
TODO: Put a short description of the package here that helps potential users
|
|
||||||
know whether this package might be useful for them.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
|
||||||
|
|
||||||
## Getting started
|
|
||||||
|
|
||||||
TODO: List prerequisites and provide or point to information on how to
|
|
||||||
start using the package.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
TODO: Include short and useful examples for package users. Add longer examples
|
|
||||||
to `/example` folder.
|
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
const like = 'sample';
|
chatService: ChatService(
|
||||||
```
|
chatRepository: FirebaseChatRepository(
|
||||||
|
chatCollection: 'chats',
|
||||||
## Additional information
|
messageCollection: 'messages',
|
||||||
|
mediaPath: 'chat',
|
||||||
TODO: Tell users more about the package: where to find more information, how to
|
),
|
||||||
contribute to the package, how to file issues, what response they can expect
|
userRepository: FirebaseUserRepository(
|
||||||
from the package authors, and more.
|
userCollection: 'users',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
```
|
|
@ -1,5 +1,2 @@
|
||||||
/// A Calculator.
|
export 'src/firebase_chat_repository.dart';
|
||||||
class Calculator {
|
export 'src/firebase_user_repository.dart';
|
||||||
/// Returns [value] plus 1.
|
|
||||||
int addOne(int value) => value + 1;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,191 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:chat_repository_interface/chat_repository_interface.dart';
|
||||||
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||||
|
import 'package:firebase_storage/firebase_storage.dart';
|
||||||
|
|
||||||
|
class FirebaseChatRepository implements ChatRepositoryInterface {
|
||||||
|
final FirebaseFirestore _firestore;
|
||||||
|
final FirebaseStorage _storage;
|
||||||
|
final String chatCollection;
|
||||||
|
final String messageCollection;
|
||||||
|
final String mediaPath;
|
||||||
|
|
||||||
|
FirebaseChatRepository({
|
||||||
|
FirebaseFirestore? firestore,
|
||||||
|
FirebaseStorage? storage,
|
||||||
|
this.chatCollection = 'chats',
|
||||||
|
this.messageCollection = 'messages',
|
||||||
|
this.mediaPath = 'chat',
|
||||||
|
}) : _firestore = firestore ?? FirebaseFirestore.instance,
|
||||||
|
_storage = storage ?? FirebaseStorage.instance;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> createChat({
|
||||||
|
required List<String> users,
|
||||||
|
required bool isGroupChat,
|
||||||
|
String? chatName,
|
||||||
|
String? description,
|
||||||
|
String? imageUrl,
|
||||||
|
List<MessageModel>? messages,
|
||||||
|
}) async {
|
||||||
|
final chatData = {
|
||||||
|
'users': users,
|
||||||
|
'isGroupChat': isGroupChat,
|
||||||
|
'chatName': chatName,
|
||||||
|
'description': description,
|
||||||
|
'imageUrl': imageUrl,
|
||||||
|
'createdAt': DateTime.now().millisecondsSinceEpoch,
|
||||||
|
};
|
||||||
|
await _firestore.collection(chatCollection).add(chatData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> deleteChat({required String chatId}) async {
|
||||||
|
await _firestore.collection(chatCollection).doc(chatId).delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<ChatModel> getChat({required String chatId}) {
|
||||||
|
return _firestore
|
||||||
|
.collection(chatCollection)
|
||||||
|
.doc(chatId)
|
||||||
|
.snapshots()
|
||||||
|
.map((snapshot) {
|
||||||
|
var data = snapshot.data() as Map<String, dynamic>;
|
||||||
|
return ChatModel.fromMap(snapshot.id, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<List<ChatModel>?> getChats({required String userId}) {
|
||||||
|
return _firestore
|
||||||
|
.collection(chatCollection)
|
||||||
|
.where('users', arrayContains: userId)
|
||||||
|
.snapshots()
|
||||||
|
.map((querySnapshot) {
|
||||||
|
return querySnapshot.docs.map((doc) {
|
||||||
|
var data = doc.data();
|
||||||
|
return ChatModel.fromMap(doc.id, data);
|
||||||
|
}).toList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<MessageModel?> getMessage(
|
||||||
|
{required String chatId, required String messageId}) {
|
||||||
|
return _firestore
|
||||||
|
.collection(chatCollection)
|
||||||
|
.doc(chatId)
|
||||||
|
.collection(messageCollection)
|
||||||
|
.doc(messageId)
|
||||||
|
.snapshots()
|
||||||
|
.map((snapshot) {
|
||||||
|
var data = snapshot.data() as Map<String, dynamic>;
|
||||||
|
return MessageModel.fromMap(
|
||||||
|
snapshot.id,
|
||||||
|
data,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<List<MessageModel>?> getMessages({
|
||||||
|
required String chatId,
|
||||||
|
required String userId,
|
||||||
|
required int pageSize,
|
||||||
|
required int page,
|
||||||
|
}) {
|
||||||
|
return _firestore
|
||||||
|
.collection(chatCollection)
|
||||||
|
.doc(chatId)
|
||||||
|
.collection(messageCollection)
|
||||||
|
.orderBy('timestamp')
|
||||||
|
.limit(pageSize)
|
||||||
|
.snapshots()
|
||||||
|
.map((query) => query.docs
|
||||||
|
.map((snapshot) => MessageModel.fromMap(
|
||||||
|
snapshot.id,
|
||||||
|
snapshot.data(),
|
||||||
|
))
|
||||||
|
.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<int> getUnreadMessagesCount(
|
||||||
|
{required String userId, String? chatId}) async* {
|
||||||
|
var query = _firestore
|
||||||
|
.collection(chatCollection)
|
||||||
|
.where('users', arrayContains: userId)
|
||||||
|
.where('unreadMessageCount', isGreaterThan: 0)
|
||||||
|
.snapshots();
|
||||||
|
|
||||||
|
await for (var snapshot in query) {
|
||||||
|
var count = 0;
|
||||||
|
for (var doc in snapshot.docs) {
|
||||||
|
var data = doc.data();
|
||||||
|
var lastMessageKey = data['lastMessage'];
|
||||||
|
|
||||||
|
var message =
|
||||||
|
await getMessage(chatId: doc.id, messageId: lastMessageKey).first;
|
||||||
|
if (message?.senderId != userId) {
|
||||||
|
count += data['unreadMessageCount'] as int;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yield count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> sendMessage({
|
||||||
|
required String chatId,
|
||||||
|
required String senderId,
|
||||||
|
required String messageId,
|
||||||
|
String? text,
|
||||||
|
String? imageUrl,
|
||||||
|
DateTime? timestamp,
|
||||||
|
}) async {
|
||||||
|
var message = MessageModel(
|
||||||
|
chatId: chatId,
|
||||||
|
id: messageId,
|
||||||
|
text: text,
|
||||||
|
imageUrl: imageUrl,
|
||||||
|
timestamp: timestamp ?? DateTime.now(),
|
||||||
|
senderId: senderId);
|
||||||
|
|
||||||
|
await _firestore
|
||||||
|
.collection(chatCollection)
|
||||||
|
.doc(chatId)
|
||||||
|
.collection(messageCollection)
|
||||||
|
.doc(messageId)
|
||||||
|
.set(
|
||||||
|
message.toMap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
await _firestore.collection(chatCollection).doc(chatId).update(
|
||||||
|
{
|
||||||
|
'lastMessage': messageId,
|
||||||
|
'unreadMessageCount': FieldValue.increment(1),
|
||||||
|
'lastUsed': DateTime.now().millisecondsSinceEpoch,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> updateChat({required ChatModel chat}) async {
|
||||||
|
await _firestore
|
||||||
|
.collection(chatCollection)
|
||||||
|
.doc(chat.id)
|
||||||
|
.update(chat.toMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String> uploadImage(
|
||||||
|
{required String path, required Uint8List image}) async {
|
||||||
|
final ref = _storage.ref().child(mediaPath).child(path);
|
||||||
|
final uploadTask = ref.putData(image);
|
||||||
|
final snapshot = await uploadTask.whenComplete(() => {});
|
||||||
|
return await snapshot.ref.getDownloadURL();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
import 'package:chat_repository_interface/chat_repository_interface.dart';
|
||||||
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||||
|
|
||||||
|
class FirebaseUserRepository implements UserRepositoryInterface {
|
||||||
|
final FirebaseFirestore _firestore;
|
||||||
|
final String userCollection;
|
||||||
|
|
||||||
|
FirebaseUserRepository({
|
||||||
|
FirebaseFirestore? firestore,
|
||||||
|
this.userCollection = 'users',
|
||||||
|
}) : _firestore = firestore ?? FirebaseFirestore.instance;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<List<UserModel>> getAllUsers() {
|
||||||
|
return _firestore
|
||||||
|
.collection(userCollection)
|
||||||
|
.snapshots()
|
||||||
|
.map((querySnapshot) {
|
||||||
|
return querySnapshot.docs
|
||||||
|
.map((doc) => UserModel.fromMap(
|
||||||
|
doc.id,
|
||||||
|
doc.data(),
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<UserModel> getUser({required String userId}) {
|
||||||
|
return _firestore
|
||||||
|
.collection(userCollection)
|
||||||
|
.doc(userId)
|
||||||
|
.snapshots()
|
||||||
|
.map((snapshot) {
|
||||||
|
return UserModel.fromMap(
|
||||||
|
snapshot.id,
|
||||||
|
snapshot.data() as Map<String, dynamic>,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ name: firebase_chat_repository
|
||||||
description: "A new Flutter package project."
|
description: "A new Flutter package project."
|
||||||
version: 0.0.1
|
version: 0.0.1
|
||||||
homepage:
|
homepage:
|
||||||
|
publish_to: 'none'
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.4.3 <4.0.0'
|
sdk: '>=3.4.3 <4.0.0'
|
||||||
|
@ -11,6 +12,12 @@ dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
|
chat_repository_interface:
|
||||||
|
path: ../chat_repository_interface
|
||||||
|
|
||||||
|
firebase_storage: any
|
||||||
|
cloud_firestore: any
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
2
packages/flutter_chat/example/.gitignore
vendored
2
packages/flutter_chat/example/.gitignore
vendored
|
@ -41,3 +41,5 @@ app.*.map.json
|
||||||
/android/app/debug
|
/android/app/debug
|
||||||
/android/app/profile
|
/android/app/profile
|
||||||
/android/app/release
|
/android/app/release
|
||||||
|
|
||||||
|
firebase_options.dart
|
1
packages/flutter_chat/example/firebase.json
Normal file
1
packages/flutter_chat/example/firebase.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"flutter":{"platforms":{"dart":{"lib/firebase_options.dart":{"projectId":"appshell-demo","configurations":{"android":"1:431820621472:android:6a0f2bc3559d17781babc5","web":"1:431820621472:web:f4b27eea24be24fd1babc5"}}},"android":{"default":{"projectId":"appshell-demo","appId":"1:431820621472:android:6a0f2bc3559d17781babc5","fileOutput":"android/app/google-services.json"}}}}}
|
|
@ -1,3 +1,7 @@
|
||||||
|
// import 'package:example/firebase_options.dart';
|
||||||
|
// import 'package:firebase_auth/firebase_auth.dart';
|
||||||
|
// import 'package:firebase_chat_repository/firebase_chat_repository.dart';
|
||||||
|
// import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_chat/flutter_chat.dart';
|
import 'package:flutter_chat/flutter_chat.dart';
|
||||||
|
|
||||||
|
@ -7,7 +11,6 @@ void main() {
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
const MyApp({super.key});
|
const MyApp({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
|
@ -16,6 +19,18 @@ class MyApp extends StatelessWidget {
|
||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
),
|
),
|
||||||
home: const MyHomePage(),
|
home: const MyHomePage(),
|
||||||
|
// FutureBuilder(
|
||||||
|
// future: Firebase.initializeApp(
|
||||||
|
// options: DefaultFirebaseOptions.currentPlatform,
|
||||||
|
// ),
|
||||||
|
// builder: (context, snapshot) {
|
||||||
|
// if (snapshot.connectionState != ConnectionState.done) {
|
||||||
|
// return const Center(
|
||||||
|
// child: CircularProgressIndicator(),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// return const MyHomePage();
|
||||||
|
// }),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +43,12 @@ class MyHomePage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MyHomePageState extends State<MyHomePage> {
|
class _MyHomePageState extends State<MyHomePage> {
|
||||||
|
// @override
|
||||||
|
// void initState() {
|
||||||
|
// FirebaseAuth.instance.signInAnonymously();
|
||||||
|
// super.initState();
|
||||||
|
// }
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
|
|
@ -13,6 +13,10 @@ dependencies:
|
||||||
cupertino_icons: ^1.0.8
|
cupertino_icons: ^1.0.8
|
||||||
flutter_chat:
|
flutter_chat:
|
||||||
path: ../
|
path: ../
|
||||||
|
# firebase_chat_repository:
|
||||||
|
# path: ../../firebase_chat_repository
|
||||||
|
# firebase_core: any
|
||||||
|
# firebase_auth: any
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -11,6 +11,7 @@ export "package:flutter_chat/src/flutter_chat_navigator_userstory.dart";
|
||||||
export "src/config/chat_builders.dart";
|
export "src/config/chat_builders.dart";
|
||||||
export "src/config/chat_options.dart";
|
export "src/config/chat_options.dart";
|
||||||
export "src/config/chat_translations.dart";
|
export "src/config/chat_translations.dart";
|
||||||
|
export 'src/config/screen_types.dart';
|
||||||
|
|
||||||
// Screens
|
// Screens
|
||||||
export "src/screens/chat_detail_screen.dart";
|
export "src/screens/chat_detail_screen.dart";
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_chat/src/config/chat_translations.dart";
|
import "package:flutter_chat/src/config/chat_translations.dart";
|
||||||
|
import "package:flutter_chat/src/config/screen_types.dart";
|
||||||
|
|
||||||
/// The chat builders
|
/// The chat builders
|
||||||
class ChatBuilders {
|
class ChatBuilders {
|
||||||
/// The chat builders constructor
|
/// The chat builders constructor
|
||||||
const ChatBuilders({
|
const ChatBuilders({
|
||||||
this.chatScreenScaffoldBuilder,
|
this.baseScreenBuilder,
|
||||||
this.newChatScreenScaffoldBuilder,
|
|
||||||
this.newGroupChatScreenScaffoldBuilder,
|
|
||||||
this.newGroupChatOverviewScaffoldBuilder,
|
|
||||||
this.chatProfileScaffoldBuilder,
|
|
||||||
this.messageInputBuilder,
|
this.messageInputBuilder,
|
||||||
this.chatDetailScaffoldBuilder,
|
|
||||||
this.chatRowContainerBuilder,
|
this.chatRowContainerBuilder,
|
||||||
this.groupAvatarBuilder,
|
this.groupAvatarBuilder,
|
||||||
this.imagePickerContainerBuilder,
|
this.imagePickerContainerBuilder,
|
||||||
|
@ -25,23 +21,21 @@ class ChatBuilders {
|
||||||
this.loadingWidgetBuilder,
|
this.loadingWidgetBuilder,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The chat screen scaffold builder
|
/// The base screen builder
|
||||||
final ScaffoldBuilder? chatScreenScaffoldBuilder;
|
/// This builder is used to build the base screen for the chat
|
||||||
|
/// You can switch on the [screenType] to build different screens
|
||||||
/// The new chat screen scaffold builder
|
/// ```dart
|
||||||
final ScaffoldBuilder? newChatScreenScaffoldBuilder;
|
/// baseScreenBuilder: (context, screenType, appBar, body) {
|
||||||
|
/// switch (screenType) {
|
||||||
/// The new group chat overview scaffold builder
|
/// case ScreenType.chatScreen:
|
||||||
final ScaffoldBuilder? newGroupChatOverviewScaffoldBuilder;
|
/// return Scaffold(
|
||||||
|
/// appBar: appBar,
|
||||||
/// The new group chat screen scaffold builder
|
/// body: body,
|
||||||
final ScaffoldBuilder? newGroupChatScreenScaffoldBuilder;
|
/// );
|
||||||
|
/// case ScreenType.chatDetailScreen:
|
||||||
/// The chat detail scaffold builder
|
/// // And so on....
|
||||||
final ScaffoldBuilder? chatDetailScaffoldBuilder;
|
/// ```
|
||||||
|
final BaseScreenBuilder? baseScreenBuilder;
|
||||||
/// The chat profile scaffold builder
|
|
||||||
final ScaffoldBuilder? chatProfileScaffoldBuilder;
|
|
||||||
|
|
||||||
/// The message input builder
|
/// The message input builder
|
||||||
final TextInputBuilder? messageInputBuilder;
|
final TextInputBuilder? messageInputBuilder;
|
||||||
|
@ -100,12 +94,12 @@ typedef TextInputBuilder = Widget Function(
|
||||||
ChatTranslations translations,
|
ChatTranslations translations,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// The scaffold builder
|
/// The base screen builder
|
||||||
typedef ScaffoldBuilder = Scaffold Function(
|
typedef BaseScreenBuilder = Widget Function(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
|
ScreenType screenType,
|
||||||
PreferredSizeWidget appBar,
|
PreferredSizeWidget appBar,
|
||||||
Widget body,
|
Widget body,
|
||||||
Color backgroundColor,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/// The container builder
|
/// The container builder
|
||||||
|
|
28
packages/flutter_chat/lib/src/config/screen_types.dart
Normal file
28
packages/flutter_chat/lib/src/config/screen_types.dart
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_chat/src/screens/chat_detail_screen.dart';
|
||||||
|
import 'package:flutter_chat/src/screens/chat_profile_screen.dart';
|
||||||
|
import 'package:flutter_chat/src/screens/chat_screen.dart';
|
||||||
|
import 'package:flutter_chat/src/screens/creation/new_chat_screen.dart';
|
||||||
|
import 'package:flutter_chat/src/screens/creation/new_group_chat_overview.dart';
|
||||||
|
import 'package:flutter_chat/src/screens/creation/new_group_chat_screen.dart';
|
||||||
|
|
||||||
|
enum ScreenType {
|
||||||
|
chatScreen(screen: ChatScreen),
|
||||||
|
chatDetailScreen(screen: ChatDetailScreen),
|
||||||
|
chatProfileScreen(screen: ChatProfileScreen),
|
||||||
|
newChatScreen(screen: NewChatScreen),
|
||||||
|
newGroupChatScreen(screen: NewGroupChatScreen),
|
||||||
|
newGroupChatOverview(screen: NewGroupChatOverview);
|
||||||
|
|
||||||
|
const ScreenType({
|
||||||
|
required this.screen,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Type screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension MapFromWidget on Widget {
|
||||||
|
ScreenType get mapScreenType {
|
||||||
|
return ScreenType.values.firstWhere((e) => e.screen == this.runtimeType);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ class FlutterChatEntryWidget extends StatefulWidget {
|
||||||
const FlutterChatEntryWidget({
|
const FlutterChatEntryWidget({
|
||||||
required this.userId,
|
required this.userId,
|
||||||
this.chatService,
|
this.chatService,
|
||||||
|
this.options,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
this.widgetSize = 75,
|
this.widgetSize = 75,
|
||||||
this.backgroundColor = Colors.grey,
|
this.backgroundColor = Colors.grey,
|
||||||
|
@ -46,6 +47,9 @@ class FlutterChatEntryWidget extends StatefulWidget {
|
||||||
/// Text style for the counter.
|
/// Text style for the counter.
|
||||||
final TextStyle? textStyle;
|
final TextStyle? textStyle;
|
||||||
|
|
||||||
|
/// The chat options
|
||||||
|
final ChatOptions? options;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<FlutterChatEntryWidget> createState() => _FlutterChatEntryWidgetState();
|
State<FlutterChatEntryWidget> createState() => _FlutterChatEntryWidgetState();
|
||||||
}
|
}
|
||||||
|
@ -69,6 +73,7 @@ class _FlutterChatEntryWidgetState extends State<FlutterChatEntryWidget> {
|
||||||
builder: (context) => FlutterChatNavigatorUserstory(
|
builder: (context) => FlutterChatNavigatorUserstory(
|
||||||
userId: widget.userId,
|
userId: widget.userId,
|
||||||
chatService: chatService,
|
chatService: chatService,
|
||||||
|
chatOptions: widget.options,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -100,9 +100,8 @@ class _NavigatorWrapper extends StatelessWidget {
|
||||||
chatService: chatService,
|
chatService: chatService,
|
||||||
chatOptions: chatOptions,
|
chatOptions: chatOptions,
|
||||||
chat: chat,
|
chat: chat,
|
||||||
onReadChat: (chat) async => chatService.markAsRead(
|
onReadChat: (chat) async =>
|
||||||
chatId: chat.id,
|
chatService.markAsRead(chatId: chat.id, userId: userId),
|
||||||
),
|
|
||||||
onPressChatTitle: (chat) async {
|
onPressChatTitle: (chat) async {
|
||||||
if (chat.isGroupChat) {
|
if (chat.isGroupChat) {
|
||||||
return route(context, chatProfileScreen(context, null, chat));
|
return route(context, chatProfileScreen(context, null, chat));
|
||||||
|
@ -117,7 +116,8 @@ class _NavigatorWrapper extends StatelessWidget {
|
||||||
onPressUserProfile: (user) =>
|
onPressUserProfile: (user) =>
|
||||||
route(context, chatProfileScreen(context, user, null)),
|
route(context, chatProfileScreen(context, user, null)),
|
||||||
onUploadImage: (data) async {
|
onUploadImage: (data) async {
|
||||||
var path = await chatService.uploadImage(path: "chats", image: data);
|
var path = await chatService.uploadImage(
|
||||||
|
path: "chats/${chat.id}-$userId-${DateTime.now()}", image: data);
|
||||||
|
|
||||||
await chatService.sendMessage(
|
await chatService.sendMessage(
|
||||||
messageId: "${chat.id}-$userId-${DateTime.now()}",
|
messageId: "${chat.id}-$userId-${DateTime.now()}",
|
||||||
|
@ -190,7 +190,8 @@ class _NavigatorWrapper extends StatelessWidget {
|
||||||
onComplete: (users, title, description, image) async {
|
onComplete: (users, title, description, image) async {
|
||||||
String? path;
|
String? path;
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
path = await chatService.uploadImage(path: "groups", image: image);
|
path = await chatService.uploadImage(
|
||||||
|
path: "groups/$title", image: image);
|
||||||
}
|
}
|
||||||
var chat = await createGroupChat(
|
var chat = await createGroupChat(
|
||||||
users,
|
users,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import "package:cached_network_image/cached_network_image.dart";
|
||||||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_chat/src/config/chat_options.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/screens/creation/widgets/image_picker.dart";
|
||||||
import "package:flutter_chat/src/services/date_formatter.dart";
|
import "package:flutter_chat/src/services/date_formatter.dart";
|
||||||
import "package:flutter_profile/flutter_profile.dart";
|
import "package:flutter_profile/flutter_profile.dart";
|
||||||
|
@ -85,46 +86,47 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
if (widget.chatOptions.builders.baseScreenBuilder == null) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: _AppBar(
|
||||||
|
chatTitle: chatTitle,
|
||||||
|
chatOptions: widget.chatOptions,
|
||||||
|
onPressChatTitle: widget.onPressChatTitle,
|
||||||
|
chatModel: widget.chat,
|
||||||
|
),
|
||||||
|
body: _Body(
|
||||||
|
chatService: widget.chatService,
|
||||||
|
options: widget.chatOptions,
|
||||||
|
chat: widget.chat,
|
||||||
|
currentUserId: widget.userId,
|
||||||
|
onPressUserProfile: widget.onPressUserProfile,
|
||||||
|
onUploadImage: widget.onUploadImage,
|
||||||
|
onMessageSubmit: widget.onMessageSubmit,
|
||||||
|
onReadChat: widget.onReadChat,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return widget.chatOptions.builders.chatDetailScaffoldBuilder?.call(
|
return widget.chatOptions.builders.baseScreenBuilder!.call(
|
||||||
context,
|
context,
|
||||||
_AppBar(
|
widget.mapScreenType,
|
||||||
chatTitle: chatTitle,
|
_AppBar(
|
||||||
chatOptions: widget.chatOptions,
|
chatTitle: chatTitle,
|
||||||
onPressChatTitle: widget.onPressChatTitle,
|
chatOptions: widget.chatOptions,
|
||||||
chatModel: widget.chat,
|
onPressChatTitle: widget.onPressChatTitle,
|
||||||
),
|
chatModel: widget.chat,
|
||||||
_Body(
|
),
|
||||||
chatService: widget.chatService,
|
_Body(
|
||||||
options: widget.chatOptions,
|
chatService: widget.chatService,
|
||||||
chat: widget.chat,
|
options: widget.chatOptions,
|
||||||
currentUserId: widget.userId,
|
chat: widget.chat,
|
||||||
onPressUserProfile: widget.onPressUserProfile,
|
currentUserId: widget.userId,
|
||||||
onUploadImage: widget.onUploadImage,
|
onPressUserProfile: widget.onPressUserProfile,
|
||||||
onMessageSubmit: widget.onMessageSubmit,
|
onUploadImage: widget.onUploadImage,
|
||||||
onReadChat: widget.onReadChat,
|
onMessageSubmit: widget.onMessageSubmit,
|
||||||
),
|
onReadChat: widget.onReadChat,
|
||||||
theme.scaffoldBackgroundColor,
|
),
|
||||||
) ??
|
);
|
||||||
Scaffold(
|
|
||||||
appBar: _AppBar(
|
|
||||||
chatTitle: chatTitle,
|
|
||||||
chatOptions: widget.chatOptions,
|
|
||||||
onPressChatTitle: widget.onPressChatTitle,
|
|
||||||
chatModel: widget.chat,
|
|
||||||
),
|
|
||||||
body: _Body(
|
|
||||||
chatService: widget.chatService,
|
|
||||||
options: widget.chatOptions,
|
|
||||||
chat: widget.chat,
|
|
||||||
currentUserId: widget.userId,
|
|
||||||
onPressUserProfile: widget.onPressUserProfile,
|
|
||||||
onUploadImage: widget.onUploadImage,
|
|
||||||
onMessageSubmit: widget.onMessageSubmit,
|
|
||||||
onReadChat: widget.onReadChat,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_chat/src/config/chat_options.dart";
|
import "package:flutter_chat/src/config/chat_options.dart";
|
||||||
|
import "package:flutter_chat/src/config/screen_types.dart";
|
||||||
import "package:flutter_profile/flutter_profile.dart";
|
import "package:flutter_profile/flutter_profile.dart";
|
||||||
|
|
||||||
/// The chat profile screen
|
/// The chat profile screen
|
||||||
|
@ -41,42 +42,43 @@ class ChatProfileScreen extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
if (options.builders.baseScreenBuilder == null) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: _AppBar(
|
||||||
|
user: userModel,
|
||||||
|
chat: chatModel,
|
||||||
|
options: options,
|
||||||
|
),
|
||||||
|
body: _Body(
|
||||||
|
currentUser: userId,
|
||||||
|
options: options,
|
||||||
|
service: service,
|
||||||
|
user: userModel,
|
||||||
|
chat: chatModel,
|
||||||
|
onTapUser: onTapUser,
|
||||||
|
onPressStartChat: onPressStartChat,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return options.builders.chatProfileScaffoldBuilder?.call(
|
return options.builders.baseScreenBuilder!.call(
|
||||||
context,
|
context,
|
||||||
_AppBar(
|
this.mapScreenType,
|
||||||
user: userModel,
|
_AppBar(
|
||||||
chat: chatModel,
|
user: userModel,
|
||||||
options: options,
|
chat: chatModel,
|
||||||
),
|
options: options,
|
||||||
_Body(
|
),
|
||||||
service: service,
|
_Body(
|
||||||
currentUser: userId,
|
currentUser: userId,
|
||||||
options: options,
|
options: options,
|
||||||
user: userModel,
|
service: service,
|
||||||
chat: chatModel,
|
user: userModel,
|
||||||
onTapUser: onTapUser,
|
chat: chatModel,
|
||||||
onPressStartChat: onPressStartChat,
|
onTapUser: onTapUser,
|
||||||
),
|
onPressStartChat: onPressStartChat,
|
||||||
theme.scaffoldBackgroundColor,
|
),
|
||||||
) ??
|
);
|
||||||
Scaffold(
|
|
||||||
appBar: _AppBar(
|
|
||||||
user: userModel,
|
|
||||||
chat: chatModel,
|
|
||||||
options: options,
|
|
||||||
),
|
|
||||||
body: _Body(
|
|
||||||
currentUser: userId,
|
|
||||||
options: options,
|
|
||||||
service: service,
|
|
||||||
user: userModel,
|
|
||||||
chat: chatModel,
|
|
||||||
onTapUser: onTapUser,
|
|
||||||
onPressStartChat: onPressStartChat,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_chat/src/config/chat_options.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/chat_translations.dart";
|
||||||
|
import "package:flutter_chat/src/config/screen_types.dart";
|
||||||
import "package:flutter_chat/src/services/date_formatter.dart";
|
import "package:flutter_chat/src/services/date_formatter.dart";
|
||||||
import "package:flutter_profile/flutter_profile.dart";
|
import "package:flutter_profile/flutter_profile.dart";
|
||||||
|
|
||||||
|
@ -39,39 +40,41 @@ class ChatScreen extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
if (chatOptions.builders.baseScreenBuilder == null) {
|
||||||
return chatOptions.builders.chatScreenScaffoldBuilder?.call(
|
return Scaffold(
|
||||||
context,
|
appBar: _AppBar(
|
||||||
_AppBar(
|
userId: userId,
|
||||||
userId: userId,
|
chatOptions: chatOptions,
|
||||||
chatOptions: chatOptions,
|
chatService: chatService,
|
||||||
chatService: chatService,
|
),
|
||||||
),
|
body: _Body(
|
||||||
_Body(
|
userId: userId,
|
||||||
userId: userId,
|
chatOptions: chatOptions,
|
||||||
chatOptions: chatOptions,
|
chatService: chatService,
|
||||||
chatService: chatService,
|
onPressChat: onPressChat,
|
||||||
onPressChat: onPressChat,
|
onPressStartChat: onPressStartChat,
|
||||||
onPressStartChat: onPressStartChat,
|
onDeleteChat: onDeleteChat,
|
||||||
onDeleteChat: onDeleteChat,
|
),
|
||||||
),
|
);
|
||||||
theme.scaffoldBackgroundColor,
|
}
|
||||||
) ??
|
|
||||||
Scaffold(
|
return chatOptions.builders.baseScreenBuilder!.call(
|
||||||
appBar: _AppBar(
|
context,
|
||||||
userId: userId,
|
this.mapScreenType,
|
||||||
chatOptions: chatOptions,
|
_AppBar(
|
||||||
chatService: chatService,
|
userId: userId,
|
||||||
),
|
chatOptions: chatOptions,
|
||||||
body: _Body(
|
chatService: chatService,
|
||||||
userId: userId,
|
),
|
||||||
chatOptions: chatOptions,
|
_Body(
|
||||||
chatService: chatService,
|
userId: userId,
|
||||||
onPressChat: onPressChat,
|
chatOptions: chatOptions,
|
||||||
onPressStartChat: onPressStartChat,
|
chatService: chatService,
|
||||||
onDeleteChat: onDeleteChat,
|
onPressChat: onPressChat,
|
||||||
),
|
onPressStartChat: onPressStartChat,
|
||||||
);
|
onDeleteChat: onDeleteChat,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,9 +398,13 @@ class _ChatListItem extends StatelessWidget {
|
||||||
|
|
||||||
var data = snapshot.data;
|
var data = snapshot.data;
|
||||||
|
|
||||||
|
var showUnreadMessageCount =
|
||||||
|
data != null && data.senderId != currentUserId;
|
||||||
|
|
||||||
return _ChatRow(
|
return _ChatRow(
|
||||||
title: chat.chatName ?? translations.groupNameEmpty,
|
title: chat.chatName ?? translations.groupNameEmpty,
|
||||||
unreadMessages: chat.unreadMessageCount,
|
unreadMessages:
|
||||||
|
showUnreadMessageCount ? chat.unreadMessageCount : 0,
|
||||||
subTitle: data != null
|
subTitle: data != null
|
||||||
? data.isTextMessage
|
? data.isTextMessage
|
||||||
? data.text
|
? data.text
|
||||||
|
@ -465,8 +472,12 @@ class _ChatListItem extends StatelessWidget {
|
||||||
|
|
||||||
var data = snapshot.data;
|
var data = snapshot.data;
|
||||||
|
|
||||||
|
var showUnreadMessageCount =
|
||||||
|
data != null && data.senderId != currentUserId;
|
||||||
|
|
||||||
return _ChatRow(
|
return _ChatRow(
|
||||||
unreadMessages: chat.unreadMessageCount,
|
unreadMessages:
|
||||||
|
showUnreadMessageCount ? chat.unreadMessageCount : 0,
|
||||||
avatar: options.builders.userAvatarBuilder?.call(
|
avatar: options.builders.userAvatarBuilder?.call(
|
||||||
context,
|
context,
|
||||||
otherUser,
|
otherUser,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_chat/src/config/chat_options.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_field.dart";
|
||||||
import "package:flutter_chat/src/screens/creation/widgets/search_icon.dart";
|
import "package:flutter_chat/src/screens/creation/widgets/search_icon.dart";
|
||||||
import "package:flutter_chat/src/screens/creation/widgets/user_list.dart";
|
import "package:flutter_chat/src/screens/creation/widgets/user_list.dart";
|
||||||
|
@ -44,74 +45,75 @@ class _NewChatScreenState extends State<NewChatScreen> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
if (widget.chatOptions.builders.baseScreenBuilder == null) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: _AppBar(
|
||||||
|
chatOptions: widget.chatOptions,
|
||||||
|
isSearching: _isSearching,
|
||||||
|
onSearch: (query) {
|
||||||
|
setState(() {
|
||||||
|
_isSearching = query.isNotEmpty;
|
||||||
|
this.query = query;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onPressedSearchIcon: () {
|
||||||
|
setState(() {
|
||||||
|
_isSearching = !_isSearching;
|
||||||
|
query = "";
|
||||||
|
});
|
||||||
|
|
||||||
return widget.chatOptions.builders.newChatScreenScaffoldBuilder?.call(
|
if (_isSearching) {
|
||||||
context,
|
_textFieldFocusNode.requestFocus();
|
||||||
_AppBar(
|
}
|
||||||
chatOptions: widget.chatOptions,
|
},
|
||||||
isSearching: _isSearching,
|
focusNode: _textFieldFocusNode,
|
||||||
onSearch: (query) {
|
),
|
||||||
setState(() {
|
body: _Body(
|
||||||
_isSearching = query.isNotEmpty;
|
chatOptions: widget.chatOptions,
|
||||||
this.query = query;
|
chatService: widget.chatService,
|
||||||
});
|
isSearching: _isSearching,
|
||||||
},
|
onPressCreateGroupChat: widget.onPressCreateGroupChat,
|
||||||
onPressedSearchIcon: () {
|
onPressCreateChat: widget.onPressCreateChat,
|
||||||
setState(() {
|
userId: widget.userId,
|
||||||
_isSearching = !_isSearching;
|
query: query,
|
||||||
query = "";
|
),
|
||||||
});
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (_isSearching) {
|
return widget.chatOptions.builders.baseScreenBuilder!.call(
|
||||||
_textFieldFocusNode.requestFocus();
|
context,
|
||||||
}
|
widget.mapScreenType,
|
||||||
},
|
_AppBar(
|
||||||
focusNode: _textFieldFocusNode,
|
chatOptions: widget.chatOptions,
|
||||||
),
|
isSearching: _isSearching,
|
||||||
_Body(
|
onSearch: (query) {
|
||||||
chatOptions: widget.chatOptions,
|
setState(() {
|
||||||
chatService: widget.chatService,
|
_isSearching = query.isNotEmpty;
|
||||||
isSearching: _isSearching,
|
this.query = query;
|
||||||
onPressCreateGroupChat: widget.onPressCreateGroupChat,
|
});
|
||||||
onPressCreateChat: widget.onPressCreateChat,
|
},
|
||||||
userId: widget.userId,
|
onPressedSearchIcon: () {
|
||||||
query: query,
|
setState(() {
|
||||||
),
|
_isSearching = !_isSearching;
|
||||||
theme.scaffoldBackgroundColor,
|
query = "";
|
||||||
) ??
|
});
|
||||||
Scaffold(
|
|
||||||
appBar: _AppBar(
|
|
||||||
chatOptions: widget.chatOptions,
|
|
||||||
isSearching: _isSearching,
|
|
||||||
onSearch: (query) {
|
|
||||||
setState(() {
|
|
||||||
_isSearching = query.isNotEmpty;
|
|
||||||
this.query = query;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onPressedSearchIcon: () {
|
|
||||||
setState(() {
|
|
||||||
_isSearching = !_isSearching;
|
|
||||||
query = "";
|
|
||||||
});
|
|
||||||
|
|
||||||
if (_isSearching) {
|
if (_isSearching) {
|
||||||
_textFieldFocusNode.requestFocus();
|
_textFieldFocusNode.requestFocus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
focusNode: _textFieldFocusNode,
|
focusNode: _textFieldFocusNode,
|
||||||
),
|
),
|
||||||
body: _Body(
|
_Body(
|
||||||
chatOptions: widget.chatOptions,
|
chatOptions: widget.chatOptions,
|
||||||
chatService: widget.chatService,
|
chatService: widget.chatService,
|
||||||
isSearching: _isSearching,
|
isSearching: _isSearching,
|
||||||
onPressCreateGroupChat: widget.onPressCreateGroupChat,
|
onPressCreateGroupChat: widget.onPressCreateGroupChat,
|
||||||
onPressCreateChat: widget.onPressCreateChat,
|
onPressCreateChat: widget.onPressCreateChat,
|
||||||
userId: widget.userId,
|
userId: widget.userId,
|
||||||
query: query,
|
query: query,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import "dart:typed_data";
|
||||||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_chat/src/config/chat_options.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/screens/creation/widgets/image_picker.dart";
|
||||||
import "package:flutter_profile/flutter_profile.dart";
|
import "package:flutter_profile/flutter_profile.dart";
|
||||||
|
|
||||||
|
@ -34,30 +35,31 @@ class NewGroupChatOverview extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
if (options.builders.baseScreenBuilder == null) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: _AppBar(
|
||||||
|
options: options,
|
||||||
|
),
|
||||||
|
body: _Body(
|
||||||
|
options: options,
|
||||||
|
users: users,
|
||||||
|
onComplete: onComplete,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return options.builders.newGroupChatOverviewScaffoldBuilder?.call(
|
return options.builders.baseScreenBuilder!.call(
|
||||||
context,
|
context,
|
||||||
_AppBar(
|
this.mapScreenType,
|
||||||
options: options,
|
_AppBar(
|
||||||
),
|
options: options,
|
||||||
_Body(
|
),
|
||||||
options: options,
|
_Body(
|
||||||
users: users,
|
options: options,
|
||||||
onComplete: onComplete,
|
users: users,
|
||||||
),
|
onComplete: onComplete,
|
||||||
theme.scaffoldBackgroundColor,
|
),
|
||||||
) ??
|
);
|
||||||
Scaffold(
|
|
||||||
appBar: _AppBar(
|
|
||||||
options: options,
|
|
||||||
),
|
|
||||||
body: _Body(
|
|
||||||
options: options,
|
|
||||||
users: users,
|
|
||||||
onComplete: onComplete,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_chat/src/config/chat_options.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_field.dart";
|
||||||
import "package:flutter_chat/src/screens/creation/widgets/search_icon.dart";
|
import "package:flutter_chat/src/screens/creation/widgets/search_icon.dart";
|
||||||
import "package:flutter_chat/src/screens/creation/widgets/user_list.dart";
|
import "package:flutter_chat/src/screens/creation/widgets/user_list.dart";
|
||||||
|
@ -42,76 +43,77 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
if (widget.chatOptions.builders.baseScreenBuilder == null) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: _AppBar(
|
||||||
|
chatOptions: widget.chatOptions,
|
||||||
|
isSearching: _isSearching,
|
||||||
|
onSearch: (query) {
|
||||||
|
setState(() {
|
||||||
|
_isSearching = query.isNotEmpty;
|
||||||
|
this.query = query;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onPressedSearchIcon: () {
|
||||||
|
setState(() {
|
||||||
|
_isSearching = !_isSearching;
|
||||||
|
query = "";
|
||||||
|
});
|
||||||
|
|
||||||
return widget.chatOptions.builders.newGroupChatScreenScaffoldBuilder?.call(
|
if (_isSearching) {
|
||||||
context,
|
_textFieldFocusNode.requestFocus();
|
||||||
_AppBar(
|
}
|
||||||
chatOptions: widget.chatOptions,
|
},
|
||||||
isSearching: _isSearching,
|
focusNode: _textFieldFocusNode,
|
||||||
onSearch: (query) {
|
),
|
||||||
setState(() {
|
body: _Body(
|
||||||
_isSearching = query.isNotEmpty;
|
onSelectedUser: handleUserTap,
|
||||||
this.query = query;
|
selectedUsers: selectedUsers,
|
||||||
});
|
onPressGroupChatOverview: widget.onContinue,
|
||||||
},
|
chatOptions: widget.chatOptions,
|
||||||
onPressedSearchIcon: () {
|
chatService: widget.chatService,
|
||||||
setState(() {
|
isSearching: _isSearching,
|
||||||
_isSearching = !_isSearching;
|
userId: widget.userId,
|
||||||
query = "";
|
query: query,
|
||||||
});
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (_isSearching) {
|
return widget.chatOptions.builders.baseScreenBuilder!.call(
|
||||||
_textFieldFocusNode.requestFocus();
|
context,
|
||||||
}
|
widget.mapScreenType,
|
||||||
},
|
_AppBar(
|
||||||
focusNode: _textFieldFocusNode,
|
chatOptions: widget.chatOptions,
|
||||||
),
|
isSearching: _isSearching,
|
||||||
_Body(
|
onSearch: (query) {
|
||||||
onSelectedUser: handleUserTap,
|
setState(() {
|
||||||
selectedUsers: selectedUsers,
|
_isSearching = query.isNotEmpty;
|
||||||
onPressGroupChatOverview: widget.onContinue,
|
this.query = query;
|
||||||
chatOptions: widget.chatOptions,
|
});
|
||||||
chatService: widget.chatService,
|
},
|
||||||
isSearching: _isSearching,
|
onPressedSearchIcon: () {
|
||||||
userId: widget.userId,
|
setState(() {
|
||||||
query: query,
|
_isSearching = !_isSearching;
|
||||||
),
|
query = "";
|
||||||
theme.scaffoldBackgroundColor,
|
});
|
||||||
) ??
|
|
||||||
Scaffold(
|
|
||||||
appBar: _AppBar(
|
|
||||||
chatOptions: widget.chatOptions,
|
|
||||||
isSearching: _isSearching,
|
|
||||||
onSearch: (query) {
|
|
||||||
setState(() {
|
|
||||||
_isSearching = query.isNotEmpty;
|
|
||||||
this.query = query;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onPressedSearchIcon: () {
|
|
||||||
setState(() {
|
|
||||||
_isSearching = !_isSearching;
|
|
||||||
query = "";
|
|
||||||
});
|
|
||||||
|
|
||||||
if (_isSearching) {
|
if (_isSearching) {
|
||||||
_textFieldFocusNode.requestFocus();
|
_textFieldFocusNode.requestFocus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
focusNode: _textFieldFocusNode,
|
focusNode: _textFieldFocusNode,
|
||||||
),
|
),
|
||||||
body: _Body(
|
_Body(
|
||||||
onSelectedUser: handleUserTap,
|
onSelectedUser: handleUserTap,
|
||||||
selectedUsers: selectedUsers,
|
selectedUsers: selectedUsers,
|
||||||
onPressGroupChatOverview: widget.onContinue,
|
onPressGroupChatOverview: widget.onContinue,
|
||||||
chatOptions: widget.chatOptions,
|
chatOptions: widget.chatOptions,
|
||||||
chatService: widget.chatService,
|
chatService: widget.chatService,
|
||||||
isSearching: _isSearching,
|
isSearching: _isSearching,
|
||||||
userId: widget.userId,
|
userId: widget.userId,
|
||||||
query: query,
|
query: query,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleUserTap(UserModel user) {
|
void handleUserTap(UserModel user) {
|
||||||
|
|
Loading…
Reference in a new issue