Skip to content
This repository has been archived by the owner on Sep 17, 2024. It is now read-only.

Commit

Permalink
Merge pull request #75 from MXCzkEVM/cache_update_bug_fix
Browse files Browse the repository at this point in the history
Cache update bug fix
  • Loading branch information
reasje authored Oct 3, 2023
2 parents 74f6f3c + f807b1a commit c899fe1
Show file tree
Hide file tree
Showing 19 changed files with 249 additions and 171 deletions.
Original file line number Diff line number Diff line change
@@ -1,57 +1,41 @@
import 'package:datadashwallet/common/components/recent_transactions/entity/transaction_history_model.dart';
import 'package:mxc_logic/mxc_logic.dart';
import 'package:datadashwallet/core/core.dart';

class TransactionsHistoryRepository extends ControlledCacheRepository {
@override
final String zone = 'transaction-history';

late final Field<List<TransactionHistoryModel>> transactionsHistory =
fieldWithDefault<List<TransactionHistoryModel>>('items', [],
late final Field<List<TransactionModel>> transactionsHistory =
fieldWithDefault<List<TransactionModel>>('items', [],
serializer: (b) => b
.map((e) => {
'chainId': e.chainId,
'txList': e.txList.map((e) => e.toMap()).toList()
})
.map((e) => e.toMap())
.toList(),
deserializer: (b) => (b as List)
.map((e) => TransactionHistoryModel(
chainId: e['chainId'],
txList: (e['txList'] as List)
.map((e) => TransactionModel.fromMap(e))
.toList(),
))
.map((e) => TransactionModel.fromMap(e)
)
.toList());

List<TransactionHistoryModel> get items => transactionsHistory.value;
List<TransactionModel> get items => transactionsHistory.value;

void addItem(TransactionHistoryModel item) =>
transactionsHistory.value = [...transactionsHistory.value, item];

void addItemTx(TransactionModel item, int index) {
final newList = transactionsHistory.value;
newList[index].txList.insert(0, item);
transactionsHistory.value = newList;
}

void updateItem(TransactionHistoryModel item, int index) {
void addItem(TransactionModel item, int index) {
final newList = transactionsHistory.value;
newList.removeAt(index);
newList.insert(index, item);
newList.insert(0, item);
transactionsHistory.value = newList;
}

void updateItemTx(TransactionModel item, int index, int txIndex) {
void updateItem(TransactionModel item, int index,) {
final newList = transactionsHistory.value;

newList[index].txList[txIndex] = item;
newList[index] = item;

transactionsHistory.value = newList;
}

void removeItem(TransactionHistoryModel item) =>
void removeItem(TransactionModel item) =>
transactionsHistory.value = transactionsHistory.value
.where((e) => e.chainId != item.chainId)
.where((e) => e.hash != item.hash)
.toList();

void removeAll() => transactionsHistory.value = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import 'package:datadashwallet/common/common.dart';
import 'package:datadashwallet/core/core.dart';
import 'package:mxc_logic/mxc_logic.dart';
import '../entity/transaction_history_model.dart';
import 'transactions_repository.dart';
import 'package:web3dart/web3dart.dart';

class TransactionsHistoryUseCase extends ReactiveUseCase {
Expand All @@ -12,36 +10,27 @@ class TransactionsHistoryUseCase extends ReactiveUseCase {

final TransactionsHistoryRepository _repository;

late final ValueStream<List<TransactionHistoryModel>> transactionsHistory =
late final ValueStream<List<TransactionModel>> transactionsHistory =
reactiveField(_repository.transactionsHistory);

List<TransactionHistoryModel> getTransactionsHistory() => _repository.items;
List<TransactionModel> getTransactionsHistory() => _repository.items;

List<String> updatingTxList = [];

void addItem(TransactionHistoryModel item) {
_repository.addItem(item);
update(transactionsHistory, _repository.items);
}

void updateItem(TransactionHistoryModel item, int index) {
_repository.updateItem(item, index);
update(transactionsHistory, _repository.items);
}

void updateItemTx(TransactionModel item, int selectedNetworkChainId) {
final txHistory = transactionsHistory.value
.firstWhere((element) => element.chainId == selectedNetworkChainId);

final index = transactionsHistory.value.indexOf(txHistory);
final txIndex = txHistory.txList.indexWhere(
void updateItem(
TransactionModel item,
) {
final index = transactionsHistory.value.indexWhere(
(element) => element.hash == item.hash,
);

if (txIndex == -1) {
_repository.addItemTx(item, index);
if (index == -1) {
_repository.addItem(item, index);
} else {
_repository.updateItemTx(item, index, txIndex);
_repository.updateItem(
item,
index,
);
}

update(transactionsHistory, _repository.items);
Expand All @@ -52,19 +41,23 @@ class TransactionsHistoryUseCase extends ReactiveUseCase {
update(transactionsHistory, _repository.items);
}

void removeItem(TransactionHistoryModel item) {
void removeItem(TransactionModel item) {
_repository.removeItem(item);
update(transactionsHistory, _repository.items);
}

void spyOnTransaction(TransactionModel item, int chainId) {
void spyOnTransaction(
TransactionModel item,
) {
if (!updatingTxList.contains(item.hash)) {
updatingTxList.add(item.hash);
final stream = _web3Repository.tokenContract.spyTransaction(item.hash);
stream.onData((succeeded) {
if (succeeded) {
final updatedItem = item.copyWith(status: TransactionStatus.done);
updateItemTx(updatedItem, chainId);
updateItem(
updatedItem,
);
updatingTxList.remove(item.hash);
stream.cancel();
}
Expand All @@ -74,16 +67,13 @@ class TransactionsHistoryUseCase extends ReactiveUseCase {

void checkForPendingTransactions(int chainId) {
if (!Config.isMxcChains(chainId)) {
final index = transactionsHistory.value
.indexWhere((element) => element.chainId == chainId);

if (index != -1) {
final chainTx = transactionsHistory.value[index];
final pendingTxList = chainTx.txList
.where((element) => element.status == TransactionStatus.pending);
for (TransactionModel pendingTx in pendingTxList) {
spyOnTransaction(pendingTx, chainId);
}
final txList = transactionsHistory.value;
final pendingTxList = txList
.where((element) => element.status == TransactionStatus.pending);
for (TransactionModel pendingTx in pendingTxList) {
spyOnTransaction(
pendingTx,
);
}
}
}
Expand All @@ -97,19 +87,10 @@ class TransactionsHistoryUseCase extends ReactiveUseCase {

if (receipt != null) {
final tx = TransactionModel.fromTransaction(receipt, address, token);
spyOnTransaction(tx, chainId);
updateItemTx(tx, chainId);
spyOnTransaction(tx);
updateItem(
tx,
);
}
}

void checkChainAvailability(int chainId) {
final index = transactionsHistory.value
.indexWhere((element) => element.chainId == chainId);

if (index == -1) {
addItem(TransactionHistoryModel(chainId: chainId, txList: []));
return;
}
update(transactionsHistory, _repository.items);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import 'package:mxc_ui/mxc_ui.dart';

export 'domain/transactions_use_case.dart';
export 'domain/transactions_repository.dart';
export 'entity/transaction_history_model.dart';

class RecentTransactions extends HookConsumerWidget {
const RecentTransactions({
Expand Down
8 changes: 8 additions & 0 deletions lib/common/utils/formatter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,12 @@ class Formatter {
final splitValue = value.split('.');
return '${splitValue[0]}.${splitValue[1].substring(0, 8)}';
}

static Uri mergeUrl(String first, String second) {
return Uri.parse(first).resolve(second);
}

static String mergeUrlString(String first, String second) {
return Uri.parse(first).resolve(second).toString();
}
}
26 changes: 22 additions & 4 deletions lib/core/src/providers/providers_loader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ part of 'providers.dart';
DatadashCache? _datadashCache;
GlobalCache? _globalCache;
DatadashSetupStore? _datadashSetupStore;
CacheManager? _cacheManager;

class _ProviderLoader {
Future<CacheManager> getCacheManager() async {
Expand All @@ -13,24 +14,41 @@ class _ProviderLoader {
}

Future<void> loadProviders() async {
final cacheManager = await getCacheManager();
_cacheManager = await getCacheManager();
_datadashSetupStore = DatadashSetupStore();
await _datadashSetupStore!.load(cacheManager);
await _datadashSetupStore!.load(_cacheManager!);

final currentNetwork = _datadashSetupStore?.getNetwork ??
Network.fixedNetworks().where((item) => item.enabled).first;
final username =
'${currentNetwork.chainId}_${_datadashSetupStore?.publicAddress}';

_datadashCache = await DatadashCache.load(
cacheManager,
_cacheManager!,
username,
);

_globalCache = await GlobalCache.load(cacheManager);
_globalCache = await GlobalCache.load(_cacheManager!);
}

Future<void> loadDataDashProviders() async {
final currentNetwork = _datadashSetupStore?.getNetwork ??
Network.fixedNetworks().where((item) => item.enabled).first;
final username =
'${currentNetwork.chainId}_${_datadashSetupStore?.publicAddress}';

_datadashCache = await DatadashCache.load(
_cacheManager!,
username,
);
}
}

Future<void> loadProviders() async {
await _ProviderLoader().loadProviders();
}

Future<void> loadDataDashProviders(Network network) async {
_datadashSetupStore!.network = network;
await _ProviderLoader().loadDataDashProviders();
}
18 changes: 18 additions & 0 deletions lib/core/src/use_case/reactive_use_case.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:async';

import 'package:meta/meta.dart';
import 'package:mxc_logic/mxc_logic.dart';
import 'package:datadashwallet/core/core.dart';
Expand All @@ -6,6 +8,7 @@ export 'package:rxdart/rxdart.dart';

class ReactiveUseCase implements Disposable {
final Map<ValueStream, ReactiveController> _streamToController = {};
final List<StreamSubscription> listeners = [];

ValueStream<T> reactive<T>([T? value]) {
final controller = ReactiveController(value);
Expand All @@ -18,6 +21,9 @@ class ReactiveUseCase implements Disposable {
final controller = ReactiveFieldController(field);
final stream = controller.stream;
_streamToController[stream] = controller;

initUpdater(stream, field);

return stream;
}

Expand All @@ -35,11 +41,23 @@ class ReactiveUseCase implements Disposable {

@override
Future<void> dispose() async {
for (final l in listeners) {
l.cancel();
}

for (final c in _streamToController.values) {
await c.dispose();
}
for (final d in _disposables) {
await d.dispose();
}
}

/// This listener is initialized to update the reactive field value
/// via the data base updates.
void initUpdater<T>(ValueStream stream, Field<T> field) {
listeners.add(field.valueStream.listen((event) {
_streamToController[stream]!.save(event);
}));
}
}
Loading

0 comments on commit c899fe1

Please sign in to comment.