75 lines
2.0 KiB
Dart
75 lines
2.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'package:provider/provider.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);
|
|
_syncTextWithAmount(amount);
|
|
|
|
return TextField(
|
|
controller: _controller,
|
|
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
|
decoration: InputDecoration(
|
|
labelText: AppLocalizations.of(context)!.amount,
|
|
border: const OutlineInputBorder(),
|
|
),
|
|
onChanged: _onChanged,
|
|
);
|
|
}
|
|
}
|