import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pullex/pullex.dart'; import 'package:f0ckapp/widgets/tagfooter.dart'; import 'package:f0ckapp/utils/customsearchdelegate.dart'; import 'package:f0ckapp/widgets/end_drawer.dart'; import 'package:f0ckapp/widgets/filter_bar.dart'; import 'package:f0ckapp/widgets/media_tile.dart'; import 'package:f0ckapp/controller/settingscontroller.dart'; import 'package:f0ckapp/controller/mediacontroller.dart'; class MediaGrid extends StatefulWidget { const MediaGrid({super.key}); @override State createState() => _MediaGrid(); } class _MediaGrid extends State { final ScrollController _scrollController = ScrollController(); final MediaController _mediaController = Get.put(MediaController()); final SettingsController _settingsController = Get.put(SettingsController()); final PullexRefreshController _refreshController = PullexRefreshController( initialRefresh: false, ); late final _MediaGridAppBar _appBar; late final _MediaGridBody _body; @override void initState() { super.initState(); _mediaController.fetchInitial(); _appBar = _MediaGridAppBar(mediaController: _mediaController); _body = _MediaGridBody( refreshController: _refreshController, mediaController: _mediaController, settingsController: _settingsController, scrollController: _scrollController, ); } @override void dispose() { _scrollController.dispose(); _refreshController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Obx( () => Scaffold( endDrawer: const EndDrawer(), endDrawerEnableOpenDragGesture: _settingsController.drawerSwipeEnabled.value, bottomNavigationBar: FilterBar(scrollController: _scrollController), appBar: _appBar, body: _body, persistentFooterButtons: _mediaController.tag.value != null ? [TagFooter()] : null, ), ); } } class _MediaGridAppBar extends StatelessWidget implements PreferredSizeWidget { const _MediaGridAppBar({required this.mediaController}); final MediaController mediaController; @override Widget build(BuildContext context) { return AppBar( title: InkWell( onTap: () { mediaController.setTag(null); }, child: Row( mainAxisSize: MainAxisSize.min, 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(), ); }, ), Obx( () => IconButton( icon: Icon( mediaController.isRandomEnabled ? Icons.shuffle_on_outlined : Icons.shuffle, ), onPressed: mediaController.toggleRandom, ), ), IconButton( icon: const Icon(Icons.menu), onPressed: () => Scaffold.of(context).openEndDrawer(), ), ], ); } @override Size get preferredSize => const Size.fromHeight(kToolbarHeight); } class _MediaGridBody extends StatelessWidget { const _MediaGridBody({ required this.refreshController, required this.mediaController, required this.settingsController, required this.scrollController, }); final PullexRefreshController refreshController; final MediaController mediaController; final SettingsController settingsController; final ScrollController scrollController; @override Widget build(BuildContext context) { return PullexRefresh( controller: refreshController, enablePullDown: true, enablePullUp: true, header: const WaterDropHeader(), onRefresh: () async { try { await mediaController.handleRefresh(); } finally { refreshController.refreshCompleted(); } }, onLoading: () async { try { await mediaController.handleLoading(); } finally { refreshController.loadComplete(); } }, child: Obx( () => GridView.builder( addAutomaticKeepAlives: false, controller: scrollController, physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, padding: const EdgeInsets.all(4), itemCount: mediaController.items.length, gridDelegate: settingsController.crossAxisCount.value == 0 ? const SliverGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 150, crossAxisSpacing: 5, mainAxisSpacing: 5, childAspectRatio: 1, ) : SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: settingsController.crossAxisCount.value, crossAxisSpacing: 5, mainAxisSpacing: 5, childAspectRatio: 1, ), itemBuilder: (context, index) { final item = mediaController.items[index]; return GestureDetector( key: ValueKey(item.id), onTap: () => Get.toNamed('/${item.id}'), child: MediaTile(item: item), ); }, ), ), ); } }