|
|
- import 'dart:convert';
- import 'dart:io';
- import 'dart:typed_data';
-
- import 'package:Envelope/database/models/conversation_users.dart';
- import 'package:sqflite/sql.dart';
- import 'package:uuid/uuid.dart';
-
- import '/database/models/conversations.dart';
- import '/database/models/friends.dart';
- import '/database/models/my_profile.dart';
- import '/utils/encryption/aes_helper.dart';
- import '/utils/strings.dart';
- import '/utils/storage/database.dart';
-
- class ConversationsRepository {
-
- static Future<Conversation> createConversation(String title, List<Friend> friends, bool twoUser) async {
- final db = await getDatabaseConnection();
-
- MyProfile profile = await MyProfile.getProfile();
-
- var uuid = const Uuid();
- final String conversationId = uuid.v4();
-
- Uint8List symmetricKey = AesHelper.deriveKey(generateRandomString(32));
-
- Conversation conversation = Conversation(
- id: conversationId,
- userId: profile.id,
- symmetricKey: base64.encode(symmetricKey),
- admin: true,
- name: title,
- twoUser: twoUser,
- status: ConversationStatus.pending,
- isRead: true,
- messageExpiryDefault: 'no_expiry',
- adminAddMembers: true,
- adminEditInfo: true,
- adminSendMessages: false,
- createdAt: DateTime.now(),
- updatedAt: DateTime.now(),
- );
-
- await db.insert(
- 'conversations',
- conversation.toMap(),
- conflictAlgorithm: ConflictAlgorithm.replace,
- );
-
- await db.insert(
- 'conversation_users',
- ConversationUser(
- id: uuid.v4(),
- userId: profile.id,
- conversationId: conversationId,
- username: profile.username,
- associationKey: uuid.v4(),
- publicKey: profile.publicKey!,
- admin: true,
- ).toMap(),
- conflictAlgorithm: ConflictAlgorithm.fail,
- );
-
- for (Friend friend in friends) {
- await db.insert(
- 'conversation_users',
- ConversationUser(
- id: uuid.v4(),
- userId: friend.friendId,
- conversationId: conversationId,
- username: friend.username,
- associationKey: uuid.v4(),
- publicKey: friend.publicKey,
- admin: twoUser ? true : false,
- ).toMap(),
- conflictAlgorithm: ConflictAlgorithm.replace,
- );
- }
-
- if (twoUser) {
- List<Map<String, dynamic>> maps = await db.query(
- 'conversation_users',
- where: 'conversation_id = ? AND user_id != ?',
- whereArgs: [ conversation.id, profile.id ],
- );
-
- if (maps.length != 1) {
- throw ArgumentError('Invalid user id');
- }
-
- conversation.name = maps[0]['username'];
-
- await db.insert(
- 'conversations',
- conversation.toMap(),
- conflictAlgorithm: ConflictAlgorithm.replace,
- );
- }
-
- return conversation;
- }
-
- static Future<Conversation> getConversationById(String id) async {
- final db = await getDatabaseConnection();
-
- final List<Map<String, dynamic>> maps = await db.query(
- 'conversations',
- where: 'id = ?',
- whereArgs: [id],
- );
-
- if (maps.length != 1) {
- throw ArgumentError('Invalid user id');
- }
-
- File? file;
- if (maps[0]['file'] != null && maps[0]['file'] != '') {
- file = File(maps[0]['file']);
- }
-
- return Conversation(
- id: maps[0]['id'],
- userId: maps[0]['user_id'],
- symmetricKey: maps[0]['symmetric_key'],
- admin: maps[0]['admin'] == 1,
- name: maps[0]['name'],
- twoUser: maps[0]['two_user'] == 1,
- status: ConversationStatus.values[maps[0]['status']],
- isRead: maps[0]['is_read'] == 1,
- icon: file,
- messageExpiryDefault: maps[0]['message_expiry'],
- adminAddMembers: maps[0]['admin_add_members'] == 1,
- adminEditInfo: maps[0]['admin_edit_info'] == 1,
- adminSendMessages: maps[0]['admin_send_messages'] == 1,
- createdAt: DateTime.parse(maps[0]['created_at']),
- updatedAt: DateTime.parse(maps[0]['updated_at']),
- );
- }
-
- static Future<List<Conversation>> getConversations() async {
- final db = await getDatabaseConnection();
-
- final List<Map<String, dynamic>> maps = await db.query(
- 'conversations',
- orderBy: 'name',
- );
-
- return List.generate(maps.length, (i) {
-
- File? file;
- if (maps[i]['file'] != null && maps[i]['file'] != '') {
- file = File(maps[i]['file']);
- }
-
- return Conversation(
- id: maps[i]['id'],
- userId: maps[i]['user_id'],
- symmetricKey: maps[i]['symmetric_key'],
- admin: maps[i]['admin'] == 1,
- name: maps[i]['name'],
- twoUser: maps[i]['two_user'] == 1,
- status: ConversationStatus.values[maps[i]['status']],
- isRead: maps[i]['is_read'] == 1,
- icon: file,
- messageExpiryDefault: maps[i]['message_expiry'] ?? 'no_expiry',
- adminAddMembers: maps[i]['admin_add_members'] == 1,
- adminEditInfo: maps[i]['admin_edit_info'] == 1,
- adminSendMessages: maps[i]['admin_send_messages'] == 1,
- createdAt: DateTime.parse(maps[i]['created_at']),
- updatedAt: DateTime.parse(maps[i]['updated_at']),
- );
- });
- }
-
- static Future<Conversation?> getTwoUserConversation(String userId) async {
- final db = await getDatabaseConnection();
-
- MyProfile profile = await MyProfile.getProfile();
-
- final List<Map<String, dynamic>> maps = await db.rawQuery(
- '''
- SELECT conversations.* FROM conversations
- LEFT JOIN conversation_users ON conversation_users.conversation_id = conversations.id
- WHERE conversation_users.user_id = ?
- AND conversation_users.user_id != ?
- AND conversations.two_user = 1
- ''',
- [ userId, profile.id ],
- );
-
- if (maps.length != 1) {
- return null;
- }
-
- return Conversation(
- id: maps[0]['id'],
- userId: maps[0]['user_id'],
- symmetricKey: maps[0]['symmetric_key'],
- admin: maps[0]['admin'] == 1,
- name: maps[0]['name'],
- twoUser: maps[0]['two_user'] == 1,
- status: ConversationStatus.values[maps[0]['status']],
- isRead: maps[0]['is_read'] == 1,
- messageExpiryDefault: maps[0]['message_expiry'],
- adminAddMembers: maps[0]['admin_add_members'] == 1,
- adminEditInfo: maps[0]['admin_edit_info'] == 1,
- adminSendMessages: maps[0]['admin_send_messages'] == 1,
- createdAt: DateTime.parse(maps[0]['created_at']),
- updatedAt: DateTime.parse(maps[0]['updated_at']),
- );
- }
-
- static Future<DateTime?> getLatestUpdatedAt() async {
- final db = await getDatabaseConnection();
-
- final List<Map<String, dynamic>> maps = await db.rawQuery(
- '''
- SELECT conversations.updated_at FROM conversations
- ORDER BY updated_at DESC
- LIMIT 1;
- '''
- );
-
- return maps.isNotEmpty ? DateTime.parse(maps[0]['updated_at']) : null;
- }
- }
-
|