import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:video_player/video_player.dart'; class VideoPage extends StatefulWidget { const VideoPage({ super.key, required this.title, required this.videoPath, }); final String title; final String videoPath; @override State createState() => _VideoPageState(); } class _VideoPageState extends State { late final VideoPlayerController _controller; late final Future _initializeVideo; bool _fullscreen = false; @override void initState() { super.initState(); final uri = Uri.tryParse(widget.videoPath); _controller = uri != null && uri.hasScheme ? VideoPlayerController.networkUrl(uri) : VideoPlayerController.asset(widget.videoPath); _initializeVideo = _controller.initialize().then((_) { _controller ..setLooping(true) ..play(); if (mounted) { setState(() {}); } }); } @override void dispose() { SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); SystemChrome.setPreferredOrientations(DeviceOrientation.values); _controller.dispose(); super.dispose(); } void _togglePlayPause() { setState(() { _controller.value.isPlaying ? _controller.pause() : _controller.play(); }); } Future _toggleFullscreen() async { setState(() => _fullscreen = !_fullscreen); if (_fullscreen) { await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); await SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight, ]); return; } await SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); await SystemChrome.setPreferredOrientations(DeviceOrientation.values); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: Stack( fit: StackFit.expand, children: [ Center( child: FutureBuilder( future: _initializeVideo, builder: (context, snapshot) { if (snapshot.connectionState != ConnectionState.done) { return const DecoratedBox( decoration: BoxDecoration(color: Colors.black), child: Center( child: CircularProgressIndicator( color: Color(0xFF14B8C4), ), ), ); } if (snapshot.hasError || _controller.value.hasError) { return Padding( padding: const EdgeInsets.all(24), child: Text( 'Video wisata gagal dimuat.', textAlign: TextAlign.center, style: Theme.of(context).textTheme.titleMedium?.copyWith( color: Colors.white, fontWeight: FontWeight.w800, ), ), ); } return SizedBox.expand( child: FittedBox( fit: BoxFit.cover, child: SizedBox( width: _controller.value.size.width, height: _controller.value.size.height, child: VideoPlayer(_controller), ), ), ); }, ), ), const DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0xCC000000), Color(0x22000000), Color(0xBB000000), ], ), ), ), SafeArea( child: Padding( padding: const EdgeInsets.fromLTRB(12, 8, 12, 20), child: Column( children: [ Row( children: [ IconButton.filledTonal( tooltip: 'Kembali', onPressed: () => Navigator.pop(context), icon: const Icon(Icons.arrow_back_rounded), ), const SizedBox(width: 10), Expanded( child: Text( widget.title, maxLines: 2, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.titleLarge?.copyWith( color: Colors.white, fontWeight: FontWeight.w900, ), ), ), IconButton.filledTonal( tooltip: _fullscreen ? 'Keluar fullscreen' : 'Fullscreen', onPressed: _toggleFullscreen, icon: Icon( _fullscreen ? Icons.fullscreen_exit_rounded : Icons.fullscreen_rounded, ), ), ], ), const Spacer(), ValueListenableBuilder( valueListenable: _controller, builder: (context, value, child) { return IconButton.filled( tooltip: value.isPlaying ? 'Jeda' : 'Putar', onPressed: value.isInitialized ? _togglePlayPause : null, iconSize: 40, style: IconButton.styleFrom( backgroundColor: Colors.white, foregroundColor: const Color(0xFF0F4C81), padding: const EdgeInsets.all(18), ), icon: Icon( value.isPlaying ? Icons.pause_rounded : Icons.play_arrow_rounded, ), ); }, ), ], ), ), ), ], ), ); } }