[Release/TestFlight] v4.1.0+40100001 (#266)

NEW
- [Networking] Strict TLS/SSL validation is now disabled globally
- [Routing] Hold the AppBar back button to pop back to the home page of the module
- [Settings/Sonarr] Toggle to enable Sonarr v3 features
- [Sonarr] Complete rewrite of Sonarr
- [Sonarr] State is now held across module switches
- [Sonarr/Overview] View tags applied to series
- [Sonarr/Catalogue] (v3 only) Ability to set and update language profile
- [Sonarr/Catalogue] Ability to view all, only monitored, or only unmonitored series
- [Sonarr/Releases] (v3 only) Ability to interactively search for season packs
- [Sonarr/Releases] Ability to view all, only approved, or only rejected releases

TWEAKS
- [Settings] Removed all toggles for strict TLS
- [Sonarr] Many tweaks to Sonarr's design
- [Sonarr/Add] (v3 only) Tapping an already-added series will take you to the series page
- [Sonarr/Add] Automatically navigate to newly added series
- [Sonarr/Series] Toggling monitored state of series has now been moved to the edit prompt

FIXES
- [Images] Images will now load for invalid/self-signed certificates
- [Tautulli/Activity] Fix grey screen for music activity
- [TextField] Fix TextField actions (cut, copy, paste, etc.) not showing
- [Timestamps] Fix 12:xx AM being shown as 00:xx AM
- Additional small bug fixes
This commit is contained in:
Jagandeep Brar
2020-10-13 09:43:28 -05:00
committed by GitHub
parent 0530fa3dee
commit 5cf33b3abd
597 changed files with 10219 additions and 9385 deletions

1
.gitignore vendored
View File

@@ -44,6 +44,7 @@ LunaSea-armeabi-v7a-release.apk
LunaSea-arm64-v8a-release.apk
LunaSea-x86_64-release.apk
ios/build/
_changelog.txt
# Build Configurations
ExportOptions.plist

View File

@@ -620,4 +620,4 @@
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
}

View File

@@ -2,16 +2,20 @@ export 'core/constants.dart';
export 'core/configuration.dart';
export 'core/database.dart';
export 'core/dialogs.dart';
export 'core/encryption.dart';
export 'core/extensions.dart';
export 'core/homescreen_actions.dart';
export 'core/filesystem.dart';
export 'core/image_cache.dart';
export 'core/in_app_purchases.dart';
export 'core/logger.dart';
export 'core/luna_ui.dart';
export 'core/module_map.dart';
export 'core/networking.dart';
export 'core/profile.dart';
export 'core/providers.dart';
export 'core/quick_actions.dart';
export 'core/router.dart';
export 'core/state.dart';
export 'core/theme.dart';
export 'core/types.dart';
export 'core/ui.dart';
export 'core/uuid.dart';
export 'core/uuid.dart';

View File

@@ -1,4 +1,2 @@
export 'configuration/export.dart';
export 'configuration/import.dart';
export 'configuration/encryption.dart';
export 'configuration/filesystem.dart';

View File

