mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-06-23 13:54:10 -04:00
smpl shortarray
This commit is contained in:
parent
c59828df90
commit
e68cbb26eb
7 changed files with 80 additions and 24 deletions
|
@ -932,7 +932,7 @@ class Conversation extends $pb.GeneratedMessage {
|
||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Conversation', createEmptyInstance: create)
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Conversation', createEmptyInstance: create)
|
||||||
..aOM<Profile>(1, _omitFieldNames ? '' : 'profile', subBuilder: Profile.create)
|
..aOM<Profile>(1, _omitFieldNames ? '' : 'profile', subBuilder: Profile.create)
|
||||||
..aOS(2, _omitFieldNames ? '' : 'identityMasterJson')
|
..aOS(2, _omitFieldNames ? '' : 'identityMasterJson')
|
||||||
..aOM<OwnedDHTRecordPointer>(3, _omitFieldNames ? '' : 'messages', subBuilder: OwnedDHTRecordPointer.create)
|
..aOM<TypedKey>(3, _omitFieldNames ? '' : 'messages', subBuilder: TypedKey.create)
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -978,15 +978,15 @@ class Conversation extends $pb.GeneratedMessage {
|
||||||
void clearIdentityMasterJson() => clearField(2);
|
void clearIdentityMasterJson() => clearField(2);
|
||||||
|
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
OwnedDHTRecordPointer get messages => $_getN(2);
|
TypedKey get messages => $_getN(2);
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
set messages(OwnedDHTRecordPointer v) { setField(3, v); }
|
set messages(TypedKey v) { setField(3, v); }
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
$core.bool hasMessages() => $_has(2);
|
$core.bool hasMessages() => $_has(2);
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
void clearMessages() => clearField(3);
|
void clearMessages() => clearField(3);
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
OwnedDHTRecordPointer ensureMessages() => $_ensure(2);
|
TypedKey ensureMessages() => $_ensure(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Contact extends $pb.GeneratedMessage {
|
class Contact extends $pb.GeneratedMessage {
|
||||||
|
|
|
@ -285,15 +285,15 @@ const Conversation$json = {
|
||||||
'2': [
|
'2': [
|
||||||
{'1': 'profile', '3': 1, '4': 1, '5': 11, '6': '.Profile', '10': 'profile'},
|
{'1': 'profile', '3': 1, '4': 1, '5': 11, '6': '.Profile', '10': 'profile'},
|
||||||
{'1': 'identity_master_json', '3': 2, '4': 1, '5': 9, '10': 'identityMasterJson'},
|
{'1': 'identity_master_json', '3': 2, '4': 1, '5': 9, '10': 'identityMasterJson'},
|
||||||
{'1': 'messages', '3': 3, '4': 1, '5': 11, '6': '.OwnedDHTRecordPointer', '10': 'messages'},
|
{'1': 'messages', '3': 3, '4': 1, '5': 11, '6': '.TypedKey', '10': 'messages'},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Descriptor for `Conversation`. Decode as a `google.protobuf.DescriptorProto`.
|
/// Descriptor for `Conversation`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
final $typed_data.Uint8List conversationDescriptor = $convert.base64Decode(
|
final $typed_data.Uint8List conversationDescriptor = $convert.base64Decode(
|
||||||
'CgxDb252ZXJzYXRpb24SIgoHcHJvZmlsZRgBIAEoCzIILlByb2ZpbGVSB3Byb2ZpbGUSMAoUaW'
|
'CgxDb252ZXJzYXRpb24SIgoHcHJvZmlsZRgBIAEoCzIILlByb2ZpbGVSB3Byb2ZpbGUSMAoUaW'
|
||||||
'RlbnRpdHlfbWFzdGVyX2pzb24YAiABKAlSEmlkZW50aXR5TWFzdGVySnNvbhIyCghtZXNzYWdl'
|
'RlbnRpdHlfbWFzdGVyX2pzb24YAiABKAlSEmlkZW50aXR5TWFzdGVySnNvbhIlCghtZXNzYWdl'
|
||||||
'cxgDIAEoCzIWLk93bmVkREhUUmVjb3JkUG9pbnRlclIIbWVzc2FnZXM=');
|
'cxgDIAEoCzIJLlR5cGVkS2V5UghtZXNzYWdlcw==');
|
||||||
|
|
||||||
@$core.Deprecated('Use contactDescriptor instead')
|
@$core.Deprecated('Use contactDescriptor instead')
|
||||||
const Contact$json = {
|
const Contact$json = {
|
||||||
|
|
|
@ -156,6 +156,7 @@ message Attachment {
|
||||||
|
|
||||||
// A single message as part of a series of messages
|
// A single message as part of a series of messages
|
||||||
// Messages are stored in a DHTLog
|
// Messages are stored in a DHTLog
|
||||||
|
// DHT Schema: SMPL(0,1,[identityPublicKey])
|
||||||
message Message {
|
message Message {
|
||||||
// Author of the message
|
// Author of the message
|
||||||
TypedKey author = 1;
|
TypedKey author = 1;
|
||||||
|
@ -183,7 +184,7 @@ message Conversation {
|
||||||
// Identity master (JSON) to publish to friend
|
// Identity master (JSON) to publish to friend
|
||||||
string identity_master_json = 2;
|
string identity_master_json = 2;
|
||||||
// Messages DHTLog (xxx for now DHTShortArray)
|
// Messages DHTLog (xxx for now DHTShortArray)
|
||||||
OwnedDHTRecordPointer messages = 3;
|
TypedKey messages = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A record of a contact that has accepted a contact invitation
|
// A record of a contact that has accepted a contact invitation
|
||||||
|
|
|
@ -205,3 +205,36 @@ Future<IList<proto.Message>?> getLocalConversationMessages({
|
||||||
return out;
|
return out;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<IList<proto.Message>?> getRemoteConversationMessages({
|
||||||
|
required ActiveAccountInfo activeAccountInfo,
|
||||||
|
required TypedKey remoteConversationKey,
|
||||||
|
required TypedKey remoteIdentityPublicKey,
|
||||||
|
}) async {
|
||||||
|
final conversation = await readRemoteConversation(
|
||||||
|
activeAccountInfo: activeAccountInfo,
|
||||||
|
remoteConversationKey: remoteConversationKey,
|
||||||
|
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||||
|
if (conversation == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final messagesOwned =
|
||||||
|
proto.OwnedDHTRecordPointerProto.fromProto(conversation.messages);
|
||||||
|
final crypto = await getConversationCrypto(
|
||||||
|
activeAccountInfo: activeAccountInfo,
|
||||||
|
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
||||||
|
|
||||||
|
return (await DHTShortArray.openOwned(messagesOwned,
|
||||||
|
parent: localConversationOwned.recordKey, crypto: crypto))
|
||||||
|
.scope((messages) async {
|
||||||
|
var out = IList<proto.Message>();
|
||||||
|
for (var i = 0; i < messages.length; i++) {
|
||||||
|
final msg = await messages.getItemProtobuf(proto.Message.fromBuffer, i);
|
||||||
|
if (msg == null) {
|
||||||
|
throw Exception('Failed to get message');
|
||||||
|
}
|
||||||
|
out = out.add(msg);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -37,12 +37,15 @@ class DHTShortArray {
|
||||||
late final int stride;
|
late final int stride;
|
||||||
switch (headRecord.schema) {
|
switch (headRecord.schema) {
|
||||||
case DHTSchemaDFLT(oCnt: final oCnt):
|
case DHTSchemaDFLT(oCnt: final oCnt):
|
||||||
stride = oCnt - 1;
|
if (oCnt <= 1) {
|
||||||
if (stride <= 0) {
|
throw StateError('Invalid DFLT schema in DHTShortArray');
|
||||||
throw StateError('Invalid stride in DHTShortArray');
|
|
||||||
}
|
}
|
||||||
case DHTSchemaSMPL():
|
stride = oCnt - 1;
|
||||||
throw StateError('Wrote kind of DHT record for DHTShortArray');
|
case DHTSchemaSMPL(oCnt: final oCnt, members: final members):
|
||||||
|
if (oCnt != 0 || members.length != 1 || members[1].mCnt <= 1) {
|
||||||
|
throw StateError('Invalid SMPL schema in DHTShortArray');
|
||||||
|
}
|
||||||
|
stride = members[1].mCnt - 1;
|
||||||
}
|
}
|
||||||
assert(stride <= maxElements, 'stride too long');
|
assert(stride <= maxElements, 'stride too long');
|
||||||
_stride = stride;
|
_stride = stride;
|
||||||
|
@ -61,15 +64,34 @@ class DHTShortArray {
|
||||||
{int stride = maxElements,
|
{int stride = maxElements,
|
||||||
VeilidRoutingContext? routingContext,
|
VeilidRoutingContext? routingContext,
|
||||||
TypedKey? parent,
|
TypedKey? parent,
|
||||||
DHTRecordCrypto? crypto}) async {
|
DHTRecordCrypto? crypto,
|
||||||
|
KeyPair? smplWriter}) async {
|
||||||
assert(stride <= maxElements, 'stride too long');
|
assert(stride <= maxElements, 'stride too long');
|
||||||
final pool = await DHTRecordPool.instance();
|
final pool = await DHTRecordPool.instance();
|
||||||
|
|
||||||
final dhtRecord = await pool.create(
|
late final DHTRecord dhtRecord;
|
||||||
parent: parent,
|
if (smplWriter != null) {
|
||||||
routingContext: routingContext,
|
final schema = DHTSchema.smpl(
|
||||||
schema: DHTSchema.dflt(oCnt: stride + 1),
|
oCnt: 0,
|
||||||
crypto: crypto);
|
members: [DHTSchemaMember(mKey: smplWriter.key, mCnt: stride + 1)]);
|
||||||
|
final dhtCreateRecord = await pool.create(
|
||||||
|
parent: parent,
|
||||||
|
routingContext: routingContext,
|
||||||
|
schema: schema,
|
||||||
|
crypto: crypto);
|
||||||
|
// Reopen with SMPL writer
|
||||||
|
await dhtCreateRecord.close();
|
||||||
|
dhtRecord = await pool.openWrite(dhtCreateRecord.key, smplWriter,
|
||||||
|
parent: parent, routingContext: routingContext, crypto: crypto);
|
||||||
|
} else {
|
||||||
|
final schema = DHTSchema.dflt(oCnt: stride + 1);
|
||||||
|
dhtRecord = await pool.create(
|
||||||
|
parent: parent,
|
||||||
|
routingContext: routingContext,
|
||||||
|
schema: schema,
|
||||||
|
crypto: crypto);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final dhtShortArray = DHTShortArray._(headRecord: dhtRecord);
|
final dhtShortArray = DHTShortArray._(headRecord: dhtRecord);
|
||||||
if (!await dhtShortArray._tryWriteHead()) {
|
if (!await dhtShortArray._tryWriteHead()) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ project(runner LANGUAGES CXX)
|
||||||
set(BINARY_NAME "veilidchat")
|
set(BINARY_NAME "veilidchat")
|
||||||
# The unique GTK application identifier for this application. See:
|
# The unique GTK application identifier for this application. See:
|
||||||
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
||||||
set(APPLICATION_ID "com.vekoni.veilidchat.veilidchat")
|
set(APPLICATION_ID "com.veilid.veilidchat")
|
||||||
|
|
||||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
||||||
# versions of CMake.
|
# versions of CMake.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Name=Flutter Linux App
|
Name=VeilidChat
|
||||||
Comment=Flutter Linux launcher icon
|
Comment=VeilidChat Private Messaging
|
||||||
Exec=app_icon
|
Exec=veilidchat
|
||||||
Icon=app_icon.png
|
Icon=app_icon.png
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Entertainment;
|
Categories=Network;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue