Skip to content

Commit

Permalink
Merge branch 'meta' into rc
Browse files Browse the repository at this point in the history
  • Loading branch information
br0ck-w00d committed Sep 24, 2024
2 parents d2d933d + a302475 commit 94b02f6
Show file tree
Hide file tree
Showing 17 changed files with 167 additions and 114 deletions.
1 change: 1 addition & 0 deletions magic/lib/cubits/app/cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class AppCubit extends UpdatableCubit<AppState> {
}

void authenticatedNow() => update(authenticatedAt: DateTime.now());

bool get isAuthenticated => () {
if (state.authenticatedAt != null) {
final seconds = DateTime.now()
Expand Down
6 changes: 2 additions & 4 deletions magic/lib/cubits/canvas/menu/cubit.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import 'dart:convert';

import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:magic/cubits/mixins.dart';
import 'package:magic/domain/concepts/side.dart';
import 'package:magic/domain/storage/storage.dart';
import 'package:magic/services/services.dart';

part 'state.dart';
Expand Down Expand Up @@ -74,14 +72,14 @@ class MenuCubit extends UpdatableCubit<MenuState> {

Future<void> loadSettings() async {
final DifficultyMode? modeSetting = DifficultyMode.fromName(
(await storage()).read(key: StorageKey.setting.key('mode')));
await storage.read(key: StorageKey.setting.key('mode')));
if (modeSetting != null) {
update(mode: modeSetting);
}
}

Future<void> saveSettings() async {
(await storage()).write(
storage.write(
key: StorageKey.setting.key('mode'),
value: state.mode.name,
);
Expand Down
10 changes: 5 additions & 5 deletions magic/lib/cubits/data/keys/cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ class KeysCubit extends UpdatableCubit<KeysState> {

// blockchain layer
Future<void> loadXPubs() async {
final List<dynamic> rawXpubs = jsonDecode(
((await storage()).read(key: StorageKey.xpubs.key())) ?? '[]');
final List<dynamic> rawXpubs =
jsonDecode(await (storage.read(key: StorageKey.xpubs.key())) ?? '[]');

final List<Map<String, Map<String, String>>> xpubs = rawXpubs.map((entry) {
// Ensure that the entry is cast to Map<String, dynamic> first
Expand All @@ -112,7 +112,7 @@ class KeysCubit extends UpdatableCubit<KeysState> {
submitting: false,
);
} else {
loadSecrets(onExisting: saveXPubs);
await loadSecrets(onExisting: saveXPubs);
}
}

Expand All @@ -134,7 +134,7 @@ class KeysCubit extends UpdatableCubit<KeysState> {
.cast<String>(),
submitting: false,
);
build(onExisting: onExisting);
await build(onExisting: onExisting);
}

Future<void> build({Future<void> Function()? onExisting}) async {
Expand Down Expand Up @@ -219,7 +219,7 @@ class KeysCubit extends UpdatableCubit<KeysState> {
.map((wallet) => wallet.asRootXPubMap)
.toList());
print(write);
(await storage()).writeKey(
storage.writeKey(
key: StorageKey.xpubs,
value: write,
);
Expand Down
82 changes: 47 additions & 35 deletions magic/lib/cubits/pane/transactions/cubit.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'dart:collection';
import 'dart:math';
import 'package:collection/collection.dart';
import 'package:equatable/equatable.dart';
Expand All @@ -7,7 +6,6 @@ import 'package:magic/cubits/cubit.dart';
import 'package:magic/cubits/mixins.dart';
import 'package:magic/domain/blockchain/blockchain.dart';
import 'package:magic/domain/concepts/money/rate.dart';
import 'package:magic/domain/concepts/numbers/coin.dart';
import 'package:magic/domain/concepts/holding.dart';
import 'package:magic/domain/concepts/numbers/sats.dart';
import 'package:magic/domain/concepts/transaction.dart';
Expand All @@ -17,13 +15,15 @@ import 'package:magic/services/calls/mempool.dart';
import 'package:magic/services/calls/transactions.dart';
import 'package:magic/services/services.dart';
import 'package:magic/utils/dart.dart';
import 'package:magic/utils/log.dart';

part 'state.dart';

class TransactionsCubit extends UpdatableCubit<TransactionsState> {
TransactionsCubit() : super(const TransactionsState());
bool reachedEnd = false;

late bool reachedEnd = false;
final Map<Asset, List<TransactionDisplay>> transactionsByAsset = {};

@override
String get key => 'transactions';
@override
Expand All @@ -47,14 +47,17 @@ class TransactionsCubit extends UpdatableCubit<TransactionsState> {
void update({
bool? active,
bool? disposed,
Holding? asset,
// should be Transaction then we convert to a display object in the ui or state.
Asset? asset,
List<TransactionDisplay>? mempool,
List<TransactionDisplay>? transactions,
Widget? child,
bool? clearing,
bool? isSubmitting,
}) {
if (transactions != null && asset != null) {
transactions = syncTransactions(transactions, asset);
}

emit(TransactionsState(
active: active ?? state.active,
asset: asset ?? state.asset,
Expand All @@ -72,14 +75,24 @@ class TransactionsCubit extends UpdatableCubit<TransactionsState> {
int? fromHeight,
}) async {
holding = holding ?? cubits.holding.state.holding;
update(isSubmitting: true);
await populateTransactions(holding: holding, fromHeight: fromHeight);
await populateMempoolTransactions(holding: holding);
see('${holding.symbol} ${cubits.holding.state.holding.symbol}');
if (holding.symbol != cubits.holding.state.holding.symbol) {
return;
if (transactionsByAsset.containsKey(holding.asset)) {
update(isSubmitting: true);
update(
asset: holding.asset,
transactions: transactionsByAsset[holding.asset]);
await populateTransactions(holding: holding, fromHeight: fromHeight);
await populateMempoolTransactions(holding: holding);
update(isSubmitting: false);
} else {
await populateTransactions(holding: holding, fromHeight: fromHeight);
update(isSubmitting: true);
await populateTransactions(holding: holding, fromHeight: fromHeight);
await populateMempoolTransactions(holding: holding);
if (holding.symbol != cubits.holding.state.holding.symbol) {
return;
}
update(isSubmitting: false);
}
update(isSubmitting: false);
}

Future<void> populateTransactions({Holding? holding, int? fromHeight}) async {
Expand All @@ -93,16 +106,7 @@ class TransactionsCubit extends UpdatableCubit<TransactionsState> {
update(isSubmitting: true);
}
await Future.delayed(fadeDuration * 10);
see('populating transactions: ${state.transactions.length}');
final replace = holding != cubits.holding.state.holding;
// get the max transaction.height from the list of transactions
fromHeight = fromHeight ??
(state.transactions.isNotEmpty
? state.transactions
.map((transaction) => transaction.height)
.reduce((a, b) => a < b ? a : b)
: null);
see('asking from: ${fromHeight ?? (state.transactions.isNotEmpty ? state.transactions.length : null)}');
final transactions = _sort(_newRateThese(
rate: holding.isRavencoin
? rates.rvnUsdRate
Expand All @@ -121,7 +125,6 @@ class TransactionsCubit extends UpdatableCubit<TransactionsState> {
update(isSubmitting: isSubmitting);
return;
}
see('${holding.symbol} ${cubits.holding.state.holding.symbol}');
if (holding.symbol != cubits.holding.state.holding.symbol) {
return;
}
Expand All @@ -132,6 +135,7 @@ class TransactionsCubit extends UpdatableCubit<TransactionsState> {
reachedEnd = true;
}
update(
asset: holding.asset,
transactions: newTransactions,
isSubmitting: isSubmitting,
);
Expand Down Expand Up @@ -166,20 +170,18 @@ class TransactionsCubit extends UpdatableCubit<TransactionsState> {
blockchain: holding.blockchain,
symbol: holding.symbol,
).call()));
see('${holding.symbol} ${cubits.holding.state.holding.symbol}');
if (holding.symbol != cubits.holding.state.holding.symbol) {
return;
}
update(
mempool: transactions,
isSubmitting: isSubmitting,
);
see('1 $isSubmitting');
}

void clearTransactions() {
reachedEnd = false;
update(mempool: [], transactions: []);
update(asset: const Asset.empty(), mempool: [], transactions: []);
}

Future<void> slowlyClearTransactions() async {
Expand Down Expand Up @@ -207,16 +209,10 @@ class TransactionsCubit extends UpdatableCubit<TransactionsState> {
transactions.sortedBy((e) => e.when).reversed.toList();

void populate() => update(
asset: Holding(
asset: const Asset(
name: 'Ravencoin',
symbol: 'RVN',
blockchain: Blockchain.ravencoinMain,
sats: Sats(21),
metadata: HoldingMetadata(
divisibility: Divisibility(8),
reissuable: false,
supply: Sats.fromCoin(Coin(coin: 21000000000)),
),
),
transactions: [
for (final index in range(16))
Expand All @@ -233,6 +229,22 @@ class TransactionsCubit extends UpdatableCubit<TransactionsState> {
}()))
]);

// todo pagenae list of holdings
//Holding getNextBatch(List<Holding> batch) {}
List<TransactionDisplay> syncTransactions(
List<TransactionDisplay> newTransactions,
Asset holding,
) {
if (!transactionsByAsset.containsKey(holding)) {
transactionsByAsset[holding] = [];
}
List<TransactionDisplay> cachedTransactions = transactionsByAsset[holding]!;
for (var newTransaction in newTransactions) {
if (!cachedTransactions
.any((cached) => cached.height == newTransaction.height)) {
cachedTransactions.add(newTransaction);
}
}
cachedTransactions.sort((a, b) => b.height.compareTo(a.height));
transactionsByAsset[holding] = cachedTransactions;
return cachedTransactions;
}
}
4 changes: 2 additions & 2 deletions magic/lib/cubits/pane/transactions/state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ part of 'cubit.dart';
@immutable
class TransactionsState with EquatableMixin, PriorActiveStateMixin {
final bool active;
final Holding asset;
final Asset asset;
final List<TransactionDisplay> mempool;
final List<TransactionDisplay> transactions;
final Widget child;
Expand All @@ -13,7 +13,7 @@ class TransactionsState with EquatableMixin, PriorActiveStateMixin {

const TransactionsState({
this.active = false,
this.asset = const Holding.empty(),
this.asset = const Asset.empty(),
this.mempool = const [],
this.transactions = const [],
this.child = const SizedBox.shrink(),
Expand Down
5 changes: 2 additions & 3 deletions magic/lib/cubits/pane/wallet/cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,8 @@ class WalletCubit extends UpdatableCubit<WalletState> {
.map((e) => e.coin.toFiat(e.rate).value)
.sumNumbers()));
// save to disk, so we can load it on next app start
storage().then((obj) => obj.write(
key: StorageKey.rate.key(rate.id),
value: rate.rate.toStringAsFixed(4)));
storage.write(
key: StorageKey.rate.key(rate.id), value: rate.rate.toStringAsFixed(4));
}

Holding? adminOf(Holding holding, [List<Holding>? overrideHoldings]) =>
Expand Down
36 changes: 36 additions & 0 deletions magic/lib/domain/concepts/holding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,41 @@ import 'package:magic/domain/concepts/numbers/fiat.dart';
import 'package:magic/domain/concepts/numbers/sats.dart';
import 'package:magic/domain/server/protocol/comm_balance_view.dart';

class Asset extends Equatable {
final String name;
final String symbol;
final Blockchain blockchain;

const Asset({
required this.name,
required this.symbol,
required this.blockchain,
});

const Asset.empty()
: name = '',
symbol = '',
blockchain = Blockchain.none;

factory Asset.fromHolding({
required Holding holding,
}) =>
Asset(
name: holding.name,
symbol: holding.symbol,
blockchain: holding.blockchain);

@override
String toString() => '$runtimeType($props)';

@override
List<Object?> get props => <Object?>[
name,
symbol,
blockchain,
];
}

class Holding extends Equatable {
final String name;
final String symbol;
Expand Down Expand Up @@ -99,6 +134,7 @@ class Holding extends Equatable {
bool get isOnEvrmore => blockchain.symbol == 'EVR';
bool get isOnRavencoin => blockchain.symbol == 'RVN';

Asset get asset => Asset.fromHolding(holding: this);
Coin get coin => sats.toCoin();
Fiat get fiat {
if (rate != null) {
Expand Down
10 changes: 5 additions & 5 deletions magic/lib/domain/storage/storage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ enum StorageKey {
}
}

extension ReadWriteExt on SharedPreferences {
Future<bool> write({required String key, required String value}) async =>
extension ReadWriteExt on SharedPreferencesAsync {
Future<void> write({required String key, required String value}) async =>
await setString(key, value);
Future<bool> writeKey({
Future<void> writeKey({
required StorageKey key,
required String value,
}) async =>
await setString(key.key(), value);
String? read({required String key}) => getString(key);
String? readKey({required StorageKey key}) => getString(key.key());
Future<String?> read({required String key}) => getString(key);
Future<String?> readKey({required StorageKey key}) => getString(key.key());
}
Loading

0 comments on commit 94b02f6

Please sign in to comment.