mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-08-02 11:16:10 -04:00
simplify reconciliation
This commit is contained in:
parent
bf38c2c44d
commit
4797184a1a
12 changed files with 512 additions and 345 deletions
|
@ -77,8 +77,8 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
|
|||
await _sentSubscription?.cancel();
|
||||
await _rcvdSubscription?.cancel();
|
||||
await _reconciledSubscription?.cancel();
|
||||
await _sentMessagesCubit?.close();
|
||||
await _rcvdMessagesCubit?.close();
|
||||
await _sentMessagesDHTLog?.close();
|
||||
await _rcvdMessagesDHTLog?.close();
|
||||
await _reconciledMessagesCubit?.close();
|
||||
|
||||
// If the local conversation record is gone, then delete the reconciled
|
||||
|
@ -111,10 +111,10 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
|
|||
await _initReconciledMessagesCubit();
|
||||
|
||||
// Local messages key
|
||||
await _initSentMessagesCubit();
|
||||
await _initSentMessagesDHTLog();
|
||||
|
||||
// Remote messages key
|
||||
await _initRcvdMessagesCubit();
|
||||
await _initRcvdMessagesDHTLog();
|
||||
|
||||
// Command execution background process
|
||||
_commandRunnerFut = Future.delayed(Duration.zero, _commandRunner);
|
||||
|
@ -129,39 +129,40 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
|
|||
}
|
||||
|
||||
// Open local messages key
|
||||
Future<void> _initSentMessagesCubit() async {
|
||||
Future<void> _initSentMessagesDHTLog() async {
|
||||
final writer = _accountInfo.identityWriter;
|
||||
|
||||
_sentMessagesCubit = DHTLogCubit(
|
||||
open: () async => DHTLog.openWrite(_localMessagesRecordKey, writer,
|
||||
final sentMessagesDHTLog =
|
||||
await DHTLog.openWrite(_localMessagesRecordKey, writer,
|
||||
debugName: 'SingleContactMessagesCubit::_initSentMessagesCubit::'
|
||||
'SentMessages',
|
||||
parent: _localConversationRecordKey,
|
||||
crypto: _conversationCrypto),
|
||||
decodeElement: proto.Message.fromBuffer);
|
||||
_sentSubscription =
|
||||
_sentMessagesCubit!.stream.listen(_updateSentMessagesState);
|
||||
_updateSentMessagesState(_sentMessagesCubit!.state);
|
||||
crypto: _conversationCrypto);
|
||||
_sentSubscription = await sentMessagesDHTLog.listen(_updateSentMessages);
|
||||
|
||||
_sentMessagesDHTLog = sentMessagesDHTLog;
|
||||
_reconciliation.addInputSourceFromDHTLog(
|
||||
_accountInfo.identityTypedPublicKey, sentMessagesDHTLog);
|
||||
}
|
||||
|
||||
// Open remote messages key
|
||||
Future<void> _initRcvdMessagesCubit() async {
|
||||
Future<void> _initRcvdMessagesDHTLog() async {
|
||||
// Don't bother if we don't have a remote messages record key yet
|
||||
if (_remoteMessagesRecordKey == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Open new cubit if one is desired
|
||||
_rcvdMessagesCubit = DHTLogCubit(
|
||||
open: () async => DHTLog.openRead(_remoteMessagesRecordKey!,
|
||||
debugName: 'SingleContactMessagesCubit::_initRcvdMessagesCubit::'
|
||||
'RcvdMessages',
|
||||
parent: _remoteConversationRecordKey,
|
||||
crypto: _conversationCrypto),
|
||||
decodeElement: proto.Message.fromBuffer);
|
||||
_rcvdSubscription =
|
||||
_rcvdMessagesCubit!.stream.listen(_updateRcvdMessagesState);
|
||||
_updateRcvdMessagesState(_rcvdMessagesCubit!.state);
|
||||
final rcvdMessagesDHTLog = await DHTLog.openRead(_remoteMessagesRecordKey!,
|
||||
debugName: 'SingleContactMessagesCubit::_initRcvdMessagesCubit::'
|
||||
'RcvdMessages',
|
||||
parent: _remoteConversationRecordKey,
|
||||
crypto: _conversationCrypto);
|
||||
_rcvdSubscription = await rcvdMessagesDHTLog.listen(_updateRcvdMessages);
|
||||
|
||||
_rcvdMessagesDHTLog = rcvdMessagesDHTLog;
|
||||
_reconciliation.addInputSourceFromDHTLog(
|
||||
_remoteIdentityPublicKey, rcvdMessagesDHTLog);
|
||||
}
|
||||
|
||||
Future<void> updateRemoteMessagesRecordKey(
|
||||
|
@ -175,17 +176,17 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
|
|||
return;
|
||||
}
|
||||
|
||||
// Close existing cubit if we have one
|
||||
final rcvdMessagesCubit = _rcvdMessagesCubit;
|
||||
_rcvdMessagesCubit = null;
|
||||
// Close existing DHTLog if we have one
|
||||
final rcvdMessagesDHTLog = _rcvdMessagesDHTLog;
|
||||
_rcvdMessagesDHTLog = null;
|
||||
_remoteMessagesRecordKey = null;
|
||||
await _rcvdSubscription?.cancel();
|
||||
_rcvdSubscription = null;
|
||||
await rcvdMessagesCubit?.close();
|
||||
await rcvdMessagesDHTLog?.close();
|
||||
|
||||
// Init the new cubit if we should
|
||||
// Init the new DHTLog if we should
|
||||
_remoteMessagesRecordKey = remoteMessagesRecordKey;
|
||||
await _initRcvdMessagesCubit();
|
||||
await _initRcvdMessagesDHTLog();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -275,30 +276,15 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// Internal implementation
|
||||
|
||||
// Called when the sent messages cubit gets a change
|
||||
// Called when the sent messages DHTLog gets a change
|
||||
// This will re-render when messages are sent from another machine
|
||||
void _updateSentMessagesState(DHTLogBusyState<proto.Message> avmessages) {
|
||||
final sentMessages = avmessages.state.asData?.value;
|
||||
if (sentMessages == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
_reconciliation.reconcileMessages(
|
||||
_accountInfo.identityTypedPublicKey, sentMessages, _sentMessagesCubit!);
|
||||
|
||||
// Update the view
|
||||
_renderState();
|
||||
void _updateSentMessages(DHTLogUpdate upd) {
|
||||
_reconciliation.reconcileMessages(_accountInfo.identityTypedPublicKey);
|
||||
}
|
||||
|
||||
// Called when the received messages cubit gets a change
|
||||
void _updateRcvdMessagesState(DHTLogBusyState<proto.Message> avmessages) {
|
||||
final rcvdMessages = avmessages.state.asData?.value;
|
||||
if (rcvdMessages == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
_reconciliation.reconcileMessages(
|
||||
_remoteIdentityPublicKey, rcvdMessages, _rcvdMessagesCubit!);
|
||||
// Called when the received messages DHTLog gets a change
|
||||
void _updateRcvdMessages(DHTLogUpdate upd) {
|
||||
_reconciliation.reconcileMessages(_remoteIdentityPublicKey);
|
||||
}
|
||||
|
||||
// Called when the reconciled messages window gets a change
|
||||
|
@ -327,7 +313,7 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
|
|||
|
||||
// _renderState();
|
||||
try {
|
||||
await _sentMessagesCubit!.operateAppendEventual((writer) async {
|
||||
await _sentMessagesDHTLog!.operateAppendEventual((writer) async {
|
||||
// Get the previous message if we have one
|
||||
var previousMessage = writer.length == 0
|
||||
? null
|
||||
|
@ -357,16 +343,17 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
|
|||
|
||||
// Produce a state for this cubit from the input cubits and queues
|
||||
void _renderState() {
|
||||
// Get all reconciled messages
|
||||
// Get all reconciled messages in the cubit window
|
||||
final reconciledMessages =
|
||||
_reconciledMessagesCubit?.state.state.asData?.value;
|
||||
// Get all sent messages
|
||||
final sentMessages = _sentMessagesCubit?.state.state.asData?.value;
|
||||
|
||||
// Get all sent messages that are still offline
|
||||
//final sentMessages = _sentMessagesDHTLog.
|
||||
//Get all items in the unsent queue
|
||||
//final unsentMessages = _unsentMessagesQueue.queue;
|
||||
|
||||
// If we aren't ready to render a state, say we're loading
|
||||
if (reconciledMessages == null || sentMessages == null) {
|
||||
if (reconciledMessages == null) {
|
||||
emit(const AsyncLoading());
|
||||
return;
|
||||
}
|
||||
|
@ -377,11 +364,11 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
|
|||
// keyMapper: (x) => x.content.authorUniqueIdString,
|
||||
// values: reconciledMessages.windowElements,
|
||||
// );
|
||||
final sentMessagesMap =
|
||||
IMap<String, OnlineElementState<proto.Message>>.fromValues(
|
||||
keyMapper: (x) => x.value.authorUniqueIdString,
|
||||
values: sentMessages.window,
|
||||
);
|
||||
// final sentMessagesMap =
|
||||
// IMap<String, OnlineElementState<proto.Message>>.fromValues(
|
||||
// keyMapper: (x) => x.value.authorUniqueIdString,
|
||||
// values: sentMessages.window,
|
||||
// );
|
||||
// final unsentMessagesMap = IMap<String, proto.Message>.fromValues(
|
||||
// keyMapper: (x) => x.authorUniqueIdString,
|
||||
// values: unsentMessages,
|
||||
|
@ -393,10 +380,12 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
|
|||
final isLocal =
|
||||
m.content.author.toVeilid() == _accountInfo.identityTypedPublicKey;
|
||||
final reconciledTimestamp = Timestamp.fromInt64(m.reconciledTime);
|
||||
final sm =
|
||||
isLocal ? sentMessagesMap[m.content.authorUniqueIdString] : null;
|
||||
final sent = isLocal && sm != null;
|
||||
final sentOffline = isLocal && sm != null && sm.isOffline;
|
||||
//final sm =
|
||||
//isLocal ? sentMessagesMap[m.content.authorUniqueIdString] : null;
|
||||
//final sent = isLocal && sm != null;
|
||||
//final sentOffline = isLocal && sm != null && sm.isOffline;
|
||||
final sent = isLocal;
|
||||
final sentOffline = false; //
|
||||
|
||||
renderedElements.add(RenderStateElement(
|
||||
message: m.content,
|
||||
|
@ -491,16 +480,16 @@ class SingleContactMessagesCubit extends Cubit<SingleContactMessagesState> {
|
|||
late final VeilidCrypto _conversationCrypto;
|
||||
late final MessageIntegrity _senderMessageIntegrity;
|
||||
|
||||
DHTLogCubit<proto.Message>? _sentMessagesCubit;
|
||||
DHTLogCubit<proto.Message>? _rcvdMessagesCubit;
|
||||
DHTLog? _sentMessagesDHTLog;
|
||||
DHTLog? _rcvdMessagesDHTLog;
|
||||
TableDBArrayProtobufCubit<proto.ReconciledMessage>? _reconciledMessagesCubit;
|
||||
|
||||
late final MessageReconciliation _reconciliation;
|
||||
|
||||
late final PersistentQueue<proto.Message> _unsentMessagesQueue;
|
||||
// IList<proto.Message> _sendingMessages = const IList.empty();
|
||||
StreamSubscription<DHTLogBusyState<proto.Message>>? _sentSubscription;
|
||||
StreamSubscription<DHTLogBusyState<proto.Message>>? _rcvdSubscription;
|
||||
StreamSubscription<void>? _sentSubscription;
|
||||
StreamSubscription<void>? _rcvdSubscription;
|
||||
StreamSubscription<TableDBArrayProtobufBusyState<proto.ReconciledMessage>>?
|
||||
_reconciledSubscription;
|
||||
final StreamController<Future<void> Function()> _commandController;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue