From 7f039396aacdfb01e2eaa966fca6fbcff8bced70 Mon Sep 17 00:00:00 2001 From: lukas-heiligenbrunner Date: Thu, 1 Dec 2022 00:50:55 +0100 Subject: [PATCH] save token and settings also in sqlite db --- lib/api/api.dart | 3 +- lib/api/token.dart | 57 +----- lib/db/database.dart | 27 ++- lib/db/settings_db.dart | 51 ++++++ lib/dialog/add_actor_dialog.dart | 3 +- lib/dialog/add_tag_dialog.dart | 3 +- lib/login/login_container.dart | 2 +- lib/login/login_screen.dart | 15 +- lib/main.dart | 2 +- lib/navigation/settings_screen.dart | 8 +- lib/preview/preview_grid.dart | 46 ++--- lib/preview/preview_tile.dart | 2 +- lib/video_screen/videoscreen.dart | 14 +- linux/flutter/generated_plugin_registrant.cc | 12 -- linux/flutter/generated_plugins.cmake | 3 - pubspec.lock | 179 +------------------ pubspec.yaml | 5 +- 17 files changed, 142 insertions(+), 290 deletions(-) create mode 100644 lib/db/settings_db.dart diff --git a/lib/api/api.dart b/lib/api/api.dart index 0d5edeb..db17183 100644 --- a/lib/api/api.dart +++ b/lib/api/api.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:http/http.dart' as http; + import 'token.dart'; class TokenException implements Exception { @@ -11,7 +12,7 @@ class TokenException implements Exception { class API { static Future query( String apinode, String action, Object payload) async { - final t = await Token.getInstance().getToken(); + final t = await getToken(); if (t != null) { final resp = await http.post( Uri.parse(t.domain + '/api/$apinode/$action'), diff --git a/lib/api/token.dart b/lib/api/token.dart index 0fed2bb..a0c76b6 100644 --- a/lib/api/token.dart +++ b/lib/api/token.dart @@ -1,60 +1,19 @@ import 'dart:async'; -import 'package:flutter/widgets.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; - -import '../log/log.dart'; +import 'package:openmediacentermobile/db/settings_db.dart'; class TokenT { String token; String domain; - String videoPath; - TokenT(this.token, this.domain, this.videoPath); + TokenT(this.token, this.domain); } -class Token { - static final Token _token = Token._(); - final _storage = const FlutterSecureStorage(); - - String _tokenval = ""; - String _domain = ""; - String _vPath = ""; - - static Token getInstance() { - return _token; +Future getToken() async { + final settings = await SettingsDB.getInstance().getSettings(); + if (settings.token == "" || settings.domain == "") { + return null; + } else { + return TokenT(settings.token, settings.domain); } - - Future getToken() async { - if (_tokenval == "" || _domain == "" || _vPath == "") { - Log.d("reading token store"); - WidgetsFlutterBinding.ensureInitialized(); - final token = await _storage.read(key: 'jwt'); - final domain = await _storage.read(key: 'domain'); - final vPath = await _storage.read(key: 'videoPath'); - - // check if value is defined in phone store - if (token != null && domain != null && vPath != null) { - _tokenval = token; - _domain = domain; - return TokenT(token, domain, vPath); - } else { - Log.d("no token defined"); - return null; - } - } else { - return TokenT(_tokenval, _domain, _vPath); - } - } - - void setToken(String token, String domain, String videoPath) { - _tokenval = token; - _domain = domain; - _vPath = videoPath; - _storage.write(key: 'jwt', value: token); - _storage.write(key: 'domain', value: domain); - _storage.write(key: 'videoPath', value: videoPath); - } - - Token._(); } diff --git a/lib/db/database.dart b/lib/db/database.dart index e3f9d58..224509a 100644 --- a/lib/db/database.dart +++ b/lib/db/database.dart @@ -8,7 +8,7 @@ import '../log/log.dart'; class Db { late Database _db; - void init() async { + Future init() async { if (kIsWeb) { Log.i("Database on web is not supported"); return; @@ -27,13 +27,20 @@ class Db { _db = await openDatabase( dbpath, onCreate: (db, version) { - return db.execute( - 'CREATE TABLE previews(id INTEGER PRIMARY KEY, thumbnail BLOB)', + final batch = db.batch(); + batch.execute( + 'CREATE TABLE previews(id INTEGER PRIMARY KEY, thumbnail BLOB);', ); + batch.execute( + 'CREATE TABLE settings(domain TEXT, token TEXT, videopath TEXT, tilewidth INTEGER);', + ); + batch.insert("settings", + {"domain": "", "token": "", "videopath": "", "tilewidth": 0}); + return batch.commit(); }, // Set the version. This executes the onCreate function and provides a // path to perform database upgrades and downgrades. - version: 1, + version: 2, ); } @@ -46,10 +53,16 @@ class Db { /// get db size in bytes Future getDbSize() async { - final int cnt = (await Db().db().rawQuery("pragma page_count;"))[0] - ["page_count"] as int; + final batch = _db.batch(); + batch.rawQuery("pragma page_count;"); + batch.rawQuery("pragma page_size;"); + final result = (await batch.commit(noResult: false)); + print(result); + + final int cnt = + ((result[0] as List>)[0]["page_count"] as int); final int pagesize = - (await Db().db().rawQuery("pragma page_size;"))[0]["page_size"] as int; + (result[1] as List>)[0]["page_size"] as int; return cnt * pagesize; } diff --git a/lib/db/settings_db.dart b/lib/db/settings_db.dart new file mode 100644 index 0000000..3ba0b02 --- /dev/null +++ b/lib/db/settings_db.dart @@ -0,0 +1,51 @@ +import 'database.dart'; + +class SettingsT { + String domain; + String token; + String videopath; + int tilewidth; + + SettingsT(this.domain, this.token, this.videopath, this.tilewidth); +} + +class SettingsDB { + static final SettingsDB _instance = SettingsDB._(); + + SettingsT _settings = SettingsT("", "", "", 0); + bool _initialized = false; + + Future getSettings() async { + if (!_initialized) { + final result = (await Db().db().query("settings", + where: "1", + columns: ["domain", "token", "videopath", "tilewidth"])) + .first; + + _settings = SettingsT( + result["domain"] as String, + result["token"] as String, + result["videopath"] as String, + result["tilewidth"] as int); + } + return _settings; + } + + Future setSettings(SettingsT settings) async { + await Db().db().update( + "settings", + { + "domain": settings.domain, + "token": settings.token, + "videopath": settings.videopath, + "tilewidth": settings.tilewidth + }, + where: "1"); + } + + static SettingsDB getInstance() { + return _instance; + } + + SettingsDB._(); +} diff --git a/lib/dialog/add_actor_dialog.dart b/lib/dialog/add_actor_dialog.dart index 4a12d0e..29d8ff4 100644 --- a/lib/dialog/add_actor_dialog.dart +++ b/lib/dialog/add_actor_dialog.dart @@ -32,7 +32,8 @@ class _AddActorDialogState extends State { return Text("Error"); } else if (snapshot.hasData) { final data = snapshot.data! as List; - data.sort((a, b) => a.name.compareTo(b.name)); + data.sort((a, b) => + a.name.toLowerCase().compareTo(b.name.toLowerCase())); return Column( mainAxisSize: MainAxisSize.min, children: data diff --git a/lib/dialog/add_tag_dialog.dart b/lib/dialog/add_tag_dialog.dart index 3990329..978cd71 100644 --- a/lib/dialog/add_tag_dialog.dart +++ b/lib/dialog/add_tag_dialog.dart @@ -33,7 +33,8 @@ class _AddTagDialogState extends State { } else if (snapshot.hasData) { final data = snapshot.data! as List; data.sort( - (a, b) => a.tagName.compareTo(b.tagName), + (a, b) => + a.tagName.toLowerCase().compareTo(b.tagName.toLowerCase()), ); return Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/login/login_container.dart b/lib/login/login_container.dart index fcfb2af..4486958 100644 --- a/lib/login/login_container.dart +++ b/lib/login/login_container.dart @@ -23,7 +23,7 @@ class _LoginContainerState extends State { } void _init() async { - final token = await Token.getInstance().getToken(); + final token = await getToken(); Log.i("The token value is $token"); if (token != null) { setState(() { diff --git a/lib/login/login_screen.dart b/lib/login/login_screen.dart index ac108cc..6cef2cf 100644 --- a/lib/login/login_screen.dart +++ b/lib/login/login_screen.dart @@ -3,8 +3,9 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; + import '../api/settings_api.dart'; -import '../api/token.dart'; +import '../db/settings_db.dart'; import '../log/log.dart'; import 'login_context.dart'; @@ -44,11 +45,13 @@ class _LoginScreenState extends State { final json = jsonDecode(resp.body); final token = json["Token"]; - // todo bit hacky - Token.getInstance().setToken(token, domain, "temp"); - // we need to call this twice because we need for the loadInitialData an api token - Token.getInstance() - .setToken(token, domain, (await loadInitialData()).videoPath); + SettingsT settings = await SettingsDB.getInstance().getSettings(); + settings.domain = domain; + settings.token = token; + SettingsDB.getInstance().setSettings(settings); + // we need two steps here because we need an authenticated api call for the videopath + settings.videopath = (await loadInitialData()).videoPath; + SettingsDB.getInstance().setSettings(settings); LoginContext.of(context).onLoggin(true); return ""; diff --git a/lib/main.dart b/lib/main.dart index 2d39da8..2770d61 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -15,7 +15,7 @@ void main() async { } else { await loadDeviceInfo(); } - Db().init(); + await Db().init(); runApp(Shortcuts(shortcuts: { LogicalKeySet(LogicalKeyboardKey.select): ActivateIntent(), diff --git a/lib/navigation/settings_screen.dart b/lib/navigation/settings_screen.dart index cc65f5e..4dabcd6 100644 --- a/lib/navigation/settings_screen.dart +++ b/lib/navigation/settings_screen.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; -import '../utils/file_formatter.dart'; +import 'package:openmediacentermobile/db/settings_db.dart'; import '../api/token.dart'; import '../db/database.dart'; import '../drawer/my_drawer.dart'; import '../login/login_context.dart'; +import '../utils/file_formatter.dart'; class SettingsScreen extends StatefulWidget { const SettingsScreen({Key? key}) : super(key: key); @@ -24,7 +25,7 @@ class _SettingsScreenState extends State { dbsize = v; })); - Token.getInstance().getToken().then((value) => setState(() { + getToken().then((value) => setState(() { serverUrl = value?.domain ?? "unknown"; })); } @@ -53,7 +54,8 @@ class _SettingsScreenState extends State { ElevatedButton( onPressed: () { loginCtx.onLoggin(false); - Token.getInstance().setToken("", "", ""); + SettingsDB.getInstance() + .setSettings(SettingsT("", "", "", 0)); Db().clear(); }, child: Text("Logout")) diff --git a/lib/preview/preview_grid.dart b/lib/preview/preview_grid.dart index dc9e389..5065e95 100644 --- a/lib/preview/preview_grid.dart +++ b/lib/preview/preview_grid.dart @@ -3,9 +3,9 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; -import '../utils/platform.dart'; import '../screen_loading.dart'; import '../types/video.dart'; +import '../utils/platform.dart'; import 'preview_tile.dart'; class PreviewGrid extends StatefulWidget { @@ -78,13 +78,13 @@ class _PreviewGridState extends State { Widget _mainGrid(List data, double width) { return Stack( children: [ - Column( - children: [ - if (widget.headerBuilder != null) widget.headerBuilder!(this), - data.length > 0 - ? Expanded( - child: Container( - color: Color(0xff999999), + Container( + color: Color(0xff999999), + child: Column( + children: [ + if (widget.headerBuilder != null) widget.headerBuilder!(this), + data.length > 0 + ? Expanded( child: MasonryGridView.count( // every tile should be at max 330 pixels long... crossAxisCount: isTV() ? width ~/ 200 : width ~/ 275, @@ -109,22 +109,22 @@ class _PreviewGridState extends State { ); }, ), + ) + : Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + height: 32, + ), + Icon(Icons.warning_amber, size: 52), + Text("no item available") + ], + ), ), - ) - : Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox( - height: 32, - ), - Icon(Icons.warning_amber, size: 52), - Text("no item available") - ], - ), - ), - if (widget.footerBuilder != null) widget.footerBuilder!(this), - ], + if (widget.footerBuilder != null) widget.footerBuilder!(this), + ], + ), ), if (_previewImage != null) ..._buildPreviewImage(), ], diff --git a/lib/preview/preview_tile.dart b/lib/preview/preview_tile.dart index c517e78..5c66bde 100644 --- a/lib/preview/preview_tile.dart +++ b/lib/preview/preview_tile.dart @@ -5,8 +5,8 @@ import 'package:sqflite/sqflite.dart'; import '../api/video_api.dart'; import '../db/database.dart'; import '../log/log.dart'; -import '../utils/platform.dart'; import '../types/video.dart'; +import '../utils/platform.dart'; import '../video_screen/videoscreen.dart'; class PreviewTile extends StatefulWidget { diff --git a/lib/video_screen/videoscreen.dart b/lib/video_screen/videoscreen.dart index 0dd4832..2326d60 100644 --- a/lib/video_screen/videoscreen.dart +++ b/lib/video_screen/videoscreen.dart @@ -1,14 +1,14 @@ import 'dart:async'; -import 'package:flutter/material.dart'; -import '../api/token.dart'; +import 'package:flutter/material.dart'; +import 'package:openmediacentermobile/db/settings_db.dart'; + import '../api/video_api.dart'; -import '../utils/platform.dart'; import '../screen_loading.dart'; import '../types/video.dart'; import '../types/video_data.dart'; +import '../utils/platform.dart'; import 'info_view.dart'; - import 'videoscreen_desktop.dart' if (dart.library.html) 'videoscreen_mobile.dart'; import 'videoscreen_mobile.dart'; @@ -34,10 +34,8 @@ class _VideoScreenState extends State { void initPlayer() async { final videodata = await _videoData; - final token = await Token.getInstance().getToken(); - if (token == null) return; - - final path = token.domain + token.videoPath + videodata.movieUrl; + final settings = await SettingsDB.getInstance().getSettings(); + final path = settings.domain + settings.videopath + videodata.movieUrl; url = path; } diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 19daffd..0e8ad7e 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,21 +7,9 @@ #include "generated_plugin_registrant.h" #include -#include -#include -#include void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) dart_vlc_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "DartVlcPlugin"); dart_vlc_plugin_register_with_registrar(dart_vlc_registrar); - g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); - flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); - g_autoptr(FlPluginRegistrar) screen_retriever_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); - screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); - g_autoptr(FlPluginRegistrar) window_manager_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin"); - window_manager_plugin_register_with_registrar(window_manager_registrar); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 3ee7e08..468f335 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,9 +4,6 @@ list(APPEND FLUTTER_PLUGIN_LIST dart_vlc - flutter_secure_storage_linux - screen_retriever - window_manager ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/pubspec.lock b/pubspec.lock index d3a2e32..b7736d4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -35,7 +35,7 @@ packages: name: chewie url: "https://pub.dartlang.org" source: hosted - version: "1.3.5" + version: "1.3.6" clock: dependency: transitive description: @@ -70,56 +70,28 @@ packages: name: dart_vlc url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.4.0" dart_vlc_ffi: dependency: transitive description: name: dart_vlc_ffi url: "https://pub.dartlang.org" source: hosted - version: "0.1.8" + version: "0.2.0+1" device_info_plus: dependency: "direct main" description: name: device_info_plus url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" - device_info_plus_linux: - dependency: transitive - description: - name: device_info_plus_linux - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - device_info_plus_macos: - dependency: transitive - description: - name: device_info_plus_macos - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.3" + version: "8.0.0" device_info_plus_platform_interface: dependency: transitive description: name: device_info_plus_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.6.1" - device_info_plus_web: - dependency: transitive - description: - name: device_info_plus_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - device_info_plus_windows: - dependency: transitive - description: - name: device_info_plus_windows - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" + version: "7.0.0" fake_async: dependency: transitive description: @@ -133,7 +105,7 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" + version: "2.0.1" file: dependency: transitive description: @@ -153,55 +125,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" - flutter_native_view: - dependency: transitive - description: - name: flutter_native_view - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.2" - flutter_secure_storage: - dependency: "direct main" - description: - name: flutter_secure_storage - url: "https://pub.dartlang.org" - source: hosted - version: "6.0.0" - flutter_secure_storage_linux: - dependency: transitive - description: - name: flutter_secure_storage_linux - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - flutter_secure_storage_macos: - dependency: transitive - description: - name: flutter_secure_storage_macos - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - flutter_secure_storage_platform_interface: - dependency: transitive - description: - name: flutter_secure_storage_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" - flutter_secure_storage_web: - dependency: transitive - description: - name: flutter_secure_storage_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - flutter_secure_storage_windows: - dependency: transitive - description: - name: flutter_secure_storage_windows - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" flutter_staggered_grid_view: dependency: "direct main" description: @@ -296,62 +219,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.2" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.21" - path_provider_ios: - dependency: transitive - description: - name: path_provider_ios - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.7" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.6" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.7" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" plugin_platform_interface: dependency: transitive description: @@ -359,13 +226,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.3" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.4" provider: dependency: transitive description: @@ -373,13 +233,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.0.4" - screen_retriever: - dependency: transitive - description: - name: screen_retriever - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.4" sky_engine: dependency: transitive description: flutter @@ -482,7 +335,7 @@ packages: name: video_player url: "https://pub.dartlang.org" source: hosted - version: "2.4.7" + version: "2.4.8" video_player_android: dependency: transitive description: @@ -545,28 +398,14 @@ packages: name: wakelock_windows url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.2.1" win32: dependency: transitive description: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.6.1" - window_manager: - dependency: transitive - description: - name: window_manager - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.7" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" + version: "3.1.2" sdks: dart: ">=2.18.0 <3.0.0" flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 3762d46..ba2ff94 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,12 +34,11 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 - flutter_secure_storage: ^6.0.0 logger: ^1.1.0 http: ^0.13.4 flutter_staggered_grid_view: ^0.6.1 - dart_vlc: ^0.3.0 - device_info_plus: ^4.0.0 + dart_vlc: ^0.4.0 + device_info_plus: ^8.0.0 video_player: ^2.3.0 chewie: ^1.3.2 sqflite: ^2.0.3+1