From 6f6fbb3897b44b7ae4836d4885c0c848b9a5cd47 Mon Sep 17 00:00:00 2001 From: lukas-heiligenbrunner Date: Sat, 15 Oct 2022 23:15:21 +0200 Subject: [PATCH] add page for tv shows only showing up if enabled in backend --- lib/api/token.dart | 14 +++-- lib/app.dart | 10 +++- lib/drawer/drawer_page.dart | 8 ++- lib/drawer/my_drawer.dart | 11 ++++ lib/login/login_screen.dart | 5 +- lib/navigation/settings_screen.dart | 2 +- lib/navigation/tv_show_screen.dart | 15 +++++ lib/utils/feature_context.dart | 68 +++++++++++++++++++++++ lib/video_screen/videoscreen_desktop.dart | 1 + 9 files changed, 123 insertions(+), 11 deletions(-) create mode 100644 lib/navigation/tv_show_screen.dart create mode 100644 lib/utils/feature_context.dart diff --git a/lib/api/token.dart b/lib/api/token.dart index 0fed2bb..a6ff9a3 100644 --- a/lib/api/token.dart +++ b/lib/api/token.dart @@ -9,8 +9,9 @@ class TokenT { String token; String domain; String videoPath; + String tvPath; - TokenT(this.token, this.domain, this.videoPath); + TokenT(this.token, this.domain, this.videoPath, this.tvPath); } class Token { @@ -20,6 +21,7 @@ class Token { String _tokenval = ""; String _domain = ""; String _vPath = ""; + String _tvPath = ""; static Token getInstance() { return _token; @@ -31,29 +33,33 @@ class Token { WidgetsFlutterBinding.ensureInitialized(); final token = await _storage.read(key: 'jwt'); final domain = await _storage.read(key: 'domain'); + // todo paths should be loaded on each app start final vPath = await _storage.read(key: 'videoPath'); + final tvPath = await _storage.read(key: 'tvPath'); // check if value is defined in phone store if (token != null && domain != null && vPath != null) { _tokenval = token; _domain = domain; - return TokenT(token, domain, vPath); + return TokenT(token, domain, vPath, tvPath ?? ""); } else { Log.d("no token defined"); return null; } } else { - return TokenT(_tokenval, _domain, _vPath); + return TokenT(_tokenval, _domain, _vPath, _tvPath); } } - void setToken(String token, String domain, String videoPath) { + void setToken(String token, String domain, String videoPath, String tvPath) { _tokenval = token; _domain = domain; _vPath = videoPath; + _tvPath = tvPath; _storage.write(key: 'jwt', value: token); _storage.write(key: 'domain', value: domain); _storage.write(key: 'videoPath', value: videoPath); + _storage.write(key: 'tvPath', value: tvPath); } Token._(); diff --git a/lib/app.dart b/lib/app.dart index c60e890..3b5ea7d 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:openmediacentermobile/log/log.dart'; import 'package:openmediacentermobile/login/login_screen.dart'; +import 'package:openmediacentermobile/utils/feature_context.dart'; import 'drawer/drawer_page.dart'; import 'login/login_context.dart'; @@ -21,18 +22,21 @@ class App extends StatelessWidget { @override Widget build(BuildContext context) { - var loginCtx = LoginContext.of(context); + final loginCtx = LoginContext.of(context); Log.d("We are logged in: ${loginCtx.loggedIn}"); if (!loginCtx.loggedIn) { return const MaterialApp(home: LoginScreen()); } else { - return MaterialApp( + return FeatureContainer( + child: MaterialApp( scrollBehavior: AppScrollBehavior(), home: DrawerPage( title: 'OpenMediaCenter', - )); + ), + ), + ); } } } diff --git a/lib/drawer/drawer_page.dart b/lib/drawer/drawer_page.dart index cececf1..f676a04 100644 --- a/lib/drawer/drawer_page.dart +++ b/lib/drawer/drawer_page.dart @@ -3,6 +3,7 @@ import 'package:openmediacentermobile/navigation/settings_screen.dart'; import '../navigation/actor_screen.dart'; import '../navigation/categorie_screen.dart'; import '../navigation/shuffle_screen.dart'; +import '../navigation/tv_show_screen.dart'; import '../navigation/video_feed.dart'; import 'drawer_context.dart'; @@ -15,7 +16,7 @@ class DrawerPage extends StatefulWidget { _DrawerPageState createState() => _DrawerPageState(); } -enum Section { HOME, SHUFFLE, SETTING, CATEGORIE, ACTOR } +enum Section { HOME, SHUFFLE, SETTING, CATEGORIE, ACTOR, TVSHOW } class _DrawerPageState extends State { Section _sec = Section.HOME; @@ -50,6 +51,11 @@ class _DrawerPageState extends State { body = ActorScreen(); title = "Actors"; break; + + case Section.TVSHOW: + body = TVShowScreen(); + title = "TV Shows"; + break; } return DrawerContext( diff --git a/lib/drawer/my_drawer.dart b/lib/drawer/my_drawer.dart index 1544d13..d85e074 100644 --- a/lib/drawer/my_drawer.dart +++ b/lib/drawer/my_drawer.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:openmediacentermobile/utils/feature_context.dart'; import 'drawer_context.dart'; import 'drawer_page.dart'; @@ -9,6 +10,7 @@ class MyDrawer extends StatelessWidget { @override Widget build(BuildContext context) { final ctx = DrawerContext.of(context); + final featureCtx = FeatureContext.of(context); return Drawer( child: ListView(children: [ @@ -44,6 +46,15 @@ class MyDrawer extends StatelessWidget { Navigator.pop(context); }, ), + if (featureCtx.tvShowEnabled) + ListTile( + title: const Text('TV Shows'), + leading: const Icon(Icons.tv), + onTap: () { + ctx.onChangePage(Section.TVSHOW); + Navigator.pop(context); + }, + ), ListTile( title: const Text('Settings'), leading: const Icon(Icons.settings), diff --git a/lib/login/login_screen.dart b/lib/login/login_screen.dart index ac108cc..3bf5ffb 100644 --- a/lib/login/login_screen.dart +++ b/lib/login/login_screen.dart @@ -45,10 +45,11 @@ class _LoginScreenState extends State { final token = json["Token"]; // todo bit hacky - Token.getInstance().setToken(token, domain, "temp"); + Token.getInstance().setToken(token, domain, "temp", "temp"); // we need to call this twice because we need for the loadInitialData an api token + final initalData = await loadInitialData(); Token.getInstance() - .setToken(token, domain, (await loadInitialData()).videoPath); + .setToken(token, domain, initalData.videoPath, initalData.tvShowPath); LoginContext.of(context).onLoggin(true); return ""; diff --git a/lib/navigation/settings_screen.dart b/lib/navigation/settings_screen.dart index cc65f5e..c6cb9bf 100644 --- a/lib/navigation/settings_screen.dart +++ b/lib/navigation/settings_screen.dart @@ -53,7 +53,7 @@ class _SettingsScreenState extends State { ElevatedButton( onPressed: () { loginCtx.onLoggin(false); - Token.getInstance().setToken("", "", ""); + Token.getInstance().setToken("", "", "", ""); Db().clear(); }, child: Text("Logout")) diff --git a/lib/navigation/tv_show_screen.dart b/lib/navigation/tv_show_screen.dart new file mode 100644 index 0000000..abc211c --- /dev/null +++ b/lib/navigation/tv_show_screen.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class TVShowScreen extends StatefulWidget { + const TVShowScreen({Key? key}) : super(key: key); + + @override + State createState() => _TVShowScreenState(); +} + +class _TVShowScreenState extends State { + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/lib/utils/feature_context.dart b/lib/utils/feature_context.dart new file mode 100644 index 0000000..bc469f1 --- /dev/null +++ b/lib/utils/feature_context.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import '../api/settings_api.dart'; + +// todo maybe instead of feature context a context for all settings? +class FeatureContext extends InheritedWidget { + const FeatureContext(this.tvShowEnabled, this.fullDeleteEnabled, + {Key? key, required Widget child}) + : super(key: key, child: child); + + final bool tvShowEnabled; + final bool fullDeleteEnabled; + + static FeatureContext of(BuildContext context) { + final FeatureContext? result = + context.dependOnInheritedWidgetOfExactType(); + assert(result != null, 'No LoginContext found in context'); + return result!; + } + + @override + bool updateShouldNotify(FeatureContext old) { + return tvShowEnabled != old.tvShowEnabled || + fullDeleteEnabled != old.fullDeleteEnabled; + } +} + +class FeatureContainer extends StatefulWidget { + const FeatureContainer({Key? key, required this.child}) : super(key: key); + final Widget child; + + @override + State createState() => _FeatureContainerState(); +} + +class _FeatureContainerState extends State { + bool? tvShowEnabled; + bool? fullDeleteEnabled; + + @override + void initState() { + loadInitialData().then((value) => setState( + () { + fullDeleteEnabled = value.fullDeleteEnabled; + tvShowEnabled = value.tvShowEnabled; + }, + )); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + if (tvShowEnabled == null || fullDeleteEnabled == null) { + return MaterialApp( + home: Container( + color: Colors.white, + child: Center( + child: Column( + children: [CircularProgressIndicator(), Text("loading features")], + )), + ), + ); + } else { + return FeatureContext(tvShowEnabled!, fullDeleteEnabled!, + child: widget.child); + } + } +} diff --git a/lib/video_screen/videoscreen_desktop.dart b/lib/video_screen/videoscreen_desktop.dart index 69657e1..e95d7d0 100644 --- a/lib/video_screen/videoscreen_desktop.dart +++ b/lib/video_screen/videoscreen_desktop.dart @@ -19,6 +19,7 @@ class _VideoScreenDesktopState extends State { Widget build(BuildContext context) { return Video( player: _player, + showFullscreenButton: true, scale: 1.0, // default showControls: true); }