token view refresh, and WIP token icon assets and other small fixes

This commit is contained in:
julian 2023-02-27 11:42:22 -06:00
parent 8dbefd87fe
commit 82842f1aa0
6 changed files with 103 additions and 37 deletions

View file

@ -4,11 +4,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart';
import 'package:stackwallet/pages/exchange_view/trade_details_view.dart';
import 'package:stackwallet/pages/token_view/token_view.dart';
import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart';
import 'package:stackwallet/providers/global/trades_service_provider.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
@ -25,11 +25,9 @@ class TokenTransactionsList extends ConsumerStatefulWidget {
const TokenTransactionsList({
Key? key,
required this.walletId,
required this.tokenService,
}) : super(key: key);
final String walletId;
final EthereumTokenService tokenService;
@override
ConsumerState<TokenTransactionsList> createState() =>
@ -208,7 +206,8 @@ class _TransactionsListState extends ConsumerState<TokenTransactionsList> {
.select((value) => value.getManager(widget.walletId)));
return FutureBuilder(
future: widget.tokenService.transactions,
future: ref
.watch(tokenServiceProvider.select((value) => value!.transactions)),
builder: (fbContext, AsyncSnapshot<List<Transaction>> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
@ -237,8 +236,8 @@ class _TransactionsListState extends ConsumerState<TokenTransactionsList> {
_transactions2.sort((a, b) => b.timestamp - a.timestamp);
return RefreshIndicator(
onRefresh: () async {
if (!widget.tokenService.isRefreshing) {
unawaited(widget.tokenService.refresh());
if (!ref.read(tokenServiceProvider)!.isRefreshing) {
unawaited(ref.read(tokenServiceProvider)!.refresh());
}
},
child: Util.isDesktop

View file

@ -4,8 +4,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/token_view/sub_widgets/token_summary.dart';
import 'package:stackwallet/pages/token_view/sub_widgets/token_transaction_list_widget.dart';
import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_refresh_button.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions_view.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -14,6 +17,7 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/background.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
import 'package:stackwallet/widgets/rounded_container.dart';
final tokenServiceStateProvider =
StateProvider<EthereumTokenService?>((ref) => null);
@ -29,7 +33,6 @@ class TokenView extends ConsumerStatefulWidget {
}) : super(key: key);
static const String routeName = "/token";
static const double navBarHeight = 65.0;
final String walletId;
final EventBus? eventBus;
@ -39,8 +42,13 @@ class TokenView extends ConsumerStatefulWidget {
}
class _TokenViewState extends ConsumerState<TokenView> {
late final WalletSyncStatus initialSyncStatus;
@override
void initState() {
initialSyncStatus = ref.read(tokenServiceProvider)!.isRefreshing
? WalletSyncStatus.syncing
: WalletSyncStatus.synced;
super.initState();
}
@ -62,35 +70,59 @@ class _TokenViewState extends ConsumerState<TokenView> {
Navigator.of(context).pop();
},
),
titleSpacing: 0,
centerTitle: true,
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset(
Assets.svg.iconFor(coin: Coin.ethereum),
Assets.svg.iconForToken(
contractAddress: ref.watch(tokenServiceProvider
.select((value) => value!.token.contractAddress))),
width: 24,
height: 24,
),
const SizedBox(
width: 16,
width: 10,
),
Expanded(
child: Text(
ref.watch(tokenServiceProvider
.select((value) => value!.token.name)),
Text(
ref.watch(
tokenServiceProvider.select((value) => value!.token.name)),
style: STextStyles.navBarTitle(context),
overflow: TextOverflow.ellipsis,
),
const SizedBox(
width: 6,
),
Expanded(
RoundedContainer(
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 4),
radiusMultiplier: 0.25,
color: const Color(
0xFF4D5798), // TODO: color theme for multi themes
child: Text(
ref.watch(tokenServiceProvider
.select((value) => value!.token.symbol)),
style: STextStyles.navBarTitle(context),
overflow: TextOverflow.ellipsis,
ref.watch(walletsChangeNotifierProvider.select((value) =>
value.getManager(widget.walletId).coin.ticker)),
style: STextStyles.w600_12(context).copyWith(
color: Colors.white, // TODO: design is wrong?
),
),
)
],
),
actions: [
Padding(
padding: const EdgeInsets.all(10),
child: AspectRatio(
aspectRatio: 1,
child: WalletRefreshButton(
walletId: widget.walletId,
initialSyncStatus: initialSyncStatus,
tokenContractAddress: ref.watch(tokenServiceProvider
.select((value) => value!.token.contractAddress)),
),
),
),
],
),
body: Container(
color: Theme.of(context).extension<StackColors>()!.background,
@ -161,8 +193,6 @@ class _TokenViewState extends ConsumerState<TokenView> {
children: [
Expanded(
child: TokenTransactionsList(
tokenService: ref.watch(tokenServiceProvider
.select((value) => value!)),
walletId: widget.walletId,
),
),

View file

@ -4,6 +4,7 @@ import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/token_view/token_view.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
@ -18,12 +19,14 @@ class WalletRefreshButton extends ConsumerStatefulWidget {
Key? key,
required this.walletId,
required this.initialSyncStatus,
this.tokenContractAddress,
this.onPressed,
this.eventBus,
}) : super(key: key);
final String walletId;
final WalletSyncStatus initialSyncStatus;
final String? tokenContractAddress;
final VoidCallback? onPressed;
final EventBus? eventBus;
@ -62,7 +65,9 @@ class _RefreshButtonState extends ConsumerState<WalletRefreshButton>
_syncStatusSubscription =
eventBus.on<WalletSyncStatusChangedEvent>().listen(
(event) async {
if (event.walletId == widget.walletId) {
if (event.walletId == widget.walletId &&
widget.tokenContractAddress == null ||
event.walletId == widget.walletId + widget.tokenContractAddress!) {
switch (event.newStatus) {
case WalletSyncStatus.unableToSync:
_spinController?.stop();
@ -104,6 +109,7 @@ class _RefreshButtonState extends ConsumerState<WalletRefreshButton>
: null,
splashColor: Theme.of(context).extension<StackColors>()!.highlight,
onPressed: () {
if (widget.tokenContractAddress == null) {
final managerProvider = ref
.read(walletsChangeNotifierProvider)
.getManagerProvider(widget.walletId);
@ -115,6 +121,11 @@ class _RefreshButtonState extends ConsumerState<WalletRefreshButton>
.refresh()
.then((_) => _spinController?.stop());
}
} else {
if (!ref.read(tokenServiceProvider)!.isRefreshing) {
ref.read(tokenServiceProvider)!.refresh();
}
}
},
elevation: 0,
highlightElevation: 0,

View file

@ -111,10 +111,13 @@ class EthTokenTx {
}
class EthereumResponse<T> {
EthereumResponse(this.value, this.exception);
final T? value;
final Exception? exception;
EthereumResponse(this.value, this.exception);
@override
toString() => "EthereumResponse{ value: $value, exception: $exception";
}
abstract class EthereumAPI {

View file

@ -14,6 +14,7 @@ import 'package:stackwallet/models/token_balance.dart';
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/services/mixins/eth_token_cache.dart';
import 'package:stackwallet/services/node_service.dart';
@ -196,6 +197,14 @@ class EthereumTokenService extends ChangeNotifier with EthTokenCache {
if (!_refreshLock) {
_refreshLock = true;
try {
GlobalEventBus.instance.fire(
WalletSyncStatusChangedEvent(
WalletSyncStatus.syncing,
ethWallet.walletId + token.contractAddress,
coin,
),
);
await refreshCachedBalance();
await _refreshTransactions();
} catch (e, s) {
@ -205,6 +214,13 @@ class EthereumTokenService extends ChangeNotifier with EthTokenCache {
);
} finally {
_refreshLock = false;
GlobalEventBus.instance.fire(
WalletSyncStatusChangedEvent(
WalletSyncStatus.synced,
ethWallet.walletId + token.contractAddress,
coin,
),
);
notifyListeners();
}
}
@ -217,7 +233,7 @@ class EthereumTokenService extends ChangeNotifier with EthTokenCache {
params: [_credentials.address]);
print("==========================================");
print("balanceRequest: $balanceRequest");
print("${token.name} balanceRequest: $balanceRequest");
print("==========================================");
String _balance = balanceRequest.first.toString();

View file

@ -278,6 +278,13 @@ class _SVG {
}
}
String iconForToken({required String contractAddress}) {
switch (contractAddress) {
default:
return ethereum;
}
}
// big icons
String bitcoinImage(BuildContext context) =>
"assets/images/${Theme.of(context).extension<StackColors>()!.themeType.name}/bitcoin.svg";