Compare commits

...

2 Commits

Author SHA1 Message Date
eff1ea0812 add load error in featurecontext 2022-10-20 09:28:14 +02:00
6f6fbb3897 add page for tv shows
only showing up if enabled in backend
2022-10-15 23:15:21 +02:00
9 changed files with 147 additions and 11 deletions

View File

@ -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._();

View File

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

View File

@ -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(

View File

@ -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),

View File

@ -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 "";

View File

@ -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"))

View 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();
}
}

View File

@ -0,0 +1,92 @@
import 'package:flutter/material.dart';
import 'package:openmediacentermobile/login/login_context.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;
bool fetcherror = false;
@override
void initState() {
loadInitialData()
.then((value) => setState(
() {
fullDeleteEnabled = value.fullDeleteEnabled;
tvShowEnabled = value.tvShowEnabled;
},
))
.catchError((err) => setState(() => fetcherror = true));
super.initState();
}
@override
Widget build(BuildContext context) {
if (fetcherror) {
final loginctx = LoginContext.of(context);
return MaterialApp(
home: Scaffold(
body: Center(
child:
Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Text("Fetch error"),
MaterialButton(
onPressed: () => loginctx.onLoggin(false),
child: Text("Logout"),
)
]),
),
),
);
} else if (tvShowEnabled == null || fullDeleteEnabled == null) {
return MaterialApp(
home: Scaffold(
body: Container(
color: Colors.white,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [CircularProgressIndicator(), Text("loading features")],
)),
),
),
);
} else {
return FeatureContext(tvShowEnabled!, fullDeleteEnabled!,
child: widget.child);
}
}
}

View File

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