-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from waterbustech/feat/map-api-chat
Feat: Map API of chat feature
- Loading branch information
Showing
36 changed files
with
1,295 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
153 changes: 153 additions & 0 deletions
153
lib/core/api/chat/datasources/chat_remote_datasource.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import 'dart:isolate'; | ||
|
||
import 'package:dio/dio.dart'; | ||
import 'package:injectable/injectable.dart'; | ||
|
||
import 'package:waterbus_sdk/constants/api_enpoints.dart'; | ||
import 'package:waterbus_sdk/constants/http_status_code.dart'; | ||
import 'package:waterbus_sdk/core/api/base/base_remote_data.dart'; | ||
import 'package:waterbus_sdk/flutter_waterbus_sdk.dart'; | ||
import 'package:waterbus_sdk/utils/encrypt/encrypt.dart'; | ||
|
||
abstract class ChatRemoteDataSource { | ||
Future<List<Meeting>> getConversations({ | ||
required int skip, | ||
required int limit, | ||
required int status, | ||
}); | ||
Future<bool> deleteConversation({required int meetingId}); | ||
Future<Meeting?> leaveConversation({required int code}); | ||
Future<Meeting?> addMember({required int code, required int userId}); | ||
Future<Meeting?> deleteMember({required int code, required int userId}); | ||
Future<Meeting?> acceptInvite({required int code}); | ||
} | ||
|
||
@LazySingleton(as: ChatRemoteDataSource) | ||
class ChatRemoteDataSourceImpl extends ChatRemoteDataSource { | ||
final BaseRemoteData _remoteData; | ||
ChatRemoteDataSourceImpl( | ||
this._remoteData, | ||
); | ||
|
||
@override | ||
Future<List<Meeting>> getConversations({ | ||
required int skip, | ||
required int limit, | ||
required int status, | ||
}) async { | ||
final Response response = await _remoteData.getRoute( | ||
"${ApiEndpoints.meetingConversations}/$status", | ||
query: "limit=$limit&skip=$skip", | ||
); | ||
|
||
if ([StatusCode.ok, StatusCode.created].contains(response.statusCode)) { | ||
final ReceivePort receivePort = ReceivePort(); | ||
|
||
final Map<String, dynamic> message = { | ||
"conversations": (response.data as List) | ||
.map((meeting) => Meeting.fromMap(meeting)) | ||
.toList(), | ||
"sendPort": receivePort.sendPort, | ||
"key": WaterbusSdk.privateMessageKey, | ||
}; | ||
|
||
await Isolate.spawn(_handleDecryptLastMessage, message); | ||
|
||
return await receivePort.first; | ||
} | ||
|
||
return []; | ||
} | ||
|
||
static Future<void> _handleDecryptLastMessage( | ||
Map<String, dynamic> map, | ||
) async { | ||
final List<Meeting> conversations = map['conversations']; | ||
final SendPort sendPort = map['sendPort']; | ||
final String key = map['key']; | ||
final List<Meeting> conversationsDecrypt = []; | ||
for (final Meeting conversation in conversations) { | ||
if (conversation.latestMessage == null) continue; | ||
|
||
final String decrypt = await EncryptAES().decryptAES256( | ||
cipherText: conversation.latestMessage?.data ?? "", | ||
key: key, | ||
); | ||
|
||
conversationsDecrypt.add( | ||
conversation.copyWith( | ||
latestMessage: conversation.latestMessage?.copyWith(data: decrypt), | ||
), | ||
); | ||
} | ||
|
||
Isolate.exit(sendPort, conversationsDecrypt); | ||
} | ||
|
||
@override | ||
Future<bool> deleteConversation({required int meetingId}) async { | ||
final response = await _remoteData.deleteRoute( | ||
"${ApiEndpoints.chatsConversations}/$meetingId", | ||
); | ||
|
||
return [StatusCode.ok, StatusCode.created].contains(response.statusCode); | ||
} | ||
|
||
@override | ||
Future<Meeting?> leaveConversation({required int code}) async { | ||
final Response response = await _remoteData.deleteRoute( | ||
'${ApiEndpoints.meetings}/$code', | ||
); | ||
|
||
if (response.statusCode == StatusCode.ok) { | ||
final Map<String, dynamic> rawData = response.data; | ||
return Meeting.fromMap(rawData); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
@override | ||
Future<Meeting?> acceptInvite({required int code}) async { | ||
final Response response = await _remoteData.postRoute( | ||
'${ApiEndpoints.acceptInvite}/$code', | ||
); | ||
|
||
if ([StatusCode.ok, StatusCode.created].contains(response.statusCode)) { | ||
return Meeting.fromMap(response.data); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
@override | ||
Future<Meeting?> addMember({required int code, required int userId}) async { | ||
final Response response = await _remoteData.postRoute( | ||
'${ApiEndpoints.meetingMembers}/$code', | ||
body: {"userId": userId}, | ||
); | ||
|
||
if ([StatusCode.ok, StatusCode.created].contains(response.statusCode)) { | ||
return Meeting.fromMap(response.data); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
@override | ||
Future<Meeting?> deleteMember({ | ||
required int code, | ||
required int userId, | ||
}) async { | ||
final Response response = await _remoteData.deleteRoute( | ||
'${ApiEndpoints.meetingMembers}/$code', | ||
body: {"userId": userId}, | ||
); | ||
|
||
if ([StatusCode.ok, StatusCode.created].contains(response.statusCode)) { | ||
return Meeting.fromMap(response.data); | ||
} | ||
|
||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import 'package:injectable/injectable.dart'; | ||
|
||
import 'package:waterbus_sdk/core/api/chat/datasources/chat_remote_datasource.dart'; | ||
import 'package:waterbus_sdk/flutter_waterbus_sdk.dart'; | ||
|
||
abstract class ChatRepository { | ||
Future<List<Meeting>> getConversations({ | ||
required int status, | ||
required int limit, | ||
required int skip, | ||
}); | ||
Future<bool> deleteConversation(int meetingId); | ||
Future<Meeting?> leaveConversation({required int code}); | ||
Future<Meeting?> addMember({required int code, required int userId}); | ||
Future<Meeting?> deleteMember({required int code, required int userId}); | ||
Future<Meeting?> acceptInvite({required int code}); | ||
} | ||
|
||
@LazySingleton(as: ChatRepository) | ||
class ChatRepositoryImpl extends ChatRepository { | ||
final ChatRemoteDataSource _remoteDataSource; | ||
|
||
ChatRepositoryImpl( | ||
this._remoteDataSource, | ||
); | ||
|
||
@override | ||
Future<List<Meeting>> getConversations({ | ||
required int status, | ||
required limit, | ||
required skip, | ||
}) async { | ||
final List<Meeting> conversations = | ||
await _remoteDataSource.getConversations( | ||
skip: skip, | ||
limit: limit, | ||
status: status, | ||
); | ||
|
||
return conversations; | ||
} | ||
|
||
@override | ||
Future<bool> deleteConversation(int meetingId) async { | ||
final bool isSucceed = await _remoteDataSource.deleteConversation( | ||
meetingId: meetingId, | ||
); | ||
|
||
return isSucceed; | ||
} | ||
|
||
@override | ||
Future<Meeting?> leaveConversation({required int code}) async { | ||
final Meeting? meeting = await _remoteDataSource.leaveConversation( | ||
code: code, | ||
); | ||
|
||
return meeting; | ||
} | ||
|
||
@override | ||
Future<Meeting?> acceptInvite({required int code}) async { | ||
final Meeting? meeting = await _remoteDataSource.acceptInvite( | ||
code: code, | ||
); | ||
|
||
return meeting; | ||
} | ||
|
||
@override | ||
Future<Meeting?> addMember({required int code, required int userId}) async { | ||
final Meeting? member = await _remoteDataSource.addMember( | ||
code: code, | ||
userId: userId, | ||
); | ||
|
||
return member; | ||
} | ||
|
||
@override | ||
Future<Meeting?> deleteMember({ | ||
required int code, | ||
required int userId, | ||
}) async { | ||
final Meeting? meeting = await _remoteDataSource.deleteMember( | ||
code: code, | ||
userId: userId, | ||
); | ||
|
||
return meeting; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.