This commit is contained in:
Flummi 2025-05-31 16:48:33 +02:00
parent 6830de4e75
commit 018581e4d2

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:f0ckapp/models/mediaitem_detail.dart';
import 'package:f0ckapp/services/api.dart'; // API Call für neue Items
import 'package:f0ckapp/services/api.dart';
class DetailView extends StatefulWidget {
final MediaItemDetail details;
@ -21,19 +21,24 @@ class _DetailViewState extends State<DetailView> {
void initState() {
super.initState();
isAudio = widget.details.mime.startsWith("audio/");
_controller = VideoPlayerController.networkUrl(Uri.parse(widget.details.mediaUrl));
_controller = VideoPlayerController.networkUrl(
Uri.parse(widget.details.mediaUrl),
);
if (!widget.details.mime.startsWith("image/")) {
_initializeVideoPlayer = _controller.initialize().then((_) {
setState(() {
_controller.play();
_controller.setLooping(true);
});
}).catchError((error) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Fehler beim Laden des Videos: $error")),
);
});
_initializeVideoPlayer = _controller
.initialize()
.then((_) {
setState(() {
_controller.play();
_controller.setLooping(true);
});
})
.catchError((error) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Fehler beim Laden des Videos: $error")),
);
});
}
}
@ -45,21 +50,29 @@ class _DetailViewState extends State<DetailView> {
Future<void> _loadNewMediaItem(int itemId, bool swipeLeft) async {
try {
var newDetails = await fetchMediaDetail(itemId); // API Call
var newDetails = await fetchMediaDetail(itemId);
Navigator.of(context).pushReplacement(PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => DetailView(details: newDetails),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
Offset begin = swipeLeft ? const Offset(-1.0, 0.0) : const Offset(1.0, 0.0); // Richtung des Swipes
const Offset end = Offset.zero;
const curve = Curves.easeInOut;
Navigator.of(context).pushReplacement(
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) =>
DetailView(details: newDetails),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
Offset begin = swipeLeft
? const Offset(-1.0, 0.0)
: const Offset(1.0, 0.0);
const Offset end = Offset.zero;
const curve = Curves.easeInOut;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
var offsetAnimation = animation.drive(tween);
var tween = Tween(
begin: begin,
end: end,
).chain(CurveTween(curve: curve));
var offsetAnimation = animation.drive(tween);
return SlideTransition(position: offsetAnimation, child: child);
},
));
return SlideTransition(position: offsetAnimation, child: child);
},
),
);
} catch (error) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Fehler beim Laden des Items: $error")),
@ -87,20 +100,27 @@ class _DetailViewState extends State<DetailView> {
body: SingleChildScrollView(
child: Column(
children: [
if (widget.details.mime.contains(RegExp(r'image/(jpeg|png|gif|webp)'))) ...[
if (widget.details.mime.contains(
RegExp(r'image/(jpeg|png|gif|webp)'),
)) ...[
Image.network(widget.details.mediaUrl),
] else ...[
Stack(
alignment: Alignment.center,
children: [
if (isAudio)
Image.network('https://f0ck.me/ca/${widget.details.id}.webp'),
Image.network(
'https://f0ck.me/ca/${widget.details.id}.webp',
),
FutureBuilder(
future: _initializeVideoPlayer,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done && _controller.value.isInitialized) {
if (snapshot.connectionState == ConnectionState.done &&
_controller.value.isInitialized) {
return AspectRatio(
aspectRatio: isAudio ? 1 : _controller.value.aspectRatio,
aspectRatio: isAudio
? 1
: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
);
} else {
@ -123,21 +143,33 @@ class _DetailViewState extends State<DetailView> {
IconButton(
icon: const Icon(Icons.replay_10),
onPressed: () {
_controller.seekTo(_controller.value.position - const Duration(seconds: 10));
_controller.seekTo(
_controller.value.position -
const Duration(seconds: 10),
);
},
),
IconButton(
icon: Icon(_controller.value.isPlaying ? Icons.pause : Icons.play_arrow),
icon: Icon(
_controller.value.isPlaying
? Icons.pause
: Icons.play_arrow,
),
onPressed: () {
setState(() {
_controller.value.isPlaying ? _controller.pause() : _controller.play();
_controller.value.isPlaying
? _controller.pause()
: _controller.play();
});
},
),
IconButton(
icon: const Icon(Icons.forward_10),
onPressed: () {
_controller.seekTo(_controller.value.position + const Duration(seconds: 10));
_controller.seekTo(
_controller.value.position +
const Duration(seconds: 10),
);
},
),
],
@ -149,9 +181,18 @@ class _DetailViewState extends State<DetailView> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('${widget.details.mime}', style: const TextStyle(fontSize: 16, color: Colors.white)),
Text("Benutzername: ${widget.details.username}", style: const TextStyle(fontSize: 16, color: Colors.white)),
Text("Zeitstempel: ${widget.details.stamp}", style: const TextStyle(fontSize: 16, color: Colors.white)),
Text(
'${widget.details.mime}',
style: const TextStyle(fontSize: 16, color: Colors.white),
),
Text(
"Benutzername: ${widget.details.username}",
style: const TextStyle(fontSize: 16, color: Colors.white),
),
Text(
"Zeitstempel: ${widget.details.stamp}",
style: const TextStyle(fontSize: 16, color: Colors.white),
),
],
),
),