mirror of
https://github.com/jagandeepbrar/lunasea.git
synced 2026-08-31 04:32:32 +00:00
(feat): Implemented Overseerr core architecture, Added platform checks for Firebase, Added module flagging (#425)
This commit is contained in:
Binary file not shown.
@@ -4,6 +4,7 @@ export 'core/extensions.dart';
|
||||
export 'core/firebase.dart';
|
||||
export 'core/mixins.dart';
|
||||
export 'core/models.dart';
|
||||
export 'core/modules.dart';
|
||||
export 'core/pages.dart';
|
||||
export 'core/router.dart';
|
||||
export 'core/state.dart';
|
||||
|
||||
@@ -24,18 +24,15 @@ class Database {
|
||||
|
||||
/// Registers all necessary object adapters for Hive.
|
||||
void _registerAdapters() {
|
||||
//General
|
||||
LunaDatabase().registerAdapters();
|
||||
DashboardDatabase().registerAdapters();
|
||||
SearchDatabase().registerAdapters();
|
||||
//Automation
|
||||
LidarrDatabase().registerAdapters();
|
||||
RadarrDatabase().registerAdapters();
|
||||
SonarrDatabase().registerAdapters();
|
||||
//Clients
|
||||
NZBGetDatabase().registerAdapters();
|
||||
SABnzbdDatabase().registerAdapters();
|
||||
//Monitoring
|
||||
OverseerrDatabase().registerAdapters();
|
||||
TautulliDatabase().registerAdapters();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ class LunaDatabase extends LunaModuleDatabase {
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_NZBGET:
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SABNZBD:
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_OMBI:
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_OVERSEERR:
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_TAUTULLI:
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SEARCH:
|
||||
case LunaDatabaseValue.USE_24_HOUR_TIME: data[value.key] = value.data; break;
|
||||
@@ -59,6 +60,7 @@ class LunaDatabase extends LunaModuleDatabase {
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SONARR:
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_NZBGET:
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SABNZBD:
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_OVERSEERR:
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_TAUTULLI:
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_OMBI:
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SEARCH:
|
||||
@@ -82,6 +84,7 @@ class LunaDatabase extends LunaModuleDatabase {
|
||||
case 'LUNASEA_QUICK_ACTIONS_NZBGET': return LunaDatabaseValue.QUICK_ACTIONS_NZBGET;
|
||||
case 'LUNASEA_QUICK_ACTIONS_SABNZBD': return LunaDatabaseValue.QUICK_ACTIONS_SABNZBD;
|
||||
case 'LUNASEA_QUICK_ACTIONS_OMBI': return LunaDatabaseValue.QUICK_ACTIONS_OMBI;
|
||||
case 'LUNASEA_QUICK_ACTIONS_OVERSEERR': return LunaDatabaseValue.QUICK_ACTIONS_OVERSEERR;
|
||||
case 'LUNASEA_QUICK_ACTIONS_TAUTULLI': return LunaDatabaseValue.QUICK_ACTIONS_TAUTULLI;
|
||||
case 'LUNASEA_QUICK_ACTIONS_SEARCH': return LunaDatabaseValue.QUICK_ACTIONS_SEARCH;
|
||||
case 'LUNASEA_USE_24_HOUR_TIME': return LunaDatabaseValue.USE_24_HOUR_TIME;
|
||||
@@ -104,6 +107,7 @@ enum LunaDatabaseValue {
|
||||
QUICK_ACTIONS_NZBGET,
|
||||
QUICK_ACTIONS_SABNZBD,
|
||||
QUICK_ACTIONS_OMBI,
|
||||
QUICK_ACTIONS_OVERSEERR,
|
||||
QUICK_ACTIONS_TAUTULLI,
|
||||
QUICK_ACTIONS_SEARCH,
|
||||
USE_24_HOUR_TIME,
|
||||
@@ -124,6 +128,7 @@ extension LunaDatabaseValueExtension on LunaDatabaseValue {
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SONARR: return 'LUNASEA_QUICK_ACTIONS_SONARR';
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_NZBGET: return 'LUNASEA_QUICK_ACTIONS_NZBGET';
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SABNZBD: return 'LUNASEA_QUICK_ACTIONS_SABNZBD';
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_OVERSEERR: return 'LUNASEA_QUICK_ACTIONS_OVERSEERR';
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_TAUTULLI: return 'LUNASEA_QUICK_ACTIONS_TAUTULLI';
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_OMBI: return 'LUNASEA_QUICK_ACTIONS_OMBI';
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SEARCH: return 'LUNASEA_QUICK_ACTIONS_SEARCH';
|
||||
@@ -147,6 +152,7 @@ extension LunaDatabaseValueExtension on LunaDatabaseValue {
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SONARR: return box.get(this.key, defaultValue: false);
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_NZBGET: return box.get(this.key, defaultValue: false);
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SABNZBD: return box.get(this.key, defaultValue: false);
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_OVERSEERR: return box.get(this.key, defaultValue: false);
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_TAUTULLI: return box.get(this.key, defaultValue: false);
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_OMBI: return box.get(this.key, defaultValue: false);
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SEARCH: return box.get(this.key, defaultValue: false);
|
||||
@@ -171,6 +177,7 @@ extension LunaDatabaseValueExtension on LunaDatabaseValue {
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_NZBGET: if(value.runtimeType == bool) box.put(this.key, value); return;
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SABNZBD: if(value.runtimeType == bool) box.put(this.key, value); return;
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_OMBI: if(value.runtimeType == bool) box.put(this.key, value); return;
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_OVERSEERR: if(value.runtimeType == bool) box.put(this.key, value); return;
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_TAUTULLI: if(value.runtimeType == bool) box.put(this.key, value); return;
|
||||
case LunaDatabaseValue.QUICK_ACTIONS_SEARCH: if(value.runtimeType == bool) box.put(this.key, value); return;
|
||||
case LunaDatabaseValue.USE_24_HOUR_TIME: if(value.runtimeType == bool) box.put(this.key, value); return;
|
||||
|
||||
@@ -6,7 +6,9 @@ import 'package:lunasea/core.dart';
|
||||
|
||||
class LunaFirebaseAnalytics {
|
||||
/// Returns true if Firebase Analytics is compatible with this build system/platform.
|
||||
static bool get isPlatformCompatible => !Platform.isLinux && !Platform.isMacOS && !Platform.isWindows;
|
||||
static bool get isPlatformCompatible {
|
||||
return LunaFirebase.isPlatformCompatible && !Platform.isLinux && !Platform.isMacOS && !Platform.isWindows;
|
||||
}
|
||||
|
||||
/// Returns an instance of [FirebaseAnalytics].
|
||||
///
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
|
||||
class LunaFirebase {
|
||||
@@ -6,6 +8,9 @@ class LunaFirebase {
|
||||
/// Throws an error if [LunaFirebase.initialize] has not been called.
|
||||
static FirebaseApp get instance => Firebase.app();
|
||||
|
||||
/// Returns true if Firebase in its entirety is compatible with this build system/platform.
|
||||
static bool get isPlatformCompatible => Platform.isIOS || Platform.isAndroid || Platform.isMacOS;
|
||||
|
||||
/// Initialize Firebase and configuration.
|
||||
///
|
||||
/// This must be called before anything accesses Firebase services, or an exception will be thrown.
|
||||
|
||||
@@ -5,7 +5,9 @@ import 'package:lunasea/core.dart';
|
||||
|
||||
class LunaFirebaseCrashlytics {
|
||||
/// Returns true if Firebase Analytics is compatible with this build system/platform.
|
||||
static bool get isPlatformCompatible => !Platform.isLinux && !Platform.isMacOS && !Platform.isWindows;
|
||||
static bool get isPlatformCompatible {
|
||||
return LunaFirebase.isPlatformCompatible && !Platform.isLinux && !Platform.isMacOS && !Platform.isWindows;
|
||||
}
|
||||
|
||||
/// Returns an instance of [FirebaseCrashlytics].
|
||||
///
|
||||
|
||||
@@ -51,6 +51,11 @@ class ProfileHiveObject extends HiveObject {
|
||||
ombiHost: '',
|
||||
ombiKey: '',
|
||||
ombiHeaders: {},
|
||||
//Overseerr
|
||||
overseerrEnabled: false,
|
||||
overseerrHost: '',
|
||||
overseerrKey: '',
|
||||
overseerrHeaders: {},
|
||||
);
|
||||
|
||||
/// Create a new [ProfileHiveObject] from another [ProfileHiveObject] (deep-copy).
|
||||
@@ -97,6 +102,11 @@ class ProfileHiveObject extends HiveObject {
|
||||
ombiHost: profile.ombiHost,
|
||||
ombiKey: profile.ombiKey,
|
||||
ombiHeaders: profile.ombiHeaders,
|
||||
//Overseerr
|
||||
overseerrEnabled: profile.overseerrEnabled,
|
||||
overseerrHost: profile.overseerrHost,
|
||||
overseerrKey: profile.overseerrKey,
|
||||
overseerrHeaders: profile.overseerrHeaders,
|
||||
);
|
||||
|
||||
/// Create a new [ProfileHiveObject] from a map where the keys map 1-to-1.
|
||||
@@ -146,6 +156,11 @@ class ProfileHiveObject extends HiveObject {
|
||||
ombiHost: profile['ombiHost'] ?? '',
|
||||
ombiKey: profile['ombiKey'] ?? '',
|
||||
ombiHeaders: profile['ombiHeaders'] ?? {},
|
||||
//Overseerr
|
||||
overseerrEnabled: profile['overseerrEnabled'] ?? false,
|
||||
overseerrHost: profile['overseerrHost'] ?? '',
|
||||
overseerrKey: profile['overseerrKey'] ?? '',
|
||||
overseerrHeaders: profile['overseerrHeaders'] ?? {},
|
||||
);
|
||||
|
||||
|
||||
@@ -192,6 +207,11 @@ class ProfileHiveObject extends HiveObject {
|
||||
@required this.ombiHost,
|
||||
@required this.ombiKey,
|
||||
@required this.ombiHeaders,
|
||||
//Overseerr
|
||||
@required this.overseerrEnabled,
|
||||
@required this.overseerrHost,
|
||||
@required this.overseerrKey,
|
||||
@required this.overseerrHeaders,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -241,6 +261,11 @@ class ProfileHiveObject extends HiveObject {
|
||||
"ombiHost": ombiHost,
|
||||
"ombiKey": ombiKey,
|
||||
"ombiHeaders": ombiHeaders,
|
||||
//Overseerr
|
||||
"overseerrEnabled": overseerrEnabled,
|
||||
"overseerrHost": overseerrHost,
|
||||
"overseerrKey": overseerrKey,
|
||||
"overseerrHeaders": overseerrHeaders,
|
||||
};
|
||||
|
||||
//Lidarr
|
||||
@@ -385,6 +410,23 @@ class ProfileHiveObject extends HiveObject {
|
||||
'headers': ombiHeaders ?? {},
|
||||
};
|
||||
|
||||
//Overseerr
|
||||
@HiveField(40)
|
||||
bool overseerrEnabled;
|
||||
@HiveField(41)
|
||||
String overseerrHost;
|
||||
@HiveField(42)
|
||||
String overseerrKey;
|
||||
@HiveField(43)
|
||||
Map overseerrHeaders;
|
||||
|
||||
Map<String, dynamic> getOverseerr() => {
|
||||
'enabled': overseerrEnabled ?? false,
|
||||
'host': overseerrHost ?? '',
|
||||
'key': overseerrKey ?? '',
|
||||
'headers': overseerrHeaders ?? {},
|
||||
};
|
||||
|
||||
List<LunaModule> get enabledModules => [
|
||||
...enabledAutomationModules,
|
||||
...enabledClientModules,
|
||||
@@ -392,18 +434,19 @@ class ProfileHiveObject extends HiveObject {
|
||||
];
|
||||
|
||||
List<LunaModule> get enabledAutomationModules => [
|
||||
if(lidarrEnabled ?? false) LunaModule.LIDARR,
|
||||
if(radarrEnabled ?? false) LunaModule.RADARR,
|
||||
if(sonarrEnabled ?? false) LunaModule.SONARR,
|
||||
if(LunaModule.LIDARR.enabled && (lidarrEnabled ?? false)) LunaModule.LIDARR,
|
||||
if(LunaModule.RADARR.enabled && (radarrEnabled ?? false)) LunaModule.RADARR,
|
||||
if(LunaModule.SONARR.enabled && (sonarrEnabled ?? false)) LunaModule.SONARR,
|
||||
];
|
||||
|
||||
List<LunaModule> get enabledClientModules => [
|
||||
if(nzbgetEnabled ?? false) LunaModule.NZBGET,
|
||||
if(sabnzbdEnabled ?? false) LunaModule.SABNZBD,
|
||||
if(LunaModule.NZBGET.enabled && (nzbgetEnabled ?? false)) LunaModule.NZBGET,
|
||||
if(LunaModule.SABNZBD.enabled && (sabnzbdEnabled ?? false)) LunaModule.SABNZBD,
|
||||
];
|
||||
|
||||
List<LunaModule> get enabledMonitoringModules => [
|
||||
if(tautulliEnabled ?? false) LunaModule.TAUTULLI,
|
||||
if(LunaModule.OVERSEERR.enabled && (overseerrEnabled ?? false)) LunaModule.OVERSEERR,
|
||||
if(LunaModule.TAUTULLI.enabled && (tautulliEnabled ?? false)) LunaModule.TAUTULLI,
|
||||
];
|
||||
|
||||
bool get anyAutomationEnabled => enabledAutomationModules.isNotEmpty;
|
||||
|
||||
@@ -51,13 +51,17 @@ class ProfileHiveObjectAdapter extends TypeAdapter<ProfileHiveObject> {
|
||||
ombiHost: fields[37] as String,
|
||||
ombiKey: fields[38] as String,
|
||||
ombiHeaders: (fields[39] as Map)?.cast<dynamic, dynamic>(),
|
||||
overseerrEnabled: fields[40] as bool,
|
||||
overseerrHost: fields[41] as String,
|
||||
overseerrKey: fields[42] as String,
|
||||
overseerrHeaders: (fields[43] as Map)?.cast<dynamic, dynamic>(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, ProfileHiveObject obj) {
|
||||
writer
|
||||
..writeByte(34)
|
||||
..writeByte(38)
|
||||
..writeByte(0)
|
||||
..write(obj.lidarrEnabled)
|
||||
..writeByte(1)
|
||||
@@ -125,7 +129,15 @@ class ProfileHiveObjectAdapter extends TypeAdapter<ProfileHiveObject> {
|
||||
..writeByte(38)
|
||||
..write(obj.ombiKey)
|
||||
..writeByte(39)
|
||||
..write(obj.ombiHeaders);
|
||||
..write(obj.ombiHeaders)
|
||||
..writeByte(40)
|
||||
..write(obj.overseerrEnabled)
|
||||
..writeByte(41)
|
||||
..write(obj.overseerrHost)
|
||||
..writeByte(42)
|
||||
..write(obj.overseerrKey)
|
||||
..writeByte(43)
|
||||
..write(obj.overseerrHeaders);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/modules.dart';
|
||||
@@ -13,6 +14,7 @@ enum LunaModule {
|
||||
SETTINGS,
|
||||
SONARR,
|
||||
TAUTULLI,
|
||||
OVERSEERR,
|
||||
WAKE_ON_LAN,
|
||||
}
|
||||
|
||||
@@ -27,6 +29,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case 'search': return LunaModule.SEARCH;
|
||||
case 'settings': return LunaModule.SETTINGS;
|
||||
case 'sonarr': return LunaModule.SONARR;
|
||||
case 'overseerr': return LunaModule.OVERSEERR;
|
||||
case 'tautulli': return LunaModule.TAUTULLI;
|
||||
case 'wake_on_lan': return LunaModule.WAKE_ON_LAN;
|
||||
}
|
||||
@@ -43,6 +46,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case LunaModule.SEARCH: return 'search';
|
||||
case LunaModule.SETTINGS: return 'settings';
|
||||
case LunaModule.SONARR: return 'sonarr';
|
||||
case LunaModule.OVERSEERR: return 'overseerr';
|
||||
case LunaModule.TAUTULLI: return 'tautulli';
|
||||
case LunaModule.WAKE_ON_LAN: return 'wake_on_lan';
|
||||
}
|
||||
@@ -51,16 +55,19 @@ extension LunaModuleExtension on LunaModule {
|
||||
|
||||
bool get enabled {
|
||||
switch(this) {
|
||||
case LunaModule.DASHBOARD: return null;
|
||||
case LunaModule.LIDARR: return Database.currentProfileObject.lidarrEnabled ?? false;
|
||||
case LunaModule.NZBGET: return Database.currentProfileObject.nzbgetEnabled ?? false;
|
||||
case LunaModule.RADARR: return Database.currentProfileObject.radarrEnabled ?? false;
|
||||
case LunaModule.SABNZBD: return Database.currentProfileObject.sabnzbdEnabled ?? false;
|
||||
case LunaModule.SEARCH: return (Database.indexersBox.values?.length ?? 0) > 0;
|
||||
case LunaModule.SETTINGS: return null;
|
||||
case LunaModule.SONARR: return Database.currentProfileObject.sonarrEnabled ?? false;
|
||||
case LunaModule.TAUTULLI: return Database.currentProfileObject.tautulliEnabled ?? false;
|
||||
case LunaModule.WAKE_ON_LAN: return Database.currentProfileObject.wakeOnLANEnabled ?? false;
|
||||
// Always enabled
|
||||
case LunaModule.DASHBOARD: return true;
|
||||
case LunaModule.SETTINGS: return true;
|
||||
// Modules
|
||||
case LunaModule.SEARCH: return true;
|
||||
case LunaModule.WAKE_ON_LAN: return true;
|
||||
case LunaModule.LIDARR: return true;
|
||||
case LunaModule.RADARR: return true;
|
||||
case LunaModule.SONARR: return true;
|
||||
case LunaModule.NZBGET: return true;
|
||||
case LunaModule.SABNZBD: return true;
|
||||
case LunaModule.OVERSEERR: return kDebugMode;
|
||||
case LunaModule.TAUTULLI: return true;
|
||||
}
|
||||
throw Exception('Invalid LunaModule');
|
||||
}
|
||||
@@ -76,6 +83,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case LunaModule.SETTINGS: return 'lunasea.Settings'.tr();
|
||||
case LunaModule.SONARR: return 'Sonarr';
|
||||
case LunaModule.TAUTULLI: return 'Tautulli';
|
||||
case LunaModule.OVERSEERR: return 'Overseerr';
|
||||
case LunaModule.WAKE_ON_LAN: return 'Wake on LAN';
|
||||
}
|
||||
throw Exception('Invalid LunaModule');
|
||||
@@ -92,6 +100,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case LunaModule.SETTINGS: return SettingsHomeRouter().route();
|
||||
case LunaModule.SONARR: return SonarrHomeRouter().route();
|
||||
case LunaModule.TAUTULLI: return TautulliHomeRouter().route();
|
||||
case LunaModule.OVERSEERR: return OverseerrHomeRouter().route();
|
||||
case LunaModule.WAKE_ON_LAN: return null;
|
||||
}
|
||||
throw Exception('Invalid LunaModule');
|
||||
@@ -108,6 +117,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case LunaModule.SETTINGS: return LunaIcons.settings;
|
||||
case LunaModule.SONARR: return LunaIcons.television;
|
||||
case LunaModule.TAUTULLI: return LunaIcons.tautulli;
|
||||
case LunaModule.OVERSEERR: return LunaIcons.overseerr;
|
||||
case LunaModule.WAKE_ON_LAN: return Icons.settings_remote;
|
||||
}
|
||||
throw Exception('Invalid LunaModule');
|
||||
@@ -124,6 +134,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case LunaModule.SETTINGS: return LunaColours.accent;
|
||||
case LunaModule.SONARR: return Color(0xFF3FC6F4);
|
||||
case LunaModule.TAUTULLI: return Color(0xFFDBA23A);
|
||||
case LunaModule.OVERSEERR: return Color(0xFF6366F1);
|
||||
case LunaModule.WAKE_ON_LAN: return LunaColours.accent;
|
||||
}
|
||||
throw Exception('Invalid LunaModule');
|
||||
@@ -140,6 +151,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case LunaModule.SETTINGS: return null;
|
||||
case LunaModule.SONARR: return 'https://sonarr.tv';
|
||||
case LunaModule.TAUTULLI: return 'https://tautulli.com';
|
||||
case LunaModule.OVERSEERR: return 'https://overseerr.dev';
|
||||
case LunaModule.WAKE_ON_LAN: return null;
|
||||
}
|
||||
throw Exception('Invalid LunaModule');
|
||||
@@ -156,6 +168,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case LunaModule.SETTINGS: return null;
|
||||
case LunaModule.SONARR: return 'https://github.com/Sonarr/Sonarr';
|
||||
case LunaModule.TAUTULLI: return 'https://github.com/Tautulli/Tautulli';
|
||||
case LunaModule.OVERSEERR: return 'https://github.com/sct/overseerr';
|
||||
case LunaModule.WAKE_ON_LAN: return null;
|
||||
}
|
||||
throw Exception('Invalid LunaModule');
|
||||
@@ -172,6 +185,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case LunaModule.SETTINGS: return 'Configure LunaSea';
|
||||
case LunaModule.SONARR: return 'Manage Television Series';
|
||||
case LunaModule.TAUTULLI: return 'View Plex Activity';
|
||||
case LunaModule.OVERSEERR: return 'Manage Requests for New Content';
|
||||
case LunaModule.WAKE_ON_LAN: return 'Wake Your Machine';
|
||||
}
|
||||
throw Exception('Invalid LunaModule');
|
||||
@@ -188,6 +202,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case LunaModule.SETTINGS: return null;
|
||||
case LunaModule.SONARR: return 'Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new episodes of your favorite shows and will grab, sort and rename them. It can also be configured to automatically upgrade the quality of files already downloaded when a better quality format becomes available.';
|
||||
case LunaModule.TAUTULLI: return 'Tautulli is an application that you can run alongside your Plex Media Server to monitor activity and track various statistics. Most importantly, these statistics include what has been watched, who watched it, when and where they watched it, and how it was watched.';
|
||||
case LunaModule.OVERSEERR: return 'Overseerr is a free and open source software application for managing requests for your media library. It integrates with your existing services, such as Sonarr, Radarr, and Plex!';
|
||||
case LunaModule.WAKE_ON_LAN: return 'Wake on LAN is an industry standard protocol for waking computers up from a very low power mode remotely by sending a specially constructed packet to the machine.';
|
||||
}
|
||||
throw Exception('Invalid LunaModule');
|
||||
@@ -204,6 +219,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case LunaModule.SETTINGS: return ShortcutItem(type: key, localizedTitle: name);
|
||||
case LunaModule.SONARR: return ShortcutItem(type: key, localizedTitle: name);
|
||||
case LunaModule.TAUTULLI: return ShortcutItem(type: key, localizedTitle: name);
|
||||
case LunaModule.OVERSEERR: return ShortcutItem(type: key, localizedTitle: name);
|
||||
case LunaModule.WAKE_ON_LAN: return null;
|
||||
}
|
||||
throw Exception('Invalid LunaModule');
|
||||
@@ -219,6 +235,7 @@ extension LunaModuleExtension on LunaModule {
|
||||
case LunaModule.SEARCH: return;
|
||||
case LunaModule.SETTINGS: return;
|
||||
case LunaModule.SONARR: return SonarrWebhooks().handle(data);
|
||||
case LunaModule.OVERSEERR: return OverseerrWebhooks().handle(data);
|
||||
case LunaModule.TAUTULLI: return TautulliWebhooks().handle(data);
|
||||
case LunaModule.WAKE_ON_LAN: return;
|
||||
}
|
||||
@@ -11,34 +11,30 @@ class LunaRouter {
|
||||
void intialize() {
|
||||
router.notFoundHandler = Handler(handlerFunc: (context, params) => LunaInvalidRoute());
|
||||
DashboardRouter().defineAllRoutes(router);
|
||||
RadarrRouter().defineAllRoutes(router);
|
||||
SearchRouter().defineAllRoutes(router);
|
||||
SettingsRouter().defineAllRoutes(router);
|
||||
SonarrRouter().defineAllRoutes(router);
|
||||
TautulliRouter().defineAllRoutes(router);
|
||||
if(LunaModule.SEARCH.enabled) SearchRouter().defineAllRoutes(router);
|
||||
if(LunaModule.RADARR.enabled) RadarrRouter().defineAllRoutes(router);
|
||||
if(LunaModule.SONARR.enabled) SonarrRouter().defineAllRoutes(router);
|
||||
if(LunaModule.OVERSEERR.enabled) OverseerrRouter().defineAllRoutes(router);
|
||||
if(LunaModule.TAUTULLI.enabled) TautulliRouter().defineAllRoutes(router);
|
||||
}
|
||||
|
||||
/// **Will be removed when all module routers are integrated.**
|
||||
///
|
||||
/// Returns a map of all module routes.
|
||||
Map<String, WidgetBuilder> get routes => <String, WidgetBuilder> {
|
||||
..._lidarr,
|
||||
..._sabnzbd,
|
||||
..._nzbget,
|
||||
if(LunaModule.LIDARR.enabled) ..._lidarr,
|
||||
if(LunaModule.SABNZBD.enabled) ..._sabnzbd,
|
||||
if(LunaModule.NZBGET.enabled) ..._nzbget,
|
||||
};
|
||||
|
||||
Map<String, WidgetBuilder> get _lidarr => <String, WidgetBuilder> {
|
||||
// /lidarr
|
||||
Lidarr.ROUTE_NAME: (context) => Lidarr(),
|
||||
// /lidarr/add/*
|
||||
LidarrAddSearch.ROUTE_NAME: (context) => LidarrAddSearch(),
|
||||
LidarrAddDetails.ROUTE_NAME: (context) => LidarrAddDetails(),
|
||||
// /lidarr/edit/*
|
||||
LidarrEditArtist.ROUTE_NAME: (context) => LidarrEditArtist(),
|
||||
// /lidarr/details/*
|
||||
LidarrDetailsAlbum.ROUTE_NAME: (context) => LidarrDetailsAlbum(),
|
||||
LidarrDetailsArtist.ROUTE_NAME: (context) => LidarrDetailsArtist(),
|
||||
// /lidarr/search/*
|
||||
LidarrSearchResults.ROUTE_NAME: (context) => LidarrSearchResults(),
|
||||
};
|
||||
|
||||
|
||||
@@ -11,19 +11,16 @@ class LunaState {
|
||||
|
||||
/// Calls `.reset()` on all states which extend [LunaModuleState].
|
||||
static void reset(BuildContext context) {
|
||||
// General
|
||||
Provider.of<DashboardState>(context, listen: false)?.reset();
|
||||
Provider.of<SearchState>(context, listen: false)?.reset();
|
||||
Provider.of<SettingsState>(context, listen: false)?.reset();
|
||||
// Automation
|
||||
Provider.of<LidarrState>(context, listen: false)?.reset();
|
||||
Provider.of<RadarrState>(context, listen: false)?.reset();
|
||||
Provider.of<SonarrState>(context, listen: false)?.reset();
|
||||
// Clients
|
||||
Provider.of<NZBGetState>(context, listen: false)?.reset();
|
||||
Provider.of<SABnzbdState>(context, listen: false)?.reset();
|
||||
// Monitoring
|
||||
Provider.of<TautulliState>(context, listen: false)?.reset();
|
||||
context.read<DashboardState>()?.reset();
|
||||
context.read<SettingsState>()?.reset();
|
||||
if(LunaModule.SEARCH.enabled) context.read<SearchState>()?.reset();
|
||||
if(LunaModule.LIDARR.enabled) context.read<LidarrState>()?.reset();
|
||||
if(LunaModule.RADARR.enabled) context.read<RadarrState>()?.reset();
|
||||
if(LunaModule.SONARR.enabled) context.read<SonarrState>()?.reset();
|
||||
if(LunaModule.NZBGET.enabled) context.read<NZBGetState>()?.reset();
|
||||
if(LunaModule.SABNZBD.enabled) context.read<SABnzbdState>()?.reset();
|
||||
if(LunaModule.OVERSEERR.enabled) context.read<OverseerrState>()?.reset();
|
||||
if(LunaModule.TAUTULLI.enabled) context.read<TautulliState>()?.reset();
|
||||
}
|
||||
|
||||
/// Returns a [MultiProvider] with the provided child.
|
||||
@@ -31,21 +28,17 @@ class LunaState {
|
||||
/// The [MultiProvider] has a [ChangeNotifierProvider] provider added for each module global state object.
|
||||
static MultiProvider providers({ @required Widget child }) => MultiProvider(
|
||||
providers: [
|
||||
// General
|
||||
ChangeNotifierProvider(create: (_) => DashboardState()),
|
||||
ChangeNotifierProvider(create: (_) => SearchState()),
|
||||
ChangeNotifierProvider(create: (_) => SettingsState()),
|
||||
// Automation
|
||||
ChangeNotifierProvider(create: (_) => SonarrState()),
|
||||
ChangeNotifierProvider(create: (_) => LidarrState()),
|
||||
ChangeNotifierProvider(create: (_) => RadarrState()),
|
||||
// Clients
|
||||
ChangeNotifierProvider(create: (_) => NZBGetState()),
|
||||
ChangeNotifierProvider(create: (_) => SABnzbdState()),
|
||||
// Monitoring
|
||||
ChangeNotifierProvider(create: (_) => TautulliState()),
|
||||
if(LunaModule.SEARCH.enabled) ChangeNotifierProvider(create: (_) => SearchState()),
|
||||
if(LunaModule.LIDARR.enabled) ChangeNotifierProvider(create: (_) => LidarrState()),
|
||||
if(LunaModule.RADARR.enabled) ChangeNotifierProvider(create: (_) => RadarrState()),
|
||||
if(LunaModule.SONARR.enabled) ChangeNotifierProvider(create: (_) => SonarrState()),
|
||||
if(LunaModule.NZBGET.enabled) ChangeNotifierProvider(create: (_) => NZBGetState()),
|
||||
if(LunaModule.SABNZBD.enabled) ChangeNotifierProvider(create: (_) => SABnzbdState()),
|
||||
if(LunaModule.OVERSEERR.enabled) ChangeNotifierProvider(create: (_) => OverseerrState()),
|
||||
if(LunaModule.TAUTULLI.enabled) ChangeNotifierProvider(create: (_) => TautulliState()),
|
||||
],
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
export 'system/configuration.dart';
|
||||
export 'system/desktop_window.dart';
|
||||
export 'system/image_cache.dart';
|
||||
export 'system/in_app_purchases.dart';
|
||||
export 'system/filesystem.dart';
|
||||
export 'system/localization.dart';
|
||||
export 'system/modules.dart';
|
||||
export 'system/networking.dart';
|
||||
export 'system/profile.dart';
|
||||
export 'system/quick_actions.dart';
|
||||
|
||||
@@ -52,6 +52,7 @@ class LunaConfiguration {
|
||||
if(config[LunaModule.SONARR.key] != null) SonarrDatabase().import(config[LunaModule.SONARR.key]);
|
||||
if(config[LunaModule.NZBGET.key] != null) NZBGetDatabase().import(config[LunaModule.NZBGET.key]);
|
||||
if(config[LunaModule.SABNZBD.key] != null) SABnzbdDatabase().import(config[LunaModule.SABNZBD.key]);
|
||||
if(config[LunaModule.OVERSEERR.key] != null) OverseerrDatabase().import(config[LunaModule.OVERSEERR.key]);
|
||||
if(config[LunaModule.TAUTULLI.key] != null) TautulliDatabase().import(config[LunaModule.TAUTULLI.key]);
|
||||
} catch (error, stack) {
|
||||
LunaLogger().error('Failed to import configuration, resetting to default', error, stack);
|
||||
@@ -76,6 +77,7 @@ class LunaConfiguration {
|
||||
LunaModule.SONARR.key: SonarrDatabase().export(),
|
||||
LunaModule.NZBGET.key: NZBGetDatabase().export(),
|
||||
LunaModule.SABNZBD.key: SABnzbdDatabase().export(),
|
||||
LunaModule.OVERSEERR.key: OverseerrDatabase().export(),
|
||||
LunaModule.TAUTULLI.key: TautulliDatabase().export(),
|
||||
});
|
||||
}
|
||||
@@ -18,13 +18,14 @@ class LunaQuickActions {
|
||||
/// Sets the shortcut items by checking the database and enabling the respective action if enabled.
|
||||
void setShortcutItems() {
|
||||
if(isPlatformCompatible) _quickActions.setShortcutItems(<ShortcutItem>[
|
||||
if(LunaDatabaseValue.QUICK_ACTIONS_SEARCH.data) LunaModule.SEARCH.shortcutItem,
|
||||
if(LunaDatabaseValue.QUICK_ACTIONS_LIDARR.data) LunaModule.LIDARR.shortcutItem,
|
||||
if(LunaDatabaseValue.QUICK_ACTIONS_RADARR.data) LunaModule.RADARR.shortcutItem,
|
||||
if(LunaDatabaseValue.QUICK_ACTIONS_SONARR.data) LunaModule.SONARR.shortcutItem,
|
||||
if(LunaDatabaseValue.QUICK_ACTIONS_NZBGET.data) LunaModule.NZBGET.shortcutItem,
|
||||
if(LunaDatabaseValue.QUICK_ACTIONS_SABNZBD.data) LunaModule.SABNZBD.shortcutItem,
|
||||
if(LunaDatabaseValue.QUICK_ACTIONS_TAUTULLI.data) LunaModule.TAUTULLI.shortcutItem,
|
||||
if(LunaModule.SEARCH.enabled && LunaDatabaseValue.QUICK_ACTIONS_SEARCH.data) LunaModule.SEARCH.shortcutItem,
|
||||
if(LunaModule.LIDARR.enabled && LunaDatabaseValue.QUICK_ACTIONS_LIDARR.data) LunaModule.LIDARR.shortcutItem,
|
||||
if(LunaModule.RADARR.enabled && LunaDatabaseValue.QUICK_ACTIONS_RADARR.data) LunaModule.RADARR.shortcutItem,
|
||||
if(LunaModule.SONARR.enabled && LunaDatabaseValue.QUICK_ACTIONS_SONARR.data) LunaModule.SONARR.shortcutItem,
|
||||
if(LunaModule.NZBGET.enabled && LunaDatabaseValue.QUICK_ACTIONS_NZBGET.data) LunaModule.NZBGET.shortcutItem,
|
||||
if(LunaModule.SABNZBD.enabled && LunaDatabaseValue.QUICK_ACTIONS_SABNZBD.data) LunaModule.SABNZBD.shortcutItem,
|
||||
if(LunaModule.OVERSEERR.enabled && LunaDatabaseValue.QUICK_ACTIONS_OVERSEERR.data) LunaModule.OVERSEERR.shortcutItem,
|
||||
if(LunaModule.TAUTULLI.enabled && LunaDatabaseValue.QUICK_ACTIONS_TAUTULLI.data) LunaModule.TAUTULLI.shortcutItem,
|
||||
LunaModule.SETTINGS.shortcutItem,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class LunaDrawer extends StatelessWidget {
|
||||
_buildEntry(context: context, module: LunaModule.SETTINGS),
|
||||
LunaDivider(),
|
||||
if(showSearch) _buildEntry(context: context, module: LunaModule.SEARCH),
|
||||
if(LunaModule.WAKE_ON_LAN.enabled) _buildWakeOnLAN(context),
|
||||
if(LunaModule.WAKE_ON_LAN.enabled && Database.currentProfileObject.wakeOnLANEnabled ?? false) _buildWakeOnLAN(context),
|
||||
if(automation.length != 0) ...List.generate(
|
||||
automation.length,
|
||||
(index) => _buildEntry(context: context, module: automation[index]),
|
||||
|
||||
@@ -4,8 +4,8 @@ import 'package:flutter/widgets.dart';
|
||||
class LunaIcons {
|
||||
LunaIcons._();
|
||||
|
||||
static const _kFontFam = 'CustomIcons';
|
||||
static const _kFontPkg = null;
|
||||
static const _kFontFam = 'LunaIcons';
|
||||
static const String _kFontPkg = null;
|
||||
|
||||
static const IconData arrow_right = IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData calendar_missing = IconData(0xe801, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
@@ -39,4 +39,5 @@ class LunaIcons {
|
||||
static const IconData tautulli = IconData(0xe81d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData plex = IconData(0xe81e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData radarr = IconData(0xe81f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData overseerr = IconData(0xe820, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
export 'utilities/changelog.dart';
|
||||
export 'utilities/configuration.dart';
|
||||
export 'utilities/encryption.dart';
|
||||
export 'utilities/logger.dart';
|
||||
export 'utilities/profile.dart';
|
||||
export 'utilities/uuid.dart';
|
||||
|
||||
@@ -19,7 +19,7 @@ class LunaEncryption {
|
||||
final _encrypted = _encrypter.encrypt(data, iv: iv).base64;
|
||||
return _encrypted;
|
||||
} catch (error, stack) {
|
||||
LunaLogger().error('Failed to decrypted "$data" with using key "$encryptionKey"', error, stack);
|
||||
LunaLogger().error('Failed to decrypted "$data" using the key "$encryptionKey"', error, stack);
|
||||
}
|
||||
return ENCRYPTION_FAILURE;
|
||||
}
|
||||
@@ -35,7 +35,7 @@ class LunaEncryption {
|
||||
final _encrypter = Encrypter(AES(key));
|
||||
return _encrypter.decrypt64(data, iv: iv);
|
||||
} catch (error) {
|
||||
LunaLogger().warning('LunaEncryption', 'decrypt', 'Failed to decrypted "$data" with using key "$decryptionKey"');
|
||||
LunaLogger().warning('LunaEncryption', 'decrypt', 'Failed to decrypted "$data" using the key "$decryptionKey"');
|
||||
}
|
||||
return ENCRYPTION_FAILURE;
|
||||
}
|
||||
|
||||
@@ -7,17 +7,19 @@ import 'package:lunasea/core.dart';
|
||||
///
|
||||
/// Runs app in guarded zone to attempt to capture fatal (crashing) errors
|
||||
Future<void> main() async {
|
||||
await _init();
|
||||
runZonedGuarded(
|
||||
() => runApp(
|
||||
EasyLocalization(
|
||||
supportedLocales: LunaLocalization().supportedLocales,
|
||||
path: LunaLocalization().fileDirectory,
|
||||
fallbackLocale: LunaLocalization().fallbackLocale,
|
||||
useFallbackTranslations: true,
|
||||
child: LunaBIOS(),
|
||||
),
|
||||
),
|
||||
() async {
|
||||
await _init();
|
||||
return runApp(
|
||||
EasyLocalization(
|
||||
supportedLocales: LunaLocalization().supportedLocales,
|
||||
path: LunaLocalization().fileDirectory,
|
||||
fallbackLocale: LunaLocalization().fallbackLocale,
|
||||
useFallbackTranslations: true,
|
||||
child: LunaBIOS(),
|
||||
),
|
||||
);
|
||||
},
|
||||
(error, stack) => LunaLogger().critical(error, stack),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export 'modules/dashboard.dart';
|
||||
export 'modules/lidarr.dart';
|
||||
export 'modules/nzbget.dart';
|
||||
export 'modules/overseerr.dart';
|
||||
export 'modules/radarr.dart';
|
||||
export 'modules/sabnzbd.dart';
|
||||
export 'modules/search.dart';
|
||||
|
||||
3
lib/modules/overseerr.dart
Normal file
3
lib/modules/overseerr.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
export 'package:overseerr/overseerr.dart';
|
||||
export 'overseerr/core.dart';
|
||||
export 'overseerr/routes.dart';
|
||||
5
lib/modules/overseerr/core.dart
Normal file
5
lib/modules/overseerr/core.dart
Normal file
@@ -0,0 +1,5 @@
|
||||
export 'core/database.dart';
|
||||
export 'core/dialogs.dart';
|
||||
export 'core/router.dart';
|
||||
export 'core/state.dart';
|
||||
export 'core/webhooks.dart';
|
||||
72
lib/modules/overseerr/core/database.dart
Normal file
72
lib/modules/overseerr/core/database.dart
Normal file
@@ -0,0 +1,72 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
class OverseerrDatabase extends LunaModuleDatabase {
|
||||
@override
|
||||
void registerAdapters() {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> export() {
|
||||
Map<String, dynamic> data = {};
|
||||
for(OverseerrDatabaseValue value in OverseerrDatabaseValue.values) {
|
||||
switch(value) {
|
||||
// Primitive values
|
||||
case OverseerrDatabaseValue.NAVIGATION_INDEX: data[value.key] = value.data; break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@override
|
||||
void import(Map<String, dynamic> config) {
|
||||
for(String key in config.keys) {
|
||||
OverseerrDatabaseValue value = valueFromKey(key);
|
||||
if(value != null) switch(value) {
|
||||
// Primitive values
|
||||
case OverseerrDatabaseValue.NAVIGATION_INDEX: value.put(config[key]); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
OverseerrDatabaseValue valueFromKey(String key) {
|
||||
switch(key) {
|
||||
case 'OVERSEERR_NAVIGATION_INDEX': return OverseerrDatabaseValue.NAVIGATION_INDEX;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum OverseerrDatabaseValue {
|
||||
NAVIGATION_INDEX,
|
||||
}
|
||||
|
||||
extension OverseerrDatabaseValueExtension on OverseerrDatabaseValue {
|
||||
String get key {
|
||||
switch(this) {
|
||||
case OverseerrDatabaseValue.NAVIGATION_INDEX: return 'OVERSEERR_NAVIGATION_INDEX';
|
||||
}
|
||||
throw Exception('Invalid OverseerrDatabaseValue instance');
|
||||
}
|
||||
|
||||
dynamic get data {
|
||||
final _box = Database.lunaSeaBox;
|
||||
switch(this) {
|
||||
case OverseerrDatabaseValue.NAVIGATION_INDEX: return _box.get(this.key, defaultValue: 0);
|
||||
}
|
||||
throw Exception('Invalid OverseerrDatabaseValue instance');
|
||||
}
|
||||
|
||||
void put(dynamic value) {
|
||||
final box = Database.lunaSeaBox;
|
||||
switch(this) {
|
||||
case OverseerrDatabaseValue.NAVIGATION_INDEX: if(value is int) box.put(this.key, value); return;
|
||||
}
|
||||
LunaLogger().warning('OverseerrDatabaseValueExtension', 'put', 'Attempted to enter data for invalid OverseerrDatabaseValue: ${this?.toString() ?? 'null'}');
|
||||
}
|
||||
|
||||
ValueListenableBuilder listen({ @required Widget Function(BuildContext, dynamic, Widget) builder }) => ValueListenableBuilder(
|
||||
valueListenable: Database.lunaSeaBox.listenable(keys: [this.key]),
|
||||
builder: builder,
|
||||
);
|
||||
}
|
||||
3
lib/modules/overseerr/core/dialogs.dart
Normal file
3
lib/modules/overseerr/core/dialogs.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
class OverseerrDialogs {
|
||||
|
||||
}
|
||||
39
lib/modules/overseerr/core/router.dart
Normal file
39
lib/modules/overseerr/core/router.dart
Normal file
@@ -0,0 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/modules/overseerr.dart';
|
||||
|
||||
class OverseerrRouter extends LunaModuleRouter {
|
||||
@override
|
||||
void defineAllRoutes(FluroRouter router) {
|
||||
OverseerrHomeRouter().defineRoute(router);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class OverseerrPageRouter extends LunaPageRouter {
|
||||
OverseerrPageRouter(String route) : super(route);
|
||||
|
||||
@override
|
||||
void noParameterRouteDefinition(FluroRouter router, Widget widget, { bool homeRoute = false }) => router.define(
|
||||
fullRoute,
|
||||
handler: Handler(handlerFunc: (context, params) {
|
||||
if(!homeRoute && !context.read<OverseerrState>().enabled) return LunaNotEnabledRoute(module: 'Overseerr');
|
||||
return widget;
|
||||
}),
|
||||
transitionType: LunaRouter.transitionType,
|
||||
);
|
||||
|
||||
@override
|
||||
void withParameterRouteDefinition(
|
||||
FluroRouter router,
|
||||
Widget Function(BuildContext, Map<String, List<String>>) handlerFunc,
|
||||
{ bool homeRoute = false }
|
||||
) => router.define(
|
||||
fullRoute,
|
||||
handler: Handler(handlerFunc: (context, params) {
|
||||
if(!homeRoute && !context.read<OverseerrState>().enabled) return LunaNotEnabledRoute(module: 'Overseerr');
|
||||
return handlerFunc(context, params);
|
||||
}),
|
||||
transitionType: LunaRouter.transitionType,
|
||||
);
|
||||
}
|
||||
53
lib/modules/overseerr/core/state.dart
Normal file
53
lib/modules/overseerr/core/state.dart
Normal file
@@ -0,0 +1,53 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/modules/overseerr.dart';
|
||||
|
||||
class OverseerrState extends LunaModuleState {
|
||||
OverseerrState() {
|
||||
reset();
|
||||
}
|
||||
|
||||
@override
|
||||
void reset() {
|
||||
resetProfile();
|
||||
}
|
||||
|
||||
///////////////
|
||||
/// PROFILE ///
|
||||
///////////////
|
||||
|
||||
/// API handler instance
|
||||
Overseerr _api;
|
||||
Overseerr get api => _api;
|
||||
|
||||
/// Is the API enabled?
|
||||
bool _enabled;
|
||||
bool get enabled => _enabled;
|
||||
|
||||
/// Overseerr host
|
||||
String _host;
|
||||
String get host => _host;
|
||||
|
||||
/// Overseerr API key
|
||||
String _apiKey;
|
||||
String get apiKey => _apiKey;
|
||||
|
||||
/// Headers to attach to all requests
|
||||
Map<dynamic, dynamic> _headers;
|
||||
Map<dynamic, dynamic> get headers => _headers;
|
||||
|
||||
/// Reset the profile data, reinitializes API instance
|
||||
void resetProfile() {
|
||||
ProfileHiveObject _profile = Database.currentProfileObject;
|
||||
// Copy profile into state
|
||||
_enabled = _profile.overseerrEnabled ?? false;
|
||||
_host = _profile.overseerrHost ?? '';
|
||||
_apiKey = _profile.overseerrKey ?? '';
|
||||
_headers = _profile.overseerrHeaders ?? {};
|
||||
// Create the API instance if Overseerr is enabled
|
||||
_api = !_enabled ? null : Overseerr(
|
||||
host: _host,
|
||||
apiKey: _apiKey,
|
||||
headers: Map<String, dynamic>.from(_headers),
|
||||
);
|
||||
}
|
||||
}
|
||||
12
lib/modules/overseerr/core/webhooks.dart
Normal file
12
lib/modules/overseerr/core/webhooks.dart
Normal file
@@ -0,0 +1,12 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
class OverseerrWebhooks extends LunaWebhooks {
|
||||
@override
|
||||
Future<void> handle(Map<dynamic, dynamic> data) async {
|
||||
LunaLogger().warning(
|
||||
'OverseerrWebhooks',
|
||||
'handle',
|
||||
'Unknown event type: ${data['event'] ?? 'null'}',
|
||||
);
|
||||
}
|
||||
}
|
||||
1
lib/modules/overseerr/routes.dart
Normal file
1
lib/modules/overseerr/routes.dart
Normal file
@@ -0,0 +1 @@
|
||||
export 'routes/overseerr.dart';
|
||||
2
lib/modules/overseerr/routes/overseerr.dart
Normal file
2
lib/modules/overseerr/routes/overseerr.dart
Normal file
@@ -0,0 +1,2 @@
|
||||
export 'overseerr/route.dart';
|
||||
export 'overseerr/widgets.dart';
|
||||
81
lib/modules/overseerr/routes/overseerr/route.dart
Normal file
81
lib/modules/overseerr/routes/overseerr/route.dart
Normal file
@@ -0,0 +1,81 @@
|
||||
import 'package:fluro/fluro.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/modules/overseerr.dart';
|
||||
|
||||
class OverseerrHomeRouter extends OverseerrPageRouter {
|
||||
OverseerrHomeRouter() : super('/overseerr');
|
||||
|
||||
@override
|
||||
void defineRoute(FluroRouter router) => super.noParameterRouteDefinition(router, _OverseerrHomeRoute(), homeRoute: true);
|
||||
}
|
||||
|
||||
class _OverseerrHomeRoute extends StatefulWidget {
|
||||
@override
|
||||
State<_OverseerrHomeRoute> createState() => _State();
|
||||
}
|
||||
|
||||
class _State extends State<_OverseerrHomeRoute> {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
LunaPageController _pageController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_pageController = LunaPageController(initialPage: OverseerrDatabaseValue.NAVIGATION_INDEX.data);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LunaScaffold(
|
||||
scaffoldKey: _scaffoldKey,
|
||||
drawer: _drawer(),
|
||||
appBar: _appBar(),
|
||||
bottomNavigationBar: _bottomNavigationBar(),
|
||||
body: _body(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _drawer() => LunaDrawer(page: LunaModule.OVERSEERR.key);
|
||||
|
||||
Widget _bottomNavigationBar() {
|
||||
if(context.read<OverseerrState>().enabled) return OverseerrNavigationBar(pageController: _pageController);
|
||||
return null;
|
||||
}
|
||||
|
||||
Widget _appBar() {
|
||||
List<String> profiles = Database.profilesBox.keys.fold([], (value, element) {
|
||||
if(Database.profilesBox.get(element)?.overseerrEnabled ?? false) value.add(element);
|
||||
return value;
|
||||
});
|
||||
List<Widget> actions;
|
||||
if(context.watch<OverseerrState>().enabled) actions = [];
|
||||
return LunaAppBar.dropdown(
|
||||
title: LunaModule.OVERSEERR.name,
|
||||
useDrawer: true,
|
||||
profiles: profiles,
|
||||
actions: actions,
|
||||
pageController: _pageController,
|
||||
scrollControllers: OverseerrNavigationBar.scrollControllers,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _body() {
|
||||
return Selector<OverseerrState, bool>(
|
||||
selector: (_, state) => state.enabled,
|
||||
builder: (context, enabled, _) {
|
||||
if(!enabled) return LunaMessage.moduleNotEnabled(context: context, module: 'Overseerr');
|
||||
return PageView(
|
||||
controller: _pageController,
|
||||
children: [
|
||||
LunaMessage(
|
||||
text: 'Coming Soon',
|
||||
buttonText: 'Go to Dashboard',
|
||||
onTap: LunaModule.DASHBOARD.launch,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
1
lib/modules/overseerr/routes/overseerr/widgets.dart
Normal file
1
lib/modules/overseerr/routes/overseerr/widgets.dart
Normal file
@@ -0,0 +1 @@
|
||||
export 'widgets/navigation_bar.dart';
|
||||
@@ -0,0 +1,30 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
class OverseerrNavigationBar extends StatelessWidget {
|
||||
final PageController pageController;
|
||||
static List<ScrollController> scrollControllers = List.generate(icons.length, (_) => ScrollController());
|
||||
|
||||
static const List<IconData> icons = [
|
||||
LunaIcons.movies,
|
||||
];
|
||||
|
||||
static List<String> get titles => [
|
||||
'Requests',
|
||||
];
|
||||
|
||||
OverseerrNavigationBar({
|
||||
Key key,
|
||||
@required this.pageController,
|
||||
}): super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LunaBottomNavigationBar(
|
||||
pageController: pageController,
|
||||
scrollControllers: scrollControllers,
|
||||
icons: icons,
|
||||
titles: titles,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/modules/radarr.dart';
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ class _State extends State<SettingsHeaderRoute> with LunaScrollControllerMixin {
|
||||
case LunaModule.SEARCH: throw Exception('Search does not have a headers page');
|
||||
case LunaModule.SETTINGS: throw Exception('Settings does not have a headers page');
|
||||
case LunaModule.WAKE_ON_LAN: throw Exception('Wake on LAN does not have a headers page');
|
||||
case LunaModule.OVERSEERR: return Database.currentProfileObject.overseerrHeaders;
|
||||
case LunaModule.TAUTULLI: return Database.currentProfileObject.tautulliHeaders;
|
||||
}
|
||||
throw Exception('An unknown LunaModule was passed in.');
|
||||
@@ -119,6 +120,7 @@ class _State extends State<SettingsHeaderRoute> with LunaScrollControllerMixin {
|
||||
case LunaModule.SETTINGS: throw Exception('Settings does not have a headers page');
|
||||
case LunaModule.WAKE_ON_LAN: throw Exception('Wake on LAN does not have a headers page');
|
||||
case LunaModule.TAUTULLI: return context.read<TautulliState>().reset();
|
||||
case LunaModule.OVERSEERR: return context.read<OverseerrState>().reset();
|
||||
}
|
||||
throw Exception('An unknown LunaModule was passed in.');
|
||||
}
|
||||
|
||||
@@ -49,6 +49,10 @@ class SettingsRouter extends LunaModuleRouter {
|
||||
SettingsConfigurationSonarrDefaultPagesRouter().defineRoute(router);
|
||||
SettingsConfigurationSonarrDefaultSortingRouter().defineRoute(router);
|
||||
SettingsConfigurationSonarrHeadersRouter().defineRoute(router);
|
||||
// Configuration/Overseerr
|
||||
SettingsConfigurationOverseerrRouter().defineRoute(router);
|
||||
SettingsConfigurationOverseerrConnectionDetailsRouter().defineRoute(router);
|
||||
SettingsConfigurationOverseerrHeadersRouter().defineRoute(router);
|
||||
// Configuration/Tautulli
|
||||
SettingsConfigurationTautulliRouter().defineRoute(router);
|
||||
SettingsConfigurationTautulliConnectionDetailsRouter().defineRoute(router);
|
||||
|
||||
@@ -5,6 +5,7 @@ export 'routes/configuration_appearance.dart';
|
||||
export 'routes/configuration_dashboard.dart';
|
||||
export 'routes/configuration_lidarr.dart';
|
||||
export 'routes/configuration_nzbget.dart';
|
||||
export 'routes/configuration_overseerr.dart';
|
||||
export 'routes/configuration_quickactions.dart';
|
||||
export 'routes/configuration_radarr.dart';
|
||||
export 'routes/configuration_sabnzbd.dart';
|
||||
|
||||
@@ -78,18 +78,49 @@ class _State extends State<_SettingsConfigurationRoute> with LunaScrollControlle
|
||||
onTap: () async => SettingsConfigurationQuickActionsRouter().navigateTo(context),
|
||||
),
|
||||
LunaDivider(),
|
||||
_tileFromModuleMap(LunaModule.DASHBOARD, () async => SettingsConfigurationDashboardRouter().navigateTo(context)),
|
||||
_tileFromModuleMap(LunaModule.SEARCH, () async => SettingsConfigurationSearchRouter().navigateTo(context)),
|
||||
_tileFromModuleMap(LunaModule.WAKE_ON_LAN, () async => SettingsConfigurationWakeOnLANRouter().navigateTo(context)),
|
||||
if(LunaModule.DASHBOARD.enabled) _tileFromModuleMap(
|
||||
LunaModule.DASHBOARD,
|
||||
() async => SettingsConfigurationDashboardRouter().navigateTo(context),
|
||||
),
|
||||
if(LunaModule.SEARCH.enabled) _tileFromModuleMap(
|
||||
LunaModule.SEARCH,
|
||||
() async => SettingsConfigurationSearchRouter().navigateTo(context),
|
||||
),
|
||||
if(LunaModule.WAKE_ON_LAN.enabled) _tileFromModuleMap(
|
||||
LunaModule.WAKE_ON_LAN,
|
||||
() async => SettingsConfigurationWakeOnLANRouter().navigateTo(context),
|
||||
),
|
||||
LunaDivider(),
|
||||
_tileFromModuleMap(LunaModule.LIDARR, () async => SettingsConfigurationLidarrRouter().navigateTo(context)),
|
||||
_tileFromModuleMap(LunaModule.RADARR, () async => SettingsConfigurationRadarrRouter().navigateTo(context)),
|
||||
_tileFromModuleMap(LunaModule.SONARR, () async => SettingsConfigurationSonarrRouter().navigateTo(context)),
|
||||
if(LunaModule.LIDARR.enabled) _tileFromModuleMap(
|
||||
LunaModule.LIDARR,
|
||||
() async => SettingsConfigurationLidarrRouter().navigateTo(context),
|
||||
),
|
||||
if(LunaModule.RADARR.enabled) _tileFromModuleMap(
|
||||
LunaModule.RADARR,
|
||||
() async => SettingsConfigurationRadarrRouter().navigateTo(context),
|
||||
),
|
||||
if(LunaModule.SONARR.enabled) _tileFromModuleMap(
|
||||
LunaModule.SONARR,
|
||||
() async => SettingsConfigurationSonarrRouter().navigateTo(context),
|
||||
),
|
||||
LunaDivider(),
|
||||
_tileFromModuleMap(LunaModule.NZBGET, () async => SettingsConfigurationNZBGetRouter().navigateTo(context)),
|
||||
_tileFromModuleMap(LunaModule.SABNZBD, () async => SettingsConfigurationSABnzbdRouter().navigateTo(context)),
|
||||
if(LunaModule.NZBGET.enabled) _tileFromModuleMap(
|
||||
LunaModule.NZBGET,
|
||||
() async => SettingsConfigurationNZBGetRouter().navigateTo(context),
|
||||
),
|
||||
if(LunaModule.SABNZBD.enabled) _tileFromModuleMap(
|
||||
LunaModule.SABNZBD,
|
||||
() async => SettingsConfigurationSABnzbdRouter().navigateTo(context),
|
||||
),
|
||||
LunaDivider(),
|
||||
_tileFromModuleMap(LunaModule.TAUTULLI, () async => SettingsConfigurationTautulliRouter().navigateTo(context)),
|
||||
if(LunaModule.OVERSEERR.enabled) _tileFromModuleMap(
|
||||
LunaModule.OVERSEERR,
|
||||
() async => SettingsConfigurationOverseerrRouter().navigateTo(context),
|
||||
),
|
||||
if(LunaModule.TAUTULLI.enabled) _tileFromModuleMap(
|
||||
LunaModule.TAUTULLI,
|
||||
() async => SettingsConfigurationTautulliRouter().navigateTo(context),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
2
lib/modules/settings/routes/configuration_overseerr.dart
Normal file
2
lib/modules/settings/routes/configuration_overseerr.dart
Normal file
@@ -0,0 +1,2 @@
|
||||
export 'configuration_overseerr/pages.dart';
|
||||
export 'configuration_overseerr/route.dart';
|
||||
@@ -0,0 +1,2 @@
|
||||
export 'pages/connection_details.dart';
|
||||
export 'pages/headers.dart';
|
||||
@@ -0,0 +1,114 @@
|
||||
import 'package:fluro/fluro.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/modules/overseerr.dart';
|
||||
import 'package:lunasea/modules/settings.dart';
|
||||
|
||||
class SettingsConfigurationOverseerrConnectionDetailsRouter extends SettingsPageRouter {
|
||||
SettingsConfigurationOverseerrConnectionDetailsRouter() : super('/settings/configuration/overseerr/connection');
|
||||
|
||||
@override
|
||||
void defineRoute(FluroRouter router) => super.noParameterRouteDefinition(router, _SettingsConfigurationOverseerrRoute());
|
||||
}
|
||||
|
||||
class _SettingsConfigurationOverseerrRoute extends StatefulWidget {
|
||||
@override
|
||||
State<_SettingsConfigurationOverseerrRoute> createState() => _State();
|
||||
}
|
||||
|
||||
class _State extends State<_SettingsConfigurationOverseerrRoute> with LunaScrollControllerMixin {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LunaScaffold(
|
||||
scaffoldKey: _scaffoldKey,
|
||||
appBar: _appBar(),
|
||||
body: _body(),
|
||||
bottomNavigationBar: _bottomActionBar(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _appBar() {
|
||||
return LunaAppBar(
|
||||
title: 'Connection Details',
|
||||
scrollControllers: [scrollController],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _bottomActionBar() {
|
||||
return LunaBottomActionBar(
|
||||
actions: [
|
||||
_testConnection(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _body() {
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: Database.profilesBox.listenable(),
|
||||
builder: (context, box, _) => LunaListView(
|
||||
controller: scrollController,
|
||||
children: [
|
||||
_host(),
|
||||
_apiKey(),
|
||||
_customHeaders(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _host() {
|
||||
String host = Database.currentProfileObject.overseerrHost;
|
||||
return LunaListTile(
|
||||
context: context,
|
||||
title: LunaText.title(text: 'Host'),
|
||||
subtitle: LunaText.subtitle(text: (host ?? '').isEmpty ? 'Not Set' : host),
|
||||
trailing: LunaIconButton(icon: Icons.arrow_forward_ios_rounded),
|
||||
onTap: () async {
|
||||
List<dynamic> _values = await SettingsDialogs.editHost(context, 'Overseerr Host', prefill: Database.currentProfileObject.overseerrHost ?? '');
|
||||
if(_values[0]) {
|
||||
Database.currentProfileObject.overseerrHost = _values[1];
|
||||
Database.currentProfileObject.save();
|
||||
context.read<OverseerrState>().reset();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _apiKey() {
|
||||
String apiKey = Database.currentProfileObject.overseerrKey;
|
||||
return LunaListTile(
|
||||
context: context,
|
||||
title: LunaText.title(text: 'API Key'),
|
||||
subtitle: LunaText.subtitle(text: (apiKey ?? '').isEmpty ? 'Not Set' : '••••••••••••'),
|
||||
trailing: LunaIconButton(icon: Icons.arrow_forward_ios_rounded),
|
||||
onTap: () async {
|
||||
Tuple2<bool, String> _values = await LunaDialogs().editText(context, 'Overseerr API Key', prefill: Database.currentProfileObject.overseerrKey ?? '');
|
||||
if(_values.item1) {
|
||||
Database.currentProfileObject.overseerrKey = _values.item2;
|
||||
Database.currentProfileObject.save();
|
||||
context.read<OverseerrState>().reset();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _testConnection() {
|
||||
return LunaButton.text(
|
||||
text: 'Test Connection',
|
||||
icon: Icons.wifi_tethering_rounded,
|
||||
onTap: () async {},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _customHeaders() {
|
||||
return LunaListTile(
|
||||
context: context,
|
||||
title: LunaText.title(text: 'Custom Headers'),
|
||||
subtitle: LunaText.subtitle(text: 'Add Custom Headers to Requests'),
|
||||
trailing: LunaIconButton(icon: Icons.arrow_forward_ios_rounded),
|
||||
onTap: () async => SettingsConfigurationOverseerrHeadersRouter().navigateTo(context),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'package:fluro/fluro.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/modules/settings.dart';
|
||||
|
||||
class SettingsConfigurationOverseerrHeadersRouter extends SettingsPageRouter {
|
||||
SettingsConfigurationOverseerrHeadersRouter() : super('/settings/configuration/overseerr/headers');
|
||||
|
||||
@override
|
||||
void defineRoute(FluroRouter router) => super.noParameterRouteDefinition(
|
||||
router,
|
||||
SettingsHeaderRoute(module: LunaModule.OVERSEERR),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import 'package:fluro/fluro.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/modules/overseerr.dart';
|
||||
import 'package:lunasea/modules/settings.dart';
|
||||
|
||||
class SettingsConfigurationOverseerrRouter extends SettingsPageRouter {
|
||||
SettingsConfigurationOverseerrRouter() : super('/settings/configuration/overseerr');
|
||||
|
||||
@override
|
||||
void defineRoute(FluroRouter router) => super.noParameterRouteDefinition(router, _SettingsConfigurationOverseerrRoute());
|
||||
}
|
||||
|
||||
class _SettingsConfigurationOverseerrRoute extends StatefulWidget {
|
||||
@override
|
||||
State<_SettingsConfigurationOverseerrRoute> createState() => _State();
|
||||
}
|
||||
|
||||
class _State extends State<_SettingsConfigurationOverseerrRoute> with LunaScrollControllerMixin {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LunaScaffold(
|
||||
scaffoldKey: _scaffoldKey,
|
||||
appBar: _appBar(),
|
||||
body: _body(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _appBar() {
|
||||
return LunaAppBar(
|
||||
title: LunaModule.OVERSEERR.name,
|
||||
scrollControllers: [scrollController],
|
||||
actions: [
|
||||
LunaIconButton(
|
||||
icon: Icons.help_outline,
|
||||
onPressed: () async => SettingsDialogs().moduleInformation(context, LunaModule.OVERSEERR),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _body() {
|
||||
return LunaListView(
|
||||
controller: scrollController,
|
||||
children: [
|
||||
_enabledToggle(),
|
||||
_connectionDetailsPage(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _enabledToggle() {
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: Database.profilesBox.listenable(),
|
||||
builder: (context, _, __) => LunaListTile(
|
||||
context: context,
|
||||
title: LunaText.title(text: 'Enable ${LunaModule.OVERSEERR.name}'),
|
||||
trailing: LunaSwitch(
|
||||
value: Database.currentProfileObject.overseerrEnabled ?? false,
|
||||
onChanged: (value) {
|
||||
Database.currentProfileObject.overseerrEnabled = value;
|
||||
Database.currentProfileObject.save();
|
||||
context.read<OverseerrState>().reset();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _connectionDetailsPage() {
|
||||
return LunaListTile(
|
||||
context: context,
|
||||
title: LunaText.title(text: 'Connection Details'),
|
||||
subtitle: LunaText.subtitle(text: 'Connection Details for ${LunaModule.OVERSEERR.name}'),
|
||||
trailing: LunaIconButton(icon: Icons.arrow_forward_ios_rounded),
|
||||
onTap: () async => SettingsConfigurationOverseerrConnectionDetailsRouter().navigateTo(context),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -702,6 +702,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
overseerr:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: overseerr
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1-pre.5"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -37,6 +37,7 @@ dependencies:
|
||||
intl: ^0.17.0 # ANDROID IOS LINUX MACOS WEB WINDOWS
|
||||
modal_bottom_sheet: ^2.0.0 # ANDROID IOS LINUX MACOS WEB WINDOWS
|
||||
network_info_plus: ^1.0.0 # ANDROID IOS LINUX MACOS WEB WINDOWS
|
||||
overseerr: ^0.0.1-pre.5 # ANDROID IOS LINUX MACOS WEB WINDOWS
|
||||
package_info_plus: ^1.0.0 # ANDROID IOS LINUX MACOS WEB WINDOWS
|
||||
path_provider: ^2.0.1 # ANDROID IOS LINUX MACOS WINDOWS
|
||||
percent_indicator: ^3.0.1 # ANDROID IOS LINUX MACOS WEB WINDOWS
|
||||
@@ -55,12 +56,12 @@ dependencies:
|
||||
url_launcher: ^6.0.3 # ANDROID IOS LINUX MACOS WEB WINDOWS
|
||||
uuid: ^3.0.4 # ANDROID IOS LINUX MACOS WEB WINDOWS
|
||||
wake_on_lan: ^2.0.1+1 # ANDROID IOS LINUX MACOS WINDOWS
|
||||
xml: ^5.1.0 # ANDROID IOS LINUX MACOS WEB WINDOWS
|
||||
window_size:
|
||||
git:
|
||||
url: git://github.com/google/flutter-desktop-embedding.git
|
||||
path: plugins/window_size
|
||||
ref: 57a2cd88486105d3d813583339eb0e23c9bfd6d2
|
||||
xml: ^5.1.0 # ANDROID IOS LINUX MACOS WEB WINDOWS
|
||||
|
||||
dev_dependencies:
|
||||
build_runner: ^1.12.2
|
||||
@@ -79,9 +80,9 @@ flutter:
|
||||
- assets/images/branding/
|
||||
- assets/images/services/
|
||||
fonts:
|
||||
- family: CustomIcons
|
||||
- family: LunaIcons
|
||||
fonts:
|
||||
- asset: assets/CustomIcons.ttf
|
||||
- asset: assets/LunaIcons.ttf
|
||||
|
||||
flutter_icons:
|
||||
android: true
|
||||
|
||||
0
test/.gitkeep
Normal file
0
test/.gitkeep
Normal file
Reference in New Issue
Block a user