refactor(platform): guard usages of dart:io and dart:html for future compatability

This commit is contained in:
Jagandeep Brar
2022-03-18 12:23:42 -04:00
parent 403edc16fb
commit c7bd62de2e
52 changed files with 159 additions and 220 deletions

View File

@@ -1,59 +1 @@
{ {}
"motd": "Welcome to LunaSea v10.0.0!\n\nThis update does not have a lot of user-facing changes but introduces substantial reworkings of core integrations and processes that will help make new releases of LunaSea more stable and easier to deploy in the future.",
"new": [
{
"module": "Networking",
"changes": [
"(HTTP) Set user-agent to \"LunaSea/{version} {build}\""
]
},
{
"module": "Radarr",
"changes": [
"(Files) Show additional media metadata"
]
},
{
"module": "Settings",
"changes": [
"(Resources) Add test build information"
]
},
{
"module": "Sonarr",
"changes": [
"(Series) Support for searching entire series for monitored episodes"
]
},
{
"module": "UI/UX",
"changes": [
"(Block) Support skeleton-state loading"
]
}
],
"tweaks": [],
"fixes": [
{
"module": "Database",
"changes": [
"Database entries could be unloaded from memory in some cases"
]
},
{
"module": "Radarr",
"changes": [
"(Availability) Prevent using preDB availability for movies",
"(System Status) Hide irrelevant lines on about page for some installations"
]
},
{
"module": "UI/UX",
"changes": [
"(ListView) Correctly handle pull-to-refresh drag action on all platforms",
"(Input Bar) Saving inputs would not actually update the underlying value in some cases"
]
}
],
"platform": []
}

View File

@@ -1,4 +1,3 @@
import 'dart:async';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';

View File

@@ -1,4 +1,3 @@
import 'dart:typed_data';
import 'package:firebase_storage/firebase_storage.dart'; import 'package:firebase_storage/firebase_storage.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';

View File

@@ -17,7 +17,7 @@ import 'package:lunasea/modules/tautulli.dart';
import '../modules/dashboard/core/database.dart'; import '../modules/dashboard/core/database.dart';
import '../modules/dashboard/core/state.dart' as dashboard_state; import '../modules/dashboard/core/state.dart' as dashboard_state;
import '../modules/dashboard/routes/dashboard/route.dart' as dashboard_home; import '../modules/dashboard/routes/dashboard/route.dart' as dashboard_home;
import '../modules/wake_on_lan/api/api.dart'; import '../modules/wake_on_lan/api/wake_on_lan.dart';
part 'modules.g.dart'; part 'modules.g.dart';

View File

