import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:provider/provider.dart'; import 'package:f0ckapp/screens/DetailView.dart'; import 'package:f0ckapp/providers/MediaProvider.dart'; import 'package:f0ckapp/utils/AppVersion.dart'; class MediaGrid extends StatefulWidget { const MediaGrid({super.key}); @override State createState() => _MediaGridState(); } class _MediaGridState extends State { final ScrollController _scrollController = ScrollController(); @override void initState() { super.initState(); final provider = Provider.of(context, listen: false); Future.microtask(() { provider.loadMedia(); }); _scrollController.addListener(() { if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 200) { provider.loadMedia(notify: false); } }); } int _calculateCrossAxisCount(BuildContext context, int defaultCount) { return defaultCount == 0 ? (MediaQuery.of(context).size.width / 110).clamp(3, 5).toInt() : defaultCount; } @override Widget build(BuildContext context) { final provider = Provider.of(context); final GlobalKey scaffoldKey = GlobalKey(); final TextEditingController _usernameController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); return Scaffold( key: scaffoldKey, appBar: AppBar( title: Image.asset( 'assets/images/f0ck_small.webp', fit: BoxFit.fitHeight, ), actions: [ IconButton( icon: Icon( provider.random ? Icons.shuffle_on_outlined : Icons.shuffle, ), onPressed: () { provider.toggleRandom(); _scrollController.jumpTo(0); }, ), IconButton( icon: const Icon(Icons.menu), onPressed: () { scaffoldKey.currentState?.openEndDrawer(); }, ), ], ), bottomNavigationBar: BottomAppBar( height: 50, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text('type: '), DropdownButton( // type value: provider.type, isDense: true, //icon: SizedBox.shrink(), items: provider.types.map((String value) { return DropdownMenuItem( value: value, child: Text(value, style: TextStyle(color: Colors.white)), ); }).toList(), onChanged: (String? newValue) { if (newValue != null) { provider.setType(newValue); _scrollController.jumpTo(0); } }, ), Text('mode: '), DropdownButton( // mode value: provider.modes[provider.mode], isDense: true, //icon: SizedBox.shrink(), items: provider.modes.map((String value) { return DropdownMenuItem( value: value, child: Text(value), ); }).toList(), onChanged: (String? newValue) { if (newValue != null) { provider.setMode(provider.modes.indexOf(newValue)); _scrollController.jumpTo(0); } }, ), ], ), ), endDrawer: Drawer( child: ListView( padding: EdgeInsets.zero, children: [ DrawerHeader( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/menu.webp'), fit: BoxFit.cover, alignment: Alignment.topCenter, ), ), child: null, ), ExpansionTile( title: Text('Login'), children: [ Padding( padding: EdgeInsets.all(16.0), child: Column( children: [ TextField( readOnly: true, controller: _usernameController, decoration: InputDecoration(labelText: 'Benutzername'), ), SizedBox(height: 10), TextField( readOnly: true, controller: _passwordController, obscureText: true, decoration: InputDecoration(labelText: 'Passwort'), ), SizedBox(height: 20), ElevatedButton( onPressed: () async { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text("noch nicht implementiert lol"), ), ); /*final success = await login( _usernameController.text, _passwordController.text, ); if (success) { Navigator.pop(context); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Login fehlgeschlagen!")), ); }*/ }, child: Text('Login'), ), ], ), ), ], ), ListTile( title: Text('v${AppVersion.version}'), onTap: () { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('jooong lass das, hier ist nichts')), ); }, ), ], ), ), persistentFooterButtons: provider.tag != null ? [ InputChip( label: Text(provider.tag!), backgroundColor: const Color(0xFF090909), labelStyle: const TextStyle(color: Colors.white), onDeleted: () { provider.setTag(null); _scrollController.jumpTo(0); }, ), ] : null, body: RefreshIndicator( onRefresh: () async { await provider.resetMedia(); _scrollController.jumpTo(0); }, child: Consumer( builder: (context, mediaProvider, child) { return GridView.builder( key: PageStorageKey('mediaGrid'), controller: _scrollController, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: _calculateCrossAxisCount( context, provider.crossAxisCount, ), crossAxisSpacing: 5.0, mainAxisSpacing: 5.0, ), itemCount: provider.mediaItems.length + (provider.isLoading ? 1 : 0), itemBuilder: (context, index) { if (index >= provider.mediaItems.length) { return const Center(child: CircularProgressIndicator()); } final item = provider.mediaItems[index]; return InkWell( onTap: () async { bool? ret = await Navigator.push( context, MaterialPageRoute( builder: (context) => DetailView(initialItemId: item.id), ), ); if (ret != null && ret) { _scrollController.jumpTo(0); } }, child: Stack( fit: StackFit.expand, children: [ CachedNetworkImage( imageUrl: item.thumbnailUrl, fit: BoxFit.cover, placeholder: (context, url) => SizedBox.shrink(), errorWidget: (context, url, error) => Icon(Icons.error), ), Align( alignment: FractionalOffset.bottomRight, child: Icon( Icons.square, color: switch (item.mode) { 1 => Colors.green, 2 => Colors.red, _ => Colors.yellow, }, size: 15.0, ), ), ], ), ); }, ); }, ), ), ); } }