import 'dart:async'; import 'package:flutter/material.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:satu/core/models/inventarization/response/inventarization_response.dart'; import 'package:satu/core/models/stock/stock_response.dart'; import 'package:satu/core/services/dialog_service.dart'; import 'package:satu/core/services/stocks_service.dart'; import 'package:satu/views/inventarization/widget/good_inventarization_list_item.dart'; import 'package:satu/views/stocks/widget/stock_tile.dart'; import '../../../core/entity/goods_entity.dart'; import '../../../core/models/inventarization/good_item/good_item.dart'; import '../../../core/services/dictionary_service.dart'; import '../../../core/services/inventarization_service.dart'; import '../../../core/services/navigator_service.dart'; import '../../../core/utils/locator.dart'; import '../../../routes/route_names.dart'; import '../../../shared/app_colors.dart'; import '../../../shared/shared_styles.dart'; import '../../../shared/ui_helpers.dart'; import '../../../widgets/bar/products_app_bar.dart'; import '../../widgets/fields/input_field.dart'; class StocksView extends StatefulWidget { const StocksView({ Key? key, }) : super(key: key); @override State createState() => _StocksViewState(); } class _StocksViewState extends State { final StockService _service = locator(); late TextEditingController _searchTextController; final FocusNode _searchFocusNode = FocusNode(); String query = ''; Timer? _debounce; static const _pageSize = 20; bool _isLastPage = false; final PagingController _pagingController = PagingController(firstPageKey: 1); @override void initState() { _searchTextController = TextEditingController(); _searchTextController.addListener(() { setState(() { query = _searchTextController.text; }); if (_debounce?.isActive ?? false) _debounce?.cancel(); _debounce = Timer(const Duration(milliseconds: 500), () { _pagingController.refresh(); }); }); _pagingController.addPageRequestListener((pageKey) { _fetchData(pageKey, _pageSize, query); }); super.initState(); } @override void dispose() { ; _debounce?.cancel(); _pagingController.dispose(); _searchTextController.dispose(); _searchFocusNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: const ProductsAppBar( title: 'Остатки', drawerShow: true, ), body: Column( children: [ InputField( placeholder: 'Поиск по наименованию товара или штрих-код', search: true, controller: _searchTextController, fieldFocusNode: _searchFocusNode, ), verticalSpaceSmall, Padding( padding: const EdgeInsets.symmetric(horizontal: 15.0), child: SizedBox( width: double.infinity, child: Row( children: [ Expanded( flex: 4, child: Text( 'Список товара', style: textGray11Style, ), ), Expanded( flex: 2, child: Text( 'Количество', style: textGray11Style, ), ), Expanded( flex: 1, child: Text( 'Сумма', style: textGray11Style, ), ), ], ), ), ), verticalSpaceSmall, Expanded( child: PagedListView.separated( //physics: const BouncingScrollPhysics(), separatorBuilder: (BuildContext context, int index) { return const Divider( height: 1.0, color: disableColor, ); }, pagingController: _pagingController, builderDelegate: PagedChildBuilderDelegate( noItemsFoundIndicatorBuilder: (BuildContext context) { return const Center( child: Text( 'В данном списке нет товаров', style: textGray11Style, ), ); }, itemBuilder: (BuildContext context, StockResponse item, int index) { return StockTile( key: Key( 'good_stock_${item.eaccGoodId}', ), name: item.name, categoryName: item.katName, count: item.cnt, price: item.price, ean: item.ean13, ); }, ), ), ), ], ), ); } Future _fetchData(int pageKey, int perPage, String? query) async { final List newItems = await _service.getList( page: pageKey, perpage: perPage, query: query, ); _isLastPage = newItems.length < _pageSize; if (_isLastPage) { _pagingController.appendLastPage(newItems); } else { final nextPageKey = pageKey + 1; _pagingController.appendPage(newItems, nextPageKey); } } }