use a Drawercontext to be able to have a specific scaffold for each page

This commit is contained in:
lukas-heiligenbrunner 2022-08-29 17:16:51 +02:00
parent 9867b913f4
commit 01049d9381
11 changed files with 255 additions and 198 deletions

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:openmediacentermobile/navigation/settings_screen.dart';
import 'db/database.dart';
import 'navigation/actor_screen.dart';
import 'navigation/categorie_screen.dart';
import 'navigation/shufflescreen.dart';
@ -17,7 +18,7 @@ class DrawerPage extends StatefulWidget {
_DrawerPageState createState() => _DrawerPageState();
}
enum Section { HOME, SHUFFLE, LOGOUT, CATEGORIE, ACTOR }
enum Section { HOME, SHUFFLE, SETTING, CATEGORIE, ACTOR }
class _DrawerPageState extends State<DrawerPage> {
Section _sec = Section.HOME;
@ -38,7 +39,7 @@ class _DrawerPageState extends State<DrawerPage> {
title = "Shuffle";
break;
case Section.LOGOUT:
case Section.SETTING:
body = SettingsScreen();
title = "Settings";
break;
@ -54,75 +55,89 @@ class _DrawerPageState extends State<DrawerPage> {
break;
}
final loginCtx = LoginContext.of(context);
return DrawerContext((newPage) {
setState(() {
_sec = newPage;
});
}, child: body);
}
}
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('Categories'),
leading: const Icon(Icons.category),
onTap: () {
setState(() {
_sec = Section.CATEGORIE;
});
Navigator.pop(context);
},
),
ListTile(
title: const Text('Actors'),
leading: const Icon(Icons.people),
onTap: () {
setState(() {
_sec = Section.ACTOR;
});
Navigator.pop(context);
},
),
ListTile(
title: const Text('Settings'),
leading: const Icon(Icons.settings),
onTap: () {
setState(() {
_sec = Section.LOGOUT;
});
Navigator.pop(context);
},
),
]),
),
class MyDrawer extends StatelessWidget {
const MyDrawer({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final ctx = DrawerContext.of(context);
return Drawer(
child: ListView(children: [
ListTile(
title: const Text('Home'),
leading: const Icon(Icons.home),
onTap: () {
ctx.onChangePage(Section.HOME);
Navigator.pop(context);
},
),
ListTile(
title: const Text('Shuffle'),
leading: const Icon(Icons.update),
onTap: () {
ctx.onChangePage(Section.SHUFFLE);
Navigator.pop(context);
},
),
ListTile(
title: const Text('Categories'),
leading: const Icon(Icons.category),
onTap: () {
ctx.onChangePage(Section.CATEGORIE);
Navigator.pop(context);
},
),
ListTile(
title: const Text('Actors'),
leading: const Icon(Icons.people),
onTap: () {
ctx.onChangePage(Section.ACTOR);
Navigator.pop(context);
},
),
ListTile(
title: const Text('Settings'),
leading: const Icon(Icons.settings),
onTap: () {
ctx.onChangePage(Section.SETTING);
Navigator.pop(context);
},
),
]),
);
}
}
class DrawerContext extends InheritedWidget {
const DrawerContext(this.onChangePage, {Key? key, required Widget child})
: super(key: key, child: child);
final void Function(Section) onChangePage;
static DrawerContext of(BuildContext context) {
final DrawerContext? result =
context.dependOnInheritedWidgetOfExactType<DrawerContext>();
assert(result != null, 'No DrawerContext found in context');
return result!;
}
@override
bool updateShouldNotify(covariant InheritedWidget oldWidget) {
return false;
}
// @override
// bool updateShouldNotify(LoginContext old) {
// return loggedIn != old.loggedIn;
// }
}

View File

@ -28,7 +28,7 @@ class Db {
// Set the path to the database. Note: Using the `join` function from the
// `path` package is best practice to ensure the path is correctly
// constructed for each platform.
join(await getDatabasesPath(), 'previews.db'),
dbpath,
onCreate: (db, version) {
// Run the CREATE TABLE statement on the database.
return db.execute(
@ -41,6 +41,22 @@ class Db {
);
}
/// delete all data but keep structure
Future<void> clear() async {
await _db.delete("previews");
// shrink the db file size
await _db.execute("VACUUM");
}
/// get db size in bytes
Future<int> getDbSize() async {
final int cnt = (await Db().db().rawQuery("pragma page_count;"))[0]
["page_count"] as int;
final int pagesize =
(await Db().db().rawQuery("pragma page_size;"))[0]["page_size"] as int;
return cnt * pagesize;
}
Database db() {
return _db;
}

View File

@ -1,8 +1,8 @@
import "package:dart_vlc/dart_vlc.dart";
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:openmediacentermobile/app.dart';
import 'app.dart';
import 'db/database.dart';
import 'log/log.dart';
import 'login/logincontext.dart';
@ -10,29 +10,14 @@ import 'platform.dart';
void main() async {
Log.i("App init!");
DartVLC.initialize();
if (isDesktop()) {
DartVLC.initialize();
} else {
await loadDeviceInfo();
}
Db().init();
// RawKeyboard.instance.addListener((event) {
// if (LogicalKeyboardKey.arrowLeft == event.logicalKey) {
// FocusManager.instance.primaryFocus?.focusInDirection(TraversalDirection.left);
// } else if (LogicalKeyboardKey.arrowRight == event.logicalKey) {
// FocusManager.instance.primaryFocus?.focusInDirection(TraversalDirection.right);
// } else if (LogicalKeyboardKey.arrowDown == event.logicalKey) {
// FocusManager.instance.primaryFocus?.focusInDirection(TraversalDirection.down);
// } else if (LogicalKeyboardKey.arrowUp == event.logicalKey) {
// FocusManager.instance.primaryFocus?.focusInDirection(TraversalDirection.up);
// }
// });
runApp(Shortcuts(shortcuts: <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.select): ActivateIntent(),
}, child: const LoginContainer(child: App())));
// runApp(const LoginContainer(child: App()));
}

View File

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:openmediacentermobile/types/actor.dart';
import 'package:openmediacentermobile/preview/actor_tile.dart';
import '../DrawerPage.dart';
import '../api/api.dart';
import '../screen_loading.dart';
@ -33,33 +34,38 @@ class _ActorScreenState extends State<ActorScreen> {
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _categories,
builder: (context, AsyncSnapshot<List<Actor>> snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return ScreenLoading();
}
return Scaffold(
appBar: AppBar(
title: Text("Temp"),
),
body: FutureBuilder(
future: _categories,
builder: (context, AsyncSnapshot<List<Actor>> snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return ScreenLoading();
}
if (snapshot.hasError) {
return Text("Error");
} else if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.all(5),
child: SingleChildScrollView(
child: Wrap(
spacing: 5,
runSpacing: 5,
alignment: WrapAlignment.start,
children: snapshot.data!
.map((e) => ActorTile(actor: e))
.toList(growable: false),
),
),
);
} else {
return ScreenLoading();
}
},
);
if (snapshot.hasError) {
return Text("Error");
} else if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.all(5),
child: SingleChildScrollView(
child: Wrap(
spacing: 5,
runSpacing: 5,
alignment: WrapAlignment.start,
children: snapshot.data!
.map((e) => ActorTile(actor: e))
.toList(growable: false),
),
),
);
} else {
return ScreenLoading();
}
},
),
drawer: MyDrawer());
}
}

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:openmediacentermobile/preview/tag_tile.dart';
import '../DrawerPage.dart';
import '../screen_loading.dart';
import '../api/api.dart';
@ -33,35 +34,40 @@ class _CategorieScreenState extends State<CategorieScreen> {
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _categories,
builder: (context, AsyncSnapshot<List<Tag>> snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return ScreenLoading();
}
return Scaffold(
appBar: AppBar(
title: Text("Temp"),
),
body: FutureBuilder(
future: _categories,
builder: (context, AsyncSnapshot<List<Tag>> snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return ScreenLoading();
}
if (snapshot.hasError) {
return Text("Error");
} else if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.all(5),
child: SingleChildScrollView(
child: Wrap(
spacing: 5,
runSpacing: 5,
alignment: WrapAlignment.start,
children: snapshot.data!
.map((e) => TagTile(
tag: e,
))
.toList(growable: false),
),
),
);
} else {
return ScreenLoading();
}
},
);
if (snapshot.hasError) {
return Text("Error");
} else if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.all(5),
child: SingleChildScrollView(
child: Wrap(
spacing: 5,
runSpacing: 5,
alignment: WrapAlignment.start,
children: snapshot.data!
.map((e) => TagTile(
tag: e,
))
.toList(growable: false),
),
),
);
} else {
return ScreenLoading();
}
},
),
drawer: MyDrawer());
}
}