@@ -1,4 +1,3 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/main.dart'; import 'package:lunasea/main.dart';
@@ -19,11 +18,7 @@ import '../../modules/dashboard/routes/routes.dart' as dashboard;
class LunaRouter { class LunaRouter {
static FluroRouter router = FluroRouter(); static FluroRouter router = FluroRouter();
static TransitionType get transitionType { static TransitionType get transitionType => TransitionType.native;
// Required otherwise no transition is executed
if (Platform.isMacOS) return TransitionType.cupertino;
return TransitionType.native;
}
/// Calls `defineAllRoutes()` on all module routers that implement [LunaModuleRouter]. /// Calls `defineAllRoutes()` on all module routers that implement [LunaModuleRouter].
void initialize() { void initialize() {

View File

@@ -1,9 +1,7 @@
export 'system/configuration.dart'; export 'system/configuration.dart';
export 'system/desktop_window.dart'; export 'system/desktop_window.dart';
export 'system/filesystem.dart';
export 'system/flavor.dart'; export 'system/flavor.dart';
export 'system/in_app_purchases.dart'; export 'system/in_app_purchases.dart';
export 'system/localization.dart'; export 'system/localization.dart';
export 'system/networking.dart';
export 'system/profile.dart'; export 'system/profile.dart';
export 'system/quick_actions.dart'; export 'system/quick_actions.dart';

View File

@@ -1,17 +1,17 @@
import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart'; import 'package:window_manager/window_manager.dart';
import 'platform.dart';
class LunaDesktopWindow { class LunaDesktopWindow {
static const double _MINIMUM_WINDOW_SIZE = 400; static const double _MINIMUM_WINDOW_SIZE = 400;
static const double _INITIAL_WINDOW_SIZE = 700; static const double _INITIAL_WINDOW_SIZE = 700;
static bool get isPlatformCompatible => static bool get isSupported => LunaPlatform().isDesktop;
Platform.isWindows || Platform.isMacOS || Platform.isLinux;
Future<void> initialize() async { Future<void> initialize() async {
if (isPlatformCompatible) { if (isSupported) {
await windowManager.ensureInitialized(); await windowManager.ensureInitialized();
windowManager.waitUntilReadyToShow().then((_) async { windowManager.waitUntilReadyToShow().then((_) async {
const Size minSize = Size(_MINIMUM_WINDOW_SIZE, _MINIMUM_WINDOW_SIZE); const Size minSize = Size(_MINIMUM_WINDOW_SIZE, _MINIMUM_WINDOW_SIZE);
@@ -27,7 +27,7 @@ class LunaDesktopWindow {
} }
Future<void> setWindowTitle(String title) async { Future<void> setWindowTitle(String title) async {
if (isPlatformCompatible) { if (isSupported) {
windowManager windowManager
.waitUntilReadyToShow() .waitUntilReadyToShow()
.then((_) async => await windowManager.setTitle(title)); .then((_) async => await windowManager.setTitle(title));

View File

@@ -1,2 +0,0 @@
export 'filesystem/file.dart';
export 'filesystem/filesystem.dart';

View File

@@ -1,9 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'file.dart'; import 'file.dart';
import './platform/filesystem_stub.dart' import 'platform/filesystem_stub.dart'
if (dart.library.io) './platform/filesystem_io.dart' if (dart.library.io) 'platform/filesystem_io.dart'
if (dart.library.html) './platform/filesystem_web.dart'; if (dart.library.html) 'platform/filesystem_html.dart';
abstract class LunaFileSystem { abstract class LunaFileSystem {
static bool get isSupported => isPlatformSupported(); static bool get isSupported => isPlatformSupported();

View File

@@ -1,5 +1,5 @@
import '../filesystem.dart'; import '../filesystem.dart';
import './platform_web.dart'; import 'platform_web.dart';
bool isPlatformSupported() => false; bool isPlatformSupported() => false;
LunaFileSystem getFileSystem() => Web(); LunaFileSystem getFileSystem() => Web();

View File

@@ -1,8 +1,8 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import '../filesystem.dart'; import '../filesystem.dart';
import './platform_desktop.dart'; import 'platform_desktop.dart';
import './platform_mobile.dart'; import 'platform_mobile.dart';
bool isPlatformSupported() { bool isPlatformSupported() {
switch (defaultTargetPlatform) { switch (defaultTargetPlatform) {

View File

@@ -1,8 +1,8 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:in_app_purchase/in_app_purchase.dart'; import 'package:in_app_purchase/in_app_purchase.dart';
import 'package:lunasea/core.dart';
import 'platform.dart';
extension ProductDetailsExtension on ProductDetails { extension ProductDetailsExtension on ProductDetails {
IconData get icon { IconData get icon {
@@ -54,7 +54,7 @@ class LunaInAppPurchases {
static List<ProductDetails> donationIAPs = []; static List<ProductDetails> donationIAPs = [];
static bool isAvailable = false; static bool isAvailable = false;
static bool get isPlatformCompatible => Platform.isAndroid || Platform.isIOS; static bool get isSupported => LunaPlatform().isMobile;
/// Callback function for [purchaseStream]. /// Callback function for [purchaseStream].
static Future<void> _purchasedCallback( static Future<void> _purchasedCallback(
@@ -74,7 +74,7 @@ class LunaInAppPurchases {
/// - Attach [InAppPurchaseConnection.instance.purchaseUpdateStream] listener for automatically completing IAP purchases /// - Attach [InAppPurchaseConnection.instance.purchaseUpdateStream] listener for automatically completing IAP purchases
/// - Fetch and store donation IAPs /// - Fetch and store donation IAPs
Future<void> initialize() async { Future<void> initialize() async {
if (isPlatformCompatible) { if (isSupported) {
isAvailable = await connection.isAvailable(); isAvailable = await connection.isAvailable();
if (isAvailable) { if (isAvailable) {
// Open listener // Open listener

View File

@@ -1,42 +0,0 @@
import 'dart:io';
import 'package:lunasea/core.dart';
import 'package:package_info_plus/package_info_plus.dart';
class LunaNetworking extends HttpOverrides {
/// Initialize the default HTTP client by setting [HttpOverrides]'s global HTTP client to [LunaNetworking].
void initialize() {
HttpOverrides.global = LunaNetworking();
}
String generateUserAgent(PackageInfo info) {
return '${info.appName}/${info.version} ${info.buildNumber}';
}
/// Overrides the default [createHttpClient] function and ensures all HTTPS connections allow bad certificate connections.
///
/// Returns a new [HttpClient] using the given [context].
@override
HttpClient createHttpClient(SecurityContext? context) {
final HttpClient client = super.createHttpClient(context);
// Disable TLS validation
if (!LunaDatabaseValue.NETWORKING_TLS_VALIDATION.data)
client.badCertificateCallback = (cert, host, port) => true;
// Set User-Agent
PackageInfo.fromPlatform()
.then((info) => client.userAgent = generateUserAgent(info))
.catchError((_) => client.userAgent = 'LunaSea/Unknown');
return client;
}
/// Overrides the default [findProxyFromEnvironment] function.
///
/// Currently just calls the super function to use the default finding function.
@override
String findProxyFromEnvironment(Uri url, Map<String, String>? environment) {
return super.findProxyFromEnvironment(url, environment);
}
}

View File

@@ -0,0 +1,10 @@
import 'platform/networking_stub.dart'
if (dart.library.io) 'platform/networking_io.dart'
if (dart.library.html) 'platform/networking_html.dart';
abstract class LunaNetworking {
static bool get isSupported => isPlatformSupported();
factory LunaNetworking() => getNetworking();
void initialize();
}

View File

@@ -0,0 +1,5 @@
import '../networking.dart';
bool isPlatformSupported() => false;
LunaNetworking getNetworking() =>
throw UnsupportedError('LunaNetworking unsupported');

View File

@@ -0,0 +1,35 @@
import 'dart:io';
import '../../../../vendor.dart';
import '../../../database/luna_database.dart';
import '../networking.dart';
bool isPlatformSupported() => true;
LunaNetworking getNetworking() => IO();
class IO extends HttpOverrides implements LunaNetworking {
@override
void initialize() {
HttpOverrides.global = IO();
}
String generateUserAgent(PackageInfo info) {
return '${info.appName}/${info.version} ${info.buildNumber}';
}
@override
HttpClient createHttpClient(SecurityContext? context) {
final HttpClient client = super.createHttpClient(context);
// Disable TLS validation
if (!LunaDatabaseValue.NETWORKING_TLS_VALIDATION.data)
client.badCertificateCallback = (cert, host, port) => true;
// Set User-Agent
PackageInfo.fromPlatform()
.then((info) => client.userAgent = generateUserAgent(info))
.catchError((_) => client.userAgent = 'LunaSea/Unknown');
return client;
}
}

View File

@@ -0,0 +1,5 @@
import '../networking.dart';
bool isPlatformSupported() => false;
LunaNetworking getNetworking() =>
throw UnsupportedError('LunaNetworking unsupported');

View File

@@ -0,0 +1,15 @@
import 'package:flutter/foundation.dart';
class LunaPlatform {
bool get isAndroid => defaultTargetPlatform == TargetPlatform.android;
bool get isIOS => defaultTargetPlatform == TargetPlatform.iOS;
bool get isLinux => defaultTargetPlatform == TargetPlatform.linux;
bool get isMacOS => defaultTargetPlatform == TargetPlatform.macOS;
bool get isWindows => defaultTargetPlatform == TargetPlatform.windows;
bool get isWeb => kIsWeb;
bool get isMobile => isAndroid || isIOS;
bool get isDesktop => isLinux || isMacOS || isWindows;
}

View File

@@ -1,11 +1,12 @@
import 'dart:io';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:quick_actions/quick_actions.dart'; import 'package:quick_actions/quick_actions.dart';
import 'platform.dart';
class LunaQuickActions { class LunaQuickActions {
static const QuickActions _quickActions = QuickActions(); static const QuickActions _quickActions = QuickActions();
static bool get isPlatformCompatible => Platform.isAndroid || Platform.isIOS; static bool get isPlatformCompatible => LunaPlatform().isMobile;
/// Initialize the quick actions by setting the action handler. /// Initialize the quick actions by setting the action handler.
/// ///

View File

@@ -1,3 +1,4 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';

View File

@@ -1,3 +1,4 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import '../../../modules/wake_on_lan/api/api.dart'; import '../../../modules/wake_on_lan/api/wake_on_lan.dart';
class LunaDrawer extends StatelessWidget { class LunaDrawer extends StatelessWidget {
final String page; final String page;

View File

@@ -1,3 +1,4 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';

View File

@@ -1,7 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:package_info_plus/package_info_plus.dart';
class LunaChangelogSheet extends LunaBottomModalSheet { class LunaChangelogSheet extends LunaBottomModalSheet {
late _Changelog _changelog; late _Changelog _changelog;
@@ -64,10 +62,6 @@ class LunaChangelogSheet extends LunaBottomModalSheet {
'lunasea.Fixes'.tr(), 'lunasea.Fixes'.tr(),
_changelog.changesFixes, _changelog.changesFixes,
), ),
..._buildChangeBlock(
'lunasea.PlatformSpecific'.tr(),
_changelog.changesPlatform,
),
const SizedBox(height: LunaUI.DEFAULT_MARGIN_SIZE / 2), const SizedBox(height: LunaUI.DEFAULT_MARGIN_SIZE / 2),
], ],
actionBar: LunaBottomActionBar( actionBar: LunaBottomActionBar(
@@ -110,50 +104,21 @@ class _Changelog {
List<_Change> changesNew = []; List<_Change> changesNew = [];
List<_Change> changesTweaks = []; List<_Change> changesTweaks = [];
List<_Change> changesFixes = []; List<_Change> changesFixes = [];
List<_Change> changesPlatform = [];
static _Changelog fromJson(Map<String, dynamic> json) { static _Changelog fromJson(Map<String, dynamic> json) {
_Changelog changelog = _Changelog(); _Changelog changelog = _Changelog();
int _index = -1;
List<dynamic>? data; List<dynamic>? data;
changelog.motd = json['motd'] ?? ''; changelog.motd = json['motd'] ?? 'Welcome to LunaSea!';
data = json['new']; data = json['new'];
data?.forEach((change) { data?.forEach((c) => changelog.changesNew.add(_Change.fromJson(c)));
_Change _change = _Change.fromJson(change);
changelog.changesNew.add(_change);
});
data = json['tweaks']; data = json['tweaks'];
data?.forEach((change) { data?.forEach((c) => changelog.changesTweaks.add(_Change.fromJson(c)));
_Change _change = _Change.fromJson(change);
changelog.changesTweaks.add(_change);
});
data = json['fixes']; data = json['fixes'];
data?.forEach((change) { data?.forEach((c) => changelog.changesFixes.add(_Change.fromJson(c)));
_Change _change = _Change.fromJson(change);
changelog.changesFixes.add(_change);
});
_index = data?.indexWhere((e) => e['module'] == 'macOS') ?? -1;
if (Platform.isMacOS && _index >= 0) {
_Change _change = _Change.fromJson(data![_index]);
changelog.changesFixes.add(_change);
}
_index = data?.indexWhere((e) => e['module'] == 'Android') ?? -1;
if (Platform.isAndroid && _index >= 0) {
_Change _change = _Change.fromJson(data![_index]);
changelog.changesFixes.add(_change);
}
_index = data?.indexWhere((e) => e['module'] == 'iOS') ?? -1;
if (Platform.isIOS && _index >= 0) {
_Change _change = _Change.fromJson(data![_index]);
changelog.changesFixes.add(_change);
}
return changelog; return changelog;
} }
@@ -167,8 +132,8 @@ class _Change {
static _Change fromJson(Map<String, dynamic> json) { static _Change fromJson(Map<String, dynamic> json) {
_Change change = _Change._(); _Change change = _Change._();
change.module = json['module']!; change.module = json['module'] as String;
change.changes = (json['changes'] as List?)?.cast<String>() ?? []; change.changes = (json['changes'] as List).cast<String>();
return change; return change;
} }
} }

View File

@@ -1,5 +1,3 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';

View File

@@ -1,11 +1,11 @@
import 'dart:async';
import 'dart:io';
import 'package:device_preview/device_preview.dart'; import 'package:device_preview/device_preview.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'core/system/networking/networking.dart';
import 'core/system/platform.dart';
import 'modules/dashboard/routes/dashboard/route.dart' show HomeRouter; import 'modules/dashboard/routes/dashboard/route.dart' show HomeRouter;
/// LunaSea Entry Point: Initialize & Run Application /// LunaSea Entry Point: Initialize & Run Application
@@ -21,7 +21,7 @@ Future<void> main() async {
LunaLogger().initialize(); LunaLogger().initialize();
LunaTheme().initialize(); LunaTheme().initialize();
await LunaDesktopWindow().initialize(); await LunaDesktopWindow().initialize();
LunaNetworking().initialize(); if (LunaNetworking.isSupported) LunaNetworking().initialize();
LunaImageCache().initialize(); LunaImageCache().initialize();
LunaRouter().initialize(); LunaRouter().initialize();
await LunaInAppPurchases().initialize(); await LunaInAppPurchases().initialize();
@@ -45,7 +45,7 @@ class LunaBIOS extends StatelessWidget {
LunaRouter router = LunaRouter(); LunaRouter router = LunaRouter();
return DevicePreview( return DevicePreview(
enabled: kDebugMode && Platform.isMacOS, enabled: kDebugMode && LunaPlatform().isDesktop,
builder: (context) => EasyLocalization( builder: (context) => EasyLocalization(
supportedLocales: localization.supportedLocales as List<Locale>, supportedLocales: localization.supportedLocales as List<Locale>,
path: localization.fileDirectory, path: localization.fileDirectory,

View File

@@ -4,7 +4,7 @@ import '../../../../../../core/database/luna_database.dart';
import '../../../../../../core/modules.dart'; import '../../../../../../core/modules.dart';
import '../../../../../../core/system/profile.dart'; import '../../../../../../core/system/profile.dart';
import '../../../../../../core/ui.dart'; import '../../../../../../core/ui.dart';
import '../../../../wake_on_lan/api/api.dart'; import '../../../../wake_on_lan/api/wake_on_lan.dart';
import '../widgets/navigation_bar.dart'; import '../widgets/navigation_bar.dart';
class ModulesPage extends StatefulWidget { class ModulesPage extends StatefulWidget {

View File

@@ -2,6 +2,9 @@ import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/nzbget.dart'; import 'package:lunasea/modules/nzbget.dart';
import '../../../core/system/filesystem/file.dart';
import '../../../core/system/filesystem/filesystem.dart';
class NZBGet extends StatefulWidget { class NZBGet extends StatefulWidget {
static const ROUTE_NAME = '/nzbget'; static const ROUTE_NAME = '/nzbget';

View File

@@ -1,5 +1,3 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/nzbget.dart'; import 'package:lunasea/modules/nzbget.dart';

View File

@@ -1,4 +1,3 @@
import 'dart:async';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/radarr.dart'; import 'package:lunasea/modules/radarr.dart';

View File

@@ -1,4 +1,3 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/sabnzbd.dart'; import 'package:lunasea/modules/sabnzbd.dart';

View File

@@ -2,6 +2,9 @@ import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/sabnzbd.dart'; import 'package:lunasea/modules/sabnzbd.dart';
import '../../../core/system/filesystem/file.dart';
import '../../../core/system/filesystem/filesystem.dart';
class SABnzbd extends StatefulWidget { class SABnzbd extends StatefulWidget {
static const ROUTE_NAME = '/sabnzbd'; static const ROUTE_NAME = '/sabnzbd';

View File

@@ -4,6 +4,8 @@ import 'package:lunasea/modules/nzbget.dart';
import 'package:lunasea/modules/sabnzbd.dart'; import 'package:lunasea/modules/sabnzbd.dart';
import 'package:lunasea/modules/search.dart'; import 'package:lunasea/modules/search.dart';
import '../../../../core/system/filesystem/filesystem.dart';
enum SearchDownloadType { enum SearchDownloadType {
NZBGET, NZBGET,
SABNZBD, SABNZBD,

View File

@@ -1,8 +1,10 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/settings.dart'; import 'package:lunasea/modules/settings.dart';
import '../../../../core/system/networking/networking.dart';
import '../../../../core/system/platform.dart';
class SettingsConfigurationRouter extends SettingsPageRouter { class SettingsConfigurationRouter extends SettingsPageRouter {
SettingsConfigurationRouter() : super('/settings/configuration'); SettingsConfigurationRouter() : super('/settings/configuration');
@@ -79,14 +81,15 @@ class _State extends State<_Widget> with LunaScrollControllerMixin {
onTap: () async => onTap: () async =>
SettingsConfigurationLocalizationRouter().navigateTo(context), SettingsConfigurationLocalizationRouter().navigateTo(context),
), ),
LunaBlock( if (LunaNetworking.isSupported)
title: 'settings.Network'.tr(), LunaBlock(
body: [TextSpan(text: 'settings.NetworkDescription'.tr())], title: 'settings.Network'.tr(),
trailing: const LunaIconButton(icon: Icons.network_check_rounded), body: [TextSpan(text: 'settings.NetworkDescription'.tr())],
onTap: () async => trailing: const LunaIconButton(icon: Icons.network_check_rounded),
SettingsConfigurationNetworkRouter().navigateTo(context), onTap: () async =>
), SettingsConfigurationNetworkRouter().navigateTo(context),
if (Platform.isIOS) ),
if (LunaPlatform().isIOS)
LunaDatabaseValue.SELECTED_BROWSER.listen( LunaDatabaseValue.SELECTED_BROWSER.listen(
builder: (context, box, widget) { builder: (context, box, widget) {
LunaDatabaseValue _db = LunaDatabaseValue.SELECTED_BROWSER; LunaDatabaseValue _db = LunaDatabaseValue.SELECTED_BROWSER;

View File

@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/settings.dart'; import 'package:lunasea/modules/settings.dart';
import '../../../../core/system/networking/networking.dart';
class SettingsConfigurationNetworkRouter extends SettingsPageRouter { class SettingsConfigurationNetworkRouter extends SettingsPageRouter {
SettingsConfigurationNetworkRouter() SettingsConfigurationNetworkRouter()
: super('/settings/configuration/network'); : super('/settings/configuration/network');
@@ -58,7 +60,10 @@ class _State extends State<_Widget> with LunaScrollControllerMixin {
], ],
trailing: LunaSwitch( trailing: LunaSwitch(
value: _db.data, value: _db.data,
onChanged: _db.put, onChanged: (data) {
_db.put(data);
if (LunaNetworking.isSupported) LunaNetworking().initialize();
},
), ),
), ),
); );

View File

@@ -1,4 +1,3 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:in_app_purchase/in_app_purchase.dart'; import 'package:in_app_purchase/in_app_purchase.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';

View File

@@ -70,7 +70,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin {
onTap: () async => SettingsProfilesRouter().navigateTo(context), onTap: () async => SettingsProfilesRouter().navigateTo(context),
), ),
LunaDivider(), LunaDivider(),
if (LunaInAppPurchases.isPlatformCompatible) if (LunaInAppPurchases.isSupported)
LunaBlock( LunaBlock(
title: 'settings.Donations'.tr(), title: 'settings.Donations'.tr(),
body: [TextSpan(text: 'settings.DonationsDescription'.tr())], body: [TextSpan(text: 'settings.DonationsDescription'.tr())],

View File

@@ -1,7 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/settings.dart'; import 'package:lunasea/modules/settings.dart';
import 'package:package_info_plus/package_info_plus.dart';
class SettingsSystemRouter extends SettingsPageRouter { class SettingsSystemRouter extends SettingsPageRouter {
SettingsSystemRouter() : super('/settings/system'); SettingsSystemRouter() : super('/settings/system');

View File

@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/settings.dart'; import 'package:lunasea/modules/settings.dart';
import '../../../../../core/system/filesystem/filesystem.dart';
class SettingsSystemBackupRestoreBackupTile extends StatelessWidget { class SettingsSystemBackupRestoreBackupTile extends StatelessWidget {
const SettingsSystemBackupRestoreBackupTile({ const SettingsSystemBackupRestoreBackupTile({
Key? key, Key? key,

View File

@@ -2,6 +2,9 @@ import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/settings.dart'; import 'package:lunasea/modules/settings.dart';
import '../../../../../core/system/filesystem/file.dart';
import '../../../../../core/system/filesystem/filesystem.dart';
class SettingsSystemBackupRestoreRestoreTile extends StatelessWidget { class SettingsSystemBackupRestoreRestoreTile extends StatelessWidget {
const SettingsSystemBackupRestoreRestoreTile({ const SettingsSystemBackupRestoreRestoreTile({
Key? key, Key? key,

View File

@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/settings.dart'; import 'package:lunasea/modules/settings.dart';
import '../../../../core/system/filesystem/filesystem.dart';
class SettingsSystemLogsRouter extends SettingsPageRouter { class SettingsSystemLogsRouter extends SettingsPageRouter {
SettingsSystemLogsRouter() : super('/settings/logs'); SettingsSystemLogsRouter() : super('/settings/logs');

View File

@@ -1,4 +1,3 @@
import 'dart:async';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/sonarr.dart'; import 'package:lunasea/modules/sonarr.dart';

View File

@@ -1,4 +1,3 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/sonarr.dart'; import 'package:lunasea/modules/sonarr.dart';

View File

@@ -1,4 +1,3 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/sonarr.dart'; import 'package:lunasea/modules/sonarr.dart';

View File

@@ -1,5 +1,3 @@
import 'dart:async';
import 'package:collection/collection.dart' show IterableExtension; import 'package:collection/collection.dart' show IterableExtension;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';

View File

@@ -1,4 +1,3 @@
import 'dart:async';
import 'package:lunasea/core.dart'; import 'package:lunasea/core.dart';
import 'package:lunasea/modules/tautulli.dart'; import 'package:lunasea/modules/tautulli.dart';

View File

@@ -1,10 +0,0 @@
import './platform/wake_on_lan_stub.dart'
if (dart.library.io) './platform/wake_on_lan_io.dart'
if (dart.library.html) './platform/wake_on_lan_web.dart';
abstract class LunaWakeOnLAN {
static bool get isSupported => isPlatformSupported();
factory LunaWakeOnLAN() => getWakeOnLAN();
Future<void> wake();
}

View File

@@ -1,4 +1,4 @@
import '../api.dart'; import '../wake_on_lan.dart';
bool isPlatformSupported() => false; bool isPlatformSupported() => false;
LunaWakeOnLAN getWakeOnLAN() => LunaWakeOnLAN getWakeOnLAN() =>

View File

@@ -4,12 +4,12 @@ import '../../../../core/models/configuration/profile.dart';
import '../../../../core/system/profile.dart'; import '../../../../core/system/profile.dart';
import '../../../../core/ui.dart'; import '../../../../core/ui.dart';
import '../../../../core/utilities/logger.dart'; import '../../../../core/utilities/logger.dart';
import '../api.dart'; import '../wake_on_lan.dart';
bool isPlatformSupported() => true; bool isPlatformSupported() => true;
LunaWakeOnLAN getWakeOnLAN() => API(); LunaWakeOnLAN getWakeOnLAN() => IO();
class API implements LunaWakeOnLAN { class IO implements LunaWakeOnLAN {
@override @override
Future<void> wake() async { Future<void> wake() async {
ProfileHiveObject profile = LunaProfile.current; ProfileHiveObject profile = LunaProfile.current;

View File

@@ -1,4 +1,4 @@
import '../api.dart'; import '../wake_on_lan.dart';
bool isPlatformSupported() => false; bool isPlatformSupported() => false;
LunaWakeOnLAN getWakeOnLAN() => LunaWakeOnLAN getWakeOnLAN() =>

View File

@@ -0,0 +1,10 @@
import 'platform/wake_on_lan_stub.dart'
if (dart.library.io) 'platform/wake_on_lan_io.dart'
if (dart.library.html) 'platform/wake_on_lan_html.dart';
abstract class LunaWakeOnLAN {
static bool get isSupported => isPlatformSupported();
factory LunaWakeOnLAN() => getWakeOnLAN();
Future<void> wake();
}

View File

@@ -1,8 +1,9 @@
// Dart // Dart
export 'dart:async';
export 'dart:convert'; export 'dart:convert';
export 'dart:math'; export 'dart:math';
export 'dart:typed_data';
// Packages // Packages
export 'package:cached_network_image/cached_network_image.dart';
export 'package:dio/dio.dart'; export 'package:dio/dio.dart';
export 'package:easy_localization/easy_localization.dart'; export 'package:easy_localization/easy_localization.dart';
export 'package:expandable/expandable.dart'; export 'package:expandable/expandable.dart';
@@ -15,6 +16,7 @@ export 'package:hive_flutter/hive_flutter.dart';
export 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; export 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
export 'package:json_annotation/json_annotation.dart'; export 'package:json_annotation/json_annotation.dart';
export 'package:layout/layout.dart'; export 'package:layout/layout.dart';
export 'package:package_info_plus/package_info_plus.dart';
export 'package:provider/provider.dart'; export 'package:provider/provider.dart';
export 'package:simple_gesture_detector/simple_gesture_detector.dart'; export 'package:simple_gesture_detector/simple_gesture_detector.dart';
export 'package:stash/stash_api.dart'; export 'package:stash/stash_api.dart';