47 Commits

Author SHA1 Message Date
Jagandeep Brar
322ec55546 release: v10.2.1
[skip ci]
2022-11-06 18:40:32 -05:00
Jagandeep Brar
34169bb1ff release(testflight): candidate
[skip ci]
2022-11-05 01:32:23 -04:00
Jagandeep Brar
0f4aef0e32 release(testflight): beta
[skip ci]
2022-11-04 19:39:21 -04:00
Jagandeep Brar
cf5bfca265 chore(flutter): upgrade to Flutter 3.3.7/857bd6b74c 2022-11-04 16:53:53 -04:00
Jagandeep Brar
affac3abc6 chore(flutter): update packages
[skip ci]
2022-11-04 15:43:33 -04:00
Jagandeep Brar
9826c5604d chore(node): update packages
[ski ci]
2022-11-04 15:21:26 -04:00
Jagandeep Brar
ea7a8ffc22 chore(ruby): update to Ruby@2.7.6, update gems
[skip ci]
2022-11-04 15:20:21 -04:00
Jagandeep Brar
4cb8caaa1d release(testflight): candidate
[skip ci]
2022-10-26 14:12:21 -05:00
Jagandeep Brar
53cb7f6675 release(testflight): beta
[skip ci]
2022-10-26 13:06:00 -05:00
Jagandeep Brar
123ab7f6a7 chore(locale): generate localizations 2022-10-26 11:00:53 -05:00
Jagandeep Brar
caf054aea2 chore: update CONTRIBUTORS.md
[skip ci]
2022-10-26 11:00:23 -05:00
Weblate (bot)
125596498e chore(locale): translations update from Hosted Weblate (#712)
Co-authored-by: Robert <rob2310@yahoo.de>
Co-authored-by: Florin Voicu <florin.bkk@gmail.com>
Co-authored-by: fyu0h <biiigback@gmail.com>

[skip ci]
2022-10-26 11:57:35 -04:00
Jagandeep Brar
38f2eb4cb2 fix(firebase): inject service file for older OS versions 2022-10-26 11:52:20 -04:00
Jagandeep Brar
7d437d5c3a feat(web): support local filesystem read/save actions 2022-10-25 12:32:30 -04:00
Jagandeep Brar
3d794099a5 chore(flutter): upgrade packages 2022-10-22 14:17:09 -05:00
Jagandeep Brar
b7ceebcb67 fix(android): utilize Kotlin v1.7.20 & Gradle v7.1.2 2022-10-22 14:15:56 -05:00
Jagandeep Brar
25e0d05142 fix(android): support Android 13 filesystem access 2022-10-22 13:19:36 -05:00
Jagandeep Brar
250a494903 fix(android): revert applying Google Play Services plugin during gradle build
[skip ci]
2022-10-22 13:08:57 -05:00
Jagandeep Brar
b47ef16001 chore(fastlane): update gems
[skip ci]
2022-10-22 12:50:05 -05:00
Jagandeep Brar
71f597baa7 fix(android): apply Google Play Services plugin during gradle build
[skip ci]
2022-10-21 18:36:17 -05:00
Jagandeep Brar
abf117ac92 chore(ci): fix typo in workflow configuration 2022-10-21 14:47:47 -05:00
Jagandeep Brar
f3a3f222bd fix(firebase): upgrade to Firebase v10 (#717) 2022-10-21 15:45:52 -04:00
Jagandeep Brar
f9a2a1c85c chore(flutter): lock Flutter version during CI/CD builds 2022-10-20 15:56:42 -05:00
Jagandeep Brar
7d469e7bad chore(github): update issue template links
[skip ci]
2022-10-20 15:32:33 -05:00
Mário Franco
137a52ccd4 chore(build): rename Android debug build (#714)
[skip ci]
2022-10-20 16:18:59 -04:00
Jagandeep Brar
9a1769595d release(testflight): beta
[skip ci]
2022-09-28 14:03:10 -04:00
Jagandeep Brar
9b930493d7 chore(contributors): add @osjurso for translation
[skip ci]
2022-09-28 13:05:34 -04:00
Weblate (bot)
bfe5dc77a0 chore: translations update from Hosted Weblate (#706)
Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Co-authored-by: Olav Markus Sjursø <olav.markus@sjurso.no>
Co-authored-by: 愿你多年归来仍是少年 <onestime@126.com>

[skip ci]
2022-09-28 13:03:40 -04:00
Jagandeep Brar
3ac2c5d791 feat(calendar): remove option to show previous days in schedule view, now always shows them 2022-09-28 01:43:53 -04:00
Jagandeep Brar
f1226e5638 feat(calendar): scroll to selected date when switching from calendar to schedule view 2022-09-28 01:28:16 -04:00
Jagandeep Brar
ee91085b07 release(testflight): beta
[skip ci]
2022-09-27 22:59:34 -04:00
Jagandeep Brar
e287baf046 chore(window): do not initialize window manager in debug mode
[skip ci]
2022-09-27 22:57:36 -04:00
Jagandeep Brar
8788f76e5c chore(recovery): small refactoring of recovery mode implementation
[skip ci]
2022-09-27 22:53:49 -04:00
Jagandeep Brar
6eff6c902c fix(calendar): start to current date when past days are enabled 2022-09-27 02:03:21 -04:00
Jagandeep Brar
d9623e992d fix(uiux): add circular radius to linear progression bars 2022-09-26 21:02:50 -04:00
Jagandeep Brar
958e6f1568 refactor(uiux): remove forced-upper case on headers 2022-09-26 18:41:10 -04:00
Jagandeep Brar
f3931c6b08 fix(backup): edge-case where backup/restore would fail 2022-09-26 12:54:14 -04:00
Jagandeep Brar
3dd087e361 feat(modules): ability to set the boot module 2022-09-26 11:48:14 -04:00
Jagandeep Brar
ac838f99a9 refactor(settings): consolidate appearance, network, and localization pages 2022-09-26 11:44:07 -04:00
Jagandeep Brar
c9bd02b750 feat(radarr): support moving files when editing the storage path 2022-09-26 11:07:19 -04:00
Jagandeep Brar
cfbfb2b3ad docs: update platform restrictions
[skip ci]
2022-09-25 14:31:29 -04:00
Jagandeep Brar
bccd1a43c4 feat(-arr): button to open indexer information page 2022-09-23 23:51:56 -04:00
Jagandeep Brar
70ed750652 fix(calendar): label unreleased movies as unreleased instead of missing 2022-09-23 23:34:57 -04:00
Jagandeep Brar
c76418d26f feat(lidarr): add MusicBrainz to links 2022-09-23 23:25:02 -04:00
Jagandeep Brar
c062b3d786 feat: launch recovery mode on bootstrap failure 2022-09-23 17:13:37 -04:00
Jagandeep Brar
a9d551df5e chore: bump version to v10.2.1
[skip ci]
2022-09-22 14:55:24 -04:00
Jagandeep Brar
dc617ed151 chore(ci): do not overwrite PATH environmental variable
[skip ci]
2022-09-22 13:05:56 -04:00
139 changed files with 2200 additions and 1403 deletions

View File

@@ -358,6 +358,42 @@
"contributions": [
"translation"
]
},
{
"login": "osjurso",
"name": "Olav Markus Sjursø",
"avatar_url": "https://avatars.githubusercontent.com/u/17827103?v=4",
"profile": "https://github.com/osjurso",
"contributions": [
"translation"
]
},
{
"login": "fyu0h",
"name": "fyu0h",
"avatar_url": "https://avatars.githubusercontent.com/u/33602841?v=4",
"profile": "https://github.com/fyu0h",
"contributions": [
"translation"
]
},
{
"login": "johnflorin",
"name": "Florin",
"avatar_url": "https://avatars.githubusercontent.com/u/45756085?v=4",
"profile": "https://github.com/johnflorin",
"contributions": [
"translation"
]
},
{
"login": "tuzumbear",
"name": "tuzumbear",
"avatar_url": "https://avatars.githubusercontent.com/u/61370405?v=4",
"profile": "https://github.com/tuzumbear",
"contributions": [
"translation"
]
}
],
"contributorsPerLine": 8,

View File

@@ -1,6 +1,6 @@
blank_issues_enabled: false
contact_links:
- name: Feedback Requets & Support via Discord
- name: Feature Requests & Support via Discord
url: https://www.lunasea.app/discord
about: Request new features and get support from the community
- name: Support via GitHub Discussions

View File

@@ -7,8 +7,8 @@ inputs:
required: true
# Config
firebase-options:
description: 'Firebase Options'
firebase-token:
description: 'Firebase Token'
required: false
default: ''
skip-core:
@@ -50,7 +50,7 @@ runs:
using: composite
steps:
- name: Checkout Repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
@@ -69,6 +69,7 @@ runs:
- name: Install Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.3.7'
channel: stable
cache: true
cache-key: ${{ github.sha }}
@@ -117,9 +118,22 @@ runs:
echo ${{ inputs.android-key-properties }} | base64 --decode > android/key.properties
- name: Setup Firebase Configuration
if: ${{ inputs.firebase-options != '' }}
if: ${{ inputs.firebase-token != '' }}
shell: bash
run: echo ${{ inputs.firebase-options }} | base64 --decode > lib/firebase/options.dart
run: |
npm install -g firebase-tools
gem install --user-install xcodeproj
dart pub global activate flutterfire_cli
flutterfire configure \
--project=comettools-lunasea \
--token=${{ inputs.firebase-token }} \
--platforms=android,ios,macos,web \
--android-package-name=app.lunasea.lunasea \
--ios-bundle-id=app.lunasea.lunasea \
--macos-bundle-id=app.lunasea.lunasea \
--out=lib/firebase/options.dart \
--yes
- name: Setup Firebase Service Worker
if: ${{ inputs.firebase-service-worker != '' }}

View File

@@ -28,7 +28,7 @@ runs:
using: composite
steps:
- name: Checkout Repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0

View File

@@ -1,4 +1,4 @@
name: Release
name: Build
on:
push:
@@ -24,7 +24,7 @@ jobs:
with:
flavor: ${{ inputs.flavor }}
secrets:
FIREBASE_OPTIONS: ${{ secrets.FIREBASE_OPTIONS }}
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
build-android:
@@ -34,7 +34,7 @@ jobs:
with:
build-number: ${{ needs.prepare.outputs.build-number }}
secrets:
FIREBASE_OPTIONS: ${{ secrets.FIREBASE_OPTIONS }}
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
KEY_JKS: ${{ secrets.KEY_JKS }}
KEY_PROPERTIES: ${{ secrets.KEY_PROPERTIES }}
@@ -48,7 +48,7 @@ jobs:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ITC_TEAM_ID: ${{ secrets.APPLE_ITC_TEAM_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
FIREBASE_OPTIONS: ${{ secrets.FIREBASE_OPTIONS }}
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
IOS_CODESIGNING_IDENTITY: ${{ secrets.IOS_CODESIGNING_IDENTITY }}
MATCH_KEYCHAIN_NAME: ${{ secrets.MATCH_KEYCHAIN_NAME }}
MATCH_KEYCHAIN_PASSWORD: ${{ secrets.MATCH_KEYCHAIN_PASSWORD }}
@@ -74,7 +74,7 @@ jobs:
APPLE_STORE_CONNECT_KEY: ${{ secrets.APPLE_STORE_CONNECT_KEY }}
APPLE_STORE_CONNECT_KEY_ID: ${{ secrets.APPLE_STORE_CONNECT_KEY_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
FIREBASE_OPTIONS: ${{ secrets.FIREBASE_OPTIONS }}
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
MACOS_INSTALLER_CERT_APP_STORE: ${{ secrets.MACOS_INSTALLER_CERT_APP_STORE }}
MACOS_INSTALLER_CERT_DIRECT: ${{ secrets.MACOS_INSTALLER_CERT_DIRECT }}
MATCH_KEYCHAIN_NAME: ${{ secrets.MATCH_KEYCHAIN_NAME }}
@@ -90,8 +90,8 @@ jobs:
build-flavor: ${{ needs.prepare.outputs.build-flavor }}
build-title: ${{ needs.prepare.outputs.build-title }}
secrets:
FIREBASE_OPTIONS: ${{ secrets.FIREBASE_OPTIONS }}
FIREBASE_SERVICE_WORKER: ${{ secrets.FIREBASE_SERVICE_WORKER }}
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
build-windows:
name: Build Windows

View File

@@ -8,7 +8,7 @@ on:
type: string
secrets:
FIREBASE_OPTIONS:
FIREBASE_TOKEN:
required: true
KEY_JKS:
required: true
@@ -23,7 +23,7 @@ jobs:
- name: Setup Environment
uses: JagandeepBrar/LunaSea/.github/actions/prepare_for_build@master
with:
firebase-options: ${{ secrets.FIREBASE_OPTIONS }}
firebase-token: ${{ secrets.FIREBASE_TOKEN }}
platform: android
android-key-jks: ${{ secrets.KEY_JKS }}
android-key-properties: ${{ secrets.KEY_PROPERTIES }}
@@ -45,7 +45,7 @@ jobs:
- name: Setup Environment
uses: JagandeepBrar/LunaSea/.github/actions/prepare_for_build@master
with:
firebase-options: ${{ secrets.FIREBASE_OPTIONS }}
firebase-token: ${{ secrets.FIREBASE_TOKEN }}
platform: android
android-key-jks: ${{ secrets.KEY_JKS }}
android-key-properties: ${{ secrets.KEY_PROPERTIES }}

View File

@@ -14,7 +14,7 @@ on:
required: true
APPLE_TEAM_ID:
required: true
FIREBASE_OPTIONS:
FIREBASE_TOKEN:
required: true
IOS_CODESIGNING_IDENTITY:
required: true
@@ -35,7 +35,7 @@ jobs:
- name: Setup Environment
uses: JagandeepBrar/LunaSea/.github/actions/prepare_for_build@master
with:
firebase-options: ${{ secrets.FIREBASE_OPTIONS }}
firebase-token: ${{ secrets.FIREBASE_TOKEN }}
platform: ios
match-ssh-private-key: ${{ secrets.MATCH_SSH_PRIVATE_KEY }}

View File

@@ -23,7 +23,7 @@ on:
required: true
APPLE_TEAM_ID:
required: true
FIREBASE_OPTIONS:
FIREBASE_TOKEN:
required: true
MACOS_INSTALLER_CERT_APP_STORE:
required: true
@@ -46,7 +46,7 @@ jobs:
- name: Setup Environment
uses: JagandeepBrar/LunaSea/.github/actions/prepare_for_build@master
with:
firebase-options: ${{ secrets.FIREBASE_OPTIONS }}
firebase-token: ${{ secrets.FIREBASE_TOKEN }}
platform: macos
appstore-connect-key: ${{ secrets.APPLE_STORE_CONNECT_KEY }}
match-ssh-private-key: ${{ secrets.MATCH_SSH_PRIVATE_KEY }}
@@ -79,7 +79,7 @@ jobs:
- name: Setup Environment
uses: JagandeepBrar/LunaSea/.github/actions/prepare_for_build@master
with:
firebase-options: ${{ secrets.FIREBASE_OPTIONS }}
firebase-token: ${{ secrets.FIREBASE_TOKEN }}
platform: macos
appstore-connect-key: ${{ secrets.APPLE_STORE_CONNECT_KEY }}
match-ssh-private-key: ${{ secrets.MATCH_SSH_PRIVATE_KEY }}
@@ -112,7 +112,7 @@ jobs:
- name: Setup Environment
uses: JagandeepBrar/LunaSea/.github/actions/prepare_for_build@master
with:
firebase-options: ${{ secrets.FIREBASE_OPTIONS }}
firebase-token: ${{ secrets.FIREBASE_TOKEN }}
platform: macos
appstore-connect-key: ${{ secrets.APPLE_STORE_CONNECT_KEY }}
match-ssh-private-key: ${{ secrets.MATCH_SSH_PRIVATE_KEY }}

View File

@@ -11,7 +11,7 @@ on:
type: string
secrets:
FIREBASE_OPTIONS:
FIREBASE_TOKEN:
required: true
FIREBASE_SERVICE_WORKER:
required: true
@@ -24,7 +24,7 @@ jobs:
- name: Setup Environment
uses: JagandeepBrar/LunaSea/.github/actions/prepare_for_build@master
with:
firebase-options: ${{ secrets.FIREBASE_OPTIONS }}
firebase-token: ${{ secrets.FIREBASE_TOKEN }}
firebase-service-worker: ${{ secrets.FIREBASE_SERVICE_WORKER }}
platform: web

View File

@@ -1,20 +0,0 @@
name: Clear Flutter Cache
on:
workflow_dispatch
jobs:
clear:
name: Clear Cache
runs-on: ubuntu-latest
steps:
- name: Install Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
cache-key: ${{ github.sha }}
- name: Flutter Doctor
working-directory: ${{ github.workspace }}
run: flutter doctor -v

View File

@@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0

View File

@@ -25,7 +25,7 @@ on:
value: ${{ jobs.build-details.outputs.build-version }}
secrets:
FIREBASE_OPTIONS:
FIREBASE_TOKEN:
required: true
SENTRY_DSN:
required: true
@@ -42,7 +42,7 @@ jobs:
build-version: ${{ steps.build-version.outputs.current-version }}
steps:
- name: Checkout Repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
@@ -124,7 +124,7 @@ jobs:
- name: Setup Environment
uses: JagandeepBrar/LunaSea/.github/actions/prepare_for_build@master
with:
firebase-options: ${{ secrets.FIREBASE_OPTIONS }}
firebase-token: ${{ secrets.FIREBASE_TOKEN }}
platform: test
skip-core: true

View File

@@ -54,10 +54,10 @@ jobs:
- name: Generate Changelog
env:
MOTD: ${{ inputs.build-motd }}
PATH: ${{ github.workspace }}/android/fastlane/metadata/android/en-CA/changelogs
OUTPUT_PATH: ${{ github.workspace }}/android/fastlane/metadata/android/en-CA/changelogs
run: |
mkdir -p $PATH
echo $MOTD > $PATH/default.txt
mkdir -p $OUTPUT_PATH
echo $MOTD > $OUTPUT_PATH/default.txt
- name: Deploy to Google Play Store
working-directory: ${{ github.workspace }}/android

View File

@@ -44,10 +44,10 @@ jobs:
- name: Generate Changelog
env:
MOTD: ${{ inputs.build-motd }}
PATH: ${{ github.workspace }}/ios/fastlane
OUTPUT_PATH: ${{ github.workspace }}/ios/fastlane
run: |
mkdir -p $PATH
echo $MOTD > $PATH/changelog.txt
mkdir -p $OUTPUT_PATH
echo $MOTD > $OUTPUT_PATH/changelog.txt
- name: Deploy to App Store Connect
working-directory: ${{ github.workspace }}/ios

View File

@@ -44,10 +44,10 @@ jobs:
- name: Generate Changelog
env:
MOTD: ${{ inputs.build-motd }}
PATH: ${{ github.workspace }}/macos/fastlane
OUTPUT_PATH: ${{ github.workspace }}/macos/fastlane
run: |
mkdir -p $PATH
echo $MOTD > $PATH/changelog.txt
mkdir -p $OUTPUT_PATH
echo $MOTD > $OUTPUT_PATH/changelog.txt
- name: Deploy to App Store Connect
working-directory: ${{ github.workspace }}/macos

View File

@@ -1,4 +1,4 @@
name: Publish s3
name: Publish S3
on:
workflow_call:

View File

@@ -1,4 +1,4 @@
name: Publish Web (Docker)
name: Publish Web
on:
workflow_call:

View File

@@ -3,7 +3,7 @@ name: Validate
on:
workflow_call:
secrets:
FIREBASE_OPTIONS:
FIREBASE_TOKEN:
required: true
jobs:
@@ -14,7 +14,7 @@ jobs:
- name: Setup Environment
uses: JagandeepBrar/LunaSea/.github/actions/prepare_for_build@master
with:
firebase-options: ${{ secrets.FIREBASE_OPTIONS }}
firebase-token: ${{ secrets.FIREBASE_TOKEN }}
platform: test
- name: Analyze Release

3
.gitignore vendored
View File

@@ -66,8 +66,11 @@ android/key.properties
# Firebase
android/firebase_app_id_file.json
android/app/google-services.json
ios/firebase_app_id_file.json
ios/Runner/GoogleService-Info.plist
macos/firebase_app_id_file.json
macos/Runner/GoogleService-Info.plist
# Node Dependency directories
node_modules/

View File

@@ -1 +1 @@
2.6.8
2.7.6

2
.vscode/cspell.json vendored
View File

@@ -55,6 +55,7 @@
"prefill",
"Radarr",
"Riverpod",
"roboto",
"SABnzbd",
"scrollview",
"sksl",
@@ -66,6 +67,7 @@
"Tautulli",
"TestFlight",
"Trakt",
"typescale",
"unencrypted",
"unignore",
"Weblate",

5
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"yaml.schemas": {
"https://json.schemastore.org/github-issue-config.json": "file:///Users/jagandeepbrar/Git/LunaSea/.github/ISSUE_TEMPLATE/config.yml"
}
}

View File

@@ -2,6 +2,40 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [10.2.1](https://github.com/JagandeepBrar/LunaSea/compare/v10.2.0...v10.2.1) (2022-11-06)
### Features
* **-arr:** button to open indexer information page ([bccd1a4](https://github.com/JagandeepBrar/LunaSea/commit/bccd1a43c42b349901137f8fc605f393b51d541a))
* **calendar:** remove option to show previous days in schedule view, now always shows them ([3ac2c5d](https://github.com/JagandeepBrar/LunaSea/commit/3ac2c5d791f94208a4004d161bb046c24b698345))
* **calendar:** scroll to selected date when switching from calendar to schedule view ([f1226e5](https://github.com/JagandeepBrar/LunaSea/commit/f1226e563899cfc0950865a9734448d4e00601b9))
* launch recovery mode on bootstrap failure ([c062b3d](https://github.com/JagandeepBrar/LunaSea/commit/c062b3d786e55bc3ba7fe767dd946d73efbef64f))
* **lidarr:** add MusicBrainz to links ([c76418d](https://github.com/JagandeepBrar/LunaSea/commit/c76418d26f1a5f52f5cb1e46951f1cf6726508c2))
* **modules:** ability to set the boot module ([3dd087e](https://github.com/JagandeepBrar/LunaSea/commit/3dd087e361619889057a0b037b1eef35157a0988))
* **radarr:** support moving files when editing the storage path ([c9bd02b](https://github.com/JagandeepBrar/LunaSea/commit/c9bd02b75086579f60ad8987c42ab217c12f6d43))
* **web:** support local filesystem read/save actions ([7d437d5](https://github.com/JagandeepBrar/LunaSea/commit/7d437d5c3a34a8681c372570fc366e869f0b2090))
### Bug Fixes
* **android:** apply Google Play Services plugin during gradle build ([71f597b](https://github.com/JagandeepBrar/LunaSea/commit/71f597baa7c23102b711c3ca3c1ea5b2f8e1f5e9))
* **android:** revert applying Google Play Services plugin during gradle build ([250a494](https://github.com/JagandeepBrar/LunaSea/commit/250a49490333f4de726226dc4aa15a681f32a70c))
* **android:** support Android 13 filesystem access ([25e0d05](https://github.com/JagandeepBrar/LunaSea/commit/25e0d051422b399de8c90e0fc71e57349e3355b7))
* **android:** utilize Kotlin v1.7.20 & Gradle v7.1.2 ([b7ceebc](https://github.com/JagandeepBrar/LunaSea/commit/b7ceebcb679dbca935b6a1810c0c67a14002e358))
* **backup:** edge-case where backup/restore would fail ([f3931c6](https://github.com/JagandeepBrar/LunaSea/commit/f3931c6b08025a70920039e5cbbc9cf7120c0b36))
* **calendar:** label unreleased movies as unreleased instead of missing ([70ed750](https://github.com/JagandeepBrar/LunaSea/commit/70ed750652ff419e6fed659a0785adc5064654e7))
* **calendar:** start to current date when past days are enabled ([6eff6c9](https://github.com/JagandeepBrar/LunaSea/commit/6eff6c902cd7bcd523d83be09034098234679a79))
* **firebase:** inject service file for older OS versions ([38f2eb4](https://github.com/JagandeepBrar/LunaSea/commit/38f2eb4cb2a8e400ce2ecb0b6f2854469c9626fc))
* **firebase:** upgrade to Firebase v10 ([#717](https://github.com/JagandeepBrar/LunaSea/issues/717)) ([f3a3f22](https://github.com/JagandeepBrar/LunaSea/commit/f3a3f222bd56beb4e961817b18d71f01fb7c5e81))
* **uiux:** add circular radius to linear progression bars ([d9623e9](https://github.com/JagandeepBrar/LunaSea/commit/d9623e992d2ac2039eaa4f069c739d968c921cc6))
### Tweaks
* **settings:** consolidate appearance, network, and localization pages ([ac838f9](https://github.com/JagandeepBrar/LunaSea/commit/ac838f99a9c839ce4e36e5eae80f1100e2787dc5))
* **uiux:** remove forced-upper case on headers ([958e6f1](https://github.com/JagandeepBrar/LunaSea/commit/958e6f156862c1092399649baa361cd955299c88))
## [10.2.0](https://github.com/JagandeepBrar/LunaSea/compare/v10.1.1...v10.2.0) (2022-09-22)

View File

@@ -3,7 +3,7 @@
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-39-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-43-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
@@ -63,6 +63,12 @@ Thank you to everyone who has helped contribute to LunaSea, from development to
<td align="center"><a href="https://github.com/Slam4uk"><img src="https://avatars.githubusercontent.com/u/78175288?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Slam4uk</b></sub></a><br /><a href="#translation-Slam4uk" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/timrettop"><img src="https://avatars.githubusercontent.com/u/434913?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tim Potter</b></sub></a><br /><a href="#translation-timrettop" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/carlesmu"><img src="https://avatars.githubusercontent.com/u/1310090?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Carles Muñoz Gorriz</b></sub></a><br /><a href="#translation-carlesmu" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/osjurso"><img src="https://avatars.githubusercontent.com/u/17827103?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Olav Markus Sjursø</b></sub></a><br /><a href="#translation-osjurso" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/fyu0h"><img src="https://avatars.githubusercontent.com/u/33602841?v=4?s=100" width="100px;" alt=""/><br /><sub><b>fyu0h</b></sub></a><br /><a href="#translation-fyu0h" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/johnflorin"><img src="https://avatars.githubusercontent.com/u/45756085?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Florin</b></sub></a><br /><a href="#translation-johnflorin" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/tuzumbear"><img src="https://avatars.githubusercontent.com/u/61370405?v=4?s=100" width="100px;" alt=""/><br /><sub><b>tuzumbear</b></sub></a><br /><a href="#translation-tuzumbear" title="Translation">🌍</a></td>
</tr>
</tbody>
</table>

View File

@@ -8,20 +8,20 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.634.0)
aws-sdk-core (3.152.0)
aws-partitions (1.655.0)
aws-sdk-core (3.166.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.58.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (1.59.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.114.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-s3 (1.117.1)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.5.1)
aws-sigv4 (1.5.2)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.1.0)
@@ -36,7 +36,7 @@ GEM
unf (>= 0.0.5, < 1.0.0)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.92.5)
excon (0.93.1)
faraday (1.10.2)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -106,9 +106,9 @@ GEM
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.27.0)
google-apis-core (>= 0.7.2, < 2.a)
google-apis-core (0.9.0)
google-apis-androidpublisher_v3 (0.30.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-core (0.9.1)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@@ -117,27 +117,27 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
google-apis-iamcredentials_v1 (0.14.0)
google-apis-core (>= 0.7.2, < 2.a)
google-apis-playcustomapp_v1 (0.10.0)
google-apis-core (>= 0.7, < 2.a)
google-apis-storage_v1 (0.17.0)
google-apis-core (>= 0.7, < 2.a)
google-apis-iamcredentials_v1 (0.16.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-playcustomapp_v1 (0.12.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-storage_v1 (0.19.0)
google-apis-core (>= 0.9.0, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.3.0)
google-cloud-storage (1.42.0)
google-cloud-storage (1.44.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.17.0)
google-apis-storage_v1 (~> 0.19.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.2.0)
googleauth (1.3.0)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
@@ -215,4 +215,4 @@ DEPENDENCIES
fastlane
BUNDLED WITH
2.3.19
2.3.25

View File

@@ -65,6 +65,10 @@ android {
}
buildTypes {
debug {
applicationIdSuffix ".debug"
versionNameSuffix "-dev"
}
release {
signingConfig signingConfigs.release
}

View File

@@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.5.32'
ext.kotlin_version = '1.7.20'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View File

@@ -1,6 +1,5 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip

Binary file not shown.

View File

@@ -1,110 +1,110 @@
{
"motd": "Welcome to LunaSea v10.2.0!\n\nThis release adds Sentry logging to allow for better error catching and tracking, full support for notifications on web (hosted version only), viewing your download client from the search and -arr releases page, and support for Android 13!\n\nThis build also includes fixes for users running Sonarr v4, safer database transactions, and a fully rewritten routing tree.\n\nFinally, the feedback board resource has been removed in favour of using Discord's new forum feature for feature requests! All requests from the previous board will slowly be transitioned to the Discord forum!",
"motd": "Welcome to LunaSea v10.2.1!\n\nThis release adds some nice quality of life changes including the ability to set your boot module, automatic scrolling to the selected date in the calendar, and support for filesystem actions on web!\n\nThis build also includes some additional Android 13 fixes and other miscellaneous fixes and tweaks!",
"feat": {
"android": [
"dashboard": [
{
"commit": "96b2b1b5b010507dd7ece3421bf02eac6ba32486",
"message": "add support for monochromatic adaptive icon"
"commit": "3ac2c5d791f94208a4004d161bb046c24b698345",
"message": "(calendar) always show previous days in schedule view"
},
{
"commit": "113b2943469464598ce07b931818c7e29c6cc63a",
"message": "use vector images for icon"
},
{
"commit": "f8dca603310a3d514c0bd29cefc07e9802ea1350",
"message": "target building for Android 13 (SDK 33)"
},
{
"commit": "83e8374c33977c82096fcf8d5a4d94da5c291f8f",
"message": "support Android 13 notification prompt"
"commit": "f1226e563899cfc0950865a9734448d4e00601b9",
"message": "(calendar) scroll to selected date when loading the schedule view"
}
],
"logging": [
"modules": [
{
"commit": "57bbb80a0188d3bed9ca70846a89df6a3c2c0953",
"message": "integrate Sentry logging support for all platforms"
}
],
"router": [
{
"commit": "1d4207ae5106c2a0648b77a3b3ef6508665561e8",
"message": "re-implementation of routing via go_router"
}
],
"search": [
{
"commit": "a6be658164fed7dd2411a167dec6b4c53eab70f0",
"message": "view download client via overlay sheet"
}
],
"settings": [
{
"commit": "3d0c5209cb3e796629817dee986634154e7ffe9e",
"message": "add option to disable Sentry logging"
},
{
"commit": "136cda5215ae1d44dcd898e8e8e0b1e1912b3a41",
"message": "show notification settings area on web"
}
],
"web": [
{
"commit": "4b411107f74f048e6f3d571845590a5d29720ac3",
"message": "enable service worker processing of notifications"
"commit": "3dd087e361619889057a0b037b1eef35157a0988",
"message": "ability to set the boot module"
}
],
"-arr": [
{
"commit": "0c59886657db0ed05a9d741c82689cb1272c6ad2",
"message": "view download client via overlay sheet"
"commit": "bccd1a43c42b349901137f8fc605f393b51d541a",
"message": "(releases) button to open indexer information page"
}
],
"lidarr": [
{
"commit": "c76418d26f1a5f52f5cb1e46951f1cf6726508c2",
"message": "(links) add MusicBrainz"
}
],
"radarr": [
{
"commit": "c9bd02b75086579f60ad8987c42ab217c12f6d43",
"message": "(edit) support moving files when editing the storage path"
}
],
"web": [
{
"commit": "7d437d5c3a34a8681c372570fc366e869f0b2090",
"message": "(filesystem) support local filesystem read/save actions"
}
],
"system": [
{
"commit": "c062b3d786e55bc3ba7fe767dd946d73efbef64f",
"message": "launch recovery mode on bootstrap failure"
},
{
"commit": "125596498ec9839e584912185ddc5b625602a701",
"message": "(locale) translations update from Weblate"
}
]
},
"fix": {
"cache": [
"firebase": [
{
"commit": "7aae4807221184dbe1d02454f73998a0458dd7f6",
"message": "add type-safety to LRU cache"
}
],
"database": [
{
"commit": "9960124d3219e2ab72e14443a1a79a1bac6b2cd3",
"message": "prevent deadlock in database deletion actions"
}
],
"notifications": [
{
"commit": "3593eb329b38fb4a5b776cf1b165ad6f463e371b",
"message": "enable in-app notifications config was inversed"
}
],
"resources": [
{
"commit": "d3d090e277f7dda7d4ef3d7808e7341cf79178fe",
"message": "remove feedback board resource"
}
],
"scrolling": [
{
"commit": "864082fd4045ef7dea0e0ab6a17d41ca86015fcb",
"message": "remove custom scrolling behaviour"
}
],
"sheets": [
{
"commit": "3a5e19b02c048df21bd169a0a06f1e9ae741debb",
"message": "set default overlay theme"
"commit": "38f2eb4cb2a8e400ce2ecb0b6f2854469c9626fc",
"message": "inject service file for older OS versions"
},
{
"commit": "3a5e19b02c048df21bd169a0a06f1e9ae741debb",
"message": "remove bottom radius clipping"
"commit": "f3a3f222bd56beb4e961817b18d71f01fb7c5e81",
"message": "upgrade to Firebase v10"
}
],
"sonarr": [
"flutter": [
{
"commit": "e477ecafcce268d7de112f33711fc02a089a4206",
"message": "support Sonarr v4 API changes"
"commit": "3d794099a5418385dc1010f204c3f46fdbdd5503",
"message": "upgrade packages"
},
{
"commit": "cf5bfca265d03b0fd966dfb069393a4bbb24c672",
"message": "upgrade to Flutter 3.3.7/857bd6b74c"
}
],
"android": [
{
"commit": "25e0d051422b399de8c90e0fc71e57349e3355b7",
"message": "support Android 13 filesystem access"
},
{
"commit": "b7ceebcb679dbca935b6a1810c0c67a14002e358",
"message": "utilize Kotlin v1.7.20 & Gradle v7.1.2"
}
],
"calendar": [
{
"commit": "70ed750652ff419e6fed659a0785adc5064654e7",
"message": "label unreleased movies as unreleased instead of missing"
}
]
},
"refactor": {
"uiux": [
{
"commit": "958e6f156862c1092399649baa361cd955299c88",
"message": "remove forced-upper case on headers"
},
{
"commit": "d9623e992d2ac2039eaa4f069c739d968c921cc6",
"message": "add circular radius to linear progression bars"
}
],
"settings": [
{
"commit": "ac838f99a9c839ce4e36e5eae80f1100e2787dc5",
"message": "consolidate appearance, network, and localization pages"
}
]
}

View File

@@ -131,6 +131,20 @@
"search": [
"tvmaze"
]
},
{
"uid": "5d832b893437e33c4a22b7029c2b781b",
"css": "musicbrainz",
"code": 59401,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M475.1 106.5C469 110.1 462.8 113.7 461.1 114.5 459.5 115.2 456.5 117 454.3 118.4 449.9 121.3 436.7 129.1 426.7 134.6 423.1 136.7 408.2 145.3 393.7 153.9 379.2 162.5 366.3 170 365.1 170.5 363.9 171.1 360.9 172.9 358.5 174.5 356.1 176.1 353.1 177.9 351.9 178.5 350 179.4 330.3 191 319.9 197.2 315.9 199.6 301.8 207.7 295.5 211.2 282.4 218.4 276.4 222.1 275.9 223.2 275.6 223.8 274.8 224.3 274 224.3 273.2 224.3 263.9 229.5 253.2 235.8 242.6 242.1 232.9 247.7 231.7 248.3 230.5 248.8 227.5 250.6 225.1 252.2 222.7 253.8 219.7 255.6 218.5 256.2 214.9 258 196.6 268.8 192.3 271.6 190.2 273 187.4 274.6 186.2 275.2 185 275.8 178.7 279.4 172.3 283.1 165.8 286.9 156.9 292 152.5 294.5L144.4 298.9 144.4 500 144.4 701.1 152.5 705.5C156.9 708 165.8 713.1 172.3 716.9 178.7 720.6 185 724.2 186.2 724.8 187.4 725.4 190.2 727 192.3 728.4 196.6 731.2 214.9 742 218.5 743.8 219.7 744.4 222.7 746.2 225.1 747.8 227.5 749.4 230.5 751.2 231.7 751.7 232.9 752.3 242.6 757.9 253.2 764.2 263.9 770.5 273.2 775.7 274 775.7 274.8 775.7 275.6 776.2 275.9 776.8 276.4 777.9 282.4 781.6 295.5 788.8 301.8 792.3 315.9 800.4 319.9 802.8 330.3 809 350 820.6 351.9 821.5 353.1 822.1 356.1 823.9 358.5 825.5 360.9 827.1 363.9 828.9 365.1 829.5 366.3 830 379.2 837.5 393.7 846.1 408.2 854.7 423.1 863.3 426.7 865.4 436.7 870.9 449.9 878.7 454.3 881.6 456.5 883 459.5 884.8 461.1 885.5 462.8 886.3 469 889.9 475.1 893.5L486.1 900 486.4 700C486.6 590 486.6 410 486.4 300L486.1 100 475.1 106.5M513.2 500L513.2 900.4 520.2 896.4C524 894.2 529.6 890.9 532.6 889 535.6 887.2 538.5 885.6 538.9 885.6 539.4 885.6 543.2 883.4 547.4 880.7 557.1 874.4 570.3 866.6 571 866.6 571.3 866.6 585.4 858.5 602.2 848.5 619 838.6 633.7 830 634.9 829.5 636.1 828.9 639.1 827.1 641.5 825.5 643.9 823.9 646.9 822.1 648.1 821.5 650 820.6 669.7 809 680.1 802.8 684.1 800.4 698.2 792.3 704.5 788.8 717.6 781.6 723.6 777.9 724.1 776.8 724.4 776.2 725.2 775.7 726 775.7 726.8 775.7 736.1 770.5 746.8 764.2 757.4 757.9 767.1 752.3 768.3 751.7 769.5 751.2 772.5 749.4 774.9 747.8 777.3 746.2 780.3 744.4 781.5 743.8 785.1 742 803.4 731.2 807.7 728.4 809.8 727 812.6 725.4 813.8 724.8 815 724.2 821.3 720.6 827.7 716.9 834.2 713.1 843.1 708 847.5 705.5L855.6 701.1 855.6 500 855.6 298.9 847.5 294.5C843.1 292 834.2 286.9 827.7 283.1 821.3 279.4 815 275.8 813.8 275.2 812.6 274.6 809.8 273 807.7 271.6 803.4 268.8 785.1 258 781.5 256.2 780.3 255.6 777.3 253.8 774.9 252.2 772.5 250.6 769.5 248.8 768.3 248.3 767.1 247.7 757.4 242.1 746.8 235.8 736.1 229.5 726.8 224.3 726 224.3 725.2 224.3 724.4 223.8 724.1 223.2 723.6 222.1 717.6 218.4 704.5 211.2 698.2 207.7 684.1 199.6 680.1 197.2 669.7 191 650 179.4 648.1 178.5 646.9 177.9 643.9 176.1 641.5 174.5 639.1 172.9 636.1 171.1 634.9 170.5 633.7 170 619 161.4 602.2 151.5 585.4 141.5 571.3 133.4 571 133.4 570.3 133.4 557.1 125.6 547.4 119.3 543.2 116.6 539.4 114.4 538.9 114.4 538.5 114.4 535.6 112.8 532.6 111 529.6 109.1 524 105.8 520.2 103.6L513.2 99.6 513.2 500",
"width": 1000
},
"search": [
"musicbrainz"
]
}
]
}

View File

@@ -0,0 +1 @@
<svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0, 0, 400,400"><g id="svgg"><path id="path0" d="M190.029 42.611 C 187.610 44.044,185.103 45.471,184.457 45.784 C 183.812 46.096,182.582 46.810,181.723 47.369 C 179.975 48.509,174.674 51.621,170.674 53.855 C 169.223 54.666,163.284 58.136,157.478 61.566 C 151.672 64.996,146.525 67.990,146.041 68.219 C 145.557 68.447,144.370 69.156,143.402 69.794 C 142.434 70.432,141.240 71.155,140.748 71.401 C 140.019 71.765,132.107 76.395,127.957 78.886 C 126.362 79.843,120.705 83.073,118.182 84.468 C 112.956 87.356,110.547 88.836,110.362 89.274 C 110.254 89.528,109.910 89.736,109.597 89.736 C 109.284 89.736,105.545 91.796,101.288 94.313 C 97.031 96.830,93.152 99.077,92.669 99.305 C 92.185 99.533,90.997 100.242,90.029 100.879 C 89.062 101.517,87.874 102.240,87.390 102.486 C 85.978 103.203,78.623 107.531,76.923 108.645 C 76.067 109.206,74.971 109.853,74.487 110.083 C 74.003 110.313,71.496 111.741,68.915 113.257 C 66.334 114.772,62.771 116.811,60.997 117.788 L 57.771 119.564 57.771 200.000 L 57.771 280.436 60.997 282.212 C 62.771 283.189,66.334 285.228,68.915 286.743 C 71.496 288.259,74.003 289.687,74.487 289.917 C 74.971 290.147,76.067 290.794,76.923 291.355 C 78.623 292.469,85.978 296.797,87.390 297.514 C 87.874 297.760,89.062 298.483,90.029 299.121 C 90.997 299.758,92.185 300.467,92.669 300.695 C 93.152 300.923,97.031 303.170,101.288 305.687 C 105.545 308.204,109.284 310.264,109.597 310.264 C 109.910 310.264,110.254 310.472,110.362 310.726 C 110.547 311.164,112.956 312.644,118.182 315.532 C 120.705 316.927,126.362 320.157,127.957 321.114 C 132.107 323.605,140.019 328.235,140.748 328.599 C 141.240 328.845,142.434 329.568,143.402 330.206 C 144.370 330.844,145.557 331.553,146.041 331.781 C 146.525 332.010,151.672 335.004,157.478 338.434 C 163.284 341.864,169.223 345.334,170.674 346.145 C 174.674 348.379,179.975 351.491,181.723 352.631 C 182.582 353.190,183.812 353.904,184.457 354.216 C 185.103 354.529,187.610 355.956,190.029 357.389 L 194.428 359.994 194.577 279.997 C 194.659 235.999,194.659 164.001,194.577 120.003 L 194.428 40.006 190.029 42.611 M205.279 200.000 L 205.279 360.167 208.065 358.562 C 209.597 357.679,211.835 356.348,213.038 355.604 C 214.241 354.861,215.384 354.252,215.578 354.252 C 215.772 354.252,217.295 353.370,218.962 352.291 C 222.855 349.773,228.101 346.628,228.408 346.628 C 228.539 346.628,234.144 343.381,240.863 339.413 C 247.582 335.445,253.475 332.011,253.959 331.782 C 254.443 331.553,255.630 330.844,256.598 330.206 C 257.566 329.568,258.760 328.845,259.252 328.599 C 259.981 328.235,267.893 323.605,272.043 321.114 C 273.638 320.157,279.295 316.927,281.818 315.532 C 287.044 312.644,289.453 311.164,289.638 310.726 C 289.746 310.472,290.090 310.264,290.403 310.264 C 290.716 310.264,294.455 308.204,298.712 305.687 C 302.969 303.170,306.848 300.923,307.331 300.695 C 307.815 300.467,309.003 299.758,309.971 299.121 C 310.938 298.483,312.126 297.760,312.610 297.514 C 314.022 296.797,321.377 292.469,323.077 291.355 C 323.933 290.794,325.029 290.147,325.513 289.917 C 325.997 289.687,328.504 288.259,331.085 286.743 C 333.666 285.228,337.229 283.189,339.003 282.212 L 342.229 280.436 342.229 200.000 L 342.229 119.564 339.003 117.788 C 337.229 116.811,333.666 114.772,331.085 113.257 C 328.504 111.741,325.997 110.313,325.513 110.083 C 325.029 109.853,323.933 109.206,323.077 108.645 C 321.377 107.531,314.022 103.203,312.610 102.486 C 312.126 102.240,310.938 101.517,309.971 100.879 C 309.003 100.242,307.815 99.533,307.331 99.305 C 306.848 99.077,302.969 96.830,298.712 94.313 C 294.455 91.796,290.716 89.736,290.403 89.736 C 290.090 89.736,289.746 89.528,289.638 89.274 C 289.453 88.836,287.044 87.356,281.818 84.468 C 279.295 83.073,273.638 79.843,272.043 78.886 C 267.893 76.395,259.981 71.765,259.252 71.401 C 258.760 71.155,257.566 70.432,256.598 69.794 C 255.630 69.156,254.443 68.447,253.959 68.218 C 253.475 67.989,247.582 64.555,240.863 60.587 C 234.144 56.619,228.539 53.372,228.408 53.372 C 228.101 53.372,222.855 50.227,218.962 47.709 C 217.295 46.630,215.772 45.748,215.578 45.748 C 215.384 45.748,214.241 45.139,213.038 44.396 C 211.835 43.652,209.597 42.321,208.065 41.438 L 205.279 39.833 205.279 200.000 " stroke="none" fill="#000000" fill-rule="evenodd"></path></g></svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -33,7 +33,9 @@
"lunasea.BuyMeASoda": "Kauf mir eine Limonade",
"lunasea.Cancel": "Abbrechen",
"lunasea.ChangeProfiles": "Profile wechseln",
"lunasea.Changelog": "Änderungsprotokoll",
"lunasea.CheckLogsMessage": "Überprüfe die Protokolle für mehr Details",
"lunasea.Chores": "Aufgaben",
"lunasea.Clear": "Entfernen",
"lunasea.Close": "Schließen",
"lunasea.ComingSoon": "Bald verfügbar",
@@ -129,6 +131,7 @@
"radarr.Codec": "Kodec",
"radarr.Configure": "Konfigurieren",
"radarr.Copy": "Kopieren",
"radarr.CopyFiles": "Dateien Kopieren",
"radarr.CopyFull": "Hardlink/Dateien kopieren",
"radarr.CutoffUnmet": "Cutoff nicht erreicht",
"radarr.DateAdded": "Hinzugefügt am",
@@ -164,7 +167,9 @@
"radarr.Monitored": "Überwacht",
"radarr.MonitoredDescription": "Neue Veröffentlichungen überwachen",
"radarr.More": "Mehr",
"radarr.Move": "Übertragen",
"radarr.Move": "Verschieben",
"radarr.MoveFiles": "Datei verschieben",
"radarr.MoveFilesDescription": "Möchten Sie die Dateien verschieben?",
"radarr.MoveFull": "Dateien übertragen",
"radarr.Movie": "Film",
"radarr.MovieFileDeleted": "Filmdatei gelöscht",

View File

@@ -78,6 +78,7 @@
"lunasea.Months": "{} Months",
"lunasea.MonthsAgo": "{} Months Ago",
"lunasea.New": "New",
"lunasea.No": "No",
"lunasea.NotSet": "Not Set",
"lunasea.NoModulesEnabled": "No Modules Enabled",
"lunasea.OneDay": "1 Day",
@@ -127,6 +128,7 @@
"lunasea.Website": "Website",
"lunasea.Years": "{} Years",
"lunasea.YearsAgo": "{} Years Ago",
"lunasea.Yes": "Yes",
"overseerr.Audio": "Audio",
"overseerr.Approved": "Approved",
"overseerr.Available": "Available",
@@ -172,6 +174,7 @@
"radarr.Codec": "Codec",
"radarr.Configure": "Configure",
"radarr.Copy": "Copy",
"radarr.CopyFiles": "Hardlink/Copy Files",
"radarr.CopyFull": "Hardlink/Copy Files",
"radarr.CutoffUnmet": "Cutoff Unmet",
"radarr.DateAdded": "Date Added",
@@ -208,6 +211,8 @@
"radarr.MonitorMovie": "Monitor Movie",
"radarr.More": "More",
"radarr.Move": "Move",
"radarr.MoveFiles": "Move Files",
"radarr.MoveFilesDescription": "Would you like to move the files?",
"radarr.MoveFull": "Move Files",
"radarr.Movie": "Movie",
"radarr.Movies": "Movies",
@@ -268,6 +273,7 @@
"radarr.UnmappedFolders": "{} Unmapped Folders",
"radarr.Unmonitored": "Unmonitored",
"radarr.UnmonitorMovie": "Unmonitor Movie",
"radarr.Unreleased": "Unreleased",
"radarr.Upcoming": "Upcoming",
"radarr.UpdateLibrary": "Update Library",
"radarr.UpdateMovie": "Update Movie",
@@ -365,6 +371,7 @@
"settings.BasicAuthenticationHint1": "The username must not contain a colon",
"settings.BasicAuthenticationHint2": "The password can contain a colon",
"settings.BasicAuthenticationHint3": "The username and password are automatically converted to base64 encoding",
"settings.BootModule": "Boot Module",
"settings.BroadcastAddress": "Broadcast Address",
"settings.BroadcastAddressHint1": "This is the broadcast address of your local network",
"settings.BroadcastAddressHint2": "Typically this is the IP address of your machine with the last octet set to 255",
@@ -462,6 +469,8 @@
"settings.FilterCategory": "Filter Category",
"settings.ForgotYourPassword": "Forgot Your Password?",
"settings.FutureDays": "Future Days",
"settings.General": "General",
"settings.GeneralDescription": "Customize LunaSea",
"settings.GitHubDescription": "View the Source Code",
"settings.HeaderAdded": "Header Added",
"settings.HeaderDeleted": "Header Deleted",

View File

@@ -84,61 +84,101 @@
"lunasea.Website": "Nettside",
"radarr.AddMovie": "Legg til film",
"radarr.AddMovieAndSearch": "Legg til + søk",
"radarr.AddedTag": "La til emne",
"radarr.Age": "Alder",
"radarr.All": "Alle",
"radarr.Alphabetical": "Alfabetisk",
"radarr.Approved": "Godkjent",
"radarr.Audio": "Lyd",
"radarr.Automatic": "Automatisk",
"radarr.AvailabilityUnknown": "Ukjent tilgjengelighet",
"radarr.AvailableIn": "Tilgjengelig i {}",
"radarr.AvailableToday": "Tilgjengelig i dag",
"radarr.BackupDatabase": "Sikkerhetskopier database",
"radarr.Channels": "Kanaler",
"radarr.CinemaDateUnknown": "Kinodato ukjent",
"radarr.Codec": "Kodek",
"radarr.Configure": "Konfigurer",
"radarr.Copy": "Kopier",
"radarr.CutoffUnmet": "Ikke oppfylt",
"radarr.DateAdded": "Dato lagt til",
"radarr.DirectoryNotFound": "Mappe ble ikke funnet",
"radarr.Discover": "Oppdag",
"radarr.Disks": "Disker",
"radarr.DownloadFailed": "Nedlasting mislyktes",
"radarr.DownloadIgnored": "Nedlasting ignorert",
"radarr.DynamicRange": "Dynamisk rekkevidde",
"radarr.EditMovie": "Rediger fil",
"radarr.FailedToAddTag": "Klarte ikke legge til emne",
"radarr.FileBrowser": "Filutforsker …",
"radarr.FilterCatalogue": "Filtrer katalog",
"radarr.GrabbedFrom": "Hentat fra {}",
"radarr.History": "Historikk",
"radarr.HistoryDescription": "Vis nylig historikk",
"radarr.Import": "Importer",
"radarr.ImportMode": "Importmodus",
"radarr.InCinemasIn": "På kino {}",
"radarr.InCinemasToday": "På kino i dag",
"radarr.Interactive": "Interaktiv",
"radarr.Language": "Språk",
"radarr.Languages": "Språk",
"radarr.ManualImport": "Manuell import",
"radarr.ManualImportDescription": "Importer filmer fra filsystemet",
"radarr.MinimumAvailability": "Minimumstilgjengelighet",
"radarr.Missing": "Mangler",
"radarr.MonitorMovie": "Hold oppsyn med film",
"radarr.Monitored": "På oppsynsliste",
"radarr.MonitoredDescription": "Hold oppsyn med nye utgivelser",
"radarr.More": "Mer",
"radarr.Move": "Flytt",
"radarr.MoveFull": "Flytt filer",
"radarr.Movie": "Film",
"radarr.MovieFileDeleted": "Filmfil slettet",
"radarr.MovieFileRenamed": "Filmfilsnavn endret",
"radarr.MovieImported": "Film importert ({})",
"radarr.MovieNotFound": "Fant ikke filmen",
"radarr.MoviePath": "Filmsti",
"radarr.Movies": "Filmer",
"radarr.NoDisksFound": "Ingen disker funnet",
"radarr.NoFilesFound": "Ingen filer funnet",
"radarr.NoHistoryFound": "Fant ingen historikk",
"radarr.NoMoviesFound": "Fant ingen filmer",
"radarr.NoResultsFound": "Resultatløst",
"radarr.NoRootFoldersFound": "Ingen rotmapper funnet",
"radarr.NoSubdirectoriesFound": "Ingen undermapper funnet",
"radarr.NoSummaryIsAvailable": "Mangler sammendrag.",
"radarr.NoTagsFound": "Ingen emner funnet",
"radarr.Other": "Annet",
"radarr.Quality": "Kvalitet",
"radarr.QualityProfile": "Kvalitetsprofil",
"radarr.Queue": "Kø",
"radarr.QueueDescription": "Vis aktivt og køplassert innhold",
"radarr.Quick": "Rask",
"radarr.RefreshMovie": "Gjenoppfrisk film",
"radarr.Rejected": "Forkastet",
"radarr.Released": "Utgitt",
"radarr.ReleasedToday": "Utgitt i dag",
"radarr.Releases": "Utgivelser",
"radarr.RemoveMovie": "Fjern film",
"radarr.Resolution": "Oppløsning",
"radarr.RootFolder": "Rotmappe",
"radarr.RootFolders": "Rotmapper",
"radarr.RunRSSSync": "Kjør RSS-synkronisering",
"radarr.Runtime": "Spilletid",
"radarr.ScanType": "Skannetype",
"radarr.Search": "Søk",
"radarr.SearchAllMissing": "Søk i alle manglende",
"radarr.SearchFor": "Søkk etter {}",
"radarr.Seeders": "Delere",
"radarr.SelectLanguage": "Velg språk",
"radarr.SelectMovie": "Velg film",
"radarr.SelectQuality": "Velg kvalitet",
"radarr.Size": "Størrelse",
"radarr.SortCatalogue": "Sorter katelog",
"radarr.StartSearchFor": "Start søk etter …",
"radarr.StartSearchForMissingMovie": "Start søk etter manglende film",
"radarr.Studio": "Studio",
"radarr.Subtitles": "Undertekster",
"radarr.SystemStatus": "Systemstatus",
"radarr.SystemStatusDescription": "Systemstatus og diskplass",
"radarr.Tags": "Etiketter",
@@ -149,10 +189,35 @@
"radarr.Upcoming": "Kommende",
"radarr.UpdateLibrary": "Oppdater bibliotek",
"radarr.UpdateMovie": "Oppdater film",
"radarr.Video": "Video",
"radarr.ViewWebGUI": "Vis vev-grensesnitt",
"radarr.Wanted": "Ønsket",
"radarr.Weight": "Vekt",
"radarr.Year": "År",
"sabnzbd.All": "Alle",
"sabnzbd.Completed": "Fullført",
"sabnzbd.Descending": "Synkende",
"sabnzbd.Duplicate": "Duplikat",
"sabnzbd.Failed": "Feilet",
"sabnzbd.Force": "Tving",
"sabnzbd.HibernatePC": "Dvalemodus",
"sabnzbd.Name": "Navn",
"sabnzbd.RepairUnpack": "Reparer/Pakk ut",
"sabnzbd.RepairUnpackDelete": "Reparer/Pakk ut/Slett",
"sabnzbd.Size": "Størrelse",
"sabnzbd.ShutdownPC": "Skru av PC",
"sabnzbd.StandbyPC": "Ventemodus",
"sabnzbd.Stop": "Stopp",
"sabnzbd.Age": "Alder",
"sabnzbd.Ascending": "Stigende",
"sabnzbd.CategoryDefault": "Standardkategori",
"sabnzbd.High": "Høy",
"sabnzbd.Low": "Lav",
"sabnzbd.None": "Ingen",
"sabnzbd.Paused": "Pauset",
"sabnzbd.Normal": "Normal",
"sabnzbd.Repair": "Reparer",
"sabnzbd.ShutdownSABnzbd": "Skru av SABnzbd",
"search.NoCategoriesFound": "Fant ingen kategorier",
"search.Subcategories": "Underkategorier",
"search.Search": "Søk",
@@ -275,7 +340,7 @@
"settings.HeaderKey": "Hode-nøkkel",
"settings.HeaderKeyValidation": "Hodenøkkel påkrevd",
"settings.Email": "E-post",
"tautulli.ETA": "Estimert tid til ankomst",
"tautulli.ETA": "Estimert tid igjen",
"tautulli.Throttled": "Strupet",
"tautulli.TerminationAttachMessage": "Du kan alternativt legge ved en avsluttingsmelding nedenfor.",
"tautulli.Location": "Sted",

View File

@@ -0,0 +1,17 @@
{
"dashboard.Modules": "Module",
"dashboard.Calendar": "Calendar",
"dashboard.Friday": "Vineri",
"dashboard.OneMonth": "O lună",
"dashboard.OneWeek": "O săptămână",
"dashboard.PastDays": "Zile trecute",
"dashboard.Saturday": "Sâmbătă",
"dashboard.Schedule": "Program",
"dashboard.Sunday": "Duminică",
"dashboard.Thursday": "Joi",
"dashboard.Tuesday": "Marți",
"dashboard.TwoWeeks": "Două săptămâni",
"dashboard.Wednesday": "Miercuri",
"dashboard.FutureDays": "Zile în viitor",
"dashboard.Monday": "Luni"
}

View File

@@ -54,6 +54,7 @@
"lunasea.Disabled": "Devre Dışı",
"lunasea.Dismiss": "Kapat",
"lunasea.Docs": "Belgeler",
"lunasea.DownloadClient": "İstemciyi İndir",
"lunasea.Edge": "Kenar",
"lunasea.Error": "Hata",
"lunasea.ExternalModules": "Harici Modüller",
@@ -77,6 +78,7 @@
"lunasea.Months": "{} Ay",
"lunasea.MonthsAgo": "{} Ay Önce",
"lunasea.New": "Yeni",
"lunasea.No": "Hayır",
"lunasea.NoModulesEnabled": "Etkin Modül Yok",
"lunasea.NotSet": "Ayarlanmadı",
"lunasea.OneDay": "1 Gün",
@@ -126,6 +128,7 @@
"lunasea.Website": "Web Sitesi",
"lunasea.Years": "{} Yıl",
"lunasea.YearsAgo": "{} Yıl Önce",
"lunasea.Yes": "Evet",
"overseerr.Users": "Kullanıcılar",
"overseerr.UnknownUser": "Bilinmeyen Kullanıcı",
"overseerr.NoUsersFound": "Kullanıcı Bulunamadı",
@@ -171,6 +174,7 @@
"radarr.Codec": "Kodek",
"radarr.Configure": "Yapılandır",
"radarr.Copy": "Kopyala",
"radarr.CopyFiles": "Dosyaları Kopyala/Sabit Bağlantı Oluştur",
"radarr.CopyFull": "Dosyaları Kopyala/Sabit Bağlantı Oluştur",
"radarr.CutoffUnmet": "Karşılanmayanı Kes",
"radarr.DateAdded": "Eklenme Tarihi",
@@ -207,6 +211,8 @@
"radarr.MonitoredDescription": "Yeni yayınlar için takip edin",
"radarr.More": "Daha Fazla",
"radarr.Move": "Taşı",
"radarr.MoveFiles": "Dosyaları Taşı",
"radarr.MoveFilesDescription": "Dosyaları taşımak istiyor musunuz?",
"radarr.MoveFull": "Dosyaları Taşı",
"radarr.Movie": "Film",
"radarr.MovieFileDeleted": "Film Dosyası Silindi",
@@ -267,6 +273,7 @@
"radarr.UnmappedFolders": "{} Eşlenmeyen Klasörler",
"radarr.UnmonitorMovie": "Filmi Takip Etmeyi Bırak",
"radarr.Unmonitored": "Takip Edilmeyen",
"radarr.Unreleased": "Yayınlanmadı",
"radarr.Upcoming": "Yakında",
"radarr.UpdateLibrary": "Kütüphaneyi Güncelle",
"radarr.UpdateMovie": "Filmi Güncelle",
@@ -552,6 +559,15 @@
"settings.RenamedProfile": "Profil Yeniden Adlandırıldı",
"settings.DeletedProfile": "Profil Silindi",
"settings.NoProfilesFound": "Profil Bulunamadı",
"settings.SentryLogging": "Sentry Günlüğü",
"settings.SentryLoggingDescription": "Hataları ve Çökmeleri Sentry'ye Yükleyin",
"settings.DatabaseCorruptionDetected": "Veri Tabanı Bozulması Tespit Edildi",
"settings.DatabaseCorruptionDetectedMessageLine1": "Veri tabanı bozulması tespit edildi ve yapılandırmanız temizlendi.",
"settings.DatabaseCorruptionDetectedMessageLine2": "Rahatsızlık için özür dileriz, daha önce oluşturulan tüm yedeklemeler, daha önce bozuk bir veri tabanı ile dışa aktarılmış olsa bile geri yüklenebilir olmalıdır.",
"settings.DiscordDescription": "Özellik İsteyin & Destek Alın",
"settings.BootModule": "Önyükleme Modülü",
"settings.GeneralDescription": "LunaSea'yi Özelleştirin",
"settings.General": "Genel",
"sonarr.AddedSeries": "Eklenen Diziler",
"sonarr.Age": "Yıl",
"sonarr.All": "Her Şey",

View File

@@ -54,6 +54,7 @@
"lunasea.Disabled": "不可用",
"lunasea.Dismiss": "解散",
"lunasea.Docs": "文档",
"lunasea.DownloadClient": "下载客户端",
"lunasea.Edge": "边缘",
"lunasea.Error": "错误",
"lunasea.ExternalModules": "外部模块",
@@ -77,6 +78,7 @@
"lunasea.Months": "{} 个月",
"lunasea.MonthsAgo": "{} 几个月前",
"lunasea.New": "新的",
"lunasea.No": "否",
"lunasea.NoModulesEnabled": "未启用模块",
"lunasea.NotSet": "未设置",
"lunasea.OneDay": "1天",
@@ -126,6 +128,7 @@
"lunasea.Website": "网站",
"lunasea.Years": "{} 年",
"lunasea.YearsAgo": "{} 年前",
"lunasea.Yes": "是",
"overseerr.NoRequests": "没有请求",
"overseerr.OneRequest": "1个请求",
"overseerr.SomeRequests": "{} 请求",
@@ -171,6 +174,7 @@
"radarr.Codec": "编解码器",
"radarr.Configure": "配置",
"radarr.Copy": "复制",
"radarr.CopyFiles": "硬链接/复制文件",
"radarr.CopyFull": "硬链接/复制文件",
"radarr.CutoffUnmet": "截止未满足",
"radarr.DateAdded": "添加日期",
@@ -207,6 +211,8 @@
"radarr.MonitoredDescription": "监控新版本",
"radarr.More": "更多",
"radarr.Move": "移动",
"radarr.MoveFiles": "移动文件",
"radarr.MoveFilesDescription": "确定要移动这些文件吗?",
"radarr.MoveFull": "移动文件",
"radarr.Movie": "电影",
"radarr.MovieFileDeleted": "电影文件已删除",
@@ -267,6 +273,7 @@
"radarr.UnmappedFolders": "{} 未映射的文件夹",
"radarr.UnmonitorMovie": "监控电影",
"radarr.Unmonitored": "不受监控",
"radarr.Unreleased": "未发布",
"radarr.Upcoming": "即将到来",
"radarr.UpdateLibrary": "更新库",
"radarr.UpdateMovie": "更新电影",
@@ -581,6 +588,11 @@
"settings.DatabaseCorruptionDetected": "检测到数据库损坏",
"settings.DatabaseCorruptionDetectedMessageLine1": "已检测到数据库损坏,并且已清除您的配置。",
"settings.DatabaseCorruptionDetectedMessageLine2": "很抱歉给您带来不便,即使以前导出的数据库已损坏,所有以前创建的备份都应该是可恢复的。",
"settings.SentryLogging": "哨兵日志记录",
"settings.SentryLoggingDescription": "上传错误崩溃到Sentry",
"settings.DiscordDescription": "请求功能获得支持",
"settings.General": "通用",
"settings.GeneralDescription": "自定义LunaSea",
"sonarr.AddSeries": "添加系列",
"sonarr.AddedOn": "添加于",
"sonarr.Age": "年龄",

View File

@@ -7,7 +7,7 @@ description: Breaking down what is and isn't supported on different platforms
The tables below showcases which modules or features may not be supported on each platform. If a module or feature is not listed, you can assume that every platform has full support for said module or feature!
> Work will continuously be down to try to achieve 100% feature parity between all platforms when possible!
> Work will continuously be done to try to achieve 100% feature parity between all platforms when possible!
## Module Support
@@ -20,11 +20,10 @@ The tables below showcases which modules or features may not be supported on eac
## Feature Support
| Feature | Android | iOS | Linux | macOS | Windows | Web (Hosted) | Web (Self-Hosted) |
| :--------------------: | :-----: | :-: | :---: | :---: | :-----: | :----------: | :---------------: |
| Local Backup & Restore | ✅ | ✅ | | ✅ | | | ❌ |
| LunaSea Accounts | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
| Notifications | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Feature | Android | iOS | Linux | macOS | Windows | Web (Hosted) | Web (Self-Hosted) |
| :--------------: | :-----: | :-: | :---: | :---: | :-----: | :----------: | :---------------: |
| LunaSea Accounts | ✅ | ✅ | | ✅ | | | ❌ |
| Notifications | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
## Web-Specific Restrictions

View File

@@ -17,20 +17,20 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.634.0)
aws-sdk-core (3.152.0)
aws-partitions (1.655.0)
aws-sdk-core (3.166.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.58.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (1.59.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.114.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-s3 (1.117.1)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.5.1)
aws-sigv4 (1.5.2)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.1.0)
@@ -86,7 +86,7 @@ GEM
escape (0.0.4)
ethon (0.15.0)
ffi (>= 1.15.0)
excon (0.92.5)
excon (0.93.1)
faraday (1.10.2)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -159,9 +159,9 @@ GEM
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.27.0)
google-apis-core (>= 0.7.2, < 2.a)
google-apis-core (0.9.0)
google-apis-androidpublisher_v3 (0.30.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-core (0.9.1)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@@ -170,27 +170,27 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
google-apis-iamcredentials_v1 (0.14.0)
google-apis-core (>= 0.7.2, < 2.a)
google-apis-playcustomapp_v1 (0.10.0)
google-apis-core (>= 0.7, < 2.a)
google-apis-storage_v1 (0.17.0)
google-apis-core (>= 0.7, < 2.a)
google-apis-iamcredentials_v1 (0.16.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-playcustomapp_v1 (0.12.0)
google-apis-core (>= 0.9.1, < 2.a)
google-apis-storage_v1 (0.19.0)
google-apis-core (>= 0.9.0, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.3.0)
google-cloud-storage (1.42.0)
google-cloud-storage (1.44.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.17.0)
google-apis-storage_v1 (~> 0.19.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.2.0)
googleauth (1.3.0)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
@@ -271,7 +271,7 @@ GEM
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
zeitwerk (2.6.0)
zeitwerk (2.6.4)
PLATFORMS
ruby
@@ -281,4 +281,4 @@ DEPENDENCIES
fastlane
BUNDLED WITH
2.3.19
2.3.25

View File

@@ -1,5 +1,5 @@
platform :ios, '11.0'
$FirebaseSDKVersion = '9.5.0'
$FirebaseSDKVersion = '10.0.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@@ -1,8 +1,9 @@
PODS:
- cloud_firestore (3.4.8):
- Firebase/Firestore (= 9.5.0)
- cloud_firestore (4.0.4):
- Firebase/Firestore (= 10.0.0)
- firebase_core
- Flutter
- nanopb (< 2.30910.0, >= 2.30908.0)
- DKImagePickerController/Core (4.3.4):
- DKImagePickerController/ImageDataManager
- DKImagePickerController/Resource
@@ -37,87 +38,78 @@ PODS:
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Firebase/Auth (9.5.0):
- Firebase/Auth (10.0.0):
- Firebase/CoreOnly
- FirebaseAuth (~> 9.5.0)
- Firebase/CoreOnly (9.5.0):
- FirebaseCore (= 9.5.0)
- Firebase/Firestore (9.5.0):
- FirebaseAuth (~> 10.0.0)
- Firebase/CoreOnly (10.0.0):
- FirebaseCore (= 10.0.0)
- Firebase/Firestore (10.0.0):
- Firebase/CoreOnly
- FirebaseFirestore (~> 9.5.0)
- Firebase/Messaging (9.5.0):
- FirebaseFirestore (~> 10.0.0)
- Firebase/Messaging (10.0.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 9.5.0)
- Firebase/Storage (9.5.0):
- FirebaseMessaging (~> 10.0.0)
- Firebase/Storage (10.0.0):
- Firebase/CoreOnly
- FirebaseStorage (~> 9.5.0)
- firebase_auth (3.9.0):
- Firebase/Auth (= 9.5.0)
- FirebaseStorage (~> 10.0.0)
- firebase_auth (4.1.1):
- Firebase/Auth (= 10.0.0)
- firebase_core
- Flutter
- firebase_core (1.22.0):
- Firebase/CoreOnly (= 9.5.0)
- firebase_core (2.1.1):
- Firebase/CoreOnly (= 10.0.0)
- Flutter
- firebase_messaging (13.0.2):
- Firebase/Messaging (= 9.5.0)
- firebase_messaging (14.0.4):
- Firebase/Messaging (= 10.0.0)
- firebase_core
- Flutter
- firebase_storage (10.3.8):
- Firebase/Storage (= 9.5.0)
- firebase_storage (11.0.4):
- Firebase/Storage (= 10.0.0)
- firebase_core
- Flutter
- FirebaseAppCheckInterop (9.6.0)
- FirebaseAuth (9.5.0):
- FirebaseCore (~> 9.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/Environment (~> 7.7)
- GTMSessionFetcher/Core (< 3.0, >= 1.7)
- FirebaseAuthInterop (9.6.0)
- FirebaseCore (9.5.0):
- FirebaseCoreDiagnostics (~> 9.0)
- FirebaseCoreInternal (~> 9.0)
- GoogleUtilities/Environment (~> 7.7)
- GoogleUtilities/Logger (~> 7.7)
- FirebaseCoreDiagnostics (9.6.0):
- GoogleDataTransport (< 10.0.0, >= 9.1.4)
- GoogleUtilities/Environment (~> 7.7)
- GoogleUtilities/Logger (~> 7.7)
- nanopb (< 2.30910.0, >= 2.30908.0)
- FirebaseCoreExtension (9.6.0):
- FirebaseCore (~> 9.0)
- FirebaseCoreInternal (9.6.0):
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- FirebaseFirestore (9.5.0):
- FirebaseFirestore/AutodetectLeveldb (= 9.5.0)
- FirebaseFirestore/AutodetectLeveldb (9.5.0):
- FirebaseAppCheckInterop (10.1.0)
- FirebaseAuth (10.0.0):
- FirebaseCore (~> 10.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
- GoogleUtilities/Environment (~> 7.8)
- GTMSessionFetcher/Core (~> 2.1)
- FirebaseAuthInterop (10.1.0)
- FirebaseCore (10.0.0):
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Logger (~> 7.8)
- FirebaseCoreExtension (10.1.0):
- FirebaseCore (~> 10.0)
- FirebaseCoreInternal (10.1.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- FirebaseFirestore (10.0.0):
- FirebaseFirestore/AutodetectLeveldb (= 10.0.0)
- FirebaseFirestore/AutodetectLeveldb (10.0.0):
- FirebaseFirestore/Base
- FirebaseFirestore/WithLeveldb
- FirebaseFirestore/Base (9.5.0)
- FirebaseFirestore/WithLeveldb (9.5.0):
- FirebaseFirestore/Base (10.0.0)
- FirebaseFirestore/WithLeveldb (10.0.0):
- FirebaseFirestore/Base
- FirebaseInstallations (9.6.0):
- FirebaseCore (~> 9.0)
- GoogleUtilities/Environment (~> 7.7)
- GoogleUtilities/UserDefaults (~> 7.7)
- FirebaseInstallations (10.1.0):
- FirebaseCore (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8)
- PromisesObjC (~> 2.1)
- FirebaseMessaging (9.5.0):
- FirebaseCore (~> 9.0)
- FirebaseInstallations (~> 9.0)
- GoogleDataTransport (< 10.0.0, >= 9.1.4)
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/Environment (~> 7.7)
- GoogleUtilities/Reachability (~> 7.7)
- GoogleUtilities/UserDefaults (~> 7.7)
- FirebaseMessaging (10.0.0):
- FirebaseCore (~> 10.0)
- FirebaseInstallations (~> 10.0)
- GoogleDataTransport (~> 9.2)
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Reachability (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8)
- nanopb (< 2.30910.0, >= 2.30908.0)
- FirebaseStorage (9.5.0):
- FirebaseAppCheckInterop (~> 9.0)
- FirebaseAuthInterop (~> 9.0)
- FirebaseCore (~> 9.0)
- FirebaseCoreExtension (~> 9.0)
- FirebaseStorageInternal (~> 9.0)
- FirebaseStorageInternal (9.6.0):
- FirebaseCore (~> 9.0)
- GTMSessionFetcher/Core (< 3.0, >= 1.7)
- FirebaseStorage (10.0.0):
- FirebaseAppCheckInterop (~> 10.0)
- FirebaseAuthInterop (~> 10.0)
- FirebaseCore (~> 10.0)
- FirebaseCoreExtension (~> 10.0)
- GTMSessionFetcher/Core (~> 2.1)
- Flutter (1.0.0)
- flutter_native_splash (0.0.1):
- Flutter
@@ -145,7 +137,7 @@ PODS:
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (7.8.0):
- GoogleUtilities/Logger
- GTMSessionFetcher/Core (2.1.0)
- GTMSessionFetcher/Core (2.2.0)
- in_app_purchase_storekit (0.0.1):
- Flutter
- nanopb (2.30909.0):
@@ -160,16 +152,16 @@ PODS:
- PromisesObjC (2.1.1)
- quick_actions_ios (0.0.1):
- Flutter
- SDWebImage (5.13.2):
- SDWebImage/Core (= 5.13.2)
- SDWebImage/Core (5.13.2)
- Sentry (7.23.0):
- Sentry/Core (= 7.23.0)
- Sentry/Core (7.23.0)
- SDWebImage (5.13.5):
- SDWebImage/Core (= 5.13.5)
- SDWebImage/Core (5.13.5)
- Sentry (7.30.0):
- Sentry/Core (= 7.30.0)
- Sentry/Core (7.30.0)
- sentry_flutter (0.0.1):
- Flutter
- FlutterMacOS
- Sentry (~> 7.23.0)
- Sentry (~> 7.30.0)
- share_plus (0.0.1):
- Flutter
- shared_preferences_ios (0.0.1):
@@ -189,7 +181,7 @@ DEPENDENCIES:
- firebase_core (from `.symlinks/plugins/firebase_core/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 `9.5.0`)
- FirebaseFirestore (from `https://github.com/invertase/firestore-ios-sdk-frameworks.git`, tag `10.0.0`)
- Flutter (from `Flutter`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/ios`)
@@ -211,13 +203,11 @@ SPEC REPOS:
- FirebaseAuth
- FirebaseAuthInterop
- FirebaseCore
- FirebaseCoreDiagnostics
- FirebaseCoreExtension
- FirebaseCoreInternal
- FirebaseInstallations
- FirebaseMessaging
- FirebaseStorage
- FirebaseStorageInternal
- FMDB
- GoogleDataTransport
- GoogleUtilities
@@ -243,7 +233,7 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/firebase_storage/ios"
FirebaseFirestore:
:git: https://github.com/invertase/firestore-ios-sdk-frameworks.git
:tag: 9.5.0
:tag: 10.0.0
Flutter:
:path: Flutter
flutter_native_splash:
@@ -270,51 +260,49 @@ EXTERNAL SOURCES:
CHECKOUT OPTIONS:
FirebaseFirestore:
:git: https://github.com/invertase/firestore-ios-sdk-frameworks.git
:tag: 9.5.0
:tag: 10.0.0
SPEC CHECKSUMS:
cloud_firestore: 7e123d5034b068e9a1fb32b2ad98a814c7f3e45d
cloud_firestore: 62c5fa0e5ce5373be25d6233e8edbbe991fa973d
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
file_picker: 817ab1d8cd2da9d2da412a417162deee3500fc95
Firebase: 800f16f07af493d98d017446a315c27af0552f41
firebase_auth: c070c7e5b66037cddb73a68ca4bf4728b063680b
firebase_core: 31872a49ffe0bf6f834e7044c7334e433536735a
firebase_messaging: 0950bacaf29e1f50e3f0502aa1c29a3a5814925e
firebase_storage: e81dc988f10c31c4ec1b1c79719ad679795b531d
FirebaseAppCheckInterop: d5ecda0c09f8069406643d6e0fa12c09d1b736e3
FirebaseAuth: 741918f1fa62ed23246a509279f91d42d79a713f
FirebaseAuthInterop: b6cf02117f13a8400c8c8b4421e12c6e850bcaf3
FirebaseCore: 25c0400b670fd1e2f2104349cd3b5dcce8d9418f
FirebaseCoreDiagnostics: 99a495094b10a57eeb3ae8efa1665700ad0bdaa6
FirebaseCoreExtension: e83465d1236b166d1d445bbf0e82b65acb30b73b
FirebaseCoreInternal: bca76517fe1ed381e989f5e7d8abb0da8d85bed3
FirebaseFirestore: cbb150095370d64f1f021e3a7eecd2b543356ae3
FirebaseInstallations: 0a115432c4e223c5ab20b0dbbe4cbefa793a0e8e
FirebaseMessaging: 732623518591384f61c287e3d8f65294beb7ffb3
FirebaseStorage: a806d9f9eededf6fb1d906e79221b83ada1dbb4f
FirebaseStorageInternal: 81d8a597324ccd06c41a43c5700bc1185a2fc328
Firebase: 1b810f3d0c0532e27a48f1961f8c0400a668a2cf
firebase_auth: dd33e93fce72a1c72040f7380dacf06e89db5705
firebase_core: 5c0bb0ca7d0e70480a68a6e9ad9bf55d1edd5305
firebase_messaging: bf848602391fa6ee68d86e337f81be14be120aaf
firebase_storage: 5cf5e677fd9793e26ec5d006100c25e28cd21c05
FirebaseAppCheckInterop: 53eec3c354a95f8fe6ff947dd9518ea17f624914
FirebaseAuth: 493382cf533cc45e2862b00e9aa4cfe4c98daf71
FirebaseAuthInterop: 15b2c717321d5e46a60562e388c4d1b039ea7e28
FirebaseCore: 97f48a3a567a72b8d4daa0f03c3aadb78df4e995
FirebaseCoreExtension: 69b966c399abc4ca6dc75006ab87160f81512725
FirebaseCoreInternal: 96d75228e10fd369564da51bd898414eb0f54df5
FirebaseFirestore: d1b97d497a6e6c31bb38dff714af8e606395b959
FirebaseInstallations: 99d24bac0243cf8b0e96cf5426340d211f0bcc80
FirebaseMessaging: 8916bf5edb1dbfac74665a181e4d1ab3a78a08a2
FirebaseStorage: 8b0b0630e11b9f3e4a479a26cfccb70ec790ec50
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
GoogleDataTransport: 1c8145da7117bd68bbbed00cf304edb6a24de00f
GoogleUtilities: 1d20a6ad97ef46f67bbdec158ce00563a671ebb7
GTMSessionFetcher: ffbb25ec00ebcb5201adab0a56d808f6f1902d9f
GTMSessionFetcher: d62ffccea5108bb9e7762ee121ae63bbdd2c6303
in_app_purchase_storekit: d7fcf4646136ec258e237872755da8ea6c1b6096
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
quick_actions_ios: 5ec8f5f1ae81512ac803fe10c197ebb875767a9e
SDWebImage: 72f86271a6f3139cc7e4a89220946489d4b9a866
Sentry: a0d4563fa4ddacba31fdcc35daaa8573d87224d6
sentry_flutter: 8bde7d0e57a721727fe573f13bb292c497b5a249
quick_actions_ios: 56c03753992beabaa6c598e470e12d430d6e5e2f
SDWebImage: 23d714cd599354ee7906dbae26dff89b421c4370
Sentry: dcd74a503a6d4594ef5d6ab28cf30895a2c19a40
sentry_flutter: d6f51618010b194d871b063903b1bb8170d396fb
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
PODFILE CHECKSUM: 4998bdd481d1c989b0fc39ba5d95ea3bed976109
PODFILE CHECKSUM: 0f2923ed3bf0e590c5af6cab3b1cde48e6ae0eec
COCOAPODS: 1.11.3

View File

@@ -8,16 +8,16 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
371E6475B0A3BE94B2BDF716 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 44EF78720B687FDBE9001C4D /* Pods_Runner.framework */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
5A2FBF43F4CBC30F9BB6CD42 /* Pods_ImageNotification.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7DFFCA57A5DC71BDB2499BC1 /* Pods_ImageNotification.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
795B891D92156DA8AA3E97A7 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1525DA337801A179F0B68D9 /* Pods_Runner.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
9C2991242453FE3100B93AB2 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C2991232453FE3100B93AB2 /* StoreKit.framework */; };
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, ); }; };
B665130F9476C363091FF832 /* Pods_ImageNotification.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6F63DD40C7860CACF800437 /* Pods_ImageNotification.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -57,12 +57,14 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
2ED7BA47F325235F982A481E /* 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 = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
67568413412812429E93495D /* 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 = "<group>"; };
44EF78720B687FDBE9001C4D /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
702080D64FE7B3882B9842A3 /* 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 = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
8A9E702DF418CEFFA625E5C7 /* 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 = "<group>"; };
7DFFCA57A5DC71BDB2499BC1 /* Pods_ImageNotification.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ImageNotification.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -78,12 +80,10 @@
9C7092B125E77E470056AE0B /* NotificationService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationService.h; sourceTree = "<group>"; };
9C7092B225E77E470056AE0B /* NotificationService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationService.m; sourceTree = "<group>"; };
9C7092B425E77E470056AE0B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B911792AFBDC33DE7936CFE1 /* 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 = "<group>"; };
C1525DA337801A179F0B68D9 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CD1E6CE85C9550ECB7D0A121 /* 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 = "<group>"; };
CF1DE2A00E71D08275431635 /* 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 = "<group>"; };
D6F63DD40C7860CACF800437 /* Pods_ImageNotification.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ImageNotification.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EAC2E4CA11768A55B5EA3B27 /* 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 = "<group>"; };
ACC178F98C7426A348E138DD /* 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 = "<group>"; };
AD9EB60D5E1FDD26501B69CA /* 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 = "<group>"; };
D010600D97E23D1BE9FBA1CC /* 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 = "<group>"; };
DB821AD0857E62B21015D760 /* 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 = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -92,7 +92,7 @@
buildActionMask = 2147483647;
files = (
9C2991242453FE3100B93AB2 /* StoreKit.framework in Frameworks */,
795B891D92156DA8AA3E97A7 /* Pods_Runner.framework in Frameworks */,
371E6475B0A3BE94B2BDF716 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -100,7 +100,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
B665130F9476C363091FF832 /* Pods_ImageNotification.framework in Frameworks */,
5A2FBF43F4CBC30F9BB6CD42 /* Pods_ImageNotification.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -179,8 +179,8 @@
isa = PBXGroup;
children = (
9C2991232453FE3100B93AB2 /* StoreKit.framework */,
D6F63DD40C7860CACF800437 /* Pods_ImageNotification.framework */,
C1525DA337801A179F0B68D9 /* Pods_Runner.framework */,
7DFFCA57A5DC71BDB2499BC1 /* Pods_ImageNotification.framework */,
44EF78720B687FDBE9001C4D /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -188,12 +188,12 @@
F5D05D221249C73674C5DB0D /* Pods */ = {
isa = PBXGroup;
children = (
CF1DE2A00E71D08275431635 /* Pods-ImageNotification.debug.xcconfig */,
EAC2E4CA11768A55B5EA3B27 /* Pods-ImageNotification.release.xcconfig */,
CD1E6CE85C9550ECB7D0A121 /* Pods-ImageNotification.profile.xcconfig */,
8A9E702DF418CEFFA625E5C7 /* Pods-Runner.debug.xcconfig */,
67568413412812429E93495D /* Pods-Runner.release.xcconfig */,
B911792AFBDC33DE7936CFE1 /* Pods-Runner.profile.xcconfig */,
ACC178F98C7426A348E138DD /* Pods-ImageNotification.debug.xcconfig */,
D010600D97E23D1BE9FBA1CC /* Pods-ImageNotification.release.xcconfig */,
702080D64FE7B3882B9842A3 /* Pods-ImageNotification.profile.xcconfig */,
2ED7BA47F325235F982A481E /* Pods-Runner.debug.xcconfig */,
DB821AD0857E62B21015D760 /* Pods-Runner.release.xcconfig */,
AD9EB60D5E1FDD26501B69CA /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@@ -205,7 +205,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
39FBDB6076758BF0DEA44641 /* [CP] Check Pods Manifest.lock */,
1AF231CBAF75F471E97C5E3F /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
@@ -213,8 +213,8 @@
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
9C7092B825E77E470056AE0B /* Embed App Extensions */,
0FCE63D04B4E3BE726679EFF /* [CP] Embed Pods Frameworks */,
221DD25D90167301CB97844A /* [CP] Copy Pods Resources */,
4C0D8B6E700C55D46B0878AF /* [CP] Embed Pods Frameworks */,
7B696945E0B5C5F36D81D6B3 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -230,7 +230,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 9C7092BC25E77E470056AE0B /* Build configuration list for PBXNativeTarget "ImageNotification" */;
buildPhases = (
CB3839E76D98CCFBB6A9F753 /* [CP] Check Pods Manifest.lock */,
1B47C8D8F52BAFB243086F88 /* [CP] Check Pods Manifest.lock */,
9C7092AB25E77E470056AE0B /* Sources */,
9C7092AC25E77E470056AE0B /* Frameworks */,
9C7092AD25E77E470056AE0B /* Resources */,
@@ -308,7 +308,65 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
0FCE63D04B4E3BE726679EFF /* [CP] Embed Pods Frameworks */ = {
1AF231CBAF75F471E97C5E3F /* [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;
};
1B47C8D8F52BAFB243086F88 /* [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-ImageNotification-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;
};
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";
};
4C0D8B6E700C55D46B0878AF /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -322,13 +380,11 @@
"${BUILT_PRODUCTS_DIR}/FirebaseAuth/FirebaseAuth.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseAuthInterop/FirebaseAuthInterop.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseCoreDiagnostics/FirebaseCoreDiagnostics.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseCoreExtension/FirebaseCoreExtension.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseMessaging/FirebaseMessaging.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseStorage/FirebaseStorage.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseStorageInternal/FirebaseStorageInternal.framework",
"${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework",
"${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework",
"${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework",
@@ -358,13 +414,11 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseAuth.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseAuthInterop.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreDiagnostics.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreExtension.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreInternal.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseMessaging.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseStorage.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseStorageInternal.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework",
@@ -390,7 +444,7 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
221DD25D90167301CB97844A /* [CP] Copy Pods Resources */ = {
7B696945E0B5C5F36D81D6B3 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -408,42 +462,6 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
39FBDB6076758BF0DEA44641 /* [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;
};
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";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -458,28 +476,6 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
};
CB3839E76D98CCFBB6A9F753 /* [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-ImageNotification-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;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */

View File

@@ -29,8 +29,15 @@ class RadarrCommandHandlerMovie {
///
/// Required Parameters:
/// - `movie`: [RadarrMovie] object with the updated information
Future<RadarrMovie> update({required RadarrMovie movie}) async =>
_commandUpdateMovie(_client, movie: movie);
Future<RadarrMovie> update({
required RadarrMovie movie,
bool moveFiles = false,
}) async =>
_commandUpdateMovie(
_client,
movie: movie,
moveFiles: moveFiles,
);
/// Handler for [movie/{id}](https://radarr.video/docs/api/#/Movie/deleteMovie).
///

View File

@@ -3,7 +3,14 @@ part of radarr_commands;
Future<RadarrMovie> _commandUpdateMovie(
Dio client, {
required RadarrMovie movie,
required bool moveFiles,
}) async {
Response response = await client.put('movie', data: movie.toJson());
Response response = await client.put(
'movie',
data: movie.toJson(),
queryParameters: {
'moveFiles': moveFiles,
},
);
return RadarrMovie.fromJson(response.data);
}

View File

@@ -17,7 +17,5 @@ export 'vendor.dart'
FutureProvider,
ChangeNotifierProvider,
Consumer,
Locator,
Create;
Locator;
export 'package:provider/provider.dart';

View File

@@ -21,7 +21,7 @@ class LunaConfig {
LunaSeaDatabase.ENABLED_PROFILE.update(LunaProfile.list[0]);
}
} catch (error, stack) {
await LunaDatabase().bootstrap(databaseCorruption: true);
await LunaDatabase().bootstrap();
LunaLogger().error(
'Failed to import configuration, resetting to default',
error,

View File

@@ -1,10 +1,8 @@
import 'package:lunasea/database/box.dart';
import 'package:lunasea/database/models/profile.dart';
import 'package:lunasea/database/table.dart';
import 'package:lunasea/database/tables/bios.dart';
import 'package:lunasea/database/tables/lunasea.dart';
import 'package:lunasea/system/filesystem/filesystem.dart';
import 'package:lunasea/system/logger.dart';
import 'package:lunasea/system/platform.dart';
import 'package:lunasea/vendor.dart';
@@ -24,20 +22,8 @@ class LunaDatabase {
}
Future<void> open() async {
try {
await LunaBox.open();
if (LunaBox.profiles.isEmpty) await bootstrap();
} catch (error, stack) {
await nuke();
await LunaBox.open();
await bootstrap(databaseCorruption: true);
LunaLogger().error(
'Database corruption detected',
error,
stack,
);
}
await LunaBox.open();
if (LunaBox.profiles.isEmpty) await bootstrap();
}
Future<void> nuke() async {
@@ -52,15 +38,12 @@ class LunaDatabase {
}
}
Future<void> bootstrap({
bool databaseCorruption = false,
}) async {
Future<void> bootstrap() async {
const defaultProfile = LunaProfile.DEFAULT_PROFILE;
await clear();
LunaBox.profiles.update(defaultProfile, LunaProfile());
LunaSeaDatabase.ENABLED_PROFILE.update(defaultProfile);
BIOSDatabase.DATABASE_CORRUPTION.update(databaseCorruption);
}
Future<void> clear() async {

View File

@@ -1,7 +1,8 @@
import 'package:lunasea/database/table.dart';
import 'package:lunasea/modules.dart';
enum BIOSDatabase<T> with LunaTableMixin<T> {
DATABASE_CORRUPTION<bool>(false),
BOOT_MODULE<LunaModule>(LunaModule.DASHBOARD),
SENTRY_LOGGING<bool>(true),
FIRST_BOOT<bool>(true);
@@ -12,4 +13,32 @@ enum BIOSDatabase<T> with LunaTableMixin<T> {
final T fallback;
const BIOSDatabase(this.fallback);
@override
dynamic export() {
BIOSDatabase db = this;
switch (db) {
case BIOSDatabase.BOOT_MODULE:
return BIOSDatabase.BOOT_MODULE.read().key;
default:
return super.export();
}
}
@override
void import(dynamic value) {
BIOSDatabase db = this;
dynamic result;
switch (db) {
case BIOSDatabase.BOOT_MODULE:
result = LunaModule.fromKey(value.toString());
break;
default:
result = value;
break;
}
return super.import(result);
}
}

View File

@@ -13,8 +13,7 @@ enum DashboardDatabase<T> with LunaTableMixin<T> {
CALENDAR_ENABLE_RADARR<bool>(true),
CALENDAR_ENABLE_SONARR<bool>(true),
CALENDAR_DAYS_PAST<int>(14),
CALENDAR_DAYS_FUTURE<int>(14),
CALENDAR_SHOW_PAST_DAYS<bool>(false);
CALENDAR_DAYS_FUTURE<int>(14);
@override
LunaTable get table => LunaTable.dashboard;

View File

@@ -4,13 +4,24 @@ import 'package:lunasea/core.dart';
extension ScrollControllerExtension on ScrollController {
static const _duration =
Duration(milliseconds: LunaUI.ANIMATION_SPEED_SCROLLING);
static const _curve = Curves.easeInOutQuart;
Future<void> animateToStart() async {
if (this.hasClients) {
this.animateTo(
0.00,
duration: _duration,
curve: Curves.easeInOutQuart,
curve: _curve,
);
}
}
Future<void> animateToOffset(double offset) async {
if (this.hasClients) {
return this.animateTo(
offset,
duration: _duration,
curve: _curve,
);
}
}

View File

@@ -11,37 +11,46 @@ import 'package:lunasea/system/cache/memory/memory_store.dart';
import 'package:lunasea/system/in_app_purchase/in_app_purchase.dart';
import 'package:lunasea/system/localization.dart';
import 'package:lunasea/system/network/network.dart';
import 'package:lunasea/system/recovery_mode/main.dart';
import 'package:lunasea/system/sentry.dart';
import 'package:lunasea/system/window_manager/window_manager.dart';
import 'package:lunasea/system/platform.dart';
/// LunaSea Entry Point: Initialize & Run Application
/// LunaSea Entry Point: Bootstrap & Run Application
///
/// Runs app in guarded zone to attempt to capture fatal (crashing) errors
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runZonedGuarded(
() async {
//LunaSea initialization
await LunaSentry().initialize();
await LunaDatabase().initialize();
LunaLogger().initialize();
if (LunaFirebase.isSupported) await LunaFirebase().initialize();
LunaTheme().initialize();
if (LunaWindowManager.isSupported) await LunaWindowManager().initialize();
if (LunaNetwork.isSupported) LunaNetwork().initialize();
if (LunaImageCache.isSupported) LunaImageCache().initialize();
LunaRouter().initialize();
if (LunaInAppPurchase.isSupported) LunaInAppPurchase().initialize();
await LunaLocalization().initialize();
await LunaMemoryStore().initialize();
// Run application
return runApp(const LunaBIOS());
try {
await bootstrap();
runApp(const LunaBIOS());
} catch (error) {
runApp(const LunaRecoveryMode());
}
},
(error, stack) => LunaLogger().critical(error, stack),
);
}
/// Bootstrap the core
///
Future<void> bootstrap() async {
await LunaSentry().initialize();
await LunaDatabase().initialize();
LunaLogger().initialize();
if (LunaFirebase.isSupported) await LunaFirebase().initialize();
LunaTheme().initialize();
if (LunaWindowManager.isSupported) await LunaWindowManager().initialize();
if (LunaNetwork.isSupported) LunaNetwork().initialize();
if (LunaImageCache.isSupported) LunaImageCache().initialize();
LunaRouter().initialize();
if (LunaInAppPurchase.isSupported) LunaInAppPurchase().initialize();
await LunaLocalization().initialize();
await LunaMemoryStore().initialize();
}
class LunaBIOS extends StatelessWidget {
const LunaBIOS({
Key? key,

View File

@@ -124,6 +124,7 @@ class API {
year: entry['year'] ?? 0,
runtime: entry['runtime'] ?? 0,
studio: entry['studio'] ?? LunaUI.TEXT_EMDASH,
releaseDate: release,
));
map[release] = day;
}

View File

@@ -14,6 +14,7 @@ class CalendarRadarrData extends CalendarData {
int year;
int runtime;
String studio;
DateTime releaseDate;
CalendarRadarrData({
required int id,
@@ -23,10 +24,14 @@ class CalendarRadarrData extends CalendarData {
required this.year,
required this.runtime,
required this.studio,
required this.releaseDate,
}) : super(id, title);
bool get hasReleased => DateTime.now().isAfter(releaseDate);
@override
List<TextSpan> get body {
final released = hasReleased;
return [
TextSpan(
children: [
@@ -37,11 +42,11 @@ class CalendarRadarrData extends CalendarData {
),
TextSpan(text: studio),
if (!hasFile)
const TextSpan(
text: 'Not Downloaded',
TextSpan(
text: released ? 'radarr.Missing'.tr() : 'radarr.Unreleased'.tr(),
style: TextStyle(
fontWeight: LunaUI.FONT_WEIGHT_BOLD,
color: LunaColours.red,
color: released ? LunaColours.red : LunaColours.blue,
),
),
if (hasFile)

View File

@@ -32,6 +32,7 @@ class CalendarSonarrData extends CalendarData {
@override
List<TextSpan> get body {
final released = hasAired;
return [
TextSpan(
children: [
@@ -49,10 +50,10 @@ class CalendarSonarrData extends CalendarData {
),
if (!hasFile)
TextSpan(
text: hasAired ? 'sonarr.Missing'.tr() : 'sonarr.Unaired'.tr(),
text: released ? 'sonarr.Missing'.tr() : 'sonarr.Unaired'.tr(),
style: TextStyle(
fontWeight: LunaUI.FONT_WEIGHT_BOLD,
color: hasAired ? LunaColours.red : LunaColours.blue,
color: released ? LunaColours.red : LunaColours.blue,
),
),
if (hasFile)

View File

@@ -1,8 +1,11 @@
import 'package:lunasea/database/tables/dashboard.dart';
import 'package:lunasea/extensions/datetime.dart';
import 'package:lunasea/modules/dashboard/core/adapters/calendar_starting_size.dart';
import 'package:lunasea/modules/dashboard/core/adapters/calendar_starting_type.dart';
import 'package:lunasea/modules/dashboard/core/api/api.dart';
import 'package:lunasea/modules/dashboard/core/api/data/abstract.dart';
import 'package:lunasea/state/state.dart';
import 'package:lunasea/vendor.dart';
class ModuleState extends LunaModuleState {
ModuleState() {
@@ -16,11 +19,19 @@ class ModuleState extends LunaModuleState {
resetUpcoming();
}
CalendarStartingType _calendarStartingType =
CalendarStartingType _calendarType =
DashboardDatabase.CALENDAR_STARTING_TYPE.read();
CalendarStartingType get calendarStartingType => _calendarStartingType;
set calendarStartingType(CalendarStartingType calendarStartingType) {
_calendarStartingType = calendarStartingType;
CalendarStartingType get calendarType => _calendarType;
set calendarType(CalendarStartingType calendarStartingType) {
_calendarType = calendarStartingType;
notifyListeners();
}
CalendarFormat _calendarFormat =
DashboardDatabase.CALENDAR_STARTING_SIZE.read().data;
CalendarFormat get calendarFormat => _calendarFormat;
set calendarFormat(CalendarFormat calendarFormat) {
_calendarFormat = calendarFormat;
notifyListeners();
}
@@ -31,10 +42,10 @@ class ModuleState extends LunaModuleState {
notifyListeners();
}
DateTime? _today;
DateTime? get today => _today;
DateTime _today = DateTime.now().floor();
DateTime get today => _today;
void resetToday() {
_today = DateTime.now();
_today = DateTime.now().floor();
notifyListeners();
}
@@ -44,4 +55,11 @@ class ModuleState extends LunaModuleState {
if (_api != null) _upcoming = _api!.getUpcoming(DateTime.now());
notifyListeners();
}
DateTime _selected = DateTime.now().floor();
DateTime get selected => _selected;
set selected(DateTime selected) {
_selected = selected;
notifyListeners();
}
}

View File

@@ -56,7 +56,7 @@ class _State extends State<CalendarPage>
snapshot.hasData) {
final events = snapshot.data!;
return Selector<ModuleState, CalendarStartingType>(
selector: (_, s) => s.calendarStartingType,
selector: (_, s) => s.calendarType,
builder: (context, type, _) {
if (type == CalendarStartingType.CALENDAR)
return CalendarView(events: events);

View File

@@ -5,7 +5,6 @@ import 'package:lunasea/database/box.dart';
import 'package:lunasea/database/tables/dashboard.dart';
import 'package:lunasea/extensions/datetime.dart';
import 'package:lunasea/modules/dashboard/core/adapters/calendar_starting_day.dart';
import 'package:lunasea/modules/dashboard/core/adapters/calendar_starting_size.dart';
import 'package:lunasea/modules/dashboard/core/api/data/abstract.dart';
import 'package:lunasea/modules/dashboard/core/api/data/lidarr.dart';
import 'package:lunasea/modules/dashboard/core/api/data/radarr.dart';
@@ -30,26 +29,11 @@ class CalendarView extends StatefulWidget {
class _State extends State<CalendarView> {
final double _calendarBulletSize = 8.0;
List<CalendarData> _selectedEvents = [];
late DateTime _selected;
late CalendarFormat _calendarFormat;
late final TextStyle dayStyle = _getTextStyle(LunaColours.white);
late final TextStyle outsideStyle = _getTextStyle(LunaColours.white70);
late final TextStyle unavailableStyle = _getTextStyle(LunaColours.white10);
late final TextStyle weekdayStyle = _getTextStyle(LunaColours.accent);
@override
void initState() {
super.initState();
final size = DashboardDatabase.CALENDAR_STARTING_SIZE.read();
_selected = context.read<ModuleState>().today!.floor();
_selectedEvents = widget.events[_selected] ?? [];
_calendarFormat = size.data;
}
TextStyle _getTextStyle(Color color) {
return TextStyle(
color: color,
@@ -60,11 +44,7 @@ class _State extends State<CalendarView> {
void _onDaySelected(DateTime selected, DateTime focused) {
HapticFeedback.selectionClick();
if (mounted)
setState(() {
_selected = selected.floor();
_selectedEvents = widget.events[selected.floor()] ?? [];
});
context.read<ModuleState>().selected = selected.floor();
}
@override
@@ -128,10 +108,10 @@ class _State extends State<CalendarView> {
DashboardDatabase.CALENDAR_STARTING_SIZE,
],
builder: (context, _) {
DateTime firstDay = context.watch<ModuleState>().today!.subtract(
DateTime firstDay = context.watch<ModuleState>().today.subtract(
Duration(days: DashboardDatabase.CALENDAR_DAYS_PAST.read()),
);
DateTime lastDay = context.watch<ModuleState>().today!.add(
DateTime lastDay = context.watch<ModuleState>().today.add(
Duration(days: DashboardDatabase.CALENDAR_DAYS_FUTURE.read()),
);
return SafeArea(
@@ -144,7 +124,7 @@ class _State extends State<CalendarView> {
),
rowHeight: 48.0,
rangeSelectionMode: RangeSelectionMode.disabled,
focusedDay: _selected,
focusedDay: context.watch<ModuleState>().selected,
firstDay: firstDay,
lastDay: lastDay,
//events: widget.events,
@@ -161,8 +141,9 @@ class _State extends State<CalendarView> {
)),
startingDayOfWeek:
DashboardDatabase.CALENDAR_STARTING_DAY.read().data,
selectedDayPredicate: (date) =>
date.floor() == _selected.floor(),
selectedDayPredicate: (date) {
return date.floor() == context.read<ModuleState>().selected;
},
calendarStyle: CalendarStyle(
markersMaxCount: 1,
isTodayHighlighted: true,
@@ -188,8 +169,9 @@ class _State extends State<CalendarView> {
markersAlignment: Alignment.bottomCenter,
todayTextStyle: dayStyle,
),
onFormatChanged: (format) =>
setState(() => _calendarFormat = format),
onFormatChanged: (format) {
context.read<ModuleState>().calendarFormat = format;
},
daysOfWeekStyle: DaysOfWeekStyle(
weekendStyle: weekdayStyle,
weekdayStyle: weekdayStyle,
@@ -198,7 +180,7 @@ class _State extends State<CalendarView> {
if (widget.events.isEmpty) return [];
return widget.events[date.floor()] ?? [];
},
calendarFormat: _calendarFormat,
calendarFormat: context.watch<ModuleState>().calendarFormat,
availableCalendarFormats: const {
CalendarFormat.month: 'Month',
CalendarFormat.twoWeeks: '2 Weeks',
@@ -246,7 +228,9 @@ class _State extends State<CalendarView> {
}
Widget _calendarList() {
if (_selectedEvents.isEmpty) {
final selected = context.read<ModuleState>().selected;
final events = widget.events[selected.floor()] ?? [];
if (events.isEmpty) {
return Expanded(
child: LunaListView(
controller: HomeNavigationBar.scrollControllers[1],
@@ -262,7 +246,7 @@ class _State extends State<CalendarView> {
return Expanded(
child: LunaListView(
controller: HomeNavigationBar.scrollControllers[1],
children: _selectedEvents.map(ContentBlock.new).toList(),
children: events.map(ContentBlock.new).toList(),
padding: MediaQuery.of(context).padding.copyWith(top: 0.0, bottom: 8.0),
),
);

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:lunasea/database/tables/dashboard.dart';
import 'package:lunasea/extensions/datetime.dart';
import 'package:lunasea/extensions/scroll_controller.dart';
import 'package:lunasea/vendor.dart';
import 'package:lunasea/widgets/ui.dart';
@@ -22,54 +21,80 @@ class ScheduleView extends StatefulWidget {
}
class _State extends State<ScheduleView> {
late DateTime _today;
@override
void initState() {
super.initState();
DateTime _floored = context.read<ModuleState>().today!.floor();
_today = _floored;
}
final _formatter = DateFormat('EEEE / MMMM dd, y');
@override
Widget build(BuildContext context) {
final controller = HomeNavigationBar.scrollControllers[1];
if (widget.events.isEmpty) {
return LunaListView(
controller: HomeNavigationBar.scrollControllers[1],
controller: controller,
children: [
LunaMessage.inList(text: 'dashboard.NoNewContent'.tr()),
],
);
}
return LunaListView(
controller: HomeNavigationBar.scrollControllers[1],
children: _buildSchedule().expand((e) => e).toList(),
final schedule = _buildSchedule();
Future.microtask(() => controller.animateToOffset(schedule.item2));
return LunaCustomScrollView(
controller: controller,
slivers: [
const SliverPadding(
padding: EdgeInsets.symmetric(vertical: LunaUI.MARGIN_SIZE_HALF),
),
...schedule.item1,
const SliverPadding(
padding: EdgeInsets.only(bottom: LunaUI.MARGIN_SIZE_HALF),
),
],
);
}
List<List<Widget>> _buildSchedule() {
List<List<Widget>> days = [];
Tuple2<List<Widget>, double> _buildSchedule() {
double offset = 0.0;
double offsetOfSelected = 0.0;
List<Widget> days = [];
List<DateTime> keys = widget.events.keys.toList();
keys.sort();
for (var key in keys) {
bool pastDays = DashboardDatabase.CALENDAR_SHOW_PAST_DAYS.read();
bool dayInFuture = key.isAfter(_today.subtract(const Duration(days: 1)));
bool hasEvents = widget.events[key]?.isNotEmpty ?? false;
if ((pastDays || dayInFuture) && hasEvents) days.add(_buildDay(key));
for (final key in keys) {
final selected = context.read<ModuleState>().selected;
if (selected.isAtSameMomentAs(key)) {
offsetOfSelected = offset;
}
final hasEvents = widget.events[key]?.isNotEmpty ?? false;
if (hasEvents) {
final built = _buildDay(key);
offset += built.item2;
days.addAll(built.item1);
}
}
return days;
return Tuple2(days, offsetOfSelected);
}
List<Widget> _buildDay(DateTime day) {
List<Widget> content = [];
Tuple2<List<Widget>, double> _buildDay(DateTime day) {
List<CalendarData> events = widget.events[day]!;
for (final event in events) content.add(ContentBlock(event));
return [
LunaHeader(text: DateFormat('EEEE / MMMM dd, y').format(day)),
...content,
final extent = LunaBlock.calculateItemExtent(3);
final offset = 39.30 + events.length * extent;
final slivers = [
SliverToBoxAdapter(
child: LunaHeader(text: _formatter.format(day)),
),
SliverFixedExtentList(
delegate: SliverChildBuilderDelegate(
(_, index) => ContentBlock(events[index]),
childCount: events.length,
),
itemExtent: extent,
),
];
return Tuple2(slivers, offset);
}
}

View File

@@ -45,7 +45,7 @@ class _State extends State<SwitchViewAction> with LunaLoadCallbackMixin {
@override
Widget build(BuildContext context) {
return Selector<ModuleState, CalendarStartingType>(
selector: (_, state) => state.calendarStartingType,
selector: (_, state) => state.calendarType,
builder: (context, view, _) {
if (_showButton) {
return LunaIconButton.appBar(
@@ -53,9 +53,9 @@ class _State extends State<SwitchViewAction> with LunaLoadCallbackMixin {
onPressed: () {
final state = context.read<ModuleState>();
if (view == CalendarStartingType.CALENDAR)
state.calendarStartingType = CalendarStartingType.SCHEDULE;
state.calendarType = CalendarStartingType.SCHEDULE;
else
state.calendarStartingType = CalendarStartingType.CALENDAR;
state.calendarType = CalendarStartingType.CALENDAR;
},
);
}

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:lunasea/extensions/string/links.dart';
import 'package:lunasea/modules/lidarr/core/api.dart';
import 'package:lunasea/utils/links.dart';
import 'package:lunasea/widgets/ui.dart';
class LinksSheet extends LunaBottomModalSheet {
@@ -38,6 +39,12 @@ class LinksSheet extends LunaBottomModalSheet {
leading: const LunaIconButton(icon: LunaIcons.LASTFM),
onTap: artist.lastfmURI!.openLink,
),
LunaBlock(
title: 'MusicBrainz',
leading: const LunaIconButton(icon: LunaIcons.MUSICBRAINZ),
onTap:
LunaLinkedContent.musicBrainz(artist.foreignArtistID)!.openLink,
),
],
);
}

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/extensions/double/time.dart';
import 'package:lunasea/extensions/int/bytes.dart';
import 'package:lunasea/extensions/string/links.dart';
import 'package:lunasea/extensions/string/string.dart';
import 'package:lunasea/modules/lidarr.dart';
import 'package:lunasea/router/router.dart';
@@ -126,6 +127,13 @@ class _State extends State<LidarrReleasesTile> {
onTap: _startDownload,
loadingState: _downloadState,
),
if (widget.release.infoUrl.isNotEmpty)
LunaButton.text(
text: 'Indexer',
icon: Icons.info_outline_rounded,
color: LunaColours.blue,
onTap: widget.release.infoUrl.openLink,
),
if (!widget.release.approved)
LunaButton.text(
text: 'Rejected',

View File

@@ -166,13 +166,12 @@ class _State extends State<NZBGetRoute> {
'nzb',
]);
if (_file != null) {
String _name = _file.path.substring(_file.path.lastIndexOf('/') + 1);
if (_file.data.isNotEmpty) {
await _api.uploadFile(_file.data, _name).then((value) {
await _api.uploadFile(_file.data, _file.name).then((value) {
_refreshKeys[0]?.currentState?.show();
showLunaSuccessSnackBar(
title: 'Uploaded NZB (File)',
message: _name,
message: _file.name,
);
});
} else {

View File

@@ -260,6 +260,7 @@ class RadarrAPIHelper {
Future<bool> updateMovie({
required BuildContext context,
required RadarrMovie movie,
required bool moveFiles,
bool showSnackbar = true,
}) async {
if (context.read<RadarrState>().enabled) {
@@ -267,7 +268,7 @@ class RadarrAPIHelper {
.read<RadarrState>()
.api!
.movie
.update(movie: movie)
.update(movie: movie, moveFiles: moveFiles)
.then((_) async {
return await context
.read<RadarrState>()

View File

@@ -702,4 +702,31 @@ class RadarrDialogs {
contentPadding: LunaDialog.listDialogContentPadding(),
);
}
Future<bool> moveFiles() async {
bool _flag = false;
void _setValues(bool flag) {
_flag = flag;
Navigator.of(LunaState.context, rootNavigator: true).pop();
}
await LunaDialog.dialog(
context: LunaState.context,
title: 'radarr.MoveFiles'.tr(),
contentPadding: LunaDialog.textDialogContentPadding(),
cancelButtonText: 'lunasea.No'.tr(),
buttons: [
LunaDialog.button(
text: 'lunasea.Yes'.tr(),
onPressed: () => _setValues(true),
),
],
content: [
LunaDialog.textContent(text: 'radarr.MoveFilesDescription'.tr()),
],
);
return _flag;
}
}

View File

@@ -24,19 +24,22 @@ class RadarrEditMovieActionBar extends StatelessWidget {
}
Future<void> _updateOnTap(BuildContext context) async {
if (context.read<RadarrMoviesEditState>().canExecuteAction) {
context.read<RadarrMoviesEditState>().state = LunaLoadingState.ACTIVE;
if (context.read<RadarrMoviesEditState>().movie != null) {
RadarrMovie movie = context
.read<RadarrMoviesEditState>()
.movie!
.updateEdits(context.read<RadarrMoviesEditState>());
bool result = await RadarrAPIHelper().updateMovie(
context: context,
movie: movie,
);
if (result) LunaRouter().popSafely();
final state = context.read<RadarrMoviesEditState>();
state.state = LunaLoadingState.ACTIVE;
if (state.canExecuteAction && state.movie != null) {
bool moveFiles = false;
if (state.path != state.movie?.path) {
moveFiles = await RadarrDialogs().moveFiles();
}
final movie = state.movie!.updateEdits(state);
bool result = await RadarrAPIHelper().updateMovie(
context: context,
movie: movie,
moveFiles: moveFiles,
);
if (result) LunaRouter().popSafely();
}
}
}

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/extensions/string/links.dart';
import 'package:lunasea/extensions/string/string.dart';
import 'package:lunasea/modules/radarr.dart';
@@ -118,6 +119,13 @@ class _State extends State<RadarrReleasesTile> {
onTap: _startDownload,
loadingState: _downloadState,
),
if (widget.release.infoUrl?.isNotEmpty ?? false)
LunaButton.text(
text: 'Indexer',
icon: Icons.info_outline_rounded,
color: LunaColours.blue,
onTap: widget.release.infoUrl!.openLink,
),
if (widget.release.rejected!)
LunaButton.text(
text: 'Rejected',

View File

@@ -219,13 +219,12 @@ class _State extends State<SABnzbdRoute> {
'gz',
]);
if (_file != null) {
String _name = _file.path.substring(_file.path.lastIndexOf('/') + 1);
if (_file.data.isNotEmpty) {
await _api.uploadFile(_file.data, _name).then((value) {
await _api.uploadFile(_file.data, _file.name).then((value) {
_refreshKeys[0]?.currentState?.show();
showLunaSuccessSnackBar(
title: 'Uploaded NZB (File)',
message: _name,
message: _file.name,
);
});
} else {

View File

@@ -2,7 +2,9 @@ import 'package:email_validator/email_validator.dart';
import 'package:flutter/material.dart';
import 'package:lunasea/database/tables/lunasea.dart';
import 'package:lunasea/firebase/types.dart';
import 'package:lunasea/modules.dart';
import 'package:lunasea/modules/settings/core/types/header.dart';
import 'package:lunasea/state/state.dart';
import 'package:lunasea/system/localization.dart';
import 'package:lunasea/vendor.dart';
import 'package:lunasea/widgets/ui.dart';
@@ -1353,4 +1355,41 @@ class SettingsDialogs {
contentPadding: LunaDialog.textDialogContentPadding(),
);
}
Future<Tuple2<bool, LunaModule?>> selectBootModule() async {
final context = LunaState.context;
bool _flag = false;
LunaModule? _module;
void _setValues(LunaModule module) {
_flag = true;
_module = module;
Navigator.of(context).pop();
}
final modules = LunaModule.values.filter((module) {
final enabled = module.isEnabled;
final featureFlag = module.featureFlag;
final homeRoute = module.homeRoute != null;
return homeRoute && enabled && featureFlag;
}).toList();
await LunaDialog.dialog(
context: context,
title: 'settings.BootModule'.tr(),
content: List.generate(
modules.length,
(index) => LunaDialog.tile(
text: modules[index].title,
icon: modules[index].icon,
iconColor: modules[index].color,
onTap: () => _setValues(modules[index]),
),
),
contentPadding: LunaDialog.listDialogContentPadding(),
);
return Tuple2(_flag, _module);
}
}

View File

@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/settings.dart';
import 'package:lunasea/router/routes/settings.dart';
import 'package:lunasea/system/network/network.dart';
import 'package:lunasea/system/quick_actions/quick_actions.dart';
import 'package:lunasea/utils/profile_tools.dart';
@@ -73,10 +72,10 @@ class _State extends State<ConfigurationRoute> with LunaScrollControllerMixin {
controller: scrollController,
children: [
LunaBlock(
title: 'settings.Appearance'.tr(),
body: [TextSpan(text: 'settings.AppearanceDescription'.tr())],
title: 'settings.General'.tr(),
body: [TextSpan(text: 'settings.GeneralDescription'.tr())],
trailing: const LunaIconButton(icon: Icons.brush_rounded),
onTap: SettingsRoutes.CONFIGURATION_APPEARANCE.go,
onTap: SettingsRoutes.CONFIGURATION_GENERAL.go,
),
LunaBlock(
title: 'settings.Drawer'.tr(),
@@ -84,19 +83,6 @@ class _State extends State<ConfigurationRoute> with LunaScrollControllerMixin {
trailing: const LunaIconButton(icon: Icons.menu_rounded),
onTap: SettingsRoutes.CONFIGURATION_DRAWER.go,
),
LunaBlock(
title: 'settings.Localization'.tr(),
body: [TextSpan(text: 'settings.LocalizationDescription'.tr())],
trailing: const LunaIconButton(icon: Icons.translate_rounded),
onTap: SettingsRoutes.CONFIGURATION_LOCALIZATION.go,
),
if (LunaNetwork.isSupported)
LunaBlock(
title: 'settings.Network'.tr(),
body: [TextSpan(text: 'settings.NetworkDescription'.tr())],
trailing: const LunaIconButton(icon: Icons.network_check_rounded),
onTap: SettingsRoutes.CONFIGURATION_NETWORK.go,
),
if (LunaQuickActions.isSupported)
LunaBlock(
title: 'settings.QuickActions'.tr(),

View File

@@ -1,104 +0,0 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/settings.dart';
class ConfigurationAppearanceRoute extends StatefulWidget {
const ConfigurationAppearanceRoute({
Key? key,
}) : super(key: key);
@override
State<ConfigurationAppearanceRoute> createState() => _State();
}
class _State extends State<ConfigurationAppearanceRoute>
with LunaScrollControllerMixin {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
body: _body(),
);
}
Widget _appBar() {
return LunaAppBar(
title: 'settings.Appearance'.tr(),
scrollControllers: [scrollController],
);
}
Widget _body() {
return LunaListView(
controller: scrollController,
children: [
_amoledTheme(),
_amoledThemeBorders(),
_imageBackgroundOpacity(),
],
);
}
Widget _amoledTheme() {
const _db = LunaSeaDatabase.THEME_AMOLED;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'settings.AmoledTheme'.tr(),
body: [
TextSpan(text: 'settings.AmoledThemeDescription'.tr()),
],
trailing: LunaSwitch(
value: _db.read(),
onChanged: (value) {
_db.update(value);
LunaTheme().initialize();
},
),
),
);
}
Widget _amoledThemeBorders() {
return LunaBox.lunasea.listenableBuilder(
selectItems: [
LunaSeaDatabase.THEME_AMOLED_BORDER,
LunaSeaDatabase.THEME_AMOLED,
],
builder: (context, _) => LunaBlock(
title: 'settings.AmoledThemeBorders'.tr(),
body: [
TextSpan(text: 'settings.AmoledThemeBordersDescription'.tr()),
],
trailing: LunaSwitch(
value: LunaSeaDatabase.THEME_AMOLED_BORDER.read(),
onChanged: LunaSeaDatabase.THEME_AMOLED.read()
? LunaSeaDatabase.THEME_AMOLED_BORDER.update
: null,
),
),
);
}
Widget _imageBackgroundOpacity() {
const _db = LunaSeaDatabase.THEME_IMAGE_BACKGROUND_OPACITY;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'settings.BackgroundImageOpacity'.tr(),
body: [
TextSpan(
text: _db.read() == 0 ? 'lunasea.Disabled'.tr() : '${_db.read()}%',
),
],
trailing: const LunaIconButton.arrow(),
onTap: () async {
Tuple2<bool, int> result =
await SettingsDialogs().changeBackgroundImageOpacity(context);
if (result.item1) _db.update(result.item2);
},
),
);
}
}

View File

@@ -45,7 +45,6 @@ class _State extends State<ConfigurationDashboardCalendarRoute>
children: [
_futureDays(),
_pastDays(),
_pastDaysInSchedule(),
LunaDivider(),
_startingDay(),
_startingSize(),
@@ -58,19 +57,6 @@ class _State extends State<ConfigurationDashboardCalendarRoute>
);
}
Widget _pastDaysInSchedule() {
const _db = DashboardDatabase.CALENDAR_SHOW_PAST_DAYS;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'settings.PastDaysInScheduleView'.tr(),
trailing: LunaSwitch(
value: _db.read(),
onChanged: _db.update,
),
),
);
}
Widget _pastDays() {
const _db = DashboardDatabase.CALENDAR_DAYS_PAST;
return _db.listenableBuilder(

View File

@@ -0,0 +1,202 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/database/tables/bios.dart';
import 'package:lunasea/modules/settings.dart';
import 'package:lunasea/system/localization.dart';
import 'package:lunasea/system/network/network.dart';
class ConfigurationGeneralRoute extends StatefulWidget {
const ConfigurationGeneralRoute({
Key? key,
}) : super(key: key);
@override
State createState() => _State();
}
class _State extends State<ConfigurationGeneralRoute>
with LunaScrollControllerMixin {
final _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar(),
body: _body(),
);
}
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'settings.General'.tr(),
scrollControllers: [scrollController],
);
}
Widget _body() {
return LunaListView(
controller: scrollController,
children: [
..._appearance(),
..._localization(),
..._modules(),
if (LunaNetwork.isSupported) ..._network(),
],
);
}
List<Widget> _appearance() {
return [
LunaHeader(text: 'settings.Appearance'.tr()),
_imageBackgroundOpacity(),
_amoledTheme(),
_amoledThemeBorders(),
];
}
List<Widget> _localization() {
return [
LunaHeader(text: 'settings.Localization'.tr()),
_language(),
_use24HourTime(),
];
}
List<Widget> _modules() {
return [
LunaHeader(text: 'dashboard.Modules'.tr()),
_bootModule(),
];
}
List<Widget> _network() {
return [
LunaHeader(text: 'settings.Network'.tr()),
_useTLSValidation(),
];
}
Widget _amoledTheme() {
const _db = LunaSeaDatabase.THEME_AMOLED;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'settings.AmoledTheme'.tr(),
body: [
TextSpan(text: 'settings.AmoledThemeDescription'.tr()),
],
trailing: LunaSwitch(
value: _db.read(),
onChanged: (value) {
_db.update(value);
LunaTheme().initialize();
},
),
),
);
}
Widget _amoledThemeBorders() {
return LunaBox.lunasea.listenableBuilder(
selectItems: [
LunaSeaDatabase.THEME_AMOLED_BORDER,
LunaSeaDatabase.THEME_AMOLED,
],
builder: (context, _) => LunaBlock(
title: 'settings.AmoledThemeBorders'.tr(),
body: [
TextSpan(text: 'settings.AmoledThemeBordersDescription'.tr()),
],
trailing: LunaSwitch(
value: LunaSeaDatabase.THEME_AMOLED_BORDER.read(),
onChanged: LunaSeaDatabase.THEME_AMOLED.read()
? LunaSeaDatabase.THEME_AMOLED_BORDER.update
: null,
),
),
);
}
Widget _imageBackgroundOpacity() {
const _db = LunaSeaDatabase.THEME_IMAGE_BACKGROUND_OPACITY;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'settings.BackgroundImageOpacity'.tr(),
body: [
TextSpan(
text: _db.read() == 0 ? 'lunasea.Disabled'.tr() : '${_db.read()}%',
),
],
trailing: const LunaIconButton.arrow(),
onTap: () async {
Tuple2<bool, int> result =
await SettingsDialogs().changeBackgroundImageOpacity(context);
if (result.item1) _db.update(result.item2);
},
),
);
}
Widget _useTLSValidation() {
const _db = LunaSeaDatabase.NETWORKING_TLS_VALIDATION;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'settings.TLSCertificateValidation'.tr(),
body: [
TextSpan(text: 'settings.TLSCertificateValidationDescription'.tr()),
],
trailing: LunaSwitch(
value: _db.read(),
onChanged: (data) {
_db.update(data);
if (LunaNetwork.isSupported) LunaNetwork().initialize();
},
),
),
);
}
Widget _language() {
String? _language = LunaLanguage.fromLocale(context.locale)?.name;
return LunaBlock(
title: 'settings.Language'.tr(),
body: [TextSpan(text: _language ?? LunaUI.TEXT_EMDASH)],
trailing: const LunaIconButton(icon: Icons.language_rounded),
onTap: () async {
final result = await SettingsDialogs().changeLanguage(context);
if (result.item1) result.item2!.use();
},
);
}
Widget _use24HourTime() {
const _db = LunaSeaDatabase.USE_24_HOUR_TIME;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'settings.Use24HourTime'.tr(),
body: [TextSpan(text: 'settings.Use24HourTimeDescription'.tr())],
trailing: LunaSwitch(
value: _db.read(),
onChanged: _db.update,
),
),
);
}
Widget _bootModule() {
const _db = BIOSDatabase.BOOT_MODULE;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'settings.BootModule'.tr(),
body: [TextSpan(text: _db.read().title)],
trailing: LunaIconButton(icon: _db.read().icon),
onTap: () async {
final result = await SettingsDialogs().selectBootModule();
if (result.item1) {
BIOSDatabase.BOOT_MODULE.update(result.item2!);
}
},
),
);
}
}

View File

@@ -1,71 +0,0 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/settings.dart';
import 'package:lunasea/system/localization.dart';
class ConfigurationLocalizationRoute extends StatefulWidget {
const ConfigurationLocalizationRoute({
Key? key,
}) : super(key: key);
@override
State<ConfigurationLocalizationRoute> createState() => _State();
}
class _State extends State<ConfigurationLocalizationRoute>
with LunaScrollControllerMixin {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
body: _body(),
);
}
Widget _appBar() {
return LunaAppBar(
title: 'settings.Localization'.tr(),
scrollControllers: [scrollController],
);
}
Widget _body() {
return LunaListView(
controller: scrollController,
children: [
_language(),
_use24HourTime(),
],
);
}
Widget _language() {
String? _language = LunaLanguage.fromLocale(context.locale)?.name;
return LunaBlock(
title: 'settings.Language'.tr(),
body: [TextSpan(text: _language ?? LunaUI.TEXT_EMDASH)],
trailing: const LunaIconButton(icon: Icons.language_rounded),
onTap: () async {
final result = await SettingsDialogs().changeLanguage(context);
if (result.item1) result.item2!.use();
},
);
}
Widget _use24HourTime() {
const _db = LunaSeaDatabase.USE_24_HOUR_TIME;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'settings.Use24HourTime'.tr(),
body: [TextSpan(text: 'settings.Use24HourTimeDescription'.tr())],
trailing: LunaSwitch(
value: _db.read(),
onChanged: _db.update,
),
),
);
}
}

View File

@@ -1,61 +0,0 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/system/network/network.dart';
class ConfigurationNetworkRoute extends StatefulWidget {
const ConfigurationNetworkRoute({
Key? key,
}) : super(key: key);
@override
State<ConfigurationNetworkRoute> createState() => _State();
}
class _State extends State<ConfigurationNetworkRoute>
with LunaScrollControllerMixin {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
body: _body(),
);
}
Widget _appBar() {
return LunaAppBar(
title: 'settings.Network'.tr(),
scrollControllers: [scrollController],
);
}
Widget _body() {
return LunaListView(
controller: scrollController,
children: [
_useTLSValidation(),
],
);
}
Widget _useTLSValidation() {
const _db = LunaSeaDatabase.NETWORKING_TLS_VALIDATION;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'settings.TLSCertificateValidation'.tr(),
body: [
TextSpan(text: 'settings.TLSCertificateValidationDescription'.tr()),
],
trailing: LunaSwitch(
value: _db.read(),
onChanged: (data) {
_db.update(data);
if (LunaNetwork.isSupported) LunaNetwork().initialize();
},
),
),
);
}
}

View File

@@ -66,7 +66,7 @@ class _State extends State<SystemRoute> with LunaScrollControllerMixin {
Widget _clearImageCache() {
return LunaBlock(
title: 'Clear Image Cache',
body: const [TextSpan(text: 'Clear cached images from the disk')],
body: const [TextSpan(text: 'Clear Cached Images From the Disk')],
trailing: const LunaIconButton(icon: Icons.image_not_supported_rounded),
onTap: () async {
bool result = await SettingsDialogs().clearImageCache(context);

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/extensions/string/links.dart';
import 'package:lunasea/extensions/string/string.dart';
import 'package:lunasea/modules/sonarr.dart';
@@ -151,6 +152,13 @@ class _State extends State<SonarrReleasesTile> {
onTap: _startDownload,
loadingState: _downloadState,
),
if (widget.release.infoUrl?.isNotEmpty ?? false)
LunaButton.text(
text: 'Indexer',
icon: Icons.info_outline_rounded,
color: LunaColours.blue,
onTap: widget.release.infoUrl!.openLink,
),
if (widget.release.rejected!)
LunaButton.text(
text: 'sonarr.Rejected'.tr(),

View File

@@ -1,4 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:lunasea/system/logger.dart';
import 'package:lunasea/system/sentry.dart';
import 'package:lunasea/widgets/pages/error_route.dart';
@@ -7,10 +7,11 @@ import 'package:lunasea/vendor.dart';
class LunaRouter {
static late GoRouter router;
static GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
void initialize() {
router = GoRouter(
debugLogDiagnostics: kDebugMode,
navigatorKey: navigator,
errorBuilder: (_, state) => ErrorRoutePage(exception: state.error),
initialLocation: LunaRoutes.initialLocation,
observers: [LunaSentry().navigatorObserver],
@@ -23,10 +24,10 @@ class LunaRouter {
}
void popToRootRoute() {
if (router.navigator == null) {
if (navigator.currentState == null) {
LunaLogger().warning('Not observing any navigation navigators, skipping');
return;
}
router.navigator!.popUntil((route) => route.isFirst);
navigator.currentState!.popUntil((route) => route.isFirst);
}
}

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:lunasea/database/tables/bios.dart';
import 'package:lunasea/modules.dart';
import 'package:lunasea/router/routes.dart';
import 'package:lunasea/router/routes/dashboard.dart';
@@ -25,7 +26,9 @@ enum BIOSRoutes with LunaRoutesMixin {
case BIOSRoutes.HOME:
return redirect(redirect: (context, _) {
LunaOS().boot(context);
return DashboardRoutes.HOME.path;
final fallback = DashboardRoutes.HOME.path;
return BIOSDatabase.BOOT_MODULE.read().homeRoute ?? fallback;
});
}
}

View File

@@ -5,7 +5,7 @@ import 'package:lunasea/modules/settings/routes/account/pages/password_reset.dar
import 'package:lunasea/modules/settings/routes/account/pages/settings.dart';
import 'package:lunasea/modules/settings/routes/account/route.dart';
import 'package:lunasea/modules/settings/routes/configuration/route.dart';
import 'package:lunasea/modules/settings/routes/configuration_appearance/route.dart';
import 'package:lunasea/modules/settings/routes/configuration_general/route.dart';
import 'package:lunasea/modules/settings/routes/configuration_dashboard/pages/calendar_settings.dart';
import 'package:lunasea/modules/settings/routes/configuration_dashboard/pages/default_pages.dart';
import 'package:lunasea/modules/settings/routes/configuration_dashboard/route.dart';
@@ -17,8 +17,6 @@ import 'package:lunasea/modules/settings/routes/configuration_lidarr/pages/conne
import 'package:lunasea/modules/settings/routes/configuration_lidarr/pages/default_pages.dart';
import 'package:lunasea/modules/settings/routes/configuration_lidarr/pages/headers.dart';
import 'package:lunasea/modules/settings/routes/configuration_lidarr/route.dart';
import 'package:lunasea/modules/settings/routes/configuration_localization/route.dart';
import 'package:lunasea/modules/settings/routes/configuration_network/route.dart';
import 'package:lunasea/modules/settings/routes/configuration_nzbget/pages/connection_details.dart';
import 'package:lunasea/modules/settings/routes/configuration_nzbget/pages/default_pages.dart';
import 'package:lunasea/modules/settings/routes/configuration_nzbget/pages/headers.dart';
@@ -72,7 +70,7 @@ enum SettingsRoutes with LunaRoutesMixin {
ACCOUNT_PASSWORD_RESET('password_reset'),
ACCOUNT_SETTINGS('settings'),
CONFIGURATION('configuration'),
CONFIGURATION_APPEARANCE('appearance'),
CONFIGURATION_GENERAL('general'),
CONFIGURATION_DASHBOARD('dashboard'),
CONFIGURATION_DASHBOARD_CALENDAR('calendar'),
CONFIGURATION_DASHBOARD_DEFAULT_PAGES('default_pages'),
@@ -84,8 +82,6 @@ enum SettingsRoutes with LunaRoutesMixin {
CONFIGURATION_LIDARR_CONNECTION_DETAILS('connection_details'),
CONFIGURATION_LIDARR_CONNECTION_DETAILS_HEADERS('headers'),
CONFIGURATION_LIDARR_DEFAULT_PAGES('default_pages'),
CONFIGURATION_LOCALIZATION('localization'),
CONFIGURATION_NETWORK('network'),
CONFIGURATION_NZBGET('nzbget'),
CONFIGURATION_NZBGET_CONNECTION_DETAILS('connection_details'),
CONFIGURATION_NZBGET_CONNECTION_DETAILS_HEADERS('headers'),
@@ -153,8 +149,8 @@ enum SettingsRoutes with LunaRoutesMixin {
return route(widget: const AccountSettingsRoute());
case SettingsRoutes.CONFIGURATION:
return route(widget: const ConfigurationRoute());
case SettingsRoutes.CONFIGURATION_APPEARANCE:
return route(widget: const ConfigurationAppearanceRoute());
case SettingsRoutes.CONFIGURATION_GENERAL:
return route(widget: const ConfigurationGeneralRoute());
case SettingsRoutes.CONFIGURATION_DASHBOARD:
return route(widget: const ConfigurationDashboardRoute());
case SettingsRoutes.CONFIGURATION_DASHBOARD_CALENDAR:
@@ -182,10 +178,6 @@ enum SettingsRoutes with LunaRoutesMixin {
);
case SettingsRoutes.CONFIGURATION_LIDARR_DEFAULT_PAGES:
return route(widget: const ConfigurationLidarrDefaultPagesRoute());
case SettingsRoutes.CONFIGURATION_LOCALIZATION:
return route(widget: const ConfigurationLocalizationRoute());
case SettingsRoutes.CONFIGURATION_NETWORK:
return route(widget: const ConfigurationNetworkRoute());
case SettingsRoutes.CONFIGURATION_NZBGET:
return route(widget: const ConfigurationNZBGetRoute());
case SettingsRoutes.CONFIGURATION_NZBGET_CONNECTION_DETAILS:
@@ -324,13 +316,11 @@ enum SettingsRoutes with LunaRoutesMixin {
];
case SettingsRoutes.CONFIGURATION:
return [
SettingsRoutes.CONFIGURATION_APPEARANCE.routes,
SettingsRoutes.CONFIGURATION_GENERAL.routes,
SettingsRoutes.CONFIGURATION_DASHBOARD.routes,
SettingsRoutes.CONFIGURATION_DRAWER.routes,
SettingsRoutes.CONFIGURATION_EXTERNAL_MODULES.routes,
SettingsRoutes.CONFIGURATION_LIDARR.routes,
SettingsRoutes.CONFIGURATION_LOCALIZATION.routes,
SettingsRoutes.CONFIGURATION_NETWORK.routes,
SettingsRoutes.CONFIGURATION_NZBGET.routes,
SettingsRoutes.CONFIGURATION_OVERSEERR.routes,
SettingsRoutes.CONFIGURATION_QUICK_ACTIONS.routes,

View File

@@ -19,7 +19,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart' show ProviderScope;
class LunaState {
LunaState._();
static BuildContext get context => LunaRouter.router.navigator!.context;
static BuildContext get context => LunaRouter.navigator.currentContext!;
/// Calls `.reset()` on all states which extend [LunaModuleState].
static void reset([BuildContext? context]) {

View File

@@ -6,7 +6,6 @@ import 'package:lunasea/system/build.dart';
import 'package:lunasea/system/localization.dart';
import 'package:lunasea/system/quick_actions/quick_actions.dart';
import 'package:lunasea/widgets/sheets/changelog/sheet.dart';
import 'package:lunasea/widgets/sheets/database_corruption/sheet.dart';
class LunaOS {
Future<void> boot(BuildContext context) async {
@@ -33,11 +32,6 @@ class LunaOS {
final isLatest = LunaBuild().isLatestBuildVersion();
final firstBoot = BIOSDatabase.FIRST_BOOT.read();
if (BIOSDatabase.DATABASE_CORRUPTION.read()) {
DatabaseCorruptionSheet().show();
BIOSDatabase.DATABASE_CORRUPTION.update(false);
}
if (!firstBoot && !isLatest.item1) {
ChangelogSheet().show();
}

View File

@@ -1,11 +1,11 @@
class LunaFile {
String path;
String name;
List<int> data;
String name;
String? path;
LunaFile({
required this.path,
required this.name,
required this.data,
required this.name,
this.path,
});
}

View File

@@ -1,6 +1,61 @@
// ignore: always_use_package_imports
import '../filesystem.dart';
// ignore: avoid_web_libraries_in_flutter
import 'dart:html';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:lunasea/system/filesystem/file.dart';
import 'package:lunasea/system/filesystem/filesystem.dart';
import 'package:lunasea/system/logger.dart';
import 'package:lunasea/vendor.dart';
import 'package:lunasea/widgets/ui.dart';
bool isPlatformSupported() => false;
LunaFileSystem getFileSystem() =>
throw UnsupportedError('LunaFileSystem unsupported');
bool isPlatformSupported() => true;
LunaFileSystem getFileSystem() {
if (isPlatformSupported()) return _Web();
throw UnsupportedError('LunaFileSystem unsupported');
}
class _Web implements LunaFileSystem {
@override
Future<void> nuke() async {}
@override
Future<bool> save(BuildContext context, String name, List<int> data) async {
try {
final blob = Blob([utf8.decode(data)]);
final anchor = AnchorElement(href: Url.createObjectUrlFromBlob(blob));
anchor.setAttribute('download', name);
anchor.click();
return true;
} catch (error, stack) {
LunaLogger().error('Failed to save to filesystem', error, stack);
rethrow;
}
}
@override
Future<LunaFile?> read(BuildContext context, List<String> extensions) async {
try {
final result = await FilePicker.platform.pickFiles(withData: true);
if (result?.files.isNotEmpty ?? false) {
String? _ext = result!.files[0].extension;
if (LunaFileSystem.isValidExtension(extensions, _ext)) {
return LunaFile(
name: result.files[0].name,
data: result.files[0].bytes!,
);
} else {
showLunaErrorSnackBar(
title: 'lunasea.InvalidFileTypeSelected'.tr(),
message: extensions.map((s) => '.$s').join(', '),
);
}
}
return null;
} catch (error, stack) {
LunaLogger().error('Failed to read from filesystem', error, stack);
rethrow;
}
}
}

View File

@@ -98,8 +98,8 @@ class _Mobile extends _Shared {
Rect? rect;
if (box != null) rect = box.localToGlobal(Offset.zero) & box.size;
ShareResult result = await Share.shareFilesWithResult(
[path],
ShareResult result = await Share.shareXFiles(
[XFile(path)],
sharePositionOrigin: rect,
);
switch (result.status) {

View File

@@ -0,0 +1,123 @@
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
abstract class RecoveryActionTile extends StatelessWidget {
final String title;
final String description;
final bool showConfirmDialog;
const RecoveryActionTile({
required this.title,
required this.description,
this.showConfirmDialog = false,
super.key,
});
@override
Widget build(BuildContext context) {
return ListTile(
title: Text(title),
subtitle: Text(description),
onTap: () async => _action(context),
);
}
Future<void> _action(BuildContext context) async {
// ignore: invalid_use_of_visible_for_testing_member
Hive.resetAdapters();
await Hive.close();
try {
if (showConfirmDialog) {
final execute = await confirm(context);
if (execute) {
await action(context);
success(context);
}
} else {
await action(context);
success(context);
}
} catch (error, stack) {
failure(context, error, stack);
}
}
Future<void> action(BuildContext context);
void success(BuildContext context) {
showDialog(
context: context,
builder: (context) => const SimpleDialog(
title: Text('Success'),
children: [
Text('Action completed successfully.'),
],
contentPadding: EdgeInsets.only(
left: 24.0,
right: 24.0,
top: 12.0,
bottom: 24.0,
),
),
);
}
void failure(BuildContext context, dynamic error, StackTrace stack) {
showDialog(
context: context,
builder: (context) => SimpleDialog(
title: const Text('Error'),
children: [
Text(error.toString()),
Text(stack.toString()),
],
contentPadding: const EdgeInsets.symmetric(
horizontal: 24.0,
vertical: 12.0,
),
),
);
}
Future<bool> confirm(BuildContext context) async {
bool result = false;
await showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('Are You Sure?'),
content: RichText(
text: TextSpan(
children: [
const TextSpan(text: 'Are you sure you want to '),
TextSpan(text: description.toLowerCase()),
const TextSpan(text: '?'),
],
),
),
actions: [
TextButton(
onPressed: Navigator.of(context).pop,
child: const Text(
'Cancel',
style: TextStyle(color: Colors.white),
),
),
TextButton(
onPressed: () {
result = true;
Navigator.of(context).pop();
},
child: const Text(
'Confirm',
style: TextStyle(color: Colors.red),
),
)
],
),
);
return result;
}
}

View File

@@ -0,0 +1,16 @@
import 'package:flutter/material.dart';
import 'package:lunasea/main.dart';
import 'package:lunasea/system/recovery_mode/action_tile.dart';
class BootstrapTile extends RecoveryActionTile {
const BootstrapTile({
super.key,
super.title = 'Bootstrap LunaSea',
super.description = 'Run the bootstrap process and show any errors',
});
@override
Future<void> action(BuildContext context) async {
await bootstrap();
}
}

View File

@@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
import 'package:lunasea/database/database.dart';
import 'package:lunasea/system/recovery_mode/action_tile.dart';
class ClearDatabaseTile extends RecoveryActionTile {
const ClearDatabaseTile({
super.key,
super.title = 'Clear Database',
super.description = 'Clear all configured settings and modules',
super.showConfirmDialog = true,
});
@override
Future<void> action(BuildContext context) async {
await LunaDatabase().nuke();
}
}

View File

@@ -0,0 +1,67 @@
import 'package:flutter/material.dart';
import 'package:lunasea/system/recovery_mode/actions/clear_database.dart';
import 'package:lunasea/system/recovery_mode/actions/bootstrap.dart';
class LunaRecoveryMode extends StatelessWidget {
const LunaRecoveryMode({
super.key,
});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: _home(),
darkTheme: ThemeData(
brightness: Brightness.dark,
useMaterial3: true,
),
themeMode: ThemeMode.dark,
);
}
Widget _home() {
return Scaffold(
appBar: _appBar(),
body: _body(),
);
}
PreferredSizeWidget _appBar() {
return AppBar(
title: const Text('Recovery Mode'),
);
}
SliverToBoxAdapter _motd() {
return const SliverToBoxAdapter(
child: Center(
child: Text(
'To exit please fully close and restart the application.',
style: TextStyle(
color: Colors.red,
fontWeight: FontWeight.w600,
),
),
),
);
}
Widget _body() {
const actions = [
BootstrapTile(),
ClearDatabaseTile(),
];
return CustomScrollView(
slivers: [
SliverPadding(
sliver: _motd(),
padding: const EdgeInsets.all(12.0),
),
SliverList(
delegate: SliverChildListDelegate(actions),
),
],
);
}
}

View File

@@ -21,6 +21,8 @@ LunaWindowManager getWindowManager() {
class IO implements LunaWindowManager {
@override
Future<void> initialize() async {
if (kDebugMode) return;
await windowManager.ensureInitialized();
windowManager.waitUntilReadyToShow().then((_) async {
await setWindowSize();
@@ -42,7 +44,7 @@ class IO implements LunaWindowManager {
const minSize = Size(min, min);
const initSize = Size(init, init);
if (!kDebugMode) await windowManager.setSize(initSize);
await windowManager.setSize(initSize);
// Currently broken on Linux
if (!LunaPlatform.isLinux) {
await windowManager.setMinimumSize(minSize);

View File

@@ -40,6 +40,13 @@ enum LunaLinkedContent {
return '$base/tmdb/$id';
}
static String? musicBrainz(String? id) {
if (id == null) return null;
String base = 'https://musicbrainz.org/artist';
return '$base/$id';
}
static String? theMovieDB(dynamic id, LinkedContentType type) {
if (id == null) return null;
String base = 'https://www.themoviedb.org';

View File

@@ -1,20 +0,0 @@
import 'package:flutter/material.dart';
import 'package:lunasea/vendor.dart';
import 'package:lunasea/widgets/ui.dart';
class DatabaseCorruptionSheet extends LunaBottomModalSheet {
@override
Widget builder(BuildContext context) {
return LunaListViewModal(
children: [
LunaHeader(
text: 'settings.DatabaseCorruptionDetected'.tr(),
subtitle: [
'settings.DatabaseCorruptionDetectedMessageLine1'.tr(),
'settings.DatabaseCorruptionDetectedMessageLine2'.tr(),
].join('\n\n'),
),
],
);
}
}

View File

@@ -12,7 +12,7 @@ class LunaBottomModalSheet<T> {
context: LunaState.context,
expand: false,
backgroundColor:
LunaTheme.isAMOLEDTheme ? Colors.black : LunaColours.secondary,
LunaTheme.isAMOLEDTheme ? Colors.black : LunaColours.primary,
shape: LunaShapeBorder(
topOnly: true,
useBorder: LunaUI.shouldUseBorder,

View File

@@ -13,7 +13,7 @@ class LunaHeader extends StatelessWidget {
Widget _headerText() {
return Text(
text!.toUpperCase(),
text!,
style: const TextStyle(
fontWeight: LunaUI.FONT_WEIGHT_BOLD,
fontSize: LunaUI.FONT_SIZE_H2,

View File

@@ -67,6 +67,7 @@ class LunaIcons {
// Brands - Custom
static const IconData LIDARR = IconData(0xe805, fontFamily: _fontFamily);
static const IconData MUSICBRAINZ = IconData(0xe809, fontFamily: _fontFamily);
static const IconData NZBGET = IconData(0xe807, fontFamily: _fontFamily);
static const IconData OVERSEERR = IconData(0xe808, fontFamily: _fontFamily);
static const IconData RADARR = IconData(0xe80a, fontFamily: _fontFamily);

View File

@@ -24,9 +24,10 @@ class LunaLinearPercentIndicator extends StatelessWidget {
alignment: Alignment.bottomCenter,
child: LinearPercentIndicator(
percent: percent!,
padding: const EdgeInsets.symmetric(horizontal: 2.0),
padding: EdgeInsets.zero,
lineHeight: 4.0,
progressColor: progressColor,
barRadius: const Radius.circular(LunaUI.BORDER_RADIUS),
backgroundColor:
backgroundColor ?? progressColor.withOpacity(LunaUI.OPACITY_SPLASH),
),

View File

@@ -1,3 +1,4 @@
export 'list_view/custom_scroll_view.dart';
export 'list_view/list_view.dart';
export 'list_view/list_view_builder.dart';
export 'list_view/list_view_modal.dart';

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
class LunaCustomScrollView extends StatelessWidget {
final ScrollController controller;
final List<Widget> slivers;
const LunaCustomScrollView({
super.key,
required this.controller,
required this.slivers,
});
@override
Widget build(BuildContext context) {
return Scrollbar(
controller: controller,
interactive: true,
child: CustomScrollView(
controller: controller,
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
slivers: slivers,
physics: const AlwaysScrollableScrollPhysics(),
),
);
}
}

View File

@@ -1,10 +1,124 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class LunaTextStyle extends TextStyle {
const LunaTextStyle.labelMedium()
: super(
fontSize: 12.0, // md.sys.typescale.label-medium.size
fontWeight: FontWeight.w500, // md.sys.typescale.label-medium.weight
height: 16.0 / 12.0, // md.sys.typescale.label-medium.line-height
);
class LunaTextStyle {
static TextStyle bodySmall() {
return GoogleFonts.robotoFlex(
height: 1.33, // md.sys.typescale.body-small.line-height
fontSize: 12.0, // md.sys.typescale.body-small.size
fontWeight: FontWeight.w400, // md.sys.typescale.body-small.weight
);
}
static TextStyle bodyMedium() {
return GoogleFonts.robotoFlex(
height: 1.43, // md.sys.typescale.body-medium.line-height
fontSize: 14.0, // md.sys.typescale.body-medium.size
fontWeight: FontWeight.w400, // md.sys.typescale.body-medium.weight
);
}
static TextStyle bodyLarge() {
return GoogleFonts.robotoFlex(
height: 1.50, // md.sys.typescale.body-large.line-height
fontSize: 16.0, // md.sys.typescale.body-large.size
fontWeight: FontWeight.w400, // md.sys.typescale.body-large.weight
);
}
static TextStyle displaySmall() {
return GoogleFonts.robotoFlex(
height: 1.22, // md.sys.typescale.display-small.line-height
fontSize: 36.0, // md.sys.typescale.display-small.size
fontWeight: FontWeight.w400, // md.sys.typescale.display-small.weight
);
}
static TextStyle displayMedium() {
return GoogleFonts.robotoFlex(
height: 1.56, // md.sys.typescale.display-medium.line-height
fontSize: 45.0, // md.sys.typescale.display-medium.size
fontWeight: FontWeight.w400, // md.sys.typescale.display-medium.weight
);
}
static TextStyle displayLarge() {
return GoogleFonts.robotoFlex(
height: 1.23, // md.sys.typescale.display-large.line-height
fontSize: 57.0, // md.sys.typescale.display-large.size
fontWeight: FontWeight.w400, // md.sys.typescale.display-large.weight
);
}
static TextStyle headlineSmall() {
return GoogleFonts.robotoFlex(
height: 1.25, // md.sys.typescale.headline-small.line-height
fontSize: 32.0, // md.sys.typescale.headline-small.size
fontWeight: FontWeight.w400, // md.sys.typescale.headline-small.weight
);
}
static TextStyle headlineMedium() {
return GoogleFonts.robotoFlex(
height: 1.29, // md.sys.typescale.headline-medium.line-height
fontSize: 28.0, // md.sys.typescale.headline-medium.size
fontWeight: FontWeight.w400, // md.sys.typescale.headline-medium.weight
);
}
static TextStyle headlineLarge() {
return GoogleFonts.robotoFlex(
height: 1.33, // md.sys.typescale.headline-large.line-height
fontSize: 24.0, // md.sys.typescale.headline-large.size
fontWeight: FontWeight.w400, // md.sys.typescale.headline-large.weight
);
}
static TextStyle labelSmall() {
return GoogleFonts.robotoFlex(
height: 1.45, // md.sys.typescale.label-small.line-height
fontSize: 11.0, // md.sys.typescale.label-small.size
fontWeight: FontWeight.w500, // md.sys.typescale.label-small.weight
);
}
static TextStyle labelMedium() {
return GoogleFonts.robotoFlex(
height: 1.33, // md.sys.typescale.label-medium.line-height
fontSize: 12.0, // md.sys.typescale.label-medium.size
fontWeight: FontWeight.w500, // md.sys.typescale.label-medium.weight
);
}
static TextStyle labelLarge() {
return GoogleFonts.robotoFlex(
height: 1.43, // md.sys.typescale.label-large.line-height
fontSize: 14.0, // md.sys.typescale.label-large.size
fontWeight: FontWeight.w500, // md.sys.typescale.label-large.weight
);
}
static TextStyle titleSmall() {
return GoogleFonts.robotoFlex(
height: 1.43, // md.sys.typescale.title-small.line-height
fontSize: 14.0, // md.sys.typescale.title-small.size
fontWeight: FontWeight.w500, // md.sys.typescale.title-small.weight
);
}
static TextStyle titleMedium() {
return GoogleFonts.robotoFlex(
height: 1.50, // md.sys.typescale.title-medium.line-height
fontSize: 16.0, // md.sys.typescale.title-medium.size
fontWeight: FontWeight.w500, // md.sys.typescale.title-medium.weight
);
}
static TextStyle titleLarge() {
return GoogleFonts.robotoFlex(
height: 1.27, // md.sys.typescale.title-large.line-height
fontSize: 22.0, // md.sys.typescale.title-large.size
fontWeight: FontWeight.w400, // md.sys.typescale.title-large.weight
);
}
}

View File

@@ -0,0 +1,17 @@
{
"dashboard.Modules": "Module",
"dashboard.Calendar": "Calendar",
"dashboard.Friday": "Vineri",
"dashboard.OneMonth": "O lună",
"dashboard.OneWeek": "O săptămână",
"dashboard.PastDays": "Zile trecute",
"dashboard.Saturday": "Sâmbătă",
"dashboard.Schedule": "Program",
"dashboard.Sunday": "Duminică",
"dashboard.Thursday": "Joi",
"dashboard.Tuesday": "Marți",
"dashboard.TwoWeeks": "Două săptămâni",
"dashboard.Wednesday": "Miercuri",
"dashboard.FutureDays": "Zile în viitor",
"dashboard.Monday": "Luni"
}

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