LCOV - code coverage report
Current view: top level - lib/pages/currency - currency_page.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 69 80 86.2 %
Date: 2024-10-04 11:12:13 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/focus_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/_classes/storage/history_data.dart';
       8             : import 'package:app_finance/_classes/structure/currency_app_data.dart';
       9             : import 'package:app_finance/_classes/storage/app_data.dart';
      10             : import 'package:app_finance/_classes/structure/navigation/app_route.dart';
      11             : import 'package:app_finance/_configs/screen_helper.dart';
      12             : import 'package:app_finance/_configs/theme_helper.dart';
      13             : import 'package:app_finance/_ext/build_context_ext.dart';
      14             : import 'package:app_finance/charts/trade_chart.dart';
      15             : import 'package:app_finance/design/button/toolbar_button_widget.dart';
      16             : import 'package:app_finance/design/wrapper/single_scroll_wrapper.dart';
      17             : import 'package:app_finance/pages/_interfaces/abstract_page_state.dart';
      18             : import 'package:app_finance/design/generic/notification_bar.dart';
      19             : import 'package:app_finance/design/form/simple_input.dart';
      20             : import 'package:app_finance/design/wrapper/row_widget.dart';
      21             : import 'package:flutter/material.dart';
      22             : 
      23             : class CurrencyPage extends StatefulWidget {
      24           1 :   const CurrencyPage({super.key});
      25             : 
      26           1 :   @override
      27           1 :   CurrencyPageState createState() => CurrencyPageState();
      28             : }
      29             : 
      30             : class CurrencyPageState extends AbstractPageState<CurrencyPage> {
      31             :   late FocusController focus;
      32             :   List<dynamic>? scope;
      33             : 
      34           1 :   @override
      35             :   void initState() {
      36           2 :     focus = FocusController();
      37           1 :     super.initState();
      38             :   }
      39             : 
      40           1 :   @override
      41             :   void dispose() {
      42           2 :     focus.dispose();
      43           1 :     super.dispose();
      44             :   }
      45             : 
      46           1 :   @override
      47           2 :   String getTitle() => AppLocale.labels.currencyHeadline;
      48             : 
      49           1 :   @override
      50           2 :   String getButtonName() => AppLocale.labels.currencyUpdateTooltip;
      51             : 
      52           1 :   @override
      53             :   Widget buildButton(BuildContext context, BoxConstraints constraints) {
      54           1 :     return FloatingActionButton(
      55             :       heroTag: 'currency_page',
      56           0 :       onPressed: () => updateAllRates(context),
      57           1 :       tooltip: getButtonName(),
      58             :       child: const Icon(Icons.save),
      59             :     );
      60             :   }
      61             : 
      62           1 :   @override
      63             :   List<Widget> getBarActions(NavigatorState nav) {
      64           1 :     return [
      65           1 :       ToolbarButtonWidget(
      66           1 :         isWide: ScreenHelper.state().isWide,
      67           2 :         tooltip: AppLocale.labels.currencyAddTooltip,
      68           0 :         onPressed: () => nav.pushNamed(AppRoute.currencyAddRoute),
      69             :         icon: Icons.add,
      70             :         color: Colors.white70,
      71           2 :         semanticLabel: AppLocale.labels.currencyAddTooltip,
      72             :       ),
      73           1 :       ...super.getBarActions(nav)
      74             :     ];
      75             :   }
      76             : 
      77           1 :   List<CurrencyAppData>? _getItems() {
      78           1 :     List<CurrencyAppData>? tmp = state
      79           1 :         .getList(AppDataType.currencies)
      80           2 :         .where((v) =>
      81           9 :             v.currencyFrom != null && v.currency != null && v.currency.code != v.currencyFrom.code && v.details != 1.0)
      82           1 :         .toList()
      83           1 :         .cast();
      84           5 :     tmp.sort((a, b) => a.uuid.compareTo(b.uuid));
      85             :     return tmp;
      86             :   }
      87             : 
      88           0 :   void updateAllRates(BuildContext context) {
      89           0 :     for (CurrencyAppData rate in scope!) {
      90           0 :       if ((state.getByUuid(rate.uuid) as CurrencyAppData).details != rate.details) {
      91           0 :         state.update(rate.uuid, rate);
      92             :       }
      93             :     }
      94           0 :     NotificationBar.showSnackBar(context, AppLocale.labels.saveNotification);
      95             :   }
      96             : 
      97           0 :   void changeRate(CurrencyAppData initial, double? value) {
      98             :     if (value != null) {
      99           0 :       initial.details = value;
     100             :     }
     101             :   }
     102             : 
     103           1 :   @override
     104             :   Widget buildContent(BuildContext context, BoxConstraints constraints) {
     105           1 :     final tmp = _getItems();
     106           4 :     if (tmp?.length != scope?.length) {
     107           6 :       WidgetsBinding.instance.addPostFrameCallback((_) => setState(() => scope = tmp));
     108             :       return ThemeHelper.emptyBox;
     109             :     }
     110           1 :     final TextTheme textTheme = context.textTheme;
     111           1 :     final indent = ThemeHelper.getIndent();
     112           1 :     final now = DateTime.now();
     113           4 :     final cutDate = DateTime(now.year, now.month - 2);
     114           1 :     final crossAxisCount = ThemeHelper.getWidthCount(null, context);
     115           1 :     return SingleScrollWrapper(
     116           1 :       controller: focus,
     117           1 :       child: Padding(
     118           1 :         padding: EdgeInsets.all(indent),
     119           1 :         child: Wrap(
     120             :           spacing: indent,
     121           1 :           runSpacing: indent * 2,
     122           3 :           children: scope!.map((item) {
     123           6 :             final history = HistoryData.getStream(item.uuid, filter: (e) => e.timestamp.isBefore(cutDate))?.toList();
     124           1 :             return RowWidget(
     125             :               indent: indent,
     126           2 :               maxWidth: ThemeHelper.getWidth(context, 4, constraints) / crossAxisCount,
     127             :               chunk: const [85, null, 100],
     128           1 :               children: [
     129           1 :                 [
     130           1 :                   Column(
     131           1 :                     crossAxisAlignment: AppDesign.getAlignment(),
     132           1 :                     children: [
     133           1 :                       Text(
     134           1 :                         item.uuid,
     135           1 :                         style: textTheme.headlineMedium,
     136             :                         overflow: TextOverflow.ellipsis,
     137             :                       ),
     138           1 :                       Text(
     139           1 :                         item.updatedAtFormatted,
     140           1 :                         style: textTheme.bodySmall,
     141             :                         overflow: TextOverflow.ellipsis,
     142             :                       ),
     143             :                     ],
     144             :                   ),
     145             :                 ],
     146           1 :                 [
     147           1 :                   SimpleInput(
     148           3 :                     controller: TextEditingController(text: item.details.toString()),
     149             :                     type: TextInputType.number,
     150           0 :                     setState: (value) => changeRate(item, double.tryParse(value)),
     151             :                   )
     152             :                 ],
     153           1 :                 [
     154           1 :                   Padding(
     155           1 :                     padding: EdgeInsets.only(top: indent),
     156           1 :                     child: TradeChart(
     157           0 :                       data: history ?? [],
     158             :                       width: 100,
     159             :                       height: 40,
     160             :                     ),
     161             :                   ),
     162             :                 ],
     163             :               ],
     164             :             );
     165           1 :           }).toList(),
     166             :         ),
     167             :       ),
     168             :     );
     169             :   }
     170             : }

Generated by: LCOV version 1.14