add drawer and shuffle page
fix desktop video play
This commit is contained in:
		
							
								
								
									
										96
									
								
								lib/DrawerPage.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								lib/DrawerPage.dart
									
									
									
									
									
										Normal 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);
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ]),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								lib/app.dart
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								lib/app.dart
									
									
									
									
									
								
							@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 | 
				
			|||||||
import 'package:openmediacentermobile/log/log.dart';
 | 
					import 'package:openmediacentermobile/log/log.dart';
 | 
				
			||||||
import 'package:openmediacentermobile/login/login_screen.dart';
 | 
					import 'package:openmediacentermobile/login/login_screen.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'DrawerPage.dart';
 | 
				
			||||||
import 'api/token.dart';
 | 
					import 'api/token.dart';
 | 
				
			||||||
import 'login/logincontext.dart';
 | 
					import 'login/logincontext.dart';
 | 
				
			||||||
import 'video_feed.dart';
 | 
					import 'video_feed.dart';
 | 
				
			||||||
@@ -24,22 +25,10 @@ class App extends StatelessWidget {
 | 
				
			|||||||
    if (!loginctx.LoggedIn) {
 | 
					    if (!loginctx.LoggedIn) {
 | 
				
			||||||
      return const MaterialApp(home: LoginScreen());
 | 
					      return const MaterialApp(home: LoginScreen());
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return MaterialApp(
 | 
					      return const MaterialApp(
 | 
				
			||||||
          home: Scaffold(
 | 
					          home: DrawerPage(
 | 
				
			||||||
              appBar: AppBar(
 | 
					            title: 'OpenMediaCenter',
 | 
				
			||||||
                title: Row(
 | 
					          ));
 | 
				
			||||||
                  children: [
 | 
					 | 
				
			||||||
                    Text("Openmediacenter"),
 | 
					 | 
				
			||||||
                    ElevatedButton(
 | 
					 | 
				
			||||||
                        onPressed: () {
 | 
					 | 
				
			||||||
                          loginctx.onLoggin(false);
 | 
					 | 
				
			||||||
                          Token.getInstance().setToken("", "");
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        child: Text("logout"))
 | 
					 | 
				
			||||||
                  ],
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
              body: VideoFeed()));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ import 'package:openmediacentermobile/videoscreen_desktop.dart'
 | 
				
			|||||||
import 'api/api.dart';
 | 
					import 'api/api.dart';
 | 
				
			||||||
import 'platform.dart';
 | 
					import 'platform.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// todo put this type in sperate class!
 | 
				
			||||||
class VideoT {
 | 
					class VideoT {
 | 
				
			||||||
  int id;
 | 
					  int id;
 | 
				
			||||||
  String title;
 | 
					  String title;
 | 
				
			||||||
@@ -39,6 +40,17 @@ class _PreviewTileState extends State<PreviewTile> {
 | 
				
			|||||||
    _preview = loadData();
 | 
					    _preview = loadData();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  void didUpdateWidget(PreviewTile oldWidget) {
 | 
				
			||||||
 | 
					    super.didUpdateWidget(oldWidget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (oldWidget.dta != widget.dta) {
 | 
				
			||||||
 | 
					      setState(() {
 | 
				
			||||||
 | 
					        _preview = loadData();
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<Image> loadData() async {
 | 
					  Future<Image> loadData() async {
 | 
				
			||||||
    final data = await API.query("video", "readThumbnail", {'Movieid': widget.dta.id});
 | 
					    final data = await API.query("video", "readThumbnail", {'Movieid': widget.dta.id});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -80,7 +92,7 @@ class _PreviewTileState extends State<PreviewTile> {
 | 
				
			|||||||
                        Navigator.push(
 | 
					                        Navigator.push(
 | 
				
			||||||
                          context,
 | 
					                          context,
 | 
				
			||||||
                          MaterialPageRoute(
 | 
					                          MaterialPageRoute(
 | 
				
			||||||
                            builder: (context) => VideoScreen(videoID: widget.dta.id),
 | 
					                            builder: (context) => VideoScreen(MetaData: widget.dta),
 | 
				
			||||||
                          ),
 | 
					                          ),
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
                      },
 | 
					                      },
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										83
									
								
								lib/shufflescreen.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								lib/shufflescreen.dart
									
									
									
									
									
										Normal 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...'),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					          ]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -5,6 +5,7 @@ import 'package:chewie/chewie.dart';
 | 
				
			|||||||
import "package:dart_vlc/dart_vlc.dart";
 | 
					import "package:dart_vlc/dart_vlc.dart";
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:flutter/services.dart';
 | 
					import 'package:flutter/services.dart';
 | 
				
			||||||
 | 
					import 'package:openmediacentermobile/preview_tile.dart';
 | 
				
			||||||
import 'package:video_player/video_player.dart';
 | 
					import 'package:video_player/video_player.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'api/api.dart';
 | 
					import 'api/api.dart';
 | 
				
			||||||
@@ -13,19 +14,19 @@ import 'log/log.dart';
 | 
				
			|||||||
import 'platform.dart';
 | 
					import 'platform.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VideoScreen extends StatefulWidget {
 | 
					class VideoScreen extends StatefulWidget {
 | 
				
			||||||
  const VideoScreen({Key? key, required this.videoID}) : super(key: key);
 | 
					  const VideoScreen({Key? key, required this.MetaData}) : super(key: key);
 | 
				
			||||||
  final int videoID;
 | 
					  final VideoT MetaData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  State<VideoScreen> createState() => _VideoScreenState();
 | 
					  State<VideoScreen> createState() => _VideoScreenState();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _VideoScreenState extends State<VideoScreen> {
 | 
					class _VideoScreenState extends State<VideoScreen> {
 | 
				
			||||||
  late Player player;
 | 
					  Player? player = isDesktop() ? Player(id: Random().nextInt(0x7fffffff)) : null;
 | 
				
			||||||
  ChewieController? _chewieController;
 | 
					  ChewieController? _chewieController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void loadData() async {
 | 
					  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);
 | 
					    final d = jsonDecode(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,10 +39,9 @@ class _VideoScreenState extends State<VideoScreen> {
 | 
				
			|||||||
    final path = baseurl + "/videos/vids/" + url;
 | 
					    final path = baseurl + "/videos/vids/" + url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (isDesktop()) {
 | 
					    if (isDesktop()) {
 | 
				
			||||||
      player = Player(id: Random().nextInt(0x7fffffff));
 | 
					 | 
				
			||||||
      final media2 = Media.network(path);
 | 
					      final media2 = Media.network(path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      player.open(
 | 
					      player?.open(
 | 
				
			||||||
        media2,
 | 
					        media2,
 | 
				
			||||||
        autoStart: true, // default
 | 
					        autoStart: true, // default
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
@@ -63,13 +63,16 @@ class _VideoScreenState extends State<VideoScreen> {
 | 
				
			|||||||
  void initState() {
 | 
					  void initState() {
 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(isDesktop()){
 | 
				
			||||||
      RawKeyboard.instance.addListener((value) {
 | 
					      RawKeyboard.instance.addListener((value) {
 | 
				
			||||||
        if (value.logicalKey == LogicalKeyboardKey.arrowRight) {
 | 
					        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) {
 | 
					        } 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();
 | 
					    loadData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -80,9 +83,7 @@ class _VideoScreenState extends State<VideoScreen> {
 | 
				
			|||||||
  void dispose() {
 | 
					  void dispose() {
 | 
				
			||||||
    super.dispose();
 | 
					    super.dispose();
 | 
				
			||||||
    if (isDesktop()) {
 | 
					    if (isDesktop()) {
 | 
				
			||||||
      player.pause();
 | 
					      player?.dispose();
 | 
				
			||||||
      player.stop();
 | 
					 | 
				
			||||||
      player.dispose();
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      _chewieController?.videoPlayerController.dispose();
 | 
					      _chewieController?.videoPlayerController.dispose();
 | 
				
			||||||
      _chewieController?.dispose();
 | 
					      _chewieController?.dispose();
 | 
				
			||||||
@@ -93,7 +94,7 @@ class _VideoScreenState extends State<VideoScreen> {
 | 
				
			|||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return Scaffold(
 | 
					    return Scaffold(
 | 
				
			||||||
      appBar: AppBar(
 | 
					      appBar: AppBar(
 | 
				
			||||||
        title: const Text('Second Route'),
 | 
					        title: Text(widget.MetaData.title),
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
      body: Center(child: isDesktop() ? videoDesktop() : videoNotDesktop()),
 | 
					      body: Center(child: isDesktop() ? videoDesktop() : videoNotDesktop()),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user