LCOV - code coverage report
Current view: top level - lib/design/generic - base_list_infinite_widget.dart Coverage Total Hit
Test: lcov.info Lines: 0.0 % 49 0
Test Date: 2026-11-14 15:04:37 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/iterator_controller.dart';
       5              : import 'package:app_finance/_configs/theme_helper.dart';
       6              : import 'package:app_finance/design/wrapper/background_wrapper.dart';
       7              : import 'package:app_finance/design/wrapper/keep_alive_wrapper.dart';
       8              : import 'package:material_ui/material_ui.dart';
       9              : 
      10              : typedef FnListWidget = Widget Function(dynamic item, BuildContext context);
      11              : 
      12              : class BaseListInfiniteWidget extends StatefulWidget {
      13              :   final InterfaceIterator? stream;
      14              :   final int batch;
      15              :   final double width;
      16              :   final FnListWidget buildListWidget;
      17              : 
      18            0 :   const BaseListInfiniteWidget({
      19              :     super.key,
      20              :     required this.stream,
      21              :     required this.width,
      22              :     required this.buildListWidget,
      23              :     this.batch = 25,
      24              :   });
      25              : 
      26            0 :   @override
      27            0 :   BaseListInfiniteWidgetState createState() => BaseListInfiniteWidgetState();
      28              : }
      29              : 
      30              : class BaseListInfiniteWidgetState extends State<BaseListInfiniteWidget> {
      31              :   final ScrollController scrollController = ScrollController();
      32              :   bool isLoading = false;
      33              :   List<dynamic> items = [];
      34              : 
      35            0 :   @override
      36              :   void initState() {
      37            0 :     super.initState();
      38            0 :     _loadItems();
      39            0 :     scrollController.addListener(_scrollListener);
      40              :   }
      41              : 
      42            0 :   @override
      43              :   void dispose() {
      44            0 :     scrollController.removeListener(_scrollListener);
      45            0 :     scrollController.dispose();
      46            0 :     super.dispose();
      47              :   }
      48              : 
      49            0 :   void _loadItems() {
      50            0 :     if (!mounted) {
      51              :       return;
      52              :     }
      53            0 :     setState(() => isLoading = true);
      54            0 :     Future.delayed(const Duration(milliseconds: 300), () {
      55            0 :       if (!mounted) {
      56              :         return;
      57              :       }
      58            0 :       setState(() {
      59            0 :         isLoading = false;
      60            0 :         _addItems();
      61              :       });
      62              :     });
      63              :   }
      64              : 
      65            0 :   void _addItems() {
      66            0 :     if (widget.stream != null) {
      67            0 :       items.addAll(widget.stream!.chunk(widget.batch));
      68              :     }
      69              :   }
      70              : 
      71            0 :   void _scrollListener() {
      72            0 :     if (scrollController.position.extentAfter < 200 &&
      73            0 :         !isLoading &&
      74            0 :         widget.stream != null &&
      75            0 :         !widget.stream!.isFinished) {
      76            0 :       _loadItems();
      77              :     }
      78              :   }
      79              : 
      80            0 :   void clearState() {
      81            0 :     if (!mounted) {
      82              :       return;
      83              :     }
      84            0 :     if (scrollController.hasClients) {
      85            0 :       scrollController.jumpTo(0);
      86            0 :       items.clear();
      87            0 :       setState(_addItems);
      88              :     }
      89              :   }
      90              : 
      91            0 :   @override
      92              :   Widget build(BuildContext context) {
      93            0 :     if (widget.stream?.isEmpty == true) {
      94              :       return ThemeHelper.emptyBox;
      95              :     }
      96            0 :     if (widget.stream?.isFirst == true) {
      97            0 :       WidgetsBinding.instance.addPostFrameCallback((_) => clearState());
      98              :     }
      99            0 :     return ListView.builder(
     100              :       scrollDirection: Axis.vertical,
     101              :       shrinkWrap: true,
     102            0 :       controller: scrollController,
     103            0 :       itemCount: items.length + 2,
     104            0 :       itemBuilder: (context, index) {
     105            0 :         if (index == 0) {
     106              :           return ThemeHelper.hIndent;
     107            0 :         } else if (index == items.length + 1) {
     108            0 :           if (isLoading) {
     109              :             return const Center(child: CircularProgressIndicator());
     110              :           } else {
     111              :             return ThemeHelper.formEndBox;
     112              :           }
     113              :         } else {
     114            0 :           return KeepAliveWrapper(
     115            0 :             child: BackgroundWrapper(
     116              :               index: index,
     117            0 :               child: widget.buildListWidget(
     118            0 :                 items[index - 1],
     119              :                 context,
     120              :               ),
     121              :             ),
     122              :           );
     123              :         }
     124              :       },
     125              :     );
     126              :   }
     127              : }
        

Generated by: LCOV version 2.0-1