mirror of
https://github.com/Iconica-Development/flutter_chat.git
synced 2025-05-18 10:23:51 +02:00
fix: add remaining documentation and fix deep nesting
This commit is contained in:
parent
b6fc7b2cb0
commit
bd14f5cd6d
8 changed files with 294 additions and 277 deletions
3
.fvmrc
Normal file
3
.fvmrc
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"flutter": "3.24.3"
|
||||
}
|
|
@ -25,6 +25,22 @@ class ChatModel {
|
|||
this.unreadMessageCount = 0,
|
||||
});
|
||||
|
||||
/// The factory chat model that creates a chat model from a map
|
||||
factory ChatModel.fromMap(String id, Map<String, dynamic> data) => 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,
|
||||
);
|
||||
|
||||
/// The chat id
|
||||
final String id;
|
||||
|
||||
|
@ -81,34 +97,17 @@ class ChatModel {
|
|||
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,
|
||||
);
|
||||
}
|
||||
|
||||
/// Creates a map representation of this object
|
||||
Map<String, dynamic> toMap() => {
|
||||
'users': users,
|
||||
'isGroupChat': isGroupChat,
|
||||
'chatName': chatName,
|
||||
'description': description,
|
||||
'imageUrl': imageUrl,
|
||||
'canBeDeleted': canBeDeleted,
|
||||
'lastUsed': lastUsed?.millisecondsSinceEpoch,
|
||||
'lastMessage': lastMessage,
|
||||
'unreadMessageCount': unreadMessageCount,
|
||||
"users": users,
|
||||
"isGroupChat": isGroupChat,
|
||||
"chatName": chatName,
|
||||
"description": description,
|
||||
"imageUrl": imageUrl,
|
||||
"canBeDeleted": canBeDeleted,
|
||||
"lastUsed": lastUsed?.millisecondsSinceEpoch,
|
||||
"lastMessage": lastMessage,
|
||||
"unreadMessageCount": unreadMessageCount,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,17 @@ class MessageModel {
|
|||
required this.senderId,
|
||||
});
|
||||
|
||||
/// Creates a message model instance given a map instance
|
||||
factory MessageModel.fromMap(String id, Map<String, dynamic> map) =>
|
||||
MessageModel(
|
||||
chatId: map["chatId"],
|
||||
id: id,
|
||||
text: map["text"],
|
||||
imageUrl: map["imageUrl"],
|
||||
timestamp: DateTime.fromMillisecondsSinceEpoch(map["timestamp"]),
|
||||
senderId: map["senderId"],
|
||||
);
|
||||
|
||||
/// The chat id
|
||||
final String chatId;
|
||||
|
||||
|
@ -52,26 +63,14 @@ class MessageModel {
|
|||
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,
|
||||
/// Creates a map representation of this object
|
||||
Map<String, dynamic> toMap() => {
|
||||
"chatId": chatId,
|
||||
"text": text,
|
||||
"imageUrl": imageUrl,
|
||||
"timestamp": timestamp.millisecondsSinceEpoch,
|
||||
"senderId": senderId,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Extension on [MessageModel] to check the message type
|
||||
|
|
|
@ -14,6 +14,14 @@ class UserModel {
|
|||
this.imageUrl,
|
||||
});
|
||||
|
||||
/// Creates a user based on a given map [data]
|
||||
factory UserModel.fromMap(String id, Map<String, dynamic> data) => UserModel(
|
||||
id: id,
|
||||
firstName: data["first_name"],
|
||||
lastName: data["last_name"],
|
||||
imageUrl: data["image_url"],
|
||||
);
|
||||
|
||||
/// The user id
|
||||
final String id;
|
||||
|
||||
|
@ -25,15 +33,6 @@ class UserModel {
|
|||
|
||||
/// The user image url
|
||||
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
|
||||
|
|
|
@ -1,24 +1,28 @@
|
|||
import 'dart:typed_data';
|
||||
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';
|
||||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||
import "package:cloud_firestore/cloud_firestore.dart";
|
||||
import "package:firebase_storage/firebase_storage.dart";
|
||||
|
||||
/// Firebase implementation of the chat repository
|
||||
class FirebaseChatRepository implements ChatRepositoryInterface {
|
||||
final FirebaseFirestore _firestore;
|
||||
final FirebaseStorage _storage;
|
||||
final String chatCollection;
|
||||
final String messageCollection;
|
||||
final String mediaPath;
|
||||
|
||||
/// Creates a firebase implementation of the chat repository
|
||||
FirebaseChatRepository({
|
||||
FirebaseFirestore? firestore,
|
||||
FirebaseStorage? storage,
|
||||
this.chatCollection = 'chats',
|
||||
this.messageCollection = 'messages',
|
||||
this.mediaPath = 'chat',
|
||||
}) : _firestore = firestore ?? FirebaseFirestore.instance,
|
||||
String chatCollection = "chats",
|
||||
String messageCollection = "messages",
|
||||
String mediaPath = "chat",
|
||||
}) : _mediaPath = mediaPath,
|
||||
_messageCollection = messageCollection,
|
||||
_chatCollection = chatCollection,
|
||||
_firestore = firestore ?? FirebaseFirestore.instance,
|
||||
_storage = storage ?? FirebaseStorage.instance;
|
||||
final FirebaseFirestore _firestore;
|
||||
final FirebaseStorage _storage;
|
||||
final String _chatCollection;
|
||||
final String _messageCollection;
|
||||
final String _mediaPath;
|
||||
|
||||
@override
|
||||
Future<void> createChat({
|
||||
|
@ -29,65 +33,62 @@ class FirebaseChatRepository implements ChatRepositoryInterface {
|
|||
String? imageUrl,
|
||||
List<MessageModel>? messages,
|
||||
}) async {
|
||||
final chatData = {
|
||||
'users': users,
|
||||
'isGroupChat': isGroupChat,
|
||||
'chatName': chatName,
|
||||
'description': description,
|
||||
'imageUrl': imageUrl,
|
||||
'createdAt': DateTime.now().millisecondsSinceEpoch,
|
||||
var chatData = {
|
||||
"users": users,
|
||||
"isGroupChat": isGroupChat,
|
||||
"chatName": chatName,
|
||||
"description": description,
|
||||
"imageUrl": imageUrl,
|
||||
"createdAt": DateTime.now().millisecondsSinceEpoch,
|
||||
};
|
||||
await _firestore.collection(chatCollection).add(chatData);
|
||||
await _firestore.collection(_chatCollection).add(chatData);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteChat({required String chatId}) async {
|
||||
await _firestore.collection(chatCollection).doc(chatId).delete();
|
||||
await _firestore.collection(_chatCollection).doc(chatId).delete();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<ChatModel> getChat({required String chatId}) {
|
||||
return _firestore
|
||||
.collection(chatCollection)
|
||||
Stream<ChatModel> getChat({required String chatId}) => _firestore
|
||||
.collection(_chatCollection)
|
||||
.doc(chatId)
|
||||
.snapshots()
|
||||
.map((snapshot) {
|
||||
var data = snapshot.data() as Map<String, dynamic>;
|
||||
var data = snapshot.data()!;
|
||||
return ChatModel.fromMap(snapshot.id, data);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<List<ChatModel>?> getChats({required String userId}) {
|
||||
return _firestore
|
||||
.collection(chatCollection)
|
||||
.where('users', arrayContains: userId)
|
||||
Stream<List<ChatModel>?> getChats({required String userId}) => _firestore
|
||||
.collection(_chatCollection)
|
||||
.where("users", arrayContains: userId)
|
||||
.snapshots()
|
||||
.map((querySnapshot) {
|
||||
return querySnapshot.docs.map((doc) {
|
||||
.map(
|
||||
(querySnapshot) => querySnapshot.docs.map((doc) {
|
||||
var data = doc.data();
|
||||
return ChatModel.fromMap(doc.id, data);
|
||||
}).toList();
|
||||
});
|
||||
}
|
||||
}).toList(),
|
||||
);
|
||||
|
||||
@override
|
||||
Stream<MessageModel?> getMessage(
|
||||
{required String chatId, required String messageId}) {
|
||||
return _firestore
|
||||
.collection(chatCollection)
|
||||
Stream<MessageModel?> getMessage({
|
||||
required String chatId,
|
||||
required String messageId,
|
||||
}) =>
|
||||
_firestore
|
||||
.collection(_chatCollection)
|
||||
.doc(chatId)
|
||||
.collection(messageCollection)
|
||||
.collection(_messageCollection)
|
||||
.doc(messageId)
|
||||
.snapshots()
|
||||
.map((snapshot) {
|
||||
var data = snapshot.data() as Map<String, dynamic>;
|
||||
var data = snapshot.data()!;
|
||||
return MessageModel.fromMap(
|
||||
snapshot.id,
|
||||
data,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<List<MessageModel>?> getMessages({
|
||||
|
@ -95,41 +96,46 @@ class FirebaseChatRepository implements ChatRepositoryInterface {
|
|||
required String userId,
|
||||
required int pageSize,
|
||||
required int page,
|
||||
}) {
|
||||
return _firestore
|
||||
.collection(chatCollection)
|
||||
}) =>
|
||||
_firestore
|
||||
.collection(_chatCollection)
|
||||
.doc(chatId)
|
||||
.collection(messageCollection)
|
||||
.orderBy('timestamp')
|
||||
.collection(_messageCollection)
|
||||
.orderBy("timestamp")
|
||||
.limit(pageSize)
|
||||
.snapshots()
|
||||
.map((query) => query.docs
|
||||
.map((snapshot) => MessageModel.fromMap(
|
||||
.map(
|
||||
(query) => query.docs
|
||||
.map(
|
||||
(snapshot) => MessageModel.fromMap(
|
||||
snapshot.id,
|
||||
snapshot.data(),
|
||||
))
|
||||
.toList());
|
||||
}
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
|
||||
@override
|
||||
Stream<int> getUnreadMessagesCount(
|
||||
{required String userId, String? chatId}) async* {
|
||||
Stream<int> getUnreadMessagesCount({
|
||||
required String userId,
|
||||
String? chatId,
|
||||
}) async* {
|
||||
var query = _firestore
|
||||
.collection(chatCollection)
|
||||
.where('users', arrayContains: userId)
|
||||
.where('unreadMessageCount', isGreaterThan: 0)
|
||||
.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 lastMessageKey = data["lastMessage"];
|
||||
|
||||
var message =
|
||||
await getMessage(chatId: doc.id, messageId: lastMessageKey).first;
|
||||
if (message?.senderId != userId) {
|
||||
count += data['unreadMessageCount'] as int;
|
||||
count += data["unreadMessageCount"] as int;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,22 +158,23 @@ class FirebaseChatRepository implements ChatRepositoryInterface {
|
|||
text: text,
|
||||
imageUrl: imageUrl,
|
||||
timestamp: timestamp ?? DateTime.now(),
|
||||
senderId: senderId);
|
||||
senderId: senderId,
|
||||
);
|
||||
|
||||
await _firestore
|
||||
.collection(chatCollection)
|
||||
.collection(_chatCollection)
|
||||
.doc(chatId)
|
||||
.collection(messageCollection)
|
||||
.collection(_messageCollection)
|
||||
.doc(messageId)
|
||||
.set(
|
||||
message.toMap(),
|
||||
);
|
||||
|
||||
await _firestore.collection(chatCollection).doc(chatId).update(
|
||||
await _firestore.collection(_chatCollection).doc(chatId).update(
|
||||
{
|
||||
'lastMessage': messageId,
|
||||
'unreadMessageCount': FieldValue.increment(1),
|
||||
'lastUsed': DateTime.now().millisecondsSinceEpoch,
|
||||
"lastMessage": messageId,
|
||||
"unreadMessageCount": FieldValue.increment(1),
|
||||
"lastUsed": DateTime.now().millisecondsSinceEpoch,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -175,17 +182,19 @@ class FirebaseChatRepository implements ChatRepositoryInterface {
|
|||
@override
|
||||
Future<void> updateChat({required ChatModel chat}) async {
|
||||
await _firestore
|
||||
.collection(chatCollection)
|
||||
.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();
|
||||
Future<String> uploadImage({
|
||||
required String path,
|
||||
required Uint8List image,
|
||||
}) async {
|
||||
var ref = _storage.ref().child(_mediaPath).child(path);
|
||||
var uploadTask = ref.putData(image);
|
||||
var snapshot = await uploadTask.whenComplete(() => {});
|
||||
return snapshot.ref.getDownloadURL();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,36 @@
|
|||
import 'package:chat_repository_interface/chat_repository_interface.dart';
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import "package:chat_repository_interface/chat_repository_interface.dart";
|
||||
import "package:cloud_firestore/cloud_firestore.dart";
|
||||
|
||||
/// Firebase implementation of a user respository for chats.
|
||||
class FirebaseUserRepository implements UserRepositoryInterface {
|
||||
final FirebaseFirestore _firestore;
|
||||
final String userCollection;
|
||||
|
||||
/// Creates a firebase implementation of a user respository for chats.
|
||||
FirebaseUserRepository({
|
||||
FirebaseFirestore? firestore,
|
||||
this.userCollection = 'users',
|
||||
}) : _firestore = firestore ?? FirebaseFirestore.instance;
|
||||
String userCollection = "users",
|
||||
}) : _userCollection = userCollection,
|
||||
_firestore = firestore ?? FirebaseFirestore.instance;
|
||||
final FirebaseFirestore _firestore;
|
||||
final String _userCollection;
|
||||
|
||||
@override
|
||||
Stream<List<UserModel>> getAllUsers() {
|
||||
return _firestore
|
||||
.collection(userCollection)
|
||||
.snapshots()
|
||||
.map((querySnapshot) {
|
||||
return querySnapshot.docs
|
||||
.map((doc) => UserModel.fromMap(
|
||||
Stream<List<UserModel>> getAllUsers() =>
|
||||
_firestore.collection(_userCollection).snapshots().map(
|
||||
(querySnapshot) => querySnapshot.docs
|
||||
.map(
|
||||
(doc) => UserModel.fromMap(
|
||||
doc.id,
|
||||
doc.data(),
|
||||
))
|
||||
.toList();
|
||||
});
|
||||
}
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
|
||||
@override
|
||||
Stream<UserModel> getUser({required String userId}) {
|
||||
return _firestore
|
||||
.collection(userCollection)
|
||||
.doc(userId)
|
||||
.snapshots()
|
||||
.map((snapshot) {
|
||||
return UserModel.fromMap(
|
||||
Stream<UserModel> getUser({required String userId}) =>
|
||||
_firestore.collection(_userCollection).doc(userId).snapshots().map(
|
||||
(snapshot) => UserModel.fromMap(
|
||||
snapshot.id,
|
||||
snapshot.data() as Map<String, dynamic>,
|
||||
snapshot.data()!,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,41 @@
|
|||
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';
|
||||
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";
|
||||
|
||||
/// Type of screen, used in custom screen builders
|
||||
enum ScreenType {
|
||||
/// Screen displaying an overview of chats
|
||||
chatScreen(screen: ChatScreen),
|
||||
|
||||
/// Screen displaying a single chat
|
||||
chatDetailScreen(screen: ChatDetailScreen),
|
||||
|
||||
/// Screen displaying the profile of a user within a chat
|
||||
chatProfileScreen(screen: ChatProfileScreen),
|
||||
|
||||
/// Screen with a form to create a new chat
|
||||
newChatScreen(screen: NewChatScreen),
|
||||
|
||||
/// Screen with a form to create a new group chat
|
||||
newGroupChatScreen(screen: NewGroupChatScreen),
|
||||
|
||||
/// Screen displaying all group chats
|
||||
newGroupChatOverview(screen: NewGroupChatOverview);
|
||||
|
||||
const ScreenType({
|
||||
required this.screen,
|
||||
});
|
||||
required Type screen,
|
||||
}) : _screen = screen;
|
||||
|
||||
final Type screen;
|
||||
final Type _screen;
|
||||
}
|
||||
|
||||
/// Extension for mapping widgets to [ScreenType]s
|
||||
extension MapFromWidget on Widget {
|
||||
ScreenType get mapScreenType {
|
||||
return ScreenType.values.firstWhere((e) => e.screen == this.runtimeType);
|
||||
}
|
||||
/// returns corresponding [ScreenType]
|
||||
ScreenType get mapScreenType =>
|
||||
ScreenType.values.firstWhere((e) => e._screen == runtimeType);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ class ChatProfileScreen extends StatelessWidget {
|
|||
/// Callback function triggered when a user is tapped
|
||||
final Function(String)? onTapUser;
|
||||
|
||||
/// instance of a chat service
|
||||
final ChatService service;
|
||||
|
||||
/// Callback function triggered when the start chat button is pressed
|
||||
|
@ -135,6 +136,76 @@ class _Body extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var theme = Theme.of(context);
|
||||
|
||||
var chatUserDisplay = Wrap(
|
||||
children: [
|
||||
...chat!.users.map(
|
||||
(tappedUser) => Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 8,
|
||||
right: 8,
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
onTapUser?.call(tappedUser);
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
FutureBuilder<UserModel>(
|
||||
future: service.getUser(userId: tappedUser).first,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const CircularProgressIndicator();
|
||||
}
|
||||
|
||||
var user = snapshot.data;
|
||||
|
||||
if (user == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return options.builders.userAvatarBuilder?.call(
|
||||
context,
|
||||
user,
|
||||
44,
|
||||
) ??
|
||||
Avatar(
|
||||
boxfit: BoxFit.cover,
|
||||
user: User(
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
imageUrl:
|
||||
user.imageUrl != null || user.imageUrl != ""
|
||||
? user.imageUrl
|
||||
: null,
|
||||
),
|
||||
size: 60,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
var targetUser = user ??
|
||||
(
|
||||
chat != null
|
||||
? UserModel(
|
||||
id: UniqueKey().toString(),
|
||||
firstName: chat?.chatName,
|
||||
imageUrl: chat?.imageUrl,
|
||||
)
|
||||
: UserModel(
|
||||
id: UniqueKey().toString(),
|
||||
firstName: options.translations.groupNameEmpty,
|
||||
),
|
||||
) as UserModel;
|
||||
return Stack(
|
||||
children: [
|
||||
ListView(
|
||||
|
@ -145,20 +216,7 @@ class _Body extends StatelessWidget {
|
|||
children: [
|
||||
options.builders.userAvatarBuilder?.call(
|
||||
context,
|
||||
user ??
|
||||
(
|
||||
chat != null
|
||||
? UserModel(
|
||||
id: UniqueKey().toString(),
|
||||
firstName: chat?.chatName,
|
||||
imageUrl: chat?.imageUrl,
|
||||
)
|
||||
: UserModel(
|
||||
id: UniqueKey().toString(),
|
||||
firstName:
|
||||
options.translations.groupNameEmpty,
|
||||
),
|
||||
) as UserModel,
|
||||
targetUser,
|
||||
60,
|
||||
) ??
|
||||
Avatar(
|
||||
|
@ -223,65 +281,7 @@ class _Body extends StatelessWidget {
|
|||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Wrap(
|
||||
children: [
|
||||
...chat!.users.map(
|
||||
(tappedUser) => Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 8,
|
||||
right: 8,
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
onTapUser?.call(tappedUser);
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
FutureBuilder<UserModel>(
|
||||
future: service
|
||||
.getUser(userId: tappedUser)
|
||||
.first,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState ==
|
||||
ConnectionState.waiting) {
|
||||
return const CircularProgressIndicator();
|
||||
}
|
||||
|
||||
var user = snapshot.data;
|
||||
|
||||
if (user == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return options.builders.userAvatarBuilder
|
||||
?.call(
|
||||
context,
|
||||
user,
|
||||
44,
|
||||
) ??
|
||||
Avatar(
|
||||
boxfit: BoxFit.cover,
|
||||
user: User(
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
imageUrl: user.imageUrl != null ||
|
||||
user.imageUrl != ""
|
||||
? user.imageUrl
|
||||
: null,
|
||||
),
|
||||
size: 60,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
chatUserDisplay,
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue