mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-03-22 15:19:11 +00:00
Merge remote-tracking branch 'stack_wallet_origin/ui-fixes' into firo/spend-mints
This commit is contained in:
commit
5262bd8933
7 changed files with 157 additions and 205 deletions
|
@ -111,6 +111,7 @@ class _ExchangeCurrencySelectionViewState
|
||||||
return currencies;
|
return currencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
await showDialog<void>(
|
await showDialog<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => StackDialog(
|
builder: (context) => StackDialog(
|
||||||
|
@ -124,13 +125,14 @@ class _ExchangeCurrencySelectionViewState
|
||||||
label: "Retry",
|
label: "Retry",
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
Navigator.of(context, rootNavigator: isDesktop).pop();
|
Navigator.of(context, rootNavigator: isDesktop).pop();
|
||||||
_currencies =
|
_currencies = await _showUpdatingCurrencies(
|
||||||
await _showUpdatingCurrencies(whileFuture: _loadCurrencies());
|
whileFuture: _loadCurrencies());
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
currencies.addAll(cn.value!);
|
currencies.addAll(cn.value!);
|
||||||
}
|
}
|
||||||
|
@ -180,13 +182,13 @@ class _ExchangeCurrencySelectionViewState
|
||||||
.where((e) =>
|
.where((e) =>
|
||||||
e.name.toLowerCase().contains(text.toLowerCase()) ||
|
e.name.toLowerCase().contains(text.toLowerCase()) ||
|
||||||
e.ticker.toLowerCase().contains(text.toLowerCase()))
|
e.ticker.toLowerCase().contains(text.toLowerCase()))
|
||||||
.toList(growable: false);
|
.toList();
|
||||||
} else {
|
} else {
|
||||||
if (text.isEmpty) {
|
if (text.isEmpty) {
|
||||||
return _currencies
|
return _currencies
|
||||||
.where((e) =>
|
.where((e) =>
|
||||||
e.ticker.toLowerCase() != widget.pairedTicker!.toLowerCase())
|
e.ticker.toLowerCase() != widget.pairedTicker!.toLowerCase())
|
||||||
.toList(growable: false);
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _currencies
|
return _currencies
|
||||||
|
@ -194,7 +196,7 @@ class _ExchangeCurrencySelectionViewState
|
||||||
e.ticker.toLowerCase() != widget.pairedTicker!.toLowerCase() &&
|
e.ticker.toLowerCase() != widget.pairedTicker!.toLowerCase() &&
|
||||||
(e.name.toLowerCase().contains(text.toLowerCase()) ||
|
(e.name.toLowerCase().contains(text.toLowerCase()) ||
|
||||||
e.ticker.toLowerCase().contains(text.toLowerCase())))
|
e.ticker.toLowerCase().contains(text.toLowerCase())))
|
||||||
.toList(growable: false);
|
.toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,18 +330,34 @@ class _ExchangeCurrencySelectionViewState
|
||||||
height: 12,
|
height: 12,
|
||||||
),
|
),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Builder(builder: (context) {
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
final coins = Coin.values.where((e) =>
|
final coins = Coin.values.where((e) =>
|
||||||
e.ticker.toLowerCase() != widget.pairedTicker?.toLowerCase());
|
e.ticker.toLowerCase() !=
|
||||||
|
widget.pairedTicker?.toLowerCase());
|
||||||
|
|
||||||
final items = filter(_searchString)
|
final items = filter(_searchString);
|
||||||
.where((e) => coins
|
|
||||||
|
final walletCoins = items
|
||||||
|
.where((currency) => coins
|
||||||
.where((coin) =>
|
.where((coin) =>
|
||||||
coin.ticker.toLowerCase() == e.ticker.toLowerCase())
|
coin.ticker.toLowerCase() ==
|
||||||
|
currency.ticker.toLowerCase())
|
||||||
.isNotEmpty)
|
.isNotEmpty)
|
||||||
.toList(growable: false);
|
.toList();
|
||||||
|
|
||||||
|
// sort alphabetically by name
|
||||||
items.sort((a, b) => a.name.compareTo(b.name));
|
items.sort((a, b) => a.name.compareTo(b.name));
|
||||||
|
|
||||||
|
// reverse sort walletCoins to prepare for next step
|
||||||
|
walletCoins.sort((a, b) => b.name.compareTo(a.name));
|
||||||
|
|
||||||
|
// insert wallet coins at beginning
|
||||||
|
for (final c in walletCoins) {
|
||||||
|
items.remove(c);
|
||||||
|
items.insert(0, c);
|
||||||
|
}
|
||||||
|
|
||||||
return RoundedWhiteContainer(
|
return RoundedWhiteContainer(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
|
@ -384,11 +402,13 @@ class _ExchangeCurrencySelectionViewState
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
items[index].name,
|
items[index].name,
|
||||||
style: STextStyles.largeMedium14(context),
|
style:
|
||||||
|
STextStyles.largeMedium14(context),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 2,
|
height: 2,
|
||||||
|
@ -413,96 +433,8 @@ class _ExchangeCurrencySelectionViewState
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 20,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
"All coins",
|
|
||||||
style: STextStyles.smallMed12(context),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
Flexible(
|
|
||||||
child: Builder(builder: (context) {
|
|
||||||
final filtered = filter(_searchString);
|
|
||||||
filtered.sort((a, b) => a.name.compareTo(b.name));
|
|
||||||
return RoundedWhiteContainer(
|
|
||||||
padding: const EdgeInsets.all(0),
|
|
||||||
child: ListView.builder(
|
|
||||||
shrinkWrap: true,
|
|
||||||
primary: isDesktop ? false : null,
|
|
||||||
itemCount: filtered.length,
|
|
||||||
itemBuilder: (builderContext, index) {
|
|
||||||
final bool hasImageUrl =
|
|
||||||
filtered[index].image.startsWith("http");
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).pop(filtered[index]);
|
|
||||||
},
|
|
||||||
child: RoundedWhiteContainer(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
child: isStackCoin(filtered[index].ticker)
|
|
||||||
? getIconForTicker(
|
|
||||||
filtered[index].ticker,
|
|
||||||
size: 24,
|
|
||||||
)
|
|
||||||
: hasImageUrl
|
|
||||||
? SvgPicture.network(
|
|
||||||
filtered[index].image,
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
placeholderBuilder: (_) =>
|
|
||||||
const LoadingIndicator(),
|
|
||||||
)
|
|
||||||
: const SizedBox(
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 10,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
filtered[index].name,
|
|
||||||
style: STextStyles.largeMedium14(context),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 2,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
filtered[index].ticker.toUpperCase(),
|
|
||||||
style: STextStyles.smallMed12(context)
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textSubtitle1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -149,6 +149,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
||||||
currency.ticker,
|
currency.ticker,
|
||||||
caseSensitive: false,
|
caseSensitive: false,
|
||||||
)
|
)
|
||||||
|
.and()
|
||||||
|
.tokenContractEqualTo(currency.tokenContract)
|
||||||
.findAll();
|
.findAll();
|
||||||
|
|
||||||
final items = [Tuple2(currency.exchangeName, currency)];
|
final items = [Tuple2(currency.exchangeName, currency)];
|
||||||
|
@ -631,6 +633,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
||||||
.getAggregateCurrency(
|
.getAggregateCurrency(
|
||||||
widget.contract == null ? coin!.ticker : widget.contract!.symbol,
|
widget.contract == null ? coin!.ticker : widget.contract!.symbol,
|
||||||
ExchangeRateType.estimated,
|
ExchangeRateType.estimated,
|
||||||
|
widget.contract == null ? null : widget.contract!.address,
|
||||||
)
|
)
|
||||||
.then((value) {
|
.then((value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:qr_flutter/qr_flutter.dart';
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
||||||
import 'package:stackwallet/pages/receive_view/addresses/wallet_addresses_view.dart';
|
import 'package:stackwallet/pages/receive_view/addresses/wallet_addresses_view.dart';
|
||||||
import 'package:stackwallet/pages/receive_view/generate_receiving_uri_qr_code_view.dart';
|
import 'package:stackwallet/pages/receive_view/generate_receiving_uri_qr_code_view.dart';
|
||||||
|
@ -25,15 +26,15 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
class ReceiveView extends ConsumerStatefulWidget {
|
class ReceiveView extends ConsumerStatefulWidget {
|
||||||
const ReceiveView({
|
const ReceiveView({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.coin,
|
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
|
this.tokenContract,
|
||||||
this.clipboard = const ClipboardWrapper(),
|
this.clipboard = const ClipboardWrapper(),
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
static const String routeName = "/receiveView";
|
static const String routeName = "/receiveView";
|
||||||
|
|
||||||
final Coin coin;
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
|
final EthContract? tokenContract;
|
||||||
final ClipboardInterface clipboard;
|
final ClipboardInterface clipboard;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -86,7 +87,7 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
walletId = widget.walletId;
|
walletId = widget.walletId;
|
||||||
coin = widget.coin;
|
coin = ref.read(walletsChangeNotifierProvider).getManager(walletId).coin;
|
||||||
clipboard = widget.clipboard;
|
clipboard = widget.clipboard;
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
||||||
|
@ -117,6 +118,8 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final ticker = widget.tokenContract?.symbol ?? coin.ticker;
|
||||||
|
|
||||||
return Background(
|
return Background(
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
|
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
|
||||||
|
@ -127,7 +130,7 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
"Receive ${coin.ticker}",
|
"Receive $ticker",
|
||||||
style: STextStyles.navBarTitle(context),
|
style: STextStyles.navBarTitle(context),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
|
@ -245,7 +248,7 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> {
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Your ${coin.ticker} address",
|
"Your $ticker address",
|
||||||
style: STextStyles.itemSubtitle(context),
|
style: STextStyles.itemSubtitle(context),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
|
|
|
@ -209,7 +209,7 @@ class TokenWalletOptions extends StatelessWidget {
|
||||||
ReceiveView.routeName,
|
ReceiveView.routeName,
|
||||||
arguments: Tuple2(
|
arguments: Tuple2(
|
||||||
walletId,
|
walletId,
|
||||||
Coin.ethereum,
|
tokenContract,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -800,10 +800,7 @@ class _WalletViewState extends ConsumerState<WalletView> {
|
||||||
unawaited(
|
unawaited(
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
ReceiveView.routeName,
|
ReceiveView.routeName,
|
||||||
arguments: Tuple2(
|
arguments: walletId,
|
||||||
walletId,
|
|
||||||
coin,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1019,12 +1019,22 @@ class RouteGenerator {
|
||||||
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
case ReceiveView.routeName:
|
case ReceiveView.routeName:
|
||||||
if (args is Tuple2<String, Coin>) {
|
if (args is String) {
|
||||||
|
return getRoute(
|
||||||
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
|
builder: (_) => ReceiveView(
|
||||||
|
walletId: args,
|
||||||
|
),
|
||||||
|
settings: RouteSettings(
|
||||||
|
name: settings.name,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (args is Tuple2<String, EthContract?>) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
builder: (_) => ReceiveView(
|
builder: (_) => ReceiveView(
|
||||||
walletId: args.item1,
|
walletId: args.item1,
|
||||||
coin: args.item2,
|
tokenContract: args.item2,
|
||||||
),
|
),
|
||||||
settings: RouteSettings(
|
settings: RouteSettings(
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
|
|
|
@ -61,10 +61,12 @@ class ExchangeDataLoadingService {
|
||||||
final sendCurrency = await getAggregateCurrency(
|
final sendCurrency = await getAggregateCurrency(
|
||||||
"BTC",
|
"BTC",
|
||||||
state.exchangeRateType,
|
state.exchangeRateType,
|
||||||
|
null,
|
||||||
);
|
);
|
||||||
final receiveCurrency = await getAggregateCurrency(
|
final receiveCurrency = await getAggregateCurrency(
|
||||||
"XMR",
|
"XMR",
|
||||||
state.exchangeRateType,
|
state.exchangeRateType,
|
||||||
|
null,
|
||||||
);
|
);
|
||||||
state.setCurrencies(sendCurrency, receiveCurrency);
|
state.setCurrencies(sendCurrency, receiveCurrency);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +74,10 @@ class ExchangeDataLoadingService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<AggregateCurrency?> getAggregateCurrency(
|
Future<AggregateCurrency?> getAggregateCurrency(
|
||||||
String ticker, ExchangeRateType rateType) async {
|
String ticker,
|
||||||
|
ExchangeRateType rateType,
|
||||||
|
String? contract,
|
||||||
|
) async {
|
||||||
final currencies = await ExchangeDataLoadingService.instance.isar.currencies
|
final currencies = await ExchangeDataLoadingService.instance.isar.currencies
|
||||||
.filter()
|
.filter()
|
||||||
.group((q) => rateType == ExchangeRateType.fixed
|
.group((q) => rateType == ExchangeRateType.fixed
|
||||||
|
@ -89,6 +94,8 @@ class ExchangeDataLoadingService {
|
||||||
ticker,
|
ticker,
|
||||||
caseSensitive: false,
|
caseSensitive: false,
|
||||||
)
|
)
|
||||||
|
.and()
|
||||||
|
.tokenContractEqualTo(contract)
|
||||||
.findAll();
|
.findAll();
|
||||||
|
|
||||||
final items = currencies
|
final items = currencies
|
||||||
|
|
Loading…
Reference in a new issue