stack_wallet/lib/widgets/node_options_sheet.dart
2024-11-26 09:18:35 -06:00

319 lines
12 KiB
Dart

/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:tuple/tuple.dart';
import '../pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart';
import '../pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart';
import '../providers/global/active_wallet_provider.dart';
import '../providers/global/secure_store_provider.dart';
import '../providers/providers.dart';
import '../themes/stack_colors.dart';
import '../utilities/assets.dart';
import '../utilities/constants.dart';
import '../utilities/default_nodes.dart';
import '../utilities/enums/sync_type_enum.dart';
import '../utilities/test_node_connection.dart';
import '../utilities/text_styles.dart';
import '../utilities/tor_plain_net_option_enum.dart';
import '../wallets/crypto_currency/crypto_currency.dart';
import 'rounded_white_container.dart';
class NodeOptionsSheet extends ConsumerWidget {
const NodeOptionsSheet({
super.key,
required this.nodeId,
required this.coin,
required this.popBackToRoute,
});
final String nodeId;
final CryptoCurrency coin;
final String popBackToRoute;
Future<void> _notifyWalletsOfUpdatedNode(WidgetRef ref) async {
final wallets =
ref.read(pWallets).wallets.where((e) => e.info.coin == coin);
final prefs = ref.read(prefsChangeNotifierProvider);
switch (prefs.syncType) {
case SyncingType.currentWalletOnly:
for (final wallet in wallets) {
if (ref.read(currentWalletIdProvider) == wallet.walletId) {
unawaited(wallet.updateNode().then((value) => wallet.refresh()));
} else {
unawaited(wallet.updateNode());
}
}
break;
case SyncingType.selectedWalletsAtStartup:
final List<String> walletIdsToSync = prefs.walletIdsSyncOnStartup;
for (final wallet in wallets) {
if (walletIdsToSync.contains(wallet.walletId)) {
unawaited(wallet.updateNode().then((value) => wallet.refresh()));
} else {
unawaited(wallet.updateNode());
}
}
break;
case SyncingType.allWalletsOnStartup:
for (final wallet in wallets) {
unawaited(wallet.updateNode().then((value) => wallet.refresh()));
}
break;
}
}
@override
Widget build(BuildContext context, WidgetRef ref) {
final maxHeight = MediaQuery.of(context).size.height * 0.60;
final node = ref.watch(
nodeServiceChangeNotifierProvider
.select((value) => value.getNodeById(id: nodeId)),
)!;
final status = ref
.watch(
nodeServiceChangeNotifierProvider.select(
(value) => value.getPrimaryNodeFor(currency: coin),
),
)
?.id !=
nodeId
? "Disconnected"
: "Connected";
return Container(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: const BorderRadius.vertical(
top: Radius.circular(20),
),
),
child: LimitedBox(
maxHeight: maxHeight,
child: Padding(
padding: const EdgeInsets.only(
left: 24,
right: 24,
top: 10,
bottom: 0,
),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Container(
decoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
width: 60,
height: 4,
),
),
const SizedBox(
height: 36,
),
Text(
"Node options",
style: STextStyles.pageTitleH2(context),
textAlign: TextAlign.left,
),
RoundedWhiteContainer(
padding: const EdgeInsets.symmetric(vertical: 38),
child: Row(
children: [
Container(
width: 32,
height: 32,
decoration: BoxDecoration(
color: node.id
.startsWith(DefaultNodes.defaultNodeIdPrefix)
? Theme.of(context)
.extension<StackColors>()!
.textSubtitle4
: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons
.withOpacity(0.2),
borderRadius: BorderRadius.circular(100),
),
child: Center(
child: SvgPicture.asset(
Assets.svg.node,
height: 15,
width: 19,
color: node.id.startsWith(
DefaultNodes.defaultNodeIdPrefix,
)
? Theme.of(context)
.extension<StackColors>()!
.accentColorDark
: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
),
),
),
const SizedBox(
width: 12,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
node.name,
style: STextStyles.titleBold12(context),
),
const SizedBox(
height: 2,
),
Text(
status,
style: STextStyles.label(context),
),
],
),
const Spacer(),
SvgPicture.asset(
Assets.svg.network,
color: status == "Connected"
? Theme.of(context)
.extension<StackColors>()!
.accentColorGreen
: Theme.of(context)
.extension<StackColors>()!
.buttonBackSecondary,
width: 18,
),
],
),
),
Row(
children: [
// if (!node.id.startsWith("default"))
Expanded(
child: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonStyle(context),
onPressed: () {
Navigator.pop(context);
Navigator.of(context).pushNamed(
NodeDetailsView.routeName,
arguments: Tuple3(
coin,
node.id,
popBackToRoute,
),
);
},
child: Text(
"Details",
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
),
),
),
),
// if (!node.id.startsWith("default"))
const SizedBox(
width: 12,
),
Expanded(
child: TextButton(
style: status == "Connected"
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonStyle(context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonStyle(context),
onPressed: status == "Connected"
? null
: () async {
final pw = await node.getPassword(
ref.read(secureStoreProvider),
);
if (context.mounted) {
final TorPlainNetworkOption netOption;
if (node.torEnabled &&
!node.clearnetEnabled) {
netOption = TorPlainNetworkOption.tor;
} else if (node.clearnetEnabled &&
!node.torEnabled) {
netOption = TorPlainNetworkOption.clear;
} else {
netOption = TorPlainNetworkOption.both;
}
final canConnect = await testNodeConnection(
context: context,
nodeFormData: NodeFormData()
..name = node.name
..host = node.host
..login = node.loginName
..password = pw
..port = node.port
..useSSL = node.useSSL
..isFailover = node.isFailover
..netOption = netOption
..trusted = node.trusted,
cryptoCurrency: coin,
ref: ref,
);
if (!canConnect) {
return;
}
await ref
.read(nodeServiceChangeNotifierProvider)
.setPrimaryNodeFor(
coin: coin,
node: node,
shouldNotifyListeners: true,
);
await _notifyWalletsOfUpdatedNode(ref);
}
},
child: Text(
// status == "Connected" ? "Disconnect" : "Connect",
"Connect",
style: STextStyles.button(context),
),
),
),
],
),
const SizedBox(
height: 24,
),
],
),
),
),
),
);
}
}