View File

@ -1,6 +1,9 @@
import 'package:flutter/material.dart';
import '../DrawerPage.dart';
import '../api/token.dart';
import '../db/database.dart';
import '../login/logincontext.dart';
class SettingsScreen extends StatefulWidget {
const SettingsScreen({Key? key}) : super(key: key);
@ -15,33 +18,37 @@ class _SettingsScreenState extends State<SettingsScreen> {
@override
void initState() {
super.initState();
loadDBSize();
}
void loadDBSize() async {
final int cnt = (await Db().db().rawQuery("pragma page_count;"))[0]
["page_count"] as int;
final int pagesize =
(await Db().db().rawQuery("pragma page_size;"))[0]["page_size"] as int;
setState(() {
dbsize = cnt * pagesize;
});
Db().getDbSize().then((v) => setState(() {
dbsize = v;
}));
}
@override
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: () async {
await Db().db().delete("previews");
// shrink the db file size
await Db().db().execute("VACUUM");
loadDBSize();
},
child: const Text("Delete cache!")),
Text("db size: ${dbsize / 1024} kb")
],
);
final loginCtx = LoginContext.of(context);
return Scaffold(
appBar: AppBar(
title: Text("Temp"),
),
body: Column(
children: [
ElevatedButton(
onPressed: () async {
await Db().clear();
Db().getDbSize().then((v) => setState(() {
dbsize = v;
}));
},
child: const Text("Delete cache!")),
Text("db size: ${dbsize / 1024} kb"),
ElevatedButton(onPressed: () {
loginCtx.onLoggin(false);
Token.getInstance().setToken("", "");
Db().clear();
}, child: Text("Logout"))
],
),
drawer: MyDrawer());
}
}

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:math';
import 'package:flutter/material.dart';
import '../DrawerPage.dart';
import '../preview/preview_grid.dart';
import '../api/api.dart';
import '../platform.dart';
@ -30,27 +31,33 @@ class _ShuffleScreenState extends State<ShuffleScreen> {
@override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
return PreviewGrid(
videoLoader: () {
return loadData((isTV() ? width ~/ 200 : width ~/ 275) * 2);
},
footerBuilder: (state) => Column(
children: [
const SizedBox(
height: 25,
return Scaffold(
appBar: AppBar(
title: Text("Temp"),
),
body: PreviewGrid(
videoLoader: () {
return loadData((isTV() ? width ~/ 200 : width ~/ 275) * 2);
},
footerBuilder: (state) => Column(
children: [
const SizedBox(
height: 25,
),
TextButton.icon(
onPressed: () {
state.loadData();
},
icon: const Icon(Icons.update),
label: const Text("Shuffle"),
),
const SizedBox(
height: 25,
),
],
),
TextButton.icon(
onPressed: () {
state.loadData();
},
icon: const Icon(Icons.update),
label: const Text("Shuffle"),
),
const SizedBox(
height: 25,
),
],
),
);
),
drawer: MyDrawer());
}
}

