fApp/lib/screens/mediagrid_screen.dart
Flummi 16ebc51e77
All checks were successful
Flutter Schmutter / build (push) Successful in 3m39s
v1.1.22+52
2025-06-11 21:30:05 +02:00

156 lines
4.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:f0ckapp/providers/media_provider.dart';
import 'package:f0ckapp/utils/customsearchdelegate_util.dart';
import 'package:f0ckapp/widgets/media_tile.dart';
import 'package:f0ckapp/widgets/filter_bar.dart';
import 'package:f0ckapp/widgets/end_drawer.dart';
class MediaGrid extends ConsumerStatefulWidget {
const MediaGrid({super.key});
@override
ConsumerState<MediaGrid> createState() => _MediaGridState();
}
class _MediaGridState extends ConsumerState<MediaGrid> {
final ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
Future.microtask(() {
ref.read(mediaProvider.notifier).loadMedia();
});
_scrollController.addListener(() {
if (_scrollController.position.pixels >=
_scrollController.position.maxScrollExtent - 200) {
ref.read(mediaProvider.notifier).loadMedia();
}
});
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final MediaState mediaState = ref.watch(mediaProvider);
final MediaNotifier mediaNotifier = ref.read(mediaProvider.notifier);
return Scaffold(
body: RefreshIndicator(
onRefresh: () async {
mediaNotifier.setTag(null);
_scrollController.jumpTo(0);
await mediaNotifier.loadMedia();
},
child: CustomScrollView(
controller: _scrollController,
slivers: [
SliverAppBar(
floating: true,
snap: true,
title: GestureDetector(
onTap: () {
mediaNotifier.setTag(null);
_scrollController.jumpTo(0);
},
child: Row(
children: [
Image.asset(
'assets/images/f0ck_small.webp',
fit: BoxFit.fitHeight,
),
const SizedBox(width: 10),
const Text('fApp', style: TextStyle(fontSize: 24)),
],
),
),
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () async {
await showSearch(
context: context,
delegate: CustomSearchDelegate(),
);
},
),
IconButton(
icon: Icon(
mediaState.random
? Icons.shuffle_on_outlined
: Icons.shuffle,
),
onPressed: () {
mediaNotifier.toggleRandom();
_scrollController.jumpTo(0);
},
),
Builder(
builder: (context) {
return IconButton(
icon: const Icon(Icons.menu),
onPressed: () {
Scaffold.of(context).openEndDrawer();
},
);
},
),
],
),
SliverPadding(
padding: EdgeInsets.zero,
sliver: SliverGrid(
delegate: SliverChildBuilderDelegate(
(context, index) {
if (index >= mediaState.mediaItems.length) {
return const Center(child: CircularProgressIndicator());
}
return MediaTile(item: mediaState.mediaItems[index]);
},
childCount:
mediaState.mediaItems.length +
(mediaState.isLoading ? 1 : 0),
),
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 150,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
childAspectRatio: 1,
),
),
),
],
),
),
bottomNavigationBar: FilterBar(
mediaNotifier: mediaNotifier,
mediaState: mediaState,
scrollController: _scrollController,
),
endDrawer: EndDrawer(ref: ref),
endDrawerEnableOpenDragGesture: false,
persistentFooterButtons: mediaState.tag != null
? [
Center(
child: InputChip(
label: Text(mediaState.tag!),
onDeleted: () {
mediaNotifier.setTag(null);
_scrollController.jumpTo(0);
},
),
),
]
: null,
);
}
}