LCOV - code coverage report
Current view: top level - lib/design/form - currency_exchange_input.dart Coverage Total Hit
Test: lcov.info Lines: 98.0 % 50 49
Test Date: 2026-11-14 15:08:11 Functions: - 0 0

            Line data    Source code
       1              : // Copyright 2023 The terCAD team. All rights reserved.
       2              : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
       3              : 
       4              : import 'package:app_finance/_classes/controller/exchange_controller.dart';
       5              : import 'package:app_finance/_classes/herald/app_design.dart';
       6              : import 'package:app_finance/_classes/herald/app_locale.dart';
       7              : import 'package:app_finance/_configs/theme_helper.dart';
       8              : import 'package:app_finance/_ext/build_context_ext.dart';
       9              : import 'package:app_finance/design/form/simple_input.dart';
      10              : import 'package:app_finance/design/wrapper/input_wrapper.dart';
      11              : import 'package:app_finance/design/wrapper/row_widget.dart';
      12              : import 'package:material_ui/material_ui.dart';
      13              : import 'package:flutter_currency_picker/flutter_currency_picker.dart';
      14              : 
      15              : class CurrencyExchangeInput extends StatefulWidget {
      16              :   final Currency? target;
      17              :   final List<Currency?> source;
      18              :   final double width;
      19              :   final double indent;
      20              :   final ExchangeController controller;
      21              : 
      22            1 :   const CurrencyExchangeInput({
      23              :     super.key,
      24              :     required this.width,
      25              :     required this.indent,
      26              :     required this.target,
      27              :     required this.controller,
      28              :     required this.source,
      29              :   });
      30              : 
      31            1 :   @override
      32            1 :   CurrencyExchangeInputState createState() => CurrencyExchangeInputState();
      33              : }
      34              : 
      35              : class CurrencyExchangeInputState extends State<CurrencyExchangeInput> {
      36              :   Currency? target;
      37              :   List<Currency?> source = [];
      38              : 
      39            1 :   @override
      40              :   initState() {
      41            1 :     _update();
      42            1 :     super.initState();
      43              :   }
      44              : 
      45            1 :   void _update() {
      46            3 :     target = widget.target;
      47            3 :     source = widget.source;
      48            5 :     widget.controller.restate(source, target);
      49              :   }
      50              : 
      51            4 :   String _convert(List<Currency?> val) => val.map((e) => e?.code ?? '-').join('');
      52              : 
      53            1 :   @override
      54              :   Widget build(BuildContext context) {
      55           10 :     if (target?.code != widget.target?.code || _convert(source) != _convert(widget.source)) {
      56            0 :       WidgetsBinding.instance.addPostFrameCallback((_) => setState(_update));
      57              :       return ThemeHelper.emptyBox;
      58              :     }
      59            7 :     if (target == null || source.isEmpty || source.where((v) => v != null).isEmpty) {
      60              :       return ThemeHelper.emptyBox;
      61              :     }
      62            1 :     final TextTheme textTheme = context.textTheme;
      63            1 :     return Column(
      64            5 :       children: List<Widget>.generate(widget.controller.length, (index) {
      65            3 :         final scope = widget.controller.get(index);
      66            1 :         return Column(
      67            1 :           mainAxisAlignment: AppDesign.getAlignment<MainAxisAlignment>(),
      68            1 :           children: [
      69            1 :             Container(
      70            2 :               width: widget.width,
      71            1 :               decoration: BoxDecoration(
      72            4 :                 border: Border.all(color: context.colorScheme.inversePrimary.withValues(alpha: 0.6)),
      73              :               ),
      74            1 :               child: Column(
      75            1 :                 mainAxisAlignment: AppDesign.getAlignment<MainAxisAlignment>(),
      76            1 :                 children: [
      77            3 :                   Text(AppLocale.labels.currencyExchange(scope.from, scope.to),
      78            2 :                       style: textTheme.bodyLarge?.copyWith(
      79            2 :                         color: context.colorScheme.primary,
      80              :                       )),
      81            1 :                   Padding(
      82            5 :                     padding: EdgeInsets.fromLTRB(widget.indent, 0, widget.indent, 0),
      83            2 :                     child: LayoutBuilder(builder: (context, constraints) {
      84            1 :                       return RowWidget(
      85            2 :                         indent: widget.indent,
      86            1 :                         maxWidth: constraints.maxWidth,
      87              :                         chunk: const [0.5, null],
      88            1 :                         children: [
      89            1 :                           [
      90            1 :                             InputWrapper.text(
      91            2 :                               title: AppLocale.labels.conversion,
      92              :                               controller: scope.rate,
      93            3 :                               tooltip: '${scope.to} ${AppLocale.labels.conversion}',
      94              :                               inputType: const TextInputType.numberWithOptions(decimal: true),
      95            2 :                               formatter: [SimpleInputFormatter.filterDouble],
      96              :                             ),
      97              :                           ],
      98            1 :                           [
      99            1 :                             InputWrapper.text(
     100            2 :                               title: AppLocale.labels.conversionMessage(scope.to),
     101              :                               controller: scope.sum,
     102            3 :                               tooltip: '${scope.from} ${AppLocale.labels.conversionMessage(scope.to)}',
     103              :                               inputType: const TextInputType.numberWithOptions(decimal: true),
     104            2 :                               formatter: [SimpleInputFormatter.filterDouble],
     105              :                             ),
     106              :                           ],
     107              :                         ],
     108              :                       );
     109              :                     }),
     110              :                   ),
     111              :                 ],
     112              :               ),
     113              :             ),
     114            3 :             SizedBox(height: widget.indent),
     115              :           ],
     116              :         );
     117              :       }),
     118              :     );
     119              :   }
     120              : }
        

Generated by: LCOV version 2.0-1