View File

@ -1,6 +1,7 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:openmediacentermobile/DrawerPage.dart';
import '../api/api.dart';
import '../log/log.dart';
@ -36,8 +37,13 @@ class VideoFeedState extends State<VideoFeed> {
double width = MediaQuery.of(context).size.width;
Log.d(width);
return PreviewGrid(
videoLoader: () => loadData(),
);
return Scaffold(
appBar: AppBar(
title: Text(widget.tag?.tagName ?? "OpenMediaCenter"),
),
body: PreviewGrid(
videoLoader: () => loadData(),
),
drawer: widget.tag == null ? MyDrawer() : null);
}
}

View File

@ -14,10 +14,7 @@ class TagTile extends StatelessWidget {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Scaffold(
appBar: AppBar(title: Text(tag.tagName)),
body: VideoFeed(tag: tag),
),
builder: (context) => VideoFeed(tag: tag),
),
);
},

View File

@ -7,6 +7,7 @@ import 'package:openmediacentermobile/types/video_data.dart';
import 'package:openmediacentermobile/preview/actor_tile.dart';
import '../api/api.dart';
import '../log/log.dart';
import '../types/actor.dart';
class InfoView extends StatefulWidget {
@ -51,11 +52,21 @@ class _InfoViewState extends State<InfoView> {
} else if (snapshot.hasData) {
final actors = snapshot.data;
return Padding(
padding: EdgeInsets.only(left: 10, right: 10, top: 30),
padding: EdgeInsets.only(left: 10, right: 10, top: 60),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Likes: ${widget.vdata.likes}"),
IconButton(onPressed: () async {
final data = await API
.query("video", "addLike", {'MovieId': widget.vdata.movieId});
final d = jsonDecode(data);
if (d["result"] != 'success') {
Log.w(d);
}
// bit hacky but it works
widget.vdata.likes += 1;
}, icon: Icon(Icons.thumb_up)),
Text("Quality: ${widget.vdata.quality}"),
Text("Length: ${widget.vdata.length}sec"),
Text("Actors:"),

View File

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../api/api.dart';
import '../api/token.dart';
@ -64,9 +65,9 @@ class _VideoScreenState extends State<VideoScreen> {
@override
void dispose() {
super.dispose();
_controller.dispose();
_appBarTimer?.cancel();
super.dispose();
}
void _setAppBarTimer() {