diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b8f505c..4f3ae243 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # LunaSea Changelog +## v5.0.0 (50000011) + +#### NEW +- `[Radarr/Add]` Tags set when adding a movie are now stored in the database +- `[Radarr/Overview]` Add a link to the movie's Trakt page +- `[Settings]` Added a link to the Weblate localization page +- `[Settings]` Added language switcher (currently only English, but preparing for WIP localization support) +- `[Sonarr/Add]` Tags set when adding a series are now stored in the database +- `[Sonarr/Overview]` Add a link to the series' Trakt page + +#### TWEAKS +- `[Branding/TMDB]` Updated the logo to The Movie Database's new logo +- `[Logging/Tracking]` Switched from Sentry to Firebase Crashlytics +- `[Radarr/Overview]` Move the links underneath the description to more closely match the layout of the web GUI +- `[Search]` Switched to a new package to parse XML responses +- `[Settings/Tracking]` Adjusted the dialog and warn users that a reboot of the application is required to set tracking state +- `[Sonarr/Overview]` Move the links underneath the description to more closely match the layout of the web GUI +- `[DateTime]` Show "Just Now" when time differences are less than 10 seconds + +#### FIXES +- `[Branding]` Normalize size of all branded logos to have the same widths for consistency +- `[Flutter]` Fully move to Flutter v2 +- `[Flutter]` Upgrade many packages to NNBD +- `[Radarr/Add]` Grey screen could potentially be shown if no initial search query is passed to the route +- `[Radarr/Add]` The navigation bar could jitter on first load in some cases +- `[Radarr/Catalogue]` The search query would not stay active between profile switches +- `[Radarr/Sorting]` Changing the releases sorting/filtering method could throw an error + +--- + ## v5.0.0 (50000010) #### NEW diff --git a/README.md b/README.md index 5e7089cf..925527ab 100644 --- a/README.md +++ b/README.md @@ -51,3 +51,4 @@ LunaSea even comes with support for multiple instances of applications using pro - [Gitbook](https://www.gitbook.com): Gitbook is used to host LunaSea's documentation - [Hellonext](https://www.hellonext.co): Hellonext is used to host LunaSea's feedback, changelog, and roadmap +- [Weblate](https://hosted.weblate.org/engage/lunasea): Weblate is used to gather community localization for LunaSea diff --git a/android/app/build.gradle b/android/app/build.gradle index 1db81ab9..bd7f5d03 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -24,6 +24,7 @@ if (flutterVersionName == null) { apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'com.google.gms.google-services' +apply plugin: 'com.google.firebase.crashlytics' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" def keystoreProperties = new Properties() diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 16c60076..db30c7ac 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -13,6 +13,9 @@ + 7.3.0) - Firebase/CoreOnly (7.3.0): - FirebaseCore (= 7.3.0) + - Firebase/Crashlytics (7.3.0): + - Firebase/CoreOnly + - FirebaseCrashlytics (~> 7.3.0) - Firebase/Firestore (7.3.0): - Firebase/CoreOnly - FirebaseFirestore (~> 7.3.0) @@ -54,18 +57,21 @@ PODS: - Firebase/Storage (7.3.0): - Firebase/CoreOnly - FirebaseStorage (~> 7.3.0) - - firebase_auth (0.20.1): + - firebase_auth (1.0.0): - Firebase/Auth (= 7.3.0) - firebase_core - Flutter - - firebase_core (0.7.0): + - firebase_core (1.0.0): - Firebase/CoreOnly (= 7.3.0) - Flutter - - firebase_messaging (8.0.0-dev.15): + - firebase_crashlytics (1.0.0): + - Firebase/Crashlytics (= 7.3.0) + - firebase_core + - firebase_messaging (9.0.0): - Firebase/Messaging (= 7.3.0) - firebase_core - Flutter - - firebase_storage (7.0.0): + - firebase_storage (8.0.0): - Firebase/Storage (= 7.3.0) - firebase_core - Flutter @@ -78,18 +84,24 @@ PODS: - FirebaseCoreDiagnostics (~> 7.0) - GoogleUtilities/Environment (~> 7.0) - GoogleUtilities/Logger (~> 7.0) - - FirebaseCoreDiagnostics (7.6.0): + - FirebaseCoreDiagnostics (7.3.0): - GoogleDataTransport (~> 8.0) - GoogleUtilities/Environment (~> 7.0) - GoogleUtilities/Logger (~> 7.0) - - nanopb (~> 2.30907.0) + - nanopb (~> 2.30906.0) + - FirebaseCrashlytics (7.3.0): + - FirebaseCore (~> 7.0) + - FirebaseInstallations (~> 7.0) + - GoogleDataTransport (~> 8.0) + - nanopb (~> 2.30906.0) + - PromisesObjC (~> 1.2) - FirebaseFirestore (7.3.0) - - FirebaseInstallations (7.6.0): + - FirebaseInstallations (7.7.0): - FirebaseCore (~> 7.0) - GoogleUtilities/Environment (~> 7.0) - GoogleUtilities/UserDefaults (~> 7.0) - PromisesObjC (~> 1.2) - - FirebaseInstanceID (7.6.0): + - FirebaseInstanceID (7.7.0): - FirebaseCore (~> 7.0) - FirebaseInstallations (~> 7.0) - GoogleUtilities/Environment (~> 7.0) @@ -105,8 +117,8 @@ PODS: - FirebaseCore (~> 7.0) - GTMSessionFetcher/Core (~> 1.4) - Flutter (1.0.0) - - GoogleDataTransport (8.2.0): - - nanopb (~> 2.30907.0) + - GoogleDataTransport (8.1.0): + - nanopb (~> 2.30906.0) - GoogleUtilities/AppDelegateSwizzler (7.2.2): - GoogleUtilities/Environment - GoogleUtilities/Logger @@ -127,19 +139,17 @@ PODS: - GTMSessionFetcher/Core (1.5.0) - in_app_purchase (0.0.1): - Flutter - - nanopb (2.30907.0): - - nanopb/decode (= 2.30907.0) - - nanopb/encode (= 2.30907.0) - - nanopb/decode (2.30907.0) - - nanopb/encode (2.30907.0) + - nanopb (2.30906.0): + - nanopb/decode (= 2.30906.0) + - nanopb/encode (= 2.30906.0) + - nanopb/decode (2.30906.0) + - nanopb/encode (2.30906.0) - network_info_plus (0.0.1): - Flutter - package_info (0.0.1): - Flutter - path_provider (0.0.1): - Flutter - - "permission_handler (5.1.0+2)": - - Flutter - PromisesObjC (1.2.12) - quick_actions (0.0.1): - Flutter @@ -147,14 +157,10 @@ PODS: - SDWebImage (5.10.4): - SDWebImage/Core (= 5.10.4) - SDWebImage/Core (5.10.4) - - Sentry (6.1.4): - - Sentry/Core (= 6.1.4) - - Sentry/Core (6.1.4) - - sentry_flutter (0.0.1): - - Flutter - - Sentry (~> 6.1.4) - share_plus (0.0.1): - Flutter + - shared_preferences (0.0.1): + - Flutter - SwiftyGif (5.4.0) - url_launcher (0.0.1): - Flutter @@ -166,6 +172,7 @@ DEPENDENCIES: - Firebase/Messaging - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`) + - firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`) - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - firebase_storage (from `.symlinks/plugins/firebase_storage/ios`) - FirebaseFirestore (from `https://github.com/invertase/firestore-ios-sdk-frameworks.git`, tag `7.3.0`) @@ -174,10 +181,9 @@ DEPENDENCIES: - network_info_plus (from `.symlinks/plugins/network_info_plus/ios`) - package_info (from `.symlinks/plugins/package_info/ios`) - path_provider (from `.symlinks/plugins/path_provider/ios`) - - permission_handler (from `.symlinks/plugins/permission_handler/ios`) - quick_actions (from `.symlinks/plugins/quick_actions/ios`) - - sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) + - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - url_launcher (from `.symlinks/plugins/url_launcher/ios`) SPEC REPOS: @@ -188,6 +194,7 @@ SPEC REPOS: - FirebaseAuth - FirebaseCore - FirebaseCoreDiagnostics + - FirebaseCrashlytics - FirebaseInstallations - FirebaseInstanceID - FirebaseMessaging @@ -199,7 +206,6 @@ SPEC REPOS: - PromisesObjC - Reachability - SDWebImage - - Sentry - SwiftyGif EXTERNAL SOURCES: @@ -213,6 +219,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/firebase_auth/ios" firebase_core: :path: ".symlinks/plugins/firebase_core/ios" + firebase_crashlytics: + :path: ".symlinks/plugins/firebase_crashlytics/ios" firebase_messaging: :path: ".symlinks/plugins/firebase_messaging/ios" firebase_storage: @@ -230,14 +238,12 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/package_info/ios" path_provider: :path: ".symlinks/plugins/path_provider/ios" - permission_handler: - :path: ".symlinks/plugins/permission_handler/ios" quick_actions: :path: ".symlinks/plugins/quick_actions/ios" - sentry_flutter: - :path: ".symlinks/plugins/sentry_flutter/ios" share_plus: :path: ".symlinks/plugins/share_plus/ios" + shared_preferences: + :path: ".symlinks/plugins/shared_preferences/ios" url_launcher: :path: ".symlinks/plugins/url_launcher/ios" @@ -247,41 +253,41 @@ CHECKOUT OPTIONS: :tag: 7.3.0 SPEC CHECKSUMS: - cloud_firestore: 357b92d4778d7715d76a393db5f89e7dcc9b7401 + cloud_firestore: efd6d2bafe5147690cff2ccfbde13752a56fa281 connectivity_plus: f5e5e0b894ec1187bfab9816d6c2f034da8d46da DKImagePickerController: b5eb7f7a388e4643264105d648d01f727110fc3d DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1 Firebase: 26223c695fe322633274198cb19dca8cb7e54416 - firebase_auth: 7220e26fc14a501a63093edc10443de6bca0d7e8 - firebase_core: 91b27774a52f41f8b58484a75edf71197ac01c59 - firebase_messaging: caf0273c76e54f0a10dfe5048ac47b89e75bb78a - firebase_storage: 554b8ce9192bfe0bd35f63da42d0d1f6ae819ccc + firebase_auth: f07f3ee03813d95157ee08ce763c649c656174b5 + firebase_core: f47224dd6a9b928b4cf0128b0d004ec9e47d4bf2 + firebase_crashlytics: a62319db93baf2bfeca8a2384af3f29e3d62b09c + firebase_messaging: fc1811236795c2313b8339c35d31295b1cd8486f + firebase_storage: a4b292db6551a64c3697c7e67cb1df524b494bb1 FirebaseAuth: c224a0cf1afa0949bd5c7bfcf154b4f5ce8ddef2 FirebaseCore: 4d3c72622ce0e2106aaa07bb4b2935ba2c370972 - FirebaseCoreDiagnostics: ee1184d51da3293335b83355aad20f537acc24cf + FirebaseCoreDiagnostics: d50e11039e5984d92c8a512be2395f13df747350 + FirebaseCrashlytics: d31325312c92e2cb2f0386d589b9aa44e303d99b FirebaseFirestore: 46e32f479aac127e742b1cf873930f7bb43e7b45 - FirebaseInstallations: 6e4e77396559bc2ae0504823837ed737b1c7e47f - FirebaseInstanceID: cf243611700eddc916b093353adbd4da822cfa63 + FirebaseInstallations: 42c86e7b02ff75b7f27f85833bf5dcb5f38a9774 + FirebaseInstanceID: cf940324a20ac14a27ad1e931d15ac9d335526db FirebaseMessaging: 68d1bcb14880189558a8ae57167abe0b7e417232 FirebaseStorage: 5002b1895bfe74a5ce92ad54f966e6162d0da2e5 Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c - GoogleDataTransport: 1024b1a4dfbd7a0e92cb20d7e0a6f1fb66b449a4 + GoogleDataTransport: 116c84c4bdeb76be2a7a46de51244368f9794eab GoogleUtilities: 31c5b01f978a70c6cff2afc6272b3f1921614b43 GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52 in_app_purchase: 3e2155afa9d03d4fa32d9e62d567885080ce97d6 - nanopb: 59221d7f958fb711001e6a449489542d92ae113e + nanopb: 1bf24dd71191072e120b83dd02d08f3da0d65e53 network_info_plus: b78876159360f5580608c2cea620d6ceffabd0ad package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c - permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97 quick_actions: 6cb2390c4dab0e737c94573c27e18d9666710720 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 SDWebImage: c666b97e1fa9c64b4909816a903322018f0a9c84 - Sentry: 9d055e2de30a77685e86b219acf02e59b82091fc - sentry_flutter: 8b2b2e1c0101ef562106b5d272d3c0c741512c01 share_plus: 2e6276f752c279a84cd68a9fc27dfbbe2a74b072 + shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d SwiftyGif: 5d4af95df24caf1c570dbbcb32a3b8a0763bc6d7 url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 4a416e4b..f825c68d 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,13 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 2A9501F70E4ADE3B795C4BD7 /* Pods_ImageNotification.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8B58106185CA1FE7B7C6832 /* Pods_ImageNotification.framework */; }; - 3355779EEB7C12DC262232AF /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5A8F6AE14D184A58D8A7331 /* Pods_Runner.framework */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; @@ -19,6 +17,8 @@ 9C5DBBF2257EB50400836D8D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9C5DBBF1257EB50400836D8D /* GoogleService-Info.plist */; }; 9C7092B325E77E470056AE0B /* NotificationService.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7092B225E77E470056AE0B /* NotificationService.m */; }; 9C7092B725E77E470056AE0B /* ImageNotification.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 9C7092AF25E77E470056AE0B /* ImageNotification.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + DDC17BDC4C5044EAC4528466 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FD90D1B5F59BF35333F5918 /* Pods_Runner.framework */; }; + F9367914379E317C1CA4A461 /* Pods_ImageNotification.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F1A8C9DEAECA3D6663706E77 /* Pods_ImageNotification.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -56,13 +56,19 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 06B283DCF068808AD480D95A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 30F261257F9F405626922227 /* Pods-ImageNotification.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ImageNotification.debug.xcconfig"; path = "Target Support Files/Pods-ImageNotification/Pods-ImageNotification.debug.xcconfig"; sourceTree = ""; }; + 3392DF551C1BF6D77A2B3208 /* Pods-ImageNotification.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ImageNotification.release.xcconfig"; path = "Target Support Files/Pods-ImageNotification/Pods-ImageNotification.release.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 688E21D2AFE08631A83E52E2 /* Pods-ImageNotification.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ImageNotification.profile.xcconfig"; path = "Target Support Files/Pods-ImageNotification/Pods-ImageNotification.profile.xcconfig"; sourceTree = ""; }; + 713F55F4545D00C46010F8E5 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7EF2984A57FD1E0C98A7277A /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 7FD90D1B5F59BF35333F5918 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 805E3FD8D2123AFBFB3413E4 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -79,13 +85,7 @@ 9C7092B125E77E470056AE0B /* NotificationService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationService.h; sourceTree = ""; }; 9C7092B225E77E470056AE0B /* NotificationService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationService.m; sourceTree = ""; }; 9C7092B425E77E470056AE0B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9C9E2734C6D4DC2FF1815F04 /* Pods-ImageNotification.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ImageNotification.debug.xcconfig"; path = "Target Support Files/Pods-ImageNotification/Pods-ImageNotification.debug.xcconfig"; sourceTree = ""; }; - A046209115F73D5EC348E242 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - D5A8F6AE14D184A58D8A7331 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - DBA43D9DEB26304D56B42917 /* Pods-ImageNotification.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ImageNotification.profile.xcconfig"; path = "Target Support Files/Pods-ImageNotification/Pods-ImageNotification.profile.xcconfig"; sourceTree = ""; }; - E2F8912DE8B8A6F72277E96C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - E8B58106185CA1FE7B7C6832 /* Pods_ImageNotification.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ImageNotification.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - FAED45593175690B5B62C40E /* Pods-ImageNotification.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ImageNotification.release.xcconfig"; path = "Target Support Files/Pods-ImageNotification/Pods-ImageNotification.release.xcconfig"; sourceTree = ""; }; + F1A8C9DEAECA3D6663706E77 /* Pods_ImageNotification.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ImageNotification.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -94,7 +94,7 @@ buildActionMask = 2147483647; files = ( 9C2991242453FE3100B93AB2 /* StoreKit.framework in Frameworks */, - 3355779EEB7C12DC262232AF /* Pods_Runner.framework in Frameworks */, + DDC17BDC4C5044EAC4528466 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -102,7 +102,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2A9501F70E4ADE3B795C4BD7 /* Pods_ImageNotification.framework in Frameworks */, + F9367914379E317C1CA4A461 /* Pods_ImageNotification.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -182,8 +182,8 @@ isa = PBXGroup; children = ( 9C2991232453FE3100B93AB2 /* StoreKit.framework */, - D5A8F6AE14D184A58D8A7331 /* Pods_Runner.framework */, - E8B58106185CA1FE7B7C6832 /* Pods_ImageNotification.framework */, + F1A8C9DEAECA3D6663706E77 /* Pods_ImageNotification.framework */, + 7FD90D1B5F59BF35333F5918 /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = ""; @@ -191,12 +191,12 @@ F5D05D221249C73674C5DB0D /* Pods */ = { isa = PBXGroup; children = ( - E2F8912DE8B8A6F72277E96C /* Pods-Runner.debug.xcconfig */, - 7EF2984A57FD1E0C98A7277A /* Pods-Runner.release.xcconfig */, - A046209115F73D5EC348E242 /* Pods-Runner.profile.xcconfig */, - 9C9E2734C6D4DC2FF1815F04 /* Pods-ImageNotification.debug.xcconfig */, - FAED45593175690B5B62C40E /* Pods-ImageNotification.release.xcconfig */, - DBA43D9DEB26304D56B42917 /* Pods-ImageNotification.profile.xcconfig */, + 30F261257F9F405626922227 /* Pods-ImageNotification.debug.xcconfig */, + 3392DF551C1BF6D77A2B3208 /* Pods-ImageNotification.release.xcconfig */, + 688E21D2AFE08631A83E52E2 /* Pods-ImageNotification.profile.xcconfig */, + 06B283DCF068808AD480D95A /* Pods-Runner.debug.xcconfig */, + 713F55F4545D00C46010F8E5 /* Pods-Runner.release.xcconfig */, + 805E3FD8D2123AFBFB3413E4 /* Pods-Runner.profile.xcconfig */, ); path = Pods; sourceTree = ""; @@ -208,16 +208,17 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - A453887CF430C3DC2D462993 /* [CP] Check Pods Manifest.lock */, + C5D0533ADA1E3EA4004D7DAE /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - FB187DB152E6AC8A61142056 /* [CP] Embed Pods Frameworks */, - 3BA7760032A55E21F5FE79FC /* [CP] Copy Pods Resources */, 9C7092B825E77E470056AE0B /* Embed App Extensions */, + 9CF1F8FD25F2A02100D93ED1 /* Firebase Crashlytics */, + E436C3831B5DC5C13E209B54 /* [CP] Embed Pods Frameworks */, + 36A81FE406DC4A67407ADCD2 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -233,7 +234,7 @@ isa = PBXNativeTarget; buildConfigurationList = 9C7092BC25E77E470056AE0B /* Build configuration list for PBXNativeTarget "ImageNotification" */; buildPhases = ( - BBE8B4F04EBFF199FEB18CC2 /* [CP] Check Pods Manifest.lock */, + 6236732558BE076D98ED487B /* [CP] Check Pods Manifest.lock */, 9C7092AB25E77E470056AE0B /* Sources */, 9C7092AC25E77E470056AE0B /* Frameworks */, 9C7092AD25E77E470056AE0B /* Resources */, @@ -312,21 +313,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 3BA7760032A55E21F5FE79FC /* [CP] Copy Pods Resources */ = { + 36A81FE406DC4A67407ADCD2 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -344,43 +331,21 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 9740EEB61CF901F6004384FC /* Run Script */ = { + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Run Script"; + name = "Thin Binary"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - A453887CF430C3DC2D462993 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - BBE8B4F04EBFF199FEB18CC2 /* [CP] Check Pods Manifest.lock */ = { + 6236732558BE076D98ED487B /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -402,7 +367,63 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - FB187DB152E6AC8A61142056 /* [CP] Embed Pods Frameworks */ = { + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + 9CF1F8FD25F2A02100D93ED1 /* Firebase Crashlytics */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)", + ); + name = "Firebase Crashlytics"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "${PODS_ROOT}/FirebaseCrashlytics/run\n"; + }; + C5D0533ADA1E3EA4004D7DAE /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + E436C3831B5DC5C13E209B54 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -414,6 +435,7 @@ "${BUILT_PRODUCTS_DIR}/FirebaseAuth/FirebaseAuth.framework", "${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework", "${BUILT_PRODUCTS_DIR}/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseCrashlytics/FirebaseCrashlytics.framework", "${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework", "${BUILT_PRODUCTS_DIR}/FirebaseInstanceID/FirebaseInstanceID.framework", "${BUILT_PRODUCTS_DIR}/FirebaseMessaging/FirebaseMessaging.framework", @@ -424,7 +446,6 @@ "${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework", "${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework", "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", - "${BUILT_PRODUCTS_DIR}/Sentry/Sentry.framework", "${BUILT_PRODUCTS_DIR}/SwiftyGif/SwiftyGif.framework", "${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework", "${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework", @@ -434,8 +455,8 @@ "${BUILT_PRODUCTS_DIR}/package_info/package_info.framework", "${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework", "${BUILT_PRODUCTS_DIR}/quick_actions/quick_actions.framework", - "${BUILT_PRODUCTS_DIR}/sentry_flutter/sentry_flutter.framework", "${BUILT_PRODUCTS_DIR}/share_plus/share_plus.framework", + "${BUILT_PRODUCTS_DIR}/shared_preferences/shared_preferences.framework", "${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework", ); name = "[CP] Embed Pods Frameworks"; @@ -445,6 +466,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseAuth.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreDiagnostics.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCrashlytics.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstanceID.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseMessaging.framework", @@ -455,7 +477,6 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sentry.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyGif.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework", @@ -465,8 +486,8 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/quick_actions.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sentry_flutter.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share_plus.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework", ); runOnlyForDeploymentPostprocessing = 0; @@ -592,7 +613,10 @@ ); INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", @@ -706,7 +730,8 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -730,7 +755,10 @@ ); INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", @@ -763,7 +791,10 @@ ); INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", @@ -794,7 +825,11 @@ GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ImageNotification/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.4; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = app.lunasea.lunasea.ImageNotification; @@ -822,7 +857,11 @@ GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ImageNotification/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.4; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = app.lunasea.lunasea.ImageNotification; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -849,7 +888,11 @@ GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ImageNotification/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.4; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = app.lunasea.lunasea.ImageNotification; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index c6ca70e4..a0031e8a 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -74,5 +74,7 @@ UIViewControllerBasedStatusBarAppearance + FirebaseCrashlyticsCollectionEnabled + diff --git a/lib/core.dart b/lib/core.dart index 31aa35c8..204a5f89 100644 --- a/lib/core.dart +++ b/lib/core.dart @@ -1,8 +1,8 @@ export 'core/constants.dart'; export 'core/database.dart'; +export 'core/deprecated_ui.dart'; export 'core/dialogs.dart'; export 'core/extensions.dart'; -export 'core/luna_ui.dart'; export 'core/mixins.dart'; export 'core/models.dart'; export 'core/system.dart'; @@ -10,6 +10,7 @@ export 'core/ui.dart'; export 'core/utilities.dart'; export 'core/widgets.dart'; export 'dart:async'; +export 'package:easy_localization/easy_localization.dart'; export 'package:flash/flash.dart'; export 'package:fluro/fluro.dart'; export 'package:hive/hive.dart'; diff --git a/lib/core/constants.dart b/lib/core/constants.dart index 60b15f57..66272867 100644 --- a/lib/core/constants.dart +++ b/lib/core/constants.dart @@ -1,8 +1,6 @@ class Constants { Constants._(); - static const APPLICATION_NAME = 'LunaSea'; - static const TEXT_EMDASH = '—'; static const TEXT_BULLET = '•'; static const TEXT_ELLIPSIS = '…'; @@ -18,13 +16,14 @@ class Constants { static const NO_SERVICES_ENABLED = '<>'; static const URL_CHANGELOG = 'https://feedback.lunasea.app/changelog'; + static const URL_CRASHLYTICS = 'https://firebase.google.com/products/crashlytics'; static const URL_DISCORD = 'https://www.lunasea.app/discord'; static const URL_DOCUMENTATION = 'https://www.lunasea.app/docs'; static const URL_FEEDBACK = 'https://www.lunasea.app/feedback'; static const URL_GITHUB = 'https://www.lunasea.app/github'; static const URL_REDDIT = 'https://www.lunasea.app/reddit'; - static const URL_SENTRY = 'https://sentry.io'; static const URL_TESTFLIGHT = 'https://www.lunasea.app/testflight'; + static const URL_WEBLATE = 'https:/www.lunasea.app/translate'; static const URL_WEBSITE = 'https://www.lunasea.app'; static const USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15'; diff --git a/lib/core/deprecated_ui.dart b/lib/core/deprecated_ui.dart new file mode 100644 index 00000000..e65aaad7 --- /dev/null +++ b/lib/core/deprecated_ui.dart @@ -0,0 +1,20 @@ +export 'deprecated_ui/button.dart'; +export 'deprecated_ui/card.dart'; +export 'deprecated_ui/containers.dart'; +export 'deprecated_ui/description_block.dart'; +export 'deprecated_ui/dialogs.dart'; +export 'deprecated_ui/divider.dart'; +export 'deprecated_ui/expandable.dart'; +export 'deprecated_ui/floating_action_button.dart'; +export 'deprecated_ui/icon.dart'; +export 'deprecated_ui/input_bar.dart'; +export 'deprecated_ui/listview.dart'; +export 'deprecated_ui/loader.dart'; +export 'deprecated_ui/messages.dart'; +export 'deprecated_ui/navigation_bar.dart'; +export 'deprecated_ui/network_image.dart'; +export 'deprecated_ui/refresh_indicator.dart'; +export 'deprecated_ui/shape.dart'; +export 'deprecated_ui/snackbar.dart'; +export 'deprecated_ui/table.dart'; +export 'deprecated_ui/text.dart'; diff --git a/lib/core/deprecated_ui/button.dart b/lib/core/deprecated_ui/button.dart new file mode 100644 index 00000000..f4f488d7 --- /dev/null +++ b/lib/core/deprecated_ui/button.dart @@ -0,0 +1,2 @@ +export 'button/button.dart'; +export 'button/button_slim.dart'; diff --git a/lib/core/ui/button/button.dart b/lib/core/deprecated_ui/button/button.dart similarity index 100% rename from lib/core/ui/button/button.dart rename to lib/core/deprecated_ui/button/button.dart diff --git a/lib/core/ui/button/button_slim.dart b/lib/core/deprecated_ui/button/button_slim.dart similarity index 100% rename from lib/core/ui/button/button_slim.dart rename to lib/core/deprecated_ui/button/button_slim.dart diff --git a/lib/core/deprecated_ui/card.dart b/lib/core/deprecated_ui/card.dart new file mode 100644 index 00000000..9502976c --- /dev/null +++ b/lib/core/deprecated_ui/card.dart @@ -0,0 +1,2 @@ +export 'card/card.dart'; +export 'card/card_tile.dart'; diff --git a/lib/core/ui/card/card.dart b/lib/core/deprecated_ui/card/card.dart similarity index 94% rename from lib/core/ui/card/card.dart rename to lib/core/deprecated_ui/card/card.dart index ebbd89bf..fe92f045 100644 --- a/lib/core/ui/card/card.dart +++ b/lib/core/deprecated_ui/card/card.dart @@ -7,6 +7,7 @@ class LSCard extends StatelessWidget { final bool reducedMargin; final Color color; final Decoration decoration; + final double height; LSCard({ @required this.child, @@ -14,6 +15,7 @@ class LSCard extends StatelessWidget { this.reducedMargin = false, this.color, this.decoration, + this.height, }); @override @@ -26,6 +28,7 @@ class LSCard extends StatelessWidget { child: Container( child: child, decoration: decoration, + height: height, ), elevation: LunaUI.ELEVATION, margin: reducedMargin diff --git a/lib/core/ui/card/card_tile.dart b/lib/core/deprecated_ui/card/card_tile.dart similarity index 100% rename from lib/core/ui/card/card_tile.dart rename to lib/core/deprecated_ui/card/card_tile.dart diff --git a/lib/core/deprecated_ui/containers.dart b/lib/core/deprecated_ui/containers.dart new file mode 100644 index 00000000..f4b62f99 --- /dev/null +++ b/lib/core/deprecated_ui/containers.dart @@ -0,0 +1 @@ +export 'containers/row.dart'; diff --git a/lib/core/ui/containers/row.dart b/lib/core/deprecated_ui/containers/row.dart similarity index 100% rename from lib/core/ui/containers/row.dart rename to lib/core/deprecated_ui/containers/row.dart diff --git a/lib/core/ui/description_block.dart b/lib/core/deprecated_ui/description_block.dart similarity index 100% rename from lib/core/ui/description_block.dart rename to lib/core/deprecated_ui/description_block.dart diff --git a/lib/core/ui/dialogs.dart b/lib/core/deprecated_ui/dialogs.dart similarity index 100% rename from lib/core/ui/dialogs.dart rename to lib/core/deprecated_ui/dialogs.dart diff --git a/lib/core/luna_ui/divider.dart b/lib/core/deprecated_ui/divider.dart similarity index 64% rename from lib/core/luna_ui/divider.dart rename to lib/core/deprecated_ui/divider.dart index 17331404..8789f3e3 100644 --- a/lib/core/luna_ui/divider.dart +++ b/lib/core/deprecated_ui/divider.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; import 'package:lunasea/core.dart'; -class LunaDivider extends Divider { - LunaDivider() : super( +class LSDivider extends StatelessWidget { + @override + Widget build(BuildContext context) => Divider( thickness: 1.0, color: LunaColours.splash, indent: 60.0, diff --git a/lib/core/ui/expandable.dart b/lib/core/deprecated_ui/expandable.dart similarity index 100% rename from lib/core/ui/expandable.dart rename to lib/core/deprecated_ui/expandable.dart diff --git a/lib/core/ui/floating_action_button.dart b/lib/core/deprecated_ui/floating_action_button.dart similarity index 100% rename from lib/core/ui/floating_action_button.dart rename to lib/core/deprecated_ui/floating_action_button.dart diff --git a/lib/core/ui/floating_action_button/floating_action_button.dart b/lib/core/deprecated_ui/floating_action_button/floating_action_button.dart similarity index 100% rename from lib/core/ui/floating_action_button/floating_action_button.dart rename to lib/core/deprecated_ui/floating_action_button/floating_action_button.dart diff --git a/lib/core/ui/floating_action_button/floating_action_button_animated.dart b/lib/core/deprecated_ui/floating_action_button/floating_action_button_animated.dart similarity index 100% rename from lib/core/ui/floating_action_button/floating_action_button_animated.dart rename to lib/core/deprecated_ui/floating_action_button/floating_action_button_animated.dart diff --git a/lib/core/ui/floating_action_button/floating_action_button_extended.dart b/lib/core/deprecated_ui/floating_action_button/floating_action_button_extended.dart similarity index 100% rename from lib/core/ui/floating_action_button/floating_action_button_extended.dart rename to lib/core/deprecated_ui/floating_action_button/floating_action_button_extended.dart diff --git a/lib/core/ui/icon.dart b/lib/core/deprecated_ui/icon.dart similarity index 100% rename from lib/core/ui/icon.dart rename to lib/core/deprecated_ui/icon.dart diff --git a/lib/core/ui/icon/icon.dart b/lib/core/deprecated_ui/icon/icon.dart similarity index 100% rename from lib/core/ui/icon/icon.dart rename to lib/core/deprecated_ui/icon/icon.dart diff --git a/lib/core/ui/icon/icon_button.dart b/lib/core/deprecated_ui/icon/icon_button.dart similarity index 100% rename from lib/core/ui/icon/icon_button.dart rename to lib/core/deprecated_ui/icon/icon_button.dart diff --git a/lib/core/ui/icon/icon_custom.dart b/lib/core/deprecated_ui/icon/icon_custom.dart similarity index 100% rename from lib/core/ui/icon/icon_custom.dart rename to lib/core/deprecated_ui/icon/icon_custom.dart diff --git a/lib/core/luna_ui/input_bar.dart b/lib/core/deprecated_ui/input_bar.dart similarity index 87% rename from lib/core/luna_ui/input_bar.dart rename to lib/core/deprecated_ui/input_bar.dart index 5a42c3e9..741b6448 100644 --- a/lib/core/luna_ui/input_bar.dart +++ b/lib/core/deprecated_ui/input_bar.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:lunasea/core.dart'; -class LunaTextInputBar extends StatefulWidget { +class LSTextInputBar extends StatefulWidget { final TextEditingController controller; final TextInputAction action; final TextInputType keyboardType; @@ -11,12 +11,12 @@ class LunaTextInputBar extends StatefulWidget { final bool autofocus; final bool obscureText; final bool isFormField; - final void Function(String) onChanged; + final void Function(String, bool) onChanged; final void Function(String) onSubmitted; final String Function(String) validator; final EdgeInsets margin; - LunaTextInputBar({ + LSTextInputBar({ @required this.controller, this.onChanged, this.onSubmitted, @@ -30,15 +30,13 @@ class LunaTextInputBar extends StatefulWidget { this.autofocus = false, this.obscureText = false, this.isFormField = false, - }) { - assert(controller != null); - } + }); @override State createState() => _State(); } -class _State extends State { +class _State extends State { bool _isFocused = false; @override @@ -72,10 +70,7 @@ class _State extends State { color: LunaColours.accent, size: 24.0, ), - onTap: widget.onChanged == null ? null : () { - widget.controller.text = ''; - widget.onChanged(''); - } + onTap: () => widget?.onChanged('', true), ), opacity: !_isFocused || widget.controller.text == '' ? 0.0 : 1.0, duration: Duration(milliseconds: 200), @@ -103,7 +98,7 @@ class _State extends State { autocorrect: false, keyboardType: widget.keyboardType, validator: widget?.validator, - onChanged: widget.onChanged == null ? null : widget.onChanged, + onChanged: widget.onChanged == null ? null : (value) => widget.onChanged(value, false), onFieldSubmitted: widget?.onSubmitted, ); @@ -118,7 +113,7 @@ class _State extends State { obscureText: widget.obscureText, autocorrect: false, keyboardType: widget.keyboardType, - onChanged: widget.onChanged == null ? null : widget.onChanged, + onChanged: widget.onChanged == null ? null : (value) => widget.onChanged(value, false), onSubmitted: widget?.onSubmitted, ); -} +} \ No newline at end of file diff --git a/lib/core/ui/listview.dart b/lib/core/deprecated_ui/listview.dart similarity index 100% rename from lib/core/ui/listview.dart rename to lib/core/deprecated_ui/listview.dart diff --git a/lib/core/ui/listview/listview.dart b/lib/core/deprecated_ui/listview/listview.dart similarity index 100% rename from lib/core/ui/listview/listview.dart rename to lib/core/deprecated_ui/listview/listview.dart diff --git a/lib/core/ui/listview/listview_builder.dart b/lib/core/deprecated_ui/listview/listview_builder.dart similarity index 100% rename from lib/core/ui/listview/listview_builder.dart rename to lib/core/deprecated_ui/listview/listview_builder.dart diff --git a/lib/core/ui/listview/listview_reorderable.dart b/lib/core/deprecated_ui/listview/listview_reorderable.dart similarity index 100% rename from lib/core/ui/listview/listview_reorderable.dart rename to lib/core/deprecated_ui/listview/listview_reorderable.dart diff --git a/lib/core/ui/listview/listview_stickyheader.dart b/lib/core/deprecated_ui/listview/listview_stickyheader.dart similarity index 100% rename from lib/core/ui/listview/listview_stickyheader.dart rename to lib/core/deprecated_ui/listview/listview_stickyheader.dart diff --git a/lib/core/luna_ui/loader.dart b/lib/core/deprecated_ui/loader.dart similarity index 91% rename from lib/core/luna_ui/loader.dart rename to lib/core/deprecated_ui/loader.dart index fc9cc497..63d0e569 100644 --- a/lib/core/luna_ui/loader.dart +++ b/lib/core/deprecated_ui/loader.dart @@ -2,11 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:lunasea/core.dart'; -class LunaLoader extends StatelessWidget { +class LSLoader extends StatelessWidget { final double size; final Color color; - LunaLoader({ + LSLoader({ Key key, this.size = 25.0, this.color, diff --git a/lib/core/ui/messages.dart b/lib/core/deprecated_ui/messages.dart similarity index 100% rename from lib/core/ui/messages.dart rename to lib/core/deprecated_ui/messages.dart diff --git a/lib/core/ui/messages/error_message.dart b/lib/core/deprecated_ui/messages/error_message.dart similarity index 100% rename from lib/core/ui/messages/error_message.dart rename to lib/core/deprecated_ui/messages/error_message.dart diff --git a/lib/core/ui/messages/generic.dart b/lib/core/deprecated_ui/messages/generic.dart similarity index 100% rename from lib/core/ui/messages/generic.dart rename to lib/core/deprecated_ui/messages/generic.dart diff --git a/lib/core/ui/messages/not_enabled.dart b/lib/core/deprecated_ui/messages/not_enabled.dart similarity index 100% rename from lib/core/ui/messages/not_enabled.dart rename to lib/core/deprecated_ui/messages/not_enabled.dart diff --git a/lib/core/ui/messages/typewriter.dart b/lib/core/deprecated_ui/messages/typewriter.dart similarity index 100% rename from lib/core/ui/messages/typewriter.dart rename to lib/core/deprecated_ui/messages/typewriter.dart diff --git a/lib/core/ui/messages/unknown_route.dart b/lib/core/deprecated_ui/messages/unknown_route.dart similarity index 100% rename from lib/core/ui/messages/unknown_route.dart rename to lib/core/deprecated_ui/messages/unknown_route.dart diff --git a/lib/core/ui/navigation_bar.dart b/lib/core/deprecated_ui/navigation_bar.dart similarity index 100% rename from lib/core/ui/navigation_bar.dart rename to lib/core/deprecated_ui/navigation_bar.dart diff --git a/lib/core/ui/navigation_bar/navigation_bar.dart b/lib/core/deprecated_ui/navigation_bar/navigation_bar.dart similarity index 100% rename from lib/core/ui/navigation_bar/navigation_bar.dart rename to lib/core/deprecated_ui/navigation_bar/navigation_bar.dart diff --git a/lib/core/deprecated_ui/network_image.dart b/lib/core/deprecated_ui/network_image.dart new file mode 100644 index 00000000..43534516 --- /dev/null +++ b/lib/core/deprecated_ui/network_image.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; +import 'package:lunasea/core.dart'; + +// ignore: non_constant_identifier_names +Widget LSNetworkImage({ + @required double height, + @required double width, + @required String url, + @required String placeholder, + Map headers, + bool roundCorners = true, +}) => ClipRRect( + child: Container( + child: Stack( + fit: StackFit.expand, + children: [ + Image.asset(placeholder), + if(url != null) FadeInImage( + height: height, + width: width, + fadeInDuration: Duration(milliseconds: LunaUI.ANIMATION_IMAGE_FADE_IN_SPEED), + fadeOutDuration: Duration(milliseconds: 1), + placeholder: AssetImage(placeholder), + fit: BoxFit.cover, + image: NetworkImage( + url, + headers: headers, + ), + ), + ], + ), + height: height, + width: width, + ), + borderRadius: roundCorners + ? BorderRadius.circular(Constants.UI_BORDER_RADIUS) + : null, +); \ No newline at end of file diff --git a/lib/core/deprecated_ui/refresh_indicator.dart b/lib/core/deprecated_ui/refresh_indicator.dart new file mode 100644 index 00000000..a9f344ce --- /dev/null +++ b/lib/core/deprecated_ui/refresh_indicator.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; + +class LSRefreshIndicator extends StatefulWidget { + final Widget child; + final Function onRefresh; + final GlobalKey refreshKey; + + LSRefreshIndicator({ + @required this.child, + @required this.onRefresh, + @required this.refreshKey, + }); + + @override + State createState() => _State(); +} + +class _State extends State { + @override + Widget build(BuildContext context) { + return RefreshIndicator( + key: widget.refreshKey, + backgroundColor: Theme.of(context).primaryColor, + onRefresh: widget.onRefresh, + child: widget.child, + ); + } +} \ No newline at end of file diff --git a/lib/core/deprecated_ui/shape.dart b/lib/core/deprecated_ui/shape.dart new file mode 100644 index 00000000..462e6be3 --- /dev/null +++ b/lib/core/deprecated_ui/shape.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:lunasea/core.dart'; + +// ignore: non_constant_identifier_names +ShapeBorder LSRoundedShape({ + double borderRadius = Constants.UI_BORDER_RADIUS, +}) => RoundedRectangleBorder( + borderRadius: BorderRadius.circular(borderRadius), +); + +// ignore: non_constant_identifier_names +ShapeBorder LSRoundedShapeWithBorder({ + double borderRadius = Constants.UI_BORDER_RADIUS, +}) => RoundedRectangleBorder( + borderRadius: BorderRadius.circular(borderRadius), + side: BorderSide( + color: Colors.white12, + ), +); diff --git a/lib/core/deprecated_ui/snackbar.dart b/lib/core/deprecated_ui/snackbar.dart new file mode 100644 index 00000000..84285668 --- /dev/null +++ b/lib/core/deprecated_ui/snackbar.dart @@ -0,0 +1,90 @@ +import 'package:flutter/material.dart'; +import 'package:flash/flash.dart'; +import 'package:lunasea/core.dart'; + +enum SNACKBAR_TYPE { + success, + failure, + info, +} + +const _LEFT_PADDING = 8.0; + +// ignore: non_constant_identifier_names +Future LSSnackBar({ + @required BuildContext context, + @required String title, + String message = LunaLogger.CHECK_LOGS_MESSAGE, + Duration duration, + SNACKBAR_TYPE type = SNACKBAR_TYPE.info, + bool showButton = false, + String buttonText = 'view', + Function buttonOnPressed, +}) async { + if(showButton) assert(buttonOnPressed != null); + Color color; + IconData icon; + switch(type) { + case SNACKBAR_TYPE.failure: color = LunaColours.red; icon = Icons.error_outline; break; + case SNACKBAR_TYPE.success: color = LunaColours.accent; icon = Icons.check_circle_outline; break; + case SNACKBAR_TYPE.info: color = LunaColours.blue; icon = Icons.info_outline; break; + } + showFlash( + context: context, + duration: duration != null + ? duration + : showButton + ? Duration(seconds: 4) + : Duration(seconds: 2), + builder: (context, controller) => Flash( + backgroundColor: Theme.of(context).primaryColor, + controller: controller, + style: FlashStyle.floating, + boxShadows: [BoxShadow(blurRadius: 6.0, spreadRadius: 4.0, color: Colors.black.withOpacity(0.10))], + horizontalDismissDirection: HorizontalDismissDirection.horizontal, + margin: EdgeInsets.all(8.0), + borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), + borderColor: LunaDatabaseValue.THEME_AMOLED.data && LunaDatabaseValue.THEME_AMOLED_BORDER.data + ? Colors.white12 + : Colors.transparent, + child: FlashBar( + title: Text( + title, + style: TextStyle( + fontWeight: LunaUI.FONT_WEIGHT_BOLD, + fontSize: Constants.UI_FONT_SIZE_TITLE, + ), + ), + message: Text( + message, + style: TextStyle( + color: Colors.white70, + fontSize: Constants.UI_FONT_SIZE_SUBTITLE, + ), + ), + icon: Padding( + child: LSIconButton( + icon: icon, + color: color, + ), + padding: EdgeInsets.only(left: _LEFT_PADDING), + ), + primaryAction: showButton + ? TextButton( + child: Text( + buttonText.toUpperCase(), + style: TextStyle( + fontWeight: LunaUI.FONT_WEIGHT_BOLD, + color: LunaColours.accent, + ), + ), + onPressed: () { + controller.dismiss(); + buttonOnPressed(); + }, + ) + : null, + ), + ), + ); +} diff --git a/lib/core/deprecated_ui/table.dart b/lib/core/deprecated_ui/table.dart new file mode 100644 index 00000000..59e9bf2b --- /dev/null +++ b/lib/core/deprecated_ui/table.dart @@ -0,0 +1,2 @@ +export 'table/block.dart'; +export 'table/content.dart'; diff --git a/lib/core/ui/table/block.dart b/lib/core/deprecated_ui/table/block.dart similarity index 100% rename from lib/core/ui/table/block.dart rename to lib/core/deprecated_ui/table/block.dart diff --git a/lib/core/ui/table/content.dart b/lib/core/deprecated_ui/table/content.dart similarity index 100% rename from lib/core/ui/table/content.dart rename to lib/core/deprecated_ui/table/content.dart diff --git a/lib/core/deprecated_ui/text.dart b/lib/core/deprecated_ui/text.dart new file mode 100644 index 00000000..271a8863 --- /dev/null +++ b/lib/core/deprecated_ui/text.dart @@ -0,0 +1,4 @@ +export 'text/header.dart'; +export 'text/text_highlighted.dart'; +export 'text/text_title.dart'; +export 'text/text_subtitle.dart'; diff --git a/lib/core/ui/text/header.dart b/lib/core/deprecated_ui/text/header.dart similarity index 100% rename from lib/core/ui/text/header.dart rename to lib/core/deprecated_ui/text/header.dart diff --git a/lib/core/ui/text/text_highlighted.dart b/lib/core/deprecated_ui/text/text_highlighted.dart similarity index 100% rename from lib/core/ui/text/text_highlighted.dart rename to lib/core/deprecated_ui/text/text_highlighted.dart diff --git a/lib/core/ui/text/text_subtitle.dart b/lib/core/deprecated_ui/text/text_subtitle.dart similarity index 100% rename from lib/core/ui/text/text_subtitle.dart rename to lib/core/deprecated_ui/text/text_subtitle.dart diff --git a/lib/core/ui/text/text_title.dart b/lib/core/deprecated_ui/text/text_title.dart similarity index 100% rename from lib/core/ui/text/text_title.dart rename to lib/core/deprecated_ui/text/text_title.dart diff --git a/lib/core/extensions/datetime.dart b/lib/core/extensions/datetime.dart index 962661f8..aa74de07 100644 --- a/lib/core/extensions/datetime.dart +++ b/lib/core/extensions/datetime.dart @@ -13,6 +13,7 @@ extension DateTimeExtension on DateTime { String get lunaAge { if(this == null) return 'Unknown'; Duration diff = DateTime.now().toLocal().difference(this); + if(diff.inSeconds < 10) return 'Just Now'; if(diff.inDays >= 1) return '${diff.inDays} ${diff.inDays == 1 ? 'Day' : 'Days'} Ago'; if(diff.inHours >= 1) return '${diff.inHours} ${diff.inHours == 1 ? 'Hour' : 'Hours'} Ago'; if(diff.inMinutes >= 1) return '${diff.inMinutes} ${diff.inMinutes == 1 ? 'Minute' : 'Minutes'} Ago'; diff --git a/lib/core/extensions/string.dart b/lib/core/extensions/string.dart index eb28d4fa..8fd9cb1f 100644 --- a/lib/core/extensions/string.dart +++ b/lib/core/extensions/string.dart @@ -65,6 +65,12 @@ extension StringLinksExtension on String { /// Attach this string as a series ID to TheTVDB and attempt to launch it as a URL. Future lunaOpenTheTVDB() async => await _openLink('https://www.thetvdb.com/?id=$this&tab=series'); + /// Attach this string as a TVDB ID to Trakt and attempt to launch it as a URL. + Future lunaOpenTraktSeries() async => await _openLink('http://trakt.tv/search/tvdb/$this?id_type=show'); + + /// Attach this string as a TMDB ID to Trakt and attempt to launch it as a URL. + Future lunaOpenTraktMovie() async => await _openLink('https://trakt.tv/search/tmdb/$this?id_type=movie'); + /// Attach this string as a series ID to TVMaze and attempt to launch it as a URL. Future lunaOpenTVMaze() async => await _openLink('https://www.tvmaze.com/shows/$this'); } diff --git a/lib/core/luna_ui.dart b/lib/core/luna_ui.dart deleted file mode 100644 index 18e3263e..00000000 --- a/lib/core/luna_ui.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:lunasea/core.dart'; -export 'luna_ui/appbar.dart'; -export 'luna_ui/bottom_modal_sheet.dart'; -export 'luna_ui/bottom_navigation_bar.dart'; -export 'luna_ui/button.dart'; -export 'luna_ui/card.dart'; -export 'luna_ui/colors.dart'; -export 'luna_ui/containers.dart'; -export 'luna_ui/controllers.dart'; -export 'luna_ui/decoration.dart'; -export 'luna_ui/divider.dart'; -export 'luna_ui/header.dart'; -export 'luna_ui/highlighted_node.dart'; -export 'luna_ui/icons.dart'; -export 'luna_ui/input_bar.dart'; -export 'luna_ui/invalid_route.dart'; -export 'luna_ui/list_tile.dart'; -export 'luna_ui/list_view.dart'; -export 'luna_ui/loader.dart'; -export 'luna_ui/message.dart'; -export 'luna_ui/network_image.dart'; -export 'luna_ui/popup_menu_button.dart'; -export 'luna_ui/refresh_indicator.dart'; -export 'luna_ui/shape.dart'; -export 'luna_ui/sliver_sticky_header.dart'; -export 'luna_ui/snackbar.dart'; -export 'luna_ui/switch.dart'; -export 'luna_ui/table.dart'; -export 'luna_ui/text.dart'; -export 'luna_ui/theme.dart'; - -class LunaUI { - // Text Constants - static const String TEXT_ARROW_LEFT = '←'; - static const String TEXT_ARROW_RIGHT = '→'; - static const String TEXT_BULLET = '•'; - static const String TEXT_ELLIPSIS = '…'; - static const String TEXT_EMDASH = '—'; - // Font-Related - static const double FONT_SIZE_APP_BAR = 18.0; - static const double FONT_SIZE_BUTTON = 14.0; - static const double FONT_SIZE_GRAPH_LEGEND = 10.0; - static const double FONT_SIZE_HEADER = 18.0; - static const double FONT_SIZE_HIGHLIGHTED_NODE = 12.0; - static const double FONT_SIZE_MESSAGES = 16.0; - static const double FONT_SIZE_NAVIGATION_BAR = 13.0; - static const double FONT_SIZE_SUBHEADER = 12.0; - static const double FONT_SIZE_SUBTITLE = 13.0; - static const double FONT_SIZE_TITLE = 16.0; - static const FontWeight FONT_WEIGHT_BOLD = FontWeight.w600; - // UI-Related - static const int ANIMATION_SPEED = 250; - static const int ANIMATION_IMAGE_FADE_IN_SPEED = 125; - static const double BORDER_RADIUS = 10.0; - static const double ELEVATION = 0.0; - static const EdgeInsets MARGIN_CARD = const EdgeInsets.symmetric(horizontal: 12.0, vertical: 6.0); - // Border-Related - static bool get shouldUseBorder => LunaDatabaseValue.THEME_AMOLED.data && LunaDatabaseValue.THEME_AMOLED_BORDER.data; - static ShapeBorder get shapeBorder => shouldUseBorder ? LunaShapeBorder.roundedWithBorder() : LunaShapeBorder.rounded(); -} diff --git a/lib/core/luna_ui/button.dart b/lib/core/luna_ui/button.dart deleted file mode 100644 index 47d72a74..00000000 --- a/lib/core/luna_ui/button.dart +++ /dev/null @@ -1,146 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:lunasea/core.dart'; - -enum _BUTTON_SIZE { - REGULAR, - SLIM, -} - -class LunaButton extends StatelessWidget { - final Color textColor; - final Color backgroundColor; - final EdgeInsets margin; - final LunaLoadingState loadingState; - final Function onTap; - final Function onLongPress; - final String text; - final Widget child; - final _BUTTON_SIZE size; - - LunaButton._({ - Key key, - @required this.onTap, - @required this.onLongPress, - @required this.size, - @required this.text, - @required this.child, - @required this.textColor, - @required this.backgroundColor, - @required this.margin, - @required this.loadingState, - }) : super(key: key); - - /// Create a standard-sized button. - factory LunaButton({ - Key key, - @required Function onTap, - Function onLongPress, - String text = '', - Widget child, - Color textColor = Colors.white, - Color backgroundColor = LunaColours.accent, - EdgeInsets margin = const EdgeInsets.symmetric(horizontal: 6.0, vertical: 6.0), - LunaLoadingState loadingState = LunaLoadingState.INACTIVE, - }) { - return LunaButton._( - key: key, - onTap: onTap, - onLongPress: onLongPress, - text: text, - child: child, - textColor: textColor, - backgroundColor: backgroundColor, - margin: margin, - loadingState: loadingState, - size: _BUTTON_SIZE.REGULAR, - ); - } - - /// Create a slim-sized button, typically used within table blocks. - factory LunaButton.slim({ - Key key, - @required Function onTap, - Function onLongPress, - String text = '', - Widget child, - Color textColor = Colors.white, - Color backgroundColor = LunaColours.accent, - EdgeInsets margin = const EdgeInsets.symmetric(horizontal: 6.0, vertical: 6.0), - LunaLoadingState loadingState = LunaLoadingState.INACTIVE, - }) { - return LunaButton._( - key: key, - onTap: onTap, - onLongPress: onLongPress, - text: text, - child: child, - textColor: textColor, - backgroundColor: backgroundColor, - margin: margin, - loadingState: loadingState, - size: _BUTTON_SIZE.SLIM, - ); - } - - @override - Widget build(BuildContext context) { - return Row( - children: [ - Expanded( - child: Card( - child: InkWell( - child: size == _BUTTON_SIZE.REGULAR ? _regular() : _slim(), - borderRadius: BorderRadius.circular(LunaUI.BORDER_RADIUS), - onTap: () async { - HapticFeedback.lightImpact(); - if(onTap != null && loadingState != LunaLoadingState.ACTIVE) onTap(); - }, - onLongPress: () async { - HapticFeedback.heavyImpact(); - if(onLongPress != null && loadingState != LunaLoadingState.ACTIVE) onLongPress(); - }, - ), - margin: margin, - color: backgroundColor, - elevation: LunaUI.ELEVATION, - shape: LunaUI.shapeBorder, - ), - ), - ], - ); - } - - Widget _regular() { - return ListTile(title: _title()); - } - - Widget _slim() { - return Padding( - child: _title(), - padding: EdgeInsets.symmetric(vertical: 14.0), - ); - } - - Widget _title() { - if(loadingState == LunaLoadingState.ACTIVE) return LunaLoader( - color: textColor, - size: size == _BUTTON_SIZE.REGULAR ? 20.0 : 17.0, - ); - if(loadingState == LunaLoadingState.ERROR) return Icon( - Icons.error, - color: textColor, - size: size == _BUTTON_SIZE.REGULAR ? 20.0 : 17.0, - ); - if(child != null) return child; - return Text( - text, - style: TextStyle( - color: textColor, - fontWeight: LunaUI.FONT_WEIGHT_BOLD, - fontSize: LunaUI.FONT_SIZE_BUTTON, - ), - textAlign: TextAlign.center, - ); - } -} \ No newline at end of file diff --git a/lib/core/luna_ui/card.dart b/lib/core/luna_ui/card.dart deleted file mode 100644 index 3844552e..00000000 --- a/lib/core/luna_ui/card.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:lunasea/core.dart'; - -class LunaCard extends Card { - LunaCard({ - Key key, - @required BuildContext context, - @required Widget child, - EdgeInsets margin = LunaUI.MARGIN_CARD, - Color color, - Decoration decoration, - }) : super( - key: key, - child: Container(child: child, decoration: decoration), - margin: margin, - color: color == null ? Theme.of(context).primaryColor : color, - shape: LunaUI.shapeBorder, - elevation: LunaUI.ELEVATION, - clipBehavior: Clip.antiAlias, - ) { - assert(context != null); - assert(child != null); - } -} diff --git a/lib/core/luna_ui/containers.dart b/lib/core/luna_ui/containers.dart deleted file mode 100644 index d6d516d7..00000000 --- a/lib/core/luna_ui/containers.dart +++ /dev/null @@ -1 +0,0 @@ -export 'containers/button_container.dart'; diff --git a/lib/core/luna_ui/network_image.dart b/lib/core/luna_ui/network_image.dart deleted file mode 100644 index 634b8612..00000000 --- a/lib/core/luna_ui/network_image.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:lunasea/core.dart'; - -class LunaNetworkImage extends ClipRRect { - LunaNetworkImage({ - double height, - double width, - String url, - @required String placeholderAsset, - Map headers, - bool roundCorners = true, - }) : super( - child: Container( - child: Stack( - fit: StackFit.expand, - children: [ - Image.asset( - placeholderAsset, - height: height, - width: width, - ), - if(url != null && url.isNotEmpty) FadeInImage( - height: height, - width: width, - fadeInDuration: Duration(milliseconds: LunaUI.ANIMATION_IMAGE_FADE_IN_SPEED), - fadeOutDuration: Duration(milliseconds: 1), - placeholder: AssetImage(placeholderAsset), - fit: BoxFit.cover, - image: NetworkImage(url, headers: headers?.cast()), - ), - ], - ), - height: height, - width: width, - ), - borderRadius: roundCorners ? BorderRadius.circular(LunaUI.BORDER_RADIUS) : null, - ) { - // assert(height != null); - // assert(width != null); - assert(placeholderAsset != null); - } -} diff --git a/lib/core/luna_ui/refresh_indicator.dart b/lib/core/luna_ui/refresh_indicator.dart deleted file mode 100644 index af0d67c5..00000000 --- a/lib/core/luna_ui/refresh_indicator.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:flutter/material.dart'; - -class LunaRefreshIndicator extends RefreshIndicator { - LunaRefreshIndicator({ - GlobalKey key, - @required BuildContext context, - @required Future Function() onRefresh, - @required Widget child, - }) : super( - key: key, - backgroundColor: Theme.of(context).primaryColor, - onRefresh: onRefresh, - child: child, - ); -} diff --git a/lib/core/luna_ui/shape.dart b/lib/core/luna_ui/shape.dart deleted file mode 100644 index 7d369d31..00000000 --- a/lib/core/luna_ui/shape.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:lunasea/core.dart'; - -class LunaShapeBorder extends RoundedRectangleBorder { - LunaShapeBorder._internal({ - bool useBorder = false, - }) : super( - borderRadius: BorderRadius.circular(LunaUI.BORDER_RADIUS), - side: useBorder ? BorderSide(color: Colors.white12) : BorderSide.none, - ); - - factory LunaShapeBorder.rounded() => LunaShapeBorder._internal(); - factory LunaShapeBorder.roundedWithBorder() => LunaShapeBorder._internal(useBorder: true); -} diff --git a/lib/core/luna_ui/snackbar.dart b/lib/core/luna_ui/snackbar.dart deleted file mode 100644 index b4d4b8f5..00000000 --- a/lib/core/luna_ui/snackbar.dart +++ /dev/null @@ -1,4 +0,0 @@ -export 'snackbar/snackbar.dart'; -export 'snackbar/snackbar_error.dart'; -export 'snackbar/snackbar_info.dart'; -export 'snackbar/snackbar_success.dart'; diff --git a/lib/core/luna_ui/table.dart b/lib/core/luna_ui/table.dart deleted file mode 100644 index 5d4c60a9..00000000 --- a/lib/core/luna_ui/table.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'table/table_card.dart'; -export 'table/table_content.dart'; diff --git a/lib/core/luna_ui/text.dart b/lib/core/luna_ui/text.dart deleted file mode 100644 index b3bd0cb4..00000000 --- a/lib/core/luna_ui/text.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:lunasea/core.dart'; - -class LunaText extends Text { - /// Create a new [Text] widget. - LunaText({ - @required String text, - Key key, - int maxLines, - TextOverflow overflow, - bool softWrap, - TextStyle style, - TextAlign textAlign, - }) : super( - text, - key: key, - maxLines: maxLines, - overflow: overflow, - softWrap: softWrap, - style: style, - textAlign: textAlign, - ); - - /// Create a [LunaText] widget with the styling pre-assigned to be a LunaSea title. - factory LunaText.title({ - Key key, - @required String text, - int maxLines = 1, - bool softWrap = false, - TextAlign textAlign = TextAlign.start, - Color color = Colors.white, - bool darken = false, - }) => LunaText( - text: text, - key: key, - maxLines: maxLines, - overflow: TextOverflow.fade, - softWrap: softWrap, - textAlign: textAlign, - style: TextStyle( - color: darken ? color.withOpacity(0.30) : color, - fontWeight: LunaUI.FONT_WEIGHT_BOLD, - fontSize: LunaUI.FONT_SIZE_TITLE, - ), - ); - - /// Create a [LunaText] widget with the styling pre-assigned to be a LunaSea subtitle. - factory LunaText.subtitle({ - Key key, - @required String text, - int maxLines = 1, - bool softWrap = false, - TextAlign textAlign = TextAlign.start, - Color color = Colors.white70, - bool darken = false, - }) => LunaText( - key: key, - text: text, - softWrap: softWrap, - maxLines: maxLines, - textAlign: textAlign, - style: TextStyle( - color: darken ? color.withOpacity(0.30) : color, - fontSize: LunaUI.FONT_SIZE_SUBTITLE, - ), - ); -} diff --git a/lib/core/models.dart b/lib/core/models.dart index a495c030..53f40065 100644 --- a/lib/core/models.dart +++ b/lib/core/models.dart @@ -1,5 +1,5 @@ export 'models/hive_objects.dart'; +export 'models/module_state.dart'; export 'models/router.dart'; -export 'models/state.dart'; export 'models/types.dart'; export 'models/webhooks.dart'; diff --git a/lib/core/models/state/module_state.dart b/lib/core/models/module_state.dart similarity index 100% rename from lib/core/models/state/module_state.dart rename to lib/core/models/module_state.dart diff --git a/lib/core/models/state.dart b/lib/core/models/state.dart deleted file mode 100644 index 22c651f1..00000000 --- a/lib/core/models/state.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'state/module_state.dart'; -export 'state/state.dart'; diff --git a/lib/core/system.dart b/lib/core/system.dart index 8cc81e2c..de5d743c 100644 --- a/lib/core/system.dart +++ b/lib/core/system.dart @@ -1,8 +1,10 @@ export 'system/firebase.dart'; export 'system/image_cache.dart'; export 'system/in_app_purchases.dart'; +export 'system/localization.dart'; export 'system/logger.dart'; export 'system/modules.dart'; export 'system/networking.dart'; export 'system/quick_actions.dart'; export 'system/router.dart'; +export 'system/state.dart'; diff --git a/lib/core/system/firebase.dart b/lib/core/system/firebase.dart index 2b0b0877..f736b7a9 100644 --- a/lib/core/system/firebase.dart +++ b/lib/core/system/firebase.dart @@ -1,5 +1,6 @@ export 'firebase/auth.dart'; export 'firebase/core.dart'; +export 'firebase/crashlytics.dart'; export 'firebase/firestore.dart'; export 'firebase/messaging.dart'; export 'firebase/storage.dart'; diff --git a/lib/core/system/firebase/crashlytics.dart b/lib/core/system/firebase/crashlytics.dart new file mode 100644 index 00000000..5eb69de1 --- /dev/null +++ b/lib/core/system/firebase/crashlytics.dart @@ -0,0 +1,17 @@ +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; +import 'package:lunasea/core.dart'; + +class LunaFirebaseCrashlytics { + /// Returns an instance of [FirebaseCrashlytics]. + /// + /// Throws an error if [LunaFirebase.initialize] has not been called. + static FirebaseCrashlytics get instance => FirebaseCrashlytics.instance; + + /// Set the enabled state of Firebase Crashlytics. + /// + /// If `enabled` is supplied, use that value, else use [LunaDatabaseValue.ENABLED_SENTRY]. + void setEnabledState() { + bool state = LunaDatabaseValue.ENABLED_SENTRY.data; + instance.setCrashlyticsCollectionEnabled(state); + } +} diff --git a/lib/core/system/firebase/messaging.dart b/lib/core/system/firebase/messaging.dart index 4ba34a60..f279375f 100644 --- a/lib/core/system/firebase/messaging.dart +++ b/lib/core/system/firebase/messaging.dart @@ -90,7 +90,7 @@ class LunaFirebaseMessaging { if(result) { module?.handleWebhook(message.data); } else { - showLunaErrorSnackBar(title: 'Unknown Profile', message: '"$profile" does not exist in ${Constants.APPLICATION_NAME}'); + showLunaErrorSnackBar(title: 'Unknown Profile', message: '"$profile" does not exist in LunaSea'); } } } diff --git a/lib/core/system/localization.dart b/lib/core/system/localization.dart new file mode 100644 index 00000000..7c95d13a --- /dev/null +++ b/lib/core/system/localization.dart @@ -0,0 +1,81 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:lunasea/core.dart'; + +class LunaLocalization { + /// List of [LunaLanguage] values with all currently supported languages + List get supportedLanguages => LunaLanguage.values.where((lang) => lang.enabled).toList(); + + /// Returns an iterable list of [Locale] objects containing all supported & enabled locales. + Iterable get supportedLocales => supportedLanguages.map((lang) => lang.locale).toList(); + + Locale get fallbackLocale => LunaLanguage.ENGLISH.locale; + + /// Directory containing all localization files + String get fileDirectory => 'assets/localization'; + + /// Initialize the localization system. + Future initialize() async { + await EasyLocalization.ensureInitialized(); + } +} + +enum LunaLanguage { + ENGLISH, + FRENCH, + NORWEGIAN_BOKMAL, + SWEDISH, +} + +extension LunaLanguageExtension on LunaLanguage { + LunaLanguage fromLocale(Locale locale) { + if(locale.toLanguageTag() == LunaLanguage.ENGLISH.languageTag) return LunaLanguage.ENGLISH; + if(locale.toLanguageTag() == LunaLanguage.FRENCH.languageTag) return LunaLanguage.FRENCH; + if(locale.toLanguageTag() == LunaLanguage.NORWEGIAN_BOKMAL.languageTag) return LunaLanguage.NORWEGIAN_BOKMAL; + if(locale.toLanguageTag() == LunaLanguage.SWEDISH.languageTag) return LunaLanguage.SWEDISH; + return null; + } + + bool get enabled { + switch(this) { + case LunaLanguage.ENGLISH: return true; + case LunaLanguage.FRENCH: return kDebugMode; + case LunaLanguage.NORWEGIAN_BOKMAL: return kDebugMode; + case LunaLanguage.SWEDISH: return kDebugMode; + } + throw Exception('Invalid LunaLanguage'); + } + + String get name { + switch(this) { + case LunaLanguage.ENGLISH: return 'English'; + case LunaLanguage.FRENCH: return 'French'; + case LunaLanguage.NORWEGIAN_BOKMAL: return 'Norwegian (Bokmål)'; + case LunaLanguage.SWEDISH: return 'Swedish'; + } + throw Exception('Invalid LunaLanguage'); + } + + String get languageTag { + switch(this) { + case LunaLanguage.ENGLISH: return 'en'; + case LunaLanguage.FRENCH: return 'fr'; + case LunaLanguage.NORWEGIAN_BOKMAL: return 'nb-NO'; + case LunaLanguage.SWEDISH: return 'sv'; + } + throw Exception('Invalid LunaLanguage'); + } + + Locale get locale { + switch(this) { + case LunaLanguage.ENGLISH: return Locale('en'); + case LunaLanguage.FRENCH: return Locale('fr'); + case LunaLanguage.NORWEGIAN_BOKMAL: return Locale('nb', 'NO'); + case LunaLanguage.SWEDISH: return Locale('sv'); + } + throw Exception('Invalid LunaLanguage'); + } + + Future use(BuildContext context) => context.setLocale(this.locale); +} diff --git a/lib/core/system/logger.dart b/lib/core/system/logger.dart index c10b6931..04bf7b35 100644 --- a/lib/core/system/logger.dart +++ b/lib/core/system/logger.dart @@ -1,25 +1,24 @@ import 'dart:async'; import 'dart:io'; -import 'package:dio/dio.dart'; import 'package:f_logs/f_logs.dart' show FLog, DataLogType, FormatType, LogsConfig; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:lunasea/core.dart'; -import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:stack_trace/stack_trace.dart'; class LunaLogger { - static const SENTRY_DSN = 'https://511f76efcf714ecfb5ed6b26b5819bd6@o426090.ingest.sentry.io/5367513'; static const CHECK_LOGS_MESSAGE = 'Check the logs for more details'; /// Initialize the logger by setting the timestamp format and capturing errors on [FlutterError.onError]. void initialize() { + LunaFirebaseCrashlytics().setEnabledState(); LogsConfig config = FLog.getDefaultConfigurations() ..formatType = FormatType.FORMAT_SQUARE ..timestampFormat = 'MMMM dd, y - hh:mm:ss a'; FLog.applyConfigurations(config); FlutterError.onError = (FlutterErrorDetails details, { bool forceReport = false }) async { if (kDebugMode) FlutterError.dumpErrorToConsole(details, forceReport: forceReport); + LunaFirebaseCrashlytics.instance.recordFlutterError(details); Zone.current.handleUncaughtError(details.exception, details.stack); }; } @@ -40,6 +39,7 @@ class LunaLogger { /// Log a new error-level log. void error(String text, dynamic error, StackTrace stack) { + if(LunaFirebaseCrashlytics.instance.isCrashlyticsCollectionEnabled) LunaFirebaseCrashlytics.instance.recordError(error, stack); Trace _trace = stack == null ? null : Trace.from(stack); FLog.error( className: (_trace?.frames?.length ?? 0) >= 1 ? _trace.frames[1].uri.toString() ?? 'Unknown' : 'Unknown', @@ -48,15 +48,12 @@ class LunaLogger { exception: error, stacktrace: stack, dataLogType: DataLogType.DEFAULT.toString(), - ); - if(!(error is DioError) && LunaDatabaseValue.ENABLED_SENTRY.data) Sentry.captureException( - error, - stackTrace: stack, - ); + ); } /// Log a new fatal-level log. void fatal(dynamic error, StackTrace stack) { + if(LunaFirebaseCrashlytics.instance.isCrashlyticsCollectionEnabled) LunaFirebaseCrashlytics.instance.recordError(error, stack); Trace _trace = stack == null ? null : Trace.from(stack); FLog.fatal( className: (_trace?.frames?.length ?? 0) >= 1 ? _trace.frames[1].uri.toString() ?? 'Unknown' : 'Unknown', @@ -66,10 +63,6 @@ class LunaLogger { stacktrace: stack, dataLogType: DataLogType.DEFAULT.toString(), ); - if(!(error is DioError) && LunaDatabaseValue.ENABLED_SENTRY.data) Sentry.captureException( - error, - stackTrace: stack, - ); } /// Export all logs, and return the [File] object containing the log file. diff --git a/lib/core/system/modules.dart b/lib/core/system/modules.dart index bea838cb..5c585719 100644 --- a/lib/core/system/modules.dart +++ b/lib/core/system/modules.dart @@ -184,7 +184,7 @@ extension LunaModuleExtension on LunaModule { case LunaModule.NZBGET: return 'NZBGet is a binary downloader, which downloads files from Usenet based on information given in nzb-files.'; case LunaModule.RADARR: return 'Radarr is a movie collection manager for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new movies and will interface with clients and indexers to grab, sort, and rename them. It can also be configured to automatically upgrade the quality of existing files in the library when a better quality format becomes available.'; case LunaModule.SABNZBD: return 'SABnzbd is a multi-platform binary newsgroup downloader. The program works in the background and simplifies the downloading verifying and extracting of files from Usenet.'; - case LunaModule.SEARCH: return '${Constants.APPLICATION_NAME} currently supports all indexers that support the newznab protocol, including NZBHydra2.'; + case LunaModule.SEARCH: return 'LunaSea currently supports all indexers that support the newznab protocol, including NZBHydra2.'; case LunaModule.SETTINGS: return null; case LunaModule.SONARR: return 'Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new episodes of your favorite shows and will grab, sort and rename them. It can also be configured to automatically upgrade the quality of files already downloaded when a better quality format becomes available.'; case LunaModule.TAUTULLI: return 'Tautulli is an application that you can run alongside your Plex Media Server to monitor activity and track various statistics. Most importantly, these statistics include what has been watched, who watched it, when and where they watched it, and how it was watched.'; diff --git a/lib/core/models/state/state.dart b/lib/core/system/state.dart similarity index 100% rename from lib/core/models/state/state.dart rename to lib/core/system/state.dart diff --git a/lib/core/ui.dart b/lib/core/ui.dart index 72df90fb..d69d775a 100644 --- a/lib/core/ui.dart +++ b/lib/core/ui.dart @@ -1,21 +1,62 @@ +import 'package:flutter/material.dart'; +import 'package:lunasea/core.dart'; +export 'ui/appbar.dart'; +export 'ui/bottom_modal_sheet.dart'; +export 'ui/bottom_navigation_bar.dart'; export 'ui/button.dart'; export 'ui/card.dart'; +export 'ui/colors.dart'; export 'ui/containers.dart'; -export 'ui/description_block.dart'; -export 'ui/dialogs.dart'; +export 'ui/controllers.dart'; +export 'ui/decoration.dart'; export 'ui/divider.dart'; export 'ui/drawer.dart'; -export 'ui/expandable.dart'; -export 'ui/floating_action_button.dart'; -export 'ui/icon.dart'; +export 'ui/header.dart'; +export 'ui/highlighted_node.dart'; +export 'ui/icons.dart'; export 'ui/input_bar.dart'; -export 'ui/listview.dart'; +export 'ui/invalid_route.dart'; +export 'ui/list_tile.dart'; +export 'ui/list_view.dart'; export 'ui/loader.dart'; -export 'ui/messages.dart'; -export 'ui/navigation_bar.dart'; +export 'ui/message.dart'; export 'ui/network_image.dart'; +export 'ui/popup_menu_button.dart'; export 'ui/refresh_indicator.dart'; export 'ui/shape.dart'; +export 'ui/sliver_sticky_header.dart'; export 'ui/snackbar.dart'; +export 'ui/switch.dart'; export 'ui/table.dart'; export 'ui/text.dart'; +export 'ui/theme.dart'; + +class LunaUI { + // Text Constants + static const String TEXT_ARROW_LEFT = '←'; + static const String TEXT_ARROW_RIGHT = '→'; + static const String TEXT_BULLET = '•'; + static const String TEXT_ELLIPSIS = '…'; + static const String TEXT_EMDASH = '—'; + // Font-Related + static const double FONT_SIZE_APP_BAR = 18.0; + static const double FONT_SIZE_BUTTON = 14.0; + static const double FONT_SIZE_GRAPH_LEGEND = 10.0; + static const double FONT_SIZE_HEADER = 18.0; + static const double FONT_SIZE_HIGHLIGHTED_NODE = 12.0; + static const double FONT_SIZE_MESSAGES = 16.0; + static const double FONT_SIZE_NAVIGATION_BAR = 13.0; + static const double FONT_SIZE_SUBHEADER = 12.0; + static const double FONT_SIZE_SUBTITLE = 13.0; + static const double FONT_SIZE_TITLE = 16.0; + static const FontWeight FONT_WEIGHT_BOLD = FontWeight.w600; + // UI-Related + static const int ANIMATION_SPEED = 250; + static const int ANIMATION_IMAGE_FADE_IN_SPEED = 125; + static const double BORDER_RADIUS = 10.0; + static const double ELEVATION = 0.0; + static const EdgeInsets MARGIN_CARD = const EdgeInsets.symmetric(horizontal: 12.0, vertical: 6.0); + // Border-Related + static bool get shouldUseBorder => LunaDatabaseValue.THEME_AMOLED.data && LunaDatabaseValue.THEME_AMOLED_BORDER.data; + static ShapeBorder get shapeBorder => shouldUseBorder ? LunaShapeBorder.roundedWithBorder() : LunaShapeBorder.rounded(); +} diff --git a/lib/core/luna_ui/appbar.dart b/lib/core/ui/appbar.dart similarity index 100% rename from lib/core/luna_ui/appbar.dart rename to lib/core/ui/appbar.dart diff --git a/lib/core/luna_ui/bottom_modal_sheet.dart b/lib/core/ui/bottom_modal_sheet.dart similarity index 100% rename from lib/core/luna_ui/bottom_modal_sheet.dart rename to lib/core/ui/bottom_modal_sheet.dart diff --git a/lib/core/luna_ui/bottom_navigation_bar.dart b/lib/core/ui/bottom_navigation_bar.dart similarity index 100% rename from lib/core/luna_ui/bottom_navigation_bar.dart rename to lib/core/ui/bottom_navigation_bar.dart diff --git a/lib/core/luna_ui/bottom_navigation_bar/badge.dart b/lib/core/ui/bottom_navigation_bar/badge.dart similarity index 100% rename from lib/core/luna_ui/bottom_navigation_bar/badge.dart rename to lib/core/ui/bottom_navigation_bar/badge.dart diff --git a/lib/core/luna_ui/bottom_navigation_bar/bottom_navigation_bar.dart b/lib/core/ui/bottom_navigation_bar/bottom_navigation_bar.dart similarity index 100% rename from lib/core/luna_ui/bottom_navigation_bar/bottom_navigation_bar.dart rename to lib/core/ui/bottom_navigation_bar/bottom_navigation_bar.dart diff --git a/lib/core/ui/button.dart b/lib/core/ui/button.dart index f4f488d7..47d72a74 100644 --- a/lib/core/ui/button.dart +++ b/lib/core/ui/button.dart @@ -1,2 +1,146 @@ -export 'button/button.dart'; -export 'button/button_slim.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:lunasea/core.dart'; + +enum _BUTTON_SIZE { + REGULAR, + SLIM, +} + +class LunaButton extends StatelessWidget { + final Color textColor; + final Color backgroundColor; + final EdgeInsets margin; + final LunaLoadingState loadingState; + final Function onTap; + final Function onLongPress; + final String text; + final Widget child; + final _BUTTON_SIZE size; + + LunaButton._({ + Key key, + @required this.onTap, + @required this.onLongPress, + @required this.size, + @required this.text, + @required this.child, + @required this.textColor, + @required this.backgroundColor, + @required this.margin, + @required this.loadingState, + }) : super(key: key); + + /// Create a standard-sized button. + factory LunaButton({ + Key key, + @required Function onTap, + Function onLongPress, + String text = '', + Widget child, + Color textColor = Colors.white, + Color backgroundColor = LunaColours.accent, + EdgeInsets margin = const EdgeInsets.symmetric(horizontal: 6.0, vertical: 6.0), + LunaLoadingState loadingState = LunaLoadingState.INACTIVE, + }) { + return LunaButton._( + key: key, + onTap: onTap, + onLongPress: onLongPress, + text: text, + child: child, + textColor: textColor, + backgroundColor: backgroundColor, + margin: margin, + loadingState: loadingState, + size: _BUTTON_SIZE.REGULAR, + ); + } + + /// Create a slim-sized button, typically used within table blocks. + factory LunaButton.slim({ + Key key, + @required Function onTap, + Function onLongPress, + String text = '', + Widget child, + Color textColor = Colors.white, + Color backgroundColor = LunaColours.accent, + EdgeInsets margin = const EdgeInsets.symmetric(horizontal: 6.0, vertical: 6.0), + LunaLoadingState loadingState = LunaLoadingState.INACTIVE, + }) { + return LunaButton._( + key: key, + onTap: onTap, + onLongPress: onLongPress, + text: text, + child: child, + textColor: textColor, + backgroundColor: backgroundColor, + margin: margin, + loadingState: loadingState, + size: _BUTTON_SIZE.SLIM, + ); + } + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: Card( + child: InkWell( + child: size == _BUTTON_SIZE.REGULAR ? _regular() : _slim(), + borderRadius: BorderRadius.circular(LunaUI.BORDER_RADIUS), + onTap: () async { + HapticFeedback.lightImpact(); + if(onTap != null && loadingState != LunaLoadingState.ACTIVE) onTap(); + }, + onLongPress: () async { + HapticFeedback.heavyImpact(); + if(onLongPress != null && loadingState != LunaLoadingState.ACTIVE) onLongPress(); + }, + ), + margin: margin, + color: backgroundColor, + elevation: LunaUI.ELEVATION, + shape: LunaUI.shapeBorder, + ), + ), + ], + ); + } + + Widget _regular() { + return ListTile(title: _title()); + } + + Widget _slim() { + return Padding( + child: _title(), + padding: EdgeInsets.symmetric(vertical: 14.0), + ); + } + + Widget _title() { + if(loadingState == LunaLoadingState.ACTIVE) return LunaLoader( + color: textColor, + size: size == _BUTTON_SIZE.REGULAR ? 20.0 : 17.0, + ); + if(loadingState == LunaLoadingState.ERROR) return Icon( + Icons.error, + color: textColor, + size: size == _BUTTON_SIZE.REGULAR ? 20.0 : 17.0, + ); + if(child != null) return child; + return Text( + text, + style: TextStyle( + color: textColor, + fontWeight: LunaUI.FONT_WEIGHT_BOLD, + fontSize: LunaUI.FONT_SIZE_BUTTON, + ), + textAlign: TextAlign.center, + ); + } +} \ No newline at end of file diff --git a/lib/core/ui/card.dart b/lib/core/ui/card.dart index 9502976c..007952fd 100644 --- a/lib/core/ui/card.dart +++ b/lib/core/ui/card.dart @@ -1,2 +1,25 @@ -export 'card/card.dart'; -export 'card/card_tile.dart'; +import 'package:flutter/material.dart'; +import 'package:lunasea/core.dart'; + +class LunaCard extends Card { + LunaCard({ + Key key, + @required BuildContext context, + @required Widget child, + EdgeInsets margin = LunaUI.MARGIN_CARD, + Color color, + Decoration decoration, + double height, + }) : super( + key: key, + child: Container(child: child, decoration: decoration, height: height), + margin: margin, + color: color == null ? Theme.of(context).primaryColor : color, + shape: LunaUI.shapeBorder, + elevation: LunaUI.ELEVATION, + clipBehavior: Clip.antiAlias, + ) { + assert(context != null); + assert(child != null); + } +} diff --git a/lib/core/luna_ui/colors.dart b/lib/core/ui/colors.dart similarity index 100% rename from lib/core/luna_ui/colors.dart rename to lib/core/ui/colors.dart diff --git a/lib/core/ui/containers.dart b/lib/core/ui/containers.dart index f4b62f99..d6d516d7 100644 --- a/lib/core/ui/containers.dart +++ b/lib/core/ui/containers.dart @@ -1 +1 @@ -export 'containers/row.dart'; +export 'containers/button_container.dart'; diff --git a/lib/core/luna_ui/containers/button_container.dart b/lib/core/ui/containers/button_container.dart similarity index 100% rename from lib/core/luna_ui/containers/button_container.dart rename to lib/core/ui/containers/button_container.dart diff --git a/lib/core/luna_ui/controllers.dart b/lib/core/ui/controllers.dart similarity index 100% rename from lib/core/luna_ui/controllers.dart rename to lib/core/ui/controllers.dart diff --git a/lib/core/luna_ui/controllers/page_controller.dart b/lib/core/ui/controllers/page_controller.dart similarity index 94% rename from lib/core/luna_ui/controllers/page_controller.dart rename to lib/core/ui/controllers/page_controller.dart index 7f951d90..dac3619a 100644 --- a/lib/core/luna_ui/controllers/page_controller.dart +++ b/lib/core/ui/controllers/page_controller.dart @@ -7,7 +7,7 @@ class LunaPageController extends PageController { LunaPageController({ int initialPage, }) : super( - initialPage: initialPage, + initialPage: initialPage ?? 0, ) { this?.addListener(_focusListener); } diff --git a/lib/core/luna_ui/decoration.dart b/lib/core/ui/decoration.dart similarity index 100% rename from lib/core/luna_ui/decoration.dart rename to lib/core/ui/decoration.dart diff --git a/lib/core/luna_ui/decoration/card_decoration.dart b/lib/core/ui/decoration/card_decoration.dart similarity index 100% rename from lib/core/luna_ui/decoration/card_decoration.dart rename to lib/core/ui/decoration/card_decoration.dart diff --git a/lib/core/ui/divider.dart b/lib/core/ui/divider.dart index 8789f3e3..17331404 100644 --- a/lib/core/ui/divider.dart +++ b/lib/core/ui/divider.dart @@ -1,9 +1,8 @@ import 'package:flutter/material.dart'; import 'package:lunasea/core.dart'; -class LSDivider extends StatelessWidget { - @override - Widget build(BuildContext context) => Divider( +class LunaDivider extends Divider { + LunaDivider() : super( thickness: 1.0, color: LunaColours.splash, indent: 60.0, diff --git a/lib/core/ui/drawer/drawer.dart b/lib/core/ui/drawer/drawer.dart index 4d82b04a..2ceface8 100644 --- a/lib/core/ui/drawer/drawer.dart +++ b/lib/core/ui/drawer/drawer.dart @@ -2,100 +2,68 @@ import 'package:flutter/material.dart'; import 'package:lunasea/core.dart'; import 'package:lunasea/modules/wake_on_lan.dart'; -class LSDrawer extends StatelessWidget { +class LunaDrawer extends StatelessWidget { final String page; - LSDrawer({ + LunaDrawer({ @required this.page, }); @override - Widget build(BuildContext context) => ValueListenableBuilder( - valueListenable: Database.lunaSeaBox.listenable(keys: [LunaDatabaseValue.ENABLED_PROFILE.key]), - builder: (context, lunaBox, widget) { - return ValueListenableBuilder( + Widget build(BuildContext context) { + return LunaDatabaseValue.ENABLED_PROFILE.listen( + builder: (context, lunaBox, widget) => ValueListenableBuilder( valueListenable: Database.indexersBox.listenable(), - builder: (context, indexerBox, widget) { - ProfileHiveObject profile = Database.profilesBox.get(lunaBox.get(LunaDatabaseValue.ENABLED_PROFILE.key)); - return Drawer( - child: ListView( - children: _getDrawerEntries(context, profile, (indexerBox as Box).length > 0), - padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 8.0), - physics: ClampingScrollPhysics(), - ), - ); - } - ); - } - ); + builder: (context, indexerBox, widget) => Drawer( + child: ListView( + children: _getDrawerEntries(context), + padding: EdgeInsets.only(bottom: 8.0), + physics: ClampingScrollPhysics(), + ), + ), + ), + ); + } - List _getDrawerEntries(BuildContext context, ProfileHiveObject profile, bool showIndexerSearch) { + List _getDrawerEntries(BuildContext context) { + List automation = Database.currentProfileObject.enabledAutomationModules; + List clients = Database.currentProfileObject.enabledClientModules; + List monitoring = Database.currentProfileObject.enabledMonitoringModules; + bool showSearch = Database.indexersBox.length > 0; return [ - LSDrawerHeader(), - _buildEntry( - context: context, - icon: LunaModule.DASHBOARD.icon, - title: LunaModule.DASHBOARD.name, - route: LunaModule.DASHBOARD.route, + LunaDrawerHeader(), + _buildEntry(context: context, module: LunaModule.DASHBOARD), + _buildEntry(context: context, module: LunaModule.SETTINGS), + LunaDivider(), + if(showSearch) _buildEntry(context: context, module: LunaModule.SEARCH), + if(LunaModule.WAKE_ON_LAN.enabled) _buildWakeOnLAN(context), + if(automation.length != 0) ...List.generate( + automation.length, + (index) => _buildEntry(context: context, module: automation[index]), ), - _buildEntry( - context: context, - icon: LunaModule.SETTINGS.icon, - title: LunaModule.SETTINGS.name, - route: LunaModule.SETTINGS.route, + if(clients.length != 0) ...List.generate( + clients.length, + (index) => _buildEntry(context: context, module: clients[index]), ), - LSDivider(), - if(showIndexerSearch) _buildEntry( - context: context, - icon: LunaModule.SEARCH.icon, - title: LunaModule.SEARCH.name, - route: LunaModule.SEARCH.route, - ), - if(LunaModule.WAKE_ON_LAN.enabled) _buildWakeOnLAN(context: context), - ...List.generate( - Database.currentProfileObject.enabledAutomationModules.length, - (index) => _buildEntry( - context: context, - route: Database.currentProfileObject.enabledAutomationModules[index].route, - icon: Database.currentProfileObject.enabledAutomationModules[index].icon, - title: Database.currentProfileObject.enabledAutomationModules[index].name, - ), - ), - ...List.generate( - Database.currentProfileObject.enabledClientModules.length, - (index) => _buildEntry( - context: context, - route: Database.currentProfileObject.enabledClientModules[index].route, - icon: Database.currentProfileObject.enabledClientModules[index].icon, - title: Database.currentProfileObject.enabledClientModules[index].name, - ), - ), - ...List.generate( - Database.currentProfileObject.enabledMonitoringModules.length, - (index) => _buildEntry( - context: context, - route: Database.currentProfileObject.enabledMonitoringModules[index].route, - icon: Database.currentProfileObject.enabledMonitoringModules[index].icon, - title: Database.currentProfileObject.enabledMonitoringModules[index].name, - ), + if(monitoring.length != 0) ...List.generate( + monitoring.length, + (index) => _buildEntry(context: context, module: monitoring[index]), ), ]; } Widget _buildEntry({ @required BuildContext context, - @required IconData icon, - @required String title, - @required String route, + @required LunaModule module, }) { - bool currentPage = page == title.toLowerCase(); + bool currentPage = page == module.key.toLowerCase(); return ListTile( - leading: LSIcon( - icon: icon, + leading: Icon( + module.icon, color: currentPage ? LunaColours.accent : Colors.white, ), title: Text( - title, + module.name, style: TextStyle( color: currentPage ? LunaColours.accent @@ -105,17 +73,15 @@ class LSDrawer extends StatelessWidget { ), onTap: () async { Navigator.of(context).pop(); - if(!currentPage) LunaState.navigatorKey.currentState.pushNamedAndRemoveUntil(route, (Route route) => false); + if(!currentPage) module.launch(); }, contentPadding: EdgeInsets.fromLTRB(16.0, 0.0, 0.0, 0.0), ); } - Widget _buildWakeOnLAN({ - @required BuildContext context, - }) { + Widget _buildWakeOnLAN(BuildContext context) { return ListTile( - leading: LSIcon(icon: LunaModule.WAKE_ON_LAN.icon), + leading: Icon(LunaModule.WAKE_ON_LAN.icon), title: Text( LunaModule.WAKE_ON_LAN.name, style: TextStyle( @@ -124,22 +90,23 @@ class LSDrawer extends StatelessWidget { ), ), onTap: () async { - WakeOnLANAPI _api = WakeOnLANAPI.from(Database.currentProfileObject); - await _api.wake() - .then((_) => LSSnackBar( + WakeOnLANAPI api = WakeOnLANAPI.fromProfile(); + await api.wake() + .then((_) => showLunaSuccessSnackBar( context: context, title: 'Machine is Waking Up...', message: 'Magic packet successfully sent', - type: SNACKBAR_TYPE.success, )) - .catchError((_) => LSSnackBar( - context: context, - title: 'Failed to Wake Machine', - message: 'Magic packet failed to send', - type: SNACKBAR_TYPE.failure, - )); + .catchError((error, stack) { + LunaLogger().error('Failed to wake machine', error, stack); + return showLunaErrorSnackBar( + context: context, + title: 'Failed to Wake Machine', + error: error, + ); + }); }, contentPadding: EdgeInsets.fromLTRB(16.0, 0.0, 0.0, 0.0), ); } -} \ No newline at end of file +} diff --git a/lib/core/ui/drawer/drawer_header.dart b/lib/core/ui/drawer/drawer_header.dart index 02ca797c..df6a46f5 100644 --- a/lib/core/ui/drawer/drawer_header.dart +++ b/lib/core/ui/drawer/drawer_header.dart @@ -2,58 +2,58 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:lunasea/core.dart'; -// ignore: non_constant_identifier_names -Widget LSDrawerHeader() => UserAccountsDrawerHeader( - accountName: StreamBuilder( - stream: LunaFirebaseAuth.instance.authStateChanges(), - builder: (context, snapshot) => LSTitle(text: LunaFirebaseAuth().email ?? Constants.APPLICATION_NAME), - ), - accountEmail: ValueListenableBuilder( - valueListenable: Database.lunaSeaBox.listenable(keys: [LunaDatabaseValue.ENABLED_PROFILE.key]), - builder: (context, lunaBox, widget) => ValueListenableBuilder( - valueListenable: Database.profilesBox.listenable(), - builder: (context, profilesBox, widget) => Padding( - child: LunaPopupMenuButton( - tooltip: 'Change Profiles', - child: Row( - mainAxisSize: MainAxisSize.max, - children: [ - LSSubtitle( - text: LunaDatabaseValue.ENABLED_PROFILE.data, - ), - LSIcon( - icon: Icons.arrow_drop_down, - color: Colors.white70, - size: Constants.UI_FONT_SIZE_HEADER, - ), - ], - ), - onSelected: (result) { - HapticFeedback.selectionClick(); - LunaProfile().safelyChangeProfiles(result); - }, - itemBuilder: (context) { - return >[for(String profile in (profilesBox as Box).keys) PopupMenuItem( - value: profile, - child: Text( - profile, - style: TextStyle( - fontSize: Constants.UI_FONT_SIZE_SUBTITLE, +class LunaDrawerHeader extends UserAccountsDrawerHeader { + LunaDrawerHeader() : super( + accountName: StreamBuilder( + stream: LunaFirebaseAuth.instance.authStateChanges(), + builder: (context, snapshot) => LunaText.title(text: LunaFirebaseAuth().email ?? 'LunaSea'), + ), + accountEmail: LunaDatabaseValue.ENABLED_PROFILE.listen( + builder: (context, lunaBox, widget) => ValueListenableBuilder( + valueListenable: Database.profilesBox.listenable(), + builder: (context, profilesBox, widget) => Padding( + child: LunaPopupMenuButton( + tooltip: 'Change Profiles', + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + LunaText.subtitle( + text: LunaDatabaseValue.ENABLED_PROFILE.data, ), - ), - )]; - }, + Icon( + Icons.arrow_drop_down, + color: Colors.white70, + size: LunaUI.FONT_SIZE_HEADER, + ), + ], + ), + onSelected: (result) { + HapticFeedback.selectionClick(); + LunaProfile().safelyChangeProfiles(result); + }, + itemBuilder: (context) { + return >[for(String profile in (profilesBox as Box).keys) PopupMenuItem( + value: profile, + child: Text( + profile, + style: TextStyle( + fontSize: LunaUI.FONT_SIZE_SUBTITLE, + ), + ), + )]; + }, + ), + padding: EdgeInsets.only(right: 12.0), ), - padding: EdgeInsets.only(right: 12.0), ), ), - ), - decoration: BoxDecoration( - color: LunaColours.accent, - image: DecorationImage( - image: AssetImage('assets/branding/icon_drawer.png'), - colorFilter: ColorFilter.mode(LunaColours.primary.withOpacity(0.15), BlendMode.dstATop), - fit: BoxFit.cover, + decoration: BoxDecoration( + color: LunaColours.accent, + image: DecorationImage( + image: AssetImage('assets/branding/icon_drawer.png'), + colorFilter: ColorFilter.mode(LunaColours.primary.withOpacity(0.15), BlendMode.dstATop), + fit: BoxFit.cover, + ), ), - ), -); + ); +} diff --git a/lib/core/luna_ui/header.dart b/lib/core/ui/header.dart similarity index 100% rename from lib/core/luna_ui/header.dart rename to lib/core/ui/header.dart diff --git a/lib/core/luna_ui/highlighted_node.dart b/lib/core/ui/highlighted_node.dart similarity index 100% rename from lib/core/luna_ui/highlighted_node.dart rename to lib/core/ui/highlighted_node.dart diff --git a/lib/core/luna_ui/icons.dart b/lib/core/ui/icons.dart similarity index 100% rename from lib/core/luna_ui/icons.dart rename to lib/core/ui/icons.dart diff --git a/lib/core/luna_ui/icons/icon_button.dart b/lib/core/ui/icons/icon_button.dart similarity index 100% rename from lib/core/luna_ui/icons/icon_button.dart rename to lib/core/ui/icons/icon_button.dart diff --git a/lib/core/luna_ui/icons/icon_custom.dart b/lib/core/ui/icons/icon_custom.dart similarity index 100% rename from lib/core/luna_ui/icons/icon_custom.dart rename to lib/core/ui/icons/icon_custom.dart diff --git a/lib/core/ui/input_bar.dart b/lib/core/ui/input_bar.dart index 741b6448..9900809a 100644 --- a/lib/core/ui/input_bar.dart +++ b/lib/core/ui/input_bar.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:lunasea/core.dart'; -class LSTextInputBar extends StatefulWidget { +class LunaTextInputBar extends StatefulWidget { final TextEditingController controller; final TextInputAction action; final TextInputType keyboardType; @@ -11,12 +11,12 @@ class LSTextInputBar extends StatefulWidget { final bool autofocus; final bool obscureText; final bool isFormField; - final void Function(String, bool) onChanged; + final void Function(String) onChanged; final void Function(String) onSubmitted; final String Function(String) validator; final EdgeInsets margin; - LSTextInputBar({ + LunaTextInputBar({ @required this.controller, this.onChanged, this.onSubmitted, @@ -24,19 +24,21 @@ class LSTextInputBar extends StatefulWidget { this.autofillHints, this.action = TextInputAction.search, this.keyboardType = TextInputType.text, - this.labelText = 'Search...', + this.labelText, this.labelIcon = Icons.search, this.margin = LunaUI.MARGIN_CARD, this.autofocus = false, this.obscureText = false, this.isFormField = false, - }); + }) { + assert(controller != null); + } @override State createState() => _State(); } -class _State extends State { +class _State extends State { bool _isFocused = false; @override @@ -57,7 +59,7 @@ class _State extends State { ); InputDecoration get _sharedInputDecoration => InputDecoration( - labelText: widget.labelText, + labelText: widget.labelText ?? 'lunasea.SearchTextBar'.tr(), labelStyle: TextStyle( color: Colors.white54, decoration: TextDecoration.none, @@ -70,7 +72,10 @@ class _State extends State { color: LunaColours.accent, size: 24.0, ), - onTap: () => widget?.onChanged('', true), + onTap: widget.onChanged == null ? null : () { + widget.controller.text = ''; + widget.onChanged(''); + } ), opacity: !_isFocused || widget.controller.text == '' ? 0.0 : 1.0, duration: Duration(milliseconds: 200), @@ -98,7 +103,7 @@ class _State extends State { autocorrect: false, keyboardType: widget.keyboardType, validator: widget?.validator, - onChanged: widget.onChanged == null ? null : (value) => widget.onChanged(value, false), + onChanged: widget.onChanged == null ? null : widget.onChanged, onFieldSubmitted: widget?.onSubmitted, ); @@ -113,7 +118,7 @@ class _State extends State { obscureText: widget.obscureText, autocorrect: false, keyboardType: widget.keyboardType, - onChanged: widget.onChanged == null ? null : (value) => widget.onChanged(value, false), + onChanged: widget.onChanged == null ? null : widget.onChanged, onSubmitted: widget?.onSubmitted, ); -} \ No newline at end of file +} diff --git a/lib/core/luna_ui/invalid_route.dart b/lib/core/ui/invalid_route.dart similarity index 100% rename from lib/core/luna_ui/invalid_route.dart rename to lib/core/ui/invalid_route.dart diff --git a/lib/core/luna_ui/list_tile.dart b/lib/core/ui/list_tile.dart similarity index 100% rename from lib/core/luna_ui/list_tile.dart rename to lib/core/ui/list_tile.dart diff --git a/lib/core/luna_ui/list_tile/list_tile.dart b/lib/core/ui/list_tile/list_tile.dart similarity index 100% rename from lib/core/luna_ui/list_tile/list_tile.dart rename to lib/core/ui/list_tile/list_tile.dart diff --git a/lib/core/luna_ui/list_view.dart b/lib/core/ui/list_view.dart similarity index 100% rename from lib/core/luna_ui/list_view.dart rename to lib/core/ui/list_view.dart diff --git a/lib/core/luna_ui/list_view/list_view.dart b/lib/core/ui/list_view/list_view.dart similarity index 100% rename from lib/core/luna_ui/list_view/list_view.dart rename to lib/core/ui/list_view/list_view.dart diff --git a/lib/core/luna_ui/list_view/list_view_builder.dart b/lib/core/ui/list_view/list_view_builder.dart similarity index 100% rename from lib/core/luna_ui/list_view/list_view_builder.dart rename to lib/core/ui/list_view/list_view_builder.dart diff --git a/lib/core/luna_ui/list_view/list_view_modal.dart b/lib/core/ui/list_view/list_view_modal.dart similarity index 100% rename from lib/core/luna_ui/list_view/list_view_modal.dart rename to lib/core/ui/list_view/list_view_modal.dart diff --git a/lib/core/luna_ui/list_view/paged_list_view.dart b/lib/core/ui/list_view/paged_list_view.dart similarity index 100% rename from lib/core/luna_ui/list_view/paged_list_view.dart rename to lib/core/ui/list_view/paged_list_view.dart diff --git a/lib/core/ui/loader.dart b/lib/core/ui/loader.dart index 63d0e569..fc9cc497 100644 --- a/lib/core/ui/loader.dart +++ b/lib/core/ui/loader.dart @@ -2,11 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:lunasea/core.dart'; -class LSLoader extends StatelessWidget { +class LunaLoader extends StatelessWidget { final double size; final Color color; - LSLoader({ + LunaLoader({ Key key, this.size = 25.0, this.color, diff --git a/lib/core/luna_ui/message.dart b/lib/core/ui/message.dart similarity index 100% rename from lib/core/luna_ui/message.dart rename to lib/core/ui/message.dart diff --git a/lib/core/luna_ui/message/message.dart b/lib/core/ui/message/message.dart similarity index 93% rename from lib/core/luna_ui/message/message.dart rename to lib/core/ui/message/message.dart index 908ca589..5950bf55 100644 --- a/lib/core/luna_ui/message/message.dart +++ b/lib/core/ui/message/message.dart @@ -45,7 +45,7 @@ class LunaMessage extends StatelessWidget { return LunaMessage( key: key, text: text, - buttonText: 'Go Back', + buttonText: 'lunasea.GoBack'.tr(), onTap: () => Navigator.of(context).pop(), useSafeArea: useSafeArea, ); @@ -60,8 +60,8 @@ class LunaMessage extends StatelessWidget { assert(onTap != null); return LunaMessage( key: key, - text: 'An Error Has Occurred', - buttonText: 'Try Again', + text: 'lunasea.AnErrorHasOccurred'.tr(), + buttonText: 'lunasea.TryAgain'.tr(), onTap: onTap, useSafeArea: useSafeArea, ); @@ -78,8 +78,8 @@ class LunaMessage extends StatelessWidget { assert(context != null); return LunaMessage( key: key, - text: '$module Is Not Enabled', - buttonText: 'Return to Dashboard', + text: 'lunasea.ModuleIsNotEnabled'.tr(args: [module]), + buttonText: 'lunasea.ReturnToDashboard'.tr(), onTap: () async => LunaModule.DASHBOARD.launch(), useSafeArea: useSafeArea, ); diff --git a/lib/core/ui/network_image.dart b/lib/core/ui/network_image.dart index 43534516..634b8612 100644 --- a/lib/core/ui/network_image.dart +++ b/lib/core/ui/network_image.dart @@ -1,38 +1,42 @@ import 'package:flutter/material.dart'; import 'package:lunasea/core.dart'; -// ignore: non_constant_identifier_names -Widget LSNetworkImage({ - @required double height, - @required double width, - @required String url, - @required String placeholder, - Map headers, - bool roundCorners = true, -}) => ClipRRect( - child: Container( - child: Stack( - fit: StackFit.expand, - children: [ - Image.asset(placeholder), - if(url != null) FadeInImage( - height: height, - width: width, - fadeInDuration: Duration(milliseconds: LunaUI.ANIMATION_IMAGE_FADE_IN_SPEED), - fadeOutDuration: Duration(milliseconds: 1), - placeholder: AssetImage(placeholder), - fit: BoxFit.cover, - image: NetworkImage( - url, - headers: headers, +class LunaNetworkImage extends ClipRRect { + LunaNetworkImage({ + double height, + double width, + String url, + @required String placeholderAsset, + Map headers, + bool roundCorners = true, + }) : super( + child: Container( + child: Stack( + fit: StackFit.expand, + children: [ + Image.asset( + placeholderAsset, + height: height, + width: width, ), - ), - ], + if(url != null && url.isNotEmpty) FadeInImage( + height: height, + width: width, + fadeInDuration: Duration(milliseconds: LunaUI.ANIMATION_IMAGE_FADE_IN_SPEED), + fadeOutDuration: Duration(milliseconds: 1), + placeholder: AssetImage(placeholderAsset), + fit: BoxFit.cover, + image: NetworkImage(url, headers: headers?.cast()), + ), + ], + ), + height: height, + width: width, ), - height: height, - width: width, - ), - borderRadius: roundCorners - ? BorderRadius.circular(Constants.UI_BORDER_RADIUS) - : null, -); \ No newline at end of file + borderRadius: roundCorners ? BorderRadius.circular(LunaUI.BORDER_RADIUS) : null, + ) { + // assert(height != null); + // assert(width != null); + assert(placeholderAsset != null); + } +} diff --git a/lib/core/luna_ui/popup_menu_button.dart b/lib/core/ui/popup_menu_button.dart similarity index 100% rename from lib/core/luna_ui/popup_menu_button.dart rename to lib/core/ui/popup_menu_button.dart diff --git a/lib/core/ui/refresh_indicator.dart b/lib/core/ui/refresh_indicator.dart index a9f344ce..af0d67c5 100644 --- a/lib/core/ui/refresh_indicator.dart +++ b/lib/core/ui/refresh_indicator.dart @@ -1,28 +1,15 @@ import 'package:flutter/material.dart'; -class LSRefreshIndicator extends StatefulWidget { - final Widget child; - final Function onRefresh; - final GlobalKey refreshKey; - - LSRefreshIndicator({ - @required this.child, - @required this.onRefresh, - @required this.refreshKey, - }); - - @override - State createState() => _State(); +class LunaRefreshIndicator extends RefreshIndicator { + LunaRefreshIndicator({ + GlobalKey key, + @required BuildContext context, + @required Future Function() onRefresh, + @required Widget child, + }) : super( + key: key, + backgroundColor: Theme.of(context).primaryColor, + onRefresh: onRefresh, + child: child, + ); } - -class _State extends State { - @override - Widget build(BuildContext context) { - return RefreshIndicator( - key: widget.refreshKey, - backgroundColor: Theme.of(context).primaryColor, - onRefresh: widget.onRefresh, - child: widget.child, - ); - } -} \ No newline at end of file diff --git a/lib/core/ui/shape.dart b/lib/core/ui/shape.dart index 462e6be3..7d369d31 100644 --- a/lib/core/ui/shape.dart +++ b/lib/core/ui/shape.dart @@ -1,19 +1,14 @@ import 'package:flutter/material.dart'; import 'package:lunasea/core.dart'; -// ignore: non_constant_identifier_names -ShapeBorder LSRoundedShape({ - double borderRadius = Constants.UI_BORDER_RADIUS, -}) => RoundedRectangleBorder( - borderRadius: BorderRadius.circular(borderRadius), -); +class LunaShapeBorder extends RoundedRectangleBorder { + LunaShapeBorder._internal({ + bool useBorder = false, + }) : super( + borderRadius: BorderRadius.circular(LunaUI.BORDER_RADIUS), + side: useBorder ? BorderSide(color: Colors.white12) : BorderSide.none, + ); -// ignore: non_constant_identifier_names -ShapeBorder LSRoundedShapeWithBorder({ - double borderRadius = Constants.UI_BORDER_RADIUS, -}) => RoundedRectangleBorder( - borderRadius: BorderRadius.circular(borderRadius), - side: BorderSide( - color: Colors.white12, - ), -); + factory LunaShapeBorder.rounded() => LunaShapeBorder._internal(); + factory LunaShapeBorder.roundedWithBorder() => LunaShapeBorder._internal(useBorder: true); +} diff --git a/lib/core/luna_ui/sliver_sticky_header.dart b/lib/core/ui/sliver_sticky_header.dart similarity index 100% rename from lib/core/luna_ui/sliver_sticky_header.dart rename to lib/core/ui/sliver_sticky_header.dart diff --git a/lib/core/ui/snackbar.dart b/lib/core/ui/snackbar.dart index 84285668..b4d4b8f5 100644 --- a/lib/core/ui/snackbar.dart +++ b/lib/core/ui/snackbar.dart @@ -1,90 +1,4 @@ -import 'package:flutter/material.dart'; -import 'package:flash/flash.dart'; -import 'package:lunasea/core.dart'; - -enum SNACKBAR_TYPE { - success, - failure, - info, -} - -const _LEFT_PADDING = 8.0; - -// ignore: non_constant_identifier_names -Future LSSnackBar({ - @required BuildContext context, - @required String title, - String message = LunaLogger.CHECK_LOGS_MESSAGE, - Duration duration, - SNACKBAR_TYPE type = SNACKBAR_TYPE.info, - bool showButton = false, - String buttonText = 'view', - Function buttonOnPressed, -}) async { - if(showButton) assert(buttonOnPressed != null); - Color color; - IconData icon; - switch(type) { - case SNACKBAR_TYPE.failure: color = LunaColours.red; icon = Icons.error_outline; break; - case SNACKBAR_TYPE.success: color = LunaColours.accent; icon = Icons.check_circle_outline; break; - case SNACKBAR_TYPE.info: color = LunaColours.blue; icon = Icons.info_outline; break; - } - showFlash( - context: context, - duration: duration != null - ? duration - : showButton - ? Duration(seconds: 4) - : Duration(seconds: 2), - builder: (context, controller) => Flash( - backgroundColor: Theme.of(context).primaryColor, - controller: controller, - style: FlashStyle.floating, - boxShadows: [BoxShadow(blurRadius: 6.0, spreadRadius: 4.0, color: Colors.black.withOpacity(0.10))], - horizontalDismissDirection: HorizontalDismissDirection.horizontal, - margin: EdgeInsets.all(8.0), - borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), - borderColor: LunaDatabaseValue.THEME_AMOLED.data && LunaDatabaseValue.THEME_AMOLED_BORDER.data - ? Colors.white12 - : Colors.transparent, - child: FlashBar( - title: Text( - title, - style: TextStyle( - fontWeight: LunaUI.FONT_WEIGHT_BOLD, - fontSize: Constants.UI_FONT_SIZE_TITLE, - ), - ), - message: Text( - message, - style: TextStyle( - color: Colors.white70, - fontSize: Constants.UI_FONT_SIZE_SUBTITLE, - ), - ), - icon: Padding( - child: LSIconButton( - icon: icon, - color: color, - ), - padding: EdgeInsets.only(left: _LEFT_PADDING), - ), - primaryAction: showButton - ? TextButton( - child: Text( - buttonText.toUpperCase(), - style: TextStyle( - fontWeight: LunaUI.FONT_WEIGHT_BOLD, - color: LunaColours.accent, - ), - ), - onPressed: () { - controller.dismiss(); - buttonOnPressed(); - }, - ) - : null, - ), - ), - ); -} +export 'snackbar/snackbar.dart'; +export 'snackbar/snackbar_error.dart'; +export 'snackbar/snackbar_info.dart'; +export 'snackbar/snackbar_success.dart'; diff --git a/lib/core/luna_ui/snackbar/snackbar.dart b/lib/core/ui/snackbar/snackbar.dart similarity index 100% rename from lib/core/luna_ui/snackbar/snackbar.dart rename to lib/core/ui/snackbar/snackbar.dart diff --git a/lib/core/luna_ui/snackbar/snackbar_error.dart b/lib/core/ui/snackbar/snackbar_error.dart similarity index 100% rename from lib/core/luna_ui/snackbar/snackbar_error.dart rename to lib/core/ui/snackbar/snackbar_error.dart diff --git a/lib/core/luna_ui/snackbar/snackbar_info.dart b/lib/core/ui/snackbar/snackbar_info.dart similarity index 100% rename from lib/core/luna_ui/snackbar/snackbar_info.dart rename to lib/core/ui/snackbar/snackbar_info.dart diff --git a/lib/core/luna_ui/snackbar/snackbar_success.dart b/lib/core/ui/snackbar/snackbar_success.dart similarity index 100% rename from lib/core/luna_ui/snackbar/snackbar_success.dart rename to lib/core/ui/snackbar/snackbar_success.dart diff --git a/lib/core/luna_ui/switch.dart b/lib/core/ui/switch.dart similarity index 100% rename from lib/core/luna_ui/switch.dart rename to lib/core/ui/switch.dart diff --git a/lib/core/ui/table.dart b/lib/core/ui/table.dart index 59e9bf2b..5d4c60a9 100644 --- a/lib/core/ui/table.dart +++ b/lib/core/ui/table.dart @@ -1,2 +1,2 @@ -export 'table/block.dart'; -export 'table/content.dart'; +export 'table/table_card.dart'; +export 'table/table_content.dart'; diff --git a/lib/core/luna_ui/table/table_card.dart b/lib/core/ui/table/table_card.dart similarity index 100% rename from lib/core/luna_ui/table/table_card.dart rename to lib/core/ui/table/table_card.dart diff --git a/lib/core/luna_ui/table/table_content.dart b/lib/core/ui/table/table_content.dart similarity index 100% rename from lib/core/luna_ui/table/table_content.dart rename to lib/core/ui/table/table_content.dart diff --git a/lib/core/ui/text.dart b/lib/core/ui/text.dart index 271a8863..b3bd0cb4 100644 --- a/lib/core/ui/text.dart +++ b/lib/core/ui/text.dart @@ -1,4 +1,67 @@ -export 'text/header.dart'; -export 'text/text_highlighted.dart'; -export 'text/text_title.dart'; -export 'text/text_subtitle.dart'; +import 'package:flutter/material.dart'; +import 'package:lunasea/core.dart'; + +class LunaText extends Text { + /// Create a new [Text] widget. + LunaText({ + @required String text, + Key key, + int maxLines, + TextOverflow overflow, + bool softWrap, + TextStyle style, + TextAlign textAlign, + }) : super( + text, + key: key, + maxLines: maxLines, + overflow: overflow, + softWrap: softWrap, + style: style, + textAlign: textAlign, + ); + + /// Create a [LunaText] widget with the styling pre-assigned to be a LunaSea title. + factory LunaText.title({ + Key key, + @required String text, + int maxLines = 1, + bool softWrap = false, + TextAlign textAlign = TextAlign.start, + Color color = Colors.white, + bool darken = false, + }) => LunaText( + text: text, + key: key, + maxLines: maxLines, + overflow: TextOverflow.fade, + softWrap: softWrap, + textAlign: textAlign, + style: TextStyle( + color: darken ? color.withOpacity(0.30) : color, + fontWeight: LunaUI.FONT_WEIGHT_BOLD, + fontSize: LunaUI.FONT_SIZE_TITLE, + ), + ); + + /// Create a [LunaText] widget with the styling pre-assigned to be a LunaSea subtitle. + factory LunaText.subtitle({ + Key key, + @required String text, + int maxLines = 1, + bool softWrap = false, + TextAlign textAlign = TextAlign.start, + Color color = Colors.white70, + bool darken = false, + }) => LunaText( + key: key, + text: text, + softWrap: softWrap, + maxLines: maxLines, + textAlign: textAlign, + style: TextStyle( + color: darken ? color.withOpacity(0.30) : color, + fontSize: LunaUI.FONT_SIZE_SUBTITLE, + ), + ); +} diff --git a/lib/core/luna_ui/theme.dart b/lib/core/ui/theme.dart similarity index 100% rename from lib/core/luna_ui/theme.dart rename to lib/core/ui/theme.dart diff --git a/lib/core/utilities/changelog.dart b/lib/core/utilities/changelog.dart index 268a2e8e..66b1ca7f 100644 --- a/lib/core/utilities/changelog.dart +++ b/lib/core/utilities/changelog.dart @@ -12,7 +12,7 @@ class LunaChangelog { .then((package) { if(AlertsDatabaseValue.CHANGELOG.data != package.buildNumber) { AlertsDatabaseValue.CHANGELOG.put(package.buildNumber); - showChangelog(); + showChangelog(package.version, package.buildNumber); } }) .catchError((error, stack) { @@ -21,7 +21,7 @@ class LunaChangelog { } /// Load the changelog asset and show a bottom modal sheet with the changelog. - Future showChangelog() async { + Future showChangelog(String version, String buildNumber) async { await DefaultAssetBundle.of(LunaState.navigatorKey.currentContext).loadString('assets/changelog.json') .then((data) { _Changelog changelog = _Changelog.fromJson(json.decode(data)); @@ -29,7 +29,7 @@ class LunaChangelog { context: LunaState.navigatorKey.currentContext, builder: (context) => LunaListViewModal( children: [ - LunaHeader(text: '${changelog.version} (${changelog.build})', subtitle: changelog.motd), + LunaHeader(text: '$version ($buildNumber)', subtitle: changelog.motd), if((changelog.changesNew?.length ?? 0) != 0) LunaHeader(text: 'New'), if((changelog.changesNew?.length ?? 0) != 0) LunaTableCard( content: List.generate( @@ -79,7 +79,6 @@ class LunaChangelog { class _Changelog { String motd; String version; - String build; List<_Change> changesNew; List<_Change> changesTweaks; List<_Change> changesFixes; @@ -88,7 +87,6 @@ class _Changelog { _Changelog changelog = _Changelog(); changelog.motd = json['motd'] ?? ''; changelog.version = json['version'] ?? ''; - changelog.build = json['build'] ?? ''; changelog.changesNew = json['new'] == null ? [] : (json['new'] as List).map<_Change>((change) => _Change.fromJson(change)).toList(); changelog.changesTweaks = json['tweaks'] == null ? [] : (json['tweaks'] as List).map<_Change>((change) => _Change.fromJson(change)).toList(); changelog.changesFixes = json['fixes'] == null ? [] : (json['fixes'] as List).map<_Change>((change) => _Change.fromJson(change)).toList(); diff --git a/lib/main.dart b/lib/main.dart index 6c5bdb74..a3d74ae6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,19 +3,26 @@ import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; import 'package:lunasea/core.dart'; -import 'package:sentry_flutter/sentry_flutter.dart'; /// LunaSea Entry Point: Initialize & Run Application /// /// Runs app in Sentry guarded zone to attempt to capture fatal (crashing) errors -Future main() async => await SentryFlutter.init( - (options) => options - ..dsn = LunaLogger.SENTRY_DSN, - appRunner: () async { - await _init(); - runApp(LunaBIOS()); - } -); +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await _init(); + runZonedGuarded( + () => runApp( + EasyLocalization( + supportedLocales: LunaLocalization().supportedLocales, + path: LunaLocalization().fileDirectory, + fallbackLocale: LunaLocalization().fallbackLocale, + useFallbackTranslations: true, + child: LunaBIOS(), + ), + ), + (error, stack) => LunaFirebaseCrashlytics.instance.recordError, + ); +} /// Initializes LunaSea before running the BIOS Widget. /// @@ -39,13 +46,14 @@ Future _init() async { statusBarColor: Colors.transparent, )); //LunaSea initialization + await Database().initialize(); + await LunaFirebase().initialize(); LunaLogger().initialize(); LunaNetworking().initialize(); LunaImageCache().initialize(); LunaRouter().intialize(); - await LunaFirebase().initialize(); await LunaInAppPurchases().initialize(); - await Database().initialize(); + await LunaLocalization().initialize(); } class LunaBIOS extends StatefulWidget { @@ -100,13 +108,15 @@ class _State extends State { ]), builder: (context, box, _) { return MaterialApp( + localizationsDelegates: context.localizationDelegates, + supportedLocales: context.supportedLocales, + locale: context.locale, routes: LunaRouter().routes, onGenerateRoute: LunaRouter.router.generator, + navigatorKey: LunaState.navigatorKey, darkTheme: LunaTheme().activeTheme(), theme: LunaTheme().activeTheme(), - title: Constants.APPLICATION_NAME, - navigatorKey: LunaState.navigatorKey, - navigatorObservers: [ SentryNavigatorObserver() ], + title: 'LunaSea', ); }, ), diff --git a/lib/modules/dashboard/routes/home.dart b/lib/modules/dashboard/routes/home.dart index 5dd5ae35..2ec38d59 100644 --- a/lib/modules/dashboard/routes/home.dart +++ b/lib/modules/dashboard/routes/home.dart @@ -48,10 +48,10 @@ class _State extends State { } } - Widget get _drawer => LSDrawer(page: LunaModule.DASHBOARD.key); + Widget get _drawer => LunaDrawer(page: LunaModule.DASHBOARD.key); Widget get _appBar => LunaAppBar( - title: Constants.APPLICATION_NAME, + title: 'LunaSea', useDrawer: true, actions: Database.currentProfileObject.anyAutomationEnabled ? [ diff --git a/lib/modules/lidarr/routes/lidarr.dart b/lib/modules/lidarr/routes/lidarr.dart index 48971347..63f07883 100644 --- a/lib/modules/lidarr/routes/lidarr.dart +++ b/lib/modules/lidarr/routes/lidarr.dart @@ -54,7 +54,7 @@ class _State extends State { ), ); - Widget get _drawer => LSDrawer(page: LunaModule.LIDARR.key); + Widget get _drawer => LunaDrawer(page: LunaModule.LIDARR.key); Widget get _bottomNavigationBar => LidarrNavigationBar(pageController: _pageController); diff --git a/lib/modules/nzbget/routes/nzbget.dart b/lib/modules/nzbget/routes/nzbget.dart index ae79a72f..4c58bae2 100644 --- a/lib/modules/nzbget/routes/nzbget.dart +++ b/lib/modules/nzbget/routes/nzbget.dart @@ -54,7 +54,7 @@ class _State extends State { ), ); - Widget get _drawer => LSDrawer(page: 'nzbget'); + Widget get _drawer => LunaDrawer(page: LunaModule.NZBGET.key); Widget get _bottomNavigationBar => NZBGetNavigationBar(pageController: _pageController); diff --git a/lib/modules/radarr/core/api_helper.dart b/lib/modules/radarr/core/api_helper.dart index 0b35b696..2e950202 100644 --- a/lib/modules/radarr/core/api_helper.dart +++ b/lib/modules/radarr/core/api_helper.dart @@ -96,7 +96,6 @@ class RadarrAPIHelper { return movie; }) .catchError((error, stack) { - print(error); LunaLogger().error('Failed to add movie (tmdbId: ${movie.tmdbId})', error, stack); if(showSnackbar) showLunaErrorSnackBar(title: 'Failed to Add Movie', error: error); return null; diff --git a/lib/modules/radarr/core/database.dart b/lib/modules/radarr/core/database.dart index d579d39b..4a69b988 100644 --- a/lib/modules/radarr/core/database.dart +++ b/lib/modules/radarr/core/database.dart @@ -41,6 +41,7 @@ class RadarrDatabase extends LunaModuleDatabase { case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_ROOT_FOLDER_ID: case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_QUALITY_PROFILE_ID: case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_MINIMUM_AVAILABILITY_ID: + case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_TAGS: case RadarrDatabaseValue.ADD_DISCOVER_USE_SUGGESTIONS: case RadarrDatabaseValue.REMOVE_MOVIE_IMPORT_LIST: case RadarrDatabaseValue.REMOVE_MOVIE_DELETE_FILES: @@ -71,6 +72,7 @@ class RadarrDatabase extends LunaModuleDatabase { case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_ROOT_FOLDER_ID: case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_QUALITY_PROFILE_ID: case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_MINIMUM_AVAILABILITY_ID: + case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_TAGS: case RadarrDatabaseValue.ADD_DISCOVER_USE_SUGGESTIONS: case RadarrDatabaseValue.REMOVE_MOVIE_DELETE_FILES: case RadarrDatabaseValue.REMOVE_MOVIE_IMPORT_LIST: @@ -96,6 +98,7 @@ class RadarrDatabase extends LunaModuleDatabase { case 'RADARR_ADD_MOVIE_DEFAULT_ROOT_FOLDER_ID': return RadarrDatabaseValue.ADD_MOVIE_DEFAULT_ROOT_FOLDER_ID; case 'RADARR_ADD_MOVIE_DEFAULT_QUALITY_PROFILE_ID': return RadarrDatabaseValue.ADD_MOVIE_DEFAULT_QUALITY_PROFILE_ID; case 'RADARR_ADD_MOVIE_DEFAULT_MINIMUM_AVAILABILITY_ID': return RadarrDatabaseValue.ADD_MOVIE_DEFAULT_MINIMUM_AVAILABILITY_ID; + case 'RADARR_ADD_MOVIE_DEFAULT_TAGS': return RadarrDatabaseValue.ADD_MOVIE_DEFAULT_TAGS; case 'RADARR_ADD_DISCOVER_USE_SUGGESTIONS': return RadarrDatabaseValue.ADD_DISCOVER_USE_SUGGESTIONS; case 'RADARR_REMOVE_MOVIE_IMPORT_LIST': return RadarrDatabaseValue.REMOVE_MOVIE_IMPORT_LIST; case 'RADARR_REMOVE_MOVIE_DELETE_FILES': return RadarrDatabaseValue.REMOVE_MOVIE_DELETE_FILES; @@ -120,6 +123,7 @@ enum RadarrDatabaseValue { ADD_MOVIE_DEFAULT_ROOT_FOLDER_ID, ADD_MOVIE_DEFAULT_QUALITY_PROFILE_ID, ADD_MOVIE_DEFAULT_MINIMUM_AVAILABILITY_ID, + ADD_MOVIE_DEFAULT_TAGS, ADD_DISCOVER_USE_SUGGESTIONS, REMOVE_MOVIE_IMPORT_LIST, REMOVE_MOVIE_DELETE_FILES, @@ -143,6 +147,7 @@ extension RadarrDatabaseValueExtension on RadarrDatabaseValue { case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_ROOT_FOLDER_ID: return 'RADARR_ADD_MOVIE_DEFAULT_ROOT_FOLDER_ID'; case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_QUALITY_PROFILE_ID: return 'RADARR_ADD_MOVIE_DEFAULT_QUALITY_PROFILE_ID'; case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_MINIMUM_AVAILABILITY_ID: return 'RADARR_ADD_MOVIE_DEFAULT_MINIMUM_AVAILABILITY_ID'; + case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_TAGS: return 'RADARR_ADD_MOVIE_DEFAULT_TAGS'; case RadarrDatabaseValue.ADD_DISCOVER_USE_SUGGESTIONS: return 'RADARR_ADD_DISCOVER_USE_SUGGESTIONS'; case RadarrDatabaseValue.REMOVE_MOVIE_IMPORT_LIST: return 'RADARR_REMOVE_MOVIE_IMPORT_LIST'; case RadarrDatabaseValue.REMOVE_MOVIE_DELETE_FILES: return 'RADARR_REMOVE_MOVIE_DELETE_FILES'; @@ -168,6 +173,7 @@ extension RadarrDatabaseValueExtension on RadarrDatabaseValue { case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_ROOT_FOLDER_ID: return _box.get(this.key, defaultValue: null); case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_QUALITY_PROFILE_ID: return _box.get(this.key, defaultValue: null); case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_MINIMUM_AVAILABILITY_ID: return _box.get(this.key, defaultValue: 'announced'); + case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_TAGS: return _box.get(this.key, defaultValue: []); case RadarrDatabaseValue.ADD_DISCOVER_USE_SUGGESTIONS: return _box.get(this.key, defaultValue: true); case RadarrDatabaseValue.REMOVE_MOVIE_DELETE_FILES: return _box.get(this.key, defaultValue: false); case RadarrDatabaseValue.REMOVE_MOVIE_IMPORT_LIST: return _box.get(this.key, defaultValue: false); @@ -179,24 +185,25 @@ extension RadarrDatabaseValueExtension on RadarrDatabaseValue { void put(dynamic value) { final box = Database.lunaSeaBox; switch(this) { - case RadarrDatabaseValue.NAVIGATION_INDEX: if(value.runtimeType == int) box.put(this.key, value); return; - case RadarrDatabaseValue.NAVIGATION_INDEX_MOVIE_DETAILS: if(value.runtimeType == int) box.put(this.key, value); return; - case RadarrDatabaseValue.NAVIGATION_INDEX_ADD_MOVIE: if(value.runtimeType == int) box.put(this.key, value); return; - case RadarrDatabaseValue.NAVIGATION_INDEX_SYSTEM_STATUS: if(value.runtimeType == int) box.put(this.key, value); return; - case RadarrDatabaseValue.DEFAULT_SORTING_MOVIES: if(value.runtimeType == RadarrMoviesSorting) box.put(this.key, value); return; - case RadarrDatabaseValue.DEFAULT_SORTING_MOVIES_ASCENDING: if(value.runtimeType == bool) box.put(this.key, value); return; - case RadarrDatabaseValue.DEFAULT_FILTERING_MOVIES: if(value.runtimeType == RadarrMoviesFilter) box.put(this.key, value); return; - case RadarrDatabaseValue.DEFAULT_SORTING_RELEASES: if(value.runtimeType == RadarrReleasesSorting) box.put(this.key, value); return; - case RadarrDatabaseValue.DEFAULT_SORTING_RELEASES_ASCENDING: if(value.runtimeType == bool) box.put(this.key, value); return; - case RadarrDatabaseValue.DEFAULT_FILTERING_RELEASES: if(value.runtimeType == RadarrReleasesFilter) box.put(this.key, value); return; - case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_MONITORED_STATE: if(value.runtimeType == bool) box.put(this.key, value); return; - case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_ROOT_FOLDER_ID: if(value.runtimeType == int) box.put(this.key, value); return; - case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_QUALITY_PROFILE_ID: if(value.runtimeType == int) box.put(this.key, value); return; - case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_MINIMUM_AVAILABILITY_ID: if(value.runtimeType == String) box.put(this.key, value); return; - case RadarrDatabaseValue.ADD_DISCOVER_USE_SUGGESTIONS: if(value.runtimeType == bool) box.put(this.key, value); return; - case RadarrDatabaseValue.REMOVE_MOVIE_DELETE_FILES: if(value.runtimeType == bool) box.put(this.key, value); return; - case RadarrDatabaseValue.REMOVE_MOVIE_IMPORT_LIST: if(value.runtimeType == bool) box.put(this.key, value); return; - case RadarrDatabaseValue.CONTENT_PAGE_SIZE: if(value.runtimeType == int) box.put(this.key, value); return; + case RadarrDatabaseValue.NAVIGATION_INDEX: if(value is int) box.put(this.key, value); return; + case RadarrDatabaseValue.NAVIGATION_INDEX_MOVIE_DETAILS: if(value is int) box.put(this.key, value); return; + case RadarrDatabaseValue.NAVIGATION_INDEX_ADD_MOVIE: if(value is int) box.put(this.key, value); return; + case RadarrDatabaseValue.NAVIGATION_INDEX_SYSTEM_STATUS: if(value is int) box.put(this.key, value); return; + case RadarrDatabaseValue.DEFAULT_SORTING_MOVIES: if(value is RadarrMoviesSorting) box.put(this.key, value); return; + case RadarrDatabaseValue.DEFAULT_SORTING_MOVIES_ASCENDING: if(value is bool) box.put(this.key, value); return; + case RadarrDatabaseValue.DEFAULT_FILTERING_MOVIES: if(value is RadarrMoviesFilter) box.put(this.key, value); return; + case RadarrDatabaseValue.DEFAULT_SORTING_RELEASES: if(value is RadarrReleasesSorting) box.put(this.key, value); return; + case RadarrDatabaseValue.DEFAULT_SORTING_RELEASES_ASCENDING: if(value is bool) box.put(this.key, value); return; + case RadarrDatabaseValue.DEFAULT_FILTERING_RELEASES: if(value is RadarrReleasesFilter) box.put(this.key, value); return; + case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_MONITORED_STATE: if(value is bool) box.put(this.key, value); return; + case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_ROOT_FOLDER_ID: if(value is int) box.put(this.key, value); return; + case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_QUALITY_PROFILE_ID: if(value is int) box.put(this.key, value); return; + case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_MINIMUM_AVAILABILITY_ID: if(value is String) box.put(this.key, value); return; + case RadarrDatabaseValue.ADD_MOVIE_DEFAULT_TAGS: if(value is List) box.put(this.key, value); return; + case RadarrDatabaseValue.ADD_DISCOVER_USE_SUGGESTIONS: if(value is bool) box.put(this.key, value); return; + case RadarrDatabaseValue.REMOVE_MOVIE_DELETE_FILES: if(value is bool) box.put(this.key, value); return; + case RadarrDatabaseValue.REMOVE_MOVIE_IMPORT_LIST: if(value is bool) box.put(this.key, value); return; + case RadarrDatabaseValue.CONTENT_PAGE_SIZE: if(value is int) box.put(this.key, value); return; } LunaLogger().warning('RadarrDatabaseValueExtension', 'put', 'Attempted to enter data for invalid RadarrDatabaseValue: ${this?.toString() ?? 'null'}'); } diff --git a/lib/modules/radarr/core/dialogs.dart b/lib/modules/radarr/core/dialogs.dart index 70a1a444..12fe6fca 100644 --- a/lib/modules/radarr/core/dialogs.dart +++ b/lib/modules/radarr/core/dialogs.dart @@ -15,7 +15,7 @@ class RadarrDialogs { await LSDialog.dialog( context: context, - title: 'Radarr Settings', + title: 'lunasea.Settings'.tr(), content: List.generate( RadarrGlobalSettingsType.values.length, (index) => LSDialog.tile( @@ -247,7 +247,7 @@ class RadarrDialogs { await LSDialog.dialog( context: context, - title: 'Minimum Availability', + title: 'radarr.MinimumAvailability'.tr(), content: List.generate( RadarrAvailability.values.length, (index) => LSDialog.tile( @@ -274,7 +274,7 @@ class RadarrDialogs { await LSDialog.dialog( context: context, - title: 'Quality Profile', + title: 'radarr.QualityProfile'.tr(), content: List.generate( profiles.length, (index) => LSDialog.tile( @@ -403,7 +403,7 @@ class RadarrDialogs { await LSDialog.dialog( context: context, - title: 'Root Folder', + title: 'radarr.RootFolder'.tr(), content: List.generate( folders.length, (index) => LSDialog.tile( diff --git a/lib/modules/radarr/core/extensions/radarr_event_type.dart b/lib/modules/radarr/core/extensions/radarr_event_type.dart index 7294dcb7..8e19e1b4 100644 --- a/lib/modules/radarr/core/extensions/radarr_event_type.dart +++ b/lib/modules/radarr/core/extensions/radarr_event_type.dart @@ -45,13 +45,13 @@ extension lunaRadarrEventType on RadarrEventType { String lunaReadable(RadarrHistoryRecord record) { switch(this) { - case RadarrEventType.GRABBED: return 'Grabbed from ${record.data['indexer'] ?? LunaUI.TEXT_EMDASH}'; - case RadarrEventType.DOWNLOAD_FAILED: return 'Download Failed'; - case RadarrEventType.DOWNLOAD_FOLDER_IMPORTED: return 'Movie Imported (${record?.quality?.quality?.name ?? LunaUI.TEXT_EMDASH})'; - case RadarrEventType.DOWNLOAD_IGNORED: return 'Download Ignored'; - case RadarrEventType.MOVIE_FILE_DELETED: return 'Movie File Deleted'; - case RadarrEventType.MOVIE_FILE_RENAMED: return 'Movie File Renamed'; - case RadarrEventType.MOVIE_FOLDER_IMPORTED: return 'Movie Imported (${record?.quality?.quality?.name ?? LunaUI.TEXT_EMDASH})'; + case RadarrEventType.GRABBED: return 'radarr.GrabbedFrom'.tr(args: [record.data['indexer'] ?? LunaUI.TEXT_EMDASH]); + case RadarrEventType.DOWNLOAD_FAILED: return 'radarr.DownloadFailed'.tr(); + case RadarrEventType.DOWNLOAD_FOLDER_IMPORTED: return 'radarr.MovieImported'.tr(args: [record?.quality?.quality?.name ?? LunaUI.TEXT_EMDASH]); + case RadarrEventType.DOWNLOAD_IGNORED: return 'radarr.DownloadIgnored'.tr(); + case RadarrEventType.MOVIE_FILE_DELETED: return 'radarr.MovieFileDeleted'.tr(); + case RadarrEventType.MOVIE_FILE_RENAMED: return 'radarr.MovieFileRenamed'.tr(); + case RadarrEventType.MOVIE_FOLDER_IMPORTED: return 'radarr.MovieImported'.tr(args: [record?.quality?.quality?.name ?? LunaUI.TEXT_EMDASH]); } return null; } diff --git a/lib/modules/radarr/core/state.dart b/lib/modules/radarr/core/state.dart index c196532a..2ba6b417 100644 --- a/lib/modules/radarr/core/state.dart +++ b/lib/modules/radarr/core/state.dart @@ -15,8 +15,6 @@ class RadarrState extends LunaModuleState { _rootFolders = null; _qualityProfiles = null; _tags = null; - // Reset search query fields - _moviesSearchQuery = ''; // Reinitialize resetProfile(); if(_enabled) { diff --git a/lib/modules/radarr/core/types/filter_movies.dart b/lib/modules/radarr/core/types/filter_movies.dart index 71000abc..84a6f2a4 100644 --- a/lib/modules/radarr/core/types/filter_movies.dart +++ b/lib/modules/radarr/core/types/filter_movies.dart @@ -34,12 +34,12 @@ extension RadarrMoviesFilterExtension on RadarrMoviesFilter { String get readable { switch(this) { - case RadarrMoviesFilter.ALL: return 'All'; - case RadarrMoviesFilter.MONITORED: return 'Monitored'; - case RadarrMoviesFilter.UNMONITORED: return 'Unmonitored'; - case RadarrMoviesFilter.MISSING: return 'Missing'; - case RadarrMoviesFilter.WANTED: return 'Wanted'; - case RadarrMoviesFilter.CUTOFF_UNMET: return 'Cutoff Unmet'; + case RadarrMoviesFilter.ALL: return 'radarr.All'.tr(); + case RadarrMoviesFilter.MONITORED: return 'radarr.Monitored'.tr(); + case RadarrMoviesFilter.UNMONITORED: return 'radarr.Unmonitored'.tr(); + case RadarrMoviesFilter.MISSING: return 'radarr.Missing'.tr(); + case RadarrMoviesFilter.WANTED: return 'radarr.Wanted'.tr(); + case RadarrMoviesFilter.CUTOFF_UNMET: return 'radarr.CutoffUnmet'.tr(); default: return null; } } diff --git a/lib/modules/radarr/core/types/filter_releases.dart b/lib/modules/radarr/core/types/filter_releases.dart index 6fb6799a..8a95b7c6 100644 --- a/lib/modules/radarr/core/types/filter_releases.dart +++ b/lib/modules/radarr/core/types/filter_releases.dart @@ -25,9 +25,9 @@ extension RadarrReleasesFilterExtension on RadarrReleasesFilter { String get readable { switch(this) { - case RadarrReleasesFilter.ALL: return 'All'; - case RadarrReleasesFilter.APPROVED: return 'Approved'; - case RadarrReleasesFilter.REJECTED: return 'Rejected'; + case RadarrReleasesFilter.ALL: return 'radarr.All'.tr(); + case RadarrReleasesFilter.APPROVED: return 'radarr.Approved'.tr(); + case RadarrReleasesFilter.REJECTED: return 'radarr.Rejected'.tr(); default: return null; } } diff --git a/lib/modules/radarr/core/types/settings_global.dart b/lib/modules/radarr/core/types/settings_global.dart index 3c05b8ea..abbfcfcd 100644 --- a/lib/modules/radarr/core/types/settings_global.dart +++ b/lib/modules/radarr/core/types/settings_global.dart @@ -24,11 +24,11 @@ extension RadarrGlobalSettingsTypeExtension on RadarrGlobalSettingsType { String get name { switch(this) { - case RadarrGlobalSettingsType.WEB_GUI: return 'View Web GUI'; - case RadarrGlobalSettingsType.UPDATE_LIBRARY: return 'Update Library'; - case RadarrGlobalSettingsType.RUN_RSS_SYNC: return 'Run RSS Sync'; - case RadarrGlobalSettingsType.SEARCH_ALL_MISSING: return 'Search All Missing'; - case RadarrGlobalSettingsType.BACKUP_DATABASE: return 'Backup Database'; + case RadarrGlobalSettingsType.WEB_GUI: return 'radarr.ViewWebGUI'.tr(); + case RadarrGlobalSettingsType.UPDATE_LIBRARY: return 'radarr.UpdateLibrary'.tr(); + case RadarrGlobalSettingsType.RUN_RSS_SYNC: return 'radarr.RunRSSSync'.tr(); + case RadarrGlobalSettingsType.SEARCH_ALL_MISSING: return 'radarr.SearchAllMissing'.tr(); + case RadarrGlobalSettingsType.BACKUP_DATABASE: return 'radarr.BackupDatabase'.tr(); } throw Exception('Invalid RadarrGlobalSettingsType'); } diff --git a/lib/modules/radarr/core/types/settings_movie.dart b/lib/modules/radarr/core/types/settings_movie.dart index dc34e38f..43e2ce9e 100644 --- a/lib/modules/radarr/core/types/settings_movie.dart +++ b/lib/modules/radarr/core/types/settings_movie.dart @@ -22,10 +22,10 @@ extension RadarrMovieSettingsTypeExtension on RadarrMovieSettingsType { String name(RadarrMovie movie) { switch(this) { - case RadarrMovieSettingsType.MONITORED: return movie.monitored ? 'Unmonitor Movie' : 'Monitor Movie'; - case RadarrMovieSettingsType.EDIT: return 'Edit Movie'; - case RadarrMovieSettingsType.REFRESH: return 'Refresh Movie'; - case RadarrMovieSettingsType.DELETE: return 'Remove Movie'; + case RadarrMovieSettingsType.MONITORED: return movie.monitored ? 'radarr.UnmonitorMovie'.tr() : 'radarr.MonitorMovie'.tr(); + case RadarrMovieSettingsType.EDIT: return 'radarr.EditMovie'.tr(); + case RadarrMovieSettingsType.REFRESH: return 'radarr.RefreshMovie'.tr(); + case RadarrMovieSettingsType.DELETE: return 'radarr.RemoveMovie'.tr(); } throw Exception('Invalid RadarrMovieSettingsType'); } diff --git a/lib/modules/radarr/core/types/sorting_movies.dart b/lib/modules/radarr/core/types/sorting_movies.dart index 31a6a622..bdb2de0b 100644 --- a/lib/modules/radarr/core/types/sorting_movies.dart +++ b/lib/modules/radarr/core/types/sorting_movies.dart @@ -40,14 +40,14 @@ extension RadarrMoviesSortingExtension on RadarrMoviesSorting { String get readable { switch(this) { - case RadarrMoviesSorting.ALPHABETICAL: return 'Alphabetical'; - case RadarrMoviesSorting.DATE_ADDED: return 'Date Added'; - case RadarrMoviesSorting.QUALITY_PROFILE: return 'Quality Profile'; - case RadarrMoviesSorting.RUNTIME: return 'Runtime'; - case RadarrMoviesSorting.SIZE: return 'Size'; - case RadarrMoviesSorting.STUDIO: return 'Studio'; - case RadarrMoviesSorting.YEAR: return 'Year'; - case RadarrMoviesSorting.MIN_AVAILABILITY: return 'Minimum Availability'; + case RadarrMoviesSorting.ALPHABETICAL: return 'radarr.Alphabetical'.tr(); + case RadarrMoviesSorting.DATE_ADDED: return 'radarr.DateAdded'.tr(); + case RadarrMoviesSorting.QUALITY_PROFILE: return 'radarr.QualityProfile'.tr(); + case RadarrMoviesSorting.RUNTIME: return 'radarr.Runtime'.tr(); + case RadarrMoviesSorting.SIZE: return 'radarr.Size'.tr(); + case RadarrMoviesSorting.STUDIO: return 'radarr.Studio'.tr(); + case RadarrMoviesSorting.YEAR: return 'radarr.Year'.tr(); + case RadarrMoviesSorting.MIN_AVAILABILITY: return 'radarr.MinimumAvailability'.tr(); default: return null; } } diff --git a/lib/modules/radarr/core/types/sorting_releases.dart b/lib/modules/radarr/core/types/sorting_releases.dart index 93a59f66..139874cc 100644 --- a/lib/modules/radarr/core/types/sorting_releases.dart +++ b/lib/modules/radarr/core/types/sorting_releases.dart @@ -34,12 +34,12 @@ extension RadarrReleasesSortingExtension on RadarrReleasesSorting { String get readable { switch(this) { - case RadarrReleasesSorting.AGE: return 'Age'; - case RadarrReleasesSorting.ALPHABETICAL: return 'Alphabetical'; - case RadarrReleasesSorting.SEEDERS: return 'Seeders'; - case RadarrReleasesSorting.WEIGHT: return 'Weight'; - case RadarrReleasesSorting.TYPE: return 'Type'; - case RadarrReleasesSorting.SIZE: return 'Size'; + case RadarrReleasesSorting.AGE: return 'radarr.Age'.tr(); + case RadarrReleasesSorting.ALPHABETICAL: return 'radarr.Alphabetical'.tr(); + case RadarrReleasesSorting.SEEDERS: return 'radarr.Seeders'.tr(); + case RadarrReleasesSorting.WEIGHT: return 'radarr.Weight'.tr(); + case RadarrReleasesSorting.TYPE: return 'radarr.Type'.tr(); + case RadarrReleasesSorting.SIZE: return 'radarr.Size'.tr(); default: return null; } } diff --git a/lib/modules/radarr/routes/add_movie/route.dart b/lib/modules/radarr/routes/add_movie/route.dart index a3ed3ff0..bd7d9f76 100644 --- a/lib/modules/radarr/routes/add_movie/route.dart +++ b/lib/modules/radarr/routes/add_movie/route.dart @@ -53,7 +53,7 @@ class _State extends State<_RadarrAddMovieRoute> { Widget _appBar() { return LunaAppBar( - title: 'Add Movie', + title: 'radarr.AddMovie'.tr(), pageController: _pageController, scrollControllers: RadarrAddMovieNavigationBar.scrollControllers, ); @@ -61,11 +61,11 @@ class _State extends State<_RadarrAddMovieRoute> { Widget _body() { return ChangeNotifierProvider( - create: (context) => RadarrAddMovieState(context, _arguments.query), + create: (context) => RadarrAddMovieState(context, _arguments?.query ?? ''), builder: (context, _) => PageView( controller: _pageController, children: [ - RadarrAddMovieSearchPage(), + RadarrAddMovieSearchPage(autofocusSearchBar: (_arguments?.query ?? '').isEmpty && _pageController.initialPage == 0), RadarrAddMovieDiscoverPage(), ], ), diff --git a/lib/modules/radarr/routes/add_movie/widgets/discovery_results_tile.dart b/lib/modules/radarr/routes/add_movie/widgets/discovery_results_tile.dart index 5cf2bb1f..a9c8ecff 100644 --- a/lib/modules/radarr/routes/add_movie/widgets/discovery_results_tile.dart +++ b/lib/modules/radarr/routes/add_movie/widgets/discovery_results_tile.dart @@ -48,7 +48,7 @@ class _State extends State { TextSpan _subtitle2() { String summary; if(widget.movie.overview == null || widget.movie.overview.isEmpty) { - summary = 'No summary is available'; + summary = 'radarr.NoSummaryIsAvailable'.tr(); } else { summary = '${widget.movie.overview}\n'; } @@ -60,7 +60,7 @@ class _State extends State { Future _onTap() async { if(widget.onTapShowOverview) { - LunaDialogs().textPreview(context, widget.movie.title, widget.movie.overview ?? 'No summary is available.'); + LunaDialogs().textPreview(context, widget.movie.title, widget.movie.overview ?? 'radarr.NoSummaryIsAvailable'.tr()); } else { RadarrAddMovieDetailsRouter().navigateTo(context, movie: widget.movie, isDiscovery: true); } diff --git a/lib/modules/radarr/routes/add_movie/widgets/navigation_bar.dart b/lib/modules/radarr/routes/add_movie/widgets/navigation_bar.dart index ce3e63ba..6325033d 100644 --- a/lib/modules/radarr/routes/add_movie/widgets/navigation_bar.dart +++ b/lib/modules/radarr/routes/add_movie/widgets/navigation_bar.dart @@ -3,10 +3,18 @@ import 'package:lunasea/core.dart'; class RadarrAddMovieNavigationBar extends StatelessWidget { final PageController pageController; - static const List icons = [Icons.search, Icons.whatshot]; - static const List titles = ['Search', 'Discover']; static List scrollControllers = List.generate(icons.length, (_) => ScrollController()); + static const List icons = [ + Icons.search, + Icons.whatshot, + ]; + + static List get titles => [ + 'radarr.Search'.tr(), + 'radarr.Discover'.tr(), + ]; + RadarrAddMovieNavigationBar({ Key key, @required this.pageController, diff --git a/lib/modules/radarr/routes/add_movie/widgets/page_discover.dart b/lib/modules/radarr/routes/add_movie/widgets/page_discover.dart index 9faebe0a..36adcbe8 100644 --- a/lib/modules/radarr/routes/add_movie/widgets/page_discover.dart +++ b/lib/modules/radarr/routes/add_movie/widgets/page_discover.dart @@ -61,8 +61,8 @@ class _State extends State with AutomaticKeepAliveCl Widget _list(List movies, List discovery, List exclusions) { List _filtered = _filterAndSort(movies, discovery, exclusions); if(_filtered.length == 0) return LunaMessage( - text: 'No Movies Found', - buttonText: 'Refresh', + text: 'radarr.NoMoviesFound'.tr(), + buttonText: 'lunasea.Refresh'.tr(), onTap: _refreshKey.currentState.show, ); return LunaListViewBuilder( diff --git a/lib/modules/radarr/routes/add_movie/widgets/page_search.dart b/lib/modules/radarr/routes/add_movie/widgets/page_search.dart index f6e1d418..0b61bb0c 100644 --- a/lib/modules/radarr/routes/add_movie/widgets/page_search.dart +++ b/lib/modules/radarr/routes/add_movie/widgets/page_search.dart @@ -3,6 +3,13 @@ import 'package:lunasea/core.dart'; import 'package:lunasea/modules/radarr.dart'; class RadarrAddMovieSearchPage extends StatefulWidget { + final bool autofocusSearchBar; + + RadarrAddMovieSearchPage({ + Key key, + @required this.autofocusSearchBar, + }) : super(key: key); + @override State createState() => _State(); } @@ -37,6 +44,7 @@ class _State extends State with AutomaticKeepAliveClie return LunaAppBar.empty( child: RadarrAddMovieSearchSearchBar( query: context.read().searchQuery, + autofocus: widget.autofocusSearchBar, ), height: 62.0, ); @@ -79,7 +87,7 @@ class _State extends State with AutomaticKeepAliveClie } Widget _list(List movies, List results, List exclusions) { - if((results?.length ?? 0) == 0) return LunaListView(children: [LunaMessage.inList(text: 'No Results Found')], controller: null); + if((results?.length ?? 0) == 0) return LunaListView(children: [LunaMessage.inList(text: 'radarr.NoResultsFound'.tr())], controller: null); return LunaListViewBuilder( controller: RadarrAddMovieNavigationBar.scrollControllers[0], itemCount: results.length, diff --git a/lib/modules/radarr/routes/add_movie/widgets/search_results_tile.dart b/lib/modules/radarr/routes/add_movie/widgets/search_results_tile.dart index e5d7e5cc..ac59faf2 100644 --- a/lib/modules/radarr/routes/add_movie/widgets/search_results_tile.dart +++ b/lib/modules/radarr/routes/add_movie/widgets/search_results_tile.dart @@ -54,7 +54,7 @@ class _State extends State { TextSpan _subtitle2() { String summary; if(widget.movie.overview == null || widget.movie.overview.isEmpty) { - summary = 'No summary is available'; + summary = 'radarr.NoSummaryIsAvailable'.tr()+'\n'; } else { summary = '${widget.movie.overview}\n'; } @@ -66,7 +66,7 @@ class _State extends State { Future _onTap() async { if(widget.onTapShowOverview) { - LunaDialogs().textPreview(context, widget.movie.title, widget.movie.overview ?? 'No summary is available.'); + LunaDialogs().textPreview(context, widget.movie.title, widget.movie.overview ?? 'radarr.NoSummaryIsAvailable'.tr()); } else if(widget.exists) { RadarrMoviesDetailsRouter().navigateTo(context, movieId: widget.movie.id ?? -1); } else { diff --git a/lib/modules/radarr/routes/add_movie/widgets/search_search_bar.dart b/lib/modules/radarr/routes/add_movie/widgets/search_search_bar.dart index 4525b022..8dc71cf2 100644 --- a/lib/modules/radarr/routes/add_movie/widgets/search_search_bar.dart +++ b/lib/modules/radarr/routes/add_movie/widgets/search_search_bar.dart @@ -4,10 +4,12 @@ import 'package:lunasea/modules/radarr.dart'; class RadarrAddMovieSearchSearchBar extends StatefulWidget implements PreferredSizeWidget { final String query; + final bool autofocus; RadarrAddMovieSearchSearchBar({ Key key, @required this.query, + @required this.autofocus, }) : super(key: key); @override @@ -35,7 +37,7 @@ class _State extends State { child: Consumer( builder: (context, state, _) => LunaTextInputBar( controller: _controller, - autofocus: context.read().searchQuery?.isEmpty ?? true, + autofocus: widget.autofocus, onChanged: (value) => context.read().searchQuery = value, onSubmitted: (value) { if(value.isNotEmpty) context.read().fetchLookup(context); diff --git a/lib/modules/radarr/routes/add_movie_details/route.dart b/lib/modules/radarr/routes/add_movie_details/route.dart index 5b2d6746..b954b4e2 100644 --- a/lib/modules/radarr/routes/add_movie_details/route.dart +++ b/lib/modules/radarr/routes/add_movie_details/route.dart @@ -57,8 +57,8 @@ class _State extends State<_RadarrMoviesAddDetailsRoute> with LunaLoadCallbackMi Widget build(BuildContext context) { _RadarrAddMovieDetailsArguments arguments = ModalRoute.of(context).settings.arguments; if(arguments == null || arguments.movie == null) return LunaInvalidRoute( - title: 'Add Movie', - message: 'Movie Not Found', + title: 'radarr.AddMovie'.tr(), + message: 'radarr.MovieNotFound'.tr(), ); return Scaffold( key: _scaffoldKey, @@ -69,7 +69,7 @@ class _State extends State<_RadarrMoviesAddDetailsRoute> with LunaLoadCallbackMi Widget _appBar() { return LunaAppBar( - title: 'Add Movie', + title: 'radarr.AddMovie'.tr(), scrollControllers: [scrollController], ); } diff --git a/lib/modules/radarr/routes/add_movie_details/state.dart b/lib/modules/radarr/routes/add_movie_details/state.dart index 197d18c5..548f9bce 100644 --- a/lib/modules/radarr/routes/add_movie_details/state.dart +++ b/lib/modules/radarr/routes/add_movie_details/state.dart @@ -18,7 +18,7 @@ class RadarrAddMovieDetailsState extends ChangeNotifier { assert(rootFolders != null); assert(qualityProfiles != null); assert(tags != null); - _tags = []; + _tags = (tags ?? []).where((tag) => ((RadarrDatabaseValue.ADD_MOVIE_DEFAULT_TAGS.data as List) ?? []).contains(tag.id)).toList(); _monitored = RadarrDatabaseValue.ADD_MOVIE_DEFAULT_MONITORED_STATE.data ?? true; _rootFolder = (rootFolders ?? []).firstWhere( (element) => element.id == RadarrDatabaseValue.ADD_MOVIE_DEFAULT_ROOT_FOLDER_ID.data, @@ -75,6 +75,7 @@ class RadarrAddMovieDetailsState extends ChangeNotifier { set tags(List tags) { assert(tags != null); _tags = tags; + RadarrDatabaseValue.ADD_MOVIE_DEFAULT_TAGS.put((tags ?? []).map((tag) => tag.id).toList()); notifyListeners(); } diff --git a/lib/modules/radarr/routes/add_movie_details/widgets/button_add_movie.dart b/lib/modules/radarr/routes/add_movie_details/widgets/button_add_movie.dart index 81e75bc3..bfc3c6db 100644 --- a/lib/modules/radarr/routes/add_movie_details/widgets/button_add_movie.dart +++ b/lib/modules/radarr/routes/add_movie_details/widgets/button_add_movie.dart @@ -16,7 +16,7 @@ class RadarrAddMovieDetailsAddButton extends StatelessWidget { @override Widget build(BuildContext context) { return LunaButton( - text: searchOnAdd ? 'Add + Search' : 'Add', + text: searchOnAdd ? 'radarr.AddMovieAndSearch'.tr() : 'radarr.AddMovie'.tr(), backgroundColor: searchOnAdd ? LunaColours.orange : LunaColours.accent, onTap: () async => _onTap(context), loadingState: context.watch().state, diff --git a/lib/modules/radarr/routes/add_movie_details/widgets/tile_minimum_availability.dart b/lib/modules/radarr/routes/add_movie_details/widgets/tile_minimum_availability.dart index e95384f4..6fb7e1d4 100644 --- a/lib/modules/radarr/routes/add_movie_details/widgets/tile_minimum_availability.dart +++ b/lib/modules/radarr/routes/add_movie_details/widgets/tile_minimum_availability.dart @@ -7,7 +7,7 @@ class RadarrAddMovieDetailsMinimumAvailabilityTile extends StatelessWidget { Widget build(BuildContext context) { return LunaListTile( context: context, - title: LunaText.title(text: 'Minimum Availability'), + title: LunaText.title(text: 'radarr.MinimumAvailability'.tr()), subtitle: Selector( selector: (_, state) => state.availability, builder: (context, availability, _) => LunaText.subtitle(text: availability?.readable ?? Constants.TEXT_EMDASH), diff --git a/lib/modules/radarr/routes/add_movie_details/widgets/tile_monitored.dart b/lib/modules/radarr/routes/add_movie_details/widgets/tile_monitored.dart index fd4dce41..019c15f1 100644 --- a/lib/modules/radarr/routes/add_movie_details/widgets/tile_monitored.dart +++ b/lib/modules/radarr/routes/add_movie_details/widgets/tile_monitored.dart @@ -7,8 +7,8 @@ class RadarrAddMovieDetailsMonitoredTile extends StatelessWidget { Widget build(BuildContext context) { return LunaListTile( context: context, - title: LunaText.title(text: 'Monitored'), - subtitle: LunaText.subtitle(text: 'Monitor movie for new releases'), + title: LunaText.title(text: 'radarr.Monitored'.tr()), + subtitle: LunaText.subtitle(text: 'radarr.MonitoredDescription'.tr()), trailing: Selector( selector: (_, state) => state.monitored, builder: (context, monitored, _) => LunaSwitch( diff --git a/lib/modules/radarr/routes/add_movie_details/widgets/tile_quality_profile.dart b/lib/modules/radarr/routes/add_movie_details/widgets/tile_quality_profile.dart index c2f5f7a3..b69e125b 100644 --- a/lib/modules/radarr/routes/add_movie_details/widgets/tile_quality_profile.dart +++ b/lib/modules/radarr/routes/add_movie_details/widgets/tile_quality_profile.dart @@ -7,7 +7,7 @@ class RadarrAddMovieDetailsQualityProfileTile extends StatelessWidget { Widget build(BuildContext context) { return LunaListTile( context: context, - title: LunaText.title(text: 'Quality Profile'), + title: LunaText.title(text: 'radarr.QualityProfile'.tr()), subtitle: Selector( selector: (_, state) => state.qualityProfile, builder: (context, profile, _) => LunaText.subtitle(text: profile?.name ?? Constants.TEXT_EMDASH), diff --git a/lib/modules/radarr/routes/add_movie_details/widgets/tile_root_folder.dart b/lib/modules/radarr/routes/add_movie_details/widgets/tile_root_folder.dart index ea872bd7..0a4fe022 100644 --- a/lib/modules/radarr/routes/add_movie_details/widgets/tile_root_folder.dart +++ b/lib/modules/radarr/routes/add_movie_details/widgets/tile_root_folder.dart @@ -7,7 +7,7 @@ class RadarrAddMovieDetailsRootFolderTile extends StatelessWidget { Widget build(BuildContext context) { return LunaListTile( context: context, - title: LunaText.title(text: 'Root Folder'), + title: LunaText.title(text: 'radarr.RootFolder'.tr()), subtitle: Selector( selector: (_, state) => state.rootFolder, builder: (context, folder, _) => LunaText.subtitle(text: folder?.path ?? Constants.TEXT_EMDASH), diff --git a/lib/modules/radarr/routes/add_movie_details/widgets/tile_tags.dart b/lib/modules/radarr/routes/add_movie_details/widgets/tile_tags.dart index 29b0365b..fd991329 100644 --- a/lib/modules/radarr/routes/add_movie_details/widgets/tile_tags.dart +++ b/lib/modules/radarr/routes/add_movie_details/widgets/tile_tags.dart @@ -7,7 +7,7 @@ class RadarrAddMovieDetailsTagsTile extends StatelessWidget { Widget build(BuildContext context) { return LunaListTile( context: context, - title: LunaText.title(text: 'Tags'), + title: LunaText.title(text: 'radarr.Tags'.tr()), subtitle: LunaText.subtitle(text: context.watch().tags.length == 0 ? LunaUI.TEXT_EMDASH : context.watch().tags.map((e) => e.label).join(', ')), diff --git a/lib/modules/radarr/routes/catalogue/route.dart b/lib/modules/radarr/routes/catalogue/route.dart index cb7d180b..a1ed0343 100644 --- a/lib/modules/radarr/routes/catalogue/route.dart +++ b/lib/modules/radarr/routes/catalogue/route.dart @@ -70,8 +70,8 @@ class _State extends State with AutomaticKeepAliveClientMi Widget _movies(List movies, List qualityProfiles) { if((movies?.length ?? 0) == 0) return LunaMessage( - text: 'No Movies Found', - buttonText: 'Refresh', + text: 'radarr.NoMoviesFound'.tr(), + buttonText: 'lunasea.Refresh'.tr(), onTap: _refreshKey.currentState.show, ); return Selector( @@ -81,13 +81,13 @@ class _State extends State with AutomaticKeepAliveClientMi if((_filtered?.length ?? 0) == 0) return LunaListView( controller: RadarrNavigationBar.scrollControllers[0], children: [ - LunaMessage.inList(text: 'No Movies Found'), + LunaMessage.inList(text: 'radarr.NoMoviesFound'.tr()), LunaButtonContainer( children: [ LunaButton( text: query.length > 20 - ? 'Search For "${query.substring(0, 20)}${LunaUI.TEXT_ELLIPSIS}"' - : 'Search For "$query"', + ? 'radarr.SearchFor'.tr(args: ['"${query.substring(0, 20)}${LunaUI.TEXT_ELLIPSIS}"']) + : 'radarr.SearchFor'.tr(args: ['"$query"']), onTap: () async => RadarrAddMovieRouter().navigateTo(context, query: query ?? ''), ), ], diff --git a/lib/modules/radarr/routes/catalogue/widgets/search_bar_filter_button.dart b/lib/modules/radarr/routes/catalogue/widgets/search_bar_filter_button.dart index 997cdf5e..de48c13b 100644 --- a/lib/modules/radarr/routes/catalogue/widgets/search_bar_filter_button.dart +++ b/lib/modules/radarr/routes/catalogue/widgets/search_bar_filter_button.dart @@ -21,7 +21,7 @@ class _State extends State { context: context, child: Consumer( builder: (context, state, _) => LunaPopupMenuButton( - tooltip: 'Filter Catalogue', + tooltip: 'radarr.FilterCatalogue'.tr(), icon: Icons.filter_alt_outlined, onSelected: (result) { state.moviesFilterType = result; diff --git a/lib/modules/radarr/routes/catalogue/widgets/search_bar_sort_button.dart b/lib/modules/radarr/routes/catalogue/widgets/search_bar_sort_button.dart index e1217804..db86a021 100644 --- a/lib/modules/radarr/routes/catalogue/widgets/search_bar_sort_button.dart +++ b/lib/modules/radarr/routes/catalogue/widgets/search_bar_sort_button.dart @@ -21,7 +21,7 @@ class _State extends State { context: context, child: Consumer( builder: (context, state, _) => LunaPopupMenuButton( - tooltip: 'Sort Catalogue', + tooltip: 'radarr.SortCatalogue'.tr(), icon: Icons.sort, onSelected: (result) { if(state.moviesSortType == result) { diff --git a/lib/modules/radarr/routes/edit_movie/route.dart b/lib/modules/radarr/routes/edit_movie/route.dart index bb60b0bb..3ede04dc 100644 --- a/lib/modules/radarr/routes/edit_movie/route.dart +++ b/lib/modules/radarr/routes/edit_movie/route.dart @@ -46,7 +46,10 @@ class _State extends State<_RadarrMoviesEditRoute> with LunaLoadCallbackMixin, L @override Widget build(BuildContext context) { - if(widget.movieId <= 0) return LunaInvalidRoute(title: 'Edit Movie', message: 'Movie Not Found'); + if(widget.movieId <= 0) return LunaInvalidRoute( + title: 'radarr.EditMovie'.tr(), + message: 'radarr.MovieNotFound'.tr(), + ); return Scaffold( key: _scaffoldKey, appBar: _appBar(), @@ -57,7 +60,7 @@ class _State extends State<_RadarrMoviesEditRoute> with LunaLoadCallbackMixin, L Widget _appBar() { return LunaAppBar( scrollControllers: [scrollController], - title: 'Edit Movie', + title: 'radarr.EditMovie'.tr(), ); } @@ -87,7 +90,10 @@ class _State extends State<_RadarrMoviesEditRoute> with LunaLoadCallbackMixin, L return ChangeNotifierProvider( create: (_) => RadarrMoviesEditState(movie: movie, qualityProfiles: qualityProfiles, tags: tags), builder: (context, _) { - if(context.watch().state == LunaLoadingState.ERROR) return LunaMessage.goBack(context: context, text: 'An Error Has Occurred'); + if(context.watch().state == LunaLoadingState.ERROR) return LunaMessage.goBack( + context: context, + text: 'lunasea.AnErrorHasOccurred'.tr(), + ); return LunaListView( controller: scrollController, children: [ diff --git a/lib/modules/radarr/routes/edit_movie/widgets/button_update_movie.dart b/lib/modules/radarr/routes/edit_movie/widgets/button_update_movie.dart index 648fc25c..6aa5fd97 100644 --- a/lib/modules/radarr/routes/edit_movie/widgets/button_update_movie.dart +++ b/lib/modules/radarr/routes/edit_movie/widgets/button_update_movie.dart @@ -15,7 +15,7 @@ class RadarrMoviesEditUpdateMovieButton extends StatelessWidget { return LunaButtonContainer( children: [ LunaButton( - text: 'Update Movie', + text: 'radarr.UpdateMovie'.tr(), loadingState: context.watch().state, onTap: () async { context.read().state = LunaLoadingState.ACTIVE; diff --git a/lib/modules/radarr/routes/edit_movie/widgets/tile_monitored.dart b/lib/modules/radarr/routes/edit_movie/widgets/tile_monitored.dart index d08b69ca..c1b5c328 100644 --- a/lib/modules/radarr/routes/edit_movie/widgets/tile_monitored.dart +++ b/lib/modules/radarr/routes/edit_movie/widgets/tile_monitored.dart @@ -7,8 +7,8 @@ class RadarrMoviesEditMonitoredTile extends StatelessWidget { Widget build(BuildContext context) { return LunaListTile( context: context, - title: LunaText.title(text: 'Monitored'), - subtitle: LunaText.subtitle(text: 'Monitor movie for new releases'), + title: LunaText.title(text: 'radarr.Monitored'.tr()), + subtitle: LunaText.subtitle(text: 'radarr.MonitoredDescription'.tr()), trailing: LunaSwitch( value: context.watch().monitored, onChanged: (value) => context.read().monitored = value, diff --git a/lib/modules/radarr/routes/edit_movie/widgets/tile_path.dart b/lib/modules/radarr/routes/edit_movie/widgets/tile_path.dart index c553a6d1..2690714a 100644 --- a/lib/modules/radarr/routes/edit_movie/widgets/tile_path.dart +++ b/lib/modules/radarr/routes/edit_movie/widgets/tile_path.dart @@ -7,11 +7,11 @@ class RadarrMoviesEditPathTile extends StatelessWidget { Widget build(BuildContext context) { return LunaListTile( context: context, - title: LunaText.title(text: 'Movie Path'), + title: LunaText.title(text: 'radarr.MoviePath'.tr()), subtitle: LunaText.subtitle(text: context.watch().path ?? Constants.TEXT_EMDASH), trailing: LunaIconButton(icon: Icons.arrow_forward_ios_rounded), onTap: () async { - Tuple2 _values = await LunaDialogs().editText(context, 'Movie Path', prefill: context.read().path); + Tuple2 _values = await LunaDialogs().editText(context, 'radarr.MoviePath'.tr(), prefill: context.read().path); if(_values.item1) context.read().path = _values.item2; }, ); diff --git a/lib/modules/radarr/routes/edit_movie/widgets/tile_quality_profile.dart b/lib/modules/radarr/routes/edit_movie/widgets/tile_quality_profile.dart index 3b501dcb..f41defc2 100644 --- a/lib/modules/radarr/routes/edit_movie/widgets/tile_quality_profile.dart +++ b/lib/modules/radarr/routes/edit_movie/widgets/tile_quality_profile.dart @@ -14,7 +14,7 @@ class RadarrMoviesEditQualityProfileTile extends StatelessWidget { Widget build(BuildContext context) { return LunaListTile( context: context, - title: LunaText.title(text: 'Quality Profile'), + title: LunaText.title(text: 'radarr.QualityProfile'.tr()), subtitle: LunaText.subtitle(text: context.watch().qualityProfile?.name ?? Constants.TEXT_EMDASH), trailing: LunaIconButton(icon: Icons.arrow_forward_ios_rounded), onTap: () async { diff --git a/lib/modules/radarr/routes/edit_movie/widgets/tile_radarr_availability.dart b/lib/modules/radarr/routes/edit_movie/widgets/tile_radarr_availability.dart index f31b8a07..4b87bdae 100644 --- a/lib/modules/radarr/routes/edit_movie/widgets/tile_radarr_availability.dart +++ b/lib/modules/radarr/routes/edit_movie/widgets/tile_radarr_availability.dart @@ -7,7 +7,7 @@ class RadarrMoviesEditMinimumAvailabilityTile extends StatelessWidget { Widget build(BuildContext context) { return LunaListTile( context: context, - title: LunaText.title(text: 'Minimum Availability'), + title: LunaText.title(text: 'radarr.MinimumAvailability'.tr()), subtitle: LunaText.subtitle(text: context.watch().availability.readable), trailing: LunaIconButton(icon: Icons.arrow_forward_ios_rounded), onTap: () async { diff --git a/lib/modules/radarr/routes/edit_movie/widgets/tile_tags.dart b/lib/modules/radarr/routes/edit_movie/widgets/tile_tags.dart index 79c82850..52d19317 100644 --- a/lib/modules/radarr/routes/edit_movie/widgets/tile_tags.dart +++ b/lib/modules/radarr/routes/edit_movie/widgets/tile_tags.dart @@ -7,9 +7,9 @@ class RadarrMoviesEditTagsTile extends StatelessWidget { Widget build(BuildContext context) { return LunaListTile( context: context, - title: LunaText.title(text: 'Tags'), + title: LunaText.title(text: 'radarr.Tags'.tr()), subtitle: LunaText.subtitle(text: context.watch().tags.length == 0 - ? 'Not Set' + ? LunaUI.TEXT_EMDASH : context.watch().tags.map((e) => e.label).join(', ')), trailing: LunaIconButton(icon: Icons.arrow_forward_ios_rounded), onTap: () async => await RadarrDialogs().setEditTags(context), diff --git a/lib/modules/radarr/routes/history/route.dart b/lib/modules/radarr/routes/history/route.dart index e8110c64..dc1542b8 100644 --- a/lib/modules/radarr/routes/history/route.dart +++ b/lib/modules/radarr/routes/history/route.dart @@ -56,7 +56,7 @@ class _State extends State<_RadarrHistoryRoute> with LunaScrollControllerMixin { Widget _appBar() { return LunaAppBar( - title: 'History', + title: 'radarr.History'.tr(), scrollControllers: [scrollController], ); } @@ -84,7 +84,7 @@ class _State extends State<_RadarrHistoryRoute> with LunaScrollControllerMixin { pagingController: _pagingController, scrollController: scrollController, listener: _fetchPage, - noItemsFoundMessage: 'No History Found', + noItemsFoundMessage: 'radarr.NoHistoryFound'.tr(), itemBuilder: (context, history, index) { RadarrMovie _movie = movies.firstWhere((movie) => movie.id == history.movieId, orElse: () => null); return RadarrHistoryTile(history: history, title: _movie?.title); diff --git a/lib/modules/radarr/routes/missing/route.dart b/lib/modules/radarr/routes/missing/route.dart index 49e1514f..b7c0f860 100644 --- a/lib/modules/radarr/routes/missing/route.dart +++ b/lib/modules/radarr/routes/missing/route.dart @@ -59,8 +59,8 @@ class _State extends State with AutomaticKeepAliveClientMixi Widget _list(List movies, List qualityProfiles) { if((movies?.length ?? 0) == 0) return LunaMessage( - text: 'No Movies Found', - buttonText: 'Refresh', + text: 'radarr.NoMoviesFound'.tr(), + buttonText: 'lunasea.Refresh'.tr(), onTap: _refreshKey.currentState.show, ); return LunaListViewBuilder( diff --git a/lib/modules/radarr/routes/missing/widgets/missing_tile.dart b/lib/modules/radarr/routes/missing/widgets/missing_tile.dart index 6f630044..caa3aa34 100644 --- a/lib/modules/radarr/routes/missing/widgets/missing_tile.dart +++ b/lib/modules/radarr/routes/missing/widgets/missing_tile.dart @@ -68,7 +68,7 @@ class _State extends State { fontWeight: LunaUI.FONT_WEIGHT_BOLD, color: LunaColours.red, ), - text: _days == null ? 'Released' : _days == 'Today' ? 'Released Today' : 'Released $_days Ago' + text: _days == null ? 'radarr.Released'.tr() : _days == 'Today' ? 'radarr.ReleasedToday'.tr() : 'Released $_days Ago' ); } diff --git a/lib/modules/radarr/routes/more/route.dart b/lib/modules/radarr/routes/more/route.dart index 1afa6aaa..bd7a902e 100644 --- a/lib/modules/radarr/routes/more/route.dart +++ b/lib/modules/radarr/routes/more/route.dart @@ -28,29 +28,29 @@ class _State extends State with AutomaticKeepAliveClientMixin { children: [ LunaListTile( context: context, - title: LunaText.title(text: 'History'), - subtitle: LunaText.subtitle(text: 'View Recent Activity'), + title: LunaText.title(text: 'radarr.History'.tr()), + subtitle: LunaText.subtitle(text: 'radarr.HistoryDescription'.tr()), trailing: LunaIconButton(icon: CustomIcons.history, color: LunaColours.list(0)), onTap: () async => RadarrHistoryRouter().navigateTo(context), ), LunaListTile( context: context, - title: LunaText.title(text: 'Queue'), - subtitle: LunaText.subtitle(text: 'View Active & Queued Content'), + title: LunaText.title(text: 'radarr.Queue'.tr()), + subtitle: LunaText.subtitle(text: 'radarr.QueueDescription'.tr()), trailing: LunaIconButton(icon: Icons.queue, color: LunaColours.list(1)), onTap: () async => RadarrQueueRouter().navigateTo(context), ), LunaListTile( context: context, - title: LunaText.title(text: 'System Status'), - subtitle: LunaText.subtitle(text: 'System Status & Disk Space'), + title: LunaText.title(text: 'radarr.SystemStatus'.tr()), + subtitle: LunaText.subtitle(text: 'radarr.SystemStatusDescription'.tr()), trailing: LunaIconButton(icon: CustomIcons.monitoring, color: LunaColours.list(2)), onTap: () async => RadarrSystemStatusRouter().navigateTo(context), ), LunaListTile( context: context, - title: LunaText.title(text: 'Tags'), - subtitle: LunaText.subtitle(text: 'Manage Your Tags'), + title: LunaText.title(text: 'radarr.Tags'.tr()), + subtitle: LunaText.subtitle(text: 'radarr.TagsDescription'.tr()), trailing: LunaIconButton(icon: Icons.style, color: LunaColours.list(3)), onTap: () async => RadarrTagsRouter().navigateTo(context), ), diff --git a/lib/modules/radarr/routes/movie_details/widgets/overview_movie_links_section.dart b/lib/modules/radarr/routes/movie_details/widgets/overview_movie_links_section.dart index 9534b543..31cad81a 100644 --- a/lib/modules/radarr/routes/movie_details/widgets/overview_movie_links_section.dart +++ b/lib/modules/radarr/routes/movie_details/widgets/overview_movie_links_section.dart @@ -18,45 +18,52 @@ class RadarrMovieDetailsOverviewLinksSection extends StatelessWidget { context: context, child: InkWell( child: Padding( - child: Image.asset( - 'assets/images/services/imdb.png', - height: 21.0, - ), - padding: EdgeInsets.all(18.0), + child: Image.asset('assets/images/services/imdb.png'), + padding: EdgeInsets.all(12.0), ), borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), onTap: () async => await movie?.imdbId?.lunaOpenIMDB(), ), + height: 50.0, margin: EdgeInsets.symmetric(horizontal: 6.0, vertical: 6.0), ), if(movie.tmdbId != null && movie.tmdbId != 0) LunaCard( context: context, child: InkWell( child: Padding( - child: Image.asset( - 'assets/images/services/themoviedb.png', - height: 22.0, - ), - padding: EdgeInsets.all(17.0), + child: Image.asset('assets/images/services/themoviedb.png'), + padding: EdgeInsets.all(12.0), ), borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), onTap: () async => await movie?.tmdbId?.toString()?.lunaOpenTheMovieDBMovie(), ), + height: 50.0, + margin: EdgeInsets.symmetric(horizontal: 6.0, vertical: 6.0), + ), + if(movie.tmdbId != null && movie.tmdbId != 0) LunaCard( + context: context, + child: InkWell( + child: Padding( + child: Image.asset('assets/images/services/trakt.png'), + padding: EdgeInsets.all(12.0), + ), + borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), + onTap: () async => await movie?.tmdbId?.toString()?.lunaOpenTraktMovie(), + ), + height: 50.0, margin: EdgeInsets.symmetric(horizontal: 6.0, vertical: 6.0), ), if(movie.youTubeTrailerId != null && movie.youTubeTrailerId.isNotEmpty) LunaCard( context: context, child: InkWell( child: Padding( - child: Image.asset( - 'assets/images/services/youtube.png', - height: 17.0, - ), - padding: EdgeInsets.all(20.0), + child: Image.asset('assets/images/services/youtube.png'), + padding: EdgeInsets.all(12.0), ), borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), onTap: () async => await movie?.youTubeTrailerId?.lunaOpenYouTube(), ), + height: 50.0, margin: EdgeInsets.symmetric(horizontal: 6.0, vertical: 6.0), ), ], diff --git a/lib/modules/radarr/routes/movie_details/widgets/page_overview.dart b/lib/modules/radarr/routes/movie_details/widgets/page_overview.dart index c8a0cd5b..98486ddb 100644 --- a/lib/modules/radarr/routes/movie_details/widgets/page_overview.dart +++ b/lib/modules/radarr/routes/movie_details/widgets/page_overview.dart @@ -35,13 +35,13 @@ class _State extends State with AutomaticKeepAli controller: RadarrMovieDetailsNavigationBar.scrollControllers[0], children: [ RadarrMovieDetailsOverviewDescriptionTile(movie: widget.movie), + RadarrMovieDetailsOverviewLinksSection(movie: widget.movie), RadarrMovieDetailsOverviewDownloadButtons(movie: widget.movie), RadarrMovieDetailsOverviewInformationBlock( movie: widget.movie, qualityProfile: widget.qualityProfile, tags: widget.tags, ), - RadarrMovieDetailsOverviewLinksSection(movie: widget.movie), ], ), ), diff --git a/lib/modules/radarr/routes/queue/route.dart b/lib/modules/radarr/routes/queue/route.dart index 831e53e3..337c2800 100644 --- a/lib/modules/radarr/routes/queue/route.dart +++ b/lib/modules/radarr/routes/queue/route.dart @@ -22,13 +22,13 @@ class _State extends State<_RadarrQueueRoute> { return Scaffold( key: _scaffoldKey, appBar: _appBar(), - body: LunaMessage.goBack(context: context, text: 'Coming Soon'), + body: LunaMessage.goBack(context: context, text: 'lunasea.ComingSoon'.tr()), ); } Widget _appBar() { return LunaAppBar( - title: 'Queue', + title: 'radarr.Queue'.tr(), ); } } diff --git a/lib/modules/radarr/routes/radarr/route.dart b/lib/modules/radarr/routes/radarr/route.dart index 4b1b2217..9de2a087 100644 --- a/lib/modules/radarr/routes/radarr/route.dart +++ b/lib/modules/radarr/routes/radarr/route.dart @@ -48,7 +48,7 @@ class _State extends State<_RadarrHomeRoute> { return false; } - Widget _drawer() => LSDrawer(page: 'radarr'); + Widget _drawer() => LunaDrawer(page: LunaModule.RADARR.key); Widget _bottomNavigationBar() { if(context.read().enabled) return RadarrNavigationBar(pageController: _pageController); diff --git a/lib/modules/radarr/routes/radarr/widgets/navigation_bar.dart b/lib/modules/radarr/routes/radarr/widgets/navigation_bar.dart index f2f489d2..7c388fe1 100644 --- a/lib/modules/radarr/routes/radarr/widgets/navigation_bar.dart +++ b/lib/modules/radarr/routes/radarr/widgets/navigation_bar.dart @@ -3,9 +3,21 @@ import 'package:lunasea/core.dart'; class RadarrNavigationBar extends StatelessWidget { final PageController pageController; - static const List icons = [CustomIcons.movies, CustomIcons.upcoming, CustomIcons.calendar_missing, Icons.more_horiz]; - static const List titles = ['Movies', 'Upcoming', 'Missing', 'More']; - static List scrollControllers = List.generate(titles.length, (_) => ScrollController()); + static List scrollControllers = List.generate(icons.length, (_) => ScrollController()); + + static const List icons = [ + CustomIcons.movies, + CustomIcons.upcoming, + CustomIcons.calendar_missing, + Icons.more_horiz, + ]; + + static List get titles => [ + 'radarr.Movies'.tr(), + 'radarr.Upcoming'.tr(), + 'radarr.Missing'.tr(), + 'radarr.More'.tr(), + ]; RadarrNavigationBar({ Key key, diff --git a/lib/modules/radarr/routes/upcoming/route.dart b/lib/modules/radarr/routes/upcoming/route.dart index aff307fb..b7e36b51 100644 --- a/lib/modules/radarr/routes/upcoming/route.dart +++ b/lib/modules/radarr/routes/upcoming/route.dart @@ -63,8 +63,8 @@ class _State extends State with AutomaticKeepAliveClientMix List qualityProfiles, ) { if((movies?.length ?? 0) == 0) return LunaMessage( - text: 'No Movies Found', - buttonText: 'Refresh', + text: 'radarr.NoMoviesFound'.tr(), + buttonText: 'lunasea.Refresh'.tr(), onTap: _refreshKey.currentState.show, ); return LunaListViewBuilder( diff --git a/lib/modules/radarr/routes/upcoming/widgets/upcoming_tile.dart b/lib/modules/radarr/routes/upcoming/widgets/upcoming_tile.dart index 92bd52da..38f6cd53 100644 --- a/lib/modules/radarr/routes/upcoming/widgets/upcoming_tile.dart +++ b/lib/modules/radarr/routes/upcoming/widgets/upcoming_tile.dart @@ -84,8 +84,20 @@ class _State extends State { color: color, ), children: [ - if(type == 'release') TextSpan(text: _days == null ? 'Availability Unknown' : _days == 'Today' ? 'Available Today' : 'Available in $_days'), - if(type == 'cinema') TextSpan(text: _days == null ? 'Cinema Date Unknown' : _days == 'Today' ? 'In Cinemas Today' : 'In Cinemas in $_days'), + if(type == 'release') TextSpan( + text: _days == null + ? 'radarr.AvailabilityUnknown'.tr() + : _days == 'Today' + ? 'radarr.AvailableToday'.tr() + : 'radarr.AvailableIn'.tr(args: [_days]), + ), + if(type == 'cinema') TextSpan( + text: _days == null + ? 'radarr.CinemaDateUnknown'.tr() + : _days == 'Today' + ? 'radarr.InCinemasToday'.tr() + : 'radarr.InCinemasIn'.tr(args: [_days]), + ), if(type == 'unknown') TextSpan(text: _days), ], ); diff --git a/lib/modules/sabnzbd/routes/sabnzbd.dart b/lib/modules/sabnzbd/routes/sabnzbd.dart index 5a71fdce..b6450cd1 100644 --- a/lib/modules/sabnzbd/routes/sabnzbd.dart +++ b/lib/modules/sabnzbd/routes/sabnzbd.dart @@ -54,7 +54,7 @@ class _State extends State { ), ); - Widget get _drawer => LSDrawer(page: 'sabnzbd'); + Widget get _drawer => LunaDrawer(page: LunaModule.SABNZBD.key); Widget get _bottomNavigationBar => SABnzbdNavigationBar(pageController: _pageController); diff --git a/lib/modules/search/core/api/api.dart b/lib/modules/search/core/api/api.dart index 398290c6..aef97dce 100644 --- a/lib/modules/search/core/api/api.dart +++ b/lib/modules/search/core/api/api.dart @@ -1,8 +1,9 @@ import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; -import 'package:xml_parser/xml_parser.dart'; +//import 'package:xml_parser/xml_parser.dart'; import 'package:lunasea/core.dart'; import 'package:lunasea/modules/search.dart'; +import 'package:xml/xml.dart'; class NewznabAPI { final Map _values; @@ -48,70 +49,59 @@ class NewznabAPI { } Future> getCategories() async { - try { - Response response = await _dio.get( - '', - queryParameters: { - 't': 'caps', - }, - ); - XmlDocument _xml = XmlDocument.fromString(response.data); - List _results = []; - for(XmlElement _category in _xml?.root?.getChild('categories')?.getChildren('Category') ?? []) { - NewznabCategoryData _data = NewznabCategoryData( - id: int.tryParse(_category.attributes.firstWhere((attr) => attr.name.toString() == 'id')?.value) ?? -1, - name: _category.attributes.firstWhere((attr) => attr.name.toString() == 'name')?.value ?? 'Unknown Category', - ); - for(XmlElement _subcategory in _category?.getChildren('subcat') ?? []) { - _data.subcategories.add(NewznabSubcategoryData( - id: int.tryParse(_subcategory.attributes.firstWhere((attr) => attr.name.toString() == 'id')?.value) ?? -1, - name: _subcategory.attributes.firstWhere((attr) => attr.name.toString() == 'name')?.value ?? 'Unknown Subcategory', + Response response = await _dio.get( + '', + queryParameters: { + 't': 'caps', + }, + ); + List results = []; + XmlDocument xml = XmlDocument.parse(response.data); + xml.getElement('caps').getElement('categories').findElements('category').forEach((cat) { + String catName = cat.getAttribute('name'); + int catId = int.tryParse(cat.getAttribute('id') ?? 'noid'); + if((catName?.isNotEmpty ?? false) && (catId != null)) { + NewznabCategoryData data = NewznabCategoryData(id: catId, name: catName); + cat.findElements('subcat').forEach((subcat) { + String subcatName = subcat.getAttribute('name'); + int subcatId = int.tryParse(subcat.getAttribute('id') ?? 'noid'); + if((subcatName?.isNotEmpty ?? false) && (subcatId != null)) data.subcategories.add(NewznabSubcategoryData( + id: subcatId, + name: subcatName, )); - } - _results.add(_data); + }); + results.add(data); } - return _results; - } on DioError catch (error, stack) { - logError('Unable to fetch categories', error, stack); - return Future.error(error); - } catch (error, stack) { - logError('Unable to fetch categories', error, stack); - return Future.error(error); - } + }); + return results; } Future> getResults({ @required int categoryId, @required String query, int offset = 0 }) async { - try { - Response response = await _dio.get( - '', - queryParameters: { - 't': 'search', - if(categoryId != -1) 'cat': categoryId, - if(query != '') 'q': query, - 'limit': 100, - 'extended': 1, - 'offset': 100*offset, - }, + Response response = await _dio.get( + '', + queryParameters: { + 't': 'search', + if(categoryId != -1) 'cat': categoryId, + if(query != '') 'q': query, + 'limit': 10, + 'extended': 1, + 'offset': 10*offset, + }, + ); + List results = []; + XmlDocument xml = XmlDocument.parse(response.data); + xml.getElement('rss')?.getElement('channel')?.findElements('item')?.forEach((item) { + int size = int.tryParse(item.getElement('enclosure')?.getAttribute('length') ?? 'nosize'); + NewznabResultData data = NewznabResultData( + title: item.getElement('title')?.innerText ?? 'Unknown Title', + category: item.getElement('category')?.innerText ?? 'Unknown Category', + size: size ?? 0, + linkComments: item.getElement('comments')?.innerText ?? '', + linkDownload: item.getElement('link')?.innerText ?? '', + date: item.getElement('pubDate')?.innerText ?? 'Unknown Date', ); - XmlDocument _xml = XmlDocument.fromString(response.data); - List _results = []; - for(XmlElement _item in _xml?.root?.getChild('channel')?.getChildren('item') ?? []) { - _results.add(NewznabResultData( - title: _item.getChild('title')?.text ?? 'Unknown Result', - category: _item.getChild('category')?.text ?? 'Unknown Category', - size: int.tryParse(_item.getChild('enclosure')?.getAttribute('length')) ?? 0, - linkComments: _item?.getChild('comments')?.text ?? '', - linkDownload: _item?.getChild('link')?.text ?? '', - date: _item?.getChild('pubDate')?.text ?? 'Unknown Date', - )); - } - return _results; - } on DioError catch (error, stack) { - logError('Unable to fetch results', error, stack); - return Future.error(error); - } catch (error, stack) { - logError('Unable to fetch results', error, stack); - return Future.error(error); - } + results.add(data); + }); + return results; } } diff --git a/lib/modules/search/core/api/data/result.dart b/lib/modules/search/core/api/data/result.dart index b0774114..0ce8457f 100644 --- a/lib/modules/search/core/api/data/result.dart +++ b/lib/modules/search/core/api/data/result.dart @@ -22,10 +22,17 @@ class NewznabResultData { DateTime get dateObject { try { DateFormat _format = DateFormat("EEE, dd MMM yyyy hh:mm:ss"); - int _offset = int.tryParse(date.substring(date.length - 5)); - DateTime _date = _format.parseUtc(date); + String _dateFixed = [ + date.substring(0, 3), + '.', + date.substring(3, 11), + '.', + date.substring(11, date.length), + ].join(); + int _offset = int.tryParse(_dateFixed.substring(_dateFixed.length - 5)); + DateTime _date = _format.parseUtc(_dateFixed); if(_offset != null) _date = _date.add(Duration(hours: (-(_offset/100).round()))); - return _date.toLocal(); + return _date.toLocal().isAfter(DateTime.now()) ? DateTime.now() : _date.toLocal(); } catch (e) {} return null; } diff --git a/lib/modules/search/routes/categories.dart b/lib/modules/search/routes/categories.dart index 0ff12595..b59eed5b 100644 --- a/lib/modules/search/routes/categories.dart +++ b/lib/modules/search/routes/categories.dart @@ -52,7 +52,10 @@ class _State extends State { builder: (context, snapshot) { switch(snapshot.connectionState) { case ConnectionState.done: { - if(snapshot.hasError || snapshot.data == null) return LSErrorMessage(onTapHandler: () => _refresh()); + if(snapshot.hasError || snapshot.data == null) { + LunaLogger().error('Unable to fetch categories', snapshot.error, snapshot.stackTrace); + return LSErrorMessage(onTapHandler: () => _refresh()); + } return _list(snapshot.data); } case ConnectionState.none: diff --git a/lib/modules/search/routes/indexers.dart b/lib/modules/search/routes/indexers.dart index 46017677..d40862eb 100644 --- a/lib/modules/search/routes/indexers.dart +++ b/lib/modules/search/routes/indexers.dart @@ -42,7 +42,7 @@ class _State extends State { title: 'Search', ); - Widget get _drawer => LSDrawer(page: 'search'); + Widget get _drawer => LunaDrawer(page: LunaModule.SEARCH.key); Widget get _body => LSListView( children: [..._indexerList], diff --git a/lib/modules/search/routes/results.dart b/lib/modules/search/routes/results.dart index 627604df..5a202d1f 100644 --- a/lib/modules/search/routes/results.dart +++ b/lib/modules/search/routes/results.dart @@ -57,7 +57,10 @@ class _State extends State { builder: (context, snapshot) { switch(snapshot.connectionState) { case ConnectionState.done: { - if(snapshot.hasError || snapshot.data == null) return LSErrorMessage(onTapHandler: () => _refresh()); + if(snapshot.hasError || snapshot.data == null) { + LunaLogger().error('Unable to fetch results', snapshot.error, snapshot.stackTrace); + return LSErrorMessage(onTapHandler: () => _refresh()); + } _results = snapshot.data; return _list; } diff --git a/lib/modules/search/routes/search.dart b/lib/modules/search/routes/search.dart index 19d65b0f..a19e0567 100644 --- a/lib/modules/search/routes/search.dart +++ b/lib/modules/search/routes/search.dart @@ -48,6 +48,7 @@ class _State extends State { switch(snapshot.connectionState) { case ConnectionState.done: { if(snapshot.hasError || snapshot.data == null) { + LunaLogger().error('Unable to fetch results', snapshot.error, snapshot.stackTrace); _data = _error; } else { _results = snapshot.data; diff --git a/lib/modules/settings/core/dialogs.dart b/lib/modules/settings/core/dialogs.dart index 250fb44f..15c9571a 100644 --- a/lib/modules/settings/core/dialogs.dart +++ b/lib/modules/settings/core/dialogs.dart @@ -27,7 +27,7 @@ class SettingsDialogs { ], content: [ LSDialog.textContent( - text: 'Are you sure you want to sign out of your ${Constants.APPLICATION_NAME} account?' + text: 'Are you sure you want to sign out of your LunaSea account?' ), ], contentPadding: LSDialog.textDialogContentPadding(), @@ -530,6 +530,34 @@ class SettingsDialogs { return Tuple2(_flag, _browser); } + Future> changeLanguage(BuildContext context) async { + List languages = LunaLocalization().supportedLanguages; + bool _flag = false; + LunaLanguage _language; + + void _setValues(bool flag, LunaLanguage language) { + _flag = flag; + _language = language; + Navigator.of(context, rootNavigator: true).pop(); + } + + await LSDialog.dialog( + context: context, + title: 'Language', + content: List.generate( + languages.length, + (index) => LSDialog.tile( + icon: Icons.language_rounded, + iconColor: LunaColours.list(index), + text: languages[index].name, + onTap: () => _setValues(true, languages[index]), + ), + ), + contentPadding: LSDialog.listDialogContentPadding(), + ); + return Tuple2(_flag, _language); + } + static Future> editCalendarStartingDay(BuildContext context) async { bool _flag = false; CalendarStartingDay _startingDate; @@ -828,7 +856,7 @@ class SettingsDialogs { return [_flag, _textController.text]; } - Future disableSentryWarning(BuildContext context) async { + Future disableCrashlyticsWarning(BuildContext context) async { bool _flag = false; void _setValues(bool flag) { @@ -838,11 +866,11 @@ class SettingsDialogs { await LSDialog.dialog( context: context, - title: 'Sentry', + title: 'Firebase Crashlytics', buttons: [ LSDialog.button( text: 'Website', - onPressed: () => Constants.URL_SENTRY.lunaOpenGenericLink(), + onPressed: () => Constants.URL_CRASHLYTICS.lunaOpenGenericLink(), textColor: LunaColours.accent, ), LSDialog.button( @@ -859,10 +887,11 @@ class SettingsDialogs { color: LunaColours.red, fontSize: LSDialog.SUBBODY_SIZE, ), - LSDialog.textSpanContent(text: 'Sentry is an open-source platform used for capturing crashes and errors.\n\n'), - LSDialog.textSpanContent(text: 'To reserve your right to privacy, I have added the option to disable Sentry error tracking, but please know that these errors and stacktraces are incredibly useful for catching and pinpointing bugs!\n\n'), + LSDialog.textSpanContent(text: 'Firebase Crashlytics is a tool used for capturing crashes and errors.\n\n'), + LSDialog.textSpanContent(text: 'To reserve your right to privacy, you have the option to disable error and crash tracking, but please know that these errors and stacktraces are incredibly useful for catching and pinpointing bugs!\n\n'), + LSDialog.textSpanContent(text: 'A link to the Firebase website is available below for more information to help make an informed decision.\n\n'), LSDialog.bolded( - text: 'A link to their website is available below for more information to help make an informed decision.', + text: 'A restart of LunaSea is required for the changes to take effect.', color: LunaColours.accent, fontSize: LSDialog.SUBBODY_SIZE, ), @@ -999,7 +1028,7 @@ class SettingsDialogs { }, ), ], - content: [LSDialog.textContent(text: '${Constants.APPLICATION_NAME} offers a free account to backup your configuration to the cloud, with additional features coming in the future!')], + content: [LSDialog.textContent(text: 'LunaSea offers a free account to backup your configuration to the cloud, with additional features coming in the future!')], contentPadding: LSDialog.textDialogContentPadding(), ); } diff --git a/lib/modules/settings/routes/account/pages/signed_in.dart b/lib/modules/settings/routes/account/pages/signed_in.dart index 271be87f..443444f1 100644 --- a/lib/modules/settings/routes/account/pages/signed_in.dart +++ b/lib/modules/settings/routes/account/pages/signed_in.dart @@ -37,7 +37,7 @@ class _State extends State { onTap: () async { bool result = await SettingsDialogs().confirmAccountSignOut(context); if(result) LunaFirebaseAuth().signOut() - .then((_) => showLunaSuccessSnackBar(context: context, title: 'Signed Out', message: 'Signed out of your ${Constants.APPLICATION_NAME} account')) + .then((_) => showLunaSuccessSnackBar(context: context, title: 'Signed Out', message: 'Signed out of your LunaSea account')) .catchError((error, stack) { LunaLogger().error('Failed to sign out', error, stack); showLunaErrorSnackBar(context: context, title: 'Failed to Sign Out', error: error); diff --git a/lib/modules/settings/routes/configuration_lidarr/pages/connection_details.dart b/lib/modules/settings/routes/configuration_lidarr/pages/connection_details.dart index e9fd85e1..77243812 100644 --- a/lib/modules/settings/routes/configuration_lidarr/pages/connection_details.dart +++ b/lib/modules/settings/routes/configuration_lidarr/pages/connection_details.dart @@ -113,7 +113,7 @@ class _State extends State<_SettingsConfigurationLidarrRoute> with LunaScrollCon .then((_) => showLunaSuccessSnackBar( context: context, title: 'Connected Successfully', - message: 'Lidarr is ready to use with ${Constants.APPLICATION_NAME}', + message: 'Lidarr is ready to use with LunaSea', )).catchError((error, trace) { LunaLogger().error('Connection Test Failed', error, trace); showLunaErrorSnackBar( diff --git a/lib/modules/settings/routes/configuration_nzbget/pages/connection_details.dart b/lib/modules/settings/routes/configuration_nzbget/pages/connection_details.dart index ae5eafe8..d2e13c67 100644 --- a/lib/modules/settings/routes/configuration_nzbget/pages/connection_details.dart +++ b/lib/modules/settings/routes/configuration_nzbget/pages/connection_details.dart @@ -133,7 +133,7 @@ class _State extends State<_SettingsConfigurationNZBGetRoute> with LunaScrollCon .then((_) => showLunaSuccessSnackBar( context: context, title: 'Connected Successfully', - message: 'NZBGet is ready to use with ${Constants.APPLICATION_NAME}', + message: 'NZBGet is ready to use with LunaSea', )).catchError((error, trace) { LunaLogger().error('Connection Test Failed', error, trace); showLunaErrorSnackBar( diff --git a/lib/modules/settings/routes/configuration_quickactions.dart b/lib/modules/settings/routes/configuration_quickactions.dart index 847bc311..c10a3770 100644 --- a/lib/modules/settings/routes/configuration_quickactions.dart +++ b/lib/modules/settings/routes/configuration_quickactions.dart @@ -36,7 +36,7 @@ class _State extends State<_SettingsConfigurationQuickActionsRoute> with LunaScr context, 'Quick Actions', [ - 'Quick actions allow you to quickly jump into modules directly from the home screen or launcher on your device by long pressing ${Constants.APPLICATION_NAME}\'s icon.', + 'Quick actions allow you to quickly jump into modules directly from the home screen or launcher on your device by long pressing LunaSea\'s icon.', 'A limited number of quick actions can be set at a time, and enabling more than your launcher can support will have no effect.' ].join('\n\n'), ), diff --git a/lib/modules/settings/routes/configuration_radarr/pages/connection_details.dart b/lib/modules/settings/routes/configuration_radarr/pages/connection_details.dart index 08ef1046..5ffb9a71 100644 --- a/lib/modules/settings/routes/configuration_radarr/pages/connection_details.dart +++ b/lib/modules/settings/routes/configuration_radarr/pages/connection_details.dart @@ -113,7 +113,7 @@ class _State extends State<_SettingsConfigurationRadarrRoute> with LunaScrollCon .system.status().then((_) => showLunaSuccessSnackBar( context: context, title: 'Connected Successfully', - message: 'Radarr is ready to use with ${Constants.APPLICATION_NAME}', + message: 'Radarr is ready to use with LunaSea', )).catchError((error, trace) { LunaLogger().error('Connection Test Failed', error, trace); showLunaErrorSnackBar( diff --git a/lib/modules/settings/routes/configuration_radarr/pages/default_sorting.dart b/lib/modules/settings/routes/configuration_radarr/pages/default_sorting.dart index 6e820b2c..6bf50277 100644 --- a/lib/modules/settings/routes/configuration_radarr/pages/default_sorting.dart +++ b/lib/modules/settings/routes/configuration_radarr/pages/default_sorting.dart @@ -116,11 +116,7 @@ class _State extends State<_SettingsConfigurationRadarrRoute> with LunaScrollCon onTap: () async { List titles = RadarrReleasesSorting.values.map((e) => e.readable).toList(); Tuple2 values = await RadarrDialogs().setDefaultSortingOrFiltering(context, titles: titles); - if(values.item1) { - RadarrDatabaseValue.DEFAULT_SORTING_RELEASES.put(RadarrReleasesSorting.values[values.item2]); - context.read().moviesSortType = RadarrDatabaseValue.DEFAULT_SORTING_RELEASES.data; - context.read().moviesSortAscending = RadarrDatabaseValue.DEFAULT_SORTING_RELEASES_ASCENDING.data; - } + if(values.item1) RadarrDatabaseValue.DEFAULT_SORTING_RELEASES.put(RadarrReleasesSorting.values[values.item2]); }, ), ); diff --git a/lib/modules/settings/routes/configuration_sabnzbd/pages/connection_details.dart b/lib/modules/settings/routes/configuration_sabnzbd/pages/connection_details.dart index 6847c31f..b84de25f 100644 --- a/lib/modules/settings/routes/configuration_sabnzbd/pages/connection_details.dart +++ b/lib/modules/settings/routes/configuration_sabnzbd/pages/connection_details.dart @@ -113,7 +113,7 @@ class _State extends State<_SettingsConfigurationSABnzbdRoute> with LunaScrollCo .then((_) => showLunaSuccessSnackBar( context: context, title: 'Connected Successfully', - message: 'SABnzbd is ready to use with ${Constants.APPLICATION_NAME}', + message: 'SABnzbd is ready to use with LunaSea', )).catchError((error, trace) { LunaLogger().error('Connection Test Failed', error, trace); showLunaErrorSnackBar( diff --git a/lib/modules/settings/routes/configuration_sonarr/pages/connection_details.dart b/lib/modules/settings/routes/configuration_sonarr/pages/connection_details.dart index 7b40c22e..6837a0a9 100644 --- a/lib/modules/settings/routes/configuration_sonarr/pages/connection_details.dart +++ b/lib/modules/settings/routes/configuration_sonarr/pages/connection_details.dart @@ -130,7 +130,7 @@ class _State extends State<_SettingsConfigurationSonarrRoute> with LunaScrollCon .system.getStatus().then((_) => showLunaSuccessSnackBar( context: context, title: 'Connected Successfully', - message: 'Sonarr is ready to use with ${Constants.APPLICATION_NAME}', + message: 'Sonarr is ready to use with LunaSea', )).catchError((error, trace) { LunaLogger().error('Connection Test Failed', error, trace); showLunaErrorSnackBar( diff --git a/lib/modules/settings/routes/configuration_tautulli/pages/connection_details.dart b/lib/modules/settings/routes/configuration_tautulli/pages/connection_details.dart index 1d1d8e58..03f0e106 100644 --- a/lib/modules/settings/routes/configuration_tautulli/pages/connection_details.dart +++ b/lib/modules/settings/routes/configuration_tautulli/pages/connection_details.dart @@ -113,7 +113,7 @@ class _State extends State<_SettingsConfigurationTautulliRoute> with LunaScrollC .miscellaneous.arnold().then((_) => showLunaSuccessSnackBar( context: context, title: 'Connected Successfully', - message: 'Tautulli is ready to use with ${Constants.APPLICATION_NAME}', + message: 'Tautulli is ready to use with LunaSea', )).catchError((error, trace) { LunaLogger().error('Connection Test Failed', error, trace); showLunaErrorSnackBar( diff --git a/lib/modules/settings/routes/donations/pages/thank_you.dart b/lib/modules/settings/routes/donations/pages/thank_you.dart index b83f3857..b56200a3 100644 --- a/lib/modules/settings/routes/donations/pages/thank_you.dart +++ b/lib/modules/settings/routes/donations/pages/thank_you.dart @@ -40,7 +40,7 @@ class _State extends State<_SettingsDonationsThankYouRoute> with LunaScrollContr text: 'Thank You', subtitle: [ "Thank you for supporting the open-source community!", - "Donations are never expected or assumed, so thank you for giving back and helping ${Constants.APPLICATION_NAME} remain free, forever!", + "Donations are never expected or assumed, so thank you for giving back and helping LunaSea remain free, forever!", ].join("\n\n"), ), ], diff --git a/lib/modules/settings/routes/profiles.dart b/lib/modules/settings/routes/profiles.dart index aa89f30f..4f58c636 100644 --- a/lib/modules/settings/routes/profiles.dart +++ b/lib/modules/settings/routes/profiles.dart @@ -35,9 +35,9 @@ class _State extends State<_SettingsProfilesRoute> with LunaScrollControllerMixi context, 'Profiles', [ - 'Profiles allow you to add multiple instances of modules into ${Constants.APPLICATION_NAME}.', + 'Profiles allow you to add multiple instances of modules into LunaSea.', 'Newznab indexer searching is enabled and shared across all profiles.', - 'You can switch between profiles in the main navigation drawer of ${Constants.APPLICATION_NAME}.', + 'You can switch between profiles in the main navigation drawer of LunaSea.', ].join('\n\n'), ), ), diff --git a/lib/modules/settings/routes/resources.dart b/lib/modules/settings/routes/resources.dart index ce662309..43c2db92 100644 --- a/lib/modules/settings/routes/resources.dart +++ b/lib/modules/settings/routes/resources.dart @@ -80,10 +80,17 @@ class _State extends State<_SettingsResourcesRoute> with LunaScrollControllerMix trailing: LunaIconButton(icon: Icons.developer_board), onTap: () async => await Constants.URL_TESTFLIGHT.lunaOpenGenericLink() ), + LunaListTile( + context: context, + title: LunaText.title(text: 'Weblate'), + subtitle: LunaText.subtitle(text: 'Help Localize LunaSea'), + trailing: LunaIconButton(icon: Icons.translate), + onTap: () async => await Constants.URL_WEBLATE.lunaOpenGenericLink(), + ), LunaListTile( context: context, title: LunaText.title(text: 'Website'), - subtitle: LunaText.subtitle(text: 'Visit ${Constants.APPLICATION_NAME}\'s Website'), + subtitle: LunaText.subtitle(text: 'Visit LunaSea\'s Website'), trailing: LunaIconButton(icon: CustomIcons.home), onTap: () async => await Constants.URL_WEBSITE.lunaOpenGenericLink(), ), diff --git a/lib/modules/settings/routes/settings.dart b/lib/modules/settings/routes/settings.dart index 9b226f84..fa9989f9 100644 --- a/lib/modules/settings/routes/settings.dart +++ b/lib/modules/settings/routes/settings.dart @@ -37,7 +37,7 @@ class _State extends State<_SettingsHomeRoute> with LunaScrollControllerMixin { return false; } - Widget _drawer() => LSDrawer(page: LunaModule.SETTINGS.key); + Widget _drawer() => LunaDrawer(page: LunaModule.SETTINGS.key); Widget _appBar() { return LunaAppBar( @@ -54,14 +54,14 @@ class _State extends State<_SettingsHomeRoute> with LunaScrollControllerMixin { LunaListTile( context: context, title: LunaText.title(text: 'Account'), - subtitle: LunaText.subtitle(text: 'Your ${Constants.APPLICATION_NAME} Account'), + subtitle: LunaText.subtitle(text: 'Your LunaSea Account'), trailing: LunaIconButton(icon: Icons.account_circle), onTap: () async => SettingsAccountRouter().navigateTo(context), ), LunaListTile( context: context, title: LunaText.title(text: 'Configuration'), - subtitle: LunaText.subtitle(text: 'Configure & Setup ${Constants.APPLICATION_NAME}'), + subtitle: LunaText.subtitle(text: 'Configure & Setup LunaSea'), trailing: LunaIconButton(icon: Icons.device_hub), onTap: () async => SettingsConfigurationRouter().navigateTo(context), ), diff --git a/lib/modules/settings/routes/system/route.dart b/lib/modules/settings/routes/system/route.dart index 2c9cd982..cb6007b0 100644 --- a/lib/modules/settings/routes/system/route.dart +++ b/lib/modules/settings/routes/system/route.dart @@ -45,6 +45,7 @@ class _State extends State<_SettingsSystemRoute> with LunaScrollControllerMixin SettingsSystemBackupRestoreBackupTile(), SettingsSystemBackupRestoreRestoreTile(), LunaDivider(), + _language(), _enableSentry(), _clearConfiguration(), ], @@ -63,11 +64,24 @@ class _State extends State<_SettingsSystemRoute> with LunaScrollControllerMixin ), subtitle: LunaText.subtitle(text: 'View Recent Changes'), trailing: LunaIconButton(icon: Icons.system_update), - onTap: LunaChangelog().showChangelog, + onTap: () async => LunaChangelog().showChangelog(snapshot.data.version, snapshot.data.buildNumber), ), ); } + Widget _language() { + return LunaListTile( + context: context, + title: LunaText.title(text: 'Language'), + subtitle: LunaText.subtitle(text: LunaLanguage.ENGLISH.fromLocale(context.locale)?.name ?? LunaUI.TEXT_EMDASH), + trailing: LunaIconButton(icon: Icons.language), + onTap: () async { + Tuple2 result = await SettingsDialogs().changeLanguage(context); + if(result.item1) result.item2.use(context); + }, + ); + } + Widget _logs() { return LunaListTile( context: context, @@ -82,13 +96,19 @@ class _State extends State<_SettingsSystemRoute> with LunaScrollControllerMixin return LunaDatabaseValue.ENABLED_SENTRY.listen( builder: (context, box, _) => LunaListTile( context: context, - title: LunaText.title(text: 'Sentry'), + title: LunaText.title(text: 'Firebase Crashlytics'), subtitle: LunaText.subtitle(text: 'Crash and Error Tracking'), trailing: LunaSwitch( value: LunaDatabaseValue.ENABLED_SENTRY.data, onChanged: (value) async { - bool result = await SettingsDialogs().disableSentryWarning(context); - if(result) LunaDatabaseValue.ENABLED_SENTRY.put(value); + LunaDatabaseValue enabled = LunaDatabaseValue.ENABLED_SENTRY; + if(enabled.data) { + bool result = await SettingsDialogs().disableCrashlyticsWarning(context); + if(result) enabled.put(value); + } else { + enabled.put(value); + } + LunaFirebaseCrashlytics().setEnabledState(); } ), ), diff --git a/lib/modules/sonarr.dart b/lib/modules/sonarr.dart index 4e70cd9d..e2ca6d9a 100644 --- a/lib/modules/sonarr.dart +++ b/lib/modules/sonarr.dart @@ -1,3 +1,3 @@ export 'package:sonarr/sonarr.dart'; export 'sonarr/core.dart'; -export 'sonarr/modules.dart'; +export 'sonarr/routes.dart'; diff --git a/lib/modules/sonarr/core/database.dart b/lib/modules/sonarr/core/database.dart index 78b1c0df..44d70bb3 100644 --- a/lib/modules/sonarr/core/database.dart +++ b/lib/modules/sonarr/core/database.dart @@ -33,6 +33,7 @@ class SonarrDatabase extends LunaModuleDatabase { case SonarrDatabaseValue.ADD_SERIES_DEFAULT_LANGUAGE_PROFILE: case SonarrDatabaseValue.ADD_SERIES_DEFAULT_QUALITY_PROFILE: case SonarrDatabaseValue.ADD_SERIES_DEFAULT_ROOT_FOLDER: + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_TAGS: case SonarrDatabaseValue.DEFAULT_SORTING_SERIES_ASCENDING: case SonarrDatabaseValue.DEFAULT_SORTING_RELEASES_ASCENDING: case SonarrDatabaseValue.UPCOMING_FUTURE_DAYS: @@ -62,7 +63,8 @@ class SonarrDatabase extends LunaModuleDatabase { case SonarrDatabaseValue.ADD_SERIES_DEFAULT_QUALITY_PROFILE: case SonarrDatabaseValue.ADD_SERIES_DEFAULT_ROOT_FOLDER: case SonarrDatabaseValue.DEFAULT_SORTING_SERIES_ASCENDING: - case SonarrDatabaseValue.DEFAULT_SORTING_RELEASES_ASCENDING: + case SonarrDatabaseValue.DEFAULT_SORTING_RELEASES_ASCENDING: + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_TAGS: case SonarrDatabaseValue.UPCOMING_FUTURE_DAYS: case SonarrDatabaseValue.QUEUE_REFRESH_RATE: case SonarrDatabaseValue.CONTENT_LOAD_LENGTH: value.put(config[key]); break; @@ -85,6 +87,7 @@ class SonarrDatabase extends LunaModuleDatabase { case 'SONARR_ADD_SERIES_DEFAULT_LANGUAGE_PROFILE': return SonarrDatabaseValue.ADD_SERIES_DEFAULT_LANGUAGE_PROFILE; case 'SONARR_ADD_SERIES_DEFAULT_QUALITY_PROFILE': return SonarrDatabaseValue.ADD_SERIES_DEFAULT_QUALITY_PROFILE; case 'SONARR_ADD_SERIES_DEFAULT_ROOT_FOLDER': return SonarrDatabaseValue.ADD_SERIES_DEFAULT_ROOT_FOLDER; + case 'SONARR_ADD_SERIES_DEFAULT_TAGS': return SonarrDatabaseValue.ADD_SERIES_DEFAULT_TAGS; case 'SONARR_DEFAULT_SORTING_SERIES': return SonarrDatabaseValue.DEFAULT_SORTING_SERIES; case 'SONARR_DEFAULT_SORTING_RELEASES': return SonarrDatabaseValue.DEFAULT_SORTING_RELEASES; case 'SONARR_DEFAULT_SORTING_SERIES_ASCENDING': return SonarrDatabaseValue.DEFAULT_SORTING_SERIES_ASCENDING; @@ -104,6 +107,7 @@ enum SonarrDatabaseValue { ADD_SERIES_DEFAULT_LANGUAGE_PROFILE, ADD_SERIES_DEFAULT_QUALITY_PROFILE, ADD_SERIES_DEFAULT_ROOT_FOLDER, + ADD_SERIES_DEFAULT_TAGS, DEFAULT_SORTING_SERIES, DEFAULT_SORTING_RELEASES, DEFAULT_SORTING_SERIES_ASCENDING, @@ -128,6 +132,7 @@ extension SonarrDatabaseValueExtension on SonarrDatabaseValue { case SonarrDatabaseValue.ADD_SERIES_DEFAULT_LANGUAGE_PROFILE: return 'SONARR_ADD_SERIES_DEFAULT_LANGUAGE_PROFILE'; case SonarrDatabaseValue.ADD_SERIES_DEFAULT_QUALITY_PROFILE: return 'SONARR_ADD_SERIES_DEFAULT_QUALITY_PROFILE'; case SonarrDatabaseValue.ADD_SERIES_DEFAULT_ROOT_FOLDER: return 'SONARR_ADD_SERIES_DEFAULT_ROOT_FOLDER'; + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_TAGS: return 'SONARR_ADD_SERIES_DEFAULT_TAGS'; case SonarrDatabaseValue.DEFAULT_SORTING_SERIES: return 'SONARR_DEFAULT_SORTING_SERIES'; case SonarrDatabaseValue.DEFAULT_SORTING_RELEASES: return 'SONARR_DEFAULT_SORTING_RELEASES'; case SonarrDatabaseValue.DEFAULT_SORTING_SERIES_ASCENDING: return 'SONARR_DEFAULT_SORTING_SERIES_ASCENDING'; @@ -151,6 +156,7 @@ extension SonarrDatabaseValueExtension on SonarrDatabaseValue { case SonarrDatabaseValue.ADD_SERIES_DEFAULT_LANGUAGE_PROFILE : return _box.get(this.key, defaultValue: null); case SonarrDatabaseValue.ADD_SERIES_DEFAULT_QUALITY_PROFILE : return _box.get(this.key, defaultValue: null); case SonarrDatabaseValue.ADD_SERIES_DEFAULT_ROOT_FOLDER : return _box.get(this.key, defaultValue: null); + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_TAGS: return _box.get(this.key, defaultValue: []); case SonarrDatabaseValue.DEFAULT_SORTING_SERIES: return _box.get(this.key, defaultValue: SonarrSeriesSorting.ALPHABETICAL); case SonarrDatabaseValue.DEFAULT_SORTING_RELEASES: return _box.get(this.key, defaultValue: SonarrReleasesSorting.WEIGHT); case SonarrDatabaseValue.DEFAULT_SORTING_SERIES_ASCENDING: return _box.get(this.key, defaultValue: true); @@ -162,22 +168,23 @@ extension SonarrDatabaseValueExtension on SonarrDatabaseValue { void put(dynamic value) { final box = Database.lunaSeaBox; switch(this) { - case SonarrDatabaseValue.NAVIGATION_INDEX: if(value.runtimeType == int) box.put(this.key, value); return; - case SonarrDatabaseValue.NAVIGATION_INDEX_SERIES_DETAILS: if(value.runtimeType == int) box.put(this.key, value); return; - case SonarrDatabaseValue.ADD_SERIES_DEFAULT_MONITORED: if(value.runtimeType == bool) box.put(this.key, value); return; - case SonarrDatabaseValue.ADD_SERIES_DEFAULT_USE_SEASON_FOLDERS: if(value.runtimeType == bool) box.put(this.key, value); return; - case SonarrDatabaseValue.ADD_SERIES_DEFAULT_SERIES_TYPE: if(value.runtimeType == String) box.put(this.key, value); return; - case SonarrDatabaseValue.ADD_SERIES_DEFAULT_MONITOR_STATUS: if(value.runtimeType == SonarrMonitorStatus) box.put(this.key, value); return; - case SonarrDatabaseValue.ADD_SERIES_DEFAULT_LANGUAGE_PROFILE: if(value.runtimeType == int) box.put(this.key, value); return; - case SonarrDatabaseValue.ADD_SERIES_DEFAULT_QUALITY_PROFILE: if(value.runtimeType == int) box.put(this.key, value); return; - case SonarrDatabaseValue.ADD_SERIES_DEFAULT_ROOT_FOLDER: if(value.runtimeType == int) box.put(this.key, value); return; - case SonarrDatabaseValue.DEFAULT_SORTING_SERIES: if(value.runtimeType == SonarrSeriesSorting) box.put(this.key, value); return; - case SonarrDatabaseValue.DEFAULT_SORTING_RELEASES: if(value.runtimeType == SonarrReleasesSorting) box.put(this.key, value); return; - case SonarrDatabaseValue.DEFAULT_SORTING_SERIES_ASCENDING: if(value.runtimeType == bool) box.put(this.key, value); return; - case SonarrDatabaseValue.DEFAULT_SORTING_RELEASES_ASCENDING: if(value.runtimeType == bool) box.put(this.key, value); return; - case SonarrDatabaseValue.UPCOMING_FUTURE_DAYS: if(value.runtimeType == int) box.put(this.key, value); return; - case SonarrDatabaseValue.QUEUE_REFRESH_RATE: if(value.runtimeType == int) box.put(this.key, value); return; - case SonarrDatabaseValue.CONTENT_LOAD_LENGTH: if(value.runtimeType == int) box.put(this.key, value); return; + case SonarrDatabaseValue.NAVIGATION_INDEX: if(value is int) box.put(this.key, value); return; + case SonarrDatabaseValue.NAVIGATION_INDEX_SERIES_DETAILS: if(value is int) box.put(this.key, value); return; + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_MONITORED: if(value is bool) box.put(this.key, value); return; + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_USE_SEASON_FOLDERS: if(value is bool) box.put(this.key, value); return; + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_SERIES_TYPE: if(value is String) box.put(this.key, value); return; + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_MONITOR_STATUS: if(value is SonarrMonitorStatus) box.put(this.key, value); return; + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_LANGUAGE_PROFILE: if(value is int) box.put(this.key, value); return; + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_QUALITY_PROFILE: if(value is int) box.put(this.key, value); return; + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_ROOT_FOLDER: if(value is int) box.put(this.key, value); return; + case SonarrDatabaseValue.ADD_SERIES_DEFAULT_TAGS: if(value is List) box.put(this.key, value); return; + case SonarrDatabaseValue.DEFAULT_SORTING_SERIES: if(value is SonarrSeriesSorting) box.put(this.key, value); return; + case SonarrDatabaseValue.DEFAULT_SORTING_RELEASES: if(value is SonarrReleasesSorting) box.put(this.key, value); return; + case SonarrDatabaseValue.DEFAULT_SORTING_SERIES_ASCENDING: if(value is bool) box.put(this.key, value); return; + case SonarrDatabaseValue.DEFAULT_SORTING_RELEASES_ASCENDING: if(value is bool) box.put(this.key, value); return; + case SonarrDatabaseValue.UPCOMING_FUTURE_DAYS: if(value is int) box.put(this.key, value); return; + case SonarrDatabaseValue.QUEUE_REFRESH_RATE: if(value is int) box.put(this.key, value); return; + case SonarrDatabaseValue.CONTENT_LOAD_LENGTH: if(value is int) box.put(this.key, value); return; } LunaLogger().warning('SonarrDatabaseValueExtension', 'put', 'Attempted to enter data for invalid SonarrDatabaseValue: ${this?.toString() ?? 'null'}'); }//=> Database.lunaSeaBox.put(this.key, value); diff --git a/lib/modules/sonarr/modules.dart b/lib/modules/sonarr/modules.dart deleted file mode 100644 index ca432133..00000000 --- a/lib/modules/sonarr/modules.dart +++ /dev/null @@ -1,13 +0,0 @@ -export 'modules/history.dart'; -export 'modules/missing.dart'; -export 'modules/queue.dart'; -export 'modules/releases.dart'; -export 'modules/season_details.dart'; -export 'modules/series.dart'; -export 'modules/series_add.dart'; -export 'modules/series_add_details.dart'; -export 'modules/series_details.dart'; -export 'modules/series_edit.dart'; -export 'modules/sonarr.dart'; -export 'modules/tags.dart'; -export 'modules/upcoming.dart'; diff --git a/lib/modules/sonarr/routes.dart b/lib/modules/sonarr/routes.dart new file mode 100644 index 00000000..3f0c44ee --- /dev/null +++ b/lib/modules/sonarr/routes.dart @@ -0,0 +1,13 @@ +export 'routes/history.dart'; +export 'routes/missing.dart'; +export 'routes/queue.dart'; +export 'routes/releases.dart'; +export 'routes/season_details.dart'; +export 'routes/series.dart'; +export 'routes/series_add.dart'; +export 'routes/series_add_details.dart'; +export 'routes/series_details.dart'; +export 'routes/series_edit.dart'; +export 'routes/sonarr.dart'; +export 'routes/tags.dart'; +export 'routes/upcoming.dart'; diff --git a/lib/modules/sonarr/modules/history.dart b/lib/modules/sonarr/routes/history.dart similarity index 100% rename from lib/modules/sonarr/modules/history.dart rename to lib/modules/sonarr/routes/history.dart diff --git a/lib/modules/sonarr/modules/history/route.dart b/lib/modules/sonarr/routes/history/route.dart similarity index 100% rename from lib/modules/sonarr/modules/history/route.dart rename to lib/modules/sonarr/routes/history/route.dart diff --git a/lib/modules/sonarr/modules/history/widgets.dart b/lib/modules/sonarr/routes/history/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/history/widgets.dart rename to lib/modules/sonarr/routes/history/widgets.dart diff --git a/lib/modules/sonarr/modules/history/widgets/history_tile.dart b/lib/modules/sonarr/routes/history/widgets/history_tile.dart similarity index 100% rename from lib/modules/sonarr/modules/history/widgets/history_tile.dart rename to lib/modules/sonarr/routes/history/widgets/history_tile.dart diff --git a/lib/modules/sonarr/modules/missing.dart b/lib/modules/sonarr/routes/missing.dart similarity index 100% rename from lib/modules/sonarr/modules/missing.dart rename to lib/modules/sonarr/routes/missing.dart diff --git a/lib/modules/sonarr/modules/missing/route.dart b/lib/modules/sonarr/routes/missing/route.dart similarity index 100% rename from lib/modules/sonarr/modules/missing/route.dart rename to lib/modules/sonarr/routes/missing/route.dart diff --git a/lib/modules/sonarr/modules/missing/widgets.dart b/lib/modules/sonarr/routes/missing/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/missing/widgets.dart rename to lib/modules/sonarr/routes/missing/widgets.dart diff --git a/lib/modules/sonarr/modules/missing/widgets/missing_tile.dart b/lib/modules/sonarr/routes/missing/widgets/missing_tile.dart similarity index 100% rename from lib/modules/sonarr/modules/missing/widgets/missing_tile.dart rename to lib/modules/sonarr/routes/missing/widgets/missing_tile.dart diff --git a/lib/modules/sonarr/modules/queue.dart b/lib/modules/sonarr/routes/queue.dart similarity index 100% rename from lib/modules/sonarr/modules/queue.dart rename to lib/modules/sonarr/routes/queue.dart diff --git a/lib/modules/sonarr/modules/queue/route.dart b/lib/modules/sonarr/routes/queue/route.dart similarity index 100% rename from lib/modules/sonarr/modules/queue/route.dart rename to lib/modules/sonarr/routes/queue/route.dart diff --git a/lib/modules/sonarr/modules/queue/widgets.dart b/lib/modules/sonarr/routes/queue/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/queue/widgets.dart rename to lib/modules/sonarr/routes/queue/widgets.dart diff --git a/lib/modules/sonarr/modules/queue/widgets/queue_tile.dart b/lib/modules/sonarr/routes/queue/widgets/queue_tile.dart similarity index 100% rename from lib/modules/sonarr/modules/queue/widgets/queue_tile.dart rename to lib/modules/sonarr/routes/queue/widgets/queue_tile.dart diff --git a/lib/modules/sonarr/modules/releases.dart b/lib/modules/sonarr/routes/releases.dart similarity index 100% rename from lib/modules/sonarr/modules/releases.dart rename to lib/modules/sonarr/routes/releases.dart diff --git a/lib/modules/sonarr/modules/releases/route.dart b/lib/modules/sonarr/routes/releases/route.dart similarity index 100% rename from lib/modules/sonarr/modules/releases/route.dart rename to lib/modules/sonarr/routes/releases/route.dart diff --git a/lib/modules/sonarr/modules/releases/widgets.dart b/lib/modules/sonarr/routes/releases/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/releases/widgets.dart rename to lib/modules/sonarr/routes/releases/widgets.dart diff --git a/lib/modules/sonarr/modules/releases/widgets/appbar.dart b/lib/modules/sonarr/routes/releases/widgets/appbar.dart similarity index 100% rename from lib/modules/sonarr/modules/releases/widgets/appbar.dart rename to lib/modules/sonarr/routes/releases/widgets/appbar.dart diff --git a/lib/modules/sonarr/modules/releases/widgets/appbar_filter_button.dart b/lib/modules/sonarr/routes/releases/widgets/appbar_filter_button.dart similarity index 100% rename from lib/modules/sonarr/modules/releases/widgets/appbar_filter_button.dart rename to lib/modules/sonarr/routes/releases/widgets/appbar_filter_button.dart diff --git a/lib/modules/sonarr/modules/releases/widgets/appbar_sort_button.dart b/lib/modules/sonarr/routes/releases/widgets/appbar_sort_button.dart similarity index 100% rename from lib/modules/sonarr/modules/releases/widgets/appbar_sort_button.dart rename to lib/modules/sonarr/routes/releases/widgets/appbar_sort_button.dart diff --git a/lib/modules/sonarr/modules/releases/widgets/tile_release.dart b/lib/modules/sonarr/routes/releases/widgets/tile_release.dart similarity index 100% rename from lib/modules/sonarr/modules/releases/widgets/tile_release.dart rename to lib/modules/sonarr/routes/releases/widgets/tile_release.dart diff --git a/lib/modules/sonarr/modules/season_details.dart b/lib/modules/sonarr/routes/season_details.dart similarity index 100% rename from lib/modules/sonarr/modules/season_details.dart rename to lib/modules/sonarr/routes/season_details.dart diff --git a/lib/modules/sonarr/modules/season_details/route.dart b/lib/modules/sonarr/routes/season_details/route.dart similarity index 100% rename from lib/modules/sonarr/modules/season_details/route.dart rename to lib/modules/sonarr/routes/season_details/route.dart diff --git a/lib/modules/sonarr/modules/season_details/widgets.dart b/lib/modules/sonarr/routes/season_details/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/season_details/widgets.dart rename to lib/modules/sonarr/routes/season_details/widgets.dart diff --git a/lib/modules/sonarr/modules/season_details/widgets/all_seasons.dart b/lib/modules/sonarr/routes/season_details/widgets/all_seasons.dart similarity index 100% rename from lib/modules/sonarr/modules/season_details/widgets/all_seasons.dart rename to lib/modules/sonarr/routes/season_details/widgets/all_seasons.dart diff --git a/lib/modules/sonarr/modules/season_details/widgets/season.dart b/lib/modules/sonarr/routes/season_details/widgets/season.dart similarity index 100% rename from lib/modules/sonarr/modules/season_details/widgets/season.dart rename to lib/modules/sonarr/routes/season_details/widgets/season.dart diff --git a/lib/modules/sonarr/modules/season_details/widgets/season_header.dart b/lib/modules/sonarr/routes/season_details/widgets/season_header.dart similarity index 100% rename from lib/modules/sonarr/modules/season_details/widgets/season_header.dart rename to lib/modules/sonarr/routes/season_details/widgets/season_header.dart diff --git a/lib/modules/sonarr/modules/season_details/widgets/tile_episode.dart b/lib/modules/sonarr/routes/season_details/widgets/tile_episode.dart similarity index 100% rename from lib/modules/sonarr/modules/season_details/widgets/tile_episode.dart rename to lib/modules/sonarr/routes/season_details/widgets/tile_episode.dart diff --git a/lib/modules/sonarr/modules/series.dart b/lib/modules/sonarr/routes/series.dart similarity index 100% rename from lib/modules/sonarr/modules/series.dart rename to lib/modules/sonarr/routes/series.dart diff --git a/lib/modules/sonarr/modules/series/route.dart b/lib/modules/sonarr/routes/series/route.dart similarity index 100% rename from lib/modules/sonarr/modules/series/route.dart rename to lib/modules/sonarr/routes/series/route.dart diff --git a/lib/modules/sonarr/modules/series/widgets.dart b/lib/modules/sonarr/routes/series/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/series/widgets.dart rename to lib/modules/sonarr/routes/series/widgets.dart diff --git a/lib/modules/sonarr/modules/series/widgets/search_bar.dart b/lib/modules/sonarr/routes/series/widgets/search_bar.dart similarity index 100% rename from lib/modules/sonarr/modules/series/widgets/search_bar.dart rename to lib/modules/sonarr/routes/series/widgets/search_bar.dart diff --git a/lib/modules/sonarr/modules/series/widgets/search_bar_filter_button.dart b/lib/modules/sonarr/routes/series/widgets/search_bar_filter_button.dart similarity index 100% rename from lib/modules/sonarr/modules/series/widgets/search_bar_filter_button.dart rename to lib/modules/sonarr/routes/series/widgets/search_bar_filter_button.dart diff --git a/lib/modules/sonarr/modules/series/widgets/search_bar_sort_button.dart b/lib/modules/sonarr/routes/series/widgets/search_bar_sort_button.dart similarity index 100% rename from lib/modules/sonarr/modules/series/widgets/search_bar_sort_button.dart rename to lib/modules/sonarr/routes/series/widgets/search_bar_sort_button.dart diff --git a/lib/modules/sonarr/modules/series/widgets/series_tile.dart b/lib/modules/sonarr/routes/series/widgets/series_tile.dart similarity index 100% rename from lib/modules/sonarr/modules/series/widgets/series_tile.dart rename to lib/modules/sonarr/routes/series/widgets/series_tile.dart diff --git a/lib/modules/sonarr/modules/series_add.dart b/lib/modules/sonarr/routes/series_add.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add.dart rename to lib/modules/sonarr/routes/series_add.dart diff --git a/lib/modules/sonarr/modules/series_add/route.dart b/lib/modules/sonarr/routes/series_add/route.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add/route.dart rename to lib/modules/sonarr/routes/series_add/route.dart diff --git a/lib/modules/sonarr/modules/series_add/widgets.dart b/lib/modules/sonarr/routes/series_add/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add/widgets.dart rename to lib/modules/sonarr/routes/series_add/widgets.dart diff --git a/lib/modules/sonarr/modules/series_add/widgets/appbar.dart b/lib/modules/sonarr/routes/series_add/widgets/appbar.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add/widgets/appbar.dart rename to lib/modules/sonarr/routes/series_add/widgets/appbar.dart diff --git a/lib/modules/sonarr/modules/series_add/widgets/search_results.dart b/lib/modules/sonarr/routes/series_add/widgets/search_results.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add/widgets/search_results.dart rename to lib/modules/sonarr/routes/series_add/widgets/search_results.dart diff --git a/lib/modules/sonarr/modules/series_add/widgets/search_results_tile.dart b/lib/modules/sonarr/routes/series_add/widgets/search_results_tile.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add/widgets/search_results_tile.dart rename to lib/modules/sonarr/routes/series_add/widgets/search_results_tile.dart diff --git a/lib/modules/sonarr/modules/series_add_details.dart b/lib/modules/sonarr/routes/series_add_details.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details.dart rename to lib/modules/sonarr/routes/series_add_details.dart diff --git a/lib/modules/sonarr/modules/series_add_details/route.dart b/lib/modules/sonarr/routes/series_add_details/route.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/route.dart rename to lib/modules/sonarr/routes/series_add_details/route.dart diff --git a/lib/modules/sonarr/modules/series_add_details/state.dart b/lib/modules/sonarr/routes/series_add_details/state.dart similarity index 94% rename from lib/modules/sonarr/modules/series_add_details/state.dart rename to lib/modules/sonarr/routes/series_add_details/state.dart index ec788075..3f461b3c 100644 --- a/lib/modules/sonarr/modules/series_add_details/state.dart +++ b/lib/modules/sonarr/routes/series_add_details/state.dart @@ -11,7 +11,7 @@ class SonarrSeriesAddDetailsState extends ChangeNotifier { @required List tags, }) { _series = series; - _tags = []; + _tags = (tags ?? []).where((tag) => ((SonarrDatabaseValue.ADD_SERIES_DEFAULT_TAGS.data as List) ?? []).contains(tag.id)).toList(); _monitored = SonarrDatabaseValue.ADD_SERIES_DEFAULT_MONITORED.data ?? true; _useSeasonFolders = SonarrDatabaseValue.ADD_SERIES_DEFAULT_USE_SEASON_FOLDERS.data ?? true; _seriesType = SonarrSeriesType.values.firstWhere( @@ -102,6 +102,7 @@ class SonarrSeriesAddDetailsState extends ChangeNotifier { set tags(List tags) { assert(tags != null); _tags = tags; + SonarrDatabaseValue.ADD_SERIES_DEFAULT_TAGS.put((tags ?? []).map((tag) => tag.id).toList()); notifyListeners(); } } diff --git a/lib/modules/sonarr/modules/series_add_details/widgets.dart b/lib/modules/sonarr/routes/series_add_details/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/widgets.dart rename to lib/modules/sonarr/routes/series_add_details/widgets.dart diff --git a/lib/modules/sonarr/modules/series_add_details/widgets/appbar_link_action.dart b/lib/modules/sonarr/routes/series_add_details/widgets/appbar_link_action.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/widgets/appbar_link_action.dart rename to lib/modules/sonarr/routes/series_add_details/widgets/appbar_link_action.dart diff --git a/lib/modules/sonarr/modules/series_add_details/widgets/button_add_series.dart b/lib/modules/sonarr/routes/series_add_details/widgets/button_add_series.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/widgets/button_add_series.dart rename to lib/modules/sonarr/routes/series_add_details/widgets/button_add_series.dart diff --git a/lib/modules/sonarr/modules/series_add_details/widgets/tile_language_profile.dart b/lib/modules/sonarr/routes/series_add_details/widgets/tile_language_profile.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/widgets/tile_language_profile.dart rename to lib/modules/sonarr/routes/series_add_details/widgets/tile_language_profile.dart diff --git a/lib/modules/sonarr/modules/series_add_details/widgets/tile_monitor_status.dart b/lib/modules/sonarr/routes/series_add_details/widgets/tile_monitor_status.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/widgets/tile_monitor_status.dart rename to lib/modules/sonarr/routes/series_add_details/widgets/tile_monitor_status.dart diff --git a/lib/modules/sonarr/modules/series_add_details/widgets/tile_monitored.dart b/lib/modules/sonarr/routes/series_add_details/widgets/tile_monitored.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/widgets/tile_monitored.dart rename to lib/modules/sonarr/routes/series_add_details/widgets/tile_monitored.dart diff --git a/lib/modules/sonarr/modules/series_add_details/widgets/tile_quality_profile.dart b/lib/modules/sonarr/routes/series_add_details/widgets/tile_quality_profile.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/widgets/tile_quality_profile.dart rename to lib/modules/sonarr/routes/series_add_details/widgets/tile_quality_profile.dart diff --git a/lib/modules/sonarr/modules/series_add_details/widgets/tile_root_folder.dart b/lib/modules/sonarr/routes/series_add_details/widgets/tile_root_folder.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/widgets/tile_root_folder.dart rename to lib/modules/sonarr/routes/series_add_details/widgets/tile_root_folder.dart diff --git a/lib/modules/sonarr/modules/series_add_details/widgets/tile_series_type.dart b/lib/modules/sonarr/routes/series_add_details/widgets/tile_series_type.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/widgets/tile_series_type.dart rename to lib/modules/sonarr/routes/series_add_details/widgets/tile_series_type.dart diff --git a/lib/modules/sonarr/modules/series_add_details/widgets/tile_tags.dart b/lib/modules/sonarr/routes/series_add_details/widgets/tile_tags.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/widgets/tile_tags.dart rename to lib/modules/sonarr/routes/series_add_details/widgets/tile_tags.dart diff --git a/lib/modules/sonarr/modules/series_add_details/widgets/tile_use_season_folders.dart b/lib/modules/sonarr/routes/series_add_details/widgets/tile_use_season_folders.dart similarity index 100% rename from lib/modules/sonarr/modules/series_add_details/widgets/tile_use_season_folders.dart rename to lib/modules/sonarr/routes/series_add_details/widgets/tile_use_season_folders.dart diff --git a/lib/modules/sonarr/modules/series_details.dart b/lib/modules/sonarr/routes/series_details.dart similarity index 100% rename from lib/modules/sonarr/modules/series_details.dart rename to lib/modules/sonarr/routes/series_details.dart diff --git a/lib/modules/sonarr/modules/series_details/route.dart b/lib/modules/sonarr/routes/series_details/route.dart similarity index 100% rename from lib/modules/sonarr/modules/series_details/route.dart rename to lib/modules/sonarr/routes/series_details/route.dart diff --git a/lib/modules/sonarr/modules/series_details/widgets.dart b/lib/modules/sonarr/routes/series_details/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/series_details/widgets.dart rename to lib/modules/sonarr/routes/series_details/widgets.dart diff --git a/lib/modules/sonarr/modules/series_details/widgets/appbar_edit_action.dart b/lib/modules/sonarr/routes/series_details/widgets/appbar_edit_action.dart similarity index 100% rename from lib/modules/sonarr/modules/series_details/widgets/appbar_edit_action.dart rename to lib/modules/sonarr/routes/series_details/widgets/appbar_edit_action.dart diff --git a/lib/modules/sonarr/modules/series_details/widgets/appbar_settings_action.dart b/lib/modules/sonarr/routes/series_details/widgets/appbar_settings_action.dart similarity index 100% rename from lib/modules/sonarr/modules/series_details/widgets/appbar_settings_action.dart rename to lib/modules/sonarr/routes/series_details/widgets/appbar_settings_action.dart diff --git a/lib/modules/sonarr/modules/series_details/widgets/navigation_bar.dart b/lib/modules/sonarr/routes/series_details/widgets/navigation_bar.dart similarity index 100% rename from lib/modules/sonarr/modules/series_details/widgets/navigation_bar.dart rename to lib/modules/sonarr/routes/series_details/widgets/navigation_bar.dart diff --git a/lib/modules/sonarr/modules/series_details/widgets/overview.dart b/lib/modules/sonarr/routes/series_details/widgets/overview.dart similarity index 66% rename from lib/modules/sonarr/modules/series_details/widgets/overview.dart rename to lib/modules/sonarr/routes/series_details/widgets/overview.dart index ebb64026..154729bd 100644 --- a/lib/modules/sonarr/modules/series_details/widgets/overview.dart +++ b/lib/modules/sonarr/routes/series_details/widgets/overview.dart @@ -24,8 +24,8 @@ class SonarrSeriesDetailsOverview extends StatelessWidget { Widget build(BuildContext context) => LSListView( children: [ _description(context), + _links(), _information(context), - _links, ], ); @@ -98,56 +98,66 @@ class SonarrSeriesDetailsOverview extends StatelessWidget { ), ); - Widget get _links => LSContainerRow( - children: [ - if(series.imdbId != '') Expanded( - child: LSCard( - child: InkWell( - child: Padding( - child: Image.asset( - 'assets/images/services/imdb.png', - height: 21.0, + Widget _links() { + return LSContainerRow( + children: [ + if(series.imdbId != '') Expanded( + child: LSCard( + child: InkWell( + child: Padding( + child: Image.asset('assets/images/services/imdb.png'), + padding: EdgeInsets.all(12.0), ), - padding: EdgeInsets.all(18.0), + borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), + onTap: () async => await series?.imdbId?.lunaOpenIMDB(), ), - borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), - onTap: () async => await series?.imdbId?.lunaOpenIMDB(), + height: 50.0, + reducedMargin: true, ), - reducedMargin: true, ), - ), - if(series.tvdbId != 0) Expanded( - child: LSCard( - child: InkWell( - child: Padding( - child: Image.asset( - 'assets/images/services/thetvdb.png', - height: 23.0, + if(series.tvdbId != 0) Expanded( + child: LSCard( + child: InkWell( + child: Padding( + child: Image.asset('assets/images/services/trakt.png'), + padding: EdgeInsets.all(12.0), ), - padding: EdgeInsets.all(17.0), + borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), + onTap: () async => await series?.tvdbId?.toString()?.lunaOpenTraktSeries(), ), - borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), - onTap: () async => await series?.tvdbId?.toString()?.lunaOpenTheTVDB(), + height: 50.0, + reducedMargin: true, ), - reducedMargin: true, ), - ), - if(series.tvMazeId != 0) Expanded( - child: LSCard( - child: InkWell( - child: Padding( - child: Image.asset( - 'assets/images/services/tvmaze.png', - height: 21.0, + if(series.tvdbId != 0) Expanded( + child: LSCard( + child: InkWell( + child: Padding( + child: Image.asset('assets/images/services/thetvdb.png'), + padding: EdgeInsets.all(12.0), ), - padding: EdgeInsets.all(18.0), + borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), + onTap: () async => await series?.tvdbId?.toString()?.lunaOpenTheTVDB(), ), - borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), - onTap: () async => await series?.tvMazeId?.toString()?.lunaOpenTVMaze(), + height: 50.0, + reducedMargin: true, ), - reducedMargin: true, ), - ), - ], - ); + if(series.tvMazeId != 0) Expanded( + child: LSCard( + child: InkWell( + child: Padding( + child: Image.asset('assets/images/services/tvmaze.png'), + padding: EdgeInsets.all(12.0), + ), + borderRadius: BorderRadius.circular(Constants.UI_BORDER_RADIUS), + onTap: () async => await series?.tvMazeId?.toString()?.lunaOpenTVMaze(), + ), + height: 50.0, + reducedMargin: true, + ), + ), + ], + ); + } } diff --git a/lib/modules/sonarr/modules/series_details/widgets/season_all_tile.dart b/lib/modules/sonarr/routes/series_details/widgets/season_all_tile.dart similarity index 100% rename from lib/modules/sonarr/modules/series_details/widgets/season_all_tile.dart rename to lib/modules/sonarr/routes/series_details/widgets/season_all_tile.dart diff --git a/lib/modules/sonarr/modules/series_details/widgets/season_list.dart b/lib/modules/sonarr/routes/series_details/widgets/season_list.dart similarity index 100% rename from lib/modules/sonarr/modules/series_details/widgets/season_list.dart rename to lib/modules/sonarr/routes/series_details/widgets/season_list.dart diff --git a/lib/modules/sonarr/modules/series_details/widgets/season_tile.dart b/lib/modules/sonarr/routes/series_details/widgets/season_tile.dart similarity index 100% rename from lib/modules/sonarr/modules/series_details/widgets/season_tile.dart rename to lib/modules/sonarr/routes/series_details/widgets/season_tile.dart diff --git a/lib/modules/sonarr/modules/series_edit.dart b/lib/modules/sonarr/routes/series_edit.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit.dart rename to lib/modules/sonarr/routes/series_edit.dart diff --git a/lib/modules/sonarr/modules/series_edit/route.dart b/lib/modules/sonarr/routes/series_edit/route.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit/route.dart rename to lib/modules/sonarr/routes/series_edit/route.dart diff --git a/lib/modules/sonarr/modules/series_edit/state.dart b/lib/modules/sonarr/routes/series_edit/state.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit/state.dart rename to lib/modules/sonarr/routes/series_edit/state.dart diff --git a/lib/modules/sonarr/modules/series_edit/widgets.dart b/lib/modules/sonarr/routes/series_edit/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit/widgets.dart rename to lib/modules/sonarr/routes/series_edit/widgets.dart diff --git a/lib/modules/sonarr/modules/series_edit/widgets/button_update_series.dart b/lib/modules/sonarr/routes/series_edit/widgets/button_update_series.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit/widgets/button_update_series.dart rename to lib/modules/sonarr/routes/series_edit/widgets/button_update_series.dart diff --git a/lib/modules/sonarr/modules/series_edit/widgets/tile_language_profile.dart b/lib/modules/sonarr/routes/series_edit/widgets/tile_language_profile.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit/widgets/tile_language_profile.dart rename to lib/modules/sonarr/routes/series_edit/widgets/tile_language_profile.dart diff --git a/lib/modules/sonarr/modules/series_edit/widgets/tile_monitored.dart b/lib/modules/sonarr/routes/series_edit/widgets/tile_monitored.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit/widgets/tile_monitored.dart rename to lib/modules/sonarr/routes/series_edit/widgets/tile_monitored.dart diff --git a/lib/modules/sonarr/modules/series_edit/widgets/tile_quality_profile.dart b/lib/modules/sonarr/routes/series_edit/widgets/tile_quality_profile.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit/widgets/tile_quality_profile.dart rename to lib/modules/sonarr/routes/series_edit/widgets/tile_quality_profile.dart diff --git a/lib/modules/sonarr/modules/series_edit/widgets/tile_series_path.dart b/lib/modules/sonarr/routes/series_edit/widgets/tile_series_path.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit/widgets/tile_series_path.dart rename to lib/modules/sonarr/routes/series_edit/widgets/tile_series_path.dart diff --git a/lib/modules/sonarr/modules/series_edit/widgets/tile_series_type.dart b/lib/modules/sonarr/routes/series_edit/widgets/tile_series_type.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit/widgets/tile_series_type.dart rename to lib/modules/sonarr/routes/series_edit/widgets/tile_series_type.dart diff --git a/lib/modules/sonarr/modules/series_edit/widgets/tile_tags.dart b/lib/modules/sonarr/routes/series_edit/widgets/tile_tags.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit/widgets/tile_tags.dart rename to lib/modules/sonarr/routes/series_edit/widgets/tile_tags.dart diff --git a/lib/modules/sonarr/modules/series_edit/widgets/tile_use_season_folders.dart b/lib/modules/sonarr/routes/series_edit/widgets/tile_use_season_folders.dart similarity index 100% rename from lib/modules/sonarr/modules/series_edit/widgets/tile_use_season_folders.dart rename to lib/modules/sonarr/routes/series_edit/widgets/tile_use_season_folders.dart diff --git a/lib/modules/sonarr/modules/sonarr.dart b/lib/modules/sonarr/routes/sonarr.dart similarity index 100% rename from lib/modules/sonarr/modules/sonarr.dart rename to lib/modules/sonarr/routes/sonarr.dart diff --git a/lib/modules/sonarr/modules/sonarr/route.dart b/lib/modules/sonarr/routes/sonarr/route.dart similarity index 97% rename from lib/modules/sonarr/modules/sonarr/route.dart rename to lib/modules/sonarr/routes/sonarr/route.dart index b18d22f8..901bb06d 100644 --- a/lib/modules/sonarr/modules/sonarr/route.dart +++ b/lib/modules/sonarr/routes/sonarr/route.dart @@ -47,7 +47,7 @@ class _State extends State<_SonarrHomeRoute> { return false; } - Widget get _drawer => LSDrawer(page: 'sonarr'); + Widget get _drawer => LunaDrawer(page: LunaModule.SONARR.key); Widget get _bottomNavigationBar => SonarrNavigationBar(pageController: _pageController); diff --git a/lib/modules/sonarr/modules/sonarr/widgets.dart b/lib/modules/sonarr/routes/sonarr/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/sonarr/widgets.dart rename to lib/modules/sonarr/routes/sonarr/widgets.dart diff --git a/lib/modules/sonarr/modules/sonarr/widgets/appbar_add_series_action.dart b/lib/modules/sonarr/routes/sonarr/widgets/appbar_add_series_action.dart similarity index 100% rename from lib/modules/sonarr/modules/sonarr/widgets/appbar_add_series_action.dart rename to lib/modules/sonarr/routes/sonarr/widgets/appbar_add_series_action.dart diff --git a/lib/modules/sonarr/modules/sonarr/widgets/appbar_global_settings_action.dart b/lib/modules/sonarr/routes/sonarr/widgets/appbar_global_settings_action.dart similarity index 100% rename from lib/modules/sonarr/modules/sonarr/widgets/appbar_global_settings_action.dart rename to lib/modules/sonarr/routes/sonarr/widgets/appbar_global_settings_action.dart diff --git a/lib/modules/sonarr/modules/sonarr/widgets/navigation_bar.dart b/lib/modules/sonarr/routes/sonarr/widgets/navigation_bar.dart similarity index 100% rename from lib/modules/sonarr/modules/sonarr/widgets/navigation_bar.dart rename to lib/modules/sonarr/routes/sonarr/widgets/navigation_bar.dart diff --git a/lib/modules/sonarr/modules/tags.dart b/lib/modules/sonarr/routes/tags.dart similarity index 100% rename from lib/modules/sonarr/modules/tags.dart rename to lib/modules/sonarr/routes/tags.dart diff --git a/lib/modules/sonarr/modules/tags/route.dart b/lib/modules/sonarr/routes/tags/route.dart similarity index 100% rename from lib/modules/sonarr/modules/tags/route.dart rename to lib/modules/sonarr/routes/tags/route.dart diff --git a/lib/modules/sonarr/modules/tags/widgets.dart b/lib/modules/sonarr/routes/tags/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/tags/widgets.dart rename to lib/modules/sonarr/routes/tags/widgets.dart diff --git a/lib/modules/sonarr/modules/tags/widgets/appbar_action_add_tag.dart b/lib/modules/sonarr/routes/tags/widgets/appbar_action_add_tag.dart similarity index 100% rename from lib/modules/sonarr/modules/tags/widgets/appbar_action_add_tag.dart rename to lib/modules/sonarr/routes/tags/widgets/appbar_action_add_tag.dart diff --git a/lib/modules/sonarr/modules/tags/widgets/tag_tile.dart b/lib/modules/sonarr/routes/tags/widgets/tag_tile.dart similarity index 100% rename from lib/modules/sonarr/modules/tags/widgets/tag_tile.dart rename to lib/modules/sonarr/routes/tags/widgets/tag_tile.dart diff --git a/lib/modules/sonarr/modules/upcoming.dart b/lib/modules/sonarr/routes/upcoming.dart similarity index 100% rename from lib/modules/sonarr/modules/upcoming.dart rename to lib/modules/sonarr/routes/upcoming.dart diff --git a/lib/modules/sonarr/modules/upcoming/route.dart b/lib/modules/sonarr/routes/upcoming/route.dart similarity index 100% rename from lib/modules/sonarr/modules/upcoming/route.dart rename to lib/modules/sonarr/routes/upcoming/route.dart diff --git a/lib/modules/sonarr/modules/upcoming/widgets.dart b/lib/modules/sonarr/routes/upcoming/widgets.dart similarity index 100% rename from lib/modules/sonarr/modules/upcoming/widgets.dart rename to lib/modules/sonarr/routes/upcoming/widgets.dart diff --git a/lib/modules/sonarr/modules/upcoming/widgets/upcoming_tile.dart b/lib/modules/sonarr/routes/upcoming/widgets/upcoming_tile.dart similarity index 100% rename from lib/modules/sonarr/modules/upcoming/widgets/upcoming_tile.dart rename to lib/modules/sonarr/routes/upcoming/widgets/upcoming_tile.dart diff --git a/lib/modules/tautulli.dart b/lib/modules/tautulli.dart index b960d394..9cdf9683 100644 --- a/lib/modules/tautulli.dart +++ b/lib/modules/tautulli.dart @@ -1,3 +1,3 @@ export 'package:tautulli/tautulli.dart'; export 'tautulli/core.dart'; -export 'tautulli/modules.dart'; +export 'tautulli/routes.dart'; diff --git a/lib/modules/tautulli/modules.dart b/lib/modules/tautulli/modules.dart deleted file mode 100644 index 3141d492..00000000 --- a/lib/modules/tautulli/modules.dart +++ /dev/null @@ -1,27 +0,0 @@ -export 'modules/activity.dart'; -export 'modules/activity_details.dart'; -export 'modules/check_for_updates.dart'; -export 'modules/graphs.dart'; -export 'modules/graphs_play_by_period.dart'; -export 'modules/graphs_stream_information.dart'; -export 'modules/history.dart'; -export 'modules/history_details.dart'; -export 'modules/ipaddress_details.dart'; -export 'modules/libraries.dart'; -export 'modules/libraries_details.dart'; -export 'modules/logs.dart'; -export 'modules/logs_logins.dart'; -export 'modules/logs_newsletters.dart'; -export 'modules/logs_notifications.dart'; -export 'modules/logs_plex_media_scanner.dart'; -export 'modules/logs_tautulli.dart'; -export 'modules/logs_plex_media_server.dart'; -export 'modules/media_details.dart'; -export 'modules/more.dart'; -export 'modules/recently_added.dart'; -export 'modules/search.dart'; -export 'modules/statistics.dart'; -export 'modules/synced_items.dart'; -export 'modules/tautulli.dart'; -export 'modules/users.dart'; -export 'modules/users_details.dart'; diff --git a/lib/modules/tautulli/routes.dart b/lib/modules/tautulli/routes.dart new file mode 100644 index 00000000..ffb9a679 --- /dev/null +++ b/lib/modules/tautulli/routes.dart @@ -0,0 +1,27 @@ +export 'routes/activity.dart'; +export 'routes/activity_details.dart'; +export 'routes/check_for_updates.dart'; +export 'routes/graphs.dart'; +export 'routes/graphs_play_by_period.dart'; +export 'routes/graphs_stream_information.dart'; +export 'routes/history.dart'; +export 'routes/history_details.dart'; +export 'routes/ipaddress_details.dart'; +export 'routes/libraries.dart'; +export 'routes/libraries_details.dart'; +export 'routes/logs.dart'; +export 'routes/logs_logins.dart'; +export 'routes/logs_newsletters.dart'; +export 'routes/logs_notifications.dart'; +export 'routes/logs_plex_media_scanner.dart'; +export 'routes/logs_tautulli.dart'; +export 'routes/logs_plex_media_server.dart'; +export 'routes/media_details.dart'; +export 'routes/more.dart'; +export 'routes/recently_added.dart'; +export 'routes/search.dart'; +export 'routes/statistics.dart'; +export 'routes/synced_items.dart'; +export 'routes/tautulli.dart'; +export 'routes/users.dart'; +export 'routes/users_details.dart'; diff --git a/lib/modules/tautulli/modules/activity.dart b/lib/modules/tautulli/routes/activity.dart similarity index 100% rename from lib/modules/tautulli/modules/activity.dart rename to lib/modules/tautulli/routes/activity.dart diff --git a/lib/modules/tautulli/modules/activity/route.dart b/lib/modules/tautulli/routes/activity/route.dart similarity index 100% rename from lib/modules/tautulli/modules/activity/route.dart rename to lib/modules/tautulli/routes/activity/route.dart diff --git a/lib/modules/tautulli/modules/activity/widgets.dart b/lib/modules/tautulli/routes/activity/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/activity/widgets.dart rename to lib/modules/tautulli/routes/activity/widgets.dart diff --git a/lib/modules/tautulli/modules/activity/widgets/activity_status.dart b/lib/modules/tautulli/routes/activity/widgets/activity_status.dart similarity index 100% rename from lib/modules/tautulli/modules/activity/widgets/activity_status.dart rename to lib/modules/tautulli/routes/activity/widgets/activity_status.dart diff --git a/lib/modules/tautulli/modules/activity/widgets/activity_tile.dart b/lib/modules/tautulli/routes/activity/widgets/activity_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/activity/widgets/activity_tile.dart rename to lib/modules/tautulli/routes/activity/widgets/activity_tile.dart diff --git a/lib/modules/tautulli/modules/activity_details.dart b/lib/modules/tautulli/routes/activity_details.dart similarity index 100% rename from lib/modules/tautulli/modules/activity_details.dart rename to lib/modules/tautulli/routes/activity_details.dart diff --git a/lib/modules/tautulli/modules/activity_details/route.dart b/lib/modules/tautulli/routes/activity_details/route.dart similarity index 100% rename from lib/modules/tautulli/modules/activity_details/route.dart rename to lib/modules/tautulli/routes/activity_details/route.dart diff --git a/lib/modules/tautulli/modules/activity_details/widgets.dart b/lib/modules/tautulli/routes/activity_details/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/activity_details/widgets.dart rename to lib/modules/tautulli/routes/activity_details/widgets.dart diff --git a/lib/modules/tautulli/modules/activity_details/widgets/information.dart b/lib/modules/tautulli/routes/activity_details/widgets/information.dart similarity index 100% rename from lib/modules/tautulli/modules/activity_details/widgets/information.dart rename to lib/modules/tautulli/routes/activity_details/widgets/information.dart diff --git a/lib/modules/tautulli/modules/activity_details/widgets/metadata.dart b/lib/modules/tautulli/routes/activity_details/widgets/metadata.dart similarity index 100% rename from lib/modules/tautulli/modules/activity_details/widgets/metadata.dart rename to lib/modules/tautulli/routes/activity_details/widgets/metadata.dart diff --git a/lib/modules/tautulli/modules/activity_details/widgets/terminate_session.dart b/lib/modules/tautulli/routes/activity_details/widgets/terminate_session.dart similarity index 100% rename from lib/modules/tautulli/modules/activity_details/widgets/terminate_session.dart rename to lib/modules/tautulli/routes/activity_details/widgets/terminate_session.dart diff --git a/lib/modules/tautulli/modules/activity_details/widgets/user.dart b/lib/modules/tautulli/routes/activity_details/widgets/user.dart similarity index 100% rename from lib/modules/tautulli/modules/activity_details/widgets/user.dart rename to lib/modules/tautulli/routes/activity_details/widgets/user.dart diff --git a/lib/modules/tautulli/modules/check_for_updates.dart b/lib/modules/tautulli/routes/check_for_updates.dart similarity index 100% rename from lib/modules/tautulli/modules/check_for_updates.dart rename to lib/modules/tautulli/routes/check_for_updates.dart diff --git a/lib/modules/tautulli/modules/check_for_updates/route.dart b/lib/modules/tautulli/routes/check_for_updates/route.dart similarity index 100% rename from lib/modules/tautulli/modules/check_for_updates/route.dart rename to lib/modules/tautulli/routes/check_for_updates/route.dart diff --git a/lib/modules/tautulli/modules/check_for_updates/widgets.dart b/lib/modules/tautulli/routes/check_for_updates/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/check_for_updates/widgets.dart rename to lib/modules/tautulli/routes/check_for_updates/widgets.dart diff --git a/lib/modules/tautulli/modules/check_for_updates/widgets/pms_tile.dart b/lib/modules/tautulli/routes/check_for_updates/widgets/pms_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/check_for_updates/widgets/pms_tile.dart rename to lib/modules/tautulli/routes/check_for_updates/widgets/pms_tile.dart diff --git a/lib/modules/tautulli/modules/check_for_updates/widgets/tautulli_tile.dart b/lib/modules/tautulli/routes/check_for_updates/widgets/tautulli_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/check_for_updates/widgets/tautulli_tile.dart rename to lib/modules/tautulli/routes/check_for_updates/widgets/tautulli_tile.dart diff --git a/lib/modules/tautulli/modules/graphs.dart b/lib/modules/tautulli/routes/graphs.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs.dart rename to lib/modules/tautulli/routes/graphs.dart diff --git a/lib/modules/tautulli/modules/graphs/route.dart b/lib/modules/tautulli/routes/graphs/route.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs/route.dart rename to lib/modules/tautulli/routes/graphs/route.dart diff --git a/lib/modules/tautulli/modules/graphs/widgets.dart b/lib/modules/tautulli/routes/graphs/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs/widgets.dart rename to lib/modules/tautulli/routes/graphs/widgets.dart diff --git a/lib/modules/tautulli/modules/graphs/widgets/navigation_bar.dart b/lib/modules/tautulli/routes/graphs/widgets/navigation_bar.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs/widgets/navigation_bar.dart rename to lib/modules/tautulli/routes/graphs/widgets/navigation_bar.dart diff --git a/lib/modules/tautulli/modules/graphs/widgets/type_button.dart b/lib/modules/tautulli/routes/graphs/widgets/type_button.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs/widgets/type_button.dart rename to lib/modules/tautulli/routes/graphs/widgets/type_button.dart diff --git a/lib/modules/tautulli/modules/graphs_play_by_period.dart b/lib/modules/tautulli/routes/graphs_play_by_period.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_play_by_period.dart rename to lib/modules/tautulli/routes/graphs_play_by_period.dart diff --git a/lib/modules/tautulli/modules/graphs_play_by_period/route.dart b/lib/modules/tautulli/routes/graphs_play_by_period/route.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_play_by_period/route.dart rename to lib/modules/tautulli/routes/graphs_play_by_period/route.dart diff --git a/lib/modules/tautulli/modules/graphs_play_by_period/widgets.dart b/lib/modules/tautulli/routes/graphs_play_by_period/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_play_by_period/widgets.dart rename to lib/modules/tautulli/routes/graphs_play_by_period/widgets.dart diff --git a/lib/modules/tautulli/modules/graphs_play_by_period/widgets/daily_play_count_graph.dart b/lib/modules/tautulli/routes/graphs_play_by_period/widgets/daily_play_count_graph.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_play_by_period/widgets/daily_play_count_graph.dart rename to lib/modules/tautulli/routes/graphs_play_by_period/widgets/daily_play_count_graph.dart diff --git a/lib/modules/tautulli/modules/graphs_play_by_period/widgets/play_count_by_day_of_week_graph.dart b/lib/modules/tautulli/routes/graphs_play_by_period/widgets/play_count_by_day_of_week_graph.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_play_by_period/widgets/play_count_by_day_of_week_graph.dart rename to lib/modules/tautulli/routes/graphs_play_by_period/widgets/play_count_by_day_of_week_graph.dart diff --git a/lib/modules/tautulli/modules/graphs_play_by_period/widgets/play_count_by_top_platforms_graph.dart b/lib/modules/tautulli/routes/graphs_play_by_period/widgets/play_count_by_top_platforms_graph.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_play_by_period/widgets/play_count_by_top_platforms_graph.dart rename to lib/modules/tautulli/routes/graphs_play_by_period/widgets/play_count_by_top_platforms_graph.dart diff --git a/lib/modules/tautulli/modules/graphs_play_by_period/widgets/play_count_by_top_users_graph.dart b/lib/modules/tautulli/routes/graphs_play_by_period/widgets/play_count_by_top_users_graph.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_play_by_period/widgets/play_count_by_top_users_graph.dart rename to lib/modules/tautulli/routes/graphs_play_by_period/widgets/play_count_by_top_users_graph.dart diff --git a/lib/modules/tautulli/modules/graphs_play_by_period/widgets/plays_by_month_graph.dart b/lib/modules/tautulli/routes/graphs_play_by_period/widgets/plays_by_month_graph.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_play_by_period/widgets/plays_by_month_graph.dart rename to lib/modules/tautulli/routes/graphs_play_by_period/widgets/plays_by_month_graph.dart diff --git a/lib/modules/tautulli/modules/graphs_stream_information.dart b/lib/modules/tautulli/routes/graphs_stream_information.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_stream_information.dart rename to lib/modules/tautulli/routes/graphs_stream_information.dart diff --git a/lib/modules/tautulli/modules/graphs_stream_information/route.dart b/lib/modules/tautulli/routes/graphs_stream_information/route.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_stream_information/route.dart rename to lib/modules/tautulli/routes/graphs_stream_information/route.dart diff --git a/lib/modules/tautulli/modules/graphs_stream_information/widgets.dart b/lib/modules/tautulli/routes/graphs_stream_information/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_stream_information/widgets.dart rename to lib/modules/tautulli/routes/graphs_stream_information/widgets.dart diff --git a/lib/modules/tautulli/modules/graphs_stream_information/widgets/daily_stream_type_breakdown_graph.dart b/lib/modules/tautulli/routes/graphs_stream_information/widgets/daily_stream_type_breakdown_graph.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_stream_information/widgets/daily_stream_type_breakdown_graph.dart rename to lib/modules/tautulli/routes/graphs_stream_information/widgets/daily_stream_type_breakdown_graph.dart diff --git a/lib/modules/tautulli/modules/graphs_stream_information/widgets/play_count_by_platform_stream_type_graph.dart b/lib/modules/tautulli/routes/graphs_stream_information/widgets/play_count_by_platform_stream_type_graph.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_stream_information/widgets/play_count_by_platform_stream_type_graph.dart rename to lib/modules/tautulli/routes/graphs_stream_information/widgets/play_count_by_platform_stream_type_graph.dart diff --git a/lib/modules/tautulli/modules/graphs_stream_information/widgets/play_count_by_source_resolution_graph.dart b/lib/modules/tautulli/routes/graphs_stream_information/widgets/play_count_by_source_resolution_graph.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_stream_information/widgets/play_count_by_source_resolution_graph.dart rename to lib/modules/tautulli/routes/graphs_stream_information/widgets/play_count_by_source_resolution_graph.dart diff --git a/lib/modules/tautulli/modules/graphs_stream_information/widgets/play_count_by_stream_resolution_graph.dart b/lib/modules/tautulli/routes/graphs_stream_information/widgets/play_count_by_stream_resolution_graph.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_stream_information/widgets/play_count_by_stream_resolution_graph.dart rename to lib/modules/tautulli/routes/graphs_stream_information/widgets/play_count_by_stream_resolution_graph.dart diff --git a/lib/modules/tautulli/modules/graphs_stream_information/widgets/play_count_by_user_stream_type_graph.dart b/lib/modules/tautulli/routes/graphs_stream_information/widgets/play_count_by_user_stream_type_graph.dart similarity index 100% rename from lib/modules/tautulli/modules/graphs_stream_information/widgets/play_count_by_user_stream_type_graph.dart rename to lib/modules/tautulli/routes/graphs_stream_information/widgets/play_count_by_user_stream_type_graph.dart diff --git a/lib/modules/tautulli/modules/history.dart b/lib/modules/tautulli/routes/history.dart similarity index 100% rename from lib/modules/tautulli/modules/history.dart rename to lib/modules/tautulli/routes/history.dart diff --git a/lib/modules/tautulli/modules/history/route.dart b/lib/modules/tautulli/routes/history/route.dart similarity index 100% rename from lib/modules/tautulli/modules/history/route.dart rename to lib/modules/tautulli/routes/history/route.dart diff --git a/lib/modules/tautulli/modules/history/widgets.dart b/lib/modules/tautulli/routes/history/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/history/widgets.dart rename to lib/modules/tautulli/routes/history/widgets.dart diff --git a/lib/modules/tautulli/modules/history/widgets/history_tile.dart b/lib/modules/tautulli/routes/history/widgets/history_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/history/widgets/history_tile.dart rename to lib/modules/tautulli/routes/history/widgets/history_tile.dart diff --git a/lib/modules/tautulli/modules/history_details.dart b/lib/modules/tautulli/routes/history_details.dart similarity index 100% rename from lib/modules/tautulli/modules/history_details.dart rename to lib/modules/tautulli/routes/history_details.dart diff --git a/lib/modules/tautulli/modules/history_details/route.dart b/lib/modules/tautulli/routes/history_details/route.dart similarity index 100% rename from lib/modules/tautulli/modules/history_details/route.dart rename to lib/modules/tautulli/routes/history_details/route.dart diff --git a/lib/modules/tautulli/modules/history_details/widgets.dart b/lib/modules/tautulli/routes/history_details/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/history_details/widgets.dart rename to lib/modules/tautulli/routes/history_details/widgets.dart diff --git a/lib/modules/tautulli/modules/history_details/widgets/information.dart b/lib/modules/tautulli/routes/history_details/widgets/information.dart similarity index 100% rename from lib/modules/tautulli/modules/history_details/widgets/information.dart rename to lib/modules/tautulli/routes/history_details/widgets/information.dart diff --git a/lib/modules/tautulli/modules/history_details/widgets/metadata.dart b/lib/modules/tautulli/routes/history_details/widgets/metadata.dart similarity index 100% rename from lib/modules/tautulli/modules/history_details/widgets/metadata.dart rename to lib/modules/tautulli/routes/history_details/widgets/metadata.dart diff --git a/lib/modules/tautulli/modules/history_details/widgets/user.dart b/lib/modules/tautulli/routes/history_details/widgets/user.dart similarity index 100% rename from lib/modules/tautulli/modules/history_details/widgets/user.dart rename to lib/modules/tautulli/routes/history_details/widgets/user.dart diff --git a/lib/modules/tautulli/modules/ipaddress_details.dart b/lib/modules/tautulli/routes/ipaddress_details.dart similarity index 100% rename from lib/modules/tautulli/modules/ipaddress_details.dart rename to lib/modules/tautulli/routes/ipaddress_details.dart diff --git a/lib/modules/tautulli/modules/ipaddress_details/route.dart b/lib/modules/tautulli/routes/ipaddress_details/route.dart similarity index 100% rename from lib/modules/tautulli/modules/ipaddress_details/route.dart rename to lib/modules/tautulli/routes/ipaddress_details/route.dart diff --git a/lib/modules/tautulli/modules/ipaddress_details/widgets.dart b/lib/modules/tautulli/routes/ipaddress_details/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/ipaddress_details/widgets.dart rename to lib/modules/tautulli/routes/ipaddress_details/widgets.dart diff --git a/lib/modules/tautulli/modules/ipaddress_details/widgets/geolocation_tile.dart b/lib/modules/tautulli/routes/ipaddress_details/widgets/geolocation_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/ipaddress_details/widgets/geolocation_tile.dart rename to lib/modules/tautulli/routes/ipaddress_details/widgets/geolocation_tile.dart diff --git a/lib/modules/tautulli/modules/ipaddress_details/widgets/whois_tile.dart b/lib/modules/tautulli/routes/ipaddress_details/widgets/whois_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/ipaddress_details/widgets/whois_tile.dart rename to lib/modules/tautulli/routes/ipaddress_details/widgets/whois_tile.dart diff --git a/lib/modules/tautulli/modules/libraries.dart b/lib/modules/tautulli/routes/libraries.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries.dart rename to lib/modules/tautulli/routes/libraries.dart diff --git a/lib/modules/tautulli/modules/libraries/route.dart b/lib/modules/tautulli/routes/libraries/route.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries/route.dart rename to lib/modules/tautulli/routes/libraries/route.dart diff --git a/lib/modules/tautulli/modules/libraries/widgets.dart b/lib/modules/tautulli/routes/libraries/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries/widgets.dart rename to lib/modules/tautulli/routes/libraries/widgets.dart diff --git a/lib/modules/tautulli/modules/libraries/widgets/library_tile.dart b/lib/modules/tautulli/routes/libraries/widgets/library_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries/widgets/library_tile.dart rename to lib/modules/tautulli/routes/libraries/widgets/library_tile.dart diff --git a/lib/modules/tautulli/modules/libraries_details.dart b/lib/modules/tautulli/routes/libraries_details.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries_details.dart rename to lib/modules/tautulli/routes/libraries_details.dart diff --git a/lib/modules/tautulli/modules/libraries_details/route.dart b/lib/modules/tautulli/routes/libraries_details/route.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries_details/route.dart rename to lib/modules/tautulli/routes/libraries_details/route.dart diff --git a/lib/modules/tautulli/modules/libraries_details/widgets.dart b/lib/modules/tautulli/routes/libraries_details/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries_details/widgets.dart rename to lib/modules/tautulli/routes/libraries_details/widgets.dart diff --git a/lib/modules/tautulli/modules/libraries_details/widgets/information.dart b/lib/modules/tautulli/routes/libraries_details/widgets/information.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries_details/widgets/information.dart rename to lib/modules/tautulli/routes/libraries_details/widgets/information.dart diff --git a/lib/modules/tautulli/modules/libraries_details/widgets/information_details.dart b/lib/modules/tautulli/routes/libraries_details/widgets/information_details.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries_details/widgets/information_details.dart rename to lib/modules/tautulli/routes/libraries_details/widgets/information_details.dart diff --git a/lib/modules/tautulli/modules/libraries_details/widgets/information_global_stats.dart b/lib/modules/tautulli/routes/libraries_details/widgets/information_global_stats.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries_details/widgets/information_global_stats.dart rename to lib/modules/tautulli/routes/libraries_details/widgets/information_global_stats.dart diff --git a/lib/modules/tautulli/modules/libraries_details/widgets/navigation_bar.dart b/lib/modules/tautulli/routes/libraries_details/widgets/navigation_bar.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries_details/widgets/navigation_bar.dart rename to lib/modules/tautulli/routes/libraries_details/widgets/navigation_bar.dart diff --git a/lib/modules/tautulli/modules/libraries_details/widgets/user_stats.dart b/lib/modules/tautulli/routes/libraries_details/widgets/user_stats.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries_details/widgets/user_stats.dart rename to lib/modules/tautulli/routes/libraries_details/widgets/user_stats.dart diff --git a/lib/modules/tautulli/modules/libraries_details/widgets/user_stats_tile.dart b/lib/modules/tautulli/routes/libraries_details/widgets/user_stats_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/libraries_details/widgets/user_stats_tile.dart rename to lib/modules/tautulli/routes/libraries_details/widgets/user_stats_tile.dart diff --git a/lib/modules/tautulli/modules/logs.dart b/lib/modules/tautulli/routes/logs.dart similarity index 100% rename from lib/modules/tautulli/modules/logs.dart rename to lib/modules/tautulli/routes/logs.dart diff --git a/lib/modules/tautulli/modules/logs/route.dart b/lib/modules/tautulli/routes/logs/route.dart similarity index 100% rename from lib/modules/tautulli/modules/logs/route.dart rename to lib/modules/tautulli/routes/logs/route.dart diff --git a/lib/modules/tautulli/modules/logs/widgets.dart b/lib/modules/tautulli/routes/logs/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/logs/widgets.dart rename to lib/modules/tautulli/routes/logs/widgets.dart diff --git a/lib/modules/tautulli/modules/logs/widgets/logins_tile.dart b/lib/modules/tautulli/routes/logs/widgets/logins_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/logs/widgets/logins_tile.dart rename to lib/modules/tautulli/routes/logs/widgets/logins_tile.dart diff --git a/lib/modules/tautulli/modules/logs/widgets/newsletters_tile.dart b/lib/modules/tautulli/routes/logs/widgets/newsletters_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/logs/widgets/newsletters_tile.dart rename to lib/modules/tautulli/routes/logs/widgets/newsletters_tile.dart diff --git a/lib/modules/tautulli/modules/logs/widgets/notifications_tile.dart b/lib/modules/tautulli/routes/logs/widgets/notifications_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/logs/widgets/notifications_tile.dart rename to lib/modules/tautulli/routes/logs/widgets/notifications_tile.dart diff --git a/lib/modules/tautulli/modules/logs/widgets/plex_media_scanner.dart b/lib/modules/tautulli/routes/logs/widgets/plex_media_scanner.dart similarity index 100% rename from lib/modules/tautulli/modules/logs/widgets/plex_media_scanner.dart rename to lib/modules/tautulli/routes/logs/widgets/plex_media_scanner.dart diff --git a/lib/modules/tautulli/modules/logs/widgets/plex_media_server_tile.dart b/lib/modules/tautulli/routes/logs/widgets/plex_media_server_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/logs/widgets/plex_media_server_tile.dart rename to lib/modules/tautulli/routes/logs/widgets/plex_media_server_tile.dart diff --git a/lib/modules/tautulli/modules/logs/widgets/tautulli_tile.dart b/lib/modules/tautulli/routes/logs/widgets/tautulli_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/logs/widgets/tautulli_tile.dart rename to lib/modules/tautulli/routes/logs/widgets/tautulli_tile.dart diff --git a/lib/modules/tautulli/modules/logs_logins.dart b/lib/modules/tautulli/routes/logs_logins.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_logins.dart rename to lib/modules/tautulli/routes/logs_logins.dart diff --git a/lib/modules/tautulli/modules/logs_logins/route.dart b/lib/modules/tautulli/routes/logs_logins/route.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_logins/route.dart rename to lib/modules/tautulli/routes/logs_logins/route.dart diff --git a/lib/modules/tautulli/modules/logs_logins/widgets.dart b/lib/modules/tautulli/routes/logs_logins/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_logins/widgets.dart rename to lib/modules/tautulli/routes/logs_logins/widgets.dart diff --git a/lib/modules/tautulli/modules/logs_logins/widgets/log_tile.dart b/lib/modules/tautulli/routes/logs_logins/widgets/log_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_logins/widgets/log_tile.dart rename to lib/modules/tautulli/routes/logs_logins/widgets/log_tile.dart diff --git a/lib/modules/tautulli/modules/logs_newsletters.dart b/lib/modules/tautulli/routes/logs_newsletters.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_newsletters.dart rename to lib/modules/tautulli/routes/logs_newsletters.dart diff --git a/lib/modules/tautulli/modules/logs_newsletters/route.dart b/lib/modules/tautulli/routes/logs_newsletters/route.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_newsletters/route.dart rename to lib/modules/tautulli/routes/logs_newsletters/route.dart diff --git a/lib/modules/tautulli/modules/logs_newsletters/widgets.dart b/lib/modules/tautulli/routes/logs_newsletters/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_newsletters/widgets.dart rename to lib/modules/tautulli/routes/logs_newsletters/widgets.dart diff --git a/lib/modules/tautulli/modules/logs_newsletters/widgets/log_tile.dart b/lib/modules/tautulli/routes/logs_newsletters/widgets/log_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_newsletters/widgets/log_tile.dart rename to lib/modules/tautulli/routes/logs_newsletters/widgets/log_tile.dart diff --git a/lib/modules/tautulli/modules/logs_notifications.dart b/lib/modules/tautulli/routes/logs_notifications.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_notifications.dart rename to lib/modules/tautulli/routes/logs_notifications.dart diff --git a/lib/modules/tautulli/modules/logs_notifications/route.dart b/lib/modules/tautulli/routes/logs_notifications/route.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_notifications/route.dart rename to lib/modules/tautulli/routes/logs_notifications/route.dart diff --git a/lib/modules/tautulli/modules/logs_notifications/widgets.dart b/lib/modules/tautulli/routes/logs_notifications/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_notifications/widgets.dart rename to lib/modules/tautulli/routes/logs_notifications/widgets.dart diff --git a/lib/modules/tautulli/modules/logs_notifications/widgets/log_tile.dart b/lib/modules/tautulli/routes/logs_notifications/widgets/log_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_notifications/widgets/log_tile.dart rename to lib/modules/tautulli/routes/logs_notifications/widgets/log_tile.dart diff --git a/lib/modules/tautulli/modules/logs_plex_media_scanner.dart b/lib/modules/tautulli/routes/logs_plex_media_scanner.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_plex_media_scanner.dart rename to lib/modules/tautulli/routes/logs_plex_media_scanner.dart diff --git a/lib/modules/tautulli/modules/logs_plex_media_scanner/route.dart b/lib/modules/tautulli/routes/logs_plex_media_scanner/route.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_plex_media_scanner/route.dart rename to lib/modules/tautulli/routes/logs_plex_media_scanner/route.dart diff --git a/lib/modules/tautulli/modules/logs_plex_media_scanner/widgets.dart b/lib/modules/tautulli/routes/logs_plex_media_scanner/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_plex_media_scanner/widgets.dart rename to lib/modules/tautulli/routes/logs_plex_media_scanner/widgets.dart diff --git a/lib/modules/tautulli/modules/logs_plex_media_scanner/widgets/log_tile.dart b/lib/modules/tautulli/routes/logs_plex_media_scanner/widgets/log_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_plex_media_scanner/widgets/log_tile.dart rename to lib/modules/tautulli/routes/logs_plex_media_scanner/widgets/log_tile.dart diff --git a/lib/modules/tautulli/modules/logs_plex_media_server.dart b/lib/modules/tautulli/routes/logs_plex_media_server.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_plex_media_server.dart rename to lib/modules/tautulli/routes/logs_plex_media_server.dart diff --git a/lib/modules/tautulli/modules/logs_plex_media_server/route.dart b/lib/modules/tautulli/routes/logs_plex_media_server/route.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_plex_media_server/route.dart rename to lib/modules/tautulli/routes/logs_plex_media_server/route.dart diff --git a/lib/modules/tautulli/modules/logs_plex_media_server/widgets.dart b/lib/modules/tautulli/routes/logs_plex_media_server/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_plex_media_server/widgets.dart rename to lib/modules/tautulli/routes/logs_plex_media_server/widgets.dart diff --git a/lib/modules/tautulli/modules/logs_plex_media_server/widgets/log_tile.dart b/lib/modules/tautulli/routes/logs_plex_media_server/widgets/log_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_plex_media_server/widgets/log_tile.dart rename to lib/modules/tautulli/routes/logs_plex_media_server/widgets/log_tile.dart diff --git a/lib/modules/tautulli/modules/logs_tautulli.dart b/lib/modules/tautulli/routes/logs_tautulli.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_tautulli.dart rename to lib/modules/tautulli/routes/logs_tautulli.dart diff --git a/lib/modules/tautulli/modules/logs_tautulli/route.dart b/lib/modules/tautulli/routes/logs_tautulli/route.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_tautulli/route.dart rename to lib/modules/tautulli/routes/logs_tautulli/route.dart diff --git a/lib/modules/tautulli/modules/logs_tautulli/widgets.dart b/lib/modules/tautulli/routes/logs_tautulli/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_tautulli/widgets.dart rename to lib/modules/tautulli/routes/logs_tautulli/widgets.dart diff --git a/lib/modules/tautulli/modules/logs_tautulli/widgets/log_tile.dart b/lib/modules/tautulli/routes/logs_tautulli/widgets/log_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/logs_tautulli/widgets/log_tile.dart rename to lib/modules/tautulli/routes/logs_tautulli/widgets/log_tile.dart diff --git a/lib/modules/tautulli/modules/media_details.dart b/lib/modules/tautulli/routes/media_details.dart similarity index 100% rename from lib/modules/tautulli/modules/media_details.dart rename to lib/modules/tautulli/routes/media_details.dart diff --git a/lib/modules/tautulli/modules/media_details/route.dart b/lib/modules/tautulli/routes/media_details/route.dart similarity index 100% rename from lib/modules/tautulli/modules/media_details/route.dart rename to lib/modules/tautulli/routes/media_details/route.dart diff --git a/lib/modules/tautulli/modules/media_details/widgets.dart b/lib/modules/tautulli/routes/media_details/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/media_details/widgets.dart rename to lib/modules/tautulli/routes/media_details/widgets.dart diff --git a/lib/modules/tautulli/modules/media_details/widgets/history.dart b/lib/modules/tautulli/routes/media_details/widgets/history.dart similarity index 100% rename from lib/modules/tautulli/modules/media_details/widgets/history.dart rename to lib/modules/tautulli/routes/media_details/widgets/history.dart diff --git a/lib/modules/tautulli/modules/media_details/widgets/metadata.dart b/lib/modules/tautulli/routes/media_details/widgets/metadata.dart similarity index 100% rename from lib/modules/tautulli/modules/media_details/widgets/metadata.dart rename to lib/modules/tautulli/routes/media_details/widgets/metadata.dart diff --git a/lib/modules/tautulli/modules/media_details/widgets/metadata_header.dart b/lib/modules/tautulli/routes/media_details/widgets/metadata_header.dart similarity index 100% rename from lib/modules/tautulli/modules/media_details/widgets/metadata_header.dart rename to lib/modules/tautulli/routes/media_details/widgets/metadata_header.dart diff --git a/lib/modules/tautulli/modules/media_details/widgets/metadata_metadata.dart b/lib/modules/tautulli/routes/media_details/widgets/metadata_metadata.dart similarity index 100% rename from lib/modules/tautulli/modules/media_details/widgets/metadata_metadata.dart rename to lib/modules/tautulli/routes/media_details/widgets/metadata_metadata.dart diff --git a/lib/modules/tautulli/modules/media_details/widgets/metadata_summary.dart b/lib/modules/tautulli/routes/media_details/widgets/metadata_summary.dart similarity index 100% rename from lib/modules/tautulli/modules/media_details/widgets/metadata_summary.dart rename to lib/modules/tautulli/routes/media_details/widgets/metadata_summary.dart diff --git a/lib/modules/tautulli/modules/media_details/widgets/navigation_bar.dart b/lib/modules/tautulli/routes/media_details/widgets/navigation_bar.dart similarity index 100% rename from lib/modules/tautulli/modules/media_details/widgets/navigation_bar.dart rename to lib/modules/tautulli/routes/media_details/widgets/navigation_bar.dart diff --git a/lib/modules/tautulli/modules/media_details/widgets/switcher_buttons.dart b/lib/modules/tautulli/routes/media_details/widgets/switcher_buttons.dart similarity index 100% rename from lib/modules/tautulli/modules/media_details/widgets/switcher_buttons.dart rename to lib/modules/tautulli/routes/media_details/widgets/switcher_buttons.dart diff --git a/lib/modules/tautulli/modules/more.dart b/lib/modules/tautulli/routes/more.dart similarity index 100% rename from lib/modules/tautulli/modules/more.dart rename to lib/modules/tautulli/routes/more.dart diff --git a/lib/modules/tautulli/modules/more/route.dart b/lib/modules/tautulli/routes/more/route.dart similarity index 100% rename from lib/modules/tautulli/modules/more/route.dart rename to lib/modules/tautulli/routes/more/route.dart diff --git a/lib/modules/tautulli/modules/more/widgets.dart b/lib/modules/tautulli/routes/more/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/more/widgets.dart rename to lib/modules/tautulli/routes/more/widgets.dart diff --git a/lib/modules/tautulli/modules/more/widgets/check_for_updates_tile.dart b/lib/modules/tautulli/routes/more/widgets/check_for_updates_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/more/widgets/check_for_updates_tile.dart rename to lib/modules/tautulli/routes/more/widgets/check_for_updates_tile.dart diff --git a/lib/modules/tautulli/modules/more/widgets/graphs_tile.dart b/lib/modules/tautulli/routes/more/widgets/graphs_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/more/widgets/graphs_tile.dart rename to lib/modules/tautulli/routes/more/widgets/graphs_tile.dart diff --git a/lib/modules/tautulli/modules/more/widgets/libraries_tile.dart b/lib/modules/tautulli/routes/more/widgets/libraries_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/more/widgets/libraries_tile.dart rename to lib/modules/tautulli/routes/more/widgets/libraries_tile.dart diff --git a/lib/modules/tautulli/modules/more/widgets/logs_tile.dart b/lib/modules/tautulli/routes/more/widgets/logs_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/more/widgets/logs_tile.dart rename to lib/modules/tautulli/routes/more/widgets/logs_tile.dart diff --git a/lib/modules/tautulli/modules/more/widgets/recently_added_tile.dart b/lib/modules/tautulli/routes/more/widgets/recently_added_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/more/widgets/recently_added_tile.dart rename to lib/modules/tautulli/routes/more/widgets/recently_added_tile.dart diff --git a/lib/modules/tautulli/modules/more/widgets/search_tile.dart b/lib/modules/tautulli/routes/more/widgets/search_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/more/widgets/search_tile.dart rename to lib/modules/tautulli/routes/more/widgets/search_tile.dart diff --git a/lib/modules/tautulli/modules/more/widgets/statistics_tile.dart b/lib/modules/tautulli/routes/more/widgets/statistics_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/more/widgets/statistics_tile.dart rename to lib/modules/tautulli/routes/more/widgets/statistics_tile.dart diff --git a/lib/modules/tautulli/modules/more/widgets/synced_items_tile.dart b/lib/modules/tautulli/routes/more/widgets/synced_items_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/more/widgets/synced_items_tile.dart rename to lib/modules/tautulli/routes/more/widgets/synced_items_tile.dart diff --git a/lib/modules/tautulli/modules/recently_added.dart b/lib/modules/tautulli/routes/recently_added.dart similarity index 100% rename from lib/modules/tautulli/modules/recently_added.dart rename to lib/modules/tautulli/routes/recently_added.dart diff --git a/lib/modules/tautulli/modules/recently_added/route.dart b/lib/modules/tautulli/routes/recently_added/route.dart similarity index 100% rename from lib/modules/tautulli/modules/recently_added/route.dart rename to lib/modules/tautulli/routes/recently_added/route.dart diff --git a/lib/modules/tautulli/modules/recently_added/widgets.dart b/lib/modules/tautulli/routes/recently_added/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/recently_added/widgets.dart rename to lib/modules/tautulli/routes/recently_added/widgets.dart diff --git a/lib/modules/tautulli/modules/recently_added/widgets/content_tile.dart b/lib/modules/tautulli/routes/recently_added/widgets/content_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/recently_added/widgets/content_tile.dart rename to lib/modules/tautulli/routes/recently_added/widgets/content_tile.dart diff --git a/lib/modules/tautulli/modules/search.dart b/lib/modules/tautulli/routes/search.dart similarity index 100% rename from lib/modules/tautulli/modules/search.dart rename to lib/modules/tautulli/routes/search.dart diff --git a/lib/modules/tautulli/modules/search/route.dart b/lib/modules/tautulli/routes/search/route.dart similarity index 100% rename from lib/modules/tautulli/modules/search/route.dart rename to lib/modules/tautulli/routes/search/route.dart diff --git a/lib/modules/tautulli/modules/search/widgets.dart b/lib/modules/tautulli/routes/search/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/search/widgets.dart rename to lib/modules/tautulli/routes/search/widgets.dart diff --git a/lib/modules/tautulli/modules/search/widgets/search_appbar.dart b/lib/modules/tautulli/routes/search/widgets/search_appbar.dart similarity index 100% rename from lib/modules/tautulli/modules/search/widgets/search_appbar.dart rename to lib/modules/tautulli/routes/search/widgets/search_appbar.dart diff --git a/lib/modules/tautulli/modules/search/widgets/search_result_tile.dart b/lib/modules/tautulli/routes/search/widgets/search_result_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/search/widgets/search_result_tile.dart rename to lib/modules/tautulli/routes/search/widgets/search_result_tile.dart diff --git a/lib/modules/tautulli/modules/search/widgets/search_results.dart b/lib/modules/tautulli/routes/search/widgets/search_results.dart similarity index 100% rename from lib/modules/tautulli/modules/search/widgets/search_results.dart rename to lib/modules/tautulli/routes/search/widgets/search_results.dart diff --git a/lib/modules/tautulli/modules/statistics.dart b/lib/modules/tautulli/routes/statistics.dart similarity index 100% rename from lib/modules/tautulli/modules/statistics.dart rename to lib/modules/tautulli/routes/statistics.dart diff --git a/lib/modules/tautulli/modules/statistics/route.dart b/lib/modules/tautulli/routes/statistics/route.dart similarity index 100% rename from lib/modules/tautulli/modules/statistics/route.dart rename to lib/modules/tautulli/routes/statistics/route.dart diff --git a/lib/modules/tautulli/modules/statistics/widgets.dart b/lib/modules/tautulli/routes/statistics/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/statistics/widgets.dart rename to lib/modules/tautulli/routes/statistics/widgets.dart diff --git a/lib/modules/tautulli/modules/statistics/widgets/media_tile.dart b/lib/modules/tautulli/routes/statistics/widgets/media_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/statistics/widgets/media_tile.dart rename to lib/modules/tautulli/routes/statistics/widgets/media_tile.dart diff --git a/lib/modules/tautulli/modules/statistics/widgets/platform_tile.dart b/lib/modules/tautulli/routes/statistics/widgets/platform_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/statistics/widgets/platform_tile.dart rename to lib/modules/tautulli/routes/statistics/widgets/platform_tile.dart diff --git a/lib/modules/tautulli/modules/statistics/widgets/recently_watched_tile.dart b/lib/modules/tautulli/routes/statistics/widgets/recently_watched_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/statistics/widgets/recently_watched_tile.dart rename to lib/modules/tautulli/routes/statistics/widgets/recently_watched_tile.dart diff --git a/lib/modules/tautulli/modules/statistics/widgets/stream_tile.dart b/lib/modules/tautulli/routes/statistics/widgets/stream_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/statistics/widgets/stream_tile.dart rename to lib/modules/tautulli/routes/statistics/widgets/stream_tile.dart diff --git a/lib/modules/tautulli/modules/statistics/widgets/time_range_button.dart b/lib/modules/tautulli/routes/statistics/widgets/time_range_button.dart similarity index 100% rename from lib/modules/tautulli/modules/statistics/widgets/time_range_button.dart rename to lib/modules/tautulli/routes/statistics/widgets/time_range_button.dart diff --git a/lib/modules/tautulli/modules/statistics/widgets/type_button.dart b/lib/modules/tautulli/routes/statistics/widgets/type_button.dart similarity index 100% rename from lib/modules/tautulli/modules/statistics/widgets/type_button.dart rename to lib/modules/tautulli/routes/statistics/widgets/type_button.dart diff --git a/lib/modules/tautulli/modules/statistics/widgets/user_tile.dart b/lib/modules/tautulli/routes/statistics/widgets/user_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/statistics/widgets/user_tile.dart rename to lib/modules/tautulli/routes/statistics/widgets/user_tile.dart diff --git a/lib/modules/tautulli/modules/synced_items.dart b/lib/modules/tautulli/routes/synced_items.dart similarity index 100% rename from lib/modules/tautulli/modules/synced_items.dart rename to lib/modules/tautulli/routes/synced_items.dart diff --git a/lib/modules/tautulli/modules/synced_items/route.dart b/lib/modules/tautulli/routes/synced_items/route.dart similarity index 100% rename from lib/modules/tautulli/modules/synced_items/route.dart rename to lib/modules/tautulli/routes/synced_items/route.dart diff --git a/lib/modules/tautulli/modules/synced_items/widgets.dart b/lib/modules/tautulli/routes/synced_items/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/synced_items/widgets.dart rename to lib/modules/tautulli/routes/synced_items/widgets.dart diff --git a/lib/modules/tautulli/modules/synced_items/widgets/synced_item_tile.dart b/lib/modules/tautulli/routes/synced_items/widgets/synced_item_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/synced_items/widgets/synced_item_tile.dart rename to lib/modules/tautulli/routes/synced_items/widgets/synced_item_tile.dart diff --git a/lib/modules/tautulli/modules/tautulli.dart b/lib/modules/tautulli/routes/tautulli.dart similarity index 100% rename from lib/modules/tautulli/modules/tautulli.dart rename to lib/modules/tautulli/routes/tautulli.dart diff --git a/lib/modules/tautulli/modules/tautulli/route.dart b/lib/modules/tautulli/routes/tautulli/route.dart similarity index 97% rename from lib/modules/tautulli/modules/tautulli/route.dart rename to lib/modules/tautulli/routes/tautulli/route.dart index 28be747a..2f2ebf01 100644 --- a/lib/modules/tautulli/modules/tautulli/route.dart +++ b/lib/modules/tautulli/routes/tautulli/route.dart @@ -60,7 +60,7 @@ class _State extends State<_TautulliHomeRoute> { return false; } - Widget get _drawer => LSDrawer(page: 'tautulli'); + Widget get _drawer => LunaDrawer(page: LunaModule.TAUTULLI.key); Widget get _bottomNavigationBar => TautulliNavigationBar(pageController: _pageController); diff --git a/lib/modules/tautulli/modules/tautulli/widgets.dart b/lib/modules/tautulli/routes/tautulli/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/tautulli/widgets.dart rename to lib/modules/tautulli/routes/tautulli/widgets.dart diff --git a/lib/modules/tautulli/modules/tautulli/widgets/global_settings.dart b/lib/modules/tautulli/routes/tautulli/widgets/global_settings.dart similarity index 100% rename from lib/modules/tautulli/modules/tautulli/widgets/global_settings.dart rename to lib/modules/tautulli/routes/tautulli/widgets/global_settings.dart diff --git a/lib/modules/tautulli/modules/tautulli/widgets/navigation_bar.dart b/lib/modules/tautulli/routes/tautulli/widgets/navigation_bar.dart similarity index 100% rename from lib/modules/tautulli/modules/tautulli/widgets/navigation_bar.dart rename to lib/modules/tautulli/routes/tautulli/widgets/navigation_bar.dart diff --git a/lib/modules/tautulli/modules/users.dart b/lib/modules/tautulli/routes/users.dart similarity index 100% rename from lib/modules/tautulli/modules/users.dart rename to lib/modules/tautulli/routes/users.dart diff --git a/lib/modules/tautulli/modules/users/route.dart b/lib/modules/tautulli/routes/users/route.dart similarity index 100% rename from lib/modules/tautulli/modules/users/route.dart rename to lib/modules/tautulli/routes/users/route.dart diff --git a/lib/modules/tautulli/modules/users/widgets.dart b/lib/modules/tautulli/routes/users/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/users/widgets.dart rename to lib/modules/tautulli/routes/users/widgets.dart diff --git a/lib/modules/tautulli/modules/users/widgets/user_tile.dart b/lib/modules/tautulli/routes/users/widgets/user_tile.dart similarity index 100% rename from lib/modules/tautulli/modules/users/widgets/user_tile.dart rename to lib/modules/tautulli/routes/users/widgets/user_tile.dart diff --git a/lib/modules/tautulli/modules/users_details.dart b/lib/modules/tautulli/routes/users_details.dart similarity index 100% rename from lib/modules/tautulli/modules/users_details.dart rename to lib/modules/tautulli/routes/users_details.dart diff --git a/lib/modules/tautulli/modules/users_details/route.dart b/lib/modules/tautulli/routes/users_details/route.dart similarity index 100% rename from lib/modules/tautulli/modules/users_details/route.dart rename to lib/modules/tautulli/routes/users_details/route.dart diff --git a/lib/modules/tautulli/modules/users_details/widgets.dart b/lib/modules/tautulli/routes/users_details/widgets.dart similarity index 100% rename from lib/modules/tautulli/modules/users_details/widgets.dart rename to lib/modules/tautulli/routes/users_details/widgets.dart diff --git a/lib/modules/tautulli/modules/users_details/widgets/history.dart b/lib/modules/tautulli/routes/users_details/widgets/history.dart similarity index 100% rename from lib/modules/tautulli/modules/users_details/widgets/history.dart rename to lib/modules/tautulli/routes/users_details/widgets/history.dart diff --git a/lib/modules/tautulli/modules/users_details/widgets/ip_addresses.dart b/lib/modules/tautulli/routes/users_details/widgets/ip_addresses.dart similarity index 100% rename from lib/modules/tautulli/modules/users_details/widgets/ip_addresses.dart rename to lib/modules/tautulli/routes/users_details/widgets/ip_addresses.dart diff --git a/lib/modules/tautulli/modules/users_details/widgets/navigation_bar.dart b/lib/modules/tautulli/routes/users_details/widgets/navigation_bar.dart similarity index 100% rename from lib/modules/tautulli/modules/users_details/widgets/navigation_bar.dart rename to lib/modules/tautulli/routes/users_details/widgets/navigation_bar.dart diff --git a/lib/modules/tautulli/modules/users_details/widgets/profile.dart b/lib/modules/tautulli/routes/users_details/widgets/profile.dart similarity index 100% rename from lib/modules/tautulli/modules/users_details/widgets/profile.dart rename to lib/modules/tautulli/routes/users_details/widgets/profile.dart diff --git a/lib/modules/tautulli/modules/users_details/widgets/synced_items.dart b/lib/modules/tautulli/routes/users_details/widgets/synced_items.dart similarity index 100% rename from lib/modules/tautulli/modules/users_details/widgets/synced_items.dart rename to lib/modules/tautulli/routes/users_details/widgets/synced_items.dart diff --git a/lib/modules/wake_on_lan/core/api.dart b/lib/modules/wake_on_lan/core/api.dart index 1ad7d089..137801ee 100644 --- a/lib/modules/wake_on_lan/core/api.dart +++ b/lib/modules/wake_on_lan/core/api.dart @@ -1,29 +1,31 @@ +import 'package:flutter/material.dart'; import 'package:lunasea/core.dart'; import 'package:wake_on_lan/wake_on_lan.dart'; class WakeOnLANAPI { - final Map _values; + final bool enabled; + final String broadcastAddress; + final String macAddress; - WakeOnLANAPI._internal(this._values); - factory WakeOnLANAPI.from(ProfileHiveObject profile) => WakeOnLANAPI._internal(profile.getWakeOnLAN()); + WakeOnLANAPI._internal({ + @required this.enabled, + @required this.broadcastAddress, + @required this.macAddress, + }); + + factory WakeOnLANAPI.fromProfile() { + ProfileHiveObject profile = Database.currentProfileObject; + return WakeOnLANAPI._internal( + enabled: profile.wakeOnLANEnabled, + broadcastAddress: profile.wakeOnLANBroadcastAddress, + macAddress: profile.wakeOnLANMACAddress, + ); + } - void logError(String text, Object error, StackTrace trace) => LunaLogger().error('Wake on LAN: $text', error, trace); - - bool get enabled => _values['enabled']; - String get broadcastAddress => _values['broadcastAddress']; - String get macAddress => _values['MACAddress']; - - Future testConnection() async => true; - - Future wake() async { - try { - IPv4Address ipv4 = IPv4Address.from(broadcastAddress); - MACAddress mac = MACAddress.from(macAddress); - await WakeOnLAN.from(ipv4, mac).wake(); - return true; - } catch (error, stack) { - logError('Failed to wake machine', error, stack); - return Future.error(error); - } + Future wake() async { + IPv4Address ipv4 = IPv4Address.from(broadcastAddress); + MACAddress mac = MACAddress.from(macAddress); + await WakeOnLAN.from(ipv4, mac).wake(); + return true; } } diff --git a/localization/lunasea/en.json b/localization/lunasea/en.json new file mode 100644 index 00000000..78a5f4d6 --- /dev/null +++ b/localization/lunasea/en.json @@ -0,0 +1,11 @@ +{ + "lunasea.AnErrorHasOccurred": "An Error Has Occurred", + "lunasea.ComingSoon": "Coming Soon", + "lunasea.GoBack": "Go Back", + "lunasea.ModuleIsNotEnabled": "{} Is Not Enabled", + "lunasea.Refresh": "Refresh", + "lunasea.ReturnToDashboard": "Return to Dashboard", + "lunasea.SearchTextBar": "Search…", + "lunasea.Settings": "Settings", + "lunasea.TryAgain": "Try Again" +} diff --git a/localization/lunasea/fr.json b/localization/lunasea/fr.json new file mode 100644 index 00000000..d9503b00 --- /dev/null +++ b/localization/lunasea/fr.json @@ -0,0 +1,11 @@ +{ + "lunasea.AnErrorHasOccurred": "Une erreur s'est produite", + "lunasea.ComingSoon": "Prochainement", + "lunasea.GoBack": "Retour en arrière", + "lunasea.ModuleIsNotEnabled": "{} n'est pas activé", + "lunasea.Refresh": "Rafraichir", + "lunasea.ReturnToDashboard": "Retour au tableau de bord", + "lunasea.SearchTextBar": "Rechercher…", + "lunasea.Settings": "Réglages", + "lunasea.TryAgain": "Réessayer" +} diff --git a/localization/lunasea/nb-NO.json b/localization/lunasea/nb-NO.json new file mode 100644 index 00000000..85b3d824 --- /dev/null +++ b/localization/lunasea/nb-NO.json @@ -0,0 +1,6 @@ +{ + "lunasea.AnErrorHasOccurred": "En feil har inntruffet", + "lunasea.Refresh": "Gjenoppfrisk", + "lunasea.SearchTextBar": "Søk …", + "lunasea.Settings": "Innstillinger" +} diff --git a/localization/lunasea/sv.json b/localization/lunasea/sv.json new file mode 100644 index 00000000..0589d4a4 --- /dev/null +++ b/localization/lunasea/sv.json @@ -0,0 +1,6 @@ +{ + "lunasea.AnErrorHasOccurred": "Ett fel har inträffat", + "lunasea.Refresh": "Uppdatera", + "lunasea.SearchTextBar": "Sök…", + "lunasea.Settings": "Inställningar" +} diff --git a/localization/radarr/en.json b/localization/radarr/en.json new file mode 100644 index 00000000..c45ffda4 --- /dev/null +++ b/localization/radarr/en.json @@ -0,0 +1,73 @@ +{ + "radarr.Age": "Age", + "radarr.All": "All", + "radarr.AddMovie": "Add Movie", + "radarr.AddMovieAndSearch": "Add + Search", + "radarr.Alphabetical": "Alphabetical", + "radarr.Approved": "Approved", + "radarr.AvailabilityUnknown": "Availability Unknown", + "radarr.AvailableIn": "Available in {}", + "radarr.AvailableToday": "Available Today", + "radarr.BackupDatabase": "Backup Database", + "radarr.CinemaDateUnknown": "Cinema Date Unknown", + "radarr.CutoffUnmet": "Cutoff Unmet", + "radarr.DateAdded": "Date Added", + "radarr.Discover": "Discover", + "radarr.DownloadFailed": "Download Failed", + "radarr.DownloadIgnored": "Download Ignored", + "radarr.EditMovie": "Edit Movie", + "radarr.FilterCatalogue": "Filter Catalogue", + "radarr.GrabbedFrom": "Grabbed from {}", + "radarr.History": "History", + "radarr.HistoryDescription": "View Recent Activity", + "radarr.InCinemasIn": "In Cinemas in {}", + "radarr.InCinemasToday": "In Cinemas Today", + "radarr.MinimumAvailability": "Minimum Availability", + "radarr.Missing": "Missing", + "radarr.Monitored": "Monitored", + "radarr.MonitoredDescription": "Monitor for new releases", + "radarr.MonitorMovie": "Monitor Movie", + "radarr.More": "More", + "radarr.Movies": "Movies", + "radarr.MovieFileDeleted": "Movie File Deleted", + "radarr.MovieFileRenamed": "Movie File Renamed", + "radarr.MovieImported": "Movie Imported ({})", + "radarr.MovieNotFound": "Movie Not Found", + "radarr.MoviePath": "Movie Path", + "radarr.NoHistoryFound": "No History Found", + "radarr.NoMoviesFound": "No Movies Found", + "radarr.NoResultsFound": "No Results Found", + "radarr.NoSummaryIsAvailable": "No summary is available.", + "radarr.QualityProfile": "Quality Profile", + "radarr.Queue": "Queue", + "radarr.QueueDescription": "View Active & Queued Content", + "radarr.RefreshMovie": "Refresh Movie", + "radarr.Rejected": "Rejected", + "radarr.Released": "Released", + "radarr.ReleasedToday": "Released Today", + "radarr.RemoveMovie": "Remove Movie", + "radarr.RootFolder": "Root Folder", + "radarr.Runtime": "Runtime", + "radarr.RunRSSSync": "Run RSS Sync", + "radarr.Search": "Search", + "radarr.SearchAllMissing": "Search All Missing", + "radarr.SearchFor": "Search for {}", + "radarr.Seeders": "Seeders", + "radarr.Size": "Size", + "radarr.SortCatalogue": "Sort Catalogue", + "radarr.Studio": "Studio", + "radarr.SystemStatus": "System Status", + "radarr.SystemStatusDescription": "System Status & Disk Space", + "radarr.Tags": "Tags", + "radarr.TagsDescription": "Manage Your Tags", + "radarr.Type": "Type", + "radarr.Unmonitored": "Unmonitored", + "radarr.UnmonitorMovie": "Unmonitor Movie", + "radarr.Upcoming": "Upcoming", + "radarr.UpdateLibrary": "Update Library", + "radarr.UpdateMovie": "Update Movie", + "radarr.ViewWebGUI": "View Web GUI", + "radarr.Wanted": "Wanted", + "radarr.Weight": "Weight", + "radarr.Year": "Year" +} diff --git a/localization/radarr/fr.json b/localization/radarr/fr.json new file mode 100644 index 00000000..094659a8 --- /dev/null +++ b/localization/radarr/fr.json @@ -0,0 +1,73 @@ +{ + "radarr.AddMovie": "Ajouter un film", + "radarr.AddMovieAndSearch": "Ajouter + Rechercher", + "radarr.Age": "Âge", + "radarr.All": "Tout", + "radarr.Alphabetical": "Alphabétique", + "radarr.Approved": "Approuvé", + "radarr.AvailabilityUnknown": "Disponibilité inconnue", + "radarr.AvailableIn": "Disponible dans {}", + "radarr.AvailableToday": "Disponible aujourd'hui", + "radarr.BackupDatabase": "Sauvegarder la base de donnée", + "radarr.CinemaDateUnknown": "Date de sortie au cinéma inconnue", + "radarr.CutoffUnmet": "Qualité préférée non atteinte", + "radarr.DateAdded": "Date ajoutée", + "radarr.Discover": "Découvrir", + "radarr.DownloadFailed": "Echec du téléchargement", + "radarr.DownloadIgnored": "Télécharger Ignoré", + "radarr.EditMovie": "Modifier le film", + "radarr.FilterCatalogue": "Catalogue des filtres", + "radarr.GrabbedFrom": "Récupéré depuis {}", + "radarr.History": "Historique", + "radarr.HistoryDescription": "Voir les activités récentes", + "radarr.InCinemasIn": "Dans les cinémas en {}", + "radarr.InCinemasToday": "Au cinéma aujourd'hui", + "radarr.MinimumAvailability": "Disponibilité minimale", + "radarr.Missing": "Manquant", + "radarr.MonitorMovie": "Surveiller le film", + "radarr.Monitored": "Surveillé", + "radarr.MonitoredDescription": "Surveiller les nouvelles versions", + "radarr.More": "Plus", + "radarr.MovieFileDeleted": "Fichier vidéo supprimé", + "radarr.MovieFileRenamed": "Fichier vidéo renommé", + "radarr.MovieImported": "Film importé ({})", + "radarr.MovieNotFound": "Film non trouvé", + "radarr.MoviePath": "Chemin du film", + "radarr.Movies": "Films", + "radarr.NoHistoryFound": "Pas d'historique trouvé", + "radarr.NoMoviesFound": "Aucun film trouvé", + "radarr.NoResultsFound": "Aucun résultat", + "radarr.NoSummaryIsAvailable": "Aucun résumé n'est disponible.", + "radarr.QualityProfile": "Profil de la qualité", + "radarr.Queue": "File d'attente", + "radarr.QueueDescription": "Voir le contenu actif et en attente", + "radarr.RefreshMovie": "Rafraichir le film", + "radarr.Rejected": "Rejeté", + "radarr.Released": "Sortie", + "radarr.ReleasedToday": "Sortie aujourd'hui", + "radarr.RemoveMovie": "Supprimer le film", + "radarr.RootFolder": "Dossier racine", + "radarr.RunRSSSync": "Lancer la synchronisation RSS", + "radarr.Runtime": "Durée", + "radarr.Search": "Rechercher", + "radarr.SearchAllMissing": "Rechercher tous les manquants", + "radarr.SearchFor": "Rechercher {}", + "radarr.Seeders": "Seeders", + "radarr.Size": "Taille", + "radarr.SortCatalogue": "Trier le catalogue", + "radarr.Studio": "Studio", + "radarr.SystemStatus": "État du système", + "radarr.SystemStatusDescription": "État du système et espace disque", + "radarr.Tags": "Tags", + "radarr.TagsDescription": "Gérer vos tags", + "radarr.Type": "Type", + "radarr.UnmonitorMovie": "Ne plus surveiller le film", + "radarr.Unmonitored": "Non surveillé", + "radarr.Upcoming": "À venir", + "radarr.UpdateLibrary": "Mettre à jour la bibliothèque", + "radarr.UpdateMovie": "Mettre à jour le film", + "radarr.ViewWebGUI": "Voir l'interface web", + "radarr.Wanted": "Recherché", + "radarr.Weight": "Poids", + "radarr.Year": "Année" +} diff --git a/localization/radarr/nb-NO.json b/localization/radarr/nb-NO.json new file mode 100644 index 00000000..4e1e76c7 --- /dev/null +++ b/localization/radarr/nb-NO.json @@ -0,0 +1,33 @@ +{ + "radarr.AddMovie": "Legg til film", + "radarr.AddMovieAndSearch": "Legg til + søk", + "radarr.Discover": "Oppdag", + "radarr.EditMovie": "Rediger fil", + "radarr.FilterCatalogue": "Filtrer katalog", + "radarr.History": "Historikk", + "radarr.HistoryDescription": "Vis nylig historikk", + "radarr.MinimumAvailability": "Minimumstilgjengelighet", + "radarr.Missing": "Mangler", + "radarr.Monitored": "På oppsynsliste", + "radarr.MonitoredDescription": "Hold oppsyn med nye utgivelser", + "radarr.More": "Mer", + "radarr.MovieNotFound": "Fant ikke filmen", + "radarr.MoviePath": "Filmsti", + "radarr.Movies": "Filmer", + "radarr.NoMoviesFound": "Fant ingen filmer", + "radarr.NoResultsFound": "Resultatløst", + "radarr.NoSummaryIsAvailable": "Mangler sammendrag.", + "radarr.QualityProfile": "Kvalitetsprofil", + "radarr.Queue": "Kø", + "radarr.QueueDescription": "Vis aktivt og køplassert innhold", + "radarr.RootFolder": "Rotmappe", + "radarr.Search": "Søk", + "radarr.SearchFor": "Søkk etter {}", + "radarr.SortCatalogue": "Sorter katelog", + "radarr.SystemStatus": "Systemstatus", + "radarr.SystemStatusDescription": "Systemstatus og diskplass", + "radarr.Tags": "Etiketter", + "radarr.TagsDescription": "Håndter dine etiketter", + "radarr.Upcoming": "Kommende", + "radarr.UpdateMovie": "Oppdater film" +} diff --git a/localization/radarr/sv.json b/localization/radarr/sv.json new file mode 100644 index 00000000..32921f81 --- /dev/null +++ b/localization/radarr/sv.json @@ -0,0 +1,33 @@ +{ + "radarr.AddMovie": "Lägg till Film", + "radarr.AddMovieAndSearch": "Lägg till + Sök", + "radarr.Discover": "Utforska", + "radarr.EditMovie": "Redigera Film", + "radarr.FilterCatalogue": "Filterkatalog", + "radarr.History": "Historik", + "radarr.HistoryDescription": "Visa Senaste Aktivitet", + "radarr.MinimumAvailability": "Minsta Tillgänglighet", + "radarr.Missing": "Saknas", + "radarr.Monitored": "Bevakad", + "radarr.MonitoredDescription": "Bevaka för nya utgåvor", + "radarr.More": "Mer", + "radarr.MovieNotFound": "Film Hittades Inte", + "radarr.MoviePath": "Film Sökväg", + "radarr.Movies": "Filmer", + "radarr.NoMoviesFound": "Inga Filmer Funna", + "radarr.NoResultsFound": "Inga Resultat Funna", + "radarr.NoSummaryIsAvailable": "Ingen sammanfattning finns tillgänglig.", + "radarr.QualityProfile": "Kvalitetsprofil", + "radarr.Queue": "Kö", + "radarr.QueueDescription": "Visa Aktivt & Köat Innehåll", + "radarr.RootFolder": "Rotmapp", + "radarr.Search": "Sök", + "radarr.SearchFor": "Sök efter {}", + "radarr.SortCatalogue": "Sortera Katalog", + "radarr.SystemStatus": "Systemstatus", + "radarr.SystemStatusDescription": "Systemstatus & Disk Utrymme", + "radarr.Tags": "Taggar", + "radarr.TagsDescription": "Hantera Dina Taggar", + "radarr.Upcoming": "Kommande", + "radarr.UpdateMovie": "Uppdatera Film" +} diff --git a/pubspec.lock b/pubspec.lock index 1b3a448a..99ff5636 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,35 +7,28 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "14.0.0" + version: "17.0.0" analyzer: dependency: "direct dev" description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.41.2" - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.13" + version: "1.1.0" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.6.0" + version: "2.0.0" asn1lib: dependency: transitive description: name: asn1lib url: "https://pub.dartlang.org" source: hosted - version: "0.8.1" + version: "0.9.0-nullsafety.0" async: dependency: transitive description: @@ -56,14 +49,14 @@ packages: name: build url: "https://pub.dartlang.org" source: hosted - version: "1.6.2" + version: "1.6.3" build_config: dependency: transitive description: name: build_config url: "https://pub.dartlang.org" source: hosted - version: "0.4.5" + version: "0.4.6" build_daemon: dependency: transitive description: @@ -77,21 +70,21 @@ packages: name: build_resolvers url: "https://pub.dartlang.org" source: hosted - version: "1.5.3" + version: "1.5.4" build_runner: dependency: "direct dev" description: name: build_runner url: "https://pub.dartlang.org" source: hosted - version: "1.11.1" + version: "1.11.5" build_runner_core: dependency: transitive description: name: build_runner_core url: "https://pub.dartlang.org" source: hosted - version: "6.1.7" + version: "6.1.10" built_collection: dependency: transitive description: @@ -147,21 +140,21 @@ packages: name: cloud_firestore url: "https://pub.dartlang.org" source: hosted - version: "0.16.0+1" + version: "1.0.0" cloud_firestore_platform_interface: dependency: transitive description: name: cloud_firestore_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.0.2" + version: "4.0.0" cloud_firestore_web: dependency: transitive description: name: cloud_firestore_web url: "https://pub.dartlang.org" source: hosted - version: "0.3.0+2" + version: "1.0.0" code_builder: dependency: transitive description: @@ -182,84 +175,70 @@ packages: name: connectivity_plus url: "https://pub.dartlang.org" source: hosted - version: "0.8.1" + version: "1.0.0" connectivity_plus_linux: dependency: transitive description: name: connectivity_plus_linux url: "https://pub.dartlang.org" source: hosted - version: "0.3.1" + version: "1.0.0" connectivity_plus_macos: dependency: transitive description: name: connectivity_plus_macos url: "https://pub.dartlang.org" source: hosted - version: "0.4.1" + version: "1.0.0" connectivity_plus_platform_interface: dependency: transitive description: name: connectivity_plus_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "0.4.1" + version: "1.0.0" connectivity_plus_web: dependency: transitive description: name: connectivity_plus_web url: "https://pub.dartlang.org" source: hosted - version: "0.6.1" + version: "1.0.0" connectivity_plus_windows: dependency: transitive description: name: connectivity_plus_windows url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" + version: "1.0.0" convert: dependency: "direct main" description: name: convert url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "3.0.0" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.5" - dapackages: - dependency: "direct dev" - description: - name: dapackages - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.0" + version: "3.0.0" dart_style: dependency: transitive description: name: dart_style url: "https://pub.dartlang.org" source: hosted - version: "1.3.12" - dartx: - dependency: transitive - description: - name: dartx - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.0" + version: "1.3.14" dbus: dependency: transitive description: name: dbus url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.2.1" dio: dependency: "direct main" description: @@ -267,20 +246,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.10" + easy_localization: + dependency: "direct main" + description: + name: easy_localization + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + easy_logger: + dependency: transitive + description: + name: easy_logger + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.2" encrypt: dependency: "direct main" description: name: encrypt url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "5.0.0-beta.1" equatable: dependency: transitive description: name: equatable url: "https://pub.dartlang.org" source: hosted - version: "1.2.6" + version: "2.0.0" expandable: dependency: "direct main" description: @@ -301,105 +294,119 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "1.0.0" file: dependency: transitive description: name: file url: "https://pub.dartlang.org" source: hosted - version: "5.2.1" + version: "6.1.0" file_picker: dependency: "direct main" description: name: file_picker url: "https://pub.dartlang.org" source: hosted - version: "2.1.6" + version: "3.0.0" firebase_auth: dependency: "direct main" description: name: firebase_auth url: "https://pub.dartlang.org" source: hosted - version: "0.20.1" + version: "1.0.0" firebase_auth_platform_interface: dependency: transitive description: name: firebase_auth_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.1.0" + version: "4.0.0" firebase_auth_web: dependency: transitive description: name: firebase_auth_web url: "https://pub.dartlang.org" source: hosted - version: "0.3.3" + version: "1.0.0" firebase_core: dependency: "direct main" description: name: firebase_core url: "https://pub.dartlang.org" source: hosted - version: "0.7.0" + version: "1.0.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "4.0.0" firebase_core_web: dependency: transitive description: name: firebase_core_web url: "https://pub.dartlang.org" source: hosted - version: "0.2.1+3" + version: "1.0.0" + firebase_crashlytics: + dependency: "direct main" + description: + name: firebase_crashlytics + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + firebase_crashlytics_platform_interface: + dependency: transitive + description: + name: firebase_crashlytics_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" firebase_messaging: dependency: "direct main" description: name: firebase_messaging url: "https://pub.dartlang.org" source: hosted - version: "8.0.0-dev.15" + version: "9.0.0" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.0-dev.10" + version: "2.0.0" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.0-dev.6" + version: "1.0.0" firebase_storage: dependency: "direct main" description: name: firebase_storage url: "https://pub.dartlang.org" source: hosted - version: "7.0.0" + version: "8.0.0" firebase_storage_platform_interface: dependency: transitive description: name: firebase_storage_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.0.0" firebase_storage_web: dependency: transitive description: name: firebase_storage_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.1+3" + version: "1.0.0" fixnum: dependency: transitive description: @@ -413,7 +420,7 @@ packages: name: fl_chart url: "https://pub.dartlang.org" source: hosted - version: "0.12.3" + version: "0.20.1" flash: dependency: "direct main" description: @@ -427,40 +434,31 @@ packages: name: fluro url: "https://pub.dartlang.org" source: hosted - version: "1.7.8" + version: "2.0.3" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" - flutter_launcher_icons: - dependency: "direct dev" - description: - name: flutter_launcher_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.1" - flutter_native_splash: - dependency: "direct dev" - description: - name: flutter_native_splash - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.0" + flutter_localizations: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" flutter_plugin_android_lifecycle: dependency: transitive description: name: flutter_plugin_android_lifecycle url: "https://pub.dartlang.org" source: hosted - version: "1.0.11" + version: "2.0.0" flutter_spinkit: dependency: "direct main" description: name: flutter_spinkit url: "https://pub.dartlang.org" source: hosted - version: "4.1.2+1" + version: "5.0.0" flutter_sticky_header: dependency: "direct main" description: @@ -479,7 +477,7 @@ packages: name: glob url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "2.0.0" google_nav_bar: dependency: "direct main" description: @@ -500,35 +498,28 @@ packages: name: hive url: "https://pub.dartlang.org" source: hosted - version: "1.4.4+1" + version: "2.0.0" hive_flutter: dependency: "direct main" description: name: hive_flutter url: "https://pub.dartlang.org" source: hosted - version: "0.3.1" + version: "1.0.0" hive_generator: dependency: "direct dev" description: name: hive_generator url: "https://pub.dartlang.org" source: hosted - version: "0.8.2" - html_character_entities: - dependency: transitive - description: - name: html_character_entities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+4" + version: "1.0.0" http: dependency: transitive description: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.12.2" + version: "0.13.0" http_multi_server: dependency: transitive description: @@ -537,47 +528,40 @@ packages: source: hosted version: "2.2.0" http_parser: - dependency: transitive + dependency: "direct overridden" description: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.4" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.19" + version: "4.0.0" in_app_purchase: dependency: "direct main" description: name: in_app_purchase url: "https://pub.dartlang.org" source: hosted - version: "0.3.5+1" + version: "0.5.0" infinite_scroll_pagination: dependency: "direct main" description: name: infinite_scroll_pagination url: "https://pub.dartlang.org" source: hosted - version: "2.3.0" + version: "3.0.0" intl: dependency: "direct main" description: name: intl url: "https://pub.dartlang.org" source: hosted - version: "0.16.1" + version: "0.17.0" io: dependency: transitive description: name: io url: "https://pub.dartlang.org" source: hosted - version: "0.3.4" + version: "0.3.5" js: dependency: transitive description: @@ -591,7 +575,7 @@ packages: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "3.1.1" + version: "4.0.0" logging: dependency: transitive description: @@ -619,7 +603,7 @@ packages: name: mime url: "https://pub.dartlang.org" source: hosted - version: "0.9.7" + version: "1.0.0" modal_bottom_sheet: dependency: "direct main" description: @@ -640,70 +624,56 @@ packages: name: network_info_plus url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "1.0.0" network_info_plus_linux: dependency: transitive description: name: network_info_plus_linux url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" + version: "1.0.0" network_info_plus_macos: dependency: transitive description: name: network_info_plus_macos url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" + version: "1.0.0" network_info_plus_platform_interface: dependency: transitive description: name: network_info_plus_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" + version: "1.0.0" network_info_plus_web: dependency: transitive description: name: network_info_plus_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" + version: "1.0.0" network_info_plus_windows: dependency: transitive description: name: network_info_plus_windows url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" - node_interop: - dependency: transitive - description: - name: node_interop - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - node_io: - dependency: transitive - description: - name: node_io - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" + version: "1.0.0" package_config: dependency: transitive description: name: package_config url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "2.0.0" package_info: dependency: "direct main" description: name: package_info url: "https://pub.dartlang.org" source: hosted - version: "0.4.3+4" + version: "2.0.0" path: dependency: transitive description: @@ -717,56 +687,56 @@ packages: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.4.1+1" + version: "0.5.0-nullsafety.0" path_parsing: dependency: transitive description: name: path_parsing url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.2.0-nullsafety.0" path_provider: dependency: "direct main" description: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "1.6.27" + version: "2.0.1" path_provider_linux: dependency: transitive description: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "0.0.1+2" + version: "2.0.0" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "0.0.4+8" + version: "2.0.0" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.0.1" path_provider_windows: dependency: transitive description: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "0.0.4+3" + version: "2.0.0" pedantic: dependency: transitive description: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.10.0" + version: "1.11.0" percent_indicator: dependency: "direct main" description: @@ -774,27 +744,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.9+1" - permission_handler: - dependency: "direct main" - description: - name: permission_handler - url: "https://pub.dartlang.org" - source: hosted - version: "5.1.0+2" - permission_handler_platform_interface: - dependency: transitive - description: - name: permission_handler_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" petitparser: dependency: transitive description: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "3.1.0" + version: "4.0.2" platform: dependency: transitive description: @@ -808,14 +764,14 @@ packages: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "2.0.0" pointycastle: dependency: transitive description: name: pointycastle url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "3.0.0-nullsafety.2" pool: dependency: transitive description: @@ -829,14 +785,14 @@ packages: name: process url: "https://pub.dartlang.org" source: hosted - version: "3.0.13" + version: "4.1.0" provider: dependency: "direct main" description: name: provider url: "https://pub.dartlang.org" source: hosted - version: "4.3.3" + version: "5.0.0" pub_semver: dependency: transitive description: @@ -857,7 +813,7 @@ packages: name: quick_actions url: "https://pub.dartlang.org" source: hosted - version: "0.4.0+10" + version: "0.5.0" quiver: dependency: transitive description: @@ -871,84 +827,105 @@ packages: name: radarr url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - recursive_regex: - dependency: transitive - description: - name: recursive_regex - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3+2" + version: "1.1.4+1" sembast: dependency: transitive description: name: sembast url: "https://pub.dartlang.org" source: hosted - version: "2.4.10+1" - sentry: - dependency: transitive - description: - name: sentry - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.5" - sentry_flutter: - dependency: "direct main" - description: - name: sentry_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.5" - service_worker: - dependency: transitive - description: - name: service_worker - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.4" + version: "2.4.10+4" share_plus: dependency: "direct main" description: name: share_plus url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "2.0.0" share_plus_linux: dependency: transitive description: name: share_plus_linux url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "2.0.0" + share_plus_macos: + dependency: transitive + description: + name: share_plus_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "2.0.0" share_plus_web: dependency: transitive description: name: share_plus_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.0" + version: "2.0.0" share_plus_windows: dependency: transitive description: name: share_plus_windows url: "https://pub.dartlang.org" source: hosted - version: "0.1.0" + version: "2.0.0" + shared_preferences: + dependency: transitive + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" shelf: dependency: transitive description: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "0.7.9" + version: "1.0.0" shelf_web_socket: dependency: transitive description: @@ -974,14 +951,14 @@ packages: name: sliver_tools url: "https://pub.dartlang.org" source: hosted - version: "0.1.10+1" + version: "0.2.0-nullsafety" sonarr: dependency: "direct main" description: name: sonarr url: "https://pub.dartlang.org" source: hosted - version: "1.1.0+1" + version: "1.1.1+1" source_gen: dependency: transitive description: @@ -1030,7 +1007,7 @@ packages: name: synchronized url: "https://pub.dartlang.org" source: hosted - version: "2.2.0+2" + version: "3.0.0" table_calendar: dependency: "direct main" description: @@ -1044,7 +1021,7 @@ packages: name: tautulli url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" + version: "1.2.2+1" term_glyph: dependency: transitive description: @@ -1052,13 +1029,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" - time: - dependency: transitive - description: - name: time - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.0" timing: dependency: transitive description: @@ -1086,49 +1056,49 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "5.7.10" + version: "6.0.2" url_launcher_linux: dependency: transitive description: name: url_launcher_linux url: "https://pub.dartlang.org" source: hosted - version: "0.0.1+4" + version: "2.0.0" url_launcher_macos: dependency: transitive description: name: url_launcher_macos url: "https://pub.dartlang.org" source: hosted - version: "0.0.1+9" + version: "2.0.0" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.9" + version: "2.0.2" url_launcher_web: dependency: transitive description: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.5+3" + version: "2.0.0" url_launcher_windows: dependency: transitive description: name: url_launcher_windows url: "https://pub.dartlang.org" source: hosted - version: "0.0.1+3" + version: "2.0.0" uuid: dependency: "direct main" description: name: uuid url: "https://pub.dartlang.org" source: hosted - version: "2.2.2" + version: "3.0.1" value_layout_builder: dependency: transitive description: @@ -1149,7 +1119,7 @@ packages: name: wake_on_lan url: "https://pub.dartlang.org" source: hosted - version: "1.1.1+6" + version: "1.1.2+1" watcher: dependency: transitive description: @@ -1170,28 +1140,21 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "1.7.4+1" + version: "2.0.0" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.2.0" xml: - dependency: transitive + dependency: "direct main" description: name: xml url: "https://pub.dartlang.org" source: hosted - version: "4.5.1" - xml_parser: - dependency: "direct main" - description: - name: xml_parser - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2" + version: "5.0.2" xxtea: dependency: transitive description: @@ -1205,7 +1168,7 @@ packages: name: yaml url: "https://pub.dartlang.org" source: hosted - version: "2.2.1" + version: "3.1.0" sdks: - dart: ">=2.12.0-0.0 <3.0.0" - flutter: ">=1.22.0" + dart: ">=2.12.0 <3.0.0" + flutter: ">=2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index ae491cfc..4bde5a71 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,84 +1,83 @@ name: lunasea description: Self-Hosted Controller -version: 5.0.0+50000010 +version: 5.0.0+50000011 publish_to: 'none' environment: sdk: ">=2.7.0 <3.0.0" dependencies: badges: ^1.1.6 - cloud_firestore: ^0.16.0+1 - connectivity_plus: ^0.8.1 - convert: ^2.1.1 + cloud_firestore: ^1.0.0 + connectivity_plus: ^1.0.0 + convert: ^3.0.0 dio: ^3.0.10 - encrypt: ^4.1.0 + easy_localization: ^3.0.0 + encrypt: ^5.0.0-beta.1 expandable: ^4.1.4 - file_picker: ^2.1.6 - firebase_core: ^0.7.0 - firebase_auth: ^0.20.1 - firebase_messaging: ^8.0.0-dev.15 - firebase_storage: ^7.0.0 + file_picker: ^3.0.0 + firebase_auth: ^1.0.0 + firebase_core: ^1.0.0 + firebase_crashlytics: ^1.0.0 + firebase_messaging: ^9.0.0 + firebase_storage: ^8.0.0 flash: ^1.3.2 - fluro: ^1.7.8 + fluro: ^2.0.3 flutter: sdk: flutter - flutter_spinkit: ^4.1.2+1 + flutter_spinkit: ^5.0.0 flutter_sticky_header: ^0.5.0 - fl_chart: ^0.12.3 + fl_chart: ^0.20.1 f_logs: ^1.3.0-alpha-02 google_nav_bar: ^4.0.2 - hive: ^1.4.4+1 - hive_flutter: ^0.3.1 - in_app_purchase: ^0.3.5+1 - infinite_scroll_pagination: ^2.3.0 - intl: ^0.16.1 + hive: ^2.0.0 + hive_flutter: ^1.0.0 + in_app_purchase: ^0.5.0 + infinite_scroll_pagination: ^3.0.0 + intl: ^0.17.0 modal_bottom_sheet: ^1.0.0+1 - network_info_plus: ^0.1.2 - package_info: ^0.4.3+4 - path_provider: ^1.6.27 + network_info_plus: ^1.0.0 + package_info: ^2.0.0 + path_provider: ^2.0.1 percent_indicator: ^2.1.9+1 - permission_handler: ^5.1.0+2 - provider: ^4.3.3 - quick_actions: ^0.4.0+10 - sentry_flutter: ^4.0.5 - share_plus: ^1.2.0 + provider: ^5.0.0 + quick_actions: ^0.5.0 + share_plus: ^2.0.0 stack_trace: ^1.10.0 table_calendar: ^2.3.3 tuple: ^1.0.3 - url_launcher: ^5.7.10 - uuid: ^2.2.2 - xml_parser: ^0.1.2 + url_launcher: ^6.0.2 + uuid: ^3.0.1 + xml: ^5.0.2 # Comet.Tools Packages - radarr: ^1.1.3 - sonarr: ^1.1.0+1 - tautulli: ^1.2.1 - wake_on_lan: ^1.1.1+6 + radarr: ^1.1.4+1 + sonarr: ^1.1.1+1 + tautulli: ^1.2.2+1 + wake_on_lan: ^1.1.2+1 + +dependency_overrides: + http_parser: ^4.0.0 + intl: ^0.17.0 + path_provider: ^2.0.1 dev_dependencies: - analyzer: ^0.41.2 - build_runner: ^1.11.1 - dapackages: ^1.4.0 - flutter_launcher_icons: ^0.8.1 - flutter_native_splash: ^0.3.0 - hive_generator: ^0.8.2 + analyzer: ^1.1.0 + build_runner: ^1.11.5 + hive_generator: ^1.0.0 flutter: uses-material-design: true assets: - # Changelog + # System Assets - assets/changelog.json - # Colors + - assets/localization/ + - assets/branding/ + # Other - assets/images/colors/ - # Automation - assets/images/lidarr/ - assets/images/radarr/ - assets/images/sonarr/ - # Monitoring - assets/images/tautulli/ - # Services - assets/images/services/ - # Branding - - assets/branding/ fonts: - family: CustomIcons fonts: @@ -97,6 +96,4 @@ flutter_native_splash: scripts: build: flutter packages pub run build_runner build --delete-conflicting-outputs - icons: flutter pub run flutter_launcher_icons:main - splash: flutter pub pub run flutter_native_splash:create - outdated: flutter pub pub run dapackages:dapackages.dart pubspec.yaml \ No newline at end of file + build_localizations: dart ./scripts/build_localizations.dart diff --git a/scripts/build_aab b/scripts/build/aab.sh similarity index 96% rename from scripts/build_aab rename to scripts/build/aab.sh index 0d7bf421..9b79182b 100755 --- a/scripts/build_aab +++ b/scripts/build/aab.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -cd .. +cd ../.. # Remove old builds rm -rf output/*.aab # Clean and build diff --git a/scripts/build_apk b/scripts/build/apk.sh similarity index 98% rename from scripts/build_apk rename to scripts/build/apk.sh index 234a44e5..8ff1fb35 100755 --- a/scripts/build_apk +++ b/scripts/build/apk.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -cd .. +cd ../.. # Remove old builds rm -rf output/*.apk # Clean and build diff --git a/scripts/build_ipa b/scripts/build/ipa.sh similarity index 97% rename from scripts/build_ipa rename to scripts/build/ipa.sh index 6cc45a04..e61df06c 100755 --- a/scripts/build_ipa +++ b/scripts/build/ipa.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -cd .. +cd ../.. # Remove old builds rm -rf build rm -rf output/*.ipa diff --git a/scripts/build_localizations.dart b/scripts/build_localizations.dart new file mode 100644 index 00000000..e77592e3 --- /dev/null +++ b/scripts/build_localizations.dart @@ -0,0 +1,62 @@ +import 'dart:convert'; +import 'dart:io'; + +/// Simple dart script to concat all module's localization files into a single file for loading into LunaSea. +/// +/// This script is designed to be run from the root of the project, using derry: `derry run build_localizations`. +void main() { + // Check and delete any found prepared localizations + Directory _assets = Directory('assets/localization'); + if(_assets.existsSync()) _assets.deleteSync(recursive: true); + // Go through each localization file + Directory _localization = Directory('localization'); + _localization.listSync().forEach((folder) { + // Ensure that the filesystem entity is a folder, and finds any files within + if(FileSystemEntity.isDirectorySync(folder.path)) { + Directory module = Directory(folder.path); + print('Processing Module: ${module.path.substring(module.path.lastIndexOf('/')+1)}'); + module.listSync().forEach((language) { + print('-> Adding language: ${language.path.substring(language.path.lastIndexOf('/')+1)}...'); + // Ensures that the filesystem entity is a JSON file + if(FileSystemEntity.isFileSync(language.path) && language.path.endsWith('.json')) { + // Create the file (if it does not exist), append language data to it + String name = language.path.split('/').last; + String path = '${_assets.path}/$name'; + _createFile(path); + File file = File(language.path); + _writeFile(path, jsonDecode(file.readAsStringSync())); + } + }); + print(''); + } + }); +} + +void _writeFile(String path, Map data) { + // Read the current data in the file + File file = File(path); + Map fileData = jsonDecode(file.readAsStringSync()); + // Ensure the file exists + if(file.existsSync()) { + print('---> Writing localization strings...'); + // Add all the localization strings to the file, and write back the string version of the map. + + fileData.addAll(data); + JsonEncoder encoder = JsonEncoder.withIndent(' '); + file.writeAsStringSync(encoder.convert(fileData), mode: FileMode.write, flush: true); + } else { + print('---> Failed to find file. Skipping...'); + return; + } +} + +void _createFile(String path) { + File file = File(path); + if(file.existsSync()) { + print('---> Found file. Skipping...'); + return; + } + print('---> Created empty file...'); + file.createSync(recursive: true); + file.writeAsStringSync('{}', flush: true); +}