91 lines
2.6 KiB
Dart
91 lines
2.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'package:provider/provider.dart';
|
|
|
|
import 'package:pshared/controllers/payment/source.dart';
|
|
import 'package:pshared/models/payment/source.dart';
|
|
import 'package:pshared/provider/payment/amount.dart';
|
|
import 'package:pshared/utils/currency.dart';
|
|
|
|
import 'package:pweb/generated/i18n/app_localizations.dart';
|
|
|
|
class PaymentAmountWidget extends StatefulWidget {
|
|
const PaymentAmountWidget({super.key});
|
|
|
|
@override
|
|
State<PaymentAmountWidget> createState() => _PaymentAmountWidgetState();
|
|
}
|
|
|
|
class _PaymentAmountWidgetState extends State<PaymentAmountWidget> {
|
|
late final TextEditingController _controller;
|
|
bool _isSyncingText = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
final initialAmount = context.read<PaymentAmountProvider>().amount;
|
|
_controller = TextEditingController(text: amountToString(initialAmount));
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_controller.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
double? _parseAmount(String value) =>
|
|
double.tryParse(value.replaceAll(',', '.'));
|
|
|
|
void _syncTextWithAmount(double amount) {
|
|
final parsedText = _parseAmount(_controller.text);
|
|
if (parsedText != null && parsedText == amount) return;
|
|
|
|
final nextText = amountToString(amount);
|
|
_isSyncingText = true;
|
|
_controller.value = TextEditingValue(
|
|
text: nextText,
|
|
selection: TextSelection.collapsed(offset: nextText.length),
|
|
);
|
|
_isSyncingText = false;
|
|
}
|
|
|
|
void _onChanged(String value) {
|
|
if (_isSyncingText) return;
|
|
|
|
final parsed = _parseAmount(value);
|
|
if (parsed != null) {
|
|
context.read<PaymentAmountProvider>().setAmount(parsed);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final amount = context.select<PaymentAmountProvider, double>(
|
|
(provider) => provider.amount,
|
|
);
|
|
final source = context.watch<PaymentSourceController>().selectedSource;
|
|
_syncTextWithAmount(amount);
|
|
final sourceCurrency = switch (source?.type) {
|
|
null => null,
|
|
PaymentSourceType.wallet => currencyCodeToString(
|
|
source!.wallet!.currency,
|
|
),
|
|
PaymentSourceType.ledger =>
|
|
source!.ledgerAccount?.currency.trim().toUpperCase(),
|
|
};
|
|
final amountLabel = sourceCurrency == null || sourceCurrency.isEmpty
|
|
? AppLocalizations.of(context)!.amount
|
|
: '${AppLocalizations.of(context)!.amount} ($sourceCurrency)';
|
|
|
|
return TextField(
|
|
controller: _controller,
|
|
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
|
decoration: InputDecoration(
|
|
labelText: amountLabel,
|
|
border: const OutlineInputBorder(),
|
|
),
|
|
onChanged: _onChanged,
|
|
);
|
|
}
|
|
}
|