From 3cbfe556cf50338218ff75cc898b7a3b4d3c11ed Mon Sep 17 00:00:00 2001 From: Guillaume Daguin <81367366+gdaguin@users.noreply.github.com> Date: Fri, 29 Sep 2023 07:53:02 +0200 Subject: [PATCH] Read older messages Still TODO : - Read more than 10 transactions within the transaction chain (default) - Discussion updates are of type 'call', which means that we are not retrieving enough messages when calling the read method --- lib/src/utils/messenger/messages_util.dart | 134 +++++++++++++++++---- 1 file changed, 112 insertions(+), 22 deletions(-) diff --git a/lib/src/utils/messenger/messages_util.dart b/lib/src/utils/messenger/messages_util.dart index aa3b637..f038152 100644 --- a/lib/src/utils/messenger/messages_util.dart +++ b/lib/src/utils/messenger/messages_util.dart @@ -128,42 +128,44 @@ mixin MessagesMixin { int limit = 0, int pagingOffset = 0, }) async { - final messagesList = await apiService.getTransactionInputs( - [discussionSCAddress], + final transactions = await _listTransactions( + apiService: apiService, + discussionSCAddress: discussionSCAddress, + ); + + final txContentMessageAddressesToTransactionAddress = + await _txContentMessageAddressesToTransactionAddress( + apiService: apiService, + transactions: transactions, limit: limit, pagingOffset: pagingOffset, ); - final txContentMessagesList = - messagesList[discussionSCAddress] ?? []; - final txContentMessagesAddresses = txContentMessagesList - .where( - (txContentMessage) => - txContentMessage.from != null && txContentMessage.type == 'call', - ) - .map((txContentMessage) => txContentMessage.from) - .whereType() - .toList(); final aeMessages = []; final contents = await apiService.getTransaction( - txContentMessagesAddresses, + txContentMessageAddressesToTransactionAddress.keys.toList(), request: ' address, chainLength, data { content }, previousPublicKey, validationStamp { timestamp } ', ); if (contents.isEmpty) return []; - final discussionKeyAccess = uint8ListToHex( - await DiscussionUtil().getDiscussionKeyAccess( - apiService: apiService, - discussionSCAddress: discussionSCAddress, - keyPair: readerKeyPair, - ), - ); + for (final contentMessageAddress + in txContentMessageAddressesToTransactionAddress.keys.toList()) { + final discussionKeyAccess = uint8ListToHex( + await DiscussionUtil().getDiscussionKeyAccess( + apiService: apiService, + discussionSCAddress: txContentMessageAddressesToTransactionAddress[ + contentMessageAddress]!, + keyPair: readerKeyPair, + ), + ); - for (final contentMessageAddress in txContentMessagesAddresses) { final contentMessageTransaction = contents[contentMessageAddress]; - if (contentMessageTransaction == null) continue; + if (contentMessageTransaction?.data?.content == null || + contentMessageTransaction!.data!.content!.isEmpty) { + continue; + } final transactionContentIM = TransactionContentMessaging.fromJson( jsonDecode(contentMessageTransaction.data!.content!), @@ -210,6 +212,94 @@ mixin MessagesMixin { return aeMessages; } + + Future> _listTransactions({ + required ApiService apiService, + required String discussionSCAddress, + }) async { + final listTransactions = []; + + final transactionChain = await apiService.getTransactionChain( + {discussionSCAddress: ''}, + orderAsc: false, + ); + + if (transactionChain[discussionSCAddress] != null) { + listTransactions.addAll(transactionChain[discussionSCAddress]!.toList()); + } + + return listTransactions; + } + + Future> _txContentMessageAddressesToTransactionAddress({ + required ApiService apiService, + required List transactions, + int limit = 0, + int pagingOffset = 0, + }) async { + final txContentMessageAddressesToTransactionAddress = {}; + for (final transaction in transactions) { + final transactionAddress = transaction.address?.address; + + if (transactionAddress == null) { + continue; + } + + var bufPagingOffset = pagingOffset; + var bufTxContentMessageAddresses = []; + do { + bufTxContentMessageAddresses = await _messagesAddresses( + apiService: apiService, + discussionSCAddress: transactionAddress, + limit: limit, + pagingOffset: bufPagingOffset, + ); + + for (final txContentMessageAddress in bufTxContentMessageAddresses) { + txContentMessageAddressesToTransactionAddress[ + txContentMessageAddress] = transactionAddress; + } + bufPagingOffset += limit; + } while (txContentMessageAddressesToTransactionAddress.length < limit && + bufTxContentMessageAddresses.isNotEmpty); + + if (txContentMessageAddressesToTransactionAddress.length >= limit) { + break; + } + } + return txContentMessageAddressesToTransactionAddress; + } + + Future> _messagesAddresses({ + required ApiService apiService, + required String discussionSCAddress, + int limit = 0, + int pagingOffset = 0, + }) async { + final messagesList = await apiService.getTransactionInputs( + [discussionSCAddress], + limit: limit, + pagingOffset: pagingOffset, + ); + + final txContentMessagesList = + messagesList[discussionSCAddress] ?? []; + final messageTransactions = txContentMessagesList + .where( + (txContentMessage) => + txContentMessage.from != null && txContentMessage.type == 'call', + ) + .map((txContentMessage) => txContentMessage.from) + .whereType() + .toList(); + final contents = await apiService.getTransaction( + messageTransactions, + request: + ' address, chainLength, data { content }, previousPublicKey, validationStamp { timestamp } ', + ); + + return messageTransactions; + } } class DiscussionUtil with DiscussionMixin {}