Skip to content

Commit

Permalink
feat(chat): integrate the chat creation with the backend (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mo2Hefny authored Dec 1, 2024
1 parent 6957c58 commit 04f327f
Show file tree
Hide file tree
Showing 21 changed files with 324 additions and 171 deletions.
94 changes: 74 additions & 20 deletions lib/core/mock/user_mock.dart
Original file line number Diff line number Diff line change
@@ -1,23 +1,77 @@
import 'package:telware_cross_platform/core/models/user_model.dart';

final UserModel userMock = UserModel(
username: 'mock.user',
screenFirstName: 'Mocka',
screenLastName: 'Mocker',
email: 'mock@gmail.com',
status: 'online',
bio: 'I am a mocking user',
maxFileSize: 30,
automaticDownloadEnable: true,
lastSeenPrivacy: 'contacts',
readReceiptsEnablePrivacy: true,
storiesPrivacy: 'private',
picturePrivacy: 'everybody',
invitePermissionsPrivacy: 'admins',
phone: '+01100663311',
photo:
'https://static1.cbrimages.com/wordpress/wp-content/uploads/2023/05/jujutsu-kaisen-gojo-223.jpg',
id: '11',
);

const userMockPassword = 'qwerty99';
const userMockPassword = 'qwerty99';

final List<UserModel> mockUsers = [
UserModel(
username: 'mock.user',
screenFirstName: 'Mocka',
screenLastName: 'Mocker',
email: 'mock@gmail.com',
status: 'online',
bio: 'I am a mocking user',
maxFileSize: 30,
automaticDownloadEnable: true,
lastSeenPrivacy: 'contacts',
readReceiptsEnablePrivacy: true,
storiesPrivacy: 'private',
picturePrivacy: 'everybody',
invitePermissionsPrivacy: 'admins',
phone: '+01100663311',
id: '110',
),
UserModel(
username: 'mock.user1',
screenFirstName: 'Mocked',
screenLastName: 'Mocker',
email: 'mock1@gmail.com',
status: 'online',
bio: 'I am a mocking user 1',
maxFileSize: 30,
automaticDownloadEnable: true,
lastSeenPrivacy: 'contacts',
readReceiptsEnablePrivacy: true,
storiesPrivacy: 'private',
picturePrivacy: 'everybody',
invitePermissionsPrivacy: 'admins',
phone: '+01100663311',
id: '111',
),
UserModel(
username: 'mock.user2',
screenFirstName: 'Mocky',
screenLastName: 'Mocker',
email: 'mock2@gmail.com',
status: 'offline',
bio: 'I am a mocking user 2',
maxFileSize: 30,
automaticDownloadEnable: true,
lastSeenPrivacy: 'contacts',
readReceiptsEnablePrivacy: true,
storiesPrivacy: 'private',
picturePrivacy: 'everybody',
invitePermissionsPrivacy: 'admins',
phone: '+01100663312',
id: '112',
),
UserModel(
username: 'mock.user3',
screenFirstName: 'Mocko',
screenLastName: 'Mocker',
email: 'mock3@gmail.com',
status: 'busy',
bio: 'I am a mocking user 3',
maxFileSize: 30,
automaticDownloadEnable: true,
lastSeenPrivacy: 'contacts',
readReceiptsEnablePrivacy: true,
storiesPrivacy: 'private',
picturePrivacy: 'everybody',
invitePermissionsPrivacy: 'admins',
phone: '+01100663313',
id: '113',
),
];

const otherUserMockPassword = 'qwerty00';
13 changes: 13 additions & 0 deletions lib/core/models/chat_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,17 @@ class ChatModel {
}

String toJson() => json.encode(toMap());

String getChatTypeString() {
switch (type) {
case ChatType.private:
return 'private';
case ChatType.group:
return 'group';
case ChatType.channel:
return 'channel';
default:
return 'unknown';
}
}
}
18 changes: 9 additions & 9 deletions lib/core/models/user_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ class UserModel {

static Future<UserModel> fromMap(Map<String, dynamic> map) async {
String first = (map['screenFirstName'] as String?) ?? '';
String last = (map['screenFirstName'] as String?) ?? '';
String last = (map['screenLastName'] as String?) ?? '';
if (first.isEmpty) {
first = 'No';
last = 'Name';
Expand All @@ -211,16 +211,16 @@ class UserModel {
screenFirstName: first,
screenLastName: last,
email: (map['email'] as String?) ?? '',
photo: map['photo'] != null ? map['photo'] as String : null,
photo: map['photo'] != null && map['photo'] != "" ? map['photo'] as String : null,
status: map['status'] as String,
bio: map['bio'] as String,
maxFileSize: map['maxFileSize'] as int,
automaticDownloadEnable: map['automaticDownloadEnable'] as bool,
lastSeenPrivacy: map['lastSeenPrivacy'] as String,
readReceiptsEnablePrivacy: map['readReceiptsEnablePrivacy'] as bool,
storiesPrivacy: map['storiesPrivacy'] as String,
picturePrivacy: map['picturePrivacy'] as String,
invitePermissionsPrivacy: map['invitePermessionsPrivacy'] as String,
maxFileSize: map['maxFileSize'] ?? 0,
automaticDownloadEnable: map['automaticDownloadEnable'] ?? false,
lastSeenPrivacy: map['lastSeenPrivacy'] ?? '',
readReceiptsEnablePrivacy: map['readReceiptsEnablePrivacy'] ?? false,
storiesPrivacy: map['storiesPrivacy'] ?? '',
picturePrivacy: map['picturePrivacy'] ?? '',
invitePermissionsPrivacy: map['invitePermissionsPrivacy'] ?? '',
phone: (map['phoneNumber'] as String?) ?? '',
id: map['id'] as String,
);
Expand Down
3 changes: 3 additions & 0 deletions lib/core/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ String formatTimestamp(DateTime timestamp) {
}

IconData getMessageStateIcon(MessageModel message) {
if (message.id == null) {
return Icons.access_time;
}
if (message.isReadByAll()) {
return Icons.done_all;
}
Expand Down
25 changes: 18 additions & 7 deletions lib/features/auth/view_model/auth_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class AuthViewModel extends _$AuthViewModel {
}

if (USE_MOCK_DATA) {
final user = userMock;
final user = mockUsers[0];
ref.read(userProvider.notifier).update((_) => user);
state = AuthState.authenticated;
return;
Expand Down Expand Up @@ -110,8 +110,8 @@ class AuthViewModel extends _$AuthViewModel {

if (USE_MOCK_DATA) {
state = AuthState.verified;
ref.read(authLocalRepositoryProvider).setUser(userMock);
ref.read(userProvider.notifier).update((_) => userMock);
ref.read(authLocalRepositoryProvider).setUser(mockUsers[0]);
ref.read(userProvider.notifier).update((_) => mockUsers[0]);

ref.read(authLocalRepositoryProvider).setToken(tokenMock);
ref.read(tokenProvider.notifier).update((_) => tokenMock);
Expand Down Expand Up @@ -155,9 +155,20 @@ class AuthViewModel extends _$AuthViewModel {
state = AuthState.loading;

if (USE_MOCK_DATA) {
if (email == userMock.email && password == userMockPassword) {
ref.read(authLocalRepositoryProvider).setUser(userMock);
ref.read(userProvider.notifier).update((_) => userMock);
if (email == mockUsers[0].email && password == userMockPassword) {
ref.read(authLocalRepositoryProvider).setUser(mockUsers[0]);
ref.read(userProvider.notifier).update((_) => mockUsers[0]);

ref.read(authLocalRepositoryProvider).setToken(tokenMock);
ref.read(tokenProvider.notifier).update((_) => tokenMock);

await ref.read(chattingControllerProvider).newLoginInit();

state = AuthState.authenticated;
return;
} else if (email == mockUsers[1].email && password == otherUserMockPassword) {
ref.read(authLocalRepositoryProvider).setUser(mockUsers[1]);
ref.read(userProvider.notifier).update((_) => mockUsers[1]);

ref.read(authLocalRepositoryProvider).setToken(tokenMock);
ref.read(tokenProvider.notifier).update((_) => tokenMock);
Expand Down Expand Up @@ -319,7 +330,7 @@ class AuthViewModel extends _$AuthViewModel {
String? token = ref.read(tokenProvider);

if (USE_MOCK_DATA) {
final user = userMock;
final user = mockUsers[0];
ref.read(userProvider.notifier).update((_) => user);
state = AuthState.authenticated;
return;
Expand Down
2 changes: 1 addition & 1 deletion lib/features/auth/view_model/auth_view_model.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions lib/features/chat/repository/chat_remote_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,38 @@ class ChatRemoteRepository {
}
}

Future<({AppError? appError, ChatModel? chat})> createChat(
String sessionID, String name, String type, List<String> memberIDs) async {
try {
final response = await _dio.post(
'/chats',
data: {
'name': name,
'type': type,
'members': memberIDs,
},
options: Options(headers: {'X-Session-Token': sessionID}),
);

final chatData = response.data['data'];

final chatID = chatData['_id'];
final members = (chatData['members'] as List).cast<String>();

final chatModel = ChatModel(
id: chatID,
title: name,
userIds: members,
type: ChatType.getType(type),
messages: [],
);

return (appError: null, chat: chatModel);
} catch (e) {
debugPrint('!!! Failed to create chat, ${e.toString()}');
return (appError: AppError('Failed to create chat', code: 500), chat: null);
}
}

// TODO Implement Fetch Messages
}
26 changes: 19 additions & 7 deletions lib/features/chat/view/screens/chat_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,16 +187,28 @@ class _ChatScreen extends ConsumerState<ChatScreen>

//TODO: Implement the sendMsg method with another types of messages
void _sendMessage(WidgetRef ref) {
ref.read(chattingControllerProvider).sendMsg(
MessageModel newMessage = MessageModel(
senderId: ref.read(userProvider)!.id!,
messageContentType: MessageContentType.text,
content: TextContent(_messageController.text),
msgType: MessageType.normal,
contentType: MessageContentType.text,
chatType: ChatType.private,
chatID: widget.chatId,
timestamp: DateTime.now(),
messageType: MessageType.normal,
userStates: {},
);
_messageController.clear();
List<MessageModel> messages = ref.watch(chatProvider(widget.chatId))?.messages ?? [];
_updateChatMessages(messages);
_updateChatMessages([...chatContent, newMessage]);
ref.read(chattingControllerProvider).sendMsg(
content: newMessage.content!,
msgType: newMessage.messageType,
contentType: newMessage.messageContentType,
chatType: ChatType.private,
chatModel: chatModel,
).then((_) {
List<MessageModel> messages = ref.watch(chatProvider(chatModel!.id!))?.messages ?? [];
_updateChatMessages(messages);
_scrollToBottom();
});

}

//--------------------------------Recording--------------------------------
Expand Down
Loading

0 comments on commit 04f327f

Please # to comment.