129 lines
3.9 KiB
Dart
129 lines
3.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'package:sxchnge_wallet/sxchnge_wallet.dart';
|
|
|
|
import '../generated/i18n/app_localizations.dart';
|
|
|
|
class CryptoFields extends StatefulWidget {
|
|
const CryptoFields({
|
|
super.key,
|
|
required this.capabilities,
|
|
required this.onChanged,
|
|
this.initial,
|
|
this.errorField,
|
|
});
|
|
final DestinationCapabilities capabilities;
|
|
final ValueChanged<DestinationDetails?> onChanged;
|
|
final CryptoDestination? initial;
|
|
final String? errorField;
|
|
@override
|
|
State<CryptoFields> createState() => _CryptoFieldsState();
|
|
}
|
|
|
|
class _CryptoFieldsState extends State<CryptoFields> {
|
|
late final address = TextEditingController(text: widget.initial?.address);
|
|
late final memo = TextEditingController(text: widget.initial?.memo);
|
|
late String? assetId = widget.initial?.assetId;
|
|
late String? networkId = widget.initial?.networkId;
|
|
void changed() {
|
|
final a = widget.capabilities.assets
|
|
.where((a) => a.id == assetId && a.networkId == networkId)
|
|
.firstOrNull;
|
|
widget.onChanged(
|
|
a == null
|
|
? null
|
|
: CryptoDestination(
|
|
assetId: a.id,
|
|
networkId: a.networkId,
|
|
address: address.text,
|
|
memo: memo.text,
|
|
assetLabel: a.label,
|
|
networkLabel: a.networkLabel,
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
address.dispose();
|
|
memo.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final l = AppLocalizations.of(context)!;
|
|
final assets = widget.capabilities.assets;
|
|
final selected = assets
|
|
.where((a) => a.id == assetId && a.networkId == networkId)
|
|
.firstOrNull;
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
DropdownButtonFormField<String>(
|
|
key: ValueKey('asset-$assetId'),
|
|
initialValue: assets.any((a) => a.id == assetId) ? assetId : null,
|
|
isExpanded: true,
|
|
decoration: InputDecoration(labelText: l.dAsset),
|
|
items: [
|
|
for (final a in assets)
|
|
DropdownMenuItem(value: a.id, child: Text(a.label)),
|
|
],
|
|
onChanged: (v) {
|
|
setState(() {
|
|
assetId = v;
|
|
networkId = null;
|
|
memo.clear();
|
|
});
|
|
changed();
|
|
},
|
|
),
|
|
const SizedBox(height: 16),
|
|
DropdownButtonFormField<String>(
|
|
key: ValueKey('network-$assetId-$networkId'),
|
|
initialValue:
|
|
assets.any((a) => a.id == assetId && a.networkId == networkId)
|
|
? networkId
|
|
: null,
|
|
isExpanded: true,
|
|
decoration: InputDecoration(labelText: l.dNetwork),
|
|
items: [
|
|
for (final a in assets.where((a) => a.id == assetId))
|
|
DropdownMenuItem(value: a.networkId, child: Text(a.networkLabel)),
|
|
],
|
|
onChanged: (v) {
|
|
setState(() => networkId = v);
|
|
changed();
|
|
},
|
|
),
|
|
const SizedBox(height: 16),
|
|
TextField(
|
|
key: const ValueKey('destination-address'),
|
|
controller: address,
|
|
autocorrect: false,
|
|
enableSuggestions: false,
|
|
decoration: InputDecoration(
|
|
labelText: l.dAddress,
|
|
errorText: widget.errorField == 'address' ? l.dInvalid : null,
|
|
),
|
|
onChanged: (_) => changed(),
|
|
),
|
|
if (selected?.memoSupported == true) ...[
|
|
const SizedBox(height: 16),
|
|
TextField(
|
|
key: const ValueKey('destination-memo'),
|
|
controller: memo,
|
|
decoration: InputDecoration(
|
|
labelText: l.dMemo,
|
|
errorText: widget.errorField == 'memo' ? l.dInvalid : null,
|
|
),
|
|
onChanged: (_) => changed(),
|
|
),
|
|
],
|
|
const SizedBox(height: 12),
|
|
Text(l.dCryptoHelp),
|
|
],
|
|
);
|
|
}
|
|
}
|