@@ -1,11 +1,13 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/core/database.dart';
class Import {
Import._();
static void _setLunaSea(Map data) {
LunaSeaDatabaseValue.ENABLED_PROFILE.put(data['profile']);
static void _setLunaSea(BuildContext context, Map data) {
LunaProfile.changeProfile(context, data['profile']);
}
static void _setProfiles(List data) {
@@ -16,33 +18,28 @@ class Import {
sonarrEnabled: profile['sonarrEnabled'] ?? false,
sonarrHost: profile['sonarrHost'] ?? '',
sonarrKey: profile['sonarrKey'] ?? '',
sonarrStrictTLS: profile['sonarrStrictTLS'] ?? true,
sonarrVersion3: profile['sonarrVersion3'] ?? false,
sonarrHeaders: profile['sonarrHeaders'] ?? {},
//Radarr
radarrEnabled: profile['radarrEnabled'] ?? false,
radarrHost: profile['radarrHost'] ?? '',
radarrKey: profile['radarrKey'] ?? '',
radarrStrictTLS: profile['radarrStrictTLS'] ?? true,
radarrHeaders: profile['radarrHeaders'] ?? {},
//Lidarr
lidarrEnabled: profile['lidarrEnabled'] ?? false,
lidarrHost: profile['lidarrHost'] ?? '',
lidarrKey: profile['lidarrKey'] ?? '',
lidarrStrictTLS: profile['lidarrStrictTLS'] ?? true,
lidarrHeaders: profile['lidarrHeaders'] ?? {},
//SABnzbd
sabnzbdEnabled: profile['sabnzbdEnabled'] ?? false,
sabnzbdHost: profile['sabnzbdHost'] ?? '',
sabnzbdKey: profile['sabnzbdKey'] ?? '',
sabnzbdStrictTLS: profile['sabnzbdStrictTLS'] ?? true,
sabnzbdHeaders: profile['sabnzbdHeaders'] ?? {},
//NZBGet
nzbgetEnabled: profile['nzbgetEnabled'] ?? false,
nzbgetHost: profile['nzbgetHost'] ?? '',
nzbgetUser: profile['nzbgetUser'] ?? '',
nzbgetPass: profile['nzbgetPass'] ?? '',
nzbgetStrictTLS: profile['nzbgetStrictTLS'] ?? true,
nzbgetBasicAuth: profile['nzbgetBasicAuth'] ?? false,
nzbgetHeaders: profile['nzbgetHeaders'] ?? {},
//Wake on LAN
@@ -53,8 +50,12 @@ class Import {
tautulliEnabled: profile['tautulliEnabled'] ?? false,
tautulliHost: profile['tautulliHost'] ?? '',
tautulliKey: profile['tautulliKey'] ?? '',
tautulliStrictTLS: profile['tautulliStrictTLS'] ?? true,
tautulliHeaders: profile['tautulliHeaders'] ?? {},
//Ombi
ombiEnabled: profile['ombiEnabled'] ?? false,
ombiHost: profile['ombiHost'] ?? '',
ombiKey: profile['ombiKey'] ?? '',
ombiHeaders: profile['ombiHeaders'] ?? {},
));
}
}
@@ -86,13 +87,13 @@ class Import {
Database.clearProfilesBox();
}
static Future<bool> import(String data) async {
static Future<bool> import(BuildContext context, String data) async {
Map _config = json.decode(data);
if(_validate(_config)) {
_clearBoxes();
_setProfiles(_config['profiles']);
_setIndexers(_config['indexers']);
_setLunaSea(_config['lunasea']);
_setLunaSea(context, _config['lunasea']);
return true;
}
return false;

View File

@@ -13,10 +13,11 @@ import 'package:lunasea/modules.dart' show
class Constants {
Constants._();
static const APPLICATION_NAME = "LunaSea";
static const SENTRY_DSN = "https://511f76efcf714ecfb5ed6b26b5819bd6@o426090.ingest.sentry.io/5367513";
//Services
static const Map<String, ModuleMap> MODULE_MAP = {
static const APPLICATION_NAME = 'LunaSea';
static const SENTRY_DSN = 'https://511f76efcf714ecfb5ed6b26b5819bd6@o426090.ingest.sentry.io/5367513';
static const Map<String, LunaModuleMap> MODULE_MAP = {
LidarrConstants.MODULE_KEY: LidarrConstants.MODULE_MAP,
RadarrConstants.MODULE_KEY: RadarrConstants.MODULE_MAP,
SonarrConstants.MODULE_KEY: SonarrConstants.MODULE_MAP,
@@ -27,27 +28,17 @@ class Constants {
WakeOnLANConstants.MODULE_KEY: WakeOnLANConstants.MODULE_MAP,
TautulliConstants.MODULE_KEY: TautulliConstants.MODULE_MAP,
};
//Colors
static const PRIMARY_COLOR = 0xFF32323E;
static const SECONDARY_COLOR = 0xFF282834;
static const ACCENT_COLOR = 0xFF4ECCA3;
static const SPLASH_COLOR = 0xFF2EA07B;
//
static const LIST_COLOR_ICONS = [
Colors.blue,
Color(ACCENT_COLOR),
Colors.red,
Colors.orange,
Colors.purpleAccent,
Colors.blueGrey,
];
//Text
static const EMPTY_MAP = {};
static const EMPTY_LIST = [];
static const EMPTY_STRING = '';
static const TEXT_EMDASH = '';
static const TEXT_BULLET = '';
static const TEXT_RARROW = '';
static const TEXT_LARROW = '';
static const TEXT_ELLIPSIS = '';
//UI
static const UI_ELEVATION = 0.0;
static const UI_CARD_MARGIN = EdgeInsets.symmetric(horizontal: 12.0, vertical: 6.0);
static const UI_NAVIGATION_SPEED = 250;
@@ -59,19 +50,15 @@ class Constants {
static const UI_FONT_SIZE_TITLE = 16.0;
static const UI_FONT_SIZE_SUBTITLE = 13.0;
static const UI_FONT_SIZE_GRAPH_LEGEND = 10.0;
//General
static const EMPTY_MAP = {};
static const EMPTY_LIST = [];
static const EMPTY_STRING = '';
//Error Values
static const CONFIGURATION_INVALID = '<<INVALID_CONFIGURATION>>';
static const ENCRYPTION_FAILURE = '<<INVALID_ENCRYPTION>>';
static const NO_SERVICES_ENABLED = '<<NO_SERVICES_ENABLED>>';
static const CHECK_LOGS_MESSAGE = 'Please check the logs for more details';
//Extensions
static const BIT_SIZES = ['b', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb', 'Eb'];
static const BYTE_SIZES = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'];
//URLs
static const URL_DOCUMENTATION = 'https://docs.lunasea.app';
static const URL_GITHUB = 'https://github.com/JagandeepBrar/LunaSea';
static const URL_REDDIT = 'https://www.reddit.com/r/LunaSeaApp';
@@ -83,7 +70,7 @@ class Constants {
static const URL_SENTRY = 'https://sentry.io';
static const URL_TESTFLIGHT = 'https://testflight.apple.com/join/WWXaybra';
static const USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15';
//Automation
static const Map historyReasonMessages = {
'Upgrade': 'Upgraded File',
'MissingFromDisk': 'Missing From Disk',

View File

@@ -5,8 +5,14 @@ import 'package:lunasea/modules.dart';
part 'profile.g.dart';
//Next HiveField ID: 31
//Next HiveField ID: 40
/**
* Dead Fields
* 16, 17, 18, 19, 20, 34
*/
/// Hive database object containing all profile fields
@HiveType(typeId: 0, adapterName: 'ProfileHiveObjectAdapter')
class ProfileHiveObject extends HiveObject {
factory ProfileHiveObject.empty() {
@@ -15,33 +21,28 @@ class ProfileHiveObject extends HiveObject {
lidarrEnabled: false,
lidarrHost: '',
lidarrKey: '',
lidarrStrictTLS: true,
lidarrHeaders: {},
//Radarr
radarrEnabled: false,
radarrHost: '',
radarrKey: '',
radarrStrictTLS: true,
radarrHeaders: {},
//Sonarr
sonarrEnabled: false,
sonarrHost: '',
sonarrKey: '',
sonarrStrictTLS: true,
sonarrVersion3: false,
sonarrHeaders: {},
//SABnzbd
sabnzbdEnabled: false,
sabnzbdHost: '',
sabnzbdKey: '',
sabnzbdStrictTLS: true,
sabnzbdHeaders: {},
//NZBGet
nzbgetEnabled: false,
nzbgetHost: '',
nzbgetUser: '',
nzbgetPass: '',
nzbgetStrictTLS: true,
nzbgetBasicAuth: false,
nzbgetHeaders: {},
//Wake on LAN
@@ -52,8 +53,12 @@ class ProfileHiveObject extends HiveObject {
tautulliEnabled: false,
tautulliHost: '',
tautulliKey: '',
tautulliStrictTLS: true,
tautulliHeaders: {},
//Ombi
ombiEnabled: false,
ombiHost: '',
ombiKey: '',
ombiHeaders: {},
);
}
@@ -63,33 +68,28 @@ class ProfileHiveObject extends HiveObject {
lidarrEnabled: obj.lidarrEnabled,
lidarrHost: obj.lidarrHost,
lidarrKey: obj.lidarrKey,
lidarrStrictTLS: obj.lidarrStrictTLS,
lidarrHeaders: obj.lidarrHeaders,
//Radarr
radarrEnabled: obj.radarrEnabled,
radarrHost: obj.radarrHost,
radarrKey: obj.radarrKey,
radarrStrictTLS: obj.radarrStrictTLS,
radarrHeaders: obj.radarrHeaders,
//Sonarr
sonarrEnabled: obj.sonarrEnabled,
sonarrHost: obj.sonarrHost,
sonarrKey: obj.sonarrKey,
sonarrStrictTLS: obj.sonarrStrictTLS,
sonarrVersion3: obj.sonarrVersion3,
sonarrHeaders: obj.sonarrHeaders,
//SABnzbd
sabnzbdEnabled: obj.sabnzbdEnabled,
sabnzbdHost: obj.sabnzbdHost,
sabnzbdKey: obj.sabnzbdKey,
sabnzbdStrictTLS: obj.sabnzbdStrictTLS,
sabnzbdHeaders: obj.sabnzbdHeaders,
//NZBGet
nzbgetEnabled: obj.nzbgetEnabled,
nzbgetHost: obj.nzbgetHost,
nzbgetUser: obj.nzbgetUser,
nzbgetPass: obj.nzbgetPass,
nzbgetStrictTLS: obj.nzbgetStrictTLS,
nzbgetBasicAuth: obj.nzbgetBasicAuth,
nzbgetHeaders: obj.nzbgetHeaders,
//Wake On LAN
@@ -100,8 +100,12 @@ class ProfileHiveObject extends HiveObject {
tautulliEnabled: obj.tautulliEnabled,
tautulliHost: obj.tautulliHost,
tautulliKey: obj.tautulliKey,
tautulliStrictTLS: obj.tautulliStrictTLS,
tautulliHeaders: obj.tautulliHeaders,
//Ombi
ombiEnabled: obj.ombiEnabled,
ombiHost: obj.ombiHost,
ombiKey: obj.ombiKey,
ombiHeaders: obj.ombiHeaders,
);
}
@@ -110,33 +114,28 @@ class ProfileHiveObject extends HiveObject {
@required this.lidarrEnabled,
@required this.lidarrHost,
@required this.lidarrKey,
@required this.lidarrStrictTLS,
@required this.lidarrHeaders,
//Radarr
@required this.radarrEnabled,
@required this.radarrHost,
@required this.radarrKey,
@required this.radarrStrictTLS,
@required this.radarrHeaders,
//Sonarr
@required this.sonarrEnabled,
@required this.sonarrHost,
@required this.sonarrKey,
@required this.sonarrStrictTLS,
@required this.sonarrVersion3,
@required this.sonarrHeaders,
//SABnzbd
@required this.sabnzbdEnabled,
@required this.sabnzbdHost,
@required this.sabnzbdKey,
@required this.sabnzbdStrictTLS,
@required this.sabnzbdHeaders,
//NZBGet
@required this.nzbgetEnabled,
@required this.nzbgetHost,
@required this.nzbgetUser,
@required this.nzbgetPass,
@required this.nzbgetStrictTLS,
@required this.nzbgetBasicAuth,
@required this.nzbgetHeaders,
//Wake On LAN
@@ -147,14 +146,16 @@ class ProfileHiveObject extends HiveObject {
@required this.tautulliEnabled,
@required this.tautulliHost,
@required this.tautulliKey,
@required this.tautulliStrictTLS,
@required this.tautulliHeaders,
//Ombi
@required this.ombiEnabled,
@required this.ombiHost,
@required this.ombiKey,
@required this.ombiHeaders,
});
@override
String toString() {
return toMap().toString();
}
String toString() => toMap().toString();
Map<String, dynamic> toMap() {
return {
@@ -163,33 +164,28 @@ class ProfileHiveObject extends HiveObject {
"sonarrEnabled": sonarrEnabled,
"sonarrHost": sonarrHost,
"sonarrKey": sonarrKey,
"sonarrStrictTLS": sonarrStrictTLS,
"sonarrVersion3": sonarrVersion3,
"sonarrHeaders": sonarrHeaders,
//Radarr
"radarrEnabled": radarrEnabled,
"radarrHost": radarrHost,
"radarrKey": radarrKey,
"radarrStrictTLS": radarrStrictTLS,
"radarrHeaders": radarrHeaders,
//Lidarr
"lidarrEnabled": lidarrEnabled,
"lidarrHost": lidarrHost,
"lidarrKey": lidarrKey,
"lidarrStrictTLS": lidarrStrictTLS,
"lidarrHeaders": lidarrHeaders,
//SABnzbd
"sabnzbdEnabled": sabnzbdEnabled,
"sabnzbdHost": sabnzbdHost,
"sabnzbdKey": sabnzbdKey,
"sabnzbdStrictTLS": sabnzbdStrictTLS,
"sabnzbdHeaders": sabnzbdHeaders,
//NZBGet
"nzbgetEnabled": nzbgetEnabled,
"nzbgetHost": nzbgetHost,
"nzbgetUser": nzbgetUser,
"nzbgetPass": nzbgetPass,
"nzbgetStrictTLS": nzbgetStrictTLS,
"nzbgetBasicAuth": nzbgetBasicAuth,
"nzbgetHeaders": nzbgetHeaders,
//Wake On LAN
@@ -200,8 +196,12 @@ class ProfileHiveObject extends HiveObject {
"tautulliEnabled": tautulliEnabled,
"tautulliHost": tautulliHost,
"tautulliKey": tautulliKey,
"tautulliStrictTLS": tautulliStrictTLS,
"tautulliHeaders": tautulliHeaders,
//Ombi
"ombiEnabled": ombiEnabled,
"ombiHost": ombiHost,
"ombiKey": ombiKey,
"ombiHeaders": ombiHeaders,
};
}
@@ -212,8 +212,6 @@ class ProfileHiveObject extends HiveObject {
String lidarrHost;
@HiveField(2)
String lidarrKey;
@HiveField(18)
bool lidarrStrictTLS;
@HiveField(26)
Map lidarrHeaders;
@@ -221,7 +219,6 @@ class ProfileHiveObject extends HiveObject {
'enabled': lidarrEnabled ?? false,
'host': lidarrHost ?? '',
'key': lidarrKey ?? '',
'strict_tls': lidarrStrictTLS ?? true,
'headers': lidarrHeaders ?? {},
};
@@ -232,8 +229,6 @@ class ProfileHiveObject extends HiveObject {
String radarrHost;
@HiveField(5)
String radarrKey;
@HiveField(17)
bool radarrStrictTLS;
@HiveField(27)
Map radarrHeaders;
@@ -241,7 +236,6 @@ class ProfileHiveObject extends HiveObject {
'enabled': radarrEnabled ?? false,
'host': radarrHost ?? '',
'key': radarrKey ?? '',
'strict_tls': radarrStrictTLS ?? true,
'headers': radarrHeaders ?? {},
};
@@ -252,8 +246,6 @@ class ProfileHiveObject extends HiveObject {
String sonarrHost;
@HiveField(8)
String sonarrKey;
@HiveField(16)
bool sonarrStrictTLS;
@HiveField(21)
bool sonarrVersion3;
@HiveField(28)
@@ -263,7 +255,6 @@ class ProfileHiveObject extends HiveObject {
'enabled': sonarrEnabled ?? false,
'host': sonarrHost ?? '',
'key': sonarrKey ?? '',
'strict_tls': sonarrStrictTLS ?? true,
'v3': sonarrVersion3 ?? false,
'headers': sonarrHeaders ?? {},
};
@@ -275,8 +266,6 @@ class ProfileHiveObject extends HiveObject {
String sabnzbdHost;
@HiveField(11)
String sabnzbdKey;
@HiveField(19)
bool sabnzbdStrictTLS;
@HiveField(29)
Map sabnzbdHeaders;
@@ -284,7 +273,6 @@ class ProfileHiveObject extends HiveObject {
'enabled': sabnzbdEnabled ?? false,
'host': sabnzbdHost ?? '',
'key': sabnzbdKey ?? '',
'strict_tls': sabnzbdStrictTLS ?? true,
'headers': sabnzbdHeaders ?? {},
};
@@ -297,8 +285,6 @@ class ProfileHiveObject extends HiveObject {
String nzbgetUser;
@HiveField(15)
String nzbgetPass;
@HiveField(20)
bool nzbgetStrictTLS;
@HiveField(22)
bool nzbgetBasicAuth;
@HiveField(30)
@@ -309,7 +295,6 @@ class ProfileHiveObject extends HiveObject {
'host': nzbgetHost ?? '',
'user': nzbgetUser ?? '',
'pass': nzbgetPass ?? '',
'strict_tls': nzbgetStrictTLS ?? true,
'basic_auth': nzbgetBasicAuth ?? false,
'headers': nzbgetHeaders ?? {},
};
@@ -335,8 +320,6 @@ class ProfileHiveObject extends HiveObject {
String tautulliHost;
@HiveField(33)
String tautulliKey;
@HiveField(34)
bool tautulliStrictTLS;
@HiveField(35)
Map tautulliHeaders;
@@ -344,10 +327,26 @@ class ProfileHiveObject extends HiveObject {
'enabled': tautulliEnabled ?? false,
'host': tautulliHost ?? '',
'key': tautulliKey ?? '',
'strict_tls': tautulliStrictTLS ?? true,
'headers': tautulliHeaders ?? {},
};
//Ombi
@HiveField(36)
bool ombiEnabled;
@HiveField(37)
String ombiHost;
@HiveField(38)
String ombiKey;
@HiveField(39)
Map ombiHeaders;
Map<String, dynamic> getOmbi() => {
'enabled': ombiEnabled ?? false,
'host': ombiHost ?? '',
'key': ombiKey ?? '',
'headers': ombiHeaders ?? {},
};
List<String> get enabledModules => [
...enabledAutomationModules,
...enabledClientModules,
@@ -367,17 +366,11 @@ class ProfileHiveObject extends HiveObject {
List<String> get enabledMonitoringModules => [
if(tautulliEnabled ?? false) TautulliConstants.MODULE_KEY,
if(ombiEnabled ?? false) OmbiConstants.MODULE_KEY,
];
bool get anyAutomationEnabled => enabledAutomationModules.isNotEmpty;
bool get anyClientsEnabled => enabledClientModules.isNotEmpty;
bool get anyMonitoringEnabled => enabledMonitoringModules.isNotEmpty;
bool get anythingEnabled => anyAutomationEnabled || anyClientsEnabled || anyMonitoringEnabled;
@override
Future<void> save({ @required BuildContext context }) {
super.save();
Providers.reset(context);
return null;
}
}

View File

@@ -20,29 +20,24 @@ class ProfileHiveObjectAdapter extends TypeAdapter<ProfileHiveObject> {
lidarrEnabled: fields[0] as bool,
lidarrHost: fields[1] as String,
lidarrKey: fields[2] as String,
lidarrStrictTLS: fields[18] as bool,
lidarrHeaders: (fields[26] as Map)?.cast<dynamic, dynamic>(),
radarrEnabled: fields[3] as bool,
radarrHost: fields[4] as String,
radarrKey: fields[5] as String,
radarrStrictTLS: fields[17] as bool,
radarrHeaders: (fields[27] as Map)?.cast<dynamic, dynamic>(),
sonarrEnabled: fields[6] as bool,
sonarrHost: fields[7] as String,
sonarrKey: fields[8] as String,
sonarrStrictTLS: fields[16] as bool,
sonarrVersion3: fields[21] as bool,
sonarrHeaders: (fields[28] as Map)?.cast<dynamic, dynamic>(),
sabnzbdEnabled: fields[9] as bool,
sabnzbdHost: fields[10] as String,
sabnzbdKey: fields[11] as String,
sabnzbdStrictTLS: fields[19] as bool,
sabnzbdHeaders: (fields[29] as Map)?.cast<dynamic, dynamic>(),
nzbgetEnabled: fields[12] as bool,
nzbgetHost: fields[13] as String,
nzbgetUser: fields[14] as String,
nzbgetPass: fields[15] as String,
nzbgetStrictTLS: fields[20] as bool,
nzbgetBasicAuth: fields[22] as bool,
nzbgetHeaders: (fields[30] as Map)?.cast<dynamic, dynamic>(),
wakeOnLANEnabled: fields[23] as bool,
@@ -51,23 +46,24 @@ class ProfileHiveObjectAdapter extends TypeAdapter<ProfileHiveObject> {
tautulliEnabled: fields[31] as bool,
tautulliHost: fields[32] as String,
tautulliKey: fields[33] as String,
tautulliStrictTLS: fields[34] as bool,
tautulliHeaders: (fields[35] as Map)?.cast<dynamic, dynamic>(),
ombiEnabled: fields[36] as bool,
ombiHost: fields[37] as String,
ombiKey: fields[38] as String,
ombiHeaders: (fields[39] as Map)?.cast<dynamic, dynamic>(),
);
}
@override
void write(BinaryWriter writer, ProfileHiveObject obj) {
writer
..writeByte(36)
..writeByte(34)
..writeByte(0)
..write(obj.lidarrEnabled)
..writeByte(1)
..write(obj.lidarrHost)
..writeByte(2)
..write(obj.lidarrKey)
..writeByte(18)
..write(obj.lidarrStrictTLS)
..writeByte(26)
..write(obj.lidarrHeaders)
..writeByte(3)
@@ -76,8 +72,6 @@ class ProfileHiveObjectAdapter extends TypeAdapter<ProfileHiveObject> {
..write(obj.radarrHost)
..writeByte(5)
..write(obj.radarrKey)
..writeByte(17)
..write(obj.radarrStrictTLS)
..writeByte(27)
..write(obj.radarrHeaders)
..writeByte(6)
@@ -86,8 +80,6 @@ class ProfileHiveObjectAdapter extends TypeAdapter<ProfileHiveObject> {
..write(obj.sonarrHost)
..writeByte(8)
..write(obj.sonarrKey)
..writeByte(16)
..write(obj.sonarrStrictTLS)
..writeByte(21)
..write(obj.sonarrVersion3)
..writeByte(28)
@@ -98,8 +90,6 @@ class ProfileHiveObjectAdapter extends TypeAdapter<ProfileHiveObject> {
..write(obj.sabnzbdHost)
..writeByte(11)
..write(obj.sabnzbdKey)
..writeByte(19)
..write(obj.sabnzbdStrictTLS)
..writeByte(29)
..write(obj.sabnzbdHeaders)
..writeByte(12)
@@ -110,8 +100,6 @@ class ProfileHiveObjectAdapter extends TypeAdapter<ProfileHiveObject> {
..write(obj.nzbgetUser)
..writeByte(15)
..write(obj.nzbgetPass)
..writeByte(20)
..write(obj.nzbgetStrictTLS)
..writeByte(22)
..write(obj.nzbgetBasicAuth)
..writeByte(30)
@@ -128,10 +116,16 @@ class ProfileHiveObjectAdapter extends TypeAdapter<ProfileHiveObject> {
..write(obj.tautulliHost)
..writeByte(33)
..write(obj.tautulliKey)
..writeByte(34)
..write(obj.tautulliStrictTLS)
..writeByte(35)
..write(obj.tautulliHeaders);
..write(obj.tautulliHeaders)
..writeByte(36)
..write(obj.ombiEnabled)
..writeByte(37)
..write(obj.ombiHost)
..writeByte(38)
..write(obj.ombiKey)
..writeByte(39)
..write(obj.ombiHeaders);
}
@override

View File

@@ -15,6 +15,10 @@ import 'package:lunasea/modules.dart' show
export 'package:hive/hive.dart';
export 'package:hive_flutter/hive_flutter.dart';
/// Next HiveType: 16
///
/// Dead Fields:
class Database {
Database._();
@@ -59,7 +63,6 @@ class Database {
//Set default profile & enabled profile
profilesBox.put('default', ProfileHiveObject.empty());
lunaSeaBox.put(LunaSeaDatabaseValue.ENABLED_PROFILE.key, 'default');
}
//Get boxes

View File

@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lunasea/core.dart';
class GlobalDialogs {
GlobalDialogs._();
class LunaDialogs {
LunaDialogs._();
static Future<List<dynamic>> editText(BuildContext context, String title, { String prefill = '' }) async {
bool _flag = false;
@@ -95,7 +95,7 @@ class GlobalDialogs {
buttons: [
LSDialog.button(
text: 'Delete',
textColor: LSColors.red,
textColor: LunaColours.red,
onPressed: () => _setValues(true),
),
],

View File

@@ -1,8 +1,8 @@
import 'package:encrypt/encrypt.dart';
import 'package:lunasea/core.dart';
class Encryption {
Encryption._();
class LunaEncryption {
LunaEncryption._();
static String encrypt(String encryptionKey, String data) {
try {
@@ -13,7 +13,7 @@ class Encryption {
final _encrypted = _encrypter.encrypt(data, iv: iv).base64;
return _encrypted;
} catch (e) {
Logger.error('package:lunasea/core/configuration/encryption.dart', 'encrypt', 'Encryption error', e, StackTrace.current);
LunaLogger.error('package:lunasea/core/configuration/encryption.dart', 'encrypt', 'Encryption error', e, StackTrace.current);
}
return Constants.ENCRYPTION_FAILURE;
}
@@ -26,7 +26,7 @@ class Encryption {
final _encrypter = Encrypter(AES(key));
return _encrypter.decrypt64(data, iv: iv);
} catch (e) {
Logger.error('package:lunasea/core/configuration/encryption.dart', 'decrypt', 'Decryption error', e, StackTrace.current);
LunaLogger.error('package:lunasea/core/configuration/encryption.dart', 'decrypt', 'Decryption error', e, StackTrace.current);
}
return Constants.ENCRYPTION_FAILURE;
}

View File

@@ -11,7 +11,7 @@ extension FLogLogLevelExtension on FLog.LogLevel {
switch(this.toString()) {
case 'LogLevel.WARNING': return Colors.orange;
case 'LogLevel.ERROR': return Colors.red;
case 'LogLevel.FATAL': return LSColors.accent;
case 'LogLevel.FATAL': return LunaColours.accent;
default: return Colors.blueGrey;
}
}

View File

@@ -6,10 +6,10 @@ extension ProductDetailsExtension on ProductDetails {
//ignore: non_constant_identifier_names
IconData get ls_Icon {
switch(this.id) {
case InAppPurchases.IAP_ID_DONATION_01: return Icons.local_drink;
case InAppPurchases.IAP_ID_DONATION_03: return Icons.local_cafe;
case InAppPurchases.IAP_ID_DONATION_05: return Icons.local_bar;
case InAppPurchases.IAP_ID_DONATION_10: return Icons.fastfood;
case LunaInAppPurchases.IAP_ID_DONATION_01: return Icons.local_drink;
case LunaInAppPurchases.IAP_ID_DONATION_03: return Icons.local_cafe;
case LunaInAppPurchases.IAP_ID_DONATION_05: return Icons.local_bar;
case LunaInAppPurchases.IAP_ID_DONATION_10: return Icons.fastfood;
default: return Icons.attach_money;
}
}
@@ -17,10 +17,10 @@ extension ProductDetailsExtension on ProductDetails {
//ignore: non_constant_identifier_names
String get ls_Name {
switch(this.id) {
case InAppPurchases.IAP_ID_DONATION_01: return 'Buy Me A Soda';
case InAppPurchases.IAP_ID_DONATION_03: return 'Buy Me A Coffee';
case InAppPurchases.IAP_ID_DONATION_05: return 'Buy Me A Beer';
case InAppPurchases.IAP_ID_DONATION_10: return 'Buy Me A Burger';
case LunaInAppPurchases.IAP_ID_DONATION_01: return 'Buy Me A Soda';
case LunaInAppPurchases.IAP_ID_DONATION_03: return 'Buy Me A Coffee';
case LunaInAppPurchases.IAP_ID_DONATION_05: return 'Buy Me A Beer';
case LunaInAppPurchases.IAP_ID_DONATION_10: return 'Buy Me A Burger';
default: return 'Unknown In-App Purchase';
}
}

View File

@@ -2,8 +2,8 @@ import 'dart:io';
import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';
class Filesystem {
Filesystem._();
class LunaFileSystem {
LunaFileSystem._();
static String get configFileName {
String _now = DateFormat('y-MM-dd kk-mm-ss').format(DateTime.now());

View File

@@ -1,7 +1,7 @@
import 'dart:async';
import 'package:in_app_purchase/in_app_purchase.dart';
class InAppPurchases {
class LunaInAppPurchases {
static const IAP_ID_DONATION_01 = 'donation_01';
static const IAP_ID_DONATION_03 = 'donation_03';
static const IAP_ID_DONATION_05 = 'donation_05';
@@ -21,7 +21,7 @@ class InAppPurchases {
static Future<void> initialize() async {
InAppPurchaseConnection.enablePendingPurchases();
purchaseStream = connection.purchaseUpdatedStream.listen((data) => InAppPurchases._purchasedCallback(data));
purchaseStream = connection.purchaseUpdatedStream.listen((data) => LunaInAppPurchases._purchasedCallback(data));
available = await connection.isAvailable();
ProductDetailsResponse _resp = await connection.queryProductDetails(Set.from(IAP_IDS));
products = _resp.productDetails;

View File

@@ -7,8 +7,8 @@ import 'package:stack_trace/stack_trace.dart';
import 'package:f_logs/f_logs.dart' show FLog, DataLogType, FormatType, LogsConfig;
export 'package:dio/dio.dart' show DioError;
class Logger {
Logger._();
class LunaLogger {
LunaLogger._();
static final SentryClient _sentry = SentryClient(dsn: Constants.SENTRY_DSN);
static void initialize() {
@@ -66,9 +66,10 @@ class Logger {
DataLogType type = DataLogType.DEFAULT,
bool uploadToSentry = true,
}) {
Trace _trace = Trace.from(trace);
FLog.fatal(
className: Trace.from(trace).frames[1].uri.toString() ?? 'Unknown',
methodName: Trace.from(trace).frames[1].member.toString() ?? 'Unknown',
className: _trace.frames.length >= 1 ? _trace.frames[1].uri.toString() ?? 'Unknown' : 'Unknown',
methodName: _trace.frames.length >= 1 ? _trace.frames[1].member.toString() ?? 'Unknown' : 'Unknown',
text: error.toString(),
exception: error,
stacktrace: trace,

8
lib/core/luna_ui.dart Normal file
View File

@@ -0,0 +1,8 @@
export 'luna_ui/appbar.dart';
export 'luna_ui/table.dart';
class LunaUI {
static const double FONT_SIZE_APPBAR = 18.0;
LunaUI._();
}

View File

@@ -0,0 +1 @@
export 'appbar/appbar.dart';

View File

@@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
class LunaAppBar extends AppBar {
LunaAppBar({
@required BuildContext context,
@required String title,
@required String popUntil,
List<Widget> actions,
PreferredSizeWidget bottom,
bool hideLeading = false,
}) : super(
title: Text(
title ?? '',
overflow: TextOverflow.fade,
style: TextStyle(
fontSize: LunaUI.FONT_SIZE_APPBAR,
),
),
leading: hideLeading ? null : InkWell(
child: Icon(Icons.arrow_back_ios),
onTap: () async => Navigator.of(context).pop(),
onLongPress: () async => popUntil == null
? Navigator.of(context).pop()
: Navigator.of(context).popUntil(ModalRoute.withName(popUntil)),
borderRadius: BorderRadius.circular(28.0),
),
centerTitle: false,
elevation: 0,
actions: actions,
bottom: bottom,
);
LunaAppBar.empty({
@required Widget child,
@required double height,
}) : super(
automaticallyImplyLeading: false,
toolbarHeight: height,
leadingWidth: 0.0,
elevation: 0.0,
titleSpacing: 0.0,
title: child,
);
}

View File

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
class ModuleMap {
class LunaModuleMap {
final String name;
final String description;
final String settingsDescription;
@@ -8,7 +8,7 @@ class ModuleMap {
final IconData icon;
final Color color;
const ModuleMap({
const LunaModuleMap({
@required this.name,
@required this.description,
@required this.settingsDescription,

12
lib/core/networking.dart Normal file
View File

@@ -0,0 +1,12 @@
import 'dart:io';
class LunaNetworking extends HttpOverrides {
static void initialize() => HttpOverrides.global = LunaNetworking();
@override
HttpClient createHttpClient(SecurityContext context) {
final HttpClient client = super.createHttpClient(context);
client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
return client;
}
}

20
lib/core/profile.dart Normal file
View File

@@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
class LunaProfile {
LunaProfile._();
static Future<bool> changeProfile(BuildContext context, String profile) async {
if(LunaSeaDatabaseValue.ENABLED_PROFILE.data != profile) {
if(Database.profilesBox.containsKey(profile)) {
LunaSeaDatabaseValue.ENABLED_PROFILE.put(profile);
LunaProvider.reset(context);
LSSnackBar(context: context, title: 'Changed Profile', message: profile);
return true;
} else {
LunaLogger.warning('LunaProfile', 'changeProfile', 'Attempted to change profile to unknown profile: $profile');
}
}
return false;
}
}

View File

@@ -6,42 +6,51 @@ import 'package:provider/provider.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/modules.dart' show
HomeState,
LidarrModel,
NZBGetModel,
RadarrState,
SABnzbdModel,
SearchModel,
SearchState,
SettingsState,
SonarrModel,
LidarrState,
RadarrState,
SonarrState,
NZBGetState,
SABnzbdState,
OmbiState,
TautulliState;
class Providers {
Providers._();
class LunaProvider {
LunaProvider._();
static void reset(BuildContext context) {
Provider.of<LunaSeaState>(context, listen: false).reset();
// General
Provider.of<HomeState>(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<OmbiState>(context, listen: false).reset();
Provider.of<TautulliState>(context, listen: false).reset();
}
static MultiProvider providers({ @required Widget child }) => MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => LunaSeaState()),
// General
ChangeNotifierProvider(create: (_) => HomeState()),
ChangeNotifierProvider(create: (_) => SearchModel()),
ChangeNotifierProvider(create: (_) => SearchState()),
ChangeNotifierProvider(create: (_) => SettingsState()),
// Automation
ChangeNotifierProvider(create: (_) => SonarrModel()),
ChangeNotifierProvider(create: (_) => LidarrModel()),
ChangeNotifierProvider(create: (_) => SonarrState()),
ChangeNotifierProvider(create: (_) => LidarrState()),
ChangeNotifierProvider(create: (_) => RadarrState()),
// Clients
ChangeNotifierProvider(create: (_) => NZBGetModel()),
ChangeNotifierProvider(create: (_) => SABnzbdModel()),
ChangeNotifierProvider(create: (_) => NZBGetState()),
ChangeNotifierProvider(create: (_) => SABnzbdState()),
// Monitoring
ChangeNotifierProvider(create: (_) => OmbiState()),
ChangeNotifierProvider(create: (_) => TautulliState()),
],
child: child,

View File

@@ -5,10 +5,10 @@ import 'package:lunasea/modules.dart';
import 'package:lunasea/main.dart';
export 'package:quick_actions/quick_actions.dart' show ShortcutItem;
class HomescreenActions {
class LunaQuickActions {
static final QuickActions _quickActions = QuickActions();
HomescreenActions._();
LunaQuickActions._();
static void initialize(BuildContext context) {
_quickActions.initialize((action) => _handler(context, action));
@@ -37,15 +37,17 @@ class HomescreenActions {
case NZBGetConstants.MODULE_KEY: _pushNZBGet(); break;
case SABnzbdConstants.MODULE_KEY: _pushSABnzbd(); break;
case TautulliConstants.MODULE_KEY: _pushTautulli(); break;
case OmbiConstants.MODULE_KEY: _pushOmbi(); break;
}
}
}
static void _pushSearch() => BIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(Search.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushLidarr() => BIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(Lidarr.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushRadarr() => BIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(Radarr.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushSonarr() => BIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(Sonarr.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushNZBGet() => BIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(NZBGet.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushSABnzbd() => BIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(SABnzbd.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushTautulli() => BIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(TautulliModule.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushSearch() => LunaBIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(Search.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushLidarr() => LunaBIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(Lidarr.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushRadarr() => LunaBIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(Radarr.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushSonarr() => LunaBIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(SonarrHomeRouter.route(), (Route<dynamic> route) => false);
static void _pushNZBGet() => LunaBIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(NZBGet.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushSABnzbd() => LunaBIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(SABnzbd.ROUTE_NAME, (Route<dynamic> route) => false);
static void _pushOmbi() => LunaBIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(OmbiHomeRouter.route(), (Route<dynamic> route) => false);
static void _pushTautulli() => LunaBIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(TautulliHomeRouter.route(), (Route<dynamic> route) => false);
}

View File

@@ -1,37 +1,37 @@
import 'package:flutter/material.dart' hide Router;
import 'package:fluro_fork/fluro_fork.dart';
import 'package:lunasea/modules/home/routes.dart';
import 'package:lunasea/modules/settings.dart' show SettingsModule, SettingsRouter;
import 'package:lunasea/modules/search/routes.dart';
import 'package:lunasea/modules/lidarr/routes.dart';
import 'package:lunasea/modules/radarr/routes.dart';
import 'package:lunasea/modules/sonarr/routes.dart';
import 'package:lunasea/modules/nzbget/routes.dart';
import 'package:lunasea/modules/sabnzbd/routes.dart';
import 'package:lunasea/modules/tautulli.dart' show TautulliModule, TautulliRouter;
import 'package:lunasea/modules/settings.dart' show SettingsRouter;
import 'package:lunasea/modules/sonarr.dart' show SonarrRouter;
import 'package:lunasea/modules/ombi.dart' show OmbiRouter;
import 'package:lunasea/modules/tautulli.dart' show TautulliRouter;
class LunaRouter {
static Router router = Router();
LunaRouter._();
static void intialize() {
// General
SettingsRouter.initialize();
// Monitoring
TautulliRouter.initialize();
SettingsRouter.initialize(router);
SonarrRouter.initialize(router);
OmbiRouter.initialize(router);
TautulliRouter.initialize(router);
}
static TransitionType get transitionType => TransitionType.native;
static Map<String, WidgetBuilder> get routes => <String, WidgetBuilder> {
..._home,
SettingsModule.ROUTE_NAME: (context) => SettingsModule(),
..._search,
..._lidarr,
..._radarr,
..._sonarr,
..._sabnzbd,
..._nzbget,
TautulliModule.ROUTE_NAME: (context) => TautulliModule(),
};
static Map<String, WidgetBuilder> get _home => <String, WidgetBuilder> {
@@ -88,25 +88,6 @@ class LunaRouter {
RadarrSearchResults.ROUTE_NAME: (context) => RadarrSearchResults(),
};
static Map<String, WidgetBuilder> get _sonarr => <String, WidgetBuilder> {
// /sonarr
Sonarr.ROUTE_NAME: (context) => Sonarr(),
// /sonarr/*
SonarrCatalogue.ROUTE_NAME: (context) => SonarrCatalogue(refreshIndicatorKey: null, refreshAllPages: null),
SonarrMissing.ROUTE_NAME: (context) => SonarrMissing(refreshIndicatorKey: null, refreshAllPages: null),
SonarrUpcoming.ROUTE_NAME: (context) => SonarrUpcoming(refreshIndicatorKey: null, refreshAllPages: null),
SonarrHistory.ROUTE_NAME: (context) => SonarrHistory(refreshIndicatorKey: null, refreshAllPages: null),
// /sonarr/add/*
SonarrAddSearch.ROUTE_NAME: (context) => SonarrAddSearch(),
SonarrAddDetails.ROUTE_NAME: (context) => SonarrAddDetails(),
// /sonarr/details/*
SonarrDetailsSeries.ROUTE_NAME: (context) => SonarrDetailsSeries(),
SonarrDetailsSeason.ROUTE_NAME: (context) => SonarrDetailsSeason(),
// /sonarr/*/*
SonarrEditSeries.ROUTE_NAME: (context) => SonarrEditSeries(),
SonarrSearchResults.ROUTE_NAME: (context) => SonarrSearchResults(),
};
static Map<String, WidgetBuilder> get _nzbget => <String, WidgetBuilder> {
// /nzbget
NZBGet.ROUTE_NAME: (context) => NZBGet(),

View File

@@ -1,13 +0,0 @@
import 'package:flutter/foundation.dart';
class LunaSeaState extends ChangeNotifier {
LunaSeaState() {
reset(initialize: true);
}
/// Reset the state of LunaSea back to the default
void reset({ bool initialize = false }) {
if(initialize) {}
notifyListeners();
}
}

View File

@@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lunasea/core.dart';
class Themes {
Themes._();
class LunaTheme {
LunaTheme._();
static ThemeData getDarkTheme() => LunaSeaDatabaseValue.THEME_AMOLED.data
static ThemeData get darkTheme => LunaSeaDatabaseValue.THEME_AMOLED.data
? _pureBlackTheme()
: _midnightTheme();
@@ -15,16 +15,16 @@ class Themes {
);
return ThemeData(
brightness: Brightness.dark,
canvasColor: LSColors.primary,
primaryColor: LSColors.secondary,
accentColor: LSColors.accent,
highlightColor: LSColors.secondary,
cardColor: LSColors.secondary,
splashColor: LSColors.splash,
dialogBackgroundColor: LSColors.secondary,
dividerColor: LSColors.accent.withAlpha(0),
canvasColor: LunaColours.primary,
primaryColor: LunaColours.secondary,
accentColor: LunaColours.accent,
highlightColor: LunaColours.secondary,
cardColor: LunaColours.secondary,
splashColor: LunaColours.splash,
dialogBackgroundColor: LunaColours.secondary,
dividerColor: LunaColours.accent.withAlpha(0),
dividerTheme: DividerThemeData(
color: LSColors.accent,
color: LunaColours.accent,
indent: 100.0,
endIndent: 100.0,
),
@@ -59,14 +59,14 @@ class Themes {
brightness: Brightness.dark,
canvasColor: Colors.black,
primaryColor: Colors.black,
accentColor: LSColors.accent,
highlightColor: LSColors.secondary,
accentColor: LunaColours.accent,
highlightColor: LunaColours.secondary,
cardColor: Colors.black,
splashColor: LSColors.splash,
splashColor: LunaColours.splash,
dialogBackgroundColor: Colors.black,
dividerColor: LSColors.accent.withAlpha(0),
dividerColor: LunaColours.accent.withAlpha(0),
dividerTheme: DividerThemeData(
color: LSColors.accent,
color: LunaColours.accent,
indent: 72.0,
endIndent: 72.0,
),

View File

@@ -1,2 +1,4 @@
export 'types/api.dart';
export 'types/loading.dart';
export 'types/sorter.dart';
export 'types/state_global.dart';

View File

@@ -0,0 +1,5 @@
enum LunaLoadingState {
ACTIVE,
INACTIVE,
ERROR,
}

View File

@@ -1,3 +1,3 @@
abstract class Sorter<T> {
abstract class LunaSorter<T> {
dynamic byType(List data, T type, bool ascending);
}

View File

@@ -0,0 +1,9 @@
import 'package:flutter/material.dart';
abstract class LunaGlobalState extends ChangeNotifier {
/// Reset the state back to the default
void reset();
/// Notify listeners of an update
void notify() => notifyListeners();
}

View File

@@ -1,2 +1 @@
export 'appbar/appbar.dart';
export 'appbar/appbar_dropdown.dart';

View File

@@ -1,19 +0,0 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
// ignore: non_constant_identifier_names
Widget LSAppBar({
@required String title,
List<Widget> actions
}) => AppBar(
title: Text(
title,
overflow: TextOverflow.fade,
style: TextStyle(
fontSize: Constants.UI_FONT_SIZE_HEADER,
),
),
centerTitle: false,
elevation: 0,
actions: actions,
);

View File

@@ -8,49 +8,40 @@ Widget LSAppBarDropdown({
@required List<String> profiles,
List<Widget> actions
}) => profiles != null && profiles.length < 2
? LSAppBar(title: title, actions: actions)
? LunaAppBar(context: context, title: title, actions: actions, popUntil: null, hideLeading: true)
: AppBar(
title: PopupMenuButton<String>(
shape: LunaSeaDatabaseValue.THEME_AMOLED.data && LunaSeaDatabaseValue.THEME_AMOLED_BORDER.data
? LSRoundedShapeWithBorder()
: LSRoundedShape(),
child: Wrap(
direction: Axis.horizontal,
children: [
Text(
title,
style: TextStyle(
fontSize: Constants.UI_FONT_SIZE_HEADER,
title: PopupMenuButton<String>(
shape: LunaSeaDatabaseValue.THEME_AMOLED.data && LunaSeaDatabaseValue.THEME_AMOLED_BORDER.data
? LSRoundedShapeWithBorder()
: LSRoundedShape(),
child: Wrap(
direction: Axis.horizontal,
children: [
Text(
title,
style: TextStyle(
fontSize: Constants.UI_FONT_SIZE_HEADER,
),
),
),
LSIcon(
icon: Icons.arrow_drop_down,
),
],
LSIcon(
icon: Icons.arrow_drop_down,
),
],
),
onSelected: (result) => LunaProfile.changeProfile(context, result),
itemBuilder: (context) {
return <PopupMenuEntry<String>>[for(String profile in profiles) PopupMenuItem<String>(
value: profile,
child: Text(
profile,
style: TextStyle(
fontSize: Constants.UI_FONT_SIZE_SUBTITLE,
),
),
)];
},
),
onSelected: (result) {
LunaSeaDatabaseValue.ENABLED_PROFILE.put(result);
Providers.reset(context);
LSSnackBar(
context: context,
title: 'Changed Profile',
message: 'Using profile "$result"',
type: SNACKBAR_TYPE.info,
);
},
itemBuilder: (context) {
return <PopupMenuEntry<String>>[for(String profile in profiles) PopupMenuItem<String>(
value: profile,
child: Text(
profile,
style: TextStyle(
fontSize: Constants.UI_FONT_SIZE_SUBTITLE,
),
),
)];
},
),
centerTitle: false,
elevation: 0,
actions: actions,
);
centerTitle: false,
elevation: 0,
actions: actions,
);

View File

@@ -11,7 +11,7 @@ class LSButton extends StatelessWidget {
LSButton({
@required this.text,
@required this.onTap,
this.backgroundColor = const Color(Constants.ACCENT_COLOR),
this.backgroundColor = const Color(LunaColours.ACCENT_COLOR),
this.textColor = Colors.white,
this.reducedMargin = false,
});

View File

@@ -11,7 +11,7 @@ class LSButtonSlim extends StatelessWidget {
LSButtonSlim({
@required this.text,
@required this.onTap,
this.backgroundColor = const Color(Constants.ACCENT_COLOR),
this.backgroundColor = const Color(LunaColours.ACCENT_COLOR),
this.textColor = Colors.white,
this.margin = const EdgeInsets.symmetric(horizontal: 6.0, vertical: 6.0),
});

View File

@@ -2,13 +2,13 @@ import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
// ignore: non_constant_identifier_names
Decoration LSCardBackground({ @required String uri, @required Map headers, bool darken = false }) => BoxDecoration(
Decoration LSCardBackground({ @required String uri, @required Map headers }) => BoxDecoration(
image: DecorationImage(
image: NetworkImage(
uri,
headers: Map<String, String>.from(headers),
),
colorFilter: ColorFilter.mode(LSColors.secondary.withOpacity(darken ? 0.10 : 0.20), BlendMode.dstATop),
colorFilter: ColorFilter.mode(LunaColours.secondary.withOpacity(0.10), BlendMode.dstATop),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS),

View File

@@ -1,13 +1,26 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core/constants.dart';
class LSColors {
LSColors._();
class LunaColours {
LunaColours._();
static Color get accent => const Color(Constants.ACCENT_COLOR);
static Color get primary => const Color(Constants.PRIMARY_COLOR);
static Color get secondary => const Color(Constants.SECONDARY_COLOR);
static Color get splash => const Color(Constants.SPLASH_COLOR);
static const PRIMARY_COLOR = 0xFF32323E;
static const SECONDARY_COLOR = 0xFF282834;
static const ACCENT_COLOR = 0xFF4ECCA3;
static const SPLASH_COLOR = 0xFF2EA07B;
static const LIST_COLOR_ICONS = [
Colors.blue,
Color(ACCENT_COLOR),
Colors.red,
Colors.orange,
Colors.purpleAccent,
Colors.blueGrey,
];
static Color get accent => const Color(ACCENT_COLOR);
static Color get primary => const Color(PRIMARY_COLOR);
static Color get secondary => const Color(SECONDARY_COLOR);
static Color get splash => const Color(SPLASH_COLOR);
static Color get blue => Colors.blue;
static Color get orange => Colors.orange;
@@ -16,15 +29,15 @@ class LSColors {
static Color get blueGrey => Colors.blueGrey;
static Color list(int i) {
return Constants.LIST_COLOR_ICONS[i%Constants.LIST_COLOR_ICONS.length];
return LIST_COLOR_ICONS[i%LIST_COLOR_ICONS.length];
}
static Color graph(int i) {
switch(i) {
case 0: return LSColors.accent;
case 1: return LSColors.purple;
case 2: return LSColors.blue;
default: return LSColors.list(i);
case 0: return LunaColours.accent;
case 1: return LunaColours.purple;
case 2: return LunaColours.blue;
default: return LunaColours.list(i);
}
}
}

View File

@@ -62,7 +62,7 @@ class _State extends State<LSDescriptionBlock> {
],
),
borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS),
onTap: () => GlobalDialogs.textPreview(context, widget.title, widget.description.trim() ?? 'No summary is available.'),
onTap: () => LunaDialogs.textPreview(context, widget.title, widget.description.trim() ?? 'No summary is available.'),
),
);
}

View File

@@ -20,9 +20,9 @@ abstract class LSDialog {
text: text,
style: TextStyle(
color: color == null
? LSColors.accent
? LunaColours.accent
: color,
fontWeight: FontWeight.bold,
fontWeight: FontWeight.w600,
fontSize: fontSize,
),
);
@@ -42,7 +42,7 @@ abstract class LSDialog {
text,
style: TextStyle(
color: textColor == null
? LSColors.accent
? LunaColours.accent
: textColor,
fontSize: LSDialog.BUTTON_SIZE,
),
@@ -101,17 +101,17 @@ abstract class LSDialog {
fontSize: LSDialog.BODY_SIZE,
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: LSColors.accent),
borderSide: BorderSide(color: LunaColours.accent),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: LSColors.accent.withOpacity(0.3)),
borderSide: BorderSide(color: LunaColours.accent.withOpacity(0.3)),
),
),
style: TextStyle(
color: Colors.white,
fontSize: LSDialog.BODY_SIZE,
),
cursorColor: LSColors.accent,
cursorColor: LunaColours.accent,
textInputAction: TextInputAction.done,
onSubmitted: onSubmitted,
);
@@ -137,17 +137,17 @@ abstract class LSDialog {
fontSize: LSDialog.BODY_SIZE,
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: LSColors.accent),
borderSide: BorderSide(color: LunaColours.accent),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: LSColors.accent.withOpacity(0.3)),
borderSide: BorderSide(color: LunaColours.accent.withOpacity(0.3)),
),
),
style: TextStyle(
color: Colors.white,
fontSize: LSDialog.BODY_SIZE,
),
cursorColor: LSColors.accent,
cursorColor: LunaColours.accent,
textInputAction: TextInputAction.done,
validator: validator,
onFieldSubmitted: onSubmitted,
@@ -165,7 +165,7 @@ abstract class LSDialog {
children: <Widget>[
LSIcon(
icon: icon ?? Icons.error_outline,
color: iconColor ?? LSColors.accent,
color: iconColor ?? LunaColours.accent,
),
],
),
@@ -202,7 +202,7 @@ abstract class LSDialog {
actions: <Widget>[
LSDialog.cancel(
context,
textColor: buttons != null ? Colors.white : LSColors.accent,
textColor: buttons != null ? Colors.white : LunaColours.accent,
),
if(buttons != null) ...buttons,
],

View File

@@ -5,6 +5,6 @@ class LSDivider extends StatelessWidget {
@override
Widget build(BuildContext context) => Divider(
thickness: 1.0,
color: LSColors.splash,
color: LunaColours.splash,
);
}

View File

@@ -127,20 +127,20 @@ class LSDrawerCategories extends StatelessWidget {
return ListTile(
leading: LSIcon(
icon: icon,
color: currentPage ? LSColors.accent : Colors.white,
color: currentPage ? LunaColours.accent : Colors.white,
),
title: Text(
title,
style: TextStyle(
color: currentPage
? LSColors.accent
? LunaColours.accent
: Colors.white,
fontSize: Constants.UI_FONT_SIZE_SUBTITLE,
),
),
onTap: () async {
Navigator.of(context).pop();
if(!currentPage) BIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(route, (Route<dynamic> route) => false);
if(!currentPage) LunaBIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(route, (Route<dynamic> route) => false);
},
contentPadding: padLeft
? EdgeInsets.fromLTRB(42.0, 0.0, 0.0, 0.0)

View File

@@ -26,16 +26,7 @@ Widget LSDrawerHeader() => UserAccountsDrawerHeader(
),
],
),
onSelected: (result) {
LunaSeaDatabaseValue.ENABLED_PROFILE.put(result);
Providers.reset(context);
LSSnackBar(
context: context,
title: 'Changed Profile',
message: 'Using profile "$result"',
type: SNACKBAR_TYPE.info,
);
},
onSelected: (result) => LunaProfile.changeProfile(context, result),
itemBuilder: (context) {
return <PopupMenuEntry<String>>[for(String profile in (profilesBox as Box).keys) PopupMenuItem<String>(
value: profile,
@@ -53,10 +44,10 @@ Widget LSDrawerHeader() => UserAccountsDrawerHeader(
),
),
decoration: BoxDecoration(
color: LSColors.accent,
color: LunaColours.accent,
image: DecorationImage(
image: AssetImage('assets/branding/icon_drawer.png'),
colorFilter: ColorFilter.mode(LSColors.primary.withOpacity(0.15), BlendMode.dstATop),
colorFilter: ColorFilter.mode(LunaColours.primary.withOpacity(0.15), BlendMode.dstATop),
fit: BoxFit.cover,
),
),

View File

@@ -93,20 +93,20 @@ class LSDrawerNoCategories extends StatelessWidget {
return ListTile(
leading: LSIcon(
icon: icon,
color: currentPage ? LSColors.accent : Colors.white,
color: currentPage ? LunaColours.accent : Colors.white,
),
title: Text(
title,
style: TextStyle(
color: currentPage
? LSColors.accent
? LunaColours.accent
: Colors.white,
fontSize: Constants.UI_FONT_SIZE_SUBTITLE,
),
),
onTap: () async {
Navigator.of(context).pop();
if(!currentPage) BIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(route, (Route<dynamic> route) => false);
if(!currentPage) LunaBIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(route, (Route<dynamic> route) => false);
},
contentPadding: EdgeInsets.fromLTRB(16.0, 0.0, 0.0, 0.0),
);

View File

@@ -22,7 +22,7 @@ class LSFloatingActionButton extends StatelessWidget {
heroTag: heroTag,
onPressed: onPressed,
backgroundColor: backgroundColor == null
? LSColors.accent
? LunaColours.accent
: backgroundColor,
);
}

View File

@@ -28,7 +28,7 @@ class LSFloatingActionButtonAnimated extends StatelessWidget {
heroTag: heroTag,
onPressed: onPressed,
backgroundColor: backgroundColor == null
? LSColors.accent
? LunaColours.accent
: backgroundColor,
);
}

View File

@@ -35,7 +35,7 @@ class LSFloatingActionButtonExtended extends StatelessWidget {
heroTag: heroTag,
onPressed: onPressed,
backgroundColor: backgroundColor == null
? LSColors.accent
? LunaColours.accent
: backgroundColor,
);
}

View File

@@ -44,7 +44,7 @@ class _State extends State<LSTextInputBar> {
child: GestureDetector(
child: Icon(
Icons.close,
color: LSColors.accent,
color: LunaColours.accent,
size: 24.0,
),
onTap: () => widget.onChanged('', true),
@@ -55,7 +55,7 @@ class _State extends State<LSTextInputBar> {
icon: Padding(
child: Icon(
widget.labelIcon,
color: LSColors.accent,
color: LunaColours.accent,
),
padding: EdgeInsets.only(left: 16.0),
),
@@ -66,7 +66,7 @@ class _State extends State<LSTextInputBar> {
color: Colors.white,
fontSize: Constants.UI_FONT_SIZE_SUBTITLE,
),
cursorColor: LSColors.accent,
cursorColor: LunaColours.accent,
textInputAction: widget.action,
autocorrect: false,
onChanged: (value) => widget.onChanged(value, false),

View File

@@ -3,16 +3,17 @@ import 'package:flutter/material.dart';
class LSListView extends StatelessWidget {
final List<Widget> children;
final EdgeInsetsGeometry customPadding;
final ScrollController controller = ScrollController();
final ScrollController controller;
LSListView({
@required this.children,
this.controller,
this.customPadding = const EdgeInsets.symmetric(vertical: 8.0),
});
@override
Widget build(BuildContext context) => Scrollbar(
controller: controller,
controller: controller == null ? ScrollController() : controller,
child: ListView(
controller: controller,
children: children,

View File

@@ -18,7 +18,7 @@ class LSLoader extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SpinKitThreeBounce(
color: color != null ? color : LSColors.accent,
color: color != null ? color : LunaColours.accent,
size: size,
),
],

View File

@@ -26,7 +26,7 @@ class LSBottomNavigationBar extends StatelessWidget {
padding: EdgeInsets.fromLTRB(18.0, 5.0, 12.0, 5.0),
duration: Duration(milliseconds: Constants.UI_NAVIGATION_SPEED),
tabBackgroundColor: Theme.of(context).canvasColor,
activeColor: LSColors.accent,
activeColor: LunaColours.accent,
tabs: List.generate(
icons.length,
(index) => GButton(
@@ -36,7 +36,7 @@ class LSBottomNavigationBar extends StatelessWidget {
textStyle: TextStyle(
fontWeight: FontWeight.w600,
fontSize: Constants.UI_FONT_SIZE_SUBTITLE,
color: LSColors.accent,
color: LunaColours.accent,
),
)
).toList(),
@@ -48,7 +48,7 @@ class LSBottomNavigationBar extends StatelessWidget {
),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
//LSColors.secondary,
//LunaColours.secondary,
),
);
}

View File

@@ -25,9 +25,9 @@ Future<void> LSSnackBar({
Color color;
IconData icon;
switch(type) {
case SNACKBAR_TYPE.failure: color = LSColors.red; icon = Icons.error_outline; break;
case SNACKBAR_TYPE.success: color = LSColors.accent; icon = Icons.check_circle_outline; break;
case SNACKBAR_TYPE.info: color = LSColors.blue; icon = Icons.info_outline; break;
case SNACKBAR_TYPE.failure: color = LunaColours.red; icon = Icons.error_outline; break;
case SNACKBAR_TYPE.success: color = LunaColours.accent; icon = Icons.check_circle_outline; break;
case SNACKBAR_TYPE.info: color = LunaColours.blue; icon = Icons.info_outline; break;
}
showFlash(
context: context,
@@ -77,7 +77,7 @@ Future<void> LSSnackBar({
fontWeight: FontWeight.bold,
),
),
textColor: LSColors.accent,
textColor: LunaColours.accent,
onPressed: () {
controller.dismiss();
buttonOnPressed();

View File

@@ -3,7 +3,7 @@ import 'package:lunasea/core.dart';
class LSTableBlock extends StatelessWidget {
final String title;
final List<LSTableContent> children;
final List<Widget> children;
LSTableBlock({
Key key,
@@ -13,7 +13,7 @@ class LSTableBlock extends StatelessWidget {
List<Widget> _block({
String title,
@required List<LSTableContent> children,
@required List<Widget> children,
}) => [
if(title != null) LSHeader(text: title),
LSCard(

View File

@@ -4,11 +4,25 @@ import 'package:lunasea/core.dart';
class LSTableContent extends StatelessWidget {
final String title;
final String body;
final TextAlign titleAlign;
final TextAlign bodyAlign;
final int titleFlex;
final int bodyFlex;
final EdgeInsets padding;
final Color titleColour;
final Color bodyColour;
LSTableContent({
Key key,
@required this.title,
@required this.body,
this.titleAlign = TextAlign.end,
this.bodyAlign = TextAlign.start,
this.titleFlex = 2,
this.bodyFlex = 5,
this.padding = const EdgeInsets.symmetric(horizontal: 12.0, vertical: 4.0),
this.titleColour = Colors.white70,
this.bodyColour = Colors.white,
}) : super(key: key);
@override
@@ -18,28 +32,29 @@ class LSTableContent extends StatelessWidget {
Expanded(
child: Text(
title.toUpperCase(),
textAlign: TextAlign.end,
textAlign: titleAlign,
style: TextStyle(
color: Colors.white70,
color: titleColour,
fontSize: Constants.UI_FONT_SIZE_SUBTITLE,
),
),
flex: 2,
flex: titleFlex,
),
Container(width: 16.0, height: 0.0),
Expanded(
child: Text(
body,
textAlign: TextAlign.start,
textAlign: bodyAlign,
style: TextStyle(
color: bodyColour,
fontSize: Constants.UI_FONT_SIZE_SUBTITLE,
),
),
flex: 5,
flex: bodyFlex,
),
],
crossAxisAlignment: CrossAxisAlignment.start,
),
padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 4.0),
padding: padding,
);
}

View File

@@ -30,7 +30,7 @@ class LSHeader extends StatelessWidget {
width: 48.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS),
color: LSColors.accent,
color: LunaColours.accent,
),
),
padding: EdgeInsets.only(

View File

@@ -9,7 +9,7 @@ class LSTextHighlighted extends StatelessWidget {
LSTextHighlighted({
@required this.text,
this.bgColor = const Color(Constants.ACCENT_COLOR),
this.bgColor = const Color(LunaColours.ACCENT_COLOR),
this.fgColor = Colors.white,
this.margin = const EdgeInsets.only(right: 8.0),
});

View File

@@ -1,6 +1,6 @@
import 'package:uuid/uuid.dart';
class UUID {
class LunaUUID {
static final _generator = Uuid();
static String get uuid => _generator.v4();
}

View File

@@ -8,8 +8,8 @@ import 'package:lunasea/core.dart';
void main() async {
await _init();
runZonedGuarded<void>(
() => runApp(BIOS()),
(Object error, StackTrace stack) => Logger.fatal(error, stack),
() => runApp(LunaBIOS()),
(Object error, StackTrace stack) => LunaLogger.fatal(error, stack),
);
}
@@ -22,33 +22,34 @@ Future<void> _init() async {
statusBarColor: Colors.transparent,
));
//LunaSea initialization
Logger.initialize();
LunaNetworking.initialize();
LunaLogger.initialize();
LunaImageCache.initialize();
LunaRouter.intialize();
await InAppPurchases.initialize();
await LunaInAppPurchases.initialize();
await Database.initialize();
}
class BIOS extends StatefulWidget {
class LunaBIOS extends StatefulWidget {
static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@override
State<StatefulWidget> createState() => _State();
}
class _State extends State<BIOS> {
class _State extends State<LunaBIOS> {
@override
Widget build(BuildContext context) => Providers.providers(
Widget build(BuildContext context) => LunaProvider.providers(
child: ValueListenableBuilder(
valueListenable: Database.lunaSeaBox.listenable(keys: [LunaSeaDatabaseValue.THEME_AMOLED.key]),
builder: (context, box, _) {
return MaterialApp(
navigatorKey: BIOS.navigatorKey,
title: Constants.APPLICATION_NAME,
debugShowCheckedModeBanner: false,
navigatorKey: LunaBIOS.navigatorKey,
routes: LunaRouter.routes,
darkTheme: Themes.getDarkTheme(),
theme: Themes.getDarkTheme(),
onGenerateRoute: LunaRouter.router.generator,
darkTheme: LunaTheme.darkTheme,
theme: LunaTheme.darkTheme,
title: Constants.APPLICATION_NAME,
);
}
),
@@ -57,7 +58,7 @@ class _State extends State<BIOS> {
@override
void dispose() {
Database.deinitialize()
.whenComplete(() => InAppPurchases.deinitialize())
.whenComplete(() => LunaInAppPurchases.deinitialize())
.whenComplete(() => super.dispose());
}
}

View File

@@ -1,6 +1,7 @@
export 'modules/home.dart';
export 'modules/lidarr.dart';
export 'modules/nzbget.dart';
export 'modules/ombi.dart';
export 'modules/radarr.dart';
export 'modules/sabnzbd.dart';
export 'modules/search.dart';

View File

@@ -1,6 +1,3 @@
import 'dart:io';
import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
@@ -28,7 +25,7 @@ class CalendarAPI extends API {
void logError(String methodName, String text, Object error, StackTrace trace, {
bool uploadToSentry = true,
}) => Logger.error(
}) => LunaLogger.error(
'package:lunasea/core/api/calendar/api.dart',
methodName,
'Home: $text',
@@ -37,7 +34,7 @@ class CalendarAPI extends API {
uploadToSentry: uploadToSentry,
);
void logWarning(String methodName, String text) => Logger.warning(
void logWarning(String methodName, String text) => LunaLogger.warning(
'package:lunasea/core/api/calendar/api.dart',
methodName,
'Home: $text',
@@ -80,11 +77,6 @@ class CalendarAPI extends API {
maxRedirects: 5,
),
);
if(!lidarr['strict_tls']) {
(_client.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
};
}
Response response = await _client.get('calendar');
if(response.data.length > 0) {
for(var entry in response.data) {
@@ -126,11 +118,6 @@ class CalendarAPI extends API {
maxRedirects: 5,
),
);
if(!radarr['strict_tls']) {
(_client.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
};
}
Response response = await _client.get('calendar');
if(response.data.length > 0) {
for(var entry in response.data) {
@@ -173,11 +160,6 @@ class CalendarAPI extends API {
maxRedirects: 5,
),
);
if(!sonarr['strict_tls']) {
(_client.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
};
}
Response response = await _client.get('calendar');
if(response.data.length > 0) {
for(var entry in response.data) {

View File

@@ -48,7 +48,7 @@ class CalendarLidarrData extends CalendarData {
text: '\nDownloaded',
style: TextStyle(
fontWeight: FontWeight.bold,
color: LSColors.accent,
color: LunaColours.accent,
),
)
],

View File

@@ -43,7 +43,7 @@ class CalendarRadarrData extends CalendarData {
text: '\nDownloaded ($fileQualityProfile)',
style: TextStyle(
fontWeight: FontWeight.bold,
color: LSColors.accent,
color: LunaColours.accent,
),
)
],

View File

@@ -52,7 +52,7 @@ class CalendarSonarrData extends CalendarData {
text: '\nDownloaded ($fileQualityProfile)',
style: TextStyle(
fontWeight: FontWeight.bold,
color: LSColors.accent,
color: LunaColours.accent,
),
)
],
@@ -66,12 +66,9 @@ class CalendarSonarrData extends CalendarData {
: '';
}
Future<void> enterContent(BuildContext context) async => Navigator.of(context).pushNamed(
SonarrDetailsSeries.ROUTE_NAME,
arguments: SonarrDetailsSeriesArguments(
data: null,
seriesID: seriesID,
),
Future<void> enterContent(BuildContext context) async => SonarrSeriesDetailsRouter.navigateTo(
context,
seriesId: seriesID,
);
Widget trailing(BuildContext context) => InkWell(
@@ -98,23 +95,40 @@ class CalendarSonarrData extends CalendarData {
if(airTimeObject != null) {
return LunaSeaDatabaseValue.USE_24_HOUR_TIME.data
? DateFormat.Hm().format(airTimeObject)
: DateFormat('KK:mm\na').format(airTimeObject);
: DateFormat('hh:mm\na').format(airTimeObject);
}
return 'Unknown';
}
@override
Future<void> trailingOnPress(BuildContext context) async {
await SonarrAPI.from(Database.currentProfileObject).searchEpisodes([id])
.then((_) => LSSnackBar(context: context, title: 'Searching...', message: episodeTitle))
.catchError((_) => LSSnackBar(context: context, title: 'Failed to Search', message: Constants.CHECK_LOGS_MESSAGE, type: SNACKBAR_TYPE.failure));
if(context.read<SonarrState>().api != null) context.read<SonarrState>().api.command.episodeSearch(episodeIds: [id])
.then((_) => LSSnackBar(
context: context,
title: 'Searching for Episode...',
message: episodeTitle,
type: SNACKBAR_TYPE.success,
))
.catchError((error, stack) {
LunaLogger.error(
'CalendarSonarrData',
'trailingOnPress',
'Failed to search for episode: $id',
error,
stack,
uploadToSentry: !(error is DioError),
);
LSSnackBar(
context: context,
title: 'Failed to Search',
type: SNACKBAR_TYPE.failure,
);
});
}
@override
Future<void> trailingOnLongPress(BuildContext context) async => Navigator.of(context).pushNamed(
SonarrSearchResults.ROUTE_NAME,
arguments: SonarrSearchResultsArguments(
episodeID: id,
title: episodeTitle,
),
Future<void> trailingOnLongPress(BuildContext context) async => SonarrReleasesRouter.navigateTo(
context,
episodeId: id,
);
}

View File

@@ -6,13 +6,13 @@ class HomeConstants {
static const MODULE_KEY = 'home';
static const ModuleMap MODULE_MAP = ModuleMap(
static const LunaModuleMap MODULE_MAP = LunaModuleMap(
name: 'Home',
description: 'Home',
settingsDescription: 'Configure the Home Screen',
icon: CustomIcons.home,
route: '/',
color: Color(Constants.ACCENT_COLOR),
color: Color(LunaColours.ACCENT_COLOR),
);
//ignore: non_constant_identifier_names

View File

@@ -23,7 +23,7 @@ class HomeDialogs {
(index) => LSDialog.tile(
text: HomeNavigationBar.titles[index],
icon: HomeNavigationBar.icons[index],
iconColor: LSColors.list(index),
iconColor: LunaColours.list(index),
onTap: () => _setValues(true, index),
),
),

View File

@@ -1,36 +1,2 @@
import 'package:flutter/foundation.dart';
import 'package:lunasea/modules/home.dart';
class HomeState extends ChangeNotifier {
HomeState() {
reset(initialize: true);
}
/// Reset the state of Home back to the default
///
/// If `initialize` is true, resets everything.
/// If false, the navigation index, etc. are not reset.
void reset({ bool initialize = false }) {
if(initialize) {
_navigationIndex = HomeDatabaseValue.NAVIGATION_INDEX.data;
_calendarStartingType = HomeDatabaseValue.CALENDAR_STARTING_TYPE.data;
}
notifyListeners();
}
int _navigationIndex;
int get navigationIndex => _navigationIndex;
set navigationIndex(int navigationIndex) {
assert(navigationIndex != null);
_navigationIndex = navigationIndex;
notifyListeners();
}
CalendarStartingType _calendarStartingType;
CalendarStartingType get calendarStartingType => _calendarStartingType;
set calendarStartingType(CalendarStartingType calendarStartingType) {
assert(calendarStartingType != null);
_calendarStartingType = calendarStartingType;
notifyListeners();
}
}
export 'state/global.dart';
export 'state/local.dart';

View File

@@ -0,0 +1,23 @@
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/home.dart';
class HomeState extends LunaGlobalState {
@override
void reset() {}
int _navigationIndex = HomeDatabaseValue.NAVIGATION_INDEX.data;
int get navigationIndex => _navigationIndex;
set navigationIndex(int navigationIndex) {
assert(navigationIndex != null);
_navigationIndex = navigationIndex;
notifyListeners();
}
CalendarStartingType _calendarStartingType = HomeDatabaseValue.CALENDAR_STARTING_TYPE.data;
CalendarStartingType get calendarStartingType => _calendarStartingType;
set calendarStartingType(CalendarStartingType calendarStartingType) {
assert(calendarStartingType != null);
_calendarStartingType = calendarStartingType;
notifyListeners();
}
}

View File

View File

@@ -19,7 +19,7 @@ class _State extends State<Home> {
@override
void initState() {
super.initState();
HomescreenActions.initialize(context);
LunaQuickActions.initialize(context);
}
@override
@@ -56,8 +56,11 @@ class _State extends State<Home> {
Widget get _drawer => LSDrawer(page: 'home');
Widget get _appBar => LSAppBar(
Widget get _appBar => LunaAppBar(
context: context,
title: Constants.APPLICATION_NAME,
popUntil: null,
hideLeading: true,
actions: Database.currentProfileObject.anyAutomationEnabled
? <Widget>[
Selector<HomeState, Tuple2<int, CalendarStartingType>>(

View File

@@ -49,7 +49,7 @@ class _State extends State<HomeQuickAccess> with AutomaticKeepAliveClientMixin {
route: Constants.MODULE_MAP[SettingsConstants.MODULE_KEY].route,
color: Constants.MODULE_MAP[SettingsConstants.MODULE_KEY].color,
);
ModuleMap data = Constants.MODULE_MAP[widget.profile.enabledModules[_hasIndexers ? index-1 : index]];
LunaModuleMap data = Constants.MODULE_MAP[widget.profile.enabledModules[_hasIndexers ? index-1 : index]];
if(data != null) return HomeSummaryTile(
title: data.name,
subtitle: data.description,

View File

@@ -30,7 +30,7 @@ class _State extends State<HomeCalendarWidget> with TickerProviderStateMixin {
fontSize: Constants.UI_FONT_SIZE_SUBTITLE,
);
final TextStyle weekdayTitleStyle = TextStyle(
color: LSColors.accent,
color: LunaColours.accent,
fontWeight: FontWeight.bold,
fontSize: Constants.UI_FONT_SIZE_SUBTITLE,
);
@@ -69,7 +69,6 @@ class _State extends State<HomeCalendarWidget> with TickerProviderStateMixin {
child: Column(
children: [
_calendar,
LSDivider(),
_list,
],
),
@@ -92,9 +91,9 @@ class _State extends State<HomeCalendarWidget> with TickerProviderStateMixin {
events: widget.events,
startingDayOfWeek: (HomeDatabaseValue.CALENDAR_STARTING_DAY.data as CalendarStartingDay).data,
calendarStyle: CalendarStyle(
selectedColor: LSColors.accent.withOpacity(0.25),
selectedColor: LunaColours.accent.withOpacity(0.25),
markersMaxAmount: 1,
markersColor: LSColors.accent,
markersColor: LunaColours.accent,
weekendStyle: dayTileStyle,
weekdayStyle: dayTileStyle,
outsideStyle: outsideDayTileStyle,
@@ -102,7 +101,7 @@ class _State extends State<HomeCalendarWidget> with TickerProviderStateMixin {
outsideWeekendStyle: outsideDayTileStyle,
renderDaysOfWeek: true,
highlightToday: true,
todayColor: LSColors.primary,
todayColor: LunaColours.primary,
todayStyle: dayTileStyle,
outsideDaysVisible: false,
),

View File

@@ -30,9 +30,9 @@ class HomeSummaryTile extends StatelessWidget {
icon: icon,
color: HomeDatabaseValue.MODULES_BRAND_COLOURS.data
? color
: LSColors.list(index),
: LunaColours.list(index),
),
onTap: () async => BIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(route, (Route<dynamic> route) => false),
onTap: () async => LunaBIOS.navigatorKey.currentState.pushNamedAndRemoveUntil(route, (Route<dynamic> route) => false),
),
);
}

View File

@@ -2,5 +2,5 @@ export 'core/api.dart';
export 'core/constants.dart';
export 'core/database.dart';
export 'core/dialogs.dart';
export 'core/state_global.dart';
export 'core/state.dart';
export 'core/sorting.dart';

View File

@@ -1,6 +1,4 @@
import 'dart:io';
import 'dart:convert';
import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/lidarr.dart';
@@ -25,18 +23,13 @@ class LidarrAPI extends API {
maxRedirects: 5,
),
);
if(!profile.getLidarr()['strict_tls']) {
(_client.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
};
}
return LidarrAPI._internal(
profile.getLidarr(),
_client,
);
}
void logWarning(String methodName, String text) => Logger.warning(
void logWarning(String methodName, String text) => LunaLogger.warning(
'package:lunasea/core/api/lidarr/api.dart',
methodName,
'Lidarr: $text',
@@ -44,7 +37,7 @@ class LidarrAPI extends API {
void logError(String methodName, String text, Object error, StackTrace trace, {
bool uploadToSentry = true,
}) => Logger.error(
}) => LunaLogger.error(
'package:lunasea/core/api/lidarr/api.dart',
methodName,
'Lidarr: $text',

View File

@@ -57,7 +57,7 @@ class LidarrHistoryDataGeneric extends LidarrHistoryData {
TextSpan(
text: '$eventType',
style: TextStyle(
color: LSColors.purple,
color: LunaColours.purple,
fontWeight: FontWeight.bold,
),
),
@@ -111,7 +111,7 @@ class LidarrHistoryDataTrackFileImported extends LidarrHistoryData {
TextSpan(
text: '${LidarrConstants.EVENT_TYPE_MESSAGES[eventType]} ($quality)',
style: TextStyle(
color: Color(Constants.ACCENT_COLOR),
color: Color(LunaColours.ACCENT_COLOR),
fontWeight: FontWeight.bold,
),
)
@@ -138,7 +138,7 @@ class LidarrHistoryDataDownloadImported extends LidarrHistoryData {
TextSpan(
text: '${LidarrConstants.EVENT_TYPE_MESSAGES[eventType]} ($quality)',
style: TextStyle(
color: Color(Constants.ACCENT_COLOR),
color: Color(LunaColours.ACCENT_COLOR),
fontWeight: FontWeight.bold,
),
)
@@ -213,7 +213,7 @@ class LidarrHistoryDataTrackFileRenamed extends LidarrHistoryData {
TextSpan(
text: '${LidarrConstants.EVENT_TYPE_MESSAGES[eventType]}',
style: TextStyle(
color: Color(Constants.ACCENT_COLOR),
color: Color(LunaColours.ACCENT_COLOR),
fontWeight: FontWeight.bold,
),
)

View File

@@ -23,7 +23,7 @@ class LidarrTrackData {
return TextSpan(
text: 'Downloaded',
style: TextStyle(
color: monitored ? Color(Constants.ACCENT_COLOR) : Color(Constants.ACCENT_COLOR).withOpacity(0.30),
color: monitored ? Color(LunaColours.ACCENT_COLOR) : Color(LunaColours.ACCENT_COLOR).withOpacity(0.30),
fontWeight: FontWeight.bold,
),
);

View File

@@ -6,7 +6,7 @@ class LidarrConstants {
static const MODULE_KEY = 'lidarr';
static const ModuleMap MODULE_MAP = ModuleMap(
static const LunaModuleMap MODULE_MAP = LunaModuleMap(
name: 'Lidarr',
description: 'Manage Music',
settingsDescription: 'Configure Lidarr',

View File

@@ -22,7 +22,7 @@ class LidarrDialogs {
qualities.length,
(index) => LSDialog.tile(
icon: Icons.portrait,
iconColor: LSColors.list(index),
iconColor: LunaColours.list(index),
text: qualities[index].name,
onTap: () => _setValues(true, qualities[index]),
),
@@ -49,7 +49,7 @@ class LidarrDialogs {
metadatas.length,
(index) => LSDialog.tile(
icon: Icons.portrait,
iconColor: LSColors.list(index),
iconColor: LunaColours.list(index),
text: metadatas[index].name,
onTap: () => _setValues(true, metadatas[index]),
),
@@ -75,12 +75,12 @@ class LidarrDialogs {
buttons: [
LSDialog.button(
text: 'Remove + Files',
textColor: LSColors.red,
textColor: LunaColours.red,
onPressed: () => _setValues(true, true),
),
LSDialog.button(
text: 'Remove',
textColor: LSColors.red,
textColor: LunaColours.red,
onPressed: () => _setValues(true, false),
),
],
@@ -164,7 +164,7 @@ class LidarrDialogs {
_options.length,
(index) => LSDialog.tile(
icon: _options[index][1],
iconColor: LSColors.list(index),
iconColor: LunaColours.list(index),
text: _options[index][0],
onTap: () => _setValues(true, _options[index][2]),
),
@@ -197,7 +197,7 @@ class LidarrDialogs {
],
),
icon: Icons.folder,
iconColor: LSColors.list(index),
iconColor: LunaColours.list(index),
onTap: () => _setValues(true, folders[index]),
),
),
@@ -231,7 +231,7 @@ class LidarrDialogs {
(index) => LSDialog.tile(
text: _options[index][0],
icon: _options[index][1],
iconColor: LSColors.list(index),
iconColor: LunaColours.list(index),
onTap: () => _setValues(true, _options[index][2]),
),
),
@@ -258,7 +258,7 @@ class LidarrDialogs {
(index) => LSDialog.tile(
text: LidarrNavigationBar.titles[index],
icon: LidarrNavigationBar.icons[index],
iconColor: LSColors.list(index),
iconColor: LunaColours.list(index),
onTap: () => _setValues(true, index),
),
),

View File

@@ -46,7 +46,7 @@ extension LidarrCatalogueSortingExtension on LidarrCatalogueSorting {
) => _sorter.byType(data, this, ascending);
}
class _Sorter extends Sorter<LidarrCatalogueSorting> {
class _Sorter extends LunaSorter<LidarrCatalogueSorting> {
@override
List byType(
List data,

View File

@@ -43,7 +43,7 @@ extension LidarrReleasesSortingExtension on LidarrReleasesSorting {
) => _sorter.byType(data, this, ascending);
}
class _Sorter extends Sorter<LidarrReleasesSorting> {
class _Sorter extends LunaSorter<LidarrReleasesSorting> {
@override
List byType(
List data,

View File

@@ -0,0 +1,2 @@
export 'state/global.dart';
export 'state/local.dart';

View File

@@ -1,9 +1,15 @@
import 'package:flutter/foundation.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/lidarr.dart';
class LidarrModel extends ChangeNotifier {
///Catalogue Sticky Header Content
class LidarrState extends LunaGlobalState {
LidarrState() {
reset();
}
@override
void reset() {}
///Catalogue Sticky Header Content
String _searchCatalogueFilter = '';
String get searchCatalogueFilter => _searchCatalogueFilter;
set searchCatalogueFilter(String searchCatalogueFilter) {

View File

View File

@@ -101,8 +101,10 @@ class _State extends State<LidarrAddDetails> {
Widget get _appBar => _arguments == null
? null
: LSAppBar(
: LunaAppBar(
context: context,
title: _arguments.data.title,
popUntil: '/lidarr',
actions: [
LSIconButton(
icon: Icons.link,
@@ -147,7 +149,6 @@ class _State extends State<LidarrAddDetails> {
squareImage: true,
headers: Database.currentProfileObject.getLidarr()['headers'],
),
LSDivider(),
ValueListenableBuilder(
valueListenable: Database.lunaSeaBox.listenable(keys: [LidarrDatabaseValue.ADD_MONITORED.key]),
builder: (context, box, widget) {
@@ -219,7 +220,6 @@ class _State extends State<LidarrAddDetails> {
);
},
),
LSDivider(),
LSContainerRow(
children: <Widget>[
Expanded(
@@ -232,7 +232,7 @@ class _State extends State<LidarrAddDetails> {
Expanded(
child: LSButton(
text: 'Add + Search',
backgroundColor: LSColors.orange,
backgroundColor: LunaColours.orange,
onTap: () async => _addArtist(true),
reducedMargin: true,
),

View File

@@ -31,7 +31,7 @@ class _State extends State<LidarrAddSearch> {
);
Future<void> _refresh() async {
final _model = Provider.of<LidarrModel>(context, listen: false);
final _model = Provider.of<LidarrState>(context, listen: false);
final _api = LidarrAPI.from(Database.currentProfileObject);
setState(() {
_future = _api.searchArtists(_model.addSearchQuery);
@@ -44,7 +44,11 @@ class _State extends State<LidarrAddSearch> {
.catchError((_) => _availableIDs = []);
}
Widget get _appBar => LSAppBar(title: 'Add Artist');
Widget get _appBar => LunaAppBar(
context: context,
title: 'Add Artist',
popUntil: '/lidarr',
);
Widget get _body => LSRefreshIndicator(
refreshKey: _refreshKey,

View File

@@ -37,7 +37,7 @@ class _State extends State<LidarrCatalogue> with AutomaticKeepAliveClientMixin {
final _api = LidarrAPI.from(Database.currentProfileObject);
if(mounted) setState(() => { _future = _api.getAllArtists() });
//Clear the search filter using a microtask
Future.microtask(() => Provider.of<LidarrModel>(context, listen: false)?.searchCatalogueFilter = '');
Future.microtask(() => Provider.of<LidarrState>(context, listen: false)?.searchCatalogueFilter = '');
}
void _refreshState() => setState(() {});
@@ -91,7 +91,7 @@ class _State extends State<LidarrCatalogue> with AutomaticKeepAliveClientMixin {
buttonText: 'Refresh',
onTapHandler: () => _refresh(),
)
: Consumer<LidarrModel>(
: Consumer<LidarrState>(
builder: (context, model, widget) {
//Filter and sort the results
List<LidarrCatalogueData> _filtered = _sort(model, _filter(model.searchCatalogueFilter));
@@ -129,8 +129,8 @@ class _State extends State<LidarrCatalogue> with AutomaticKeepAliveClientMixin {
: entry.title.toLowerCase().contains(filter.toLowerCase())
).toList();
List<LidarrCatalogueData> _sort(LidarrModel model, List<LidarrCatalogueData> data) {
if(data != null && data.length != 0) return model.sortCatalogueType.sort(data, model.sortCatalogueAscending);
List<LidarrCatalogueData> _sort(LidarrState state, List<LidarrCatalogueData> data) {
if(data != null && data.length != 0) return state.sortCatalogueType.sort(data, state.sortCatalogueAscending);
return data;
}

View File

@@ -53,7 +53,9 @@ class _State extends State<LidarrDetailsAlbum> {
appBar: _appBar,
);
Widget get _appBar => LSAppBar(
Widget get _appBar => LunaAppBar(
context: context,
popUntil: '/lidarr',
title: _arguments == null ? 'Details Album' : _arguments.title,
actions: <Widget>[
InkWell(

View File

@@ -31,7 +31,7 @@ class _State extends State<LidarrDetailsArtist> {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) {
_arguments = ModalRoute.of(context).settings.arguments;
Provider.of<LidarrModel>(context, listen: false).artistNavigationIndex = 1;
Provider.of<LidarrState>(context, listen: false).artistNavigationIndex = 1;
_fetch();
});
}
@@ -65,7 +65,9 @@ class _State extends State<LidarrDetailsArtist> {
: null,
);
Widget get _appBar => LSAppBar(
Widget get _appBar => LunaAppBar(
context: context,
popUntil: '/lidarr',
title: _arguments == null || _arguments.data == null
? 'Artist Details'
: _arguments.data.title,
@@ -93,7 +95,7 @@ class _State extends State<LidarrDetailsArtist> {
onPageChanged: _onPageChanged,
);
void _onPageChanged(int index) => Provider.of<LidarrModel>(context, listen: false).artistNavigationIndex = index;
void _onPageChanged(int index) => Provider.of<LidarrState>(context, listen: false).artistNavigationIndex = index;
Future<void> _removeCallback(bool withData) async => Navigator.of(context).pop(['remove_artist', withData]);
}

View File

@@ -93,7 +93,11 @@ class _State extends State<LidarrEditArtist> {
.catchError((error) => Future.error(error));
}
Widget get _appBar => LSAppBar(title: _arguments?.entry?.title ?? 'Edit Artist');
Widget get _appBar => LunaAppBar(
context: context,
popUntil: '/lidarr',
title: _arguments?.entry?.title ?? 'Edit Artist',
);
Widget get _body => FutureBuilder(
future: _future,
@@ -147,7 +151,6 @@ class _State extends State<LidarrEditArtist> {
trailing: LSIconButton(icon: Icons.arrow_forward_ios),
onTap: () => _changeMetadata(),
),
LSDivider(),
LSButton(
text: 'Update Artist',
onTap: () async => _save().catchError((_) {}),
@@ -156,7 +159,7 @@ class _State extends State<LidarrEditArtist> {
);
Future<void> _changePath() async {
List<dynamic> _values = await GlobalDialogs.editText(context, 'Artist Path', prefill: _path);
List<dynamic> _values = await LunaDialogs.editText(context, 'Artist Path', prefill: _path);
if(_values[0] && mounted) setState(() => _path = _values[1]);
}

View File

@@ -24,7 +24,7 @@ class _State extends State<Lidarr> {
@override
void initState() {
super.initState();
Future.microtask(() => Provider.of<LidarrModel>(context, listen: false).navigationIndex = 0);
Future.microtask(() => Provider.of<LidarrState>(context, listen: false).navigationIndex = 0);
}
@override
@@ -102,7 +102,7 @@ class _State extends State<Lidarr> {
);
Future<void> _enterAddArtist() async {
final _model = Provider.of<LidarrModel>(context, listen: false);
final _model = Provider.of<LidarrState>(context, listen: false);
_model.addSearchQuery = '';
final dynamic result = await Navigator.of(context).pushNamed(LidarrAddSearch.ROUTE_NAME);
if(result != null) switch(result[0]) {
@@ -124,7 +124,7 @@ class _State extends State<Lidarr> {
_refreshAllPages();
break;
}
default: Logger.warning('Lidarr', '_enterAddArtist', 'Unknown Case: ${result[0]}');
default: LunaLogger.warning('Lidarr', '_enterAddArtist', 'Unknown Case: ${result[0]}');
}
}
@@ -151,11 +151,11 @@ class _State extends State<Lidarr> {
.catchError((_) => LSSnackBar(context: context, title: 'Failed to Search', message: Constants.CHECK_LOGS_MESSAGE, type: SNACKBAR_TYPE.failure));
break;
}
default: Logger.warning('Lidarr', '_handlePopup', 'Unknown Case: ${values[1]}');
default: LunaLogger.warning('Lidarr', '_handlePopup', 'Unknown Case: ${values[1]}');
}
}
void _onPageChanged(int index) => Provider.of<LidarrModel>(context, listen: false).navigationIndex = index;
void _onPageChanged(int index) => Provider.of<LidarrState>(context, listen: false).navigationIndex = index;
void _refreshProfile() {
_api = LidarrAPI.from(Database.currentProfileObject);

View File

@@ -43,7 +43,7 @@ class _State extends State<LidarrSearchResults> {
final _api = LidarrAPI.from(Database.currentProfileObject);
setState(() => { _future = _api.getReleases(_arguments.albumID) });
//Clear the search filter using a microtask
Future.microtask(() => Provider.of<LidarrModel>(context, listen: false)?.searchReleasesFilter = '');
Future.microtask(() => Provider.of<LidarrState>(context, listen: false)?.searchReleasesFilter = '');
}
@override
@@ -55,7 +55,11 @@ class _State extends State<LidarrSearchResults> {
Widget get _appBar => _arguments == null
? null
: LSAppBar(title: _arguments.title);
: LunaAppBar(
context: context,
popUntil: '/lidarr',
title: _arguments.title,
);
Widget get _body => _arguments == null
? null
@@ -97,7 +101,7 @@ class _State extends State<LidarrSearchResults> {
buttonText: 'Refresh',
onTapHandler: () => _refresh(),
)
: Consumer<LidarrModel>(
: Consumer<LidarrState>(
builder: (context, model, widget) {
List<LidarrReleaseData> _filtered = _sort(model, _filter(model.searchReleasesFilter));
_filtered = model.hideRejectedReleases ? _hide(_filtered) : _filtered;
@@ -129,8 +133,8 @@ class _State extends State<LidarrSearchResults> {
: entry.title.toLowerCase().contains(filter.toLowerCase())
).toList();
List<LidarrReleaseData> _sort(LidarrModel model, List<LidarrReleaseData> data) {
if(data != null && data.length != 0) return model.sortReleasesType.sort(data, model.sortReleasesAscending);
List<LidarrReleaseData> _sort(LidarrState state, List<LidarrReleaseData> data) {
if(data != null && data.length != 0) return state.sortReleasesType.sort(data, state.sortReleasesAscending);
return data;
}

View File

@@ -19,13 +19,13 @@ class _State extends State<LidarrAddSearchBar> {
@override
void initState() {
super.initState();
final model = Provider.of<LidarrModel>(context, listen: false);
final model = Provider.of<LidarrState>(context, listen: false);
_controller.text = model.addSearchQuery;
}
@override
Widget build(BuildContext context) => Expanded(
child: Consumer<LidarrModel>(
child: Consumer<LidarrState>(
builder: (context, model, widget) => LSTextInputBar(
controller: _controller,
autofocus: true,
@@ -36,8 +36,8 @@ class _State extends State<LidarrAddSearchBar> {
),
);
void _onChange(LidarrModel model, String text, bool updateController) {
model.addSearchQuery = text;
void _onChange(LidarrState state, String text, bool updateController) {
state.addSearchQuery = text;
if(updateController) _controller.text = text;
}

View File

@@ -42,7 +42,7 @@ class LidarrAddSearchResultTile extends StatelessWidget {
);
if(result != null) switch(result[0]) {
case 'artist_added': Navigator.of(context).pop(result); break;
default: Logger.warning('LidarrAddSearchResultTile', '_enterDetails', 'Unknown Case: ${result[0]}');
default: LunaLogger.warning('LidarrAddSearchResultTile', '_enterDetails', 'Unknown Case: ${result[0]}');
}
}
}

View File

@@ -26,8 +26,8 @@ class _State extends State<LidarrArtistNavigationBar> {
];
@override
Widget build(BuildContext context) => Selector<LidarrModel, int>(
selector: (_, model) => model.artistNavigationIndex,
Widget build(BuildContext context) => Selector<LidarrState, int>(
selector: (_, state) => state.artistNavigationIndex,
builder: (context, index, _) => LSBottomNavigationBar(
index: index,
icons: _navbarIcons,
@@ -41,6 +41,6 @@ class _State extends State<LidarrArtistNavigationBar> {
index,
duration: Duration(milliseconds: Constants.UI_NAVIGATION_SPEED),
curve: Curves.easeOutSine,
).then((_) => Provider.of<LidarrModel>(context, listen: false).artistNavigationIndex = index);
).then((_) => Provider.of<LidarrState>(context, listen: false).artistNavigationIndex = index);
}
}

View File

@@ -17,7 +17,7 @@ class LidarrCatalogueHideButton extends StatefulWidget {
class _State extends State<LidarrCatalogueHideButton> {
@override
Widget build(BuildContext context) => LSCard(
child: Consumer<LidarrModel>(
child: Consumer<LidarrState>(
builder: (context, model, widget) => InkWell(
child: LSIconButton(
icon: model.hideUnmonitoredArtists

View File

@@ -12,18 +12,18 @@ class _State extends State<LidarrCatalogueSearchBar> {
@override
Widget build(BuildContext context) => Expanded(
child: Consumer<LidarrModel>(
builder: (context, model, widget) => LSTextInputBar(
child: Consumer<LidarrState>(
builder: (context, state, widget) => LSTextInputBar(
controller: _textController,
labelText: 'Search Artists...',
onChanged: (text, update) => _onChanged(model, text, update),
onChanged: (text, update) => _onChanged(state, text, update),
margin: EdgeInsets.fromLTRB(12.0, 0.0, 12.0, 12.0),
),
),
);
void _onChanged(LidarrModel model, String text, bool update) {
model.searchCatalogueFilter = text;
void _onChanged(LidarrState state, String text, bool update) {
state.searchCatalogueFilter = text;
if(update) _textController.text = '';
}
}

View File

@@ -17,7 +17,7 @@ class LidarrCatalogueSortButton extends StatefulWidget {
class _State extends State<LidarrCatalogueSortButton> {
@override
Widget build(BuildContext context) => LSCard(
child: Consumer<LidarrModel>(
child: Consumer<LidarrState>(
builder: (context, model, widget) => PopupMenuButton<LidarrCatalogueSorting>(
shape: LunaSeaDatabaseValue.THEME_AMOLED.data && LunaSeaDatabaseValue.THEME_AMOLED_BORDER.data
? LSRoundedShapeWithBorder()
@@ -50,7 +50,7 @@ class _State extends State<LidarrCatalogueSortButton> {
? Icons.arrow_upward
: Icons.arrow_downward,
size: Constants.UI_FONT_SIZE_SUBTITLE+2.0,
color: LSColors.accent,
color: LunaColours.accent,
),
],
),

View File

@@ -26,8 +26,8 @@ class _State extends State<LidarrCatalogueTile> {
text: widget.data.title,
darken: !widget.data.monitored,
),
subtitle: Selector<LidarrModel, LidarrCatalogueSorting>(
selector: (_, model) => model.sortCatalogueType,
subtitle: Selector<LidarrState, LidarrCatalogueSorting>(
selector: (_, state) => state.sortCatalogueType,
builder: (context, type, _) => LSSubtitle(
text: widget.data.subtitle(type),
darken: !widget.data.monitored,
@@ -47,7 +47,6 @@ class _State extends State<LidarrCatalogueTile> {
decoration: LSCardBackground(
uri: widget.data.bannerURI(),
headers: Database.currentProfileObject.getLidarr()['headers'],
darken: !widget.data.monitored,
),
onTap: () async => _enterArtist(),
onLongPress: () async => _handlePopup(),
@@ -95,7 +94,7 @@ class _State extends State<LidarrCatalogueTile> {
widget.refresh();
break;
}
default: Logger.warning('LidarrCatalogueTile', '_enterArtist', 'Unknown Case: ${result[0]}');
default: LunaLogger.warning('LidarrCatalogueTile', '_enterArtist', 'Unknown Case: ${result[0]}');
}
}
@@ -105,7 +104,7 @@ class _State extends State<LidarrCatalogueTile> {
case 'refresh_artist': _refreshArtist(); break;
case 'edit_artist': _enterEditArtist(); break;
case 'remove_artist': _removeArtist(); break;
default: Logger.warning('LidarrCatalogueTile', '_handlePopup', 'Invalid method passed through popup. (${values[1]})');
default: LunaLogger.warning('LidarrCatalogueTile', '_handlePopup', 'Invalid method passed through popup. (${values[1]})');
}
}
@@ -134,7 +133,7 @@ class _State extends State<LidarrCatalogueTile> {
List values = await LidarrDialogs.deleteArtist(context);
if(values[0]) {
if(values[1]) {
values = await GlobalDialogs.deleteCatalogueWithFiles(context, widget.data.title);
values = await LunaDialogs.deleteCatalogueWithFiles(context, widget.data.title);
if(values[0]) {
await _api.removeArtist(widget.data.artistID, deleteFiles: true)
.then((_) {

View File

@@ -65,7 +65,7 @@ class _State extends State<LidarrDetailsAlbumList> with AutomaticKeepAliveClient
),
);
Widget get _list => Consumer<LidarrModel>(
Widget get _list => Consumer<LidarrState>(
builder: (context, model, widget) {
List<LidarrAlbumData> _filtered = model.hideUnmonitoredAlbums ? _hide(_results) : _results;
return LSListViewBuilder(

Some files were not shown because too many files have changed in this diff Show More