add page for tv shows
only showing up if enabled in backend
This commit is contained in:
		@@ -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._();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								lib/app.dart
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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',
 | 
			
		||||
          ));
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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<DrawerPage> {
 | 
			
		||||
  Section _sec = Section.HOME;
 | 
			
		||||
@@ -50,6 +51,11 @@ class _DrawerPageState extends State<DrawerPage> {
 | 
			
		||||
        body = ActorScreen();
 | 
			
		||||
        title = "Actors";
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case Section.TVSHOW:
 | 
			
		||||
        body = TVShowScreen();
 | 
			
		||||
        title = "TV Shows";
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return DrawerContext(
 | 
			
		||||
 
 | 
			
		||||
@@ -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),
 | 
			
		||||
 
 | 
			
		||||
@@ -45,10 +45,11 @@ class _LoginScreenState extends State<LoginScreen> {
 | 
			
		||||
      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 "";
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
 | 
			
		||||
            ElevatedButton(
 | 
			
		||||
                onPressed: () {
 | 
			
		||||
                  loginCtx.onLoggin(false);
 | 
			
		||||
                  Token.getInstance().setToken("", "", "");
 | 
			
		||||
                  Token.getInstance().setToken("", "", "", "");
 | 
			
		||||
                  Db().clear();
 | 
			
		||||
                },
 | 
			
		||||
                child: Text("Logout"))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								lib/navigation/tv_show_screen.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								lib/navigation/tv_show_screen.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
class TVShowScreen extends StatefulWidget {
 | 
			
		||||
  const TVShowScreen({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<TVShowScreen> createState() => _TVShowScreenState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _TVShowScreenState extends State<TVShowScreen> {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Container();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								lib/utils/feature_context.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								lib/utils/feature_context.dart
									
									
									
									
									
										Normal file
									
								
							@@ -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<FeatureContext>();
 | 
			
		||||
    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<FeatureContainer> createState() => _FeatureContainerState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _FeatureContainerState extends State<FeatureContainer> {
 | 
			
		||||
  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);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -19,6 +19,7 @@ class _VideoScreenDesktopState extends State<VideoScreenDesktop> {
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Video(
 | 
			
		||||
        player: _player,
 | 
			
		||||
        showFullscreenButton: true,
 | 
			
		||||
        scale: 1.0, // default
 | 
			
		||||
        showControls: true);
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user