mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2024-12-25 07:39:25 -05:00
switch to smpl key
This commit is contained in:
parent
e68cbb26eb
commit
ee80dbf3a5
@ -1,6 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
|
||||
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
|
||||
@ -61,13 +60,13 @@ class ChatComponentState extends ConsumerState<ChatComponent> {
|
||||
}
|
||||
|
||||
Future<void> _loadMessages() async {
|
||||
final localConversationOwned = proto.OwnedDHTRecordPointerProto.fromProto(
|
||||
widget.activeChatContact.localConversation);
|
||||
final localConversationRecordKey = proto.TypedKeyProto.fromProto(
|
||||
widget.activeChatContact.localConversationRecordKey);
|
||||
final remoteIdentityPublicKey = proto.TypedKeyProto.fromProto(
|
||||
widget.activeChatContact.identityPublicKey);
|
||||
final protoMessages = await getLocalConversationMessages(
|
||||
activeAccountInfo: widget.activeAccountInfo,
|
||||
localConversationOwned: localConversationOwned,
|
||||
localConversationRecordKey: localConversationRecordKey,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||
if (protoMessages == null) {
|
||||
return;
|
||||
@ -108,14 +107,14 @@ class ChatComponentState extends ConsumerState<ChatComponent> {
|
||||
});
|
||||
|
||||
// Now add the message to the conversation messages
|
||||
final localConversationOwned = proto.OwnedDHTRecordPointerProto.fromProto(
|
||||
widget.activeChatContact.localConversation);
|
||||
final localConversationRecordKey = proto.TypedKeyProto.fromProto(
|
||||
widget.activeChatContact.localConversationRecordKey);
|
||||
final remoteIdentityPublicKey = proto.TypedKeyProto.fromProto(
|
||||
widget.activeChatContact.identityPublicKey);
|
||||
|
||||
await addLocalConversationMessage(
|
||||
activeAccountInfo: widget.activeAccountInfo,
|
||||
localConversationOwned: localConversationOwned,
|
||||
localConversationRecordKey: localConversationRecordKey,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey,
|
||||
message: protoMessage);
|
||||
}
|
||||
|
@ -23,8 +23,9 @@ class ChatSingleContactItemWidget extends ConsumerWidget {
|
||||
final scale = theme.extension<ScaleScheme>()!;
|
||||
|
||||
final activeChat = ref.watch(activeChatStateProvider).asData?.value;
|
||||
final selected = activeChat ==
|
||||
proto.TypedKeyProto.fromProto(contact.remoteConversationKey);
|
||||
final remoteConversationRecordKey =
|
||||
proto.TypedKeyProto.fromProto(contact.remoteConversationRecordKey);
|
||||
final selected = activeChat == remoteConversationRecordKey;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.fromLTRB(4, 4, 4, 0),
|
||||
@ -47,8 +48,7 @@ class ChatSingleContactItemWidget extends ConsumerWidget {
|
||||
await deleteChat(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteConversationRecordKey:
|
||||
proto.TypedKeyProto.fromProto(
|
||||
contact.remoteConversationKey));
|
||||
remoteConversationRecordKey);
|
||||
ref.invalidate(fetchChatListProvider);
|
||||
}
|
||||
},
|
||||
@ -71,8 +71,7 @@ class ChatSingleContactItemWidget extends ConsumerWidget {
|
||||
// component is not dragged.
|
||||
child: ListTile(
|
||||
onTap: () async {
|
||||
activeChatState.add(proto.TypedKeyProto.fromProto(
|
||||
contact.remoteConversationKey));
|
||||
activeChatState.add(remoteConversationRecordKey);
|
||||
ref.invalidate(fetchChatListProvider);
|
||||
},
|
||||
title: Text(contact.editedProfile.name),
|
||||
|
@ -19,7 +19,8 @@ class ChatSingleContactListWidget extends ConsumerWidget {
|
||||
required this.chatList,
|
||||
super.key})
|
||||
: contactMap = IMap.fromIterable(contactList,
|
||||
keyMapper: (c) => c.remoteConversationKey, valueMapper: (c) => c);
|
||||
keyMapper: (c) => c.remoteConversationRecordKey,
|
||||
valueMapper: (c) => c);
|
||||
|
||||
final IMap<proto.TypedKey, proto.Contact> contactMap;
|
||||
final IList<proto.Chat> chatList;
|
||||
|
@ -24,7 +24,7 @@ class ContactItemWidget extends ConsumerWidget {
|
||||
final scale = theme.extension<ScaleScheme>()!;
|
||||
|
||||
final remoteConversationKey =
|
||||
proto.TypedKeyProto.fromProto(contact.remoteConversationKey);
|
||||
proto.TypedKeyProto.fromProto(contact.remoteConversationRecordKey);
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.fromLTRB(4, 4, 4, 0),
|
||||
@ -80,8 +80,12 @@ class ContactItemWidget extends ConsumerWidget {
|
||||
remoteConversationRecordKey: remoteConversationKey);
|
||||
|
||||
// Click over to chats
|
||||
await MainPager.of(context)?.pageController.animateToPage(1,
|
||||
duration: 250.ms, curve: Curves.easeInOut);
|
||||
if (context.mounted) {
|
||||
await MainPager.of(context)?.pageController.animateToPage(
|
||||
1,
|
||||
duration: 250.ms,
|
||||
curve: Curves.easeInOut);
|
||||
}
|
||||
}
|
||||
|
||||
// // ignore: use_build_context_synchronously
|
||||
|
@ -116,8 +116,10 @@ class PasteInviteDialogState extends ConsumerState<PasteInviteDialog> {
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
profile: acceptedContact.profile,
|
||||
remoteIdentity: acceptedContact.remoteIdentity,
|
||||
remoteConversationKey: acceptedContact.remoteConversationKey,
|
||||
localConversation: acceptedContact.localConversation,
|
||||
remoteConversationRecordKey:
|
||||
acceptedContact.remoteConversationRecordKey,
|
||||
localConversationRecordKey:
|
||||
acceptedContact.localConversationRecordKey,
|
||||
);
|
||||
ref
|
||||
..invalidate(fetchContactInvitationRecordsProvider)
|
||||
|
@ -1000,8 +1000,8 @@ class Contact extends $pb.GeneratedMessage {
|
||||
..aOM<Profile>(2, _omitFieldNames ? '' : 'remoteProfile', subBuilder: Profile.create)
|
||||
..aOS(3, _omitFieldNames ? '' : 'identityMasterJson')
|
||||
..aOM<TypedKey>(4, _omitFieldNames ? '' : 'identityPublicKey', subBuilder: TypedKey.create)
|
||||
..aOM<TypedKey>(5, _omitFieldNames ? '' : 'remoteConversationKey', subBuilder: TypedKey.create)
|
||||
..aOM<OwnedDHTRecordPointer>(6, _omitFieldNames ? '' : 'localConversation', subBuilder: OwnedDHTRecordPointer.create)
|
||||
..aOM<TypedKey>(5, _omitFieldNames ? '' : 'remoteConversationRecordKey', subBuilder: TypedKey.create)
|
||||
..aOM<TypedKey>(6, _omitFieldNames ? '' : 'localConversationRecordKey', subBuilder: TypedKey.create)
|
||||
..aOB(7, _omitFieldNames ? '' : 'showAvailability')
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
@ -1070,26 +1070,26 @@ class Contact extends $pb.GeneratedMessage {
|
||||
TypedKey ensureIdentityPublicKey() => $_ensure(3);
|
||||
|
||||
@$pb.TagNumber(5)
|
||||
TypedKey get remoteConversationKey => $_getN(4);
|
||||
TypedKey get remoteConversationRecordKey => $_getN(4);
|
||||
@$pb.TagNumber(5)
|
||||
set remoteConversationKey(TypedKey v) { setField(5, v); }
|
||||
set remoteConversationRecordKey(TypedKey v) { setField(5, v); }
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasRemoteConversationKey() => $_has(4);
|
||||
$core.bool hasRemoteConversationRecordKey() => $_has(4);
|
||||
@$pb.TagNumber(5)
|
||||
void clearRemoteConversationKey() => clearField(5);
|
||||
void clearRemoteConversationRecordKey() => clearField(5);
|
||||
@$pb.TagNumber(5)
|
||||
TypedKey ensureRemoteConversationKey() => $_ensure(4);
|
||||
TypedKey ensureRemoteConversationRecordKey() => $_ensure(4);
|
||||
|
||||
@$pb.TagNumber(6)
|
||||
OwnedDHTRecordPointer get localConversation => $_getN(5);
|
||||
TypedKey get localConversationRecordKey => $_getN(5);
|
||||
@$pb.TagNumber(6)
|
||||
set localConversation(OwnedDHTRecordPointer v) { setField(6, v); }
|
||||
set localConversationRecordKey(TypedKey v) { setField(6, v); }
|
||||
@$pb.TagNumber(6)
|
||||
$core.bool hasLocalConversation() => $_has(5);
|
||||
$core.bool hasLocalConversationRecordKey() => $_has(5);
|
||||
@$pb.TagNumber(6)
|
||||
void clearLocalConversation() => clearField(6);
|
||||
void clearLocalConversationRecordKey() => clearField(6);
|
||||
@$pb.TagNumber(6)
|
||||
OwnedDHTRecordPointer ensureLocalConversation() => $_ensure(5);
|
||||
TypedKey ensureLocalConversationRecordKey() => $_ensure(5);
|
||||
|
||||
@$pb.TagNumber(7)
|
||||
$core.bool get showAvailability => $_getBF(6);
|
||||
@ -1654,7 +1654,7 @@ class ContactResponse extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ContactResponse', createEmptyInstance: create)
|
||||
..aOB(1, _omitFieldNames ? '' : 'accept')
|
||||
..aOM<TypedKey>(2, _omitFieldNames ? '' : 'identityMasterRecordKey', subBuilder: TypedKey.create)
|
||||
..aOM<TypedKey>(3, _omitFieldNames ? '' : 'remoteConversationKey', subBuilder: TypedKey.create)
|
||||
..aOM<TypedKey>(3, _omitFieldNames ? '' : 'remoteConversationRecordKey', subBuilder: TypedKey.create)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@ -1700,15 +1700,15 @@ class ContactResponse extends $pb.GeneratedMessage {
|
||||
TypedKey ensureIdentityMasterRecordKey() => $_ensure(1);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
TypedKey get remoteConversationKey => $_getN(2);
|
||||
TypedKey get remoteConversationRecordKey => $_getN(2);
|
||||
@$pb.TagNumber(3)
|
||||
set remoteConversationKey(TypedKey v) { setField(3, v); }
|
||||
set remoteConversationRecordKey(TypedKey v) { setField(3, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasRemoteConversationKey() => $_has(2);
|
||||
$core.bool hasRemoteConversationRecordKey() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearRemoteConversationKey() => clearField(3);
|
||||
void clearRemoteConversationRecordKey() => clearField(3);
|
||||
@$pb.TagNumber(3)
|
||||
TypedKey ensureRemoteConversationKey() => $_ensure(2);
|
||||
TypedKey ensureRemoteConversationRecordKey() => $_ensure(2);
|
||||
}
|
||||
|
||||
class SignedContactResponse extends $pb.GeneratedMessage {
|
||||
@ -1775,7 +1775,7 @@ class ContactInvitationRecord extends $pb.GeneratedMessage {
|
||||
..aOM<OwnedDHTRecordPointer>(1, _omitFieldNames ? '' : 'contactRequestInbox', subBuilder: OwnedDHTRecordPointer.create)
|
||||
..aOM<CryptoKey>(2, _omitFieldNames ? '' : 'writerKey', subBuilder: CryptoKey.create)
|
||||
..aOM<CryptoKey>(3, _omitFieldNames ? '' : 'writerSecret', subBuilder: CryptoKey.create)
|
||||
..aOM<OwnedDHTRecordPointer>(4, _omitFieldNames ? '' : 'localConversation', subBuilder: OwnedDHTRecordPointer.create)
|
||||
..aOM<TypedKey>(4, _omitFieldNames ? '' : 'localConversationRecordKey', subBuilder: TypedKey.create)
|
||||
..a<$fixnum.Int64>(5, _omitFieldNames ? '' : 'expiration', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO)
|
||||
..a<$core.List<$core.int>>(6, _omitFieldNames ? '' : 'invitation', $pb.PbFieldType.OY)
|
||||
..aOS(7, _omitFieldNames ? '' : 'message')
|
||||
@ -1837,15 +1837,15 @@ class ContactInvitationRecord extends $pb.GeneratedMessage {
|
||||
CryptoKey ensureWriterSecret() => $_ensure(2);
|
||||
|
||||
@$pb.TagNumber(4)
|
||||
OwnedDHTRecordPointer get localConversation => $_getN(3);
|
||||
TypedKey get localConversationRecordKey => $_getN(3);
|
||||
@$pb.TagNumber(4)
|
||||
set localConversation(OwnedDHTRecordPointer v) { setField(4, v); }
|
||||
set localConversationRecordKey(TypedKey v) { setField(4, v); }
|
||||
@$pb.TagNumber(4)
|
||||
$core.bool hasLocalConversation() => $_has(3);
|
||||
$core.bool hasLocalConversationRecordKey() => $_has(3);
|
||||
@$pb.TagNumber(4)
|
||||
void clearLocalConversation() => clearField(4);
|
||||
void clearLocalConversationRecordKey() => clearField(4);
|
||||
@$pb.TagNumber(4)
|
||||
OwnedDHTRecordPointer ensureLocalConversation() => $_ensure(3);
|
||||
TypedKey ensureLocalConversationRecordKey() => $_ensure(3);
|
||||
|
||||
@$pb.TagNumber(5)
|
||||
$fixnum.Int64 get expiration => $_getI64(4);
|
||||
|
@ -303,8 +303,8 @@ const Contact$json = {
|
||||
{'1': 'remote_profile', '3': 2, '4': 1, '5': 11, '6': '.Profile', '10': 'remoteProfile'},
|
||||
{'1': 'identity_master_json', '3': 3, '4': 1, '5': 9, '10': 'identityMasterJson'},
|
||||
{'1': 'identity_public_key', '3': 4, '4': 1, '5': 11, '6': '.TypedKey', '10': 'identityPublicKey'},
|
||||
{'1': 'remote_conversation_key', '3': 5, '4': 1, '5': 11, '6': '.TypedKey', '10': 'remoteConversationKey'},
|
||||
{'1': 'local_conversation', '3': 6, '4': 1, '5': 11, '6': '.OwnedDHTRecordPointer', '10': 'localConversation'},
|
||||
{'1': 'remote_conversation_record_key', '3': 5, '4': 1, '5': 11, '6': '.TypedKey', '10': 'remoteConversationRecordKey'},
|
||||
{'1': 'local_conversation_record_key', '3': 6, '4': 1, '5': 11, '6': '.TypedKey', '10': 'localConversationRecordKey'},
|
||||
{'1': 'show_availability', '3': 7, '4': 1, '5': 8, '10': 'showAvailability'},
|
||||
],
|
||||
};
|
||||
@ -314,11 +314,11 @@ final $typed_data.Uint8List contactDescriptor = $convert.base64Decode(
|
||||
'CgdDb250YWN0Ei8KDmVkaXRlZF9wcm9maWxlGAEgASgLMgguUHJvZmlsZVINZWRpdGVkUHJvZm'
|
||||
'lsZRIvCg5yZW1vdGVfcHJvZmlsZRgCIAEoCzIILlByb2ZpbGVSDXJlbW90ZVByb2ZpbGUSMAoU'
|
||||
'aWRlbnRpdHlfbWFzdGVyX2pzb24YAyABKAlSEmlkZW50aXR5TWFzdGVySnNvbhI5ChNpZGVudG'
|
||||
'l0eV9wdWJsaWNfa2V5GAQgASgLMgkuVHlwZWRLZXlSEWlkZW50aXR5UHVibGljS2V5EkEKF3Jl'
|
||||
'bW90ZV9jb252ZXJzYXRpb25fa2V5GAUgASgLMgkuVHlwZWRLZXlSFXJlbW90ZUNvbnZlcnNhdG'
|
||||
'lvbktleRJFChJsb2NhbF9jb252ZXJzYXRpb24YBiABKAsyFi5Pd25lZERIVFJlY29yZFBvaW50'
|
||||
'ZXJSEWxvY2FsQ29udmVyc2F0aW9uEisKEXNob3dfYXZhaWxhYmlsaXR5GAcgASgIUhBzaG93QX'
|
||||
'ZhaWxhYmlsaXR5');
|
||||
'l0eV9wdWJsaWNfa2V5GAQgASgLMgkuVHlwZWRLZXlSEWlkZW50aXR5UHVibGljS2V5Ek4KHnJl'
|
||||
'bW90ZV9jb252ZXJzYXRpb25fcmVjb3JkX2tleRgFIAEoCzIJLlR5cGVkS2V5UhtyZW1vdGVDb2'
|
||||
'52ZXJzYXRpb25SZWNvcmRLZXkSTAodbG9jYWxfY29udmVyc2F0aW9uX3JlY29yZF9rZXkYBiAB'
|
||||
'KAsyCS5UeXBlZEtleVIabG9jYWxDb252ZXJzYXRpb25SZWNvcmRLZXkSKwoRc2hvd19hdmFpbG'
|
||||
'FiaWxpdHkYByABKAhSEHNob3dBdmFpbGFiaWxpdHk=');
|
||||
|
||||
@$core.Deprecated('Use profileDescriptor instead')
|
||||
const Profile$json = {
|
||||
@ -462,7 +462,7 @@ const ContactResponse$json = {
|
||||
'2': [
|
||||
{'1': 'accept', '3': 1, '4': 1, '5': 8, '10': 'accept'},
|
||||
{'1': 'identity_master_record_key', '3': 2, '4': 1, '5': 11, '6': '.TypedKey', '10': 'identityMasterRecordKey'},
|
||||
{'1': 'remote_conversation_key', '3': 3, '4': 1, '5': 11, '6': '.TypedKey', '10': 'remoteConversationKey'},
|
||||
{'1': 'remote_conversation_record_key', '3': 3, '4': 1, '5': 11, '6': '.TypedKey', '10': 'remoteConversationRecordKey'},
|
||||
],
|
||||
};
|
||||
|
||||
@ -470,8 +470,8 @@ const ContactResponse$json = {
|
||||
final $typed_data.Uint8List contactResponseDescriptor = $convert.base64Decode(
|
||||
'Cg9Db250YWN0UmVzcG9uc2USFgoGYWNjZXB0GAEgASgIUgZhY2NlcHQSRgoaaWRlbnRpdHlfbW'
|
||||
'FzdGVyX3JlY29yZF9rZXkYAiABKAsyCS5UeXBlZEtleVIXaWRlbnRpdHlNYXN0ZXJSZWNvcmRL'
|
||||
'ZXkSQQoXcmVtb3RlX2NvbnZlcnNhdGlvbl9rZXkYAyABKAsyCS5UeXBlZEtleVIVcmVtb3RlQ2'
|
||||
'9udmVyc2F0aW9uS2V5');
|
||||
'ZXkSTgoecmVtb3RlX2NvbnZlcnNhdGlvbl9yZWNvcmRfa2V5GAMgASgLMgkuVHlwZWRLZXlSG3'
|
||||
'JlbW90ZUNvbnZlcnNhdGlvblJlY29yZEtleQ==');
|
||||
|
||||
@$core.Deprecated('Use signedContactResponseDescriptor instead')
|
||||
const SignedContactResponse$json = {
|
||||
@ -495,7 +495,7 @@ const ContactInvitationRecord$json = {
|
||||
{'1': 'contact_request_inbox', '3': 1, '4': 1, '5': 11, '6': '.OwnedDHTRecordPointer', '10': 'contactRequestInbox'},
|
||||
{'1': 'writer_key', '3': 2, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'writerKey'},
|
||||
{'1': 'writer_secret', '3': 3, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'writerSecret'},
|
||||
{'1': 'local_conversation', '3': 4, '4': 1, '5': 11, '6': '.OwnedDHTRecordPointer', '10': 'localConversation'},
|
||||
{'1': 'local_conversation_record_key', '3': 4, '4': 1, '5': 11, '6': '.TypedKey', '10': 'localConversationRecordKey'},
|
||||
{'1': 'expiration', '3': 5, '4': 1, '5': 4, '10': 'expiration'},
|
||||
{'1': 'invitation', '3': 6, '4': 1, '5': 12, '10': 'invitation'},
|
||||
{'1': 'message', '3': 7, '4': 1, '5': 9, '10': 'message'},
|
||||
@ -507,8 +507,8 @@ final $typed_data.Uint8List contactInvitationRecordDescriptor = $convert.base64D
|
||||
'ChdDb250YWN0SW52aXRhdGlvblJlY29yZBJKChVjb250YWN0X3JlcXVlc3RfaW5ib3gYASABKA'
|
||||
'syFi5Pd25lZERIVFJlY29yZFBvaW50ZXJSE2NvbnRhY3RSZXF1ZXN0SW5ib3gSKQoKd3JpdGVy'
|
||||
'X2tleRgCIAEoCzIKLkNyeXB0b0tleVIJd3JpdGVyS2V5Ei8KDXdyaXRlcl9zZWNyZXQYAyABKA'
|
||||
'syCi5DcnlwdG9LZXlSDHdyaXRlclNlY3JldBJFChJsb2NhbF9jb252ZXJzYXRpb24YBCABKAsy'
|
||||
'Fi5Pd25lZERIVFJlY29yZFBvaW50ZXJSEWxvY2FsQ29udmVyc2F0aW9uEh4KCmV4cGlyYXRpb2'
|
||||
'4YBSABKARSCmV4cGlyYXRpb24SHgoKaW52aXRhdGlvbhgGIAEoDFIKaW52aXRhdGlvbhIYCgdt'
|
||||
'ZXNzYWdlGAcgASgJUgdtZXNzYWdl');
|
||||
'syCi5DcnlwdG9LZXlSDHdyaXRlclNlY3JldBJMCh1sb2NhbF9jb252ZXJzYXRpb25fcmVjb3Jk'
|
||||
'X2tleRgEIAEoCzIJLlR5cGVkS2V5Uhpsb2NhbENvbnZlcnNhdGlvblJlY29yZEtleRIeCgpleH'
|
||||
'BpcmF0aW9uGAUgASgEUgpleHBpcmF0aW9uEh4KCmludml0YXRpb24YBiABKAxSCmludml0YXRp'
|
||||
'b24SGAoHbWVzc2FnZRgHIAEoCVIHbWVzc2FnZQ==');
|
||||
|
||||
|
@ -204,9 +204,9 @@ message Contact {
|
||||
// Copy of friend's most recent identity public key from their identityMaster
|
||||
TypedKey identity_public_key = 4;
|
||||
// Remote conversation key to sync from friend
|
||||
TypedKey remote_conversation_key = 5;
|
||||
TypedKey remote_conversation_record_key = 5;
|
||||
// Our conversation key for friend to sync
|
||||
OwnedDHTRecordPointer local_conversation = 6;
|
||||
TypedKey local_conversation_record_key = 6;
|
||||
// Show availability
|
||||
bool show_availability = 7;
|
||||
}
|
||||
@ -343,7 +343,7 @@ message ContactResponse {
|
||||
// Remote identity master DHT record key
|
||||
TypedKey identity_master_record_key = 2;
|
||||
// Remote chat DHT record key if accepted
|
||||
TypedKey remote_conversation_key = 3;
|
||||
TypedKey remote_conversation_record_key = 3;
|
||||
}
|
||||
|
||||
// Signature of response with identity
|
||||
@ -364,7 +364,7 @@ message ContactInvitationRecord {
|
||||
// Writer secret sent encrypted in the invitation
|
||||
CryptoKey writer_secret = 3;
|
||||
// Local chat DHT record key (parent is accountkey, will be moved to Contact if accepted)
|
||||
OwnedDHTRecordPointer local_conversation = 4;
|
||||
TypedKey local_conversation_record_key = 4;
|
||||
// Expiration timestamp
|
||||
uint64 expiration = 5;
|
||||
// A copy of the raw SignedContactInvitation invitation bytes post-encryption and signing
|
||||
|
@ -14,6 +14,7 @@ import '../providers/account.dart';
|
||||
import '../providers/chat.dart';
|
||||
import '../providers/contact.dart';
|
||||
import '../providers/contact_invite.dart';
|
||||
import '../providers/conversation.dart';
|
||||
import '../providers/window_control.dart';
|
||||
import '../tools/tools.dart';
|
||||
import 'main_pager/main_pager.dart';
|
||||
@ -113,8 +114,10 @@ class HomePageState extends ConsumerState<HomePage>
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
profile: acceptedContact.profile,
|
||||
remoteIdentity: acceptedContact.remoteIdentity,
|
||||
remoteConversationKey: acceptedContact.remoteConversationKey,
|
||||
localConversation: acceptedContact.localConversation,
|
||||
remoteConversationRecordKey:
|
||||
acceptedContact.remoteConversationRecordKey,
|
||||
localConversationRecordKey:
|
||||
acceptedContact.localConversationRecordKey,
|
||||
);
|
||||
ref
|
||||
..invalidate(fetchContactInvitationRecordsProvider)
|
||||
@ -134,19 +137,34 @@ class HomePageState extends ConsumerState<HomePage>
|
||||
if (activeChat == null) {
|
||||
return;
|
||||
}
|
||||
final activeAccountInfo = await ref.read(fetchActiveAccountProvider.future);
|
||||
if (activeAccountInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final contactList = ref.read(fetchContactListProvider).asData?.value ??
|
||||
const IListConst([]);
|
||||
|
||||
final activeChatContactIdx = contactList.indexWhere(
|
||||
(c) =>
|
||||
proto.TypedKeyProto.fromProto(c.remoteConversationKey) == activeChat,
|
||||
proto.TypedKeyProto.fromProto(c.remoteConversationRecordKey) ==
|
||||
activeChat,
|
||||
);
|
||||
if (activeChatContactIdx == -1) {
|
||||
return;
|
||||
}
|
||||
final activeChatContact = contactList[activeChatContactIdx];
|
||||
final remoteIdentityPublicKey =
|
||||
proto.TypedKeyProto.fromProto(activeChatContact.identityPublicKey);
|
||||
final remoteConversationRecordKey = proto.TypedKeyProto.fromProto(
|
||||
activeChatContact.remoteConversationRecordKey);
|
||||
|
||||
//activeChatContact.rem
|
||||
await getRemoteConversationMessages(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey,
|
||||
remoteConversationRecordKey: remoteConversationRecordKey);
|
||||
|
||||
// xxx add messages
|
||||
}
|
||||
|
||||
// ignore: prefer_expression_function_bodies
|
||||
@ -186,7 +204,8 @@ class HomePageState extends ConsumerState<HomePage>
|
||||
|
||||
final activeChatContactIdx = contactList.indexWhere(
|
||||
(c) =>
|
||||
proto.TypedKeyProto.fromProto(c.remoteConversationKey) == activeChat,
|
||||
proto.TypedKeyProto.fromProto(c.remoteConversationRecordKey) ==
|
||||
activeChat,
|
||||
);
|
||||
if (activeChatContactIdx == -1) {
|
||||
activeChatState.add(null);
|
||||
|
@ -17,8 +17,8 @@ Future<void> createContact({
|
||||
required ActiveAccountInfo activeAccountInfo,
|
||||
required proto.Profile profile,
|
||||
required IdentityMaster remoteIdentity,
|
||||
required TypedKey remoteConversationKey,
|
||||
required OwnedDHTRecordPointer localConversation,
|
||||
required TypedKey remoteConversationRecordKey,
|
||||
required TypedKey localConversationRecordKey,
|
||||
}) async {
|
||||
final accountRecordKey =
|
||||
activeAccountInfo.userLogin.accountRecordInfo.accountRecord.recordKey;
|
||||
@ -32,8 +32,8 @@ Future<void> createContact({
|
||||
kind: remoteIdentity.identityRecordKey.kind,
|
||||
value: remoteIdentity.identityPublicKey)
|
||||
.toProto()
|
||||
..remoteConversationKey = remoteConversationKey.toProto()
|
||||
..localConversation = localConversation.toProto()
|
||||
..remoteConversationRecordKey = remoteConversationRecordKey.toProto()
|
||||
..localConversationRecordKey = localConversationRecordKey.toProto()
|
||||
..showAvailability = false;
|
||||
|
||||
// Add Contact to account's list
|
||||
@ -56,7 +56,7 @@ Future<void> deleteContact(
|
||||
final accountRecordKey =
|
||||
activeAccountInfo.userLogin.accountRecordInfo.accountRecord.recordKey;
|
||||
final remoteConversationKey =
|
||||
proto.TypedKeyProto.fromProto(contact.remoteConversationKey);
|
||||
proto.TypedKeyProto.fromProto(contact.remoteConversationRecordKey);
|
||||
|
||||
// Remove any chats for this contact
|
||||
await deleteChat(
|
||||
@ -75,14 +75,14 @@ Future<void> deleteContact(
|
||||
if (item == null) {
|
||||
throw Exception('Failed to get contact');
|
||||
}
|
||||
if (item.remoteConversationKey == contact.remoteConversationKey) {
|
||||
if (item.remoteConversationRecordKey ==
|
||||
contact.remoteConversationRecordKey) {
|
||||
await contactList.tryRemoveItem(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
await (await pool.openOwned(
|
||||
proto.OwnedDHTRecordPointerProto.fromProto(
|
||||
contact.localConversation),
|
||||
await (await pool.openRead(
|
||||
proto.TypedKeyProto.fromProto(contact.localConversationRecordKey),
|
||||
parent: accountRecordKey))
|
||||
.delete();
|
||||
await (await pool.openRead(remoteConversationKey, parent: accountRecordKey))
|
||||
|
@ -28,14 +28,14 @@ class AcceptedContact {
|
||||
AcceptedContact({
|
||||
required this.profile,
|
||||
required this.remoteIdentity,
|
||||
required this.remoteConversationKey,
|
||||
required this.localConversation,
|
||||
required this.remoteConversationRecordKey,
|
||||
required this.localConversationRecordKey,
|
||||
});
|
||||
|
||||
proto.Profile profile;
|
||||
IdentityMaster remoteIdentity;
|
||||
TypedKey remoteConversationKey;
|
||||
OwnedDHTRecordPointer localConversation;
|
||||
TypedKey remoteConversationRecordKey;
|
||||
TypedKey localConversationRecordKey;
|
||||
}
|
||||
|
||||
class AcceptedOrRejectedContact {
|
||||
@ -92,33 +92,33 @@ Future<AcceptedOrRejectedContact?> checkAcceptRejectContact(
|
||||
contactResponseBytes, signature);
|
||||
|
||||
// Pull profile from remote conversation key
|
||||
final remoteConversationKey =
|
||||
proto.TypedKeyProto.fromProto(contactResponse.remoteConversationKey);
|
||||
final remoteConversationRecordKey = proto.TypedKeyProto.fromProto(
|
||||
contactResponse.remoteConversationRecordKey);
|
||||
final remoteConversation = await readRemoteConversation(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteIdentityPublicKey:
|
||||
contactIdentityMaster.identityPublicTypedKey(),
|
||||
remoteConversationKey: remoteConversationKey);
|
||||
remoteConversationRecordKey: remoteConversationRecordKey);
|
||||
if (remoteConversation == null) {
|
||||
log.info('Remote conversation could not be read. Waiting...');
|
||||
return null;
|
||||
}
|
||||
// Complete the local conversation now that we have the remote profile
|
||||
final localConversationOwned = proto.OwnedDHTRecordPointerProto.fromProto(
|
||||
contactInvitationRecord.localConversation);
|
||||
final localConversationRecordKey = proto.TypedKeyProto.fromProto(
|
||||
contactInvitationRecord.localConversationRecordKey);
|
||||
return createConversation(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteIdentityPublicKey:
|
||||
contactIdentityMaster.identityPublicTypedKey(),
|
||||
existingConversationOwned: localConversationOwned,
|
||||
existingConversationRecordKey: localConversationRecordKey,
|
||||
// ignore: prefer_expression_function_bodies
|
||||
callback: (localConversation) async {
|
||||
return AcceptedOrRejectedContact(
|
||||
acceptedContact: AcceptedContact(
|
||||
profile: remoteConversation.profile,
|
||||
remoteIdentity: contactIdentityMaster,
|
||||
remoteConversationKey: remoteConversationKey,
|
||||
localConversation: localConversationOwned));
|
||||
remoteConversationRecordKey: remoteConversationRecordKey,
|
||||
localConversationRecordKey: localConversationRecordKey));
|
||||
});
|
||||
});
|
||||
|
||||
@ -182,9 +182,9 @@ Future<void> deleteContactInvitation(
|
||||
await contactRequestInbox.delete();
|
||||
});
|
||||
if (!accepted) {
|
||||
await (await pool.openOwned(
|
||||
proto.OwnedDHTRecordPointerProto.fromProto(
|
||||
contactInvitationRecord.localConversation),
|
||||
await (await pool.openRead(
|
||||
proto.TypedKeyProto.fromProto(
|
||||
contactInvitationRecord.localConversationRecordKey),
|
||||
parent: accountRecordKey))
|
||||
.delete();
|
||||
}
|
||||
@ -206,11 +206,13 @@ Future<Uint8List> createContactInvitation(
|
||||
|
||||
// Generate writer keypair to share with new contact
|
||||
final cs = await pool.veilid.bestCryptoSystem();
|
||||
final writer = await cs.generateKeyPair();
|
||||
final contactRequestWriter = await cs.generateKeyPair();
|
||||
final conversationWriter =
|
||||
getConversationWriter(activeAccountInfo: activeAccountInfo);
|
||||
|
||||
// Encrypt the writer secret with the encryption key
|
||||
final encryptedSecret = await encryptSecretToBytes(
|
||||
secret: writer.secret,
|
||||
secret: contactRequestWriter.secret,
|
||||
cryptoKind: cs.kind(),
|
||||
encryptionKey: encryptionKey,
|
||||
encryptionKeyType: encryptionKeyType);
|
||||
@ -220,19 +222,24 @@ Future<Uint8List> createContactInvitation(
|
||||
// to and it will be eventually encrypted with the DH of the contact's
|
||||
// identity key
|
||||
late final Uint8List signedContactInvitationBytes;
|
||||
await (await pool.create(parent: accountRecordKey))
|
||||
await (await pool.create(
|
||||
parent: accountRecordKey,
|
||||
schema: DHTSchema.smpl(oCnt: 0, members: [
|
||||
DHTSchemaMember(mKey: conversationWriter.key, mCnt: 1)
|
||||
])))
|
||||
.deleteScope((localConversation) async {
|
||||
// dont bother reopening localConversation with writer
|
||||
// Make ContactRequestPrivate and encrypt with the writer secret
|
||||
final crpriv = ContactRequestPrivate()
|
||||
..writerKey = writer.key.toProto()
|
||||
..writerKey = contactRequestWriter.key.toProto()
|
||||
..profile = activeAccountInfo.account.profile
|
||||
..identityMasterRecordKey =
|
||||
activeAccountInfo.userLogin.accountMasterRecordKey.toProto()
|
||||
..chatRecordKey = localConversation.key.toProto()
|
||||
..expiration = expiration?.toInt64() ?? Int64.ZERO;
|
||||
final crprivbytes = crpriv.writeToBuffer();
|
||||
final encryptedContactRequestPrivate =
|
||||
await cs.encryptNoAuthWithNonce(crprivbytes, writer.secret);
|
||||
final encryptedContactRequestPrivate = await cs.encryptNoAuthWithNonce(
|
||||
crprivbytes, contactRequestWriter.secret);
|
||||
|
||||
// Create ContactRequest and embed contactrequestprivate
|
||||
final creq = ContactRequest()
|
||||
@ -242,8 +249,9 @@ Future<Uint8List> createContactInvitation(
|
||||
// Create DHT unicast inbox for ContactRequest
|
||||
await (await pool.create(
|
||||
parent: accountRecordKey,
|
||||
schema: DHTSchema.smpl(
|
||||
oCnt: 1, members: [DHTSchemaMember(mCnt: 1, mKey: writer.key)]),
|
||||
schema: DHTSchema.smpl(oCnt: 1, members: [
|
||||
DHTSchemaMember(mCnt: 1, mKey: contactRequestWriter.key)
|
||||
]),
|
||||
crypto: const DHTRecordCryptoPublic()))
|
||||
.deleteScope((contactRequestInbox) async {
|
||||
// Store ContactRequest in owner subkey
|
||||
@ -264,9 +272,9 @@ Future<Uint8List> createContactInvitation(
|
||||
final cinvrec = ContactInvitationRecord()
|
||||
..contactRequestInbox =
|
||||
contactRequestInbox.ownedDHTRecordPointer.toProto()
|
||||
..writerKey = writer.key.toProto()
|
||||
..writerSecret = writer.secret.toProto()
|
||||
..localConversation = localConversation.ownedDHTRecordPointer.toProto()
|
||||
..writerKey = contactRequestWriter.key.toProto()
|
||||
..writerSecret = contactRequestWriter.secret.toProto()
|
||||
..localConversationRecordKey = localConversation.key.toProto()
|
||||
..expiration = expiration?.toInt64() ?? Int64.ZERO
|
||||
..invitation = signedContactInvitationBytes
|
||||
..message = message;
|
||||
@ -390,7 +398,7 @@ Future<AcceptedContact?> acceptContactInvitation(
|
||||
callback: (localConversation) async {
|
||||
final contactResponse = ContactResponse()
|
||||
..accept = true
|
||||
..remoteConversationKey = localConversation.key.toProto()
|
||||
..remoteConversationRecordKey = localConversation.key.toProto()
|
||||
..identityMasterRecordKey = activeAccountInfo
|
||||
.localAccount.identityMaster.masterRecordKey
|
||||
.toProto();
|
||||
@ -418,9 +426,9 @@ Future<AcceptedContact?> acceptContactInvitation(
|
||||
return AcceptedContact(
|
||||
profile: validContactInvitation.contactRequestPrivate.profile,
|
||||
remoteIdentity: validContactInvitation.contactIdentityMaster,
|
||||
remoteConversationKey: proto.TypedKeyProto.fromProto(
|
||||
remoteConversationRecordKey: proto.TypedKeyProto.fromProto(
|
||||
validContactInvitation.contactRequestPrivate.chatRecordKey),
|
||||
localConversation: localConversation.ownedDHTRecordPointer,
|
||||
localConversationRecordKey: localConversation.key,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -24,6 +24,15 @@ Future<DHTRecordCrypto> getConversationCrypto({
|
||||
return DHTRecordCryptoPrivate.fromSecret(identitySecret.kind, sharedSecret);
|
||||
}
|
||||
|
||||
KeyPair getConversationWriter({
|
||||
required ActiveAccountInfo activeAccountInfo,
|
||||
}) {
|
||||
final identityKey =
|
||||
activeAccountInfo.localAccount.identityMaster.identityPublicKey;
|
||||
final identitySecret = activeAccountInfo.userLogin.identitySecret;
|
||||
return KeyPair(key: identityKey, secret: identitySecret.value);
|
||||
}
|
||||
|
||||
// Create a conversation
|
||||
// If we were the initator of the conversation there may be an
|
||||
// incomplete 'existingConversationRecord' that we need to fill
|
||||
@ -32,7 +41,7 @@ Future<T> createConversation<T>(
|
||||
{required ActiveAccountInfo activeAccountInfo,
|
||||
required TypedKey remoteIdentityPublicKey,
|
||||
required FutureOr<T> Function(DHTRecord) callback,
|
||||
OwnedDHTRecordPointer? existingConversationOwned}) async {
|
||||
TypedKey? existingConversationRecordKey}) async {
|
||||
final pool = await DHTRecordPool.instance();
|
||||
final accountRecordKey =
|
||||
activeAccountInfo.userLogin.accountRecordInfo.accountRecord.recordKey;
|
||||
@ -40,28 +49,38 @@ Future<T> createConversation<T>(
|
||||
final crypto = await getConversationCrypto(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||
final writer = getConversationWriter(activeAccountInfo: activeAccountInfo);
|
||||
|
||||
// Open with SMPL scheme for identity writer
|
||||
late final DHTRecord localConversationRecord;
|
||||
if (existingConversationOwned != null) {
|
||||
localConversationRecord = await pool.openOwned(existingConversationOwned,
|
||||
if (existingConversationRecordKey != null) {
|
||||
localConversationRecord = await pool.openWrite(
|
||||
existingConversationRecordKey, writer,
|
||||
parent: accountRecordKey, crypto: crypto);
|
||||
} else {
|
||||
localConversationRecord =
|
||||
await pool.create(parent: accountRecordKey, crypto: crypto);
|
||||
final localConversationRecordCreate = await pool.create(
|
||||
parent: accountRecordKey,
|
||||
crypto: crypto,
|
||||
schema: DHTSchema.smpl(
|
||||
oCnt: 0, members: [DHTSchemaMember(mKey: writer.key, mCnt: 1)]));
|
||||
await localConversationRecordCreate.close();
|
||||
localConversationRecord = await pool.openWrite(
|
||||
localConversationRecordCreate.key, writer,
|
||||
parent: accountRecordKey, crypto: crypto);
|
||||
}
|
||||
return localConversationRecord
|
||||
// ignore: prefer_expression_function_bodies
|
||||
.deleteScope((localConversation) async {
|
||||
// Make messages log
|
||||
return (await DHTShortArray.create(
|
||||
parent: localConversation.key, crypto: crypto))
|
||||
parent: localConversation.key, crypto: crypto, smplWriter: writer))
|
||||
.deleteScope((messages) async {
|
||||
// Write local conversation key
|
||||
final conversation = Conversation()
|
||||
..profile = activeAccountInfo.account.profile
|
||||
..identityMasterJson =
|
||||
jsonEncode(activeAccountInfo.localAccount.identityMaster.toJson())
|
||||
..messages = messages.record.ownedDHTRecordPointer.toProto();
|
||||
..messages = messages.record.key.toProto();
|
||||
|
||||
//
|
||||
final update = await localConversation.tryWriteProtobuf(
|
||||
@ -76,8 +95,8 @@ Future<T> createConversation<T>(
|
||||
|
||||
Future<Conversation?> readRemoteConversation({
|
||||
required ActiveAccountInfo activeAccountInfo,
|
||||
required TypedKey remoteConversationRecordKey,
|
||||
required TypedKey remoteIdentityPublicKey,
|
||||
required TypedKey remoteConversationKey,
|
||||
}) async {
|
||||
final accountRecordKey =
|
||||
activeAccountInfo.userLogin.accountRecordInfo.accountRecord.recordKey;
|
||||
@ -86,7 +105,7 @@ Future<Conversation?> readRemoteConversation({
|
||||
final crypto = await getConversationCrypto(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||
return (await pool.openRead(remoteConversationKey,
|
||||
return (await pool.openRead(remoteConversationRecordKey,
|
||||
parent: accountRecordKey, crypto: crypto))
|
||||
.scope((remoteConversation) async {
|
||||
//
|
||||
@ -98,7 +117,7 @@ Future<Conversation?> readRemoteConversation({
|
||||
|
||||
Future<Conversation?> writeLocalConversation({
|
||||
required ActiveAccountInfo activeAccountInfo,
|
||||
required OwnedDHTRecordPointer localConversationOwned,
|
||||
required TypedKey localConversationRecordKey,
|
||||
required TypedKey remoteIdentityPublicKey,
|
||||
required Conversation conversation,
|
||||
}) async {
|
||||
@ -109,8 +128,9 @@ Future<Conversation?> writeLocalConversation({
|
||||
final crypto = await getConversationCrypto(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||
final writer = getConversationWriter(activeAccountInfo: activeAccountInfo);
|
||||
|
||||
return (await pool.openOwned(localConversationOwned,
|
||||
return (await pool.openWrite(localConversationRecordKey, writer,
|
||||
parent: accountRecordKey, crypto: crypto))
|
||||
.scope((localConversation) async {
|
||||
//
|
||||
@ -125,7 +145,7 @@ Future<Conversation?> writeLocalConversation({
|
||||
|
||||
Future<Conversation?> readLocalConversation({
|
||||
required ActiveAccountInfo activeAccountInfo,
|
||||
required OwnedDHTRecordPointer localConversationOwned,
|
||||
required TypedKey localConversationRecordKey,
|
||||
required TypedKey remoteIdentityPublicKey,
|
||||
}) async {
|
||||
final accountRecordKey =
|
||||
@ -136,7 +156,7 @@ Future<Conversation?> readLocalConversation({
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||
|
||||
return (await pool.openOwned(localConversationOwned,
|
||||
return (await pool.openRead(localConversationRecordKey,
|
||||
parent: accountRecordKey, crypto: crypto))
|
||||
.scope((localConversation) async {
|
||||
//
|
||||
@ -150,24 +170,25 @@ Future<Conversation?> readLocalConversation({
|
||||
|
||||
Future<void> addLocalConversationMessage(
|
||||
{required ActiveAccountInfo activeAccountInfo,
|
||||
required OwnedDHTRecordPointer localConversationOwned,
|
||||
required TypedKey localConversationRecordKey,
|
||||
required TypedKey remoteIdentityPublicKey,
|
||||
required proto.Message message}) async {
|
||||
final conversation = await readLocalConversation(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
localConversationOwned: localConversationOwned,
|
||||
localConversationRecordKey: localConversationRecordKey,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||
if (conversation == null) {
|
||||
return;
|
||||
}
|
||||
final messagesOwned =
|
||||
proto.OwnedDHTRecordPointerProto.fromProto(conversation.messages);
|
||||
final messagesRecordKey =
|
||||
proto.TypedKeyProto.fromProto(conversation.messages);
|
||||
final crypto = await getConversationCrypto(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||
final writer = getConversationWriter(activeAccountInfo: activeAccountInfo);
|
||||
|
||||
await (await DHTShortArray.openOwned(messagesOwned,
|
||||
parent: localConversationOwned.recordKey, crypto: crypto))
|
||||
await (await DHTShortArray.openWrite(messagesRecordKey, writer,
|
||||
parent: localConversationRecordKey, crypto: crypto))
|
||||
.scope((messages) async {
|
||||
await messages.tryAddItem(message.writeToBuffer());
|
||||
});
|
||||
@ -175,24 +196,24 @@ Future<void> addLocalConversationMessage(
|
||||
|
||||
Future<IList<proto.Message>?> getLocalConversationMessages({
|
||||
required ActiveAccountInfo activeAccountInfo,
|
||||
required OwnedDHTRecordPointer localConversationOwned,
|
||||
required TypedKey localConversationRecordKey,
|
||||
required TypedKey remoteIdentityPublicKey,
|
||||
}) async {
|
||||
final conversation = await readLocalConversation(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
localConversationOwned: localConversationOwned,
|
||||
localConversationRecordKey: localConversationRecordKey,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||
if (conversation == null) {
|
||||
return null;
|
||||
}
|
||||
final messagesOwned =
|
||||
proto.OwnedDHTRecordPointerProto.fromProto(conversation.messages);
|
||||
final messagesRecordKey =
|
||||
proto.TypedKeyProto.fromProto(conversation.messages);
|
||||
final crypto = await getConversationCrypto(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||
|
||||
return (await DHTShortArray.openOwned(messagesOwned,
|
||||
parent: localConversationOwned.recordKey, crypto: crypto))
|
||||
return (await DHTShortArray.openRead(messagesRecordKey,
|
||||
parent: localConversationRecordKey, crypto: crypto))
|
||||
.scope((messages) async {
|
||||
var out = IList<proto.Message>();
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
@ -208,24 +229,24 @@ Future<IList<proto.Message>?> getLocalConversationMessages({
|
||||
|
||||
Future<IList<proto.Message>?> getRemoteConversationMessages({
|
||||
required ActiveAccountInfo activeAccountInfo,
|
||||
required TypedKey remoteConversationKey,
|
||||
required TypedKey remoteConversationRecordKey,
|
||||
required TypedKey remoteIdentityPublicKey,
|
||||
}) async {
|
||||
final conversation = await readRemoteConversation(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteConversationKey: remoteConversationKey,
|
||||
remoteConversationRecordKey: remoteConversationRecordKey,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||
if (conversation == null) {
|
||||
return null;
|
||||
}
|
||||
final messagesOwned =
|
||||
proto.OwnedDHTRecordPointerProto.fromProto(conversation.messages);
|
||||
final messagesRecordKey =
|
||||
proto.TypedKeyProto.fromProto(conversation.messages);
|
||||
final crypto = await getConversationCrypto(
|
||||
activeAccountInfo: activeAccountInfo,
|
||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||
|
||||
return (await DHTShortArray.openOwned(messagesOwned,
|
||||
parent: localConversationOwned.recordKey, crypto: crypto))
|
||||
return (await DHTShortArray.openRead(messagesRecordKey,
|
||||
parent: remoteConversationRecordKey, crypto: crypto))
|
||||
.scope((messages) async {
|
||||
var out = IList<proto.Message>();
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
|
@ -60,6 +60,9 @@ class DHTShortArray {
|
||||
// Cached representation refreshed from head record
|
||||
_DHTShortArrayCache _head;
|
||||
|
||||
// Create a DHTShortArray
|
||||
// if smplWriter is specified, uses a SMPL schema with a single writer
|
||||
// rather than the key owner
|
||||
static Future<DHTShortArray> create(
|
||||
{int stride = maxElements,
|
||||
VeilidRoutingContext? routingContext,
|
||||
|
Loading…
Reference in New Issue
Block a user