Files
Remever/lib/screens/collections/collections_screen.dart

150 lines
4.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<CollectionScreen> createState() => _CollectionScreenState();
}
class _CollectionScreenState extends State<CollectionScreen> {
/// Контроллер скролла для коллекции
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<List<Collection>>(
stream: getIt<CollectionsInterface>().getCollectionsList(),
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('Нет доступных коллекций')),
);
}
}