add drawer and shuffle page

fix desktop video play
This commit is contained in:
lukas 2022-04-15 21:57:15 +02:00
parent 0fce95faa0
commit 51b4d4b38d
5 changed files with 215 additions and 34 deletions

96
lib/DrawerPage.dart Normal file
View File

@ -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<DrawerPage> {
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);
},
),
]),
),
);
}
}

View File

@ -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',
));
}
}
}

View File

@ -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<PreviewTile> {
_preview = loadData();
}
@override
void didUpdateWidget(PreviewTile oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.dta != widget.dta) {
setState(() {
_preview = loadData();
});
}
}
Future<Image> loadData() async {
final data = await API.query("video", "readThumbnail", {'Movieid': widget.dta.id});
@ -80,7 +92,7 @@ class _PreviewTileState extends State<PreviewTile> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => VideoScreen(videoID: widget.dta.id),
builder: (context) => VideoScreen(MetaData: widget.dta),
),
);
},

83
lib/shufflescreen.dart Normal file
View File

@ -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<ShuffleScreen> createState() => _ShuffleScreenState();
}
class _ShuffleScreenState extends State<ShuffleScreen> {
late Future<List<VideoT>> _data;
Future<List<VideoT>> loadData() async {
final data = await API.query("video", "getRandomMovies", {'Number': 4, 'Seed': Random().nextInt(0x7fffffff)});
final d = jsonDecode(data);
List<VideoT> 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<List<VideoT>>(
future: _data, // a previously-obtained Future<String> or null
builder: (BuildContext context, AsyncSnapshot<List<VideoT>> 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 <Widget>[
SizedBox(
width: 60,
height: 60,
child: CircularProgressIndicator(),
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting result...'),
)
]);
}
},
);
}
}

View File

@ -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<VideoScreen> createState() => _VideoScreenState();
}
class _VideoScreenState extends State<VideoScreen> {
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<VideoScreen> {
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<VideoScreen> {
void initState() {
super.initState();
if(isDesktop()){
RawKeyboard.instance.addListener((value) {
if (value.logicalKey == LogicalKeyboardKey.arrowRight) {
player.seek(player.position.position! + const Duration(seconds: 5));
player?.seek(player!.position.position! + const Duration(seconds: 5));
} else if (value.logicalKey == LogicalKeyboardKey.arrowLeft) {
player.seek(player.position.position! + const Duration(seconds: -5));
player?.seek(player!.position.position! + const Duration(seconds: -5));
}
});
}
loadData();
@ -80,9 +83,7 @@ class _VideoScreenState extends State<VideoScreen> {
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<VideoScreen> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Second Route'),
title: Text(widget.MetaData.title),
),
body: Center(child: isDesktop() ? videoDesktop() : videoNotDesktop()),
);