153 lines
4.5 KiB
Dart
153 lines
4.5 KiB
Dart
import 'package:auto_route/auto_route.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/rendering.dart';
|
||
import 'package:remever/common/functions.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) {
|
||
logger.logBuild('build collection screen');
|
||
|
||
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>().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({super.key});
|
||
|
||
@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({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return SizedBox(
|
||
height: MediaQuery.sizeOf(context).height / 2,
|
||
child: Center(
|
||
child: AppTypography('Произошла ошибка при загрузке данных'),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
class EmptyList extends StatelessWidget {
|
||
const EmptyList({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return SizedBox(
|
||
height: MediaQuery.sizeOf(context).height / 2,
|
||
child: Center(child: AppTypography('Нет доступных коллекций')),
|
||
);
|
||
}
|
||
}
|