mirror of
https://github.com/jagandeepbrar/lunasea.git
synced 2026-08-30 20:24:25 +00:00
refactor(core): destructure core folder and reintegrate extensions
This commit is contained in:
@@ -1,49 +1 @@
|
||||
{
|
||||
"motd": "This release is the first build to be built on Flutter 3, which now supports 120hz displays and is more performant across the board!",
|
||||
"new": [
|
||||
{
|
||||
"module": "-arr",
|
||||
"changes": [
|
||||
"(Details) Updated UI for viewing content links"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "LunaSea",
|
||||
"changes": [
|
||||
"Support 120hz displays"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "Notifications",
|
||||
"changes": [
|
||||
"Option to disable in-app notifications"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "Radarr",
|
||||
"changes": [
|
||||
"(Links) Added Letterboxd"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "Settings",
|
||||
"changes": [
|
||||
"(System) Ability to check for updates"
|
||||
]
|
||||
}
|
||||
],
|
||||
"fixes": [
|
||||
{
|
||||
"module": "-arr",
|
||||
"changes": [
|
||||
"(Releases) Correctly calculate age of releases"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "UI/UX",
|
||||
"changes": [
|
||||
"(Scrollbar) Enable interactivity on all platforms"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{}
|
||||
@@ -61,7 +61,6 @@
|
||||
"lunasea.New": "Neu",
|
||||
"lunasea.NoModulesEnabled": "Keine Module aktiviert",
|
||||
"lunasea.NotSet": "Nicht gesetzt",
|
||||
"lunasea.OneHourAgo": "Vor einer Stunde",
|
||||
"lunasea.Options": "Optionen",
|
||||
"lunasea.Page": "Seite",
|
||||
"lunasea.PlatformSpecific": "Plattformspezifisch",
|
||||
|
||||
@@ -41,8 +41,11 @@
|
||||
"lunasea.ComingSoon": "Coming Soon",
|
||||
"lunasea.Copied": "Copied",
|
||||
"lunasea.CopiedContentToTheClipboard": "Copied Content to the Clipboard",
|
||||
"lunasea.Critical": "Critical",
|
||||
"lunasea.Dashboard": "Dashboard",
|
||||
"lunasea.Days": "{} Days",
|
||||
"lunasea.DaysAgo": "{} Days Ago",
|
||||
"lunasea.Debug": "Debug",
|
||||
"lunasea.Delete": "Delete",
|
||||
"lunasea.Descending": "Descending",
|
||||
"lunasea.Develop": "Develop",
|
||||
@@ -50,6 +53,7 @@
|
||||
"lunasea.Disabled": "Disabled",
|
||||
"lunasea.Dismiss": "Dismiss",
|
||||
"lunasea.Edge": "Edge",
|
||||
"lunasea.Error": "Error",
|
||||
"lunasea.ExternalModules": "External Modules",
|
||||
"lunasea.Fixes": "Fixes",
|
||||
"lunasea.FullChangelog": "Full Changelog",
|
||||
@@ -57,19 +61,23 @@
|
||||
"lunasea.GoToSettings": "Go to Settings",
|
||||
"lunasea.GridView": "Grid View",
|
||||
"lunasea.Home": "Home",
|
||||
"lunasea.Hours": "{} Hours",
|
||||
"lunasea.HoursAgo": "{} Hours Ago",
|
||||
"lunasea.IncorrectEncryptionKey": "Incorrect encryption key",
|
||||
"lunasea.Internal": "Internal",
|
||||
"lunasea.InvalidFileTypeSelected": "Invalid File Type Selected",
|
||||
"lunasea.JustNow": "Just Now",
|
||||
"lunasea.Minutes": "{} Minutes",
|
||||
"lunasea.MinutesAgo": "{} Minutes Ago",
|
||||
"lunasea.Module": "Module",
|
||||
"lunasea.ModuleIsNotEnabled": "{} Is Not Enabled",
|
||||
"lunasea.New": "New",
|
||||
"lunasea.NotSet": "Not Set",
|
||||
"lunasea.NoModulesEnabled": "No Modules Enabled",
|
||||
"lunasea.OneHourAgo": "1 Hour Ago",
|
||||
"lunasea.OneMinuteAgo": "1 Minute Ago",
|
||||
"lunasea.OneDay": "1 Day",
|
||||
"lunasea.OneHour": "1 Hour",
|
||||
"lunasea.OneMinute": "1 Minute",
|
||||
"lunasea.OneSecond": "1 Second",
|
||||
"lunasea.Options": "Options",
|
||||
"lunasea.Page": "Page",
|
||||
"lunasea.PlatformSpecific": "Platform-Specific",
|
||||
@@ -83,6 +91,8 @@
|
||||
"lunasea.Retry": "Retry",
|
||||
"lunasea.ReturnToDashboard": "Return to Dashboard",
|
||||
"lunasea.SearchTextBar": "Search…",
|
||||
"lunasea.Seconds": "{} Seconds",
|
||||
"lunasea.SecondsAgo": "{} Seconds Ago",
|
||||
"lunasea.Set": "Set",
|
||||
"lunasea.Settings": "Settings",
|
||||
"lunasea.Stable": "Stable",
|
||||
@@ -90,12 +100,14 @@
|
||||
"lunasea.TransactionFailure": "Transaction Failure",
|
||||
"lunasea.TryAgain": "Try Again",
|
||||
"lunasea.Tweaks": "Tweaks",
|
||||
"lunasea.UnderAMinute": "Under a Minute",
|
||||
"lunasea.Unknown": "Unknown",
|
||||
"lunasea.UnknownDate": "Unknown Date",
|
||||
"lunasea.UnknownError": "Unknown Error",
|
||||
"lunasea.UnknownModule": "Unknown Module",
|
||||
"lunasea.Update": "Update",
|
||||
"lunasea.View": "View",
|
||||
"lunasea.Warning": "Warning",
|
||||
"lunasea.Website": "Website",
|
||||
"overseerr.Audio": "Audio",
|
||||
"overseerr.Approved": "Approved",
|
||||
@@ -522,6 +534,7 @@
|
||||
"settings.UsernameValidation": "Username Required",
|
||||
"settings.Version": "Version",
|
||||
"settings.ViewRecentChanges": "View Recent Changes",
|
||||
"settings.ViewTypeLogs": "View {} Logs",
|
||||
"settings.WeblateDescription": "Help Localize LunaSea",
|
||||
"settings.Website": "Website",
|
||||
"settings.WebsiteDescription": "Visit LunaSea's Website",
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
"lunasea.New": "Nouveau",
|
||||
"lunasea.NoModulesEnabled": "Aucun module activé",
|
||||
"lunasea.NotSet": "Non défini",
|
||||
"lunasea.OneHourAgo": "Il y a une heure",
|
||||
"lunasea.Options": "Options",
|
||||
"lunasea.Page": "Page",
|
||||
"lunasea.PlatformSpecific": "Spécifique à la plateforme",
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
"lunasea.New": "Új",
|
||||
"lunasea.NoModulesEnabled": "Nincs engedélyezett modul",
|
||||
"lunasea.NotSet": "Nincs beállítva",
|
||||
"lunasea.OneHourAgo": "1 órával ezelőtt",
|
||||
"lunasea.Options": "Opciók",
|
||||
"lunasea.Page": "Oldal",
|
||||
"lunasea.PlatformSpecific": "Platform-specifikus",
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
"lunasea.New": "Nuovo",
|
||||
"lunasea.NoModulesEnabled": "Nessun modulo abilitato",
|
||||
"lunasea.NotSet": "Non impostato",
|
||||
"lunasea.OneHourAgo": "1 ora fa",
|
||||
"lunasea.Options": "Opzioni",
|
||||
"lunasea.Page": "Pagina",
|
||||
"lunasea.PlatformSpecific": "Specifico della piattaforma",
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
"lunasea.New": "Ny",
|
||||
"lunasea.NoModulesEnabled": "Ingen påslåtte moduler",
|
||||
"lunasea.NotSet": "Ikke satt",
|
||||
"lunasea.OneHourAgo": "Én time siden",
|
||||
"lunasea.Options": "Innstillinger",
|
||||
"lunasea.Page": "Side",
|
||||
"lunasea.PlatformSpecific": "Plattformsspesifikk",
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
"lunasea.New": "Yeni",
|
||||
"lunasea.NoModulesEnabled": "Etkin Modül Yok",
|
||||
"lunasea.NotSet": "Ayarlanmadı",
|
||||
"lunasea.OneHourAgo": "1 Saat Önce",
|
||||
"lunasea.Options": "Seçenekler",
|
||||
"lunasea.Page": "Sayfa",
|
||||
"lunasea.PlatformSpecific": "Platforma Özgü",
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
"lunasea.New": "新的",
|
||||
"lunasea.NoModulesEnabled": "未启用模块",
|
||||
"lunasea.NotSet": "未设置",
|
||||
"lunasea.OneHourAgo": "1小时前",
|
||||
"lunasea.Options": "选项",
|
||||
"lunasea.Page": "页",
|
||||
"lunasea.PlatformSpecific": "平台特定",
|
||||
|
||||
@@ -1,32 +1,19 @@
|
||||
export 'core/cache/memory_lru.dart';
|
||||
export 'core/cache/memory_store.dart';
|
||||
export 'core/extensions/async_snapshot.dart';
|
||||
export 'core/extensions/datetime.dart';
|
||||
export 'core/extensions/duration.dart';
|
||||
export 'core/extensions/iap_product_details.dart';
|
||||
export 'core/extensions/int.dart';
|
||||
export 'core/extensions/navigator_state.dart';
|
||||
export 'core/extensions/page_controller.dart';
|
||||
export 'core/extensions/scroll_controller.dart';
|
||||
export 'core/models/configuration.dart';
|
||||
export 'core/models/logs.dart';
|
||||
export 'core/models/types.dart';
|
||||
export 'core/models/webhooks.dart';
|
||||
export 'core/pages/invalid_route.dart';
|
||||
export 'core/pages/not_enabled.dart';
|
||||
export 'core/router/module_router.dart';
|
||||
export 'core/router/page_router.dart';
|
||||
export 'core/router/router.dart';
|
||||
export 'core/services/the_movie_db.dart';
|
||||
export 'core/state/module_state.dart';
|
||||
export 'core/state/state.dart';
|
||||
export 'core/utilities/changelog.dart';
|
||||
export 'core/utilities/dialogs.dart';
|
||||
/// This file is deprecated and should no longer be actively used.
|
||||
/// All imports should happen directly and canonical export files will not be used anymore.
|
||||
|
||||
export 'deprecated/extensions/datetime.dart';
|
||||
export 'deprecated/state/module_state.dart';
|
||||
export 'deprecated/state/state.dart';
|
||||
export 'deprecated/router/module_router.dart';
|
||||
export 'deprecated/router/page_router.dart';
|
||||
export 'deprecated/router/router.dart';
|
||||
|
||||
export 'types/loading_state.dart';
|
||||
export 'database/box.dart';
|
||||
export 'database/models/profile.dart';
|
||||
export 'database/tables/lunasea.dart';
|
||||
export 'system/logger.dart';
|
||||
export 'system/profile.dart';
|
||||
export 'utils/dialogs.dart';
|
||||
export 'widgets/ui.dart';
|
||||
export 'modules.dart';
|
||||
export 'vendor.dart'
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
extension LunaAsyncSnapshotExtension on AsyncSnapshot {
|
||||
bool get lunaIsFinishedWithData {
|
||||
return this.connectionState == ConnectionState.done && this.hasData;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
extension DurationExtension on Duration {
|
||||
/// Return a string representation of the timestamp.
|
||||
/// `HH:MM:SS` or `MM:SS` if the duration is less than one hour.
|
||||
String get lunaTimestamp {
|
||||
return [
|
||||
if (this.inHours != 0) this.inHours.toString().padLeft(2, '0'),
|
||||
(this.inMinutes % 60).toString().padLeft(2, '0'),
|
||||
(this.inSeconds % 60).toString().padLeft(2, '0'),
|
||||
].join(':');
|
||||
}
|
||||
|
||||
/// Returns a string representation of the timestamp as words.
|
||||
///
|
||||
/// Format example: 1 Day, 23 Hours, 10 Minutes
|
||||
String get lunaTimestampWords {
|
||||
String? days, hours, minutes;
|
||||
if (this.inDays == 1) days = '1 Day';
|
||||
if (this.inDays > 1) days = '${this.inDays.toString()} Days';
|
||||
if (this.inHours == 1) hours = '1 Hour';
|
||||
if (this.inHours > 1) hours = '${(this.inHours % 24).toString()} Hours';
|
||||
if (this.inMinutes == 1) minutes = '1 Minute';
|
||||
if (this.inMinutes > 1)
|
||||
minutes = '${(this.inMinutes % 60).toString()} Minutes';
|
||||
return [
|
||||
if (days != null) days,
|
||||
if (hours != null) hours,
|
||||
if (minutes != null) minutes,
|
||||
if (minutes == null) LunaUI.TEXT_EMDASH,
|
||||
].join(' ');
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
extension IntegerBytesExtension on int? {
|
||||
static const _BIT_SIZES = ['b', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb', 'Eb'];
|
||||
static const _BYTE_SIZES = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'];
|
||||
|
||||
String _bytesToString({int decimals = 2, position = 0, bool bytes = true}) {
|
||||
if (this == null || this! <= 0) return '${0.toStringAsFixed(decimals)} B';
|
||||
int chunk = bytes ? 1024 : 1000;
|
||||
double size = this!.toDouble();
|
||||
while (size > chunk) {
|
||||
size /= chunk;
|
||||
position++;
|
||||
}
|
||||
return '${size.toStringAsFixed(decimals)} ${bytes ? _BYTE_SIZES[position] : _BIT_SIZES[position]}';
|
||||
}
|
||||
|
||||
/// Given an integer of the number of bytes/bits, return a string representation.
|
||||
String lunaBytesToString({int decimals = 2, bool bytes = true}) =>
|
||||
_bytesToString(decimals: decimals, position: 0, bytes: bytes);
|
||||
|
||||
/// Given an integer of the number of kilobytes/kilobits, return a string representation.
|
||||
String lunaKilobytesToString({int decimals = 2, bool bytes = true}) =>
|
||||
_bytesToString(decimals: decimals, position: 1, bytes: bytes);
|
||||
|
||||
/// Given an integer of the number of megabytes/megabits, return a string representation.
|
||||
String lunaMegabytesToString({int decimals = 2, bool bytes = true}) =>
|
||||
_bytesToString(decimals: decimals, position: 2, bytes: bytes);
|
||||
|
||||
/// Given an integer of the number of gigabytes/gigabits, return a string representation.
|
||||
String lunaGigabytesToString({int decimals = 2, bool bytes = true}) =>
|
||||
_bytesToString(decimals: decimals, position: 3, bytes: bytes);
|
||||
}
|
||||
|
||||
extension IntegerTimeExtension on int? {
|
||||
static const int _MINUTE_IN_SECONDS = 60;
|
||||
static const int _HOUR_IN_SECONDS = 60 * 60;
|
||||
static const int _DAY_IN_SECONDS = 60 * 60 * 24;
|
||||
|
||||
/// Given an integer duration, converts it to a readable string. Assumes the duration is in seconds, use the `divisor` and `multipler` variables to easily modify the input.
|
||||
///
|
||||
/// Only contains the highest factor (2.5 Days would return 2 Days).
|
||||
String lunaDuration({int divisor = 1, int multiplier = 1}) {
|
||||
if (this == null) return '';
|
||||
int duration = ((this! * multiplier) / divisor).floor();
|
||||
int days = (duration / _DAY_IN_SECONDS).floor();
|
||||
if (days > 0) return '$days ${days == 1 ? 'Day' : 'Days'}';
|
||||
int hours = (duration / _HOUR_IN_SECONDS).floor();
|
||||
if (hours > 0) return '$hours ${hours == 1 ? 'Hour' : 'Hours'}';
|
||||
int minutes = (duration / _MINUTE_IN_SECONDS).floor();
|
||||
if (minutes > 0) return '$minutes ${minutes == 1 ? 'Minute' : 'Minutes'}';
|
||||
return '$duration ${duration == 1 ? 'Second' : 'Seconds'}';
|
||||
}
|
||||
|
||||
/// Given an integer duration, converts it to a readable runtime string. Assumes the duration is in seconds, use the `divisor` and `multipler` variables to easily modify the input.
|
||||
///
|
||||
/// Format example: 1h 23m
|
||||
String lunaRuntime({int divisor = 1, int multiplier = 1}) {
|
||||
if (this == null || this == 0) return '';
|
||||
double runtime = ((this! * multiplier) / divisor);
|
||||
if (runtime < 60) return '${runtime.floor()}m';
|
||||
return '${(runtime / 60).floor()}h ${(runtime - ((runtime / 60).floor() * 60)).floor()}m';
|
||||
}
|
||||
|
||||
/// Given an integer duration, converts it to a readable timestamp string. Assumes the duration is in seconds, use the `divisor` and `multiplier` variables to easily modify the input.
|
||||
///
|
||||
/// Format example: 1:23:45 (1 hour, 23 minutes, and 45 seconds)
|
||||
String lunaTimestamp({int divisor = 1, int multiplier = 1}) {
|
||||
if (this == null) return '';
|
||||
int duration = ((this! * multiplier) / divisor).floor();
|
||||
int hours = 0, minutes = 0;
|
||||
while (duration >= _HOUR_IN_SECONDS) {
|
||||
duration -= _HOUR_IN_SECONDS;
|
||||
hours++;
|
||||
}
|
||||
while (duration >= _MINUTE_IN_SECONDS) {
|
||||
duration -= _MINUTE_IN_SECONDS;
|
||||
minutes++;
|
||||
}
|
||||
return '${hours.toString().padLeft(1, '0')}:${minutes.toString().padLeft(2, '0')}:${duration.toString().padLeft(2, '0')}';
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
extension NavigatorStateExtension on NavigatorState {
|
||||
/// Safely pops the route by first checking that the route *can* be popped.
|
||||
/// If the route can not be popped (it is the first/lowest route in the navigator), nothing occurs.
|
||||
void lunaSafetyPop() {
|
||||
if (this.canPop()) this.pop();
|
||||
}
|
||||
|
||||
/// Pops every route until the route is the first/lowest route in the navigator.
|
||||
void lunaPopToFirst() {
|
||||
this.popUntil((route) => route.isFirst);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
extension ScrollControllerExtension on ScrollController {
|
||||
/// Animate a [Scrollable] back to 1.00, with a predefined duration and curve.
|
||||
Future<void> lunaAnimateToStart() async {
|
||||
if (this.hasClients)
|
||||
this.animateTo(
|
||||
0.00,
|
||||
duration: const Duration(
|
||||
milliseconds: LunaUI.ANIMATION_SPEED_SCROLLING,
|
||||
),
|
||||
curve: Curves.easeInOutQuart,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/vendor.dart';
|
||||
|
||||
abstract class LunaPageGoRouter {
|
||||
GoRoute get route;
|
||||
Future<void> go(BuildContext context);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export 'configuration/external_module.dart';
|
||||
export 'configuration/indexer.dart';
|
||||
export 'configuration/profile.dart';
|
||||
@@ -1,49 +0,0 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
part 'external_module.g.dart';
|
||||
|
||||
/// Hive database object containing all information on an indexer
|
||||
@HiveType(typeId: 26, adapterName: 'ExternalModuleHiveObjectAdapter')
|
||||
class ExternalModuleHiveObject extends HiveObject {
|
||||
/// Create a new [ExternalModuleHiveObject] object with all fields set to empty values('', false, 0, {}, etc.)
|
||||
factory ExternalModuleHiveObject.empty() => ExternalModuleHiveObject(
|
||||
displayName: '',
|
||||
host: '',
|
||||
);
|
||||
|
||||
/// Create a new [ExternalModuleHiveObject] from another [ExternalModuleHiveObject] (deep-copy).
|
||||
factory ExternalModuleHiveObject.fromExternalModuleHiveObject(
|
||||
ExternalModuleHiveObject indexer) =>
|
||||
ExternalModuleHiveObject(
|
||||
displayName: indexer.displayName,
|
||||
host: indexer.host,
|
||||
);
|
||||
|
||||
/// Create a new [ExternalModuleHiveObject] from a map where the keys map 1-to-1 except for "key", which was the old key for apiKey.
|
||||
///
|
||||
/// - Does _not_ do type checking, and will throw an error if the type is invalid.
|
||||
/// - If the key is null, sets to the "empty" value
|
||||
factory ExternalModuleHiveObject.fromMap(Map module) =>
|
||||
ExternalModuleHiveObject(
|
||||
displayName: module['displayName'] ?? '',
|
||||
host: module['host'] ?? '',
|
||||
);
|
||||
|
||||
ExternalModuleHiveObject({
|
||||
required this.displayName,
|
||||
required this.host,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => toMap().toString();
|
||||
|
||||
Map<String, dynamic> toMap() => {
|
||||
"displayName": displayName ?? '',
|
||||
"host": host ?? '',
|
||||
};
|
||||
|
||||
@HiveField(0)
|
||||
String? displayName;
|
||||
@HiveField(1)
|
||||
String? host;
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
part 'indexer.g.dart';
|
||||
|
||||
/// Hive database object containing all information on an indexer
|
||||
@HiveType(typeId: 1, adapterName: 'IndexerHiveObjectAdapter')
|
||||
class IndexerHiveObject extends HiveObject {
|
||||
/// Create a new [IndexerHiveObject] object with all fields set to empty values('', false, 0, {}, etc.)
|
||||
factory IndexerHiveObject.empty() => IndexerHiveObject(
|
||||
displayName: '',
|
||||
host: '',
|
||||
apiKey: '',
|
||||
headers: {},
|
||||
icon: null,
|
||||
);
|
||||
|
||||
/// Create a new [IndexerHiveObject] from another [IndexerHiveObject] (deep-copy).
|
||||
factory IndexerHiveObject.fromIndexerHiveObject(IndexerHiveObject indexer) =>
|
||||
IndexerHiveObject(
|
||||
displayName: indexer.displayName,
|
||||
host: indexer.host,
|
||||
apiKey: indexer.apiKey,
|
||||
headers: indexer.headers,
|
||||
icon: indexer.icon,
|
||||
);
|
||||
|
||||
/// Create a new [IndexerHiveObject] from a map where the keys map 1-to-1 except for "key", which was the old key for apiKey.
|
||||
///
|
||||
/// - Does _not_ do type checking, and will throw an error if the type is invalid.
|
||||
/// - If the key is null, sets to the "empty" value
|
||||
factory IndexerHiveObject.fromMap(Map indexer) => IndexerHiveObject(
|
||||
displayName: indexer['displayName'] ?? '',
|
||||
host: indexer['host'] ?? '',
|
||||
apiKey: indexer['key'] ?? '',
|
||||
headers: indexer['headers'] ?? {},
|
||||
icon: LunaIndexerIcon.GENERIC.fromKey(indexer['icon'] ?? ''),
|
||||
);
|
||||
|
||||
IndexerHiveObject({
|
||||
required this.displayName,
|
||||
required this.host,
|
||||
required this.apiKey,
|
||||
required this.headers,
|
||||
required this.icon,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => toMap().toString();
|
||||
|
||||
Map<String, dynamic> toMap() => {
|
||||
"displayName": displayName ?? '',
|
||||
"host": host ?? '',
|
||||
"key": apiKey ?? '',
|
||||
"headers": headers ?? {},
|
||||
"icon": icon?.key ?? '',
|
||||
};
|
||||
|
||||
@HiveField(0)
|
||||
String? displayName;
|
||||
@HiveField(1)
|
||||
String? host;
|
||||
@HiveField(2)
|
||||
String? apiKey;
|
||||
@HiveField(3)
|
||||
Map? headers;
|
||||
@HiveField(4)
|
||||
LunaIndexerIcon? icon;
|
||||
}
|
||||
@@ -1,422 +0,0 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
part 'profile.g.dart';
|
||||
|
||||
/// Hive database object containing all profile fields
|
||||
@HiveType(typeId: 0, adapterName: 'ProfileHiveObjectAdapter')
|
||||
class ProfileHiveObject extends HiveObject {
|
||||
/// Create a new [ProfileHiveObject] object with all fields set to empty values('', false, 0, {}, etc.)
|
||||
factory ProfileHiveObject.empty() => ProfileHiveObject(
|
||||
//Lidarr
|
||||
lidarrEnabled: false,
|
||||
lidarrHost: '',
|
||||
lidarrKey: '',
|
||||
lidarrHeaders: {},
|
||||
//Radarr
|
||||
radarrEnabled: false,
|
||||
radarrHost: '',
|
||||
radarrKey: '',
|
||||
radarrHeaders: {},
|
||||
//Sonarr
|
||||
sonarrEnabled: false,
|
||||
sonarrHost: '',
|
||||
sonarrKey: '',
|
||||
sonarrHeaders: {},
|
||||
//SABnzbd
|
||||
sabnzbdEnabled: false,
|
||||
sabnzbdHost: '',
|
||||
sabnzbdKey: '',
|
||||
sabnzbdHeaders: {},
|
||||
//NZBGet
|
||||
nzbgetEnabled: false,
|
||||
nzbgetHost: '',
|
||||
nzbgetUser: '',
|
||||
nzbgetPass: '',
|
||||
nzbgetHeaders: {},
|
||||
//Wake on LAN
|
||||
wakeOnLANEnabled: false,
|
||||
wakeOnLANBroadcastAddress: '',
|
||||
wakeOnLANMACAddress: '',
|
||||
//Tautulli
|
||||
tautulliEnabled: false,
|
||||
tautulliHost: '',
|
||||
tautulliKey: '',
|
||||
tautulliHeaders: {},
|
||||
//Ombi
|
||||
ombiEnabled: false,
|
||||
ombiHost: '',
|
||||
ombiKey: '',
|
||||
ombiHeaders: {},
|
||||
//Overseerr
|
||||
overseerrEnabled: false,
|
||||
overseerrHost: '',
|
||||
overseerrKey: '',
|
||||
overseerrHeaders: {},
|
||||
);
|
||||
|
||||
/// Create a new [ProfileHiveObject] from another [ProfileHiveObject] (deep-copy).
|
||||
factory ProfileHiveObject.fromProfileHiveObject(ProfileHiveObject profile) =>
|
||||
ProfileHiveObject(
|
||||
//Lidarr
|
||||
lidarrEnabled: profile.lidarrEnabled,
|
||||
lidarrHost: profile.lidarrHost,
|
||||
lidarrKey: profile.lidarrKey,
|
||||
lidarrHeaders: profile.lidarrHeaders,
|
||||
//Radarr
|
||||
radarrEnabled: profile.radarrEnabled,
|
||||
radarrHost: profile.radarrHost,
|
||||
radarrKey: profile.radarrKey,
|
||||
radarrHeaders: profile.radarrHeaders,
|
||||
//Sonarr
|
||||
sonarrEnabled: profile.sonarrEnabled,
|
||||
sonarrHost: profile.sonarrHost,
|
||||
sonarrKey: profile.sonarrKey,
|
||||
sonarrHeaders: profile.sonarrHeaders,
|
||||
//SABnzbd
|
||||
sabnzbdEnabled: profile.sabnzbdEnabled,
|
||||
sabnzbdHost: profile.sabnzbdHost,
|
||||
sabnzbdKey: profile.sabnzbdKey,
|
||||
sabnzbdHeaders: profile.sabnzbdHeaders,
|
||||
//NZBGet
|
||||
nzbgetEnabled: profile.nzbgetEnabled,
|
||||
nzbgetHost: profile.nzbgetHost,
|
||||
nzbgetUser: profile.nzbgetUser,
|
||||
nzbgetPass: profile.nzbgetPass,
|
||||
nzbgetHeaders: profile.nzbgetHeaders,
|
||||
//Wake On LAN
|
||||
wakeOnLANEnabled: profile.wakeOnLANEnabled,
|
||||
wakeOnLANBroadcastAddress: profile.wakeOnLANBroadcastAddress,
|
||||
wakeOnLANMACAddress: profile.wakeOnLANMACAddress,
|
||||
//Tautulli
|
||||
tautulliEnabled: profile.tautulliEnabled,
|
||||
tautulliHost: profile.tautulliHost,
|
||||
tautulliKey: profile.tautulliKey,
|
||||
tautulliHeaders: profile.tautulliHeaders,
|
||||
//Ombi
|
||||
ombiEnabled: profile.ombiEnabled,
|
||||
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.
|
||||
///
|
||||
/// - Does _not_ do type checking, and will throw an error if the type is invalid.
|
||||
/// - If the key is null, sets to the "empty" value
|
||||
factory ProfileHiveObject.fromMap(Map profile) => ProfileHiveObject(
|
||||
//Sonarr
|
||||
sonarrEnabled: profile['sonarrEnabled'] ?? false,
|
||||
sonarrHost: profile['sonarrHost'] ?? '',
|
||||
sonarrKey: profile['sonarrKey'] ?? '',
|
||||
sonarrHeaders: profile['sonarrHeaders'] ?? {},
|
||||
//Radarr
|
||||
radarrEnabled: profile['radarrEnabled'] ?? false,
|
||||
radarrHost: profile['radarrHost'] ?? '',
|
||||
radarrKey: profile['radarrKey'] ?? '',
|
||||
radarrHeaders: profile['radarrHeaders'] ?? {},
|
||||
//Lidarr
|
||||
lidarrEnabled: profile['lidarrEnabled'] ?? false,
|
||||
lidarrHost: profile['lidarrHost'] ?? '',
|
||||
lidarrKey: profile['lidarrKey'] ?? '',
|
||||
lidarrHeaders: profile['lidarrHeaders'] ?? {},
|
||||
//SABnzbd
|
||||
sabnzbdEnabled: profile['sabnzbdEnabled'] ?? false,
|
||||
sabnzbdHost: profile['sabnzbdHost'] ?? '',
|
||||
sabnzbdKey: profile['sabnzbdKey'] ?? '',
|
||||
sabnzbdHeaders: profile['sabnzbdHeaders'] ?? {},
|
||||
//NZBGet
|
||||
nzbgetEnabled: profile['nzbgetEnabled'] ?? false,
|
||||
nzbgetHost: profile['nzbgetHost'] ?? '',
|
||||
nzbgetUser: profile['nzbgetUser'] ?? '',
|
||||
nzbgetPass: profile['nzbgetPass'] ?? '',
|
||||
nzbgetHeaders: profile['nzbgetHeaders'] ?? {},
|
||||
//Wake on LAN
|
||||
wakeOnLANEnabled: profile['wakeOnLANEnabled'] ?? false,
|
||||
wakeOnLANBroadcastAddress: profile['wakeOnLANBroadcastAddress'] ?? '',
|
||||
wakeOnLANMACAddress: profile['wakeOnLANMACAddress'] ?? '',
|
||||
//Tautulli
|
||||
tautulliEnabled: profile['tautulliEnabled'] ?? false,
|
||||
tautulliHost: profile['tautulliHost'] ?? '',
|
||||
tautulliKey: profile['tautulliKey'] ?? '',
|
||||
tautulliHeaders: profile['tautulliHeaders'] ?? {},
|
||||
//Ombi
|
||||
ombiEnabled: profile['ombiEnabled'] ?? false,
|
||||
ombiHost: profile['ombiHost'] ?? '',
|
||||
ombiKey: profile['ombiKey'] ?? '',
|
||||
ombiHeaders: profile['ombiHeaders'] ?? {},
|
||||
//Overseerr
|
||||
overseerrEnabled: profile['overseerrEnabled'] ?? false,
|
||||
overseerrHost: profile['overseerrHost'] ?? '',
|
||||
overseerrKey: profile['overseerrKey'] ?? '',
|
||||
overseerrHeaders: profile['overseerrHeaders'] ?? {},
|
||||
);
|
||||
|
||||
ProfileHiveObject({
|
||||
//Lidarr
|
||||
required this.lidarrEnabled,
|
||||
required this.lidarrHost,
|
||||
required this.lidarrKey,
|
||||
required this.lidarrHeaders,
|
||||
//Radarr
|
||||
required this.radarrEnabled,
|
||||
required this.radarrHost,
|
||||
required this.radarrKey,
|
||||
required this.radarrHeaders,
|
||||
//Sonarr
|
||||
required this.sonarrEnabled,
|
||||
required this.sonarrHost,
|
||||
required this.sonarrKey,
|
||||
required this.sonarrHeaders,
|
||||
//SABnzbd
|
||||
required this.sabnzbdEnabled,
|
||||
required this.sabnzbdHost,
|
||||
required this.sabnzbdKey,
|
||||
required this.sabnzbdHeaders,
|
||||
//NZBGet
|
||||
required this.nzbgetEnabled,
|
||||
required this.nzbgetHost,
|
||||
required this.nzbgetUser,
|
||||
required this.nzbgetPass,
|
||||
required this.nzbgetHeaders,
|
||||
//Wake On LAN
|
||||
required this.wakeOnLANEnabled,
|
||||
required this.wakeOnLANBroadcastAddress,
|
||||
required this.wakeOnLANMACAddress,
|
||||
//Tautulli
|
||||
required this.tautulliEnabled,
|
||||
required this.tautulliHost,
|
||||
required this.tautulliKey,
|
||||
required this.tautulliHeaders,
|
||||
//Ombi
|
||||
required this.ombiEnabled,
|
||||
required this.ombiHost,
|
||||
required this.ombiKey,
|
||||
required this.ombiHeaders,
|
||||
//Overseerr
|
||||
required this.overseerrEnabled,
|
||||
required this.overseerrHost,
|
||||
required this.overseerrKey,
|
||||
required this.overseerrHeaders,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => toMap().toString();
|
||||
|
||||
Map<String, dynamic> toMap() => {
|
||||
"key": key,
|
||||
//Sonarr
|
||||
"sonarrEnabled": sonarrEnabled,
|
||||
"sonarrHost": sonarrHost,
|
||||
"sonarrKey": sonarrKey,
|
||||
"sonarrHeaders": sonarrHeaders,
|
||||
//Radarr
|
||||
"radarrEnabled": radarrEnabled,
|
||||
"radarrHost": radarrHost,
|
||||
"radarrKey": radarrKey,
|
||||
"radarrHeaders": radarrHeaders,
|
||||
//Lidarr
|
||||
"lidarrEnabled": lidarrEnabled,
|
||||
"lidarrHost": lidarrHost,
|
||||
"lidarrKey": lidarrKey,
|
||||
"lidarrHeaders": lidarrHeaders,
|
||||
//SABnzbd
|
||||
"sabnzbdEnabled": sabnzbdEnabled,
|
||||
"sabnzbdHost": sabnzbdHost,
|
||||
"sabnzbdKey": sabnzbdKey,
|
||||
"sabnzbdHeaders": sabnzbdHeaders,
|
||||
//NZBGet
|
||||
"nzbgetEnabled": nzbgetEnabled,
|
||||
"nzbgetHost": nzbgetHost,
|
||||
"nzbgetUser": nzbgetUser,
|
||||
"nzbgetPass": nzbgetPass,
|
||||
"nzbgetHeaders": nzbgetHeaders,
|
||||
//Wake On LAN
|
||||
"wakeOnLANEnabled": wakeOnLANEnabled,
|
||||
"wakeOnLANBroadcastAddress": wakeOnLANBroadcastAddress,
|
||||
"wakeOnLANMACAddress": wakeOnLANMACAddress,
|
||||
//Tautulli
|
||||
"tautulliEnabled": tautulliEnabled,
|
||||
"tautulliHost": tautulliHost,
|
||||
"tautulliKey": tautulliKey,
|
||||
"tautulliHeaders": tautulliHeaders,
|
||||
//Ombi
|
||||
"ombiEnabled": ombiEnabled,
|
||||
"ombiHost": ombiHost,
|
||||
"ombiKey": ombiKey,
|
||||
"ombiHeaders": ombiHeaders,
|
||||
//Overseerr
|
||||
"overseerrEnabled": overseerrEnabled,
|
||||
"overseerrHost": overseerrHost,
|
||||
"overseerrKey": overseerrKey,
|
||||
"overseerrHeaders": overseerrHeaders,
|
||||
};
|
||||
|
||||
//Lidarr
|
||||
@HiveField(0)
|
||||
bool? lidarrEnabled;
|
||||
@HiveField(1)
|
||||
String? lidarrHost;
|
||||
@HiveField(2)
|
||||
String? lidarrKey;
|
||||
@HiveField(26)
|
||||
Map? lidarrHeaders;
|
||||
|
||||
Map<String, dynamic> getLidarr() => {
|
||||
'enabled': lidarrEnabled ?? false,
|
||||
'host': lidarrHost ?? '',
|
||||
'key': lidarrKey ?? '',
|
||||
'headers': lidarrHeaders ?? {},
|
||||
};
|
||||
|
||||
//Radarr
|
||||
@HiveField(3)
|
||||
bool? radarrEnabled;
|
||||
@HiveField(4)
|
||||
String? radarrHost;
|
||||
@HiveField(5)
|
||||
String? radarrKey;
|
||||
@HiveField(27)
|
||||
Map? radarrHeaders;
|
||||
|
||||
Map<String, dynamic> getRadarr() => {
|
||||
'enabled': radarrEnabled ?? false,
|
||||
'host': radarrHost ?? '',
|
||||
'key': radarrKey ?? '',
|
||||
'headers': radarrHeaders ?? {},
|
||||
};
|
||||
|
||||
//Sonarr
|
||||
@HiveField(6)
|
||||
bool? sonarrEnabled;
|
||||
@HiveField(7)
|
||||
String? sonarrHost;
|
||||
@HiveField(8)
|
||||
String? sonarrKey;
|
||||
@HiveField(21)
|
||||
bool? sonarrVersion3; // Deprecated
|
||||
@HiveField(28)
|
||||
Map? sonarrHeaders;
|
||||
|
||||
Map<String, dynamic> getSonarr() => {
|
||||
'enabled': sonarrEnabled ?? false,
|
||||
'host': sonarrHost ?? '',
|
||||
'key': sonarrKey ?? '',
|
||||
'headers': sonarrHeaders ?? {},
|
||||
};
|
||||
|
||||
//SABnzbd
|
||||
@HiveField(9)
|
||||
bool? sabnzbdEnabled;
|
||||
@HiveField(10)
|
||||
String? sabnzbdHost;
|
||||
@HiveField(11)
|
||||
String? sabnzbdKey;
|
||||
@HiveField(29)
|
||||
Map? sabnzbdHeaders;
|
||||
|
||||
Map<String, dynamic> getSABnzbd() => {
|
||||
'enabled': sabnzbdEnabled ?? false,
|
||||
'host': sabnzbdHost ?? '',
|
||||
'key': sabnzbdKey ?? '',
|
||||
'headers': sabnzbdHeaders ?? {},
|
||||
};
|
||||
|
||||
//NZBGet
|
||||
@HiveField(12)
|
||||
bool? nzbgetEnabled;
|
||||
@HiveField(13)
|
||||
String? nzbgetHost;
|
||||
@HiveField(14)
|
||||
String? nzbgetUser;
|
||||
@HiveField(15)
|
||||
String? nzbgetPass;
|
||||
@HiveField(22)
|
||||
bool? nzbgetBasicAuth; // Deprecated
|
||||
@HiveField(30)
|
||||
Map? nzbgetHeaders;
|
||||
|
||||
Map<String, dynamic> getNZBGet() => {
|
||||
'enabled': nzbgetEnabled ?? false,
|
||||
'host': nzbgetHost ?? '',
|
||||
'user': nzbgetUser ?? '',
|
||||
'pass': nzbgetPass ?? '',
|
||||
'headers': nzbgetHeaders ?? {},
|
||||
};
|
||||
|
||||
//Wake On LAN
|
||||
@HiveField(23)
|
||||
bool? wakeOnLANEnabled;
|
||||
@HiveField(24)
|
||||
String? wakeOnLANBroadcastAddress;
|
||||
@HiveField(25)
|
||||
String? wakeOnLANMACAddress;
|
||||
|
||||
Map<String, dynamic> getWakeOnLAN() => {
|
||||
'enabled': wakeOnLANEnabled ?? false,
|
||||
'broadcastAddress': wakeOnLANBroadcastAddress ?? '',
|
||||
'MACAddress': wakeOnLANMACAddress ?? '',
|
||||
};
|
||||
|
||||
//Tautulli
|
||||
@HiveField(31)
|
||||
bool? tautulliEnabled;
|
||||
@HiveField(32)
|
||||
String? tautulliHost;
|
||||
@HiveField(33)
|
||||
String? tautulliKey;
|
||||
@HiveField(35)
|
||||
Map? tautulliHeaders;
|
||||
|
||||
Map<String, dynamic> getTautulli() => {
|
||||
'enabled': tautulliEnabled ?? false,
|
||||
'host': tautulliHost ?? '',
|
||||
'key': tautulliKey ?? '',
|
||||
'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 ?? {},
|
||||
};
|
||||
|
||||
//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 ?? {},
|
||||
};
|
||||
|
||||
bool get anythingEnabled {
|
||||
for (final module in LunaModule.active) {
|
||||
if (module.isEnabled) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
export 'logs/log.dart';
|
||||
export 'logs/log_type.dart';
|
||||
@@ -1,5 +0,0 @@
|
||||
export 'types/browser.dart';
|
||||
export 'types/indexer_icon.dart';
|
||||
export 'types/links.dart';
|
||||
export 'types/list_view_option.dart';
|
||||
export 'types/loading_state.dart';
|
||||
@@ -1,17 +0,0 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
part 'browser.g.dart';
|
||||
|
||||
@HiveType(typeId: 11, adapterName: 'DeprecatedLunaBrowserAdapter')
|
||||
enum DeprecatedLunaBrowser {
|
||||
@HiveField(0)
|
||||
APPLE_SAFARI,
|
||||
@HiveField(1)
|
||||
BRAVE_BROWSER,
|
||||
@HiveField(2)
|
||||
GOOGLE_CHROME,
|
||||
@HiveField(3)
|
||||
MICROSOFT_EDGE,
|
||||
@HiveField(4)
|
||||
MOZILLA_FIREFOX,
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/string_links.dart';
|
||||
|
||||
enum LunaLinks {
|
||||
CHANGELOG('https://www.lunasea.app/changelog'),
|
||||
BUILD_CHANNELS('https://www.lunasea.app/build-channels'),
|
||||
BUILDS('https://www.lunasea.app/builds'),
|
||||
DISCORD('https://www.lunasea.app/discord'),
|
||||
DOCUMENTATION('https://www.lunasea.app/docs'),
|
||||
FEEDBACK_BOARD('https://www.lunasea.app/feedback'),
|
||||
GITHUB('https://www.lunasea.app/github'),
|
||||
NOTIFICATIONS_DOC('https://docs.lunasea.app/lunasea/notifications'),
|
||||
REDDIT('https://www.lunasea.app/reddit'),
|
||||
WEBLATE('https:/www.lunasea.app/translate'),
|
||||
WEBSITE('https://www.lunasea.app');
|
||||
|
||||
final String url;
|
||||
const LunaLinks(this.url);
|
||||
|
||||
Future<void> launch() async => url.openLink();
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
abstract class LunaWebhooks {
|
||||
/// Handle the incoming webhook for the module.
|
||||
Future<void> handle(Map<dynamic, dynamic> data);
|
||||
|
||||
/// Given a [LunaModule] and Firebase UID, return the module's webhook endpoint for the user.
|
||||
static String buildUserTokenURL(String? token, LunaModule module) =>
|
||||
'https://notify.lunasea.app/v1/${module.key}/user/$token';
|
||||
|
||||
/// Given a [LunaModule] and Firebase device token, return the module's webhook endpoint for the device.
|
||||
static String buildDeviceTokenURL(String? token, LunaModule module) =>
|
||||
'https://notify.lunasea.app/v1/${module.key}/device/$token';
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
class LunaInvalidRoute extends StatelessWidget {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
final String title;
|
||||
final String message;
|
||||
|
||||
LunaInvalidRoute({
|
||||
Key? key,
|
||||
this.title = 'LunaSea',
|
||||
this.message = '404: Not Found',
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LunaScaffold(
|
||||
scaffoldKey: _scaffoldKey,
|
||||
module: LunaModule.SETTINGS,
|
||||
appBar: LunaAppBar(
|
||||
title: title,
|
||||
scrollControllers: const [],
|
||||
),
|
||||
body: LunaMessage.goBack(
|
||||
context: context,
|
||||
text: message,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export 'the_movie_db/api.dart';
|
||||
@@ -1,16 +0,0 @@
|
||||
class TheMovieDB {
|
||||
static const String _IMAGE_ENDPOINT_URL = 'https://image.tmdb.org/t/p/';
|
||||
|
||||
static const String _IMAGE_BACKDROP_SIZE = 'w300';
|
||||
static const String _IMAGE_POSTER_SIZE = 'w185';
|
||||
|
||||
static String? getPosterURL(String? id) {
|
||||
if (id != null) return '$_IMAGE_ENDPOINT_URL$_IMAGE_POSTER_SIZE$id';
|
||||
return null;
|
||||
}
|
||||
|
||||
static String? getBackdropURL(String? id) {
|
||||
if (id != null) return '$_IMAGE_ENDPOINT_URL$_IMAGE_BACKDROP_SIZE$id';
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/string.dart';
|
||||
import 'package:lunasea/system/build.dart';
|
||||
import 'package:lunasea/system/flavor.dart';
|
||||
|
||||
class LunaChangelogSheet extends LunaBottomModalSheet {
|
||||
late _Changelog _changelog;
|
||||
String _version = '';
|
||||
|
||||
bool _isBuildDifferent() {
|
||||
final db = LunaSeaDatabase.CHANGELOG_LAST_BUILD.read();
|
||||
final current = _version.split('.').map((s) => int.parse(s)).toList();
|
||||
final stored = db.split('.').map((s) => int.parse(s)).toList();
|
||||
|
||||
if (current[0] != stored[0]) return true;
|
||||
if (current[1] != stored[1]) return true;
|
||||
if (current[2] != stored[2]) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<dynamic> show({
|
||||
required BuildContext context,
|
||||
Widget Function(BuildContext context)? builder,
|
||||
bool checkBuildVersion = false,
|
||||
bool showCommitHistory = false,
|
||||
}) async {
|
||||
// Do not show unless it is a prod release
|
||||
if (LunaFlavor.CANDIDATE.isRunningFlavor()) {
|
||||
if (showCommitHistory) LunaBuild().openCommitHistory();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
_changelog = await DefaultAssetBundle.of(context)
|
||||
.loadString('assets/changelog.json')
|
||||
.then((data) => _Changelog.fromJson(json.decode(data)));
|
||||
|
||||
PackageInfo _package = await PackageInfo.fromPlatform();
|
||||
|
||||
_version = _package.version;
|
||||
|
||||
if (checkBuildVersion) {
|
||||
if (!_isBuildDifferent()) return;
|
||||
LunaSeaDatabase.CHANGELOG_LAST_BUILD.update(_version);
|
||||
}
|
||||
|
||||
return this.showModal(context: context, builder: builder);
|
||||
} catch (error, stack) {
|
||||
LunaLogger().error('Failed to show changelog sheet', error, stack);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget builder(BuildContext context) {
|
||||
return LunaListViewModal(
|
||||
children: [
|
||||
LunaHeader(
|
||||
text: _version,
|
||||
subtitle: _changelog.motd,
|
||||
),
|
||||
..._buildChangeBlock(
|
||||
'lunasea.New'.tr(),
|
||||
_changelog.changesNew,
|
||||
),
|
||||
..._buildChangeBlock(
|
||||
'lunasea.Tweaks'.tr(),
|
||||
_changelog.changesTweaks,
|
||||
),
|
||||
..._buildChangeBlock(
|
||||
'lunasea.Fixes'.tr(),
|
||||
_changelog.changesFixes,
|
||||
),
|
||||
const SizedBox(height: LunaUI.DEFAULT_MARGIN_SIZE / 2),
|
||||
],
|
||||
actionBar: LunaBottomActionBar(
|
||||
actions: [
|
||||
LunaButton.text(
|
||||
text: 'lunasea.FullChangelog'.tr(),
|
||||
icon: Icons.track_changes_rounded,
|
||||
onTap: LunaLinks.CHANGELOG.launch,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _buildChangeBlock(String header, List<_Change> changes) {
|
||||
if (changes.isEmpty) return [];
|
||||
return [
|
||||
LunaHeader(text: header),
|
||||
LunaTableCard(
|
||||
content: List<LunaTableContent>.generate(
|
||||
changes.length,
|
||||
(index) {
|
||||
String _body = changes[index]
|
||||
.changes
|
||||
.map((s) => '${LunaUI.TEXT_BULLET.pad()}$s')
|
||||
.join('\n');
|
||||
return LunaTableContent(
|
||||
title: changes[index].module,
|
||||
body: _body,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class _Changelog {
|
||||
String? motd;
|
||||
List<_Change> changesNew = [];
|
||||
List<_Change> changesTweaks = [];
|
||||
List<_Change> changesFixes = [];
|
||||
|
||||
static _Changelog fromJson(Map<String, dynamic> json) {
|
||||
_Changelog changelog = _Changelog();
|
||||
List<dynamic>? data;
|
||||
|
||||
changelog.motd = json['motd'] ?? 'Welcome to LunaSea!';
|
||||
|
||||
data = json['new'];
|
||||
data?.forEach((c) => changelog.changesNew.add(_Change.fromJson(c)));
|
||||
|
||||
data = json['tweaks'];
|
||||
data?.forEach((c) => changelog.changesTweaks.add(_Change.fromJson(c)));
|
||||
|
||||
data = json['fixes'];
|
||||
data?.forEach((c) => changelog.changesFixes.add(_Change.fromJson(c)));
|
||||
|
||||
return changelog;
|
||||
}
|
||||
}
|
||||
|
||||
class _Change {
|
||||
late String module;
|
||||
late List<String> changes;
|
||||
|
||||
_Change._();
|
||||
|
||||
static _Change fromJson(Map<String, dynamic> json) {
|
||||
_Change change = _Change._();
|
||||
change.module = json['module'] as String;
|
||||
change.changes = (json['changes'] as List).cast<String>();
|
||||
return change;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,20 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core/models/configuration/external_module.dart';
|
||||
import 'package:lunasea/core/models/configuration/indexer.dart';
|
||||
import 'package:lunasea/core/models/configuration/profile.dart';
|
||||
import 'package:lunasea/core/models/logs/log.dart';
|
||||
import 'package:lunasea/database/models/external_module.dart';
|
||||
import 'package:lunasea/database/models/indexer.dart';
|
||||
import 'package:lunasea/database/models/log.dart';
|
||||
import 'package:lunasea/database/models/profile.dart';
|
||||
import 'package:lunasea/database/table.dart';
|
||||
import 'package:lunasea/system/logger.dart';
|
||||
import 'package:lunasea/vendor.dart';
|
||||
|
||||
enum LunaBox<T> {
|
||||
alerts<dynamic>('alerts'),
|
||||
externalModules<ExternalModuleHiveObject>('external_modules'),
|
||||
indexers<IndexerHiveObject>('indexers'),
|
||||
externalModules<LunaExternalModule>('external_modules'),
|
||||
indexers<LunaIndexer>('indexers'),
|
||||
logs<LunaLogHiveObject>('logs'),
|
||||
lunasea<dynamic>('lunasea'),
|
||||
profiles<ProfileHiveObject>('profiles');
|
||||
profiles<LunaProfile>('profiles');
|
||||
|
||||
final String key;
|
||||
const LunaBox(this.key);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/database/database.dart';
|
||||
import 'package:lunasea/database/models/external_module.dart';
|
||||
import 'package:lunasea/database/models/indexer.dart';
|
||||
import 'package:lunasea/database/table.dart';
|
||||
|
||||
class LunaConfig {
|
||||
@@ -40,7 +42,7 @@ class LunaConfig {
|
||||
|
||||
for (final item in data) {
|
||||
final key = item['key'];
|
||||
final obj = ProfileHiveObject.fromMap(item);
|
||||
final obj = LunaProfile.fromJson((item as Map).cast<String, dynamic>());
|
||||
LunaBox.profiles.update(key, obj);
|
||||
}
|
||||
}
|
||||
@@ -49,7 +51,7 @@ class LunaConfig {
|
||||
if (data == null) return;
|
||||
|
||||
for (final indexer in data) {
|
||||
final obj = IndexerHiveObject.fromMap(indexer);
|
||||
final obj = LunaIndexer.fromJson(indexer);
|
||||
LunaBox.indexers.create(obj);
|
||||
}
|
||||
}
|
||||
@@ -58,7 +60,7 @@ class LunaConfig {
|
||||
if (data == null) return;
|
||||
|
||||
for (final module in data) {
|
||||
final obj = ExternalModuleHiveObject.fromMap(module);
|
||||
final obj = LunaExternalModule.fromJson(module);
|
||||
LunaBox.externalModules.create(obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import 'package:lunasea/core/models/configuration/profile.dart';
|
||||
import 'package:lunasea/database/box.dart';
|
||||
import 'package:lunasea/database/models/profile.dart';
|
||||
import 'package:lunasea/database/table.dart';
|
||||
import 'package:lunasea/database/tables/lunasea.dart';
|
||||
import 'package:lunasea/system/platform.dart';
|
||||
import 'package:lunasea/system/profile.dart';
|
||||
import 'package:lunasea/vendor.dart';
|
||||
|
||||
class LunaDatabase {
|
||||
@@ -27,7 +26,7 @@ class LunaDatabase {
|
||||
await clear();
|
||||
|
||||
const defaultProfile = LunaProfile.DEFAULT_PROFILE;
|
||||
LunaBox.profiles.update(defaultProfile, ProfileHiveObject.empty());
|
||||
LunaBox.profiles.update(defaultProfile, LunaProfile());
|
||||
LunaSeaDatabase.ENABLED_PROFILE.update(defaultProfile);
|
||||
}
|
||||
|
||||
|
||||
37
lib/database/models/deprecated.dart
Normal file
37
lib/database/models/deprecated.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'package:lunasea/vendor.dart';
|
||||
|
||||
part 'deprecated.g.dart';
|
||||
|
||||
void registerDeprecatedAdapters() {
|
||||
Hive.registerAdapter(_Deprecated02Adapter());
|
||||
Hive.registerAdapter(_Deprecated03Adapter());
|
||||
Hive.registerAdapter(_Deprecated04Adapter());
|
||||
Hive.registerAdapter(_Deprecated05Adapter());
|
||||
Hive.registerAdapter(_Deprecated06Adapter());
|
||||
Hive.registerAdapter(_Deprecated07Adapter());
|
||||
Hive.registerAdapter(_Deprecated11Adapter());
|
||||
}
|
||||
|
||||
@HiveType(typeId: 2, adapterName: '_Deprecated02Adapter') // Next: 2
|
||||
class _Deprecated02 extends HiveObject {}
|
||||
|
||||
@HiveType(typeId: 3, adapterName: '_Deprecated03Adapter') // Next: 3
|
||||
class _Deprecated03 extends HiveObject {}
|
||||
|
||||
@HiveType(typeId: 4, adapterName: '_Deprecated04Adapter') // Next: 1
|
||||
class _Deprecated04 extends HiveObject {}
|
||||
|
||||
@HiveType(typeId: 5, adapterName: '_Deprecated05Adapter') // Next: 3
|
||||
class _Deprecated05 extends HiveObject {}
|
||||
|
||||
@HiveType(typeId: 6, adapterName: '_Deprecated06Adapter') // Next: 2
|
||||
class _Deprecated06 extends HiveObject {}
|
||||
|
||||
@HiveType(typeId: 7, adapterName: '_Deprecated07Adapter') // Next: 2
|
||||
class _Deprecated07 extends HiveObject {}
|
||||
|
||||
@HiveType(typeId: 11, adapterName: '_Deprecated11Adapter') // Next: 5
|
||||
enum _Deprecated11 {
|
||||
@HiveField(0)
|
||||
DEPRECATED,
|
||||
}
|
||||
37
lib/database/models/external_module.dart
Normal file
37
lib/database/models/external_module.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
part 'external_module.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
@HiveType(typeId: 26, adapterName: 'LunaExternalModuleAdapter')
|
||||
class LunaExternalModule extends HiveObject {
|
||||
@JsonKey()
|
||||
@HiveField(0)
|
||||
String displayName;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(1)
|
||||
String host;
|
||||
|
||||
LunaExternalModule({
|
||||
this.displayName = '',
|
||||
this.host = '',
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => json.encode(this.toJson());
|
||||
|
||||
Map<String, dynamic> toJson() => _$LunaExternalModuleToJson(this);
|
||||
|
||||
factory LunaExternalModule.fromJson(Map<String, dynamic> json) {
|
||||
return _$LunaExternalModuleFromJson(json);
|
||||
}
|
||||
|
||||
factory LunaExternalModule.clone(LunaExternalModule profile) {
|
||||
return LunaExternalModule.fromJson(profile.toJson());
|
||||
}
|
||||
|
||||
factory LunaExternalModule.get(String key) {
|
||||
return LunaBox.externalModules.read(key)!;
|
||||
}
|
||||
}
|
||||
53
lib/database/models/indexer.dart
Normal file
53
lib/database/models/indexer.dart
Normal file
@@ -0,0 +1,53 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/types/indexer_icon.dart';
|
||||
|
||||
part 'indexer.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
@HiveType(typeId: 1, adapterName: 'LunaIndexerAdapter')
|
||||
class LunaIndexer extends HiveObject {
|
||||
@JsonKey()
|
||||
@HiveField(0)
|
||||
String displayName;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(1)
|
||||
String host;
|
||||
|
||||
@JsonKey(name: 'key')
|
||||
@HiveField(2)
|
||||
String apiKey;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(3)
|
||||
Map headers;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(4)
|
||||
LunaIndexerIcon? icon;
|
||||
|
||||
LunaIndexer({
|
||||
this.displayName = '',
|
||||
this.host = '',
|
||||
this.apiKey = '',
|
||||
this.headers = const {},
|
||||
this.icon,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => json.encode(this.toJson());
|
||||
|
||||
Map<String, dynamic> toJson() => _$LunaIndexerToJson(this);
|
||||
|
||||
factory LunaIndexer.fromJson(Map<String, dynamic> json) {
|
||||
return _$LunaIndexerFromJson(json);
|
||||
}
|
||||
|
||||
factory LunaIndexer.clone(LunaIndexer profile) {
|
||||
return LunaIndexer.fromJson(profile.toJson());
|
||||
}
|
||||
|
||||
factory LunaIndexer.get(String key) {
|
||||
return LunaBox.indexers.read(key)!;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/types/log_type.dart';
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
|
||||
part 'log.g.dart';
|
||||
|
||||
/// Hive database object containing all information on a log
|
||||
@HiveType(typeId: 23, adapterName: 'LunaLogHiveObjectAdapter')
|
||||
class LunaLogHiveObject extends HiveObject {
|
||||
@HiveField(0)
|
||||
@@ -71,14 +71,14 @@ class LunaLogHiveObject extends HiveObject {
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"timestamp":
|
||||
DateTime.fromMillisecondsSinceEpoch(timestamp).toIso8601String(),
|
||||
"type": type.name,
|
||||
"type": type.title,
|
||||
"message": message,
|
||||
if (className?.isNotEmpty ?? false) "class_name": className,
|
||||
if (methodName?.isNotEmpty ?? false) "method_name": methodName,
|
||||
"message": message,
|
||||
if (error?.isNotEmpty ?? false) "error": error,
|
||||
if (stackTrace?.isNotEmpty ?? false)
|
||||
"stack_trace": stackTrace?.trim().split('\n') ?? [],
|
||||
290
lib/database/models/profile.dart
Normal file
290
lib/database/models/profile.dart
Normal file
@@ -0,0 +1,290 @@
|
||||
import 'package:lunasea/database/box.dart';
|
||||
import 'package:lunasea/database/tables/lunasea.dart';
|
||||
import 'package:lunasea/modules.dart';
|
||||
import 'package:lunasea/vendor.dart';
|
||||
|
||||
part 'profile.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
@HiveType(typeId: 0, adapterName: 'LunaProfileAdapter')
|
||||
class LunaProfile extends HiveObject {
|
||||
static const String DEFAULT_PROFILE = 'default';
|
||||
|
||||
static LunaProfile get current {
|
||||
final enabled = LunaSeaDatabase.ENABLED_PROFILE.read();
|
||||
return LunaBox.profiles.read(enabled) ?? LunaProfile();
|
||||
}
|
||||
|
||||
static List<String> get list {
|
||||
final profiles = LunaBox.profiles.keys.cast<String>().toList();
|
||||
profiles.sort((a, b) => a.toLowerCase().compareTo(b.toLowerCase()));
|
||||
return profiles;
|
||||
}
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(0)
|
||||
bool lidarrEnabled;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(1)
|
||||
String lidarrHost;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(2)
|
||||
String lidarrKey;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(26)
|
||||
Map lidarrHeaders;
|
||||
|
||||
Map<String, dynamic> getLidarr() {
|
||||
return {
|
||||
'enabled': lidarrEnabled,
|
||||
'host': lidarrHost,
|
||||
'key': lidarrKey,
|
||||
'headers': lidarrHeaders,
|
||||
};
|
||||
}
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(3)
|
||||
bool radarrEnabled;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(4)
|
||||
String radarrHost;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(5)
|
||||
String radarrKey;
|
||||
|
||||
@HiveField(27)
|
||||
Map radarrHeaders;
|
||||
|
||||
Map<String, dynamic> getRadarr() {
|
||||
return {
|
||||
'enabled': radarrEnabled,
|
||||
'host': radarrHost,
|
||||
'key': radarrKey,
|
||||
'headers': radarrHeaders,
|
||||
};
|
||||
}
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(6)
|
||||
bool sonarrEnabled;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(7)
|
||||
String sonarrHost;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(8)
|
||||
String sonarrKey;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(28)
|
||||
Map sonarrHeaders;
|
||||
|
||||
Map<String, dynamic> getSonarr() {
|
||||
return {
|
||||
'enabled': sonarrEnabled,
|
||||
'host': sonarrHost,
|
||||
'key': sonarrKey,
|
||||
'headers': sonarrHeaders,
|
||||
};
|
||||
}
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(9)
|
||||
bool sabnzbdEnabled;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(10)
|
||||
String sabnzbdHost;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(11)
|
||||
String sabnzbdKey;
|
||||
|
||||
@JsonKey()
|
||||
@JsonKey()
|
||||
@HiveField(29)
|
||||
Map sabnzbdHeaders;
|
||||
|
||||
Map<String, dynamic> getSABnzbd() {
|
||||
return {
|
||||
'enabled': sabnzbdEnabled,
|
||||
'host': sabnzbdHost,
|
||||
'key': sabnzbdKey,
|
||||
'headers': sabnzbdHeaders,
|
||||
};
|
||||
}
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(12)
|
||||
bool nzbgetEnabled;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(13)
|
||||
String nzbgetHost;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(14)
|
||||
String nzbgetUser;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(15)
|
||||
String nzbgetPass;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(30)
|
||||
Map nzbgetHeaders;
|
||||
|
||||
Map<String, dynamic> getNZBGet() {
|
||||
return {
|
||||
'enabled': nzbgetEnabled,
|
||||
'host': nzbgetHost,
|
||||
'user': nzbgetUser,
|
||||
'pass': nzbgetPass,
|
||||
'headers': nzbgetHeaders,
|
||||
};
|
||||
}
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(23)
|
||||
bool wakeOnLANEnabled;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(24)
|
||||
String wakeOnLANBroadcastAddress;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(25)
|
||||
String wakeOnLANMACAddress;
|
||||
|
||||
Map<String, dynamic> getWakeOnLAN() {
|
||||
return {
|
||||
'enabled': wakeOnLANEnabled,
|
||||
'broadcastAddress': wakeOnLANBroadcastAddress,
|
||||
'MACAddress': wakeOnLANMACAddress,
|
||||
};
|
||||
}
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(31)
|
||||
bool tautulliEnabled;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(32)
|
||||
String tautulliHost;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(33)
|
||||
String tautulliKey;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(35)
|
||||
Map tautulliHeaders;
|
||||
|
||||
Map<String, dynamic> getTautulli() {
|
||||
return {
|
||||
'enabled': tautulliEnabled,
|
||||
'host': tautulliHost,
|
||||
'key': tautulliKey,
|
||||
'headers': tautulliHeaders,
|
||||
};
|
||||
}
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(40)
|
||||
bool overseerrEnabled;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(41)
|
||||
String overseerrHost;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(42)
|
||||
String overseerrKey;
|
||||
|
||||
@JsonKey()
|
||||
@HiveField(43)
|
||||
Map overseerrHeaders;
|
||||
|
||||
Map<String, dynamic> getOverseerr() {
|
||||
return {
|
||||
'enabled': overseerrEnabled,
|
||||
'host': overseerrHost,
|
||||
'key': overseerrKey,
|
||||
'headers': overseerrHeaders,
|
||||
};
|
||||
}
|
||||
|
||||
LunaProfile({
|
||||
//Lidarr
|
||||
this.lidarrEnabled = false,
|
||||
this.lidarrHost = '',
|
||||
this.lidarrKey = '',
|
||||
this.lidarrHeaders = const {},
|
||||
//Radarr
|
||||
this.radarrEnabled = false,
|
||||
this.radarrHost = '',
|
||||
this.radarrKey = '',
|
||||
this.radarrHeaders = const {},
|
||||
//Sonarr
|
||||
this.sonarrEnabled = false,
|
||||
this.sonarrHost = '',
|
||||
this.sonarrKey = '',
|
||||
this.sonarrHeaders = const {},
|
||||
//SABnzbd
|
||||
this.sabnzbdEnabled = false,
|
||||
this.sabnzbdHost = '',
|
||||
this.sabnzbdKey = '',
|
||||
this.sabnzbdHeaders = const {},
|
||||
//NZBGet
|
||||
this.nzbgetEnabled = false,
|
||||
this.nzbgetHost = '',
|
||||
this.nzbgetUser = '',
|
||||
this.nzbgetPass = '',
|
||||
this.nzbgetHeaders = const {},
|
||||
//Wake On LAN
|
||||
this.wakeOnLANEnabled = false,
|
||||
this.wakeOnLANBroadcastAddress = '',
|
||||
this.wakeOnLANMACAddress = '',
|
||||
//Tautulli
|
||||
this.tautulliEnabled = false,
|
||||
this.tautulliHost = '',
|
||||
this.tautulliKey = '',
|
||||
this.tautulliHeaders = const {},
|
||||
//Overseerr
|
||||
this.overseerrEnabled = false,
|
||||
this.overseerrHost = '',
|
||||
this.overseerrKey = '',
|
||||
this.overseerrHeaders = const {},
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => json.encode(this.toJson());
|
||||
|
||||
Map<String, dynamic> toJson() => _$LunaProfileToJson(this);
|
||||
|
||||
factory LunaProfile.fromJson(Map<String, dynamic> json) {
|
||||
return _$LunaProfileFromJson(json);
|
||||
}
|
||||
|
||||
factory LunaProfile.clone(LunaProfile profile) {
|
||||
return LunaProfile.fromJson(profile.toJson());
|
||||
}
|
||||
|
||||
factory LunaProfile.get(String key) {
|
||||
return LunaBox.profiles.read(key)!;
|
||||
}
|
||||
|
||||
bool isAnythingEnabled() {
|
||||
for (final module in LunaModule.active) {
|
||||
if (module.isEnabled) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/database/box.dart';
|
||||
import 'package:lunasea/database/models/deprecated.dart';
|
||||
import 'package:lunasea/database/tables/dashboard.dart';
|
||||
import 'package:lunasea/database/tables/lidarr.dart';
|
||||
import 'package:lunasea/database/tables/lunasea.dart';
|
||||
@@ -32,7 +33,8 @@ enum LunaTable<T extends LunaTableMixin> {
|
||||
});
|
||||
|
||||
static void register() {
|
||||
LunaTable.values.forEach((t) => t.items[0].register());
|
||||
for (final table in LunaTable.values) table.items[0].register();
|
||||
registerDeprecatedAdapters();
|
||||
}
|
||||
|
||||
T? _itemFromKey(String key) {
|
||||
@@ -72,7 +74,7 @@ mixin LunaTableMixin<T> on Enum {
|
||||
T read() => box.read(key, fallback: fallback);
|
||||
void update(T value) => box.update(key, value);
|
||||
|
||||
/// Default is a no-op and does not register any Hive adapters
|
||||
/// Default is an empty list and does not register any Hive adapters
|
||||
void register() {}
|
||||
|
||||
/// The list of items that are not imported or exported by default
|
||||
@@ -86,8 +88,8 @@ mixin LunaTableMixin<T> on Enum {
|
||||
|
||||
@mustCallSuper
|
||||
void import(dynamic value) {
|
||||
if (blockedFromImportExport.contains(this)) return;
|
||||
return update(value);
|
||||
if (blockedFromImportExport.contains(this) || value == null) return;
|
||||
return update(value as T);
|
||||
}
|
||||
|
||||
ValueListenableBuilder watch({
|
||||
|
||||
@@ -33,35 +33,39 @@ enum DashboardDatabase<T> with LunaTableMixin<T> {
|
||||
|
||||
@override
|
||||
dynamic export() {
|
||||
if (this == DashboardDatabase.CALENDAR_STARTING_DAY) {
|
||||
return DashboardDatabase.CALENDAR_STARTING_DAY.read().key;
|
||||
DashboardDatabase db = this;
|
||||
switch (db) {
|
||||
case DashboardDatabase.CALENDAR_STARTING_DAY:
|
||||
return DashboardDatabase.CALENDAR_STARTING_DAY.read().key;
|
||||
case DashboardDatabase.CALENDAR_STARTING_SIZE:
|
||||
return DashboardDatabase.CALENDAR_STARTING_SIZE.read().key;
|
||||
case DashboardDatabase.CALENDAR_STARTING_TYPE:
|
||||
return DashboardDatabase.CALENDAR_STARTING_TYPE.read().key;
|
||||
default:
|
||||
return super.export();
|
||||
}
|
||||
if (this == DashboardDatabase.CALENDAR_STARTING_SIZE) {
|
||||
return DashboardDatabase.CALENDAR_STARTING_SIZE.read().key;
|
||||
}
|
||||
if (this == DashboardDatabase.CALENDAR_STARTING_TYPE) {
|
||||
return DashboardDatabase.CALENDAR_STARTING_TYPE.read().key;
|
||||
}
|
||||
return super.export();
|
||||
}
|
||||
|
||||
@override
|
||||
void import(dynamic value) {
|
||||
if (this == DashboardDatabase.CALENDAR_STARTING_DAY) {
|
||||
final item = CalendarStartingDay.MONDAY.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
DashboardDatabase db = this;
|
||||
dynamic result;
|
||||
|
||||
switch (db) {
|
||||
case DashboardDatabase.CALENDAR_STARTING_DAY:
|
||||
result = CalendarStartingDay.MONDAY.fromKey(value.toString());
|
||||
break;
|
||||
case DashboardDatabase.CALENDAR_STARTING_SIZE:
|
||||
result = CalendarStartingSize.ONE_WEEK.fromKey(value.toString());
|
||||
break;
|
||||
case DashboardDatabase.CALENDAR_STARTING_TYPE:
|
||||
result = CalendarStartingType.CALENDAR.fromKey(value.toString());
|
||||
break;
|
||||
default:
|
||||
result = value;
|
||||
break;
|
||||
}
|
||||
if (this == DashboardDatabase.CALENDAR_STARTING_SIZE) {
|
||||
final item = CalendarStartingSize.ONE_WEEK.fromKey(value.toString());
|
||||
if (item != null) return update(item as T);
|
||||
return;
|
||||
}
|
||||
if (this == DashboardDatabase.CALENDAR_STARTING_TYPE) {
|
||||
final item = CalendarStartingType.CALENDAR.fromKey(value.toString());
|
||||
if (item != null) return update(item as T);
|
||||
return;
|
||||
}
|
||||
return super.import(value);
|
||||
|
||||
return super.import(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import 'package:lunasea/core/models/configuration/external_module.dart';
|
||||
import 'package:lunasea/core/models/configuration/indexer.dart';
|
||||
import 'package:lunasea/core/models/configuration/profile.dart';
|
||||
import 'package:lunasea/core/models/logs/log.dart';
|
||||
import 'package:lunasea/core/models/logs/log_type.dart';
|
||||
import 'package:lunasea/core/models/types/browser.dart';
|
||||
import 'package:lunasea/core/models/types/indexer_icon.dart';
|
||||
import 'package:lunasea/core/models/types/list_view_option.dart';
|
||||
import 'package:lunasea/database/models/external_module.dart';
|
||||
import 'package:lunasea/database/models/indexer.dart';
|
||||
import 'package:lunasea/database/models/log.dart';
|
||||
import 'package:lunasea/database/models/profile.dart';
|
||||
import 'package:lunasea/types/indexer_icon.dart';
|
||||
import 'package:lunasea/types/list_view_option.dart';
|
||||
import 'package:lunasea/modules.dart';
|
||||
import 'package:lunasea/database/table.dart';
|
||||
import 'package:lunasea/system/profile.dart';
|
||||
import 'package:lunasea/types/log_type.dart';
|
||||
import 'package:lunasea/vendor.dart';
|
||||
import 'package:lunasea/widgets/ui.dart';
|
||||
|
||||
@@ -43,12 +41,9 @@ enum LunaSeaDatabase<T> with LunaTableMixin<T> {
|
||||
|
||||
@override
|
||||
void register() {
|
||||
// Deprecated
|
||||
Hive.registerAdapter(DeprecatedLunaBrowserAdapter());
|
||||
// Active
|
||||
Hive.registerAdapter(ExternalModuleHiveObjectAdapter());
|
||||
Hive.registerAdapter(IndexerHiveObjectAdapter());
|
||||
Hive.registerAdapter(ProfileHiveObjectAdapter());
|
||||
Hive.registerAdapter(LunaExternalModuleAdapter());
|
||||
Hive.registerAdapter(LunaIndexerAdapter());
|
||||
Hive.registerAdapter(LunaProfileAdapter());
|
||||
Hive.registerAdapter(LunaLogHiveObjectAdapter());
|
||||
Hive.registerAdapter(LunaIndexerIconAdapter());
|
||||
Hive.registerAdapter(LunaLogTypeAdapter());
|
||||
@@ -58,33 +53,41 @@ enum LunaSeaDatabase<T> with LunaTableMixin<T> {
|
||||
|
||||
@override
|
||||
dynamic export() {
|
||||
if (this == LunaSeaDatabase.DEFAULT_LAUNCH_MODULE) {
|
||||
return LunaSeaDatabase.DEFAULT_LAUNCH_MODULE.read().key;
|
||||
LunaSeaDatabase db = this;
|
||||
switch (db) {
|
||||
case LunaSeaDatabase.DEFAULT_LAUNCH_MODULE:
|
||||
return LunaSeaDatabase.DEFAULT_LAUNCH_MODULE.read().key;
|
||||
case LunaSeaDatabase.DRAWER_MANUAL_ORDER:
|
||||
return LunaDrawer.moduleOrderedList()
|
||||
.map<String>((module) => module.key)
|
||||
.toList();
|
||||
default:
|
||||
return super.export();
|
||||
}
|
||||
if (this == LunaSeaDatabase.DRAWER_MANUAL_ORDER) {
|
||||
return LunaDrawer.moduleOrderedList()
|
||||
.map<String>((module) => module.key)
|
||||
.toList();
|
||||
}
|
||||
return super.export();
|
||||
}
|
||||
|
||||
@override
|
||||
void import(dynamic value) {
|
||||
if (this == LunaSeaDatabase.DEFAULT_LAUNCH_MODULE) {
|
||||
final item = LunaModule.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
LunaSeaDatabase db = this;
|
||||
dynamic result;
|
||||
|
||||
switch (db) {
|
||||
case LunaSeaDatabase.DEFAULT_LAUNCH_MODULE:
|
||||
result = LunaModule.fromKey(value.toString());
|
||||
break;
|
||||
case LunaSeaDatabase.DRAWER_MANUAL_ORDER:
|
||||
List<LunaModule> item = [];
|
||||
(value as List).cast<String>().forEach((val) {
|
||||
LunaModule? module = LunaModule.fromKey(val);
|
||||
if (module != null) item.add(module);
|
||||
});
|
||||
result = item;
|
||||
break;
|
||||
default:
|
||||
result = value;
|
||||
break;
|
||||
}
|
||||
if (this == LunaSeaDatabase.DRAWER_MANUAL_ORDER) {
|
||||
List<LunaModule> item = [];
|
||||
(value as List).cast<String>().forEach((val) {
|
||||
LunaModule? module = LunaModule.fromKey(val);
|
||||
if (module != null) item.add(module);
|
||||
});
|
||||
update(item as T);
|
||||
return;
|
||||
}
|
||||
return super.import(value);
|
||||
|
||||
return super.import(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import 'package:lunasea/core/models/types/list_view_option.dart';
|
||||
import 'package:lunasea/types/list_view_option.dart';
|
||||
import 'package:lunasea/database/table.dart';
|
||||
import 'package:lunasea/modules/radarr/core/deprecated/availability.dart';
|
||||
import 'package:lunasea/modules/radarr/core/deprecated/qualityprofile.dart';
|
||||
import 'package:lunasea/modules/radarr/core/deprecated/rootfolder.dart';
|
||||
import 'package:lunasea/modules/radarr/core/types/filter_movies.dart';
|
||||
import 'package:lunasea/modules/radarr/core/types/filter_releases.dart';
|
||||
import 'package:lunasea/modules/radarr/core/types/sorting_movies.dart';
|
||||
@@ -39,11 +36,6 @@ enum RadarrDatabase<T> with LunaTableMixin<T> {
|
||||
|
||||
@override
|
||||
void register() {
|
||||
// Deprecated, not in use but necessary to avoid Hive read errors
|
||||
Hive.registerAdapter(DeprecatedRadarrQualityProfileAdapter());
|
||||
Hive.registerAdapter(DeprecatedRadarrRootFolderAdapter());
|
||||
Hive.registerAdapter(DeprecatedRadarrAvailabilityAdapter());
|
||||
// Active adapters
|
||||
Hive.registerAdapter(RadarrMoviesSortingAdapter());
|
||||
Hive.registerAdapter(RadarrMoviesFilterAdapter());
|
||||
Hive.registerAdapter(RadarrReleasesSortingAdapter());
|
||||
@@ -60,51 +52,49 @@ enum RadarrDatabase<T> with LunaTableMixin<T> {
|
||||
|
||||
@override
|
||||
dynamic export() {
|
||||
if (this == RadarrDatabase.DEFAULT_SORTING_MOVIES) {
|
||||
return RadarrDatabase.DEFAULT_SORTING_MOVIES.read().key;
|
||||
RadarrDatabase db = this;
|
||||
switch (db) {
|
||||
case RadarrDatabase.DEFAULT_SORTING_MOVIES:
|
||||
return RadarrDatabase.DEFAULT_SORTING_MOVIES.read().key;
|
||||
case RadarrDatabase.DEFAULT_SORTING_RELEASES:
|
||||
return RadarrDatabase.DEFAULT_SORTING_RELEASES.read().key;
|
||||
case RadarrDatabase.DEFAULT_FILTERING_MOVIES:
|
||||
return RadarrDatabase.DEFAULT_FILTERING_MOVIES.read().key;
|
||||
case RadarrDatabase.DEFAULT_FILTERING_RELEASES:
|
||||
return RadarrDatabase.DEFAULT_FILTERING_RELEASES.read().key;
|
||||
case RadarrDatabase.DEFAULT_VIEW_MOVIES:
|
||||
return RadarrDatabase.DEFAULT_VIEW_MOVIES.read().key;
|
||||
default:
|
||||
return super.export();
|
||||
}
|
||||
if (this == RadarrDatabase.DEFAULT_SORTING_RELEASES) {
|
||||
return RadarrDatabase.DEFAULT_SORTING_RELEASES.read().key;
|
||||
}
|
||||
if (this == RadarrDatabase.DEFAULT_FILTERING_MOVIES) {
|
||||
return RadarrDatabase.DEFAULT_FILTERING_MOVIES.read().key;
|
||||
}
|
||||
if (this == RadarrDatabase.DEFAULT_FILTERING_RELEASES) {
|
||||
return RadarrDatabase.DEFAULT_FILTERING_RELEASES.read().key;
|
||||
}
|
||||
if (this == RadarrDatabase.DEFAULT_VIEW_MOVIES) {
|
||||
return RadarrDatabase.DEFAULT_VIEW_MOVIES.read().key;
|
||||
}
|
||||
return super.export();
|
||||
}
|
||||
|
||||
@override
|
||||
void import(dynamic value) {
|
||||
if (this == RadarrDatabase.DEFAULT_SORTING_MOVIES) {
|
||||
final item = RadarrMoviesSorting.ALPHABETICAL.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
RadarrDatabase db = this;
|
||||
dynamic result;
|
||||
|
||||
switch (db) {
|
||||
case RadarrDatabase.DEFAULT_SORTING_MOVIES:
|
||||
result = RadarrMoviesSorting.ALPHABETICAL.fromKey(value.toString());
|
||||
break;
|
||||
case RadarrDatabase.DEFAULT_SORTING_RELEASES:
|
||||
result = RadarrReleasesSorting.ALPHABETICAL.fromKey(value.toString());
|
||||
break;
|
||||
case RadarrDatabase.DEFAULT_FILTERING_MOVIES:
|
||||
result = RadarrMoviesFilter.ALL.fromKey(value.toString());
|
||||
break;
|
||||
case RadarrDatabase.DEFAULT_FILTERING_RELEASES:
|
||||
result = RadarrReleasesFilter.ALL.fromKey(value.toString());
|
||||
break;
|
||||
case RadarrDatabase.DEFAULT_VIEW_MOVIES:
|
||||
result = LunaListViewOption.fromKey(value.toString());
|
||||
break;
|
||||
default:
|
||||
result = value;
|
||||
break;
|
||||
}
|
||||
if (this == RadarrDatabase.DEFAULT_SORTING_RELEASES) {
|
||||
final item = RadarrReleasesSorting.ALPHABETICAL.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
}
|
||||
if (this == RadarrDatabase.DEFAULT_FILTERING_MOVIES) {
|
||||
final item = RadarrMoviesFilter.ALL.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
}
|
||||
if (this == RadarrDatabase.DEFAULT_FILTERING_RELEASES) {
|
||||
final item = RadarrReleasesFilter.ALL.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
}
|
||||
if (this == RadarrDatabase.DEFAULT_VIEW_MOVIES) {
|
||||
final item = LunaListViewOption.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
}
|
||||
return super.import(value);
|
||||
|
||||
return super.import(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:lunasea/core/models/types/list_view_option.dart';
|
||||
import 'package:lunasea/types/list_view_option.dart';
|
||||
import 'package:lunasea/database/table.dart';
|
||||
import 'package:lunasea/modules/sonarr/core/deprecated.dart';
|
||||
import 'package:lunasea/modules/sonarr/core/types/filter_releases.dart';
|
||||
import 'package:lunasea/modules/sonarr/core/types/filter_series.dart';
|
||||
import 'package:lunasea/modules/sonarr/core/types/monitor_status.dart';
|
||||
@@ -48,65 +47,58 @@ enum SonarrDatabase<T> with LunaTableMixin<T> {
|
||||
|
||||
@override
|
||||
void register() {
|
||||
// Deprecated, not in use but necessary to avoid Hive read errors
|
||||
Hive.registerAdapter(DeprecatedSonarrQualityProfileAdapter());
|
||||
Hive.registerAdapter(DeprecatedSonarrRootFolderAdapter());
|
||||
Hive.registerAdapter(DeprecatedSonarrSeriesTypeAdapter());
|
||||
// Active adapters
|
||||
Hive.registerAdapter(SonarrMonitorStatusAdapter());
|
||||
Hive.registerAdapter(SonarrSeriesSortingAdapter());
|
||||
Hive.registerAdapter(SonarrSeriesFilterAdapter());
|
||||
Hive.registerAdapter(SonarrReleasesSortingAdapter());
|
||||
Hive.registerAdapter(SonarrReleasesFilterAdapter());
|
||||
Hive.registerAdapter(SonarrMonitorStatusAdapter());
|
||||
Hive.registerAdapter(SonarrSeriesSortingAdapter());
|
||||
Hive.registerAdapter(SonarrSeriesFilterAdapter());
|
||||
Hive.registerAdapter(SonarrReleasesSortingAdapter());
|
||||
Hive.registerAdapter(SonarrReleasesFilterAdapter());
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic export() {
|
||||
if (this == SonarrDatabase.DEFAULT_SORTING_SERIES) {
|
||||
return SonarrDatabase.DEFAULT_SORTING_SERIES.read().key;
|
||||
SonarrDatabase db = this;
|
||||
switch (db) {
|
||||
case SonarrDatabase.DEFAULT_SORTING_SERIES:
|
||||
return SonarrDatabase.DEFAULT_SORTING_SERIES.read().key;
|
||||
case SonarrDatabase.DEFAULT_SORTING_RELEASES:
|
||||
return SonarrDatabase.DEFAULT_SORTING_RELEASES.read().key;
|
||||
case SonarrDatabase.DEFAULT_FILTERING_SERIES:
|
||||
return SonarrDatabase.DEFAULT_FILTERING_SERIES.read().key;
|
||||
case SonarrDatabase.DEFAULT_FILTERING_RELEASES:
|
||||
return SonarrDatabase.DEFAULT_FILTERING_RELEASES.read().key;
|
||||
case SonarrDatabase.DEFAULT_VIEW_SERIES:
|
||||
return SonarrDatabase.DEFAULT_VIEW_SERIES.read().key;
|
||||
default:
|
||||
return super.export();
|
||||
}
|
||||
if (this == SonarrDatabase.DEFAULT_SORTING_RELEASES) {
|
||||
return SonarrDatabase.DEFAULT_SORTING_RELEASES.read().key;
|
||||
}
|
||||
if (this == SonarrDatabase.DEFAULT_FILTERING_SERIES) {
|
||||
return SonarrDatabase.DEFAULT_FILTERING_SERIES.read().key;
|
||||
}
|
||||
if (this == SonarrDatabase.DEFAULT_FILTERING_RELEASES) {
|
||||
return SonarrDatabase.DEFAULT_FILTERING_RELEASES.read().key;
|
||||
}
|
||||
if (this == SonarrDatabase.DEFAULT_VIEW_SERIES) {
|
||||
return SonarrDatabase.DEFAULT_VIEW_SERIES.read().key;
|
||||
}
|
||||
return super.export();
|
||||
}
|
||||
|
||||
@override
|
||||
void import(dynamic value) {
|
||||
if (this == SonarrDatabase.DEFAULT_SORTING_SERIES) {
|
||||
final item = SonarrSeriesSorting.ALPHABETICAL.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
SonarrDatabase db = this;
|
||||
dynamic result;
|
||||
|
||||
switch (db) {
|
||||
case SonarrDatabase.DEFAULT_SORTING_SERIES:
|
||||
result = SonarrSeriesSorting.ALPHABETICAL.fromKey(value.toString());
|
||||
break;
|
||||
case SonarrDatabase.DEFAULT_SORTING_RELEASES:
|
||||
result = SonarrReleasesSorting.ALPHABETICAL.fromKey(value.toString());
|
||||
break;
|
||||
case SonarrDatabase.DEFAULT_FILTERING_SERIES:
|
||||
result = SonarrSeriesFilter.ALL.fromKey(value.toString());
|
||||
break;
|
||||
case SonarrDatabase.DEFAULT_FILTERING_RELEASES:
|
||||
result = SonarrReleasesFilter.ALL.fromKey(value.toString());
|
||||
break;
|
||||
case SonarrDatabase.DEFAULT_VIEW_SERIES:
|
||||
result = LunaListViewOption.fromKey(value.toString());
|
||||
break;
|
||||
default:
|
||||
result = value;
|
||||
break;
|
||||
}
|
||||
if (this == SonarrDatabase.DEFAULT_SORTING_RELEASES) {
|
||||
final item = SonarrReleasesSorting.ALPHABETICAL.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
}
|
||||
if (this == SonarrDatabase.DEFAULT_FILTERING_SERIES) {
|
||||
final item = SonarrSeriesFilter.ALL.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
}
|
||||
if (this == SonarrDatabase.DEFAULT_FILTERING_RELEASES) {
|
||||
final item = SonarrReleasesFilter.ALL.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
}
|
||||
if (this == SonarrDatabase.DEFAULT_VIEW_SERIES) {
|
||||
final item = LunaListViewOption.fromKey(value.toString());
|
||||
if (item != null) update(item as T);
|
||||
return;
|
||||
}
|
||||
return super.import(value);
|
||||
|
||||
return super.import(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/string.dart';
|
||||
import 'package:lunasea/extensions/string/string.dart';
|
||||
|
||||
extension DateTimeExtension on DateTime {
|
||||
/// Get the floor of a date.
|
||||
///
|
||||
/// The floor is a new [DateTime] object with only the year, month, and day copied from the original source.
|
||||
DateTime get lunaFloor => DateTime(this.year, this.month, this.day);
|
||||
|
||||
/// Returns a string representation of the "age" of the [DateTime] object.
|
||||
///
|
||||
/// Compares to [DateTime.now().toLocal()] to calculate the age.
|
||||
@@ -27,7 +27,7 @@ abstract class LunaPageRouter {
|
||||
/// - Calls [FluroRouter.define] with the [fullRoute]
|
||||
/// - Creates a basic [Handler]
|
||||
/// - Sets the transition type to [LunaRouter.transitionType]
|
||||
/// - Checks that the module is enabled, and if not returns a `[LunaNotEnabledRoute] instead of the intended route
|
||||
/// - Checks that the module is enabled, and if not returns a `[NotEnabledPage] instead of the intended route
|
||||
void noParameterRouteDefinition(
|
||||
FluroRouter router, {
|
||||
bool homeRoute = false,
|
||||
@@ -39,7 +39,7 @@ abstract class LunaPageRouter {
|
||||
/// - Calls [FluroRouter.define] with the [fullRoute]
|
||||
/// - Creates a basic [Handler]
|
||||
/// - Sets the transition type to [LunaRouter.transitionType]
|
||||
/// - Checks that the module is enabled, and if not returns a `[LunaNotEnabledRoute] instead of the intended route
|
||||
/// - Checks that the module is enabled, and if not returns a `[NotEnabledPage] instead of the intended route
|
||||
/// - Parses and injects the required parameters into the route for the handler
|
||||
void withParameterRouteDefinition(
|
||||
FluroRouter router,
|
||||
@@ -15,6 +15,7 @@ import 'package:lunasea/modules/nzbget.dart';
|
||||
import 'package:lunasea/modules/tautulli.dart';
|
||||
|
||||
import 'package:lunasea/modules/dashboard/routes/routes.dart' as dashboard;
|
||||
import 'package:lunasea/widgets/pages/invalid_route.dart';
|
||||
|
||||
class LunaRouter {
|
||||
static FluroRouter router = FluroRouter();
|
||||
@@ -23,7 +24,7 @@ class LunaRouter {
|
||||
/// Calls `defineAllRoutes()` on all module routers that implement [LunaModuleRouter].
|
||||
void initialize() {
|
||||
router.notFoundHandler = Handler(
|
||||
handlerFunc: (context, params) => LunaInvalidRoute(),
|
||||
handlerFunc: (context, params) => const InvalidRoutePage(),
|
||||
);
|
||||
router.define(
|
||||
'/',
|
||||
@@ -13,6 +13,7 @@ import 'package:lunasea/modules/tautulli/core/state.dart';
|
||||
import 'package:lunasea/modules.dart';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart' show ProviderScope;
|
||||
|
||||
class LunaState {
|
||||
LunaState._();
|
||||
@@ -22,15 +23,14 @@ class LunaState {
|
||||
GlobalKey<NavigatorState>();
|
||||
|
||||
/// Calls `.reset()` on all states which extend [LunaModuleState].
|
||||
static void reset([BuildContext? ctx]) {
|
||||
final context = ctx ?? navigatorKey.currentContext!;
|
||||
LunaModule.values.forEach((module) => module.state(context)?.reset());
|
||||
static void reset([BuildContext? context]) {
|
||||
final ctx = context ?? navigatorKey.currentContext!;
|
||||
LunaModule.values.forEach((module) => module.state(ctx)?.reset());
|
||||
}
|
||||
|
||||
/// Returns a [MultiProvider] with the provided child.
|
||||
///
|
||||
/// The [MultiProvider] has a [ChangeNotifierProvider] provider added for each module global state object.
|
||||
static MultiProvider providers({required Widget child}) => MultiProvider(
|
||||
static ProviderScope providers({required Widget child}) {
|
||||
return ProviderScope(
|
||||
child: MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (_) => dashboard.ModuleState()),
|
||||
ChangeNotifierProvider(create: (_) => SettingsState()),
|
||||
@@ -44,5 +44,7 @@ class LunaState {
|
||||
ChangeNotifierProvider(create: (_) => TautulliState()),
|
||||
],
|
||||
child: child,
|
||||
);
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
5
lib/extensions/datetime.dart
Normal file
5
lib/extensions/datetime.dart
Normal file
@@ -0,0 +1,5 @@
|
||||
extension DateTimeExtension on DateTime {
|
||||
DateTime floor() {
|
||||
return DateTime(this.year, this.month, this.day);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
extension DoubleExtension on double? {
|
||||
String get asTimeAgo {
|
||||
extension DoubleAsTimeExtension on double? {
|
||||
String asTimeAgo() {
|
||||
if (this == null || this! < 0) return LunaUI.TEXT_EMDASH;
|
||||
|
||||
double hours = this!;
|
||||
51
lib/extensions/duration/timestamp.dart
Normal file
51
lib/extensions/duration/timestamp.dart
Normal file
@@ -0,0 +1,51 @@
|
||||
import 'package:lunasea/widgets/ui.dart';
|
||||
|
||||
extension DurationAsTimestampExtension on Duration? {
|
||||
String asNumberTimestamp() {
|
||||
if (this == null) return LunaUI.TEXT_EMDASH;
|
||||
|
||||
final hours = this!.inHours.toString().padLeft(2, '0');
|
||||
final minutes = (this!.inMinutes % 60).toString().padLeft(2, '0');
|
||||
final seconds = (this!.inSeconds % 60).toString().padLeft(2, '0');
|
||||
|
||||
if (hours == '00') return '$minutes:$seconds';
|
||||
return '$hours:$minutes:$seconds';
|
||||
}
|
||||
|
||||
String asWordsTimestamp({
|
||||
int multiplier = 1,
|
||||
int divisor = 1,
|
||||
}) {
|
||||
if (this == null) return 'lunasea.Unknown'.tr();
|
||||
final List<String> words = [];
|
||||
|
||||
final days = this!.inDays;
|
||||
if (days > 0) {
|
||||
if (days == 1) {
|
||||
words.add('lunasea.OneDay'.tr());
|
||||
} else {
|
||||
words.add('lunasea.Days'.tr(args: [days.toString()]));
|
||||
}
|
||||
}
|
||||
|
||||
final hours = this!.inHours % 24;
|
||||
if (hours > 0) {
|
||||
if (hours == 1) {
|
||||
words.add('lunasea.OneHour'.tr());
|
||||
} else {
|
||||
words.add('lunasea.Hours'.tr(args: [hours.toString()]));
|
||||
}
|
||||
}
|
||||
|
||||
final minutes = this!.inMinutes % 60;
|
||||
if (minutes > 0) {
|
||||
if (minutes == 1) {
|
||||
words.add('lunasea.OneMinute'.tr());
|
||||
} else {
|
||||
words.add('lunasea.Minutes'.tr(args: [minutes.toString()]));
|
||||
}
|
||||
}
|
||||
|
||||
return words.isEmpty ? 'lunasea.UnderAMinute'.tr() : words.join(' ');
|
||||
}
|
||||
}
|
||||
45
lib/extensions/int/bytes.dart
Normal file
45
lib/extensions/int/bytes.dart
Normal file
@@ -0,0 +1,45 @@
|
||||
extension IntegerAsBytesExtension on int? {
|
||||
static const _BIT_CHUNK = 1000;
|
||||
static const _BIT_SIZES = ['b', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb', 'Eb'];
|
||||
|
||||
static const _BYTE_CHUNK = 1024;
|
||||
static const _BYTE_SIZES = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'];
|
||||
|
||||
String _toBits(int decimals, int position) {
|
||||
if (this == null || this! <= 0) return '${0.toStringAsFixed(decimals)} B';
|
||||
|
||||
int idx = position;
|
||||
double size = this!.toDouble();
|
||||
|
||||
while (size > _BIT_CHUNK) {
|
||||
size /= _BIT_CHUNK;
|
||||
idx++;
|
||||
}
|
||||
|
||||
return '${size.toStringAsFixed(decimals)} ${_BIT_SIZES[idx]}';
|
||||
}
|
||||
|
||||
String _toBytes(int decimals, int position) {
|
||||
if (this == null || this! <= 0) return '${0.toStringAsFixed(decimals)} B';
|
||||
|
||||
int idx = position;
|
||||
double size = this!.toDouble();
|
||||
|
||||
while (size > _BYTE_CHUNK) {
|
||||
size /= _BYTE_CHUNK;
|
||||
idx++;
|
||||
}
|
||||
|
||||
return '${size.toStringAsFixed(decimals)} ${_BYTE_SIZES[idx]}';
|
||||
}
|
||||
|
||||
String asBits({int decimals = 2}) => _toBits(decimals, 0);
|
||||
String asKilobits({int decimals = 2}) => _toBits(decimals, 1);
|
||||
String asMegabits({int decimals = 2}) => _toBits(decimals, 2);
|
||||
String asGigabits({int decimals = 2}) => _toBits(decimals, 3);
|
||||
|
||||
String asBytes({int decimals = 2}) => _toBytes(decimals, 0);
|
||||
String asKilobytes({int decimals = 2}) => _toBytes(decimals, 1);
|
||||
String asMegabytes({int decimals = 2}) => _toBytes(decimals, 2);
|
||||
String asGigabytes({int decimals = 2}) => _toBytes(decimals, 3);
|
||||
}
|
||||
72
lib/extensions/int/duration.dart
Normal file
72
lib/extensions/int/duration.dart
Normal file
@@ -0,0 +1,72 @@
|
||||
import 'package:lunasea/vendor.dart';
|
||||
|
||||
extension IntegerAsDurationExtension on int? {
|
||||
static const int _MINUTE_IN_SECONDS = 60;
|
||||
static const int _HOUR_IN_SECONDS = _MINUTE_IN_SECONDS * 60;
|
||||
static const int _DAY_IN_SECONDS = _HOUR_IN_SECONDS * 24;
|
||||
|
||||
String asWordDuration({
|
||||
int multiplier = 1,
|
||||
int divisor = 1,
|
||||
}) {
|
||||
if (this == null || this! <= 0) return 'lunasea.Unknown'.tr();
|
||||
final seconds = ((this! * multiplier) / divisor).floor();
|
||||
|
||||
final days = seconds ~/ _DAY_IN_SECONDS;
|
||||
if (days > 1) {
|
||||
return 'lunasea.Days'.tr(args: [days.toString()]);
|
||||
}
|
||||
|
||||
final hours = seconds ~/ _HOUR_IN_SECONDS;
|
||||
if (hours > 1) {
|
||||
return 'lunasea.Hours'.tr(args: [hours.toString()]);
|
||||
}
|
||||
|
||||
final minutes = seconds ~/ _MINUTE_IN_SECONDS;
|
||||
if (minutes > 0) {
|
||||
return 'lunasea.Minutes'.tr(args: [minutes.toString()]);
|
||||
}
|
||||
|
||||
return 'lunasea.Seconds'.tr(args: [seconds.toString()]);
|
||||
}
|
||||
|
||||
String asVideoDuration({
|
||||
int multiplier = 1,
|
||||
int divisor = 1,
|
||||
}) {
|
||||
if (this == null || this! <= 0) return 'lunasea.Unknown'.tr();
|
||||
|
||||
final minutes = ((this! * multiplier) / divisor).floor();
|
||||
final hours = (minutes ~/ 60);
|
||||
final remainder = (minutes - (60 * hours));
|
||||
|
||||
if (minutes < 60) return '${minutes}m';
|
||||
return '${hours}h ${remainder}m';
|
||||
}
|
||||
|
||||
String asTrackDuration({
|
||||
int multiplier = 1,
|
||||
int divisor = 1,
|
||||
}) {
|
||||
if (this == null || this! <= 0) return '00:00';
|
||||
|
||||
int duration = ((this! * multiplier) / divisor).floor();
|
||||
int hourCounter = 0, minuteCounter = 0;
|
||||
|
||||
while (duration >= _HOUR_IN_SECONDS) {
|
||||
duration -= _HOUR_IN_SECONDS;
|
||||
hourCounter++;
|
||||
}
|
||||
while (duration >= _MINUTE_IN_SECONDS) {
|
||||
duration -= _MINUTE_IN_SECONDS;
|
||||
minuteCounter++;
|
||||
}
|
||||
|
||||
final hours = hourCounter.toString().padLeft(1, '0');
|
||||
final minutes = minuteCounter.toString().padLeft(2, '0');
|
||||
final seconds = duration.toString().padLeft(2, '0');
|
||||
|
||||
if (hourCounter > 0) return '$hours:$minutes:$seconds';
|
||||
return '$minutes:$seconds';
|
||||
}
|
||||
}
|
||||
11
lib/extensions/navigator_state.dart
Normal file
11
lib/extensions/navigator_state.dart
Normal file
@@ -0,0 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
extension NavigatorStateExtension on NavigatorState {
|
||||
void safetyPop() {
|
||||
if (this.canPop()) this.pop();
|
||||
}
|
||||
|
||||
void popToRootRoute() {
|
||||
this.popUntil((route) => route.isFirst);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
extension PageControllerExtension on PageController {
|
||||
/// Jump a [PageView] to the given index.
|
||||
Future<void> lunaJumpToPage(int index) async {
|
||||
Future<void> protectedJumpToPage(int index) async {
|
||||
if (this.hasClients) this.jumpToPage(index);
|
||||
}
|
||||
}
|
||||
17
lib/extensions/scroll_controller.dart
Normal file
17
lib/extensions/scroll_controller.dart
Normal file
@@ -0,0 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
extension ScrollControllerExtension on ScrollController {
|
||||
static const _duration =
|
||||
Duration(milliseconds: LunaUI.ANIMATION_SPEED_SCROLLING);
|
||||
|
||||
Future<void> animateToStart() async {
|
||||
if (this.hasClients) {
|
||||
this.animateTo(
|
||||
0.00,
|
||||
duration: _duration,
|
||||
curve: Curves.easeInOutQuart,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,4 +56,12 @@ extension StringExtension on String {
|
||||
.padLeft((this.length + count), padding)
|
||||
.padRight((this.length + (count * 2)), padding);
|
||||
}
|
||||
|
||||
/// Returns the string with a bullet appended to the front.
|
||||
String bulleted({
|
||||
String bullet = LunaUI.TEXT_BULLET,
|
||||
int padCount = 1,
|
||||
}) {
|
||||
return '${bullet.pad(count: padCount)}$this';
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/utils/profile_tools.dart';
|
||||
import 'package:lunasea/firebase/core.dart';
|
||||
import 'package:lunasea/system/platform.dart';
|
||||
|
||||
@@ -115,8 +116,6 @@ class LunaFirebaseMessaging {
|
||||
LunaModule? module = LunaModule.fromKey(message.data['module']);
|
||||
if (module == null) {
|
||||
LunaLogger().warning(
|
||||
'LunaFirebaseMessaging',
|
||||
'_handleWebhook',
|
||||
'Unknown module found inside of RemoteMessage: ${message.data['module'] ?? 'null'}',
|
||||
);
|
||||
return;
|
||||
@@ -124,13 +123,11 @@ class LunaFirebaseMessaging {
|
||||
String profile = message.data['profile'] ?? '';
|
||||
if (profile.isEmpty) {
|
||||
LunaLogger().warning(
|
||||
'LunaFirebaseMessaging',
|
||||
'_handleWebhook',
|
||||
'Invalid profile received in webhook: ${message.data['profile'] ?? 'null'}',
|
||||
);
|
||||
return;
|
||||
}
|
||||
bool result = LunaProfile().changeTo(profile, popToRoot: true);
|
||||
bool result = LunaProfileTools().changeTo(profile, popToRootRoute: true);
|
||||
if (result) {
|
||||
module.handleWebhook(message.data);
|
||||
} else {
|
||||
|
||||
@@ -4,19 +4,22 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/core/cache/image_cache/image_cache.dart';
|
||||
import 'package:lunasea/database/database.dart';
|
||||
import 'package:lunasea/firebase/core.dart';
|
||||
import 'package:lunasea/firebase/firestore.dart';
|
||||
import 'package:lunasea/firebase/messaging.dart';
|
||||
import 'package:lunasea/modules/dashboard/routes/dashboard/route.dart'
|
||||
show HomeRouter;
|
||||
import 'package:lunasea/system/build.dart';
|
||||
import 'package:lunasea/system/cache/image/image_cache.dart';
|
||||
import 'package:lunasea/system/flavor.dart';
|
||||
import 'package:lunasea/system/in_app_purchase/in_app_purchase.dart';
|
||||
import 'package:lunasea/system/localization.dart';
|
||||
import 'package:lunasea/system/network/network.dart';
|
||||
import 'package:lunasea/system/quick_actions/quick_actions.dart';
|
||||
import 'package:lunasea/system/window_manager/window_manager.dart';
|
||||
import 'package:lunasea/system/platform.dart';
|
||||
import 'package:lunasea/widgets/changelog/sheet.dart';
|
||||
|
||||
/// LunaSea Entry Point: Initialize & Run Application
|
||||
///
|
||||
@@ -53,7 +56,7 @@ class LunaBIOS extends StatelessWidget {
|
||||
LunaTheme theme = LunaTheme();
|
||||
LunaRouter router = LunaRouter();
|
||||
|
||||
return ProviderScope(
|
||||
return LunaState.providers(
|
||||
child: DevicePreview(
|
||||
enabled: kDebugMode && LunaPlatform.isDesktop,
|
||||
builder: (context) => EasyLocalization(
|
||||
@@ -62,29 +65,27 @@ class LunaBIOS extends StatelessWidget {
|
||||
fallbackLocale: LunaLocalization.fallbackLocale,
|
||||
startLocale: LunaLocalization.fallbackLocale,
|
||||
useFallbackTranslations: true,
|
||||
child: LunaState.providers(
|
||||
child: LunaBox.lunasea.watch(
|
||||
selectItems: [
|
||||
LunaSeaDatabase.THEME_AMOLED,
|
||||
LunaSeaDatabase.THEME_AMOLED_BORDER,
|
||||
],
|
||||
builder: (context, _) {
|
||||
return MaterialApp(
|
||||
localizationsDelegates: context.localizationDelegates,
|
||||
supportedLocales: context.supportedLocales,
|
||||
locale: context.locale,
|
||||
builder: DevicePreview.appBuilder,
|
||||
routes: router.routes,
|
||||
useInheritedMediaQuery: true,
|
||||
onGenerateRoute: LunaRouter.router.generator,
|
||||
navigatorKey: LunaState.navigatorKey,
|
||||
darkTheme: theme.activeTheme(),
|
||||
theme: theme.activeTheme(),
|
||||
scrollBehavior: LunaScrollBehavior(),
|
||||
title: 'LunaSea',
|
||||
);
|
||||
},
|
||||
),
|
||||
child: LunaBox.lunasea.watch(
|
||||
selectItems: [
|
||||
LunaSeaDatabase.THEME_AMOLED,
|
||||
LunaSeaDatabase.THEME_AMOLED_BORDER,
|
||||
],
|
||||
builder: (context, _) {
|
||||
return MaterialApp(
|
||||
localizationsDelegates: context.localizationDelegates,
|
||||
supportedLocales: context.supportedLocales,
|
||||
locale: context.locale,
|
||||
builder: DevicePreview.appBuilder,
|
||||
routes: router.routes,
|
||||
useInheritedMediaQuery: true,
|
||||
onGenerateRoute: LunaRouter.router.generator,
|
||||
navigatorKey: LunaState.navigatorKey,
|
||||
darkTheme: theme.activeTheme(),
|
||||
theme: theme.activeTheme(),
|
||||
scrollBehavior: LunaScrollBehavior(),
|
||||
title: 'LunaSea',
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -93,9 +94,7 @@ class LunaBIOS extends StatelessWidget {
|
||||
}
|
||||
|
||||
class LunaOS extends StatefulWidget {
|
||||
const LunaOS({
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
const LunaOS({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _State();
|
||||
@@ -105,7 +104,10 @@ class _State extends State<LunaOS> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) => _boot());
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
_boot();
|
||||
_healthCheck();
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _initNotifications() async {
|
||||
@@ -119,6 +121,14 @@ class _State extends State<LunaOS> {
|
||||
messaging.registerOnMessageOpenedAppListener();
|
||||
}
|
||||
|
||||
Future<void> _healthCheck() async {
|
||||
if (LunaFlavor.isStable) {
|
||||
LunaBuild().isLatestBuildVersion().then((isLatest) {
|
||||
if (!isLatest.item1) ChangelogSheet().show();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _boot() async {
|
||||
if (LunaFirebaseMessaging.isSupported) _initNotifications();
|
||||
|
||||
@@ -127,10 +137,6 @@ class _State extends State<LunaOS> {
|
||||
Intl.defaultLocale = tag;
|
||||
|
||||
if (LunaQuickActions.isSupported) LunaQuickActions().initialize();
|
||||
LunaChangelogSheet().show(
|
||||
context: LunaState.navigatorKey.currentContext!,
|
||||
checkBuildVersion: true,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/extensions/string_links.dart';
|
||||
import 'package:lunasea/extensions/string/links.dart';
|
||||
import 'package:quick_actions/quick_actions.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
|
||||
@@ -124,23 +124,23 @@ extension LunaModuleEnablementExtension on LunaModule {
|
||||
case LunaModule.SETTINGS:
|
||||
return true;
|
||||
case LunaModule.LIDARR:
|
||||
return LunaProfile.current.lidarrEnabled ?? false;
|
||||
return LunaProfile.current.lidarrEnabled;
|
||||
case LunaModule.NZBGET:
|
||||
return LunaProfile.current.nzbgetEnabled ?? false;
|
||||
return LunaProfile.current.nzbgetEnabled;
|
||||
case LunaModule.OVERSEERR:
|
||||
return LunaProfile.current.overseerrEnabled ?? false;
|
||||
return LunaProfile.current.overseerrEnabled;
|
||||
case LunaModule.RADARR:
|
||||
return LunaProfile.current.radarrEnabled ?? false;
|
||||
return LunaProfile.current.radarrEnabled;
|
||||
case LunaModule.SABNZBD:
|
||||
return LunaProfile.current.sabnzbdEnabled ?? false;
|
||||
return LunaProfile.current.sabnzbdEnabled;
|
||||
case LunaModule.SEARCH:
|
||||
return !LunaBox.indexers.isEmpty;
|
||||
case LunaModule.SONARR:
|
||||
return LunaProfile.current.sonarrEnabled ?? false;
|
||||
return LunaProfile.current.sonarrEnabled;
|
||||
case LunaModule.TAUTULLI:
|
||||
return LunaProfile.current.tautulliEnabled ?? false;
|
||||
return LunaProfile.current.tautulliEnabled;
|
||||
case LunaModule.WAKE_ON_LAN:
|
||||
return LunaProfile.current.wakeOnLANEnabled ?? false;
|
||||
return LunaProfile.current.wakeOnLANEnabled;
|
||||
case LunaModule.EXTERNAL_MODULES:
|
||||
return !LunaBox.externalModules.isEmpty;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:lunasea/core/extensions/datetime.dart';
|
||||
import 'package:lunasea/core/models/configuration/profile.dart';
|
||||
import 'package:lunasea/database/models/profile.dart';
|
||||
import 'package:lunasea/database/tables/dashboard.dart';
|
||||
import 'package:lunasea/extensions/datetime.dart';
|
||||
import 'package:lunasea/modules/dashboard/core/api/data/abstract.dart';
|
||||
import 'package:lunasea/modules/dashboard/core/api/data/lidarr.dart';
|
||||
import 'package:lunasea/modules/dashboard/core/api/data/radarr.dart';
|
||||
@@ -19,7 +19,7 @@ class API {
|
||||
required this.sonarr,
|
||||
});
|
||||
|
||||
factory API.from(ProfileHiveObject? profile) {
|
||||
factory API.from(LunaProfile? profile) {
|
||||
return API._internal(
|
||||
lidarr: profile?.getLidarr(),
|
||||
radarr: profile?.getRadarr(),
|
||||
@@ -61,7 +61,7 @@ class API {
|
||||
if (response.data.length > 0) {
|
||||
for (var entry in response.data) {
|
||||
DateTime? date =
|
||||
DateTime.tryParse(entry['releaseDate'] ?? '')?.toLocal().lunaFloor;
|
||||
DateTime.tryParse(entry['releaseDate'] ?? '')?.toLocal().floor();
|
||||
if (date != null && _isDateWithinBounds(date, today)) {
|
||||
List<CalendarData> day = map[date] ?? [];
|
||||
day.add(CalendarLidarrData(
|
||||
@@ -108,11 +108,9 @@ class API {
|
||||
DateTime? physicalRelease =
|
||||
DateTime.tryParse(entry['physicalRelease'] ?? '')
|
||||
?.toLocal()
|
||||
.lunaFloor;
|
||||
.floor();
|
||||
DateTime? digitalRelease =
|
||||
DateTime.tryParse(entry['digitalRelease'] ?? '')
|
||||
?.toLocal()
|
||||
.lunaFloor;
|
||||
DateTime.tryParse(entry['digitalRelease'] ?? '')?.toLocal().floor();
|
||||
DateTime? release;
|
||||
if (physicalRelease != null || digitalRelease != null) {
|
||||
if (physicalRelease == null) release = digitalRelease;
|
||||
@@ -166,7 +164,7 @@ class API {
|
||||
if (response.data.length > 0) {
|
||||
for (var entry in response.data) {
|
||||
DateTime? date =
|
||||
DateTime.tryParse(entry['airDateUtc'] ?? '')?.toLocal().lunaFloor;
|
||||
DateTime.tryParse(entry['airDateUtc'] ?? '')?.toLocal().floor();
|
||||
if (date != null && _isDateWithinBounds(date, today)) {
|
||||
List<CalendarData> day = map[date] ?? [];
|
||||
day.add(CalendarSonarrData(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/system/profile.dart';
|
||||
import 'package:lunasea/database/models/profile.dart';
|
||||
import 'package:lunasea/widgets/ui.dart';
|
||||
import 'package:lunasea/modules/lidarr/core/api/api.dart';
|
||||
import 'package:lunasea/modules/lidarr/routes/details_artist.dart';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core/extensions/int.dart';
|
||||
import 'package:lunasea/extensions/string.dart';
|
||||
import 'package:lunasea/system/profile.dart';
|
||||
import 'package:lunasea/database/models/profile.dart';
|
||||
import 'package:lunasea/extensions/int/duration.dart';
|
||||
import 'package:lunasea/extensions/string/string.dart';
|
||||
import 'package:lunasea/vendor.dart';
|
||||
import 'package:lunasea/widgets/ui.dart';
|
||||
import 'package:lunasea/modules/radarr/core/api_helper.dart';
|
||||
@@ -37,7 +37,7 @@ class CalendarRadarrData extends CalendarData {
|
||||
children: [
|
||||
TextSpan(text: year.toString()),
|
||||
TextSpan(text: LunaUI.TEXT_BULLET.pad()),
|
||||
TextSpan(text: runtime.lunaRuntime()),
|
||||
TextSpan(text: runtime.asVideoDuration()),
|
||||
],
|
||||
),
|
||||
TextSpan(text: studio),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/database/models/profile.dart';
|
||||
import 'package:lunasea/database/tables/lunasea.dart';
|
||||
import 'package:lunasea/extensions/string.dart';
|
||||
import 'package:lunasea/extensions/string/string.dart';
|
||||
|
||||
import 'package:lunasea/system/profile.dart';
|
||||
import 'package:lunasea/system/logger.dart';
|
||||
import 'package:lunasea/widgets/ui.dart';
|
||||
import 'package:lunasea/vendor.dart';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:lunasea/core/models/configuration/profile.dart';
|
||||
import 'package:lunasea/core/state/module_state.dart';
|
||||
import 'package:lunasea/system/profile.dart';
|
||||
import 'package:lunasea/database/models/profile.dart';
|
||||
import 'package:lunasea/deprecated/state/module_state.dart';
|
||||
import 'package:lunasea/database/tables/dashboard.dart';
|
||||
import 'package:lunasea/modules/dashboard/core/adapters/calendar_starting_type.dart';
|
||||
import 'package:lunasea/modules/dashboard/core/api/api.dart';
|
||||
@@ -29,7 +28,7 @@ class ModuleState extends LunaModuleState {
|
||||
API? _api;
|
||||
API? get api => _api;
|
||||
void resetAPI() {
|
||||
ProfileHiveObject? _profile = LunaProfile.current;
|
||||
LunaProfile? _profile = LunaProfile.current;
|
||||
_api = API.from(_profile);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core/extensions/async_snapshot.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:lunasea/widgets/ui.dart';
|
||||
@@ -53,7 +52,8 @@ class _State extends State<CalendarPage>
|
||||
return LunaMessage.error(onTap: _refreshKey.currentState!.show);
|
||||
}
|
||||
|
||||
if (snapshot.lunaIsFinishedWithData) {
|
||||
if (snapshot.connectionState == ConnectionState.done &&
|
||||
snapshot.hasData) {
|
||||
final events = snapshot.data!;
|
||||
return Selector<ModuleState, CalendarStartingType>(
|
||||
selector: (_, s) => s.calendarStartingType,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:lunasea/modules.dart';
|
||||
import 'package:lunasea/system/profile.dart';
|
||||
import 'package:lunasea/database/models/profile.dart';
|
||||
import 'package:lunasea/database/tables/lunasea.dart';
|
||||
import 'package:lunasea/widgets/ui.dart';
|
||||
import 'package:lunasea/modules/wake_on_lan/api/wake_on_lan.dart';
|
||||
@@ -27,7 +27,7 @@ class _State extends State<ModulesPage> with AutomaticKeepAliveClientMixin {
|
||||
}
|
||||
|
||||
Widget _list() {
|
||||
if (!(LunaProfile.current.anythingEnabled)) {
|
||||
if (!(LunaProfile.current.isAnythingEnabled())) {
|
||||
return LunaMessage(
|
||||
text: 'lunasea.NoModulesEnabled'.tr(),
|
||||
buttonText: 'lunasea.GoToSettings'.tr(),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:lunasea/core/extensions/datetime.dart';
|
||||
import 'package:lunasea/database/box.dart';
|
||||
import 'package:lunasea/database/tables/dashboard.dart';
|
||||
import 'package:lunasea/extensions/datetime.dart';
|
||||
import 'package:lunasea/widgets/ui.dart';
|
||||
import 'package:lunasea/vendor.dart';
|
||||
import 'package:lunasea/modules/dashboard/core/adapters/calendar_starting_day.dart';
|
||||
@@ -47,7 +47,7 @@ class _State extends State<CalendarView> {
|
||||
super.initState();
|
||||
|
||||
final size = DashboardDatabase.CALENDAR_STARTING_SIZE.read();
|
||||
_selected = context.read<ModuleState>().today!.lunaFloor;
|
||||
_selected = context.read<ModuleState>().today!.floor();
|
||||
_selectedEvents = widget.events[_selected] ?? [];
|
||||
_calendarFormat = size.data;
|
||||
}
|
||||
@@ -64,8 +64,8 @@ class _State extends State<CalendarView> {
|
||||
HapticFeedback.selectionClick();
|
||||
if (mounted)
|
||||
setState(() {
|
||||
_selected = selected.lunaFloor;
|
||||
_selectedEvents = widget.events[selected.lunaFloor] ?? [];
|
||||
_selected = selected.floor();
|
||||
_selectedEvents = widget.events[selected.floor()] ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ class _State extends State<CalendarView> {
|
||||
startingDayOfWeek:
|
||||
DashboardDatabase.CALENDAR_STARTING_DAY.read().data,
|
||||
selectedDayPredicate: (date) =>
|
||||
date.lunaFloor == _selected.lunaFloor,
|
||||
date.floor() == _selected.floor(),
|
||||
calendarStyle: CalendarStyle(
|
||||
markersMaxCount: 1,
|
||||
isTodayHighlighted: true,
|
||||
@@ -191,7 +191,7 @@ class _State extends State<CalendarView> {
|
||||
),
|
||||
eventLoader: (date) {
|
||||
if (widget.events.isEmpty) return [];
|
||||
return widget.events[date.lunaFloor] ?? [];
|
||||
return widget.events[date.floor()] ?? [];
|
||||
},
|
||||
calendarFormat: _calendarFormat,
|
||||
availableCalendarFormats: const {
|
||||
@@ -214,8 +214,8 @@ class _State extends State<CalendarView> {
|
||||
/// -1: Date is after today (with content)
|
||||
/// -100: Event list was empty or null
|
||||
int _countMissingContent(DateTime date, List<dynamic> events) {
|
||||
DateTime _date = date.lunaFloor;
|
||||
DateTime _now = DateTime.now().lunaFloor;
|
||||
DateTime _date = date.floor();
|
||||
DateTime _now = DateTime.now().floor();
|
||||
|
||||
if (events.isEmpty) return -100;
|
||||
if (_date.isAfter(_now)) return -1;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:lunasea/system/profile.dart';
|
||||
import 'package:lunasea/database/models/profile.dart';
|
||||
import 'package:lunasea/widgets/ui.dart';
|
||||
import 'package:lunasea/modules/dashboard/core/api/data/abstract.dart';
|
||||
import 'package:lunasea/modules/dashboard/core/api/data/lidarr.dart';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core/extensions/datetime.dart';
|
||||
import 'package:lunasea/database/tables/dashboard.dart';
|
||||
import 'package:lunasea/extensions/datetime.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:lunasea/widgets/ui.dart';
|
||||
@@ -27,7 +27,7 @@ class _State extends State<ScheduleView> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
DateTime _floored = context.read<ModuleState>().today!.lunaFloor;
|
||||
DateTime _floored = context.read<ModuleState>().today!.floor();
|
||||
_today = _floored;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:lunasea/core/router/module_router.dart';
|
||||
import 'package:lunasea/core/router/page_router.dart';
|
||||
import 'package:lunasea/core/router/router.dart';
|
||||
import 'package:lunasea/deprecated/router/module_router.dart';
|
||||
import 'package:lunasea/deprecated/router/page_router.dart';
|
||||
import 'package:lunasea/deprecated/router/router.dart';
|
||||
import 'package:lunasea/vendor.dart';
|
||||
import 'package:lunasea/modules/dashboard/routes/dashboard/route.dart';
|
||||
|
||||
|
||||
@@ -61,9 +61,9 @@ class _State extends State<_Widget> with LunaScrollControllerMixin {
|
||||
final list = LunaBox.externalModules.data
|
||||
.map((module) => ExternalModulesModuleTile(module: module))
|
||||
.toList();
|
||||
list.sort((a, b) => a.module!.displayName!
|
||||
list.sort((a, b) => a.module!.displayName
|
||||
.toLowerCase()
|
||||
.compareTo(b.module!.displayName!.toLowerCase()));
|
||||
.compareTo(b.module!.displayName.toLowerCase()));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/string_links.dart';
|
||||
import 'package:lunasea/database/models/external_module.dart';
|
||||
import 'package:lunasea/extensions/string/links.dart';
|
||||
|
||||
class ExternalModulesModuleTile extends StatelessWidget {
|
||||
final ExternalModuleHiveObject? module;
|
||||
final LunaExternalModule? module;
|
||||
|
||||
const ExternalModulesModuleTile({
|
||||
Key? key,
|
||||
@@ -16,7 +17,7 @@ class ExternalModulesModuleTile extends StatelessWidget {
|
||||
title: module!.displayName,
|
||||
body: [TextSpan(text: module!.host)],
|
||||
trailing: const LunaIconButton.arrow(),
|
||||
onTap: module!.host!.openLink,
|
||||
onTap: module!.host.openLink,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ class LidarrAPI {
|
||||
final Dio _dio;
|
||||
|
||||
LidarrAPI._internal(this._values, this._dio);
|
||||
factory LidarrAPI.from(ProfileHiveObject profile) {
|
||||
factory LidarrAPI.from(LunaProfile profile) {
|
||||
Map<String, dynamic> _headers =
|
||||
Map<String, dynamic>.from(profile.getLidarr()['headers']);
|
||||
Dio _client = Dio(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/int/bytes.dart';
|
||||
import 'package:lunasea/modules/lidarr.dart';
|
||||
|
||||
class LidarrCatalogueData {
|
||||
@@ -70,7 +71,7 @@ class LidarrCatalogueData {
|
||||
return dateAdded;
|
||||
case LidarrCatalogueSorting.size:
|
||||
case LidarrCatalogueSorting.alphabetical:
|
||||
return sizeOnDisk.lunaBytesToString();
|
||||
return sizeOnDisk.asBytes();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/int/bytes.dart';
|
||||
import 'package:lunasea/modules/lidarr.dart';
|
||||
|
||||
class LidarrDialogs {
|
||||
@@ -229,7 +230,7 @@ class LidarrDialogs {
|
||||
subtitle: LunaDialog.richText(
|
||||
children: [
|
||||
LunaDialog.bolded(
|
||||
text: folders[index].freeSpace.lunaBytesToString(),
|
||||
text: folders[index].freeSpace.asBytes(),
|
||||
fontSize: LunaDialog.BUTTON_SIZE,
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/system/webhooks.dart';
|
||||
|
||||
class LidarrWebhooks extends LunaWebhooks {
|
||||
@override
|
||||
@@ -6,8 +7,6 @@ class LidarrWebhooks extends LunaWebhooks {
|
||||
_EventType? event = _EventType.GRAB.fromKey(data['event']);
|
||||
if (event == null)
|
||||
LunaLogger().warning(
|
||||
'LidarrWebhooks',
|
||||
'handle',
|
||||
'Unknown event type: ${data['event'] ?? 'null'}',
|
||||
);
|
||||
event?.execute(data);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/string_links.dart';
|
||||
import 'package:lunasea/extensions/string/links.dart';
|
||||
import 'package:lunasea/modules/lidarr.dart';
|
||||
|
||||
class LidarrAddDetailsArguments {
|
||||
|
||||
@@ -81,7 +81,7 @@ class _State extends State<LidarrDetailsArtist> {
|
||||
LunaIconButton(
|
||||
icon: LunaIcons.LINK,
|
||||
onPressed: () async {
|
||||
LinksSheet(artist: _arguments!.data!).show(context: context);
|
||||
LinksSheet(artist: _arguments!.data!).show();
|
||||
},
|
||||
),
|
||||
LidarrDetailsEditButton(data: _arguments!.data),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/string_links.dart';
|
||||
import 'package:lunasea/extensions/string/links.dart';
|
||||
import 'package:lunasea/modules/lidarr.dart';
|
||||
|
||||
class Lidarr extends StatefulWidget {
|
||||
@@ -133,8 +133,7 @@ class _State extends State<Lidarr> {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LunaLogger().warning(
|
||||
'Lidarr', '_enterAddArtist', 'Unknown Case: ${result[0]}');
|
||||
LunaLogger().warning('[_enterAddArtist] Unknown Case: ${result[0]}');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,8 +142,8 @@ class _State extends State<Lidarr> {
|
||||
if (values[0])
|
||||
switch (values[1]) {
|
||||
case 'web_gui':
|
||||
ProfileHiveObject profile = LunaProfile.current;
|
||||
await profile.lidarrHost?.openLink();
|
||||
LunaProfile profile = LunaProfile.current;
|
||||
await profile.lidarrHost.openLink();
|
||||
break;
|
||||
case 'update_library':
|
||||
await _api
|
||||
@@ -188,8 +187,7 @@ class _State extends State<Lidarr> {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LunaLogger()
|
||||
.warning('Lidarr', '_handlePopup', 'Unknown Case: ${values[1]}');
|
||||
LunaLogger().warning('Unknown Case: ${values[1]}');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/extensions/string_links.dart';
|
||||
import 'package:lunasea/extensions/string/links.dart';
|
||||
import 'package:lunasea/modules/lidarr/core/api.dart';
|
||||
import 'package:lunasea/widgets/ui.dart';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/string_links.dart';
|
||||
import 'package:lunasea/extensions/string/links.dart';
|
||||
import 'package:lunasea/modules/lidarr.dart';
|
||||
|
||||
class LidarrAddSearchResultTile extends StatelessWidget {
|
||||
@@ -63,8 +63,6 @@ class LidarrAddSearchResultTile extends StatelessWidget {
|
||||
break;
|
||||
default:
|
||||
LunaLogger().warning(
|
||||
'LidarrAddSearchResultTile',
|
||||
'_enterDetails',
|
||||
'Unknown Case: ${result[0]}',
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/scroll_controller.dart';
|
||||
import 'package:lunasea/modules/lidarr.dart';
|
||||
|
||||
class LidarrCatalogueSortButton extends StatefulWidget {
|
||||
@@ -32,7 +33,7 @@ class _State extends State<LidarrCatalogueSortButton> {
|
||||
model.sortCatalogueAscending = true;
|
||||
model.sortCatalogueType = result;
|
||||
}
|
||||
widget.controller.lunaAnimateToStart();
|
||||
widget.controller.animateToStart();
|
||||
},
|
||||
itemBuilder: (context) =>
|
||||
List<PopupMenuEntry<LidarrCatalogueSorting>>.generate(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/string.dart';
|
||||
import 'package:lunasea/extensions/string/string.dart';
|
||||
import 'package:lunasea/modules/lidarr.dart';
|
||||
|
||||
class LidarrCatalogueTile extends StatefulWidget {
|
||||
@@ -99,8 +99,7 @@ class _State extends State<LidarrCatalogueTile> {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LunaLogger().warning('LidarrCatalogueTile', '_enterArtist',
|
||||
'Unknown Case: ${result[0]}');
|
||||
LunaLogger().warning('Unknown Case: ${result[0]}');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +117,8 @@ class _State extends State<LidarrCatalogueTile> {
|
||||
_removeArtist();
|
||||
break;
|
||||
default:
|
||||
LunaLogger().warning('LidarrCatalogueTile', '_handlePopup',
|
||||
'Invalid method passed through popup. (${values[1]})');
|
||||
LunaLogger()
|
||||
.warning('Invalid method passed through popup. (${values[1]})');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/int/duration.dart';
|
||||
import 'package:lunasea/modules/lidarr.dart';
|
||||
|
||||
class LidarrDetailsTrackTile extends StatefulWidget {
|
||||
@@ -21,7 +22,7 @@ class _State extends State<LidarrDetailsTrackTile> {
|
||||
Widget build(BuildContext context) => LunaBlock(
|
||||
title: widget.data.title,
|
||||
body: [
|
||||
TextSpan(text: widget.data.duration.lunaTimestamp(divisor: 1000)),
|
||||
TextSpan(text: widget.data.duration.asTrackDuration(divisor: 1000)),
|
||||
widget.data.file(widget.monitored),
|
||||
],
|
||||
disabled: !widget.monitored,
|
||||
|
||||
@@ -40,8 +40,8 @@ class _State extends State<LidarrDetailsSettingsButton> {
|
||||
_removeArtist(context);
|
||||
break;
|
||||
default:
|
||||
LunaLogger().warning('LidarrDetailsSettingsButton', '_handlePopup',
|
||||
'Invalid method passed through popup. (${values[1]})');
|
||||
LunaLogger()
|
||||
.warning('Invalid method passed through popup. (${values[1]})');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/scroll_controller.dart';
|
||||
import 'package:lunasea/modules/lidarr.dart';
|
||||
|
||||
class LidarrReleasesSortButton extends StatefulWidget {
|
||||
@@ -32,7 +33,7 @@ class _State extends State<LidarrReleasesSortButton> {
|
||||
model.sortReleasesAscending = true;
|
||||
model.sortReleasesType = result;
|
||||
}
|
||||
widget.controller.lunaAnimateToStart();
|
||||
widget.controller.animateToStart();
|
||||
},
|
||||
itemBuilder: (context) =>
|
||||
List<PopupMenuEntry<LidarrReleasesSorting>>.generate(
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/double.dart';
|
||||
import 'package:lunasea/extensions/string.dart';
|
||||
import 'package:lunasea/extensions/double/time.dart';
|
||||
import 'package:lunasea/extensions/int/bytes.dart';
|
||||
import 'package:lunasea/extensions/string/string.dart';
|
||||
import 'package:lunasea/modules/lidarr.dart';
|
||||
import 'package:lunasea/modules/dashboard/routes/dashboard/route.dart'
|
||||
as dashboard_home;
|
||||
@@ -56,7 +57,7 @@ class _State extends State<LidarrReleasesTile> {
|
||||
TextSpan(text: LunaUI.TEXT_BULLET.pad()),
|
||||
TextSpan(text: widget.release.indexer),
|
||||
TextSpan(text: LunaUI.TEXT_BULLET.pad()),
|
||||
TextSpan(text: widget.release.ageHours.asTimeAgo),
|
||||
TextSpan(text: widget.release.ageHours.asTimeAgo()),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -65,7 +66,7 @@ class _State extends State<LidarrReleasesTile> {
|
||||
children: [
|
||||
TextSpan(text: widget.release.quality),
|
||||
TextSpan(text: LunaUI.TEXT_BULLET.pad()),
|
||||
TextSpan(text: widget.release.size.lunaBytesToString()),
|
||||
TextSpan(text: widget.release.size.asBytes()),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -96,10 +97,9 @@ class _State extends State<LidarrReleasesTile> {
|
||||
return [
|
||||
LunaTableContent(
|
||||
title: 'source', body: widget.release.protocol.toTitleCase()),
|
||||
LunaTableContent(title: 'age', body: widget.release.ageHours.asTimeAgo),
|
||||
LunaTableContent(title: 'age', body: widget.release.ageHours.asTimeAgo()),
|
||||
LunaTableContent(title: 'indexer', body: widget.release.indexer),
|
||||
LunaTableContent(
|
||||
title: 'size', body: widget.release.size.lunaBytesToString()),
|
||||
LunaTableContent(title: 'size', body: widget.release.size.asBytes()),
|
||||
LunaTableContent(title: 'quality', body: widget.release.quality),
|
||||
if (widget.release.protocol == 'torrent' &&
|
||||
widget.release.seeders != null)
|
||||
|
||||
@@ -6,7 +6,7 @@ class NZBGetAPI {
|
||||
final Dio _dio;
|
||||
|
||||
NZBGetAPI._internal(this._values, this._dio);
|
||||
factory NZBGetAPI.from(ProfileHiveObject profile) {
|
||||
factory NZBGetAPI.from(LunaProfile profile) {
|
||||
String _baseURL = Uri.encodeFull(profile.getNZBGet()['host']);
|
||||
Map<String, dynamic> _headers =
|
||||
Map<String, dynamic>.from(profile.getNZBGet()['headers']);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/int/bytes.dart';
|
||||
|
||||
class NZBGetHistoryData {
|
||||
int id;
|
||||
@@ -38,12 +37,12 @@ class NZBGetHistoryData {
|
||||
return '0.00 MB/s';
|
||||
} else {
|
||||
int speed = (downloaded / downloadTime).floor();
|
||||
return '${speed.lunaBytesToString()}/s';
|
||||
return '${speed.asBytes()}/s';
|
||||
}
|
||||
}
|
||||
|
||||
String get sizeReadable {
|
||||
return downloaded.lunaBytesToString();
|
||||
return downloaded.asBytes();
|
||||
}
|
||||
|
||||
DateTime? get timestampObject {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/string.dart';
|
||||
import 'package:lunasea/extensions/int/duration.dart';
|
||||
import 'package:lunasea/extensions/string/string.dart';
|
||||
|
||||
class NZBGetQueueData {
|
||||
int id;
|
||||
@@ -41,9 +42,9 @@ class NZBGetQueueData {
|
||||
}
|
||||
|
||||
String get timestamp {
|
||||
return (queueSeconds + remainingTime).lunaTimestamp() == '0:00:00'
|
||||
return (queueSeconds + remainingTime).asTrackDuration() == '00:00'
|
||||
? '―'
|
||||
: (queueSeconds + remainingTime).lunaTimestamp();
|
||||
: (queueSeconds + remainingTime).asTrackDuration();
|
||||
}
|
||||
|
||||
String get statusString {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/int/bytes.dart';
|
||||
import 'package:lunasea/extensions/int/duration.dart';
|
||||
|
||||
class NZBGetStatisticsData {
|
||||
int freeSpaceHigh;
|
||||
@@ -32,19 +33,19 @@ class NZBGetStatisticsData {
|
||||
}
|
||||
|
||||
String get freeSpaceString {
|
||||
return freeSpace.lunaBytesToString(decimals: 1);
|
||||
return freeSpace.asBytes(decimals: 1);
|
||||
}
|
||||
|
||||
String get downloadedString {
|
||||
return downloaded.lunaBytesToString(decimals: 1);
|
||||
return downloaded.asBytes(decimals: 1);
|
||||
}
|
||||
|
||||
String get uptimeString {
|
||||
return uptimeSeconds.lunaDuration();
|
||||
return uptimeSeconds.asWordDuration();
|
||||
}
|
||||
|
||||
String get speedLimitString {
|
||||
String limit = speedLimit.lunaBytesToString();
|
||||
String limit = speedLimit.asBytes();
|
||||
return limit == '0.00 B' ? 'No Limit Set' : '$limit/s';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/int/bytes.dart';
|
||||
import 'package:lunasea/extensions/int/duration.dart';
|
||||
|
||||
class NZBGetStatusData {
|
||||
bool paused;
|
||||
@@ -20,22 +21,20 @@ class NZBGetStatusData {
|
||||
}
|
||||
|
||||
String get currentSpeed {
|
||||
return '${speed.lunaBytesToString(decimals: 1)}/s';
|
||||
return '${speed.asBytes(decimals: 1)}/s';
|
||||
}
|
||||
|
||||
String get remainingString {
|
||||
return remaining.lunaBytesToString(decimals: 1);
|
||||
return remaining.asBytes(decimals: 1);
|
||||
}
|
||||
|
||||
String get timeLeft {
|
||||
return speed == 0
|
||||
? '0:00:00'
|
||||
: ((remaining / speed).floor()).lunaTimestamp();
|
||||
: ((remaining / speed).floor()).asTrackDuration();
|
||||
}
|
||||
|
||||
String get speedlimitString {
|
||||
return speedlimit == 0
|
||||
? 'Unlimited'
|
||||
: speedlimit.lunaBytesToString(decimals: 0);
|
||||
return speedlimit == 0 ? 'Unlimited' : speedlimit.asBytes(decimals: 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/database/tables/nzbget.dart';
|
||||
import 'package:lunasea/extensions/string_links.dart';
|
||||
import 'package:lunasea/extensions/string/links.dart';
|
||||
import 'package:lunasea/modules/nzbget.dart';
|
||||
|
||||
import 'package:lunasea/system/filesystem/file.dart';
|
||||
@@ -113,8 +113,8 @@ class _State extends State<NZBGet> {
|
||||
if (values[0])
|
||||
switch (values[1]) {
|
||||
case 'web_gui':
|
||||
ProfileHiveObject profile = LunaProfile.current;
|
||||
await profile.nzbgetHost?.openLink();
|
||||
LunaProfile profile = LunaProfile.current;
|
||||
await profile.nzbgetHost.openLink();
|
||||
break;
|
||||
case 'add_nzb':
|
||||
_addNZB();
|
||||
@@ -126,8 +126,7 @@ class _State extends State<NZBGet> {
|
||||
_serverDetails();
|
||||
break;
|
||||
default:
|
||||
LunaLogger()
|
||||
.warning('NZBGet', '_handlePopup', 'Unknown Case: ${values[1]}');
|
||||
LunaLogger().warning('Unknown Case: ${values[1]}');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,8 +141,7 @@ class _State extends State<NZBGet> {
|
||||
_addByFile();
|
||||
break;
|
||||
default:
|
||||
LunaLogger()
|
||||
.warning('NZBGet', '_addNZB', 'Unknown Case: ${values[1]}');
|
||||
LunaLogger().warning('Unknown Case: ${values[1]}');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/string.dart';
|
||||
import 'package:lunasea/extensions/int/bytes.dart';
|
||||
import 'package:lunasea/extensions/string/string.dart';
|
||||
import 'package:lunasea/modules/nzbget.dart';
|
||||
|
||||
class NZBGetAppBarStats extends StatelessWidget {
|
||||
@@ -72,7 +73,7 @@ class NZBGetAppBarStats extends StatelessWidget {
|
||||
.then((_) => showLunaSuccessSnackBar(
|
||||
title: 'Speed Limit Set',
|
||||
message:
|
||||
'Set to ${(values[1] as int?).lunaKilobytesToString(decimals: 0)}/s',
|
||||
'Set to ${(values[1] as int?).asKilobytes(decimals: 0)}/s',
|
||||
))
|
||||
.catchError((error) => showLunaErrorSnackBar(
|
||||
title: 'Failed to Set Speed Limit',
|
||||
@@ -86,7 +87,7 @@ class NZBGetAppBarStats extends StatelessWidget {
|
||||
.then((_) => showLunaSuccessSnackBar(
|
||||
title: 'Speed Limit Set',
|
||||
message:
|
||||
'Set to ${(values[1] as int?).lunaKilobytesToString(decimals: 0)}/s',
|
||||
'Set to ${(values[1] as int?).asKilobytes(decimals: 0)}/s',
|
||||
))
|
||||
.catchError((error) => showLunaErrorSnackBar(
|
||||
title: 'Failed to Set Speed Limit',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/string.dart';
|
||||
import 'package:lunasea/extensions/string/string.dart';
|
||||
import 'package:lunasea/modules/nzbget.dart';
|
||||
|
||||
class NZBGetHistoryTile extends StatefulWidget {
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:lunasea/extensions/int/duration.dart';
|
||||
import 'package:lunasea/modules/nzbget.dart';
|
||||
|
||||
class NZBGetQueueFAB extends StatefulWidget {
|
||||
@@ -112,7 +113,7 @@ class _State extends State<NZBGetQueueFAB> with TickerProviderStateMixin {
|
||||
.then((_) => showLunaSuccessSnackBar(
|
||||
title: 'Pausing Queue',
|
||||
message:
|
||||
'For ${(values[1] as int?).lunaDuration(multiplier: 60)}',
|
||||
'For ${(values[1] as int?).asWordDuration(multiplier: 60)}',
|
||||
))
|
||||
.catchError((error) => showLunaErrorSnackBar(
|
||||
title: 'Failed to Pause Queue',
|
||||
@@ -124,7 +125,7 @@ class _State extends State<NZBGetQueueFAB> with TickerProviderStateMixin {
|
||||
.then((_) => showLunaSuccessSnackBar(
|
||||
title: 'Pausing Queue',
|
||||
message:
|
||||
'For ${(values[1] as int).lunaDuration(multiplier: 60)}',
|
||||
'For ${(values[1] as int).asWordDuration(multiplier: 60)}',
|
||||
))
|
||||
.catchError((error) => showLunaErrorSnackBar(
|
||||
title: 'Failed to Pause Queue',
|
||||
|
||||
@@ -59,8 +59,7 @@ class _State extends State<NZBGetQueueTile> {
|
||||
_helper._delete();
|
||||
break;
|
||||
default:
|
||||
LunaLogger().warning(
|
||||
'NZBGetQueueTile', '_handlePopup', 'Unknown Case: ${values[1]}');
|
||||
LunaLogger().warning('Unknown Case: ${values[1]}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user