LCOV - code coverage report
Current view: top level - lib/design/generic - base_list_infinite_widget.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 45 0.0 %
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/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:flutter/material.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.dispose();
      45           0 :     super.dispose();
      46             :   }
      47             : 
      48           0 :   void _loadItems() {
      49           0 :     setState(() => isLoading = true);
      50           0 :     Future.delayed(const Duration(milliseconds: 300), () {
      51           0 :       setState(() {
      52           0 :         isLoading = false;
      53           0 :         _addItems();
      54             :       });
      55             :     });
      56             :   }
      57             : 
      58           0 :   void _addItems() {
      59           0 :     if (widget.stream != null) {
      60           0 :       items.addAll(widget.stream!.chunk(widget.batch));
      61             :     }
      62             :   }
      63             : 
      64           0 :   void _scrollListener() {
      65           0 :     if (scrollController.position.extentAfter < 200 &&
      66           0 :         !isLoading &&
      67           0 :         widget.stream != null &&
      68           0 :         !widget.stream!.isFinished) {
      69           0 :       _loadItems();
      70             :     }
      71             :   }
      72             : 
      73           0 :   void clearState() {
      74           0 :     setState(() {
      75           0 :       scrollController.jumpTo(0);
      76           0 :       items.clear();
      77           0 :       _addItems();
      78             :     });
      79             :   }
      80             : 
      81           0 :   @override
      82             :   Widget build(BuildContext context) {
      83           0 :     if (widget.stream?.isEmpty == true) {
      84             :       return ThemeHelper.emptyBox;
      85             :     }
      86           0 :     if (widget.stream?.isFirst == true) {
      87           0 :       WidgetsBinding.instance.addPostFrameCallback((_) => clearState());
      88             :     }
      89           0 :     return ListView.builder(
      90             :       scrollDirection: Axis.vertical,
      91             :       shrinkWrap: true,
      92           0 :       controller: scrollController,
      93           0 :       itemCount: items.length + 2,
      94           0 :       itemBuilder: (context, index) {
      95           0 :         if (index == 0) {
      96             :           return ThemeHelper.hIndent;
      97           0 :         } else if (index == items.length + 1) {
      98           0 :           if (isLoading) {
      99             :             return const Center(child: CircularProgressIndicator());
     100             :           } else {
     101             :             return ThemeHelper.formEndBox;
     102             :           }
     103             :         } else {
     104           0 :           return KeepAliveWrapper(
     105           0 :             child: BackgroundWrapper(
     106             :               index: index,
     107           0 :               child: widget.buildListWidget(
     108           0 :                 items[index - 1],
     109             :                 context,
     110             :               ),
     111             :             ),
     112             :           );
     113             :         }
     114             :       },
     115             :     );
     116             :   }
     117             : }

Generated by: LCOV version 1.14