import 'package:flutter/material.dart'; import 'package:f0ckapp/models/mediaitem.dart'; import 'package:f0ckapp/services/api.dart'; import 'package:f0ckapp/widgets/video_widget.dart'; class DetailView extends StatefulWidget { final int initialItemId; final List mediaItems; final String type; final int mode; final bool random; const DetailView({ super.key, required this.initialItemId, required this.mediaItems, required this.type, required this.mode, required this.random, }); @override State createState() => _DetailViewState(); } class _DetailViewState extends State { late PageController _pageController; late List mediaItems; final List _modes = ["sfw", "nsfw", "untagged", "all"]; int currentItemId = 0; bool isLoading = false; @override void initState() { super.initState(); mediaItems = widget.mediaItems; final initialIndex = mediaItems.indexWhere( (item) => item.id == widget.initialItemId, ); _pageController = PageController(initialPage: initialIndex); currentItemId = mediaItems[initialIndex].id; _pageController.addListener(() { final newIndex = _pageController.page?.round(); if (newIndex != null && newIndex < mediaItems.length) { setState(() => currentItemId = mediaItems[newIndex].id); } if (_pageController.position.pixels >= _pageController.position.maxScrollExtent - 100) { _loadMoreMedia(); } }); } Future _loadMoreMedia() async { if (isLoading) return; setState(() => isLoading = true); try { final newMedia = await fetchMedia( older: mediaItems.last.id.toString(), type: widget.type, mode: widget.mode, random: widget.random, ); if (mounted) { setState(() => mediaItems.addAll(newMedia)); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Fehler beim Laden weiterer Medien: $e')), ); } } finally { setState(() => isLoading = false); } } Future _refreshMediaItem() async { try { final updatedItem = await fetchMediaDetail(currentItemId); if (mounted) { setState(() { final index = mediaItems.indexWhere( (item) => item.id == currentItemId, ); if (index != -1) { mediaItems[index] = updatedItem; } }); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Fehler beim Aktualisieren des Items: $e')), ); } } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFF171717), appBar: AppBar( backgroundColor: const Color(0xFF2B2B2B), foregroundColor: Colors.white, title: Text( 'f0ck #$currentItemId (${widget.type}, ${_modes[widget.mode]})', ), centerTitle: true, ), body: RefreshIndicator( onRefresh: _refreshMediaItem, child: SingleChildScrollView( child: Column( children: [ SizedBox( height: MediaQuery.of(context).size.height, child: PageView.builder( controller: _pageController, itemCount: mediaItems.length, itemBuilder: (context, index) { final item = mediaItems[index]; return Column( children: [ if (item.mime.startsWith('image')) Image.network(item.mediaUrl, fit: BoxFit.contain) else VideoWidget(details: item), const SizedBox(height: 20), Text( item.mime, style: const TextStyle( color: Colors.white, fontSize: 18, ), ), const SizedBox(height: 10), Wrap( alignment: WrapAlignment.center, spacing: 5.0, children: item.tags.map((tag) { Color tagColor; switch (tag.id) { case 1: tagColor = Colors.green; break; case 2: tagColor = Colors.red; break; default: tagColor = const Color(0xFF090909); } return Chip( label: Text(tag.tag), backgroundColor: tagColor, labelStyle: const TextStyle(color: Colors.white), ); }).toList(), ), const SizedBox(height: 40), ], ); }, ), ), ], ), ), ), ); } }