@ -0,0 +1,175 @@ | |||
import 'dart:convert'; | |||
import 'dart:io'; | |||
import 'package:http/http.dart' as http; | |||
import 'package:sqflite/sqflite.dart'; | |||
import 'package:uuid/uuid.dart'; | |||
import '/database/models/messages.dart'; | |||
import '/database/models/image_message.dart'; | |||
import '/database/models/text_messages.dart'; | |||
import '/database/models/conversation_users.dart'; | |||
import '/database/models/conversations.dart'; | |||
import '/database/models/my_profile.dart'; | |||
import '/utils/storage/database.dart'; | |||
import '/utils/storage/session_cookie.dart'; | |||
import '/utils/storage/write_file.dart'; | |||
class MessagesService { | |||
static Future<void> sendMessage(Conversation conversation, { | |||
String? data, | |||
List<File> files = const [] | |||
}) async { | |||
MyProfile profile = await MyProfile.getProfile(); | |||
var uuid = const Uuid(); | |||
ConversationUser currentUser = await getConversationUser(conversation, profile.id); | |||
List<Message> messages = []; | |||
List<Map<String, dynamic>> messagesToSend = []; | |||
final db = await getDatabaseConnection(); | |||
if (data != null) { | |||
TextMessage message = TextMessage( | |||
id: uuid.v4(), | |||
symmetricKey: '', | |||
userSymmetricKey: '', | |||
senderId: currentUser.userId, | |||
senderUsername: profile.username, | |||
associationKey: currentUser.associationKey, | |||
createdAt: DateTime.now().toIso8601String(), | |||
failedToSend: false, | |||
text: data, | |||
); | |||
messages.add(message); | |||
messagesToSend.add(await message.payloadJson( | |||
conversation, | |||
)); | |||
await db.insert( | |||
'messages', | |||
message.toMap(), | |||
conflictAlgorithm: ConflictAlgorithm.replace, | |||
); | |||
} | |||
for (File file in files) { | |||
String messageId = uuid.v4(); | |||
File writtenFile = await writeImage( | |||
messageId, | |||
file.readAsBytesSync(), | |||
); | |||
ImageMessage message = ImageMessage( | |||
id: messageId, | |||
symmetricKey: '', | |||
userSymmetricKey: '', | |||
senderId: currentUser.userId, | |||
senderUsername: profile.username, | |||
associationKey: currentUser.associationKey, | |||
createdAt: DateTime.now().toIso8601String(), | |||
failedToSend: false, | |||
file: writtenFile, | |||
); | |||
messages.add(message); | |||
messagesToSend.add(await message.payloadJson( | |||
conversation, | |||
)); | |||
await db.insert( | |||
'messages', | |||
message.toMap(), | |||
conflictAlgorithm: ConflictAlgorithm.replace, | |||
); | |||
} | |||
String sessionCookie = await getSessionCookie(); | |||
return http.post( | |||
await MyProfile.getServerUrl('api/v1/auth/message'), | |||
headers: <String, String>{ | |||
'Content-Type': 'application/json; charset=UTF-8', | |||
'cookie': sessionCookie, | |||
}, | |||
body: jsonEncode(messagesToSend), | |||
) | |||
.then((resp) { | |||
if (resp.statusCode != 204) { | |||
throw Exception('Unable to send message'); | |||
} | |||
}) | |||
.catchError((exception) { | |||
for (Message message in messages) { | |||
message.failedToSend = true; | |||
db.update( | |||
'messages', | |||
message.toMap(), | |||
where: 'id = ?', | |||
whereArgs: [message.id], | |||
); | |||
} | |||
throw exception; | |||
}); | |||
} | |||
static Future<void> updateMessageThread(Conversation conversation, {MyProfile? profile}) async { | |||
profile ??= await MyProfile.getProfile(); | |||
ConversationUser currentUser = await getConversationUser(conversation, profile.id); | |||
var resp = await http.get( | |||
await MyProfile.getServerUrl('api/v1/auth/messages/${currentUser.associationKey}'), | |||
headers: { | |||
'cookie': await getSessionCookie(), | |||
} | |||
); | |||
if (resp.statusCode != 200) { | |||
throw Exception(resp.body); | |||
} | |||
List<dynamic> messageThreadJson = jsonDecode(resp.body); | |||
final db = await getDatabaseConnection(); | |||
for (var i = 0; i < messageThreadJson.length; i++) { | |||
var messageJson = messageThreadJson[i] as Map<String, dynamic>; | |||
var message = messageJson['message_data']['attachment_id'] != null ? | |||
await ImageMessage.fromJson( | |||
messageJson, | |||
profile.privateKey!, | |||
) : | |||
TextMessage.fromJson( | |||
messageJson, | |||
profile.privateKey!, | |||
); | |||
ConversationUser messageUser = await getConversationUser(conversation, message.senderId); | |||
message.senderUsername = messageUser.username; | |||
await db.insert( | |||
'messages', | |||
message.toMap(), | |||
conflictAlgorithm: ConflictAlgorithm.replace, | |||
); | |||
} | |||
} | |||
static Future<void> updateMessageThreads({List<Conversation>? conversations}) async { | |||
MyProfile profile = await MyProfile.getProfile(); | |||
conversations ??= await getConversations(); | |||
for (var i = 0; i < conversations.length; i++) { | |||
await updateMessageThread(conversations[i], profile: profile); | |||
} | |||
} | |||
} |
@ -1,176 +0,0 @@ | |||
import 'dart:convert'; | |||
import 'dart:io'; | |||
import 'package:Envelope/utils/storage/write_file.dart'; | |||
import 'package:http/http.dart' as http; | |||
import 'package:sqflite/sqflite.dart'; | |||
import 'package:uuid/uuid.dart'; | |||
import '/database/models/messages.dart'; | |||
import '/database/models/image_message.dart'; | |||
import '/database/models/text_messages.dart'; | |||
import '/database/models/conversation_users.dart'; | |||
import '/database/models/conversations.dart'; | |||
import '/database/models/my_profile.dart'; | |||
import '/utils/storage/database.dart'; | |||
import '/utils/storage/session_cookie.dart'; | |||
Future<void> sendMessage(Conversation conversation, { | |||
String? data, | |||
List<File> files = const [] | |||
}) async { | |||
MyProfile profile = await MyProfile.getProfile(); | |||
var uuid = const Uuid(); | |||
ConversationUser currentUser = await getConversationUser(conversation, profile.id); | |||
List<Message> messages = []; | |||
List<Map<String, dynamic>> messagesToSend = []; | |||
final db = await getDatabaseConnection(); | |||
if (data != null) { | |||
TextMessage message = TextMessage( | |||
id: uuid.v4(), | |||
symmetricKey: '', | |||
userSymmetricKey: '', | |||
senderId: currentUser.userId, | |||
senderUsername: profile.username, | |||
associationKey: currentUser.associationKey, | |||
createdAt: DateTime.now().toIso8601String(), | |||
failedToSend: false, | |||
text: data, | |||
); | |||
messages.add(message); | |||
messagesToSend.add(await message.payloadJson( | |||
conversation, | |||
)); | |||
await db.insert( | |||
'messages', | |||
message.toMap(), | |||
conflictAlgorithm: ConflictAlgorithm.replace, | |||
); | |||
} | |||
for (File file in files) { | |||
String messageId = uuid.v4(); | |||
File writtenFile = await writeImage( | |||
messageId, | |||
file.readAsBytesSync(), | |||
); | |||
ImageMessage message = ImageMessage( | |||
id: messageId, | |||
symmetricKey: '', | |||
userSymmetricKey: '', | |||
senderId: currentUser.userId, | |||
senderUsername: profile.username, | |||
associationKey: currentUser.associationKey, | |||
createdAt: DateTime.now().toIso8601String(), | |||
failedToSend: false, | |||
file: writtenFile, | |||
); | |||
messages.add(message); | |||
messagesToSend.add(await message.payloadJson( | |||
conversation, | |||
)); | |||
await db.insert( | |||
'messages', | |||
message.toMap(), | |||
conflictAlgorithm: ConflictAlgorithm.replace, | |||
); | |||
} | |||
String sessionCookie = await getSessionCookie(); | |||
return http.post( | |||
await MyProfile.getServerUrl('api/v1/auth/message'), | |||
headers: <String, String>{ | |||
'Content-Type': 'application/json; charset=UTF-8', | |||
'cookie': sessionCookie, | |||
}, | |||
body: jsonEncode(messagesToSend), | |||
) | |||
.then((resp) { | |||
if (resp.statusCode != 204) { | |||
throw Exception('Unable to send message'); | |||
} | |||
}) | |||
.catchError((exception) { | |||
for (Message message in messages) { | |||
message.failedToSend = true; | |||
db.update( | |||
'messages', | |||
message.toMap(), | |||
where: 'id = ?', | |||
whereArgs: [message.id], | |||
); | |||
} | |||
throw exception; | |||
}); | |||
} | |||
Future<void> updateMessageThread(Conversation conversation, {MyProfile? profile}) async { | |||
profile ??= await MyProfile.getProfile(); | |||
ConversationUser currentUser = await getConversationUser(conversation, profile.id); | |||
var resp = await http.get( | |||
await MyProfile.getServerUrl('api/v1/auth/messages/${currentUser.associationKey}'), | |||
headers: { | |||
'cookie': await getSessionCookie(), | |||
} | |||
); | |||
if (resp.statusCode != 200) { | |||
throw Exception(resp.body); | |||
} | |||
List<dynamic> messageThreadJson = jsonDecode(resp.body); | |||
final db = await getDatabaseConnection(); | |||
for (var i = 0; i < messageThreadJson.length; i++) { | |||
var messageJson = messageThreadJson[i] as Map<String, dynamic>; | |||
var message = messageJson['message_data']['attachment_id'] != null ? | |||
await ImageMessage.fromJson( | |||
messageJson, | |||
profile.privateKey!, | |||
) : | |||
TextMessage.fromJson( | |||
messageJson, | |||
profile.privateKey!, | |||
); | |||
ConversationUser messageUser = await getConversationUser(conversation, message.senderId); | |||
message.senderUsername = messageUser.username; | |||
await db.insert( | |||
'messages', | |||
message.toMap(), | |||
conflictAlgorithm: ConflictAlgorithm.replace, | |||
); | |||
} | |||
} | |||
Future<void> updateMessageThreads({List<Conversation>? conversations}) async { | |||
// try { | |||
MyProfile profile = await MyProfile.getProfile(); | |||
conversations ??= await getConversations(); | |||
for (var i = 0; i < conversations.length; i++) { | |||
await updateMessageThread(conversations[i], profile: profile); | |||
} | |||
// } catch(SocketException) { | |||
// return; | |||
// } | |||
} |