veilidchat/lib/contacts/cubits/contact_list_cubit.dart

103 lines
3.4 KiB
Dart
Raw Normal View History

2024-01-30 17:03:14 -05:00
import 'dart:async';
import 'dart:convert';
import 'package:veilid_support/veilid_support.dart';
import '../../account_manager/account_manager.dart';
import '../../proto/proto.dart' as proto;
import '../../tools/tools.dart';
//////////////////////////////////////////////////
// Mutable state for per-account contacts
class ContactListCubit extends DHTShortArrayCubit<proto.Contact> {
ContactListCubit({
required ActiveAccountInfo activeAccountInfo,
required proto.Account account,
2024-03-28 22:46:26 -04:00
}) : super(
2024-01-30 17:03:14 -05:00
open: () => _open(activeAccountInfo, account),
decodeElement: proto.Contact.fromBuffer);
static Future<DHTShortArray> _open(
ActiveAccountInfo activeAccountInfo, proto.Account account) async {
final accountRecordKey =
activeAccountInfo.userLogin.accountRecordInfo.accountRecord.recordKey;
2024-02-12 09:10:07 -05:00
final contactListRecordKey = account.contactList.toVeilid();
2024-01-30 17:03:14 -05:00
final dhtRecord = await DHTShortArray.openOwned(contactListRecordKey,
parent: accountRecordKey);
return dhtRecord;
}
Future<void> createContact({
required proto.Profile remoteProfile,
required IdentityMaster remoteIdentity,
required TypedKey remoteConversationRecordKey,
required TypedKey localConversationRecordKey,
}) async {
// Create Contact
final contact = proto.Contact()
..editedProfile = remoteProfile
..remoteProfile = remoteProfile
..identityMasterJson = jsonEncode(remoteIdentity.toJson())
..identityPublicKey = TypedKey(
kind: remoteIdentity.identityRecordKey.kind,
value: remoteIdentity.identityPublicKey)
.toProto()
..remoteConversationRecordKey = remoteConversationRecordKey.toProto()
..localConversationRecordKey = localConversationRecordKey.toProto()
..showAvailability = false;
// Add Contact to account's list
// if this fails, don't keep retrying, user can try again later
2024-02-27 12:45:58 -05:00
await operate((shortArray) async {
if (await shortArray.tryAddItem(contact.writeToBuffer()) == false) {
throw Exception('Failed to add contact record');
}
});
2024-01-30 17:03:14 -05:00
}
Future<void> deleteContact({required proto.Contact contact}) async {
final pool = DHTRecordPool.instance;
2024-02-12 09:10:07 -05:00
final localConversationKey = contact.localConversationRecordKey.toVeilid();
2024-01-30 17:03:14 -05:00
final remoteConversationKey =
2024-02-12 09:10:07 -05:00
contact.remoteConversationRecordKey.toVeilid();
2024-01-30 17:03:14 -05:00
// Remove Contact from account's list
2024-03-28 22:46:26 -04:00
final deletedItem = await operate((shortArray) async {
2024-02-27 12:45:58 -05:00
for (var i = 0; i < shortArray.length; i++) {
final item =
await shortArray.getItemProtobuf(proto.Contact.fromBuffer, i);
if (item == null) {
throw Exception('Failed to get contact');
}
if (item.remoteConversationRecordKey ==
contact.remoteConversationRecordKey) {
2024-03-28 22:46:26 -04:00
if (await shortArray.tryRemoveItem(i) != null) {
return item;
}
return null;
2024-02-27 12:45:58 -05:00
}
2024-01-30 17:03:14 -05:00
}
2024-03-28 22:46:26 -04:00
return null;
});
if (deletedItem != null) {
2024-02-27 12:45:58 -05:00
try {
2024-03-28 22:46:26 -04:00
await pool.delete(localConversationKey);
2024-02-27 12:45:58 -05:00
} on Exception catch (e) {
log.debug('error removing local conversation record key: $e', e);
}
try {
if (localConversationKey != remoteConversationKey) {
2024-03-28 22:46:26 -04:00
await pool.delete(remoteConversationKey);
2024-02-27 12:45:58 -05:00
}
} on Exception catch (e) {
log.debug('error removing remote conversation record key: $e', e);
2024-01-30 17:03:14 -05:00
}
2024-03-28 22:46:26 -04:00
}
2024-01-30 17:03:14 -05:00
}
}