diff --git a/lib/DrawerPage.dart b/lib/DrawerPage.dart new file mode 100644 index 0000000..7dee1c9 --- /dev/null +++ b/lib/DrawerPage.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; +import 'package:openmediacentermobile/shufflescreen.dart'; +import 'package:openmediacentermobile/video_feed.dart'; + +import 'api/token.dart'; +import 'login/logincontext.dart'; + +class DrawerPage extends StatefulWidget { + const DrawerPage({Key? key, required this.title}) : super(key: key); + + final String title; + + @override + _DrawerPageState createState() => _DrawerPageState(); +} + +enum Section { HOME, SHUFFLE, LOGOUT } + +class _DrawerPageState extends State { + Section sec = Section.HOME; + + @override + Widget build(BuildContext context) { + Widget body; + String title; + + /// You can easily control the section for example inside the initState where you check + /// if the user logged in, or other related logic + switch (sec) { + + /// Display the home section, simply by + case Section.HOME: + body = const VideoFeed(); + title = widget.title; + break; + + case Section.SHUFFLE: + body = const ShuffleScreen(); + title = "Shuffle"; + break; + + case Section.LOGOUT: + body = const Text("also todo"); + title = "Settings"; + break; + } + + var loginctx = LoginContext.of(context); + + return Scaffold( + appBar: AppBar(title: Text(title), actions: [ + IconButton( + onPressed: () { + loginctx.onLoggin(false); + Token.getInstance().setToken("", ""); + }, + icon: const Icon(Icons.logout)) + ],), + body: body, + drawer: Drawer( + child: ListView(children: [ + ListTile( + title: const Text('Home'), + leading: const Icon(Icons.home), + onTap: () { + setState(() { + sec = Section.HOME; + }); + Navigator.pop(context); + }, + ), + ListTile( + title: const Text('Shuffle'), + leading: const Icon(Icons.update), + onTap: () { + setState(() { + sec = Section.SHUFFLE; + }); + Navigator.pop(context); + }, + ), + ListTile( + title: const Text('Settings'), + leading: const Icon(Icons.settings), + onTap: () { + setState(() { + sec = Section.LOGOUT; + }); + Navigator.pop(context); + }, + ), + ]), + ), + ); + } +} diff --git a/lib/app.dart b/lib/app.dart index c3273ea..f13b296 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:openmediacentermobile/log/log.dart'; import 'package:openmediacentermobile/login/login_screen.dart'; +import 'DrawerPage.dart'; import 'api/token.dart'; import 'login/logincontext.dart'; import 'video_feed.dart'; @@ -24,22 +25,10 @@ class App extends StatelessWidget { if (!loginctx.LoggedIn) { return const MaterialApp(home: LoginScreen()); } else { - return MaterialApp( - home: Scaffold( - appBar: AppBar( - title: Row( - children: [ - Text("Openmediacenter"), - ElevatedButton( - onPressed: () { - loginctx.onLoggin(false); - Token.getInstance().setToken("", ""); - }, - child: Text("logout")) - ], - ), - ), - body: VideoFeed())); + return const MaterialApp( + home: DrawerPage( + title: 'OpenMediaCenter', + )); } } } diff --git a/lib/preview_tile.dart b/lib/preview_tile.dart index 74c8df0..57dcac6 100644 --- a/lib/preview_tile.dart +++ b/lib/preview_tile.dart @@ -9,6 +9,7 @@ import 'package:openmediacentermobile/videoscreen_desktop.dart' import 'api/api.dart'; import 'platform.dart'; +// todo put this type in sperate class! class VideoT { int id; String title; @@ -39,6 +40,17 @@ class _PreviewTileState extends State { _preview = loadData(); } + @override + void didUpdateWidget(PreviewTile oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.dta != widget.dta) { + setState(() { + _preview = loadData(); + }); + } + } + Future loadData() async { final data = await API.query("video", "readThumbnail", {'Movieid': widget.dta.id}); @@ -80,7 +92,7 @@ class _PreviewTileState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => VideoScreen(videoID: widget.dta.id), + builder: (context) => VideoScreen(MetaData: widget.dta), ), ); }, diff --git a/lib/shufflescreen.dart b/lib/shufflescreen.dart new file mode 100644 index 0000000..3d1308e --- /dev/null +++ b/lib/shufflescreen.dart @@ -0,0 +1,83 @@ +import 'dart:convert'; +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; +import 'package:openmediacentermobile/preview_tile.dart'; + +import 'api/api.dart'; +import 'platform.dart'; + +class ShuffleScreen extends StatefulWidget { + const ShuffleScreen({Key? key}) : super(key: key); + + @override + State createState() => _ShuffleScreenState(); +} + +class _ShuffleScreenState extends State { + late Future> _data; + + Future> loadData() async { + final data = await API.query("video", "getRandomMovies", {'Number': 4, 'Seed': Random().nextInt(0x7fffffff)}); + + final d = jsonDecode(data); + + List dta = (d['Videos'] as List).map((e) => VideoT.fromJson(e)).toList(); + + return dta; + } + + @override + void initState() { + super.initState(); + + _data = loadData(); + } + + @override + Widget build(BuildContext context) { + double width = MediaQuery.of(context).size.width; + return FutureBuilder>( + future: _data, // a previously-obtained Future or null + builder: (BuildContext context, AsyncSnapshot> snapshot) { + if (snapshot.hasError) { + return Text("Error"); + } else if (snapshot.hasData) { + return Column(children: [ + MasonryGridView.count( + shrinkWrap: true, + // every tile should be at max 330 pixels long... + crossAxisCount: isTV() ? width ~/ 200 : width ~/ 330, + mainAxisSpacing: 4, + crossAxisSpacing: 4, + itemCount: 4, + itemBuilder: (context, index) { + return PreviewTile(dta: snapshot.data![index]); + }, + ), + const SizedBox(height: 25,), + TextButton.icon(onPressed: () { + setState(() { + _data = loadData(); + }); + + }, icon: const Icon(Icons.update), label: const Text("Shuffle")) + ]); + } else { + return Column(children: const [ + SizedBox( + width: 60, + height: 60, + child: CircularProgressIndicator(), + ), + Padding( + padding: EdgeInsets.only(top: 16), + child: Text('Awaiting result...'), + ) + ]); + } + }, + ); + } +} diff --git a/lib/videoscreen_desktop.dart b/lib/videoscreen_desktop.dart index d2eef7b..12ff1e8 100644 --- a/lib/videoscreen_desktop.dart +++ b/lib/videoscreen_desktop.dart @@ -5,6 +5,7 @@ import 'package:chewie/chewie.dart'; import "package:dart_vlc/dart_vlc.dart"; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:openmediacentermobile/preview_tile.dart'; import 'package:video_player/video_player.dart'; import 'api/api.dart'; @@ -13,19 +14,19 @@ import 'log/log.dart'; import 'platform.dart'; class VideoScreen extends StatefulWidget { - const VideoScreen({Key? key, required this.videoID}) : super(key: key); - final int videoID; + const VideoScreen({Key? key, required this.MetaData}) : super(key: key); + final VideoT MetaData; @override State createState() => _VideoScreenState(); } class _VideoScreenState extends State { - late Player player; + Player? player = isDesktop() ? Player(id: Random().nextInt(0x7fffffff)) : null; ChewieController? _chewieController; void loadData() async { - final data = await API.query("video", "loadVideo", {'MovieId': widget.videoID}); + final data = await API.query("video", "loadVideo", {'MovieId': widget.MetaData.id}); final d = jsonDecode(data); @@ -38,10 +39,9 @@ class _VideoScreenState extends State { final path = baseurl + "/videos/vids/" + url; if (isDesktop()) { - player = Player(id: Random().nextInt(0x7fffffff)); final media2 = Media.network(path); - player.open( + player?.open( media2, autoStart: true, // default ); @@ -63,13 +63,16 @@ class _VideoScreenState extends State { void initState() { super.initState(); - RawKeyboard.instance.addListener((value) { - if (value.logicalKey == LogicalKeyboardKey.arrowRight) { - player.seek(player.position.position! + const Duration(seconds: 5)); - } else if (value.logicalKey == LogicalKeyboardKey.arrowLeft) { - player.seek(player.position.position! + const Duration(seconds: -5)); - } - }); + if(isDesktop()){ + RawKeyboard.instance.addListener((value) { + if (value.logicalKey == LogicalKeyboardKey.arrowRight) { + player?.seek(player!.position.position! + const Duration(seconds: 5)); + } else if (value.logicalKey == LogicalKeyboardKey.arrowLeft) { + player?.seek(player!.position.position! + const Duration(seconds: -5)); + } + }); + } + loadData(); @@ -80,9 +83,7 @@ class _VideoScreenState extends State { void dispose() { super.dispose(); if (isDesktop()) { - player.pause(); - player.stop(); - player.dispose(); + player?.dispose(); } else { _chewieController?.videoPlayerController.dispose(); _chewieController?.dispose(); @@ -93,7 +94,7 @@ class _VideoScreenState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('Second Route'), + title: Text(widget.MetaData.title), ), body: Center(child: isDesktop() ? videoDesktop() : videoNotDesktop()), );