import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:remever/common/resources.dart'; import 'package:remever/common/widgets/typography.dart'; import 'package:remever/components/extensions/context.dart'; import 'package:remever/database/database.dart'; import 'package:remever/inject.dart'; import 'package:remever/router.gr.dart'; import 'package:remever/screens/collections/widgets/collection_card.dart'; import 'package:remever/screens/collections/widgets/collections_app_bar.dart'; import 'package:remever/screens/collections/widgets/collections_filters.dart'; import 'package:remever/services/collection/collections_interface.dart'; @RoutePage() class CollectionScreen extends StatefulWidget { const CollectionScreen({super.key}); @override State createState() => _CollectionScreenState(); } class _CollectionScreenState extends State { /// Контроллер скролла для коллекции final ScrollController _scrollController = ScrollController(); /// Показ FAB'а bool _showFab = true; @override void initState() { super.initState(); _initScrollListener(); } @override void dispose() { _scrollController.dispose(); super.dispose(); } /// Инициализация слушателя скролла void _initScrollListener() { _scrollController.addListener(() { setState(() { _showFab = _scrollController.position.userScrollDirection == ScrollDirection.reverse ? false : true; }); }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.bg, appBar: const CollectionsAppBar(), body: _buildMain(context), floatingActionButton: AnimatedOpacity( opacity: _showFab ? 1.0 : 0.0, duration: const Duration(milliseconds: 200), child: FloatingActionButton( backgroundColor: AppColors.primary, onPressed: () => context.pushRoute(CrudCollectionRoute()), child: const Icon(Icons.add), ), ), ); } /// Построение основного экрана Widget _buildMain(BuildContext context) { return Column( children: [ const CollectionsFilters(), Expanded( child: StreamBuilder>( stream: getIt().watchCollectionsList(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const _LoadingList(); } if (snapshot.hasError) { return const _ErrorList(); } final collections = snapshot.data; if (collections == null || collections.isEmpty) { return const _EmptyList(); } return ListView.builder( controller: _scrollController, itemCount: collections.length, padding: const EdgeInsets.symmetric(horizontal: 16).r, itemBuilder: (context, index) => Padding( padding: const EdgeInsets.only(bottom: 8).r, child: CollectionCard(collection: collections[index]), ), ); }, ), ), ], ); } } class _LoadingList extends StatelessWidget { const _LoadingList(); @override Widget build(BuildContext context) { return SizedBox( height: MediaQuery.sizeOf(context).height / 2, child: Center(child: CircularProgressIndicator(color: AppColors.primary)), ); } } class _ErrorList extends StatelessWidget { const _ErrorList(); @override Widget build(BuildContext context) { return SizedBox( height: MediaQuery.sizeOf(context).height / 2, child: Center( child: AppTypography('Произошла ошибка при загрузке данных'), ), ); } } class _EmptyList extends StatelessWidget { const _EmptyList(); @override Widget build(BuildContext context) { return SizedBox( height: MediaQuery.sizeOf(context).height / 2, child: Center(child: AppTypography('Нет доступных коллекций')), ); } }