mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-06 04:17:42 +00:00
254 lines
10 KiB
Dart
254 lines
10 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:isar/isar.dart';
|
|
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
|
|
import 'package:stackwallet/pages/exchange_view/exchange_form.dart';
|
|
import 'package:stackwallet/pages/exchange_view/trade_details_view.dart';
|
|
import 'package:stackwallet/providers/global/trades_service_provider.dart';
|
|
import 'package:stackwallet/providers/providers.dart';
|
|
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
|
|
import 'package:stackwallet/utilities/constants.dart';
|
|
import 'package:stackwallet/utilities/text_styles.dart';
|
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
|
import 'package:stackwallet/widgets/conditional_parent.dart';
|
|
import 'package:stackwallet/widgets/custom_loading_overlay.dart';
|
|
import 'package:stackwallet/widgets/trade_card.dart';
|
|
import 'package:tuple/tuple.dart';
|
|
|
|
import '../../db/main_db.dart';
|
|
|
|
class ExchangeView extends ConsumerStatefulWidget {
|
|
const ExchangeView({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
ConsumerState<ExchangeView> createState() => _ExchangeViewState();
|
|
}
|
|
|
|
class _ExchangeViewState extends ConsumerState<ExchangeView> {
|
|
bool _initialCachePopulationUnderway = false;
|
|
|
|
@override
|
|
void initState() {
|
|
if (!ref.read(prefsChangeNotifierProvider).externalCalls) {
|
|
if (ExchangeDataLoadingService.currentCacheVersion <
|
|
ExchangeDataLoadingService.cacheVersion) {
|
|
_initialCachePopulationUnderway = true;
|
|
ExchangeDataLoadingService.instance.onLoadingComplete = () {
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
|
await ExchangeDataLoadingService.instance.setCurrenciesIfEmpty(
|
|
ref.read(exchangeFormStateProvider),
|
|
);
|
|
setState(() {
|
|
_initialCachePopulationUnderway = false;
|
|
});
|
|
});
|
|
};
|
|
}
|
|
ExchangeDataLoadingService.instance
|
|
.init()
|
|
.then((_) => ExchangeDataLoadingService.instance.loadAll());
|
|
} else if (ExchangeDataLoadingService.instance.isLoading &&
|
|
ExchangeDataLoadingService.currentCacheVersion <
|
|
ExchangeDataLoadingService.cacheVersion) {
|
|
_initialCachePopulationUnderway = true;
|
|
ExchangeDataLoadingService.instance.onLoadingComplete = () {
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
|
await ExchangeDataLoadingService.instance.setCurrenciesIfEmpty(
|
|
ref.read(exchangeFormStateProvider),
|
|
);
|
|
setState(() {
|
|
_initialCachePopulationUnderway = false;
|
|
});
|
|
});
|
|
};
|
|
}
|
|
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
debugPrint("BUILD: $runtimeType");
|
|
|
|
return ConditionalParent(
|
|
condition: _initialCachePopulationUnderway,
|
|
builder: (child) {
|
|
return Stack(
|
|
children: [
|
|
child,
|
|
Material(
|
|
color: Theme.of(context)
|
|
.extension<StackColors>()!
|
|
.overlay
|
|
.withOpacity(0.6),
|
|
child: const CustomLoadingOverlay(
|
|
message: "Updating exchange data",
|
|
subMessage: "This could take a few minutes",
|
|
eventBus: null,
|
|
),
|
|
)
|
|
],
|
|
);
|
|
},
|
|
child: SafeArea(
|
|
child: NestedScrollView(
|
|
floatHeaderSlivers: true,
|
|
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
|
return [
|
|
SliverOverlapAbsorber(
|
|
handle:
|
|
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
|
sliver: const SliverToBoxAdapter(
|
|
child: Padding(
|
|
padding: EdgeInsets.only(
|
|
left: 16,
|
|
right: 16,
|
|
top: 16,
|
|
),
|
|
child: ExchangeForm(),
|
|
),
|
|
),
|
|
)
|
|
];
|
|
},
|
|
body: Builder(
|
|
builder: (buildContext) {
|
|
final trades = ref
|
|
.watch(tradesServiceProvider.select((value) => value.trades));
|
|
final tradeCount = trades.length;
|
|
final hasHistory = tradeCount > 0;
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
child: CustomScrollView(
|
|
slivers: [
|
|
SliverOverlapInjector(
|
|
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
|
|
buildContext,
|
|
),
|
|
),
|
|
SliverToBoxAdapter(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
const SizedBox(
|
|
height: 12,
|
|
),
|
|
Text(
|
|
"Trades",
|
|
style: STextStyles.itemSubtitle(context).copyWith(
|
|
color: Theme.of(context)
|
|
.extension<StackColors>()!
|
|
.textDark3,
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 12,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
if (hasHistory)
|
|
SliverList(
|
|
delegate: SliverChildBuilderDelegate((context, index) {
|
|
return Padding(
|
|
padding: const EdgeInsets.all(4),
|
|
child: TradeCard(
|
|
key: Key("tradeCard_${trades[index].uuid}"),
|
|
trade: trades[index],
|
|
onTap: () async {
|
|
final String tradeId = trades[index].tradeId;
|
|
|
|
final lookup = ref
|
|
.read(tradeSentFromStackLookupProvider)
|
|
.all;
|
|
|
|
//todo: check if print needed
|
|
// debugPrint("ALL: $lookup");
|
|
|
|
final String? txid = ref
|
|
.read(tradeSentFromStackLookupProvider)
|
|
.getTxidForTradeId(tradeId);
|
|
final List<String>? walletIds = ref
|
|
.read(tradeSentFromStackLookupProvider)
|
|
.getWalletIdsForTradeId(tradeId);
|
|
|
|
if (txid != null &&
|
|
walletIds != null &&
|
|
walletIds.isNotEmpty) {
|
|
final manager = ref
|
|
.read(walletsChangeNotifierProvider)
|
|
.getManager(walletIds.first);
|
|
|
|
//todo: check if print needed
|
|
// debugPrint("name: ${manager.walletName}");
|
|
|
|
final tx = await MainDB.instance
|
|
.getTransactions(walletIds.first)
|
|
.filter()
|
|
.txidEqualTo(txid)
|
|
.findFirst();
|
|
|
|
if (mounted) {
|
|
unawaited(Navigator.of(context).pushNamed(
|
|
TradeDetailsView.routeName,
|
|
arguments: Tuple4(tradeId, tx,
|
|
walletIds.first, manager.walletName),
|
|
));
|
|
}
|
|
} else {
|
|
unawaited(Navigator.of(context).pushNamed(
|
|
TradeDetailsView.routeName,
|
|
arguments: Tuple4(
|
|
tradeId, null, walletIds?.first, null),
|
|
));
|
|
}
|
|
},
|
|
),
|
|
);
|
|
}, childCount: tradeCount),
|
|
),
|
|
if (!hasHistory)
|
|
SliverToBoxAdapter(
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context)
|
|
.extension<StackColors>()!
|
|
.popupBG,
|
|
borderRadius: BorderRadius.circular(
|
|
Constants.size.circularBorderRadius,
|
|
),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(12),
|
|
child: Text(
|
|
"Trades will appear here",
|
|
textAlign: TextAlign.center,
|
|
style: STextStyles.itemSubtitle(context),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|