From 05ac1768d38c321ea8cf005d7dbfe87667b63178 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Sun, 20 Sep 2026 03:28:35 +0000 Subject: [PATCH] start kotlin/jetpack compose rewrite replace the flutter project with a gradle/compose android app: - nix flake dev shell (jdk21, android sdk 35, build-tools 37, gradle) - material3 app with a placeholder screen - roborazzi/robolectric screenshot tests with one golden - carry over the existing launcher/notification assets --- .env.example | 4 - .fvm/fvm_config.json | 4 - .github/workflows/build-flutter-release.yml | 78 - .github/workflows/build-flutter.yml | 30 - .gitignore | 58 +- .metadata | 30 - .untranslated-messages.json | 500 -- .vscode/launch.json | 26 - BUILDING.md | 0 TODO.md | 30 - analysis_options.yaml | 19 - android/.gitignore | 13 - android/app/build.gradle | 88 - android/app/src/debug/AndroidManifest.xml | 8 - android/app/src/main/AndroidManifest.xml | 72 - .../app/src/main/ic_launcher-playstore.png | Bin 13266 -> 0 bytes .../app/FlutterMultiDexApplication.java | 25 - .../com/example/subtracks2/MainActivity.kt | 6 - .../res/drawable-anydpi/ic_action_name.xml | 29 - .../res/drawable-v21/launch_background.xml | 12 - .../main/res/drawable/launch_background.xml | 12 - android/app/src/main/res/raw/keep.xml | 4 - .../app/src/main/res/values-night/styles.xml | 18 - android/app/src/main/res/values/styles.xml | 18 - android/app/src/profile/AndroidManifest.xml | 8 - android/build.gradle | 31 - android/gradle.properties | 3 - android/gradle/wrapper/gradle-wrapper.jar | Bin 53636 -> 0 bytes android/gradlew | 160 - android/gradlew.bat | 90 - android/settings.gradle | 11 - app/build.gradle.kts | 79 + app/src/main/AndroidManifest.xml | 34 + .../main/kotlin/com/subtracks/MainActivity.kt | 20 + .../main/kotlin/com/subtracks/SubtracksApp.kt | 5 + .../kotlin/com/subtracks/ui/HelloScreen.kt | 53 + .../kotlin/com/subtracks/ui/theme/Color.kt | 11 + .../kotlin/com/subtracks/ui/theme/Theme.kt | 20 + .../kotlin/com/subtracks/ui/theme/Type.kt | 12 + .../res/drawable-anydpi-v24/ic_stat_name.xml | 0 .../main/res/drawable-hdpi/ic_action_name.png | Bin .../main/res/drawable-hdpi/ic_stat_name.png | Bin .../main/res/drawable-mdpi/ic_action_name.png | Bin .../main/res/drawable-mdpi/ic_stat_name.png | Bin .../res/drawable-xhdpi/ic_action_name.png | Bin .../main/res/drawable-xhdpi/ic_stat_name.png | Bin .../res/drawable-xxhdpi/ic_action_name.png | Bin .../main/res/drawable-xxhdpi/ic_stat_name.png | Bin .../res/drawable/ic_launcher_foreground.xml | 0 .../src/main/res/drawable}/placeholder.png | Bin .../main/res/drawable}/placeholder_thumb.png | Bin .../res/mipmap-anydpi-v26/ic_launcher.xml | 0 .../mipmap-anydpi-v26/ic_launcher_round.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../mipmap-hdpi/ic_launcher_foreground.png | Bin .../res/mipmap-hdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../mipmap-mdpi/ic_launcher_foreground.png | Bin .../res/mipmap-mdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../mipmap-xhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin .../res/values/ic_launcher_background.xml | 0 app/src/main/res/values/strings.xml | 4 + app/src/main/res/values/themes.xml | 8 + .../com/subtracks/ui/HelloScreenshotTest.kt | 32 + app/src/test/resources/robolectric.properties | 1 + assets/tag_FILL0_wght400_GRAD0_opsz24.svg | 1 - build.gradle.kts | 7 + build.yaml | 11 - flake.lock | 27 + flake.nix | 58 + gradle.properties | 9 + gradle/libs.versions.toml | 74 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43764 bytes .../wrapper/gradle-wrapper.properties | 4 +- gradlew | 251 + gradlew.bat | 94 + l10n.yaml | 4 - lib/app/app.dart | 85 - lib/app/app.g.dart | 23 - lib/app/app_router.dart | 140 - lib/app/app_router.gr.dart | 720 --- lib/app/buttons.dart | 63 - lib/app/context_menus.dart | 414 -- lib/app/dialogs.dart | 96 - lib/app/gradient.dart | 76 - lib/app/hooks/use_download_actions.dart | 149 - .../use_list_query_paging_controller.dart | 91 - lib/app/hooks/use_paging_controller.dart | 66 - lib/app/images.dart | 368 -- lib/app/images.g.dart | 307 - lib/app/items.dart | 433 -- lib/app/lists.dart | 136 - lib/app/now_playing_bar.dart | 226 - lib/app/pages/artist_page.dart | 152 - lib/app/pages/bottom_nav_page.dart | 216 - lib/app/pages/bottom_nav_page.g.dart | 56 - lib/app/pages/browse_page.dart | 281 - lib/app/pages/browse_page.g.dart | 114 - lib/app/pages/library_albums_page.dart | 41 - lib/app/pages/library_artists_page.dart | 39 - lib/app/pages/library_page.dart | 635 -- lib/app/pages/library_page.g.dart | 176 - lib/app/pages/library_playlists_page.dart | 39 - lib/app/pages/library_songs_page.dart | 81 - lib/app/pages/library_songs_page.g.dart | 111 - lib/app/pages/now_playing_page.dart | 429 -- lib/app/pages/search_page.dart | 247 - lib/app/pages/search_page.g.dart | 38 - lib/app/pages/settings_page.dart | 448 -- lib/app/pages/songs_page.dart | 511 -- lib/app/pages/source_page.dart | 283 - lib/app/snackbars.dart | 14 - lib/cache/image_cache.dart | 30 - lib/cache/image_cache.g.dart | 23 - lib/database/converters.dart | 72 - lib/database/database.dart | 681 -- lib/database/database.g.dart | 5573 ----------------- lib/database/error_logging_database.dart | 94 - lib/database/tables.drift | 567 -- lib/database/util.dart | 23 - lib/http/client.dart | 32 - lib/http/client.g.dart | 23 - lib/l10n/app_ar.arb | 196 - lib/l10n/app_ca.arb | 196 - lib/l10n/app_cs.arb | 226 - lib/l10n/app_da.arb | 186 - lib/l10n/app_de.arb | 280 - lib/l10n/app_en.arb | 280 - lib/l10n/app_es.arb | 280 - lib/l10n/app_eu.arb | 200 - lib/l10n/app_fr.arb | 280 - lib/l10n/app_gl.arb | 280 - lib/l10n/app_hu.arb | 224 - lib/l10n/app_it.arb | 280 - lib/l10n/app_ja.arb | 88 - lib/l10n/app_ko.arb | 189 - lib/l10n/app_nb.arb | 280 - lib/l10n/app_pa.arb | 196 - lib/l10n/app_pl.arb | 232 - lib/l10n/app_pt-BR.arb | 280 - lib/l10n/app_pt.arb | 230 - lib/l10n/app_ru.arb | 280 - lib/l10n/app_sv.arb | 280 - lib/l10n/app_ta.arb | 280 - lib/l10n/app_th.arb | 280 - lib/l10n/app_tr.arb | 201 - lib/l10n/app_uk.arb | 280 - lib/l10n/app_vi.arb | 201 - lib/l10n/app_zh-Hant.arb | 280 - lib/l10n/app_zh.arb | 280 - lib/log.dart | 209 - lib/main.dart | 26 - lib/models/music.dart | 115 - lib/models/music.freezed.dart | 1834 ------ lib/models/query.dart | 97 - lib/models/query.freezed.dart | 1934 ------ lib/models/query.g.dart | 143 - lib/models/settings.dart | 120 - lib/models/settings.freezed.dart | 810 --- lib/models/support.dart | 187 - lib/models/support.freezed.dart | 2141 ------- lib/models/support.g.dart | 83 - lib/services/audio_service.dart | 703 --- lib/services/audio_service.g.dart | 38 - lib/services/cache_service.dart | 112 - lib/services/cache_service.g.dart | 23 - lib/services/download_service.dart | 589 -- lib/services/download_service.freezed.dart | 495 -- lib/services/download_service.g.dart | 25 - lib/services/settings_service.dart | 129 - lib/services/settings_service.g.dart | 25 - lib/services/sync_service.dart | 105 - lib/services/sync_service.g.dart | 23 - lib/sources/music_source.dart | 95 - lib/sources/subsonic/client.dart | 140 - lib/sources/subsonic/source.dart | 285 - lib/sources/subsonic/xml.dart | 19 - lib/state/audio.dart | 143 - lib/state/audio.g.dart | 229 - lib/state/init.dart | 82 - lib/state/init.g.dart | 97 - lib/state/music.dart | 152 - lib/state/music.g.dart | 1206 ---- lib/state/settings.dart | 88 - lib/state/settings.g.dart | 79 - lib/state/theme.dart | 258 - lib/state/theme.g.dart | 485 -- pubspec.lock | 1384 ---- pubspec.yaml | 85 - scripts/arb-delete-key.js | 17 - scripts/arb-rename-key.js | 37 - settings.gradle.kts | 24 + tools/preview_server.py | 66 + 201 files changed, 905 insertions(+), 37425 deletions(-) delete mode 100644 .env.example delete mode 100644 .fvm/fvm_config.json delete mode 100644 .github/workflows/build-flutter-release.yml delete mode 100644 .github/workflows/build-flutter.yml delete mode 100644 .metadata delete mode 100644 .untranslated-messages.json delete mode 100644 .vscode/launch.json delete mode 100644 BUILDING.md delete mode 100644 TODO.md delete mode 100644 analysis_options.yaml delete mode 100644 android/.gitignore delete mode 100644 android/app/build.gradle delete mode 100644 android/app/src/debug/AndroidManifest.xml delete mode 100644 android/app/src/main/AndroidManifest.xml delete mode 100644 android/app/src/main/ic_launcher-playstore.png delete mode 100644 android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java delete mode 100644 android/app/src/main/kotlin/com/example/subtracks2/MainActivity.kt delete mode 100644 android/app/src/main/res/drawable-anydpi/ic_action_name.xml delete mode 100644 android/app/src/main/res/drawable-v21/launch_background.xml delete mode 100644 android/app/src/main/res/drawable/launch_background.xml delete mode 100644 android/app/src/main/res/raw/keep.xml delete mode 100644 android/app/src/main/res/values-night/styles.xml delete mode 100644 android/app/src/main/res/values/styles.xml delete mode 100644 android/app/src/profile/AndroidManifest.xml delete mode 100644 android/build.gradle delete mode 100644 android/gradle.properties delete mode 100755 android/gradle/wrapper/gradle-wrapper.jar delete mode 100755 android/gradlew delete mode 100755 android/gradlew.bat delete mode 100644 android/settings.gradle create mode 100644 app/build.gradle.kts create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/kotlin/com/subtracks/MainActivity.kt create mode 100644 app/src/main/kotlin/com/subtracks/SubtracksApp.kt create mode 100644 app/src/main/kotlin/com/subtracks/ui/HelloScreen.kt create mode 100644 app/src/main/kotlin/com/subtracks/ui/theme/Color.kt create mode 100644 app/src/main/kotlin/com/subtracks/ui/theme/Theme.kt create mode 100644 app/src/main/kotlin/com/subtracks/ui/theme/Type.kt rename {android/app => app}/src/main/res/drawable-anydpi-v24/ic_stat_name.xml (100%) rename {android/app => app}/src/main/res/drawable-hdpi/ic_action_name.png (100%) rename {android/app => app}/src/main/res/drawable-hdpi/ic_stat_name.png (100%) rename {android/app => app}/src/main/res/drawable-mdpi/ic_action_name.png (100%) rename {android/app => app}/src/main/res/drawable-mdpi/ic_stat_name.png (100%) rename {android/app => app}/src/main/res/drawable-xhdpi/ic_action_name.png (100%) rename {android/app => app}/src/main/res/drawable-xhdpi/ic_stat_name.png (100%) rename {android/app => app}/src/main/res/drawable-xxhdpi/ic_action_name.png (100%) rename {android/app => app}/src/main/res/drawable-xxhdpi/ic_stat_name.png (100%) rename {android/app => app}/src/main/res/drawable/ic_launcher_foreground.xml (100%) rename {assets => app/src/main/res/drawable}/placeholder.png (100%) rename {assets => app/src/main/res/drawable}/placeholder_thumb.png (100%) rename {android/app => app}/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (100%) rename {android/app => app}/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (100%) rename {android/app => app}/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {android/app => app}/src/main/res/mipmap-hdpi/ic_launcher_foreground.png (100%) rename {android/app => app}/src/main/res/mipmap-hdpi/ic_launcher_round.png (100%) rename {android/app => app}/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {android/app => app}/src/main/res/mipmap-mdpi/ic_launcher_foreground.png (100%) rename {android/app => app}/src/main/res/mipmap-mdpi/ic_launcher_round.png (100%) rename {android/app => app}/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {android/app => app}/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png (100%) rename {android/app => app}/src/main/res/mipmap-xhdpi/ic_launcher_round.png (100%) rename {android/app => app}/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {android/app => app}/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png (100%) rename {android/app => app}/src/main/res/mipmap-xxhdpi/ic_launcher_round.png (100%) rename {android/app => app}/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {android/app => app}/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png (100%) rename {android/app => app}/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png (100%) rename {android/app => app}/src/main/res/values/ic_launcher_background.xml (100%) create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 app/src/test/kotlin/com/subtracks/ui/HelloScreenshotTest.kt create mode 100644 app/src/test/resources/robolectric.properties delete mode 100644 assets/tag_FILL0_wght400_GRAD0_opsz24.svg create mode 100644 build.gradle.kts delete mode 100644 build.yaml create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 gradle.properties create mode 100644 gradle/libs.versions.toml create mode 100644 gradle/wrapper/gradle-wrapper.jar rename {android/gradle => gradle}/wrapper/gradle-wrapper.properties (73%) create mode 100755 gradlew create mode 100644 gradlew.bat delete mode 100644 l10n.yaml delete mode 100644 lib/app/app.dart delete mode 100644 lib/app/app.g.dart delete mode 100644 lib/app/app_router.dart delete mode 100644 lib/app/app_router.gr.dart delete mode 100644 lib/app/buttons.dart delete mode 100644 lib/app/context_menus.dart delete mode 100644 lib/app/dialogs.dart delete mode 100644 lib/app/gradient.dart delete mode 100644 lib/app/hooks/use_download_actions.dart delete mode 100644 lib/app/hooks/use_list_query_paging_controller.dart delete mode 100644 lib/app/hooks/use_paging_controller.dart delete mode 100644 lib/app/images.dart delete mode 100644 lib/app/images.g.dart delete mode 100644 lib/app/items.dart delete mode 100644 lib/app/lists.dart delete mode 100644 lib/app/now_playing_bar.dart delete mode 100644 lib/app/pages/artist_page.dart delete mode 100644 lib/app/pages/bottom_nav_page.dart delete mode 100644 lib/app/pages/bottom_nav_page.g.dart delete mode 100644 lib/app/pages/browse_page.dart delete mode 100644 lib/app/pages/browse_page.g.dart delete mode 100644 lib/app/pages/library_albums_page.dart delete mode 100644 lib/app/pages/library_artists_page.dart delete mode 100644 lib/app/pages/library_page.dart delete mode 100644 lib/app/pages/library_page.g.dart delete mode 100644 lib/app/pages/library_playlists_page.dart delete mode 100644 lib/app/pages/library_songs_page.dart delete mode 100644 lib/app/pages/library_songs_page.g.dart delete mode 100644 lib/app/pages/now_playing_page.dart delete mode 100644 lib/app/pages/search_page.dart delete mode 100644 lib/app/pages/search_page.g.dart delete mode 100644 lib/app/pages/settings_page.dart delete mode 100644 lib/app/pages/songs_page.dart delete mode 100644 lib/app/pages/source_page.dart delete mode 100644 lib/app/snackbars.dart delete mode 100644 lib/cache/image_cache.dart delete mode 100644 lib/cache/image_cache.g.dart delete mode 100644 lib/database/converters.dart delete mode 100644 lib/database/database.dart delete mode 100644 lib/database/database.g.dart delete mode 100644 lib/database/error_logging_database.dart delete mode 100644 lib/database/tables.drift delete mode 100644 lib/database/util.dart delete mode 100644 lib/http/client.dart delete mode 100644 lib/http/client.g.dart delete mode 100644 lib/l10n/app_ar.arb delete mode 100644 lib/l10n/app_ca.arb delete mode 100644 lib/l10n/app_cs.arb delete mode 100644 lib/l10n/app_da.arb delete mode 100644 lib/l10n/app_de.arb delete mode 100644 lib/l10n/app_en.arb delete mode 100644 lib/l10n/app_es.arb delete mode 100644 lib/l10n/app_eu.arb delete mode 100644 lib/l10n/app_fr.arb delete mode 100644 lib/l10n/app_gl.arb delete mode 100644 lib/l10n/app_hu.arb delete mode 100644 lib/l10n/app_it.arb delete mode 100644 lib/l10n/app_ja.arb delete mode 100644 lib/l10n/app_ko.arb delete mode 100644 lib/l10n/app_nb.arb delete mode 100644 lib/l10n/app_pa.arb delete mode 100644 lib/l10n/app_pl.arb delete mode 100644 lib/l10n/app_pt-BR.arb delete mode 100644 lib/l10n/app_pt.arb delete mode 100644 lib/l10n/app_ru.arb delete mode 100644 lib/l10n/app_sv.arb delete mode 100644 lib/l10n/app_ta.arb delete mode 100644 lib/l10n/app_th.arb delete mode 100644 lib/l10n/app_tr.arb delete mode 100644 lib/l10n/app_uk.arb delete mode 100644 lib/l10n/app_vi.arb delete mode 100644 lib/l10n/app_zh-Hant.arb delete mode 100644 lib/l10n/app_zh.arb delete mode 100644 lib/log.dart delete mode 100644 lib/main.dart delete mode 100644 lib/models/music.dart delete mode 100644 lib/models/music.freezed.dart delete mode 100644 lib/models/query.dart delete mode 100644 lib/models/query.freezed.dart delete mode 100644 lib/models/query.g.dart delete mode 100644 lib/models/settings.dart delete mode 100644 lib/models/settings.freezed.dart delete mode 100644 lib/models/support.dart delete mode 100644 lib/models/support.freezed.dart delete mode 100644 lib/models/support.g.dart delete mode 100644 lib/services/audio_service.dart delete mode 100644 lib/services/audio_service.g.dart delete mode 100644 lib/services/cache_service.dart delete mode 100644 lib/services/cache_service.g.dart delete mode 100644 lib/services/download_service.dart delete mode 100644 lib/services/download_service.freezed.dart delete mode 100644 lib/services/download_service.g.dart delete mode 100644 lib/services/settings_service.dart delete mode 100644 lib/services/settings_service.g.dart delete mode 100644 lib/services/sync_service.dart delete mode 100644 lib/services/sync_service.g.dart delete mode 100644 lib/sources/music_source.dart delete mode 100644 lib/sources/subsonic/client.dart delete mode 100644 lib/sources/subsonic/source.dart delete mode 100644 lib/sources/subsonic/xml.dart delete mode 100644 lib/state/audio.dart delete mode 100644 lib/state/audio.g.dart delete mode 100644 lib/state/init.dart delete mode 100644 lib/state/init.g.dart delete mode 100644 lib/state/music.dart delete mode 100644 lib/state/music.g.dart delete mode 100644 lib/state/settings.dart delete mode 100644 lib/state/settings.g.dart delete mode 100644 lib/state/theme.dart delete mode 100644 lib/state/theme.g.dart delete mode 100644 pubspec.lock delete mode 100644 pubspec.yaml delete mode 100644 scripts/arb-delete-key.js delete mode 100644 scripts/arb-rename-key.js create mode 100644 settings.gradle.kts create mode 100644 tools/preview_server.py diff --git a/.env.example b/.env.example deleted file mode 100644 index 2990b8cf..00000000 --- a/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -TEST_SERVER_NAME=Subsonic Demo -TEST_SERVER_URL=http://demo.subsonic.org -TEST_SERVER_USERNAME=guest -TEST_SERVER_PASSWORD=guest diff --git a/.fvm/fvm_config.json b/.fvm/fvm_config.json deleted file mode 100644 index 5cb9b8f3..00000000 --- a/.fvm/fvm_config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "flutterSdkVersion": "3.7.11", - "flavors": {} -} \ No newline at end of file diff --git a/.github/workflows/build-flutter-release.yml b/.github/workflows/build-flutter-release.yml deleted file mode 100644 index 3f2ae1b6..00000000 --- a/.github/workflows/build-flutter-release.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: build-flutter-release - -on: - push: - tags: ['v*'] - -jobs: - build-apk: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v3 - - - name: Get subtracks version - run: echo "SUBTRACKS_VERSION=$(yq '.version' pubspec.yaml | cut -d '+' -f 1)" >> $GITHUB_ENV - - - uses: subosito/flutter-action@v2 - with: - flutter-version: '3.7.11' - channel: 'stable' - cache: true - - - run: cp .env.example .env - - run: flutter pub get - - - name: Retrieve subtracks.keystore - env: - SUBTRACKS_KEYSTORE_BASE64: ${{ secrets.SUBTRACKS_KEYSTORE_BASE64 }} - run: | - echo "$SUBTRACKS_KEYSTORE_BASE64" | base64 --decode > android/subtracks.keystore - - name: Retrieve key.properties - env: - SUBTRACKS_KEYPROPERTIES_BASE64: ${{ secrets.SUBTRACKS_KEYPROPERTIES_BASE64 }} - run: | - echo "$SUBTRACKS_KEYPROPERTIES_BASE64" | base64 --decode > android/key.properties - - - run: flutter build apk -PsignRelease - - - run: mv build/app/outputs/flutter-apk/app-release.apk subtracks-${SUBTRACKS_VERSION}.apk - - uses: actions/upload-artifact@v3 - with: - name: subtracks-release-apk - path: subtracks-*.apk - - build-aab: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v3 - - - name: Get subtracks version - run: echo "SUBTRACKS_VERSION=$(yq '.version' pubspec.yaml)" >> $GITHUB_ENV - - - uses: subosito/flutter-action@v2 - with: - flutter-version: '3.7.11' - channel: 'stable' - cache: true - - - run: cp .env.example .env - - run: flutter pub get - - - name: Retrieve subtracks.keystore - env: - SUBTRACKS_KEYSTORE_BASE64: ${{ secrets.SUBTRACKS_KEYSTORE_BASE64 }} - run: | - echo "$SUBTRACKS_KEYSTORE_BASE64" | base64 --decode > android/subtracks.keystore - - name: Retrieve key.properties - env: - SUBTRACKS_KEYPROPERTIES_BASE64: ${{ secrets.SUBTRACKS_KEYPROPERTIES_BASE64 }} - run: | - echo "$SUBTRACKS_KEYPROPERTIES_BASE64" | base64 --decode > android/key.properties - - - run: flutter build appbundle -PsignRelease - - - run: mv build/app/outputs/bundle/release/app-release.aab subtracks-${SUBTRACKS_VERSION}.aab - - uses: actions/upload-artifact@v3 - with: - name: subtracks-release-aab - path: subtracks-*.aab diff --git a/.github/workflows/build-flutter.yml b/.github/workflows/build-flutter.yml deleted file mode 100644 index 7a24bd08..00000000 --- a/.github/workflows/build-flutter.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: build-flutter - -on: - push: - branches: ['main'] - pull_request: - branches: ['main'] - -jobs: - build-apk: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v3 - - - uses: subosito/flutter-action@v2 - with: - flutter-version: '3.7.11' - channel: 'stable' - cache: true - - - run: cp .env.example .env - - run: flutter pub get - - run: flutter analyze - - run: flutter build apk - - - run: mv build/app/outputs/flutter-apk/app-release.apk subtracks-$(git rev-parse --short HEAD).apk - - uses: actions/upload-artifact@v3 - with: - name: subtracks-testing - path: subtracks-*.apk diff --git a/.gitignore b/.gitignore index 0574f2a9..41f83c1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,49 +1,17 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ -migrate_working_dir/ +.gradle/ +build/ +local.properties + +*.apk +*.aab +captures/ +.cxx/ -# IntelliJ related -*.iml -*.ipr -*.iws .idea/ +*.iml +.vscode/ -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ +.kotlin/ +.preview/ -# Flutter/Dart/Pub related -**/doc/api/ -**/ios/Flutter/.last_build_id -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.packages -.pub-cache/ -.pub/ -/build/ - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json - -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release - -/.env -*.sqlite* -/.fvm/flutter_sdk -*.keystore +.DS_Store diff --git a/.metadata b/.metadata deleted file mode 100644 index 25a8e60d..00000000 --- a/.metadata +++ /dev/null @@ -1,30 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled. - -version: - revision: 9944297138845a94256f1cf37beb88ff9a8e811a - channel: stable - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a - base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a - - platform: android - create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a - base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/.untranslated-messages.json b/.untranslated-messages.json deleted file mode 100644 index c3c8d177..00000000 --- a/.untranslated-messages.json +++ /dev/null @@ -1,500 +0,0 @@ -{ - "ar": [ - "actionsCancel", - "actionsDelete", - "actionsDownload", - "actionsDownloadCancel", - "actionsDownloadDelete", - "actionsOk", - "controlsShuffle", - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterOwner", - "resourcesFilterYear", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "settingsAboutActionsSupport", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ], - - "ca": [ - "actionsCancel", - "actionsDelete", - "actionsDownload", - "actionsDownloadCancel", - "actionsDownloadDelete", - "actionsOk", - "controlsShuffle", - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterOwner", - "resourcesFilterYear", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "settingsAboutActionsSupport", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ], - - "cs": [ - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesPlaylistCount", - "resourcesSongCount", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsMusicName", - "settingsMusicOptionsScrobbleDescriptionOff", - "settingsMusicOptionsScrobbleDescriptionOn", - "settingsMusicOptionsScrobbleTitle", - "settingsNetworkOptionsMaxBufferTitle", - "settingsNetworkOptionsMinBufferTitle", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn" - ], - - "da": [ - "actionsCancel", - "actionsDelete", - "actionsDownload", - "actionsDownloadCancel", - "actionsDownloadDelete", - "actionsOk", - "actionsStar", - "actionsUnstar", - "controlsShuffle", - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterOwner", - "resourcesFilterStarred", - "resourcesFilterYear", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAdded", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByFrequentlyPlayed", - "resourcesSortByRecentlyPlayed", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "settingsAboutActionsSupport", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsMusicOptionsScrobbleDescriptionOff", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName", - "settingsServersOptionsForcePlaintextPasswordDescriptionOff", - "settingsServersOptionsForcePlaintextPasswordDescriptionOn", - "settingsServersOptionsForcePlaintextPasswordTitle" - ], - - "de": [ - "settingsAboutShareLogs", - "settingsAboutChooseLog" - ], - - "es": [ - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterOwner", - "resourcesFilterYear", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "settingsAboutActionsSupport", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ], - - "fr": [ - "actionsCancel", - "actionsDelete", - "actionsDownload", - "actionsDownloadCancel", - "actionsDownloadDelete", - "actionsOk", - "controlsShuffle", - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterOwner", - "resourcesFilterYear", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "settingsAboutActionsSupport", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ], - - "it": [ - "actionsCancel", - "actionsDelete", - "actionsDownload", - "actionsDownloadCancel", - "actionsDownloadDelete", - "actionsOk", - "controlsShuffle", - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterOwner", - "resourcesFilterYear", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "settingsAboutActionsSupport", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ], - - "ja": [ - "actionsCancel", - "actionsDelete", - "actionsDownload", - "actionsDownloadCancel", - "actionsDownloadDelete", - "actionsOk", - "actionsStar", - "actionsUnstar", - "controlsShuffle", - "messagesNothingHere", - "resourcesAlbumActionsPlay", - "resourcesAlbumActionsView", - "resourcesAlbumCount", - "resourcesAlbumListsSort", - "resourcesArtistActionsView", - "resourcesArtistCount", - "resourcesArtistListsSort", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterGenre", - "resourcesFilterOwner", - "resourcesFilterYear", - "resourcesPlaylistActionsPlay", - "resourcesPlaylistCount", - "resourcesQueueName", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAdded", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByArtist", - "resourcesSortByName", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "resourcesSortByYear", - "searchHeaderTitle", - "searchMoreResults", - "searchNowPlayingContext", - "settingsAboutActionsLicenses", - "settingsAboutActionsSupport", - "settingsAboutName", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsAboutVersion", - "settingsMusicOptionsScrobbleDescriptionOff", - "settingsMusicOptionsScrobbleDescriptionOn", - "settingsMusicOptionsScrobbleTitle", - "settingsNetworkOptionsMaxBitrateMobileTitle", - "settingsNetworkOptionsMaxBitrateWifiTitle", - "settingsNetworkOptionsMaxBufferTitle", - "settingsNetworkOptionsMinBufferTitle", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsNetworkValuesKbps", - "settingsNetworkValuesSeconds", - "settingsNetworkValuesUnlimitedKbps", - "settingsResetActionsClearImageCache", - "settingsServersActionsAdd", - "settingsServersActionsDelete", - "settingsServersActionsEdit", - "settingsServersActionsSave", - "settingsServersActionsTestConnection", - "settingsServersFieldsAddress", - "settingsServersFieldsName", - "settingsServersFieldsPassword", - "settingsServersFieldsUsername", - "settingsServersMessagesConnectionFailed", - "settingsServersMessagesConnectionOk", - "settingsServersOptionsForcePlaintextPasswordDescriptionOff", - "settingsServersOptionsForcePlaintextPasswordDescriptionOn", - "settingsServersOptionsForcePlaintextPasswordTitle" - ], - - "nb": [ - "actionsCancel", - "actionsDelete", - "actionsDownload", - "actionsDownloadCancel", - "actionsDownloadDelete", - "actionsOk", - "controlsShuffle", - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterOwner", - "resourcesFilterYear", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "settingsAboutActionsSupport", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ], - - "pa": [ - "actionsCancel", - "actionsDelete", - "actionsDownload", - "actionsDownloadCancel", - "actionsDownloadDelete", - "actionsOk", - "controlsShuffle", - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterOwner", - "resourcesFilterYear", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "settingsAboutActionsSupport", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ], - - "pl": [ - "actionsCancel", - "actionsDelete", - "actionsDownload", - "actionsDownloadCancel", - "actionsDownloadDelete", - "actionsOk", - "controlsShuffle", - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterOwner", - "resourcesFilterYear", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "settingsAboutActionsSupport", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ], - - "pt": [ - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterOwner", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAlbumCount", - "resourcesSortByUpdated", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ], - - "tr": [ - "actionsCancel", - "actionsDelete", - "actionsDownload", - "actionsDownloadCancel", - "actionsDownloadDelete", - "actionsOk", - "controlsShuffle", - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterOwner", - "resourcesFilterYear", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "settingsAboutActionsSupport", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ], - - "vi": [ - "actionsCancel", - "actionsDelete", - "actionsDownload", - "actionsDownloadCancel", - "actionsDownloadDelete", - "actionsOk", - "controlsShuffle", - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesFilterAlbum", - "resourcesFilterArtist", - "resourcesFilterOwner", - "resourcesFilterYear", - "resourcesPlaylistCount", - "resourcesSongCount", - "resourcesSongListDeleteAllContent", - "resourcesSongListDeleteAllTitle", - "resourcesSortByAlbum", - "resourcesSortByAlbumCount", - "resourcesSortByTitle", - "resourcesSortByUpdated", - "settingsAboutActionsSupport", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ], - - "zh": [ - "controlsShuffle", - "resourcesAlbumCount", - "resourcesArtistCount", - "resourcesPlaylistCount", - "resourcesSongCount", - "settingsAboutShareLogs", - "settingsAboutChooseLog", - "settingsNetworkOptionsOfflineMode", - "settingsNetworkOptionsOfflineModeOff", - "settingsNetworkOptionsOfflineModeOn", - "settingsNetworkOptionsStreamFormat", - "settingsNetworkOptionsStreamFormatServerDefault", - "settingsServersFieldsName" - ] -} diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 30438a80..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "debug", - "request": "launch", - "type": "dart", - "flutterMode": "debug" - }, - { - "name": "profile mode", - "request": "launch", - "type": "dart", - "flutterMode": "profile" - }, - { - "name": "release mode", - "request": "launch", - "type": "dart", - "flutterMode": "release" - } - ] -} diff --git a/BUILDING.md b/BUILDING.md deleted file mode 100644 index e69de29b..00000000 diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 360193e1..00000000 --- a/TODO.md +++ /dev/null @@ -1,30 +0,0 @@ -## To-do -- Star/unstar -- Context menus - - Download actions for song -- Playlist management - - Add to playlist (from context) -- Queue management - - View playing queue - - Re-order queue - - Add to queue (from context) - - Remove from queue -- Scrobbling -- Library filters (year/genre/etc) -- Library list display modes -- Search - - Individual "more" results pages -- Now playing gestures - - Swipe bar/album to skip - - Double-tap to seek forward/back (bar only) -- Settings - - Music - - Scrobble - - Downloads - - Used/available space - - Clear downloads - - Clear images - - About - - Licenses -- Welcome/setup flow -- Proper loading screen/animation diff --git a/analysis_options.yaml b/analysis_options.yaml deleted file mode 100644 index 3b059d12..00000000 --- a/analysis_options.yaml +++ /dev/null @@ -1,19 +0,0 @@ -include: package:flutter_lints/flutter.yaml - -linter: - rules: - prefer_relative_imports: true - -analyzer: - exclude: - - '**.freezed.dart' - - '**.g.dart' - - '**.gr.dart' - plugins: - # broken currently and may not get fixed - # https://github.com/simolus3/drift/issues/2342 - # - drift - - # also broken but only recently reported - # https://github.com/rrousselGit/riverpod/issues/2180 - # - custom_lint diff --git a/android/.gitignore b/android/.gitignore deleted file mode 100644 index 6f568019..00000000 --- a/android/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java - -# Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app -key.properties -**/*.keystore -**/*.jks diff --git a/android/app/build.gradle b/android/app/build.gradle deleted file mode 100644 index aa6b4ec0..00000000 --- a/android/app/build.gradle +++ /dev/null @@ -1,88 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -def keystoreProperties = new Properties() -def keystorePropertiesFile = rootProject.file('key.properties') -if (keystorePropertiesFile.exists()) { - keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) -} - -android { - compileSdkVersion flutter.compileSdkVersion - ndkVersion flutter.ndkVersion - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = '1.8' - } - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.subtracks2" - // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion 19 - targetSdkVersion flutter.targetSdkVersion - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - } - - signingConfigs { - release { - keyAlias keystoreProperties['keyAlias'] - keyPassword keystoreProperties['keyPassword'] - storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null - storePassword keystoreProperties['storePassword'] - } - } - - buildTypes { - release { - if (project.hasProperty("signRelease")) { - signingConfig signingConfigs.release - } else { - signingConfig signingConfigs.debug - } - } - } -} - -flutter { - source '../..' -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index a4bd2ddd..00000000 --- a/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index adb244be..00000000 --- a/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/app/src/main/ic_launcher-playstore.png b/android/app/src/main/ic_launcher-playstore.png deleted file mode 100644 index eac0bfb7be73002f76a9fb9b2c83df954978fdde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13266 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 - - - - - - diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml deleted file mode 100644 index f74085f3..00000000 --- a/android/app/src/main/res/drawable-v21/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f8..00000000 --- a/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/android/app/src/main/res/raw/keep.xml b/android/app/src/main/res/raw/keep.xml deleted file mode 100644 index 6ea56693..00000000 --- a/android/app/src/main/res/raw/keep.xml +++ /dev/null @@ -1,4 +0,0 @@ - - diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml deleted file mode 100644 index 06952be7..00000000 --- a/android/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml deleted file mode 100644 index cb1ef880..00000000 --- a/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index a4bd2ddd..00000000 --- a/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100644 index 58a8c74b..00000000 --- a/android/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.2.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/android/gradle.properties b/android/gradle.properties deleted file mode 100644 index 94adc3a3..00000000 --- a/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.useAndroidX=true -android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100755 index 13372aef5e24af05341d49695ee84e5f9b594659..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53636 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 diff --git a/android/gradlew b/android/gradlew deleted file mode 100755 index 9d82f789..00000000 --- a/android/gradlew +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat deleted file mode 100755 index aec99730..00000000 --- a/android/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/android/settings.gradle b/android/settings.gradle deleted file mode 100644 index 44e62bcf..00000000 --- a/android/settings.gradle +++ /dev/null @@ -1,11 +0,0 @@ -include ':app' - -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() - -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } - -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 00000000..f2c1b95d --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,79 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.compose.compiler) + alias(libs.plugins.roborazzi) +} + +android { + namespace = "com.subtracks" + compileSdk = 35 + buildToolsVersion = "37.0.0" + + defaultConfig { + applicationId = "com.subtracks.next" + minSdk = 24 + targetSdk = 35 + versionCode = 1 + versionName = "0.1.0" + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildFeatures { + compose = true + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = "17" + } + + testOptions { + unitTests { + isIncludeAndroidResources = true + } + } + + buildTypes { + release { + isMinifyEnabled = false + } + } +} + +roborazzi { + outputDir.set(file("src/test/screenshots")) +} + +dependencies { + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.lifecycle.viewmodel.compose) + implementation(libs.androidx.activity.compose) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.ui.graphics) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.compose.material3) + implementation(libs.androidx.navigation.compose) + implementation(libs.koin.android) + implementation(libs.koin.androidx.compose) + implementation(libs.kotlinx.coroutines.android) + implementation(libs.kotlinx.serialization.json) + + debugImplementation(libs.androidx.compose.ui.tooling) + debugImplementation(libs.androidx.compose.ui.test.manifest) + + testImplementation(libs.junit) + testImplementation(libs.robolectric) + testImplementation(libs.roborazzi) + testImplementation(libs.roborazzi.compose) + testImplementation(libs.roborazzi.junit.rule) + testImplementation(libs.androidx.compose.ui.test.junit4) + testImplementation(libs.androidx.test.ext.junit) + testImplementation(libs.androidx.test.core) +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..23abd2e9 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/kotlin/com/subtracks/MainActivity.kt b/app/src/main/kotlin/com/subtracks/MainActivity.kt new file mode 100644 index 00000000..9be85da4 --- /dev/null +++ b/app/src/main/kotlin/com/subtracks/MainActivity.kt @@ -0,0 +1,20 @@ +package com.subtracks + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import com.subtracks.ui.HelloScreen +import com.subtracks.ui.theme.SubtracksTheme + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContent { + SubtracksTheme { + HelloScreen() + } + } + } +} diff --git a/app/src/main/kotlin/com/subtracks/SubtracksApp.kt b/app/src/main/kotlin/com/subtracks/SubtracksApp.kt new file mode 100644 index 00000000..f784f4fc --- /dev/null +++ b/app/src/main/kotlin/com/subtracks/SubtracksApp.kt @@ -0,0 +1,5 @@ +package com.subtracks + +import android.app.Application + +class SubtracksApp : Application() diff --git a/app/src/main/kotlin/com/subtracks/ui/HelloScreen.kt b/app/src/main/kotlin/com/subtracks/ui/HelloScreen.kt new file mode 100644 index 00000000..ae745c44 --- /dev/null +++ b/app/src/main/kotlin/com/subtracks/ui/HelloScreen.kt @@ -0,0 +1,53 @@ +package com.subtracks.ui + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.subtracks.ui.theme.SubtracksTheme + +@Composable +fun HelloScreen(modifier: Modifier = Modifier) { + Surface( + modifier = modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background, + ) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(24.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = "Subtracks", + style = MaterialTheme.typography.headlineLarge, + color = MaterialTheme.colorScheme.onBackground, + ) + Spacer(Modifier.height(8.dp)) + Text( + text = "Kotlin / Jetpack Compose rewrite", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + } +} + +@Preview +@Composable +private fun HelloScreenPreview() { + SubtracksTheme { + HelloScreen() + } +} diff --git a/app/src/main/kotlin/com/subtracks/ui/theme/Color.kt b/app/src/main/kotlin/com/subtracks/ui/theme/Color.kt new file mode 100644 index 00000000..8d2eb1a9 --- /dev/null +++ b/app/src/main/kotlin/com/subtracks/ui/theme/Color.kt @@ -0,0 +1,11 @@ +package com.subtracks.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650A4) +val PurpleGrey40 = Color(0xFF625B71) +val Pink40 = Color(0xFF7D5260) diff --git a/app/src/main/kotlin/com/subtracks/ui/theme/Theme.kt b/app/src/main/kotlin/com/subtracks/ui/theme/Theme.kt new file mode 100644 index 00000000..573e2e08 --- /dev/null +++ b/app/src/main/kotlin/com/subtracks/ui/theme/Theme.kt @@ -0,0 +1,20 @@ +package com.subtracks.ui.theme + +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.runtime.Composable + +private val SubtracksDarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80, +) + +@Composable +fun SubtracksTheme(content: @Composable () -> Unit) { + MaterialTheme( + colorScheme = SubtracksDarkColorScheme, + typography = SubtracksTypography, + content = content, + ) +} diff --git a/app/src/main/kotlin/com/subtracks/ui/theme/Type.kt b/app/src/main/kotlin/com/subtracks/ui/theme/Type.kt new file mode 100644 index 00000000..7907a208 --- /dev/null +++ b/app/src/main/kotlin/com/subtracks/ui/theme/Type.kt @@ -0,0 +1,12 @@ +package com.subtracks.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.font.FontWeight + +val SubtracksTypography = Typography().let { base -> + base.copy( + headlineLarge = base.headlineLarge.copy(fontWeight = FontWeight.W800), + headlineMedium = base.headlineMedium.copy(fontWeight = FontWeight.W700), + headlineSmall = base.headlineSmall.copy(fontWeight = FontWeight.W600), + ) +} diff --git a/android/app/src/main/res/drawable-anydpi-v24/ic_stat_name.xml b/app/src/main/res/drawable-anydpi-v24/ic_stat_name.xml similarity index 100% rename from android/app/src/main/res/drawable-anydpi-v24/ic_stat_name.xml rename to app/src/main/res/drawable-anydpi-v24/ic_stat_name.xml diff --git a/android/app/src/main/res/drawable-hdpi/ic_action_name.png b/app/src/main/res/drawable-hdpi/ic_action_name.png similarity index 100% rename from android/app/src/main/res/drawable-hdpi/ic_action_name.png rename to app/src/main/res/drawable-hdpi/ic_action_name.png diff --git a/android/app/src/main/res/drawable-hdpi/ic_stat_name.png b/app/src/main/res/drawable-hdpi/ic_stat_name.png similarity index 100% rename from android/app/src/main/res/drawable-hdpi/ic_stat_name.png rename to app/src/main/res/drawable-hdpi/ic_stat_name.png diff --git a/android/app/src/main/res/drawable-mdpi/ic_action_name.png b/app/src/main/res/drawable-mdpi/ic_action_name.png similarity index 100% rename from android/app/src/main/res/drawable-mdpi/ic_action_name.png rename to app/src/main/res/drawable-mdpi/ic_action_name.png diff --git a/android/app/src/main/res/drawable-mdpi/ic_stat_name.png b/app/src/main/res/drawable-mdpi/ic_stat_name.png similarity index 100% rename from android/app/src/main/res/drawable-mdpi/ic_stat_name.png rename to app/src/main/res/drawable-mdpi/ic_stat_name.png diff --git a/android/app/src/main/res/drawable-xhdpi/ic_action_name.png b/app/src/main/res/drawable-xhdpi/ic_action_name.png similarity index 100% rename from android/app/src/main/res/drawable-xhdpi/ic_action_name.png rename to app/src/main/res/drawable-xhdpi/ic_action_name.png diff --git a/android/app/src/main/res/drawable-xhdpi/ic_stat_name.png b/app/src/main/res/drawable-xhdpi/ic_stat_name.png similarity index 100% rename from android/app/src/main/res/drawable-xhdpi/ic_stat_name.png rename to app/src/main/res/drawable-xhdpi/ic_stat_name.png diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_action_name.png b/app/src/main/res/drawable-xxhdpi/ic_action_name.png similarity index 100% rename from android/app/src/main/res/drawable-xxhdpi/ic_action_name.png rename to app/src/main/res/drawable-xxhdpi/ic_action_name.png diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_stat_name.png b/app/src/main/res/drawable-xxhdpi/ic_stat_name.png similarity index 100% rename from android/app/src/main/res/drawable-xxhdpi/ic_stat_name.png rename to app/src/main/res/drawable-xxhdpi/ic_stat_name.png diff --git a/android/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml similarity index 100% rename from android/app/src/main/res/drawable/ic_launcher_foreground.xml rename to app/src/main/res/drawable/ic_launcher_foreground.xml diff --git a/assets/placeholder.png b/app/src/main/res/drawable/placeholder.png similarity index 100% rename from assets/placeholder.png rename to app/src/main/res/drawable/placeholder.png diff --git a/assets/placeholder_thumb.png b/app/src/main/res/drawable/placeholder_thumb.png similarity index 100% rename from assets/placeholder_thumb.png rename to app/src/main/res/drawable/placeholder_thumb.png diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png similarity index 100% rename from android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png rename to app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png similarity index 100% rename from android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png rename to app/src/main/res/mipmap-hdpi/ic_launcher_round.png diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png similarity index 100% rename from android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png rename to app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png similarity index 100% rename from android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png rename to app/src/main/res/mipmap-mdpi/ic_launcher_round.png diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png similarity index 100% rename from android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png rename to app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png similarity index 100% rename from android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png rename to app/src/main/res/mipmap-xhdpi/ic_launcher_round.png diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png similarity index 100% rename from android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png rename to app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png similarity index 100% rename from android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png rename to app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png similarity index 100% rename from android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png rename to app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png similarity index 100% rename from android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png rename to app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png diff --git a/android/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml similarity index 100% rename from android/app/src/main/res/values/ic_launcher_background.xml rename to app/src/main/res/values/ic_launcher_background.xml diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..98d44127 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Subtracks + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 00000000..7175c491 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,8 @@ + + + + diff --git a/app/src/test/kotlin/com/subtracks/ui/HelloScreenshotTest.kt b/app/src/test/kotlin/com/subtracks/ui/HelloScreenshotTest.kt new file mode 100644 index 00000000..35400aec --- /dev/null +++ b/app/src/test/kotlin/com/subtracks/ui/HelloScreenshotTest.kt @@ -0,0 +1,32 @@ +package com.subtracks.ui + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.takahirom.roborazzi.RobolectricDeviceQualifiers +import com.github.takahirom.roborazzi.captureRoboImage +import com.subtracks.ui.theme.SubtracksTheme +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(qualifiers = RobolectricDeviceQualifiers.PixelXL) +class HelloScreenshotTest { + @get:Rule + val composeRule = createAndroidComposeRule() + + @Test + fun hello() { + composeRule.setContent { + SubtracksTheme { + HelloScreen() + } + } + composeRule.onRoot().captureRoboImage("src/test/screenshots/hello.png") + } +} diff --git a/app/src/test/resources/robolectric.properties b/app/src/test/resources/robolectric.properties new file mode 100644 index 00000000..979b5eeb --- /dev/null +++ b/app/src/test/resources/robolectric.properties @@ -0,0 +1 @@ +sdk=34 diff --git a/assets/tag_FILL0_wght400_GRAD0_opsz24.svg b/assets/tag_FILL0_wght400_GRAD0_opsz24.svg deleted file mode 100644 index f834a3cd..00000000 --- a/assets/tag_FILL0_wght400_GRAD0_opsz24.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..97ebae34 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + alias(libs.plugins.android.application) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.serialization) apply false + alias(libs.plugins.compose.compiler) apply false + alias(libs.plugins.roborazzi) apply false +} diff --git a/build.yaml b/build.yaml deleted file mode 100644 index a121b344..00000000 --- a/build.yaml +++ /dev/null @@ -1,11 +0,0 @@ -targets: - $default: - builders: - drift_dev: - options: - sql: - dialect: sqlite - options: - version: "3.38" - modules: - - fts5 diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..d3ec4cb3 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1780453794, + "narHash": "sha256-bXMRa9VTsHSPXL4Cw8R6JJLQeY3Y/IP4+YJCYVmQ7FY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6b316287bae2ee04c9b93c8c858d930fd07d7338", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6b316287bae2ee04c9b93c8c858d930fd07d7338", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..74fcf51b --- /dev/null +++ b/flake.nix @@ -0,0 +1,58 @@ +{ + description = "Subtracks - Kotlin/Jetpack Compose Android development shell"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/6b316287bae2ee04c9b93c8c858d930fd07d7338"; + }; + + outputs = + { nixpkgs, ... }: + let + systems = [ "x86_64-linux" ]; + forEachSystem = nixpkgs.lib.genAttrs systems; + in + { + devShells = forEachSystem ( + system: + let + pkgs = import nixpkgs { + inherit system; + config = { + android_sdk.accept_license = true; + allowUnfree = true; + }; + }; + android = pkgs.androidenv.composeAndroidPackages { + platformVersions = [ "35" ]; + buildToolsVersions = [ "latest" ]; + includeEmulator = false; + includeSystemImages = false; + includeNDK = false; + includeSources = false; + includeCmake = false; + }; + androidSdk = android.androidsdk; + in + { + default = pkgs.mkShell { + packages = [ + pkgs.jdk21 + pkgs.gradle + pkgs.git + androidSdk + android.platform-tools + ]; + + ANDROID_HOME = "${androidSdk}/libexec/android-sdk"; + ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk"; + + shellHook = '' + echo "subtracks dev shell" + echo " java: $(java -version 2>&1 | head -n1)" + echo " ANDROID_HOME: $ANDROID_HOME" + ''; + }; + } + ); + }; +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..c42f32ba --- /dev/null +++ b/gradle.properties @@ -0,0 +1,9 @@ +org.gradle.jvmargs=-Xmx4g -Dfile.encoding=UTF-8 +org.gradle.parallel=true +org.gradle.caching=true + +android.useAndroidX=true +android.nonTransitiveRClass=true +android.builder.sdkDownload=false + +kotlin.code.style=official diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..2ea97f1f --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,74 @@ +[versions] +agp = "8.7.3" +kotlin = "2.1.0" +coreKtx = "1.15.0" +lifecycle = "2.8.7" +activityCompose = "1.9.3" +composeBom = "2024.12.01" +navigation = "2.8.5" +paging = "3.3.5" +koin = "4.0.0" +coroutines = "1.9.0" +serialization = "1.7.3" +sqldelight = "2.0.2" +okhttp = "4.12.0" +retrofit = "2.11.0" +coil = "3.0.4" +media3 = "1.5.0" +datastore = "1.1.1" +material = "1.12.0" +roborazzi = "1.32.2" +robolectric = "4.14.1" +junit = "4.13.2" +androidxTestExtJunit = "1.2.1" +androidxTestCore = "1.6.1" +androidxTestRunner = "1.6.2" + +[libraries] +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" } +androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycle" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } +androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } +androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation" } +androidx-paging-runtime = { group = "androidx.paging", name = "paging-runtime", version.ref = "paging" } +androidx-paging-compose = { group = "androidx.paging", name = "paging-compose", version.ref = "paging" } +androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" } +koin-android = { group = "io.insert-koin", name = "koin-android", version.ref = "koin" } +koin-androidx-compose = { group = "io.insert-koin", name = "koin-androidx-compose", version.ref = "koin" } +kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "serialization" } +sqldelight-android-driver = { group = "app.cash.sqldelight", name = "android-driver", version.ref = "sqldelight" } +sqldelight-sqlite-driver = { group = "app.cash.sqldelight", name = "sqlite-driver", version.ref = "sqldelight" } +okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" } +okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" } +retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" } +coil-compose = { group = "io.coil-kt.coil3", name = "coil-compose", version.ref = "coil" } +coil-network-okhttp = { group = "io.coil-kt.coil3", name = "coil-network-okhttp", version.ref = "coil" } +media3-exoplayer = { group = "androidx.media3", name = "media3-exoplayer", version.ref = "media3" } +media3-session = { group = "androidx.media3", name = "media3-session", version.ref = "media3" } +media3-ui = { group = "androidx.media3", name = "media3-ui", version.ref = "media3" } +material = { group = "com.google.android.material", name = "material", version.ref = "material" } +roborazzi = { group = "io.github.takahirom.roborazzi", name = "roborazzi", version.ref = "roborazzi" } +roborazzi-compose = { group = "io.github.takahirom.roborazzi", name = "roborazzi-compose", version.ref = "roborazzi" } +roborazzi-junit-rule = { group = "io.github.takahirom.roborazzi", name = "roborazzi-junit-rule", version.ref = "roborazzi" } +robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectric" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidxTestExtJunit" } +androidx-test-core = { group = "androidx.test", name = "core", version.ref = "androidxTestCore" } +androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidxTestRunner" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" } +sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..1b33c55baabb587c669f562ae36f953de2481846 GIT binary patch literal 43764 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..5eed7ee8 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/l10n.yaml b/l10n.yaml deleted file mode 100644 index 08ae7412..00000000 --- a/l10n.yaml +++ /dev/null @@ -1,4 +0,0 @@ -arb-dir: lib/l10n -template-arb-file: app_en.arb -nullable-getter: false -untranslated-messages-file: .untranslated-messages.json diff --git a/lib/app/app.dart b/lib/app/app.dart deleted file mode 100644 index ad2eea45..00000000 --- a/lib/app/app.dart +++ /dev/null @@ -1,85 +0,0 @@ -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../database/database.dart'; -import '../services/settings_service.dart'; -import '../state/init.dart'; -import '../state/theme.dart'; - -part 'app.g.dart'; - -class MyApp extends HookConsumerWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final init = ref.watch(initProvider); - return init.when( - data: (_) => const App(), - error: (e, s) => Directionality( - textDirection: TextDirection.ltr, - child: Container( - color: Colors.red[900], - child: Column(children: [ - const SizedBox(height: 100), - Text(e.toString()), - Text(s.toString()), - ]), - ), - ), - loading: () => const CircularProgressIndicator(), - ); - } -} - -@Riverpod(keepAlive: true) -class LastPath extends _$LastPath { - @override - String build() { - return '/settings'; - } - - Future init() async { - final db = ref.read(databaseProvider); - final lastBottomNav = await db.getLastBottomNavState().getSingleOrNull(); - final lastLibrary = await db.getLastLibraryState().getSingleOrNull(); - - if (lastBottomNav == null || lastLibrary == null) return; - - // TODO: replace this with a proper first-time setup flow - final hasActiveSource = ref.read(settingsServiceProvider.select( - (value) => value.activeSource != null, - )); - if (!hasActiveSource) return; - - state = lastBottomNav.tab == 'library' - ? '/library/${lastLibrary.tab}' - : '/${lastBottomNav.tab}'; - } -} - -class App extends HookConsumerWidget { - const App({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final appRouter = ref.watch(routerProvider); - final base = ref.watch(baseThemeProvider); - final lastPath = ref.watch(lastPathProvider); - - return MaterialApp.router( - theme: base.theme, - debugShowCheckedModeBanner: false, - routerDelegate: appRouter.delegate( - initialDeepLink: lastPath, - ), - routeInformationParser: appRouter.defaultRouteParser(), - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: [...AppLocalizations.supportedLocales] - ..moveToTheFront(const Locale('en')), - ); - } -} diff --git a/lib/app/app.g.dart b/lib/app/app.g.dart deleted file mode 100644 index 0ccf7823..00000000 --- a/lib/app/app.g.dart +++ /dev/null @@ -1,23 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'app.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$lastPathHash() => r'25ba5df6bd984fcce011eec40a12fb74627a790a'; - -/// See also [LastPath]. -@ProviderFor(LastPath) -final lastPathProvider = NotifierProvider.internal( - LastPath.new, - name: r'lastPathProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$lastPathHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$LastPath = Notifier; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/app/app_router.dart b/lib/app/app_router.dart deleted file mode 100644 index f1feaf31..00000000 --- a/lib/app/app_router.dart +++ /dev/null @@ -1,140 +0,0 @@ -// ignore_for_file: use_key_in_widget_constructors - -import 'dart:async'; - -import 'package:auto_route/auto_route.dart'; -import 'package:flutter/material.dart'; - -import 'pages/artist_page.dart'; -import 'pages/bottom_nav_page.dart'; -import 'pages/browse_page.dart'; -import 'pages/library_albums_page.dart'; -import 'pages/library_artists_page.dart'; -import 'pages/library_page.dart'; -import 'pages/library_playlists_page.dart'; -import 'pages/library_songs_page.dart'; -import 'pages/now_playing_page.dart'; -import 'pages/search_page.dart'; -import 'pages/settings_page.dart'; -import 'pages/songs_page.dart'; -import 'pages/source_page.dart'; - -part 'app_router.gr.dart'; - -const kCustomTransitionBuilder = TransitionsBuilders.slideRightWithFade; -const kCustomTransitionDuration = 160; - -const itemRoutes = [ - CustomRoute( - path: 'album/:id', - page: AlbumSongsPage, - transitionsBuilder: kCustomTransitionBuilder, - durationInMilliseconds: kCustomTransitionDuration, - reverseDurationInMilliseconds: kCustomTransitionDuration, - ), - CustomRoute( - path: 'artist/:id', - page: ArtistPage, - transitionsBuilder: kCustomTransitionBuilder, - durationInMilliseconds: kCustomTransitionDuration, - reverseDurationInMilliseconds: kCustomTransitionDuration, - ), - CustomRoute( - path: 'playlist/:id', - page: PlaylistSongsPage, - transitionsBuilder: kCustomTransitionBuilder, - durationInMilliseconds: kCustomTransitionDuration, - reverseDurationInMilliseconds: kCustomTransitionDuration, - ), - CustomRoute( - path: 'genre/:genre', - page: GenreSongsPage, - transitionsBuilder: kCustomTransitionBuilder, - durationInMilliseconds: kCustomTransitionDuration, - reverseDurationInMilliseconds: kCustomTransitionDuration, - ), -]; - -class EmptyRouterPage extends AutoRouter { - const EmptyRouterPage({Key? key}) - : super( - key: key, - inheritNavigatorObservers: false, - ); -} - -@MaterialAutoRouter( - replaceInRouteName: 'Page,Route', - routes: [ - AutoRoute(path: '/', name: 'RootRouter', page: EmptyRouterPage, children: [ - AutoRoute(path: '', page: BottomNavTabsPage, children: [ - AutoRoute( - path: 'library', - name: 'LibraryRouter', - page: EmptyRouterPage, - children: [ - AutoRoute(path: '', page: LibraryTabsPage, children: [ - AutoRoute(path: 'albums', page: LibraryAlbumsPage), - AutoRoute(path: 'artists', page: LibraryArtistsPage), - AutoRoute(path: 'playlists', page: LibraryPlaylistsPage), - AutoRoute(path: 'songs', page: LibrarySongsPage), - ]), - ...itemRoutes, - ]), - AutoRoute( - path: 'browse', - name: 'BrowseRouter', - page: EmptyRouterPage, - children: [ - AutoRoute(path: '', page: BrowsePage), - ...itemRoutes, - ]), - AutoRoute( - path: 'search', - name: 'SearchRouter', - page: EmptyRouterPage, - children: [ - AutoRoute(path: '', page: SearchPage), - ...itemRoutes, - ]), - AutoRoute( - path: 'settings', - name: 'SettingsRouter', - page: EmptyRouterPage, - children: [ - AutoRoute(path: '', page: SettingsPage), - CustomRoute( - path: 'source/:id', - page: SourcePage, - transitionsBuilder: kCustomTransitionBuilder, - durationInMilliseconds: kCustomTransitionDuration, - reverseDurationInMilliseconds: kCustomTransitionDuration, - ), - ]), - ]), - ]), - CustomRoute( - path: '/now-playing', - page: NowPlayingPage, - transitionsBuilder: TransitionsBuilders.slideBottom, - durationInMilliseconds: 200, - reverseDurationInMilliseconds: 160, - ), - ], -) -class AppRouter extends _$AppRouter {} - -class TabObserver extends AutoRouterObserver { - final StreamController _controller = StreamController.broadcast(); - Stream get path => _controller.stream; - - @override - void didInitTabRoute(TabPageRoute route, TabPageRoute? previousRoute) { - _controller.add(route.path); - } - - @override - void didChangeTabRoute(TabPageRoute route, TabPageRoute previousRoute) { - _controller.add(route.path); - } -} diff --git a/lib/app/app_router.gr.dart b/lib/app/app_router.gr.dart deleted file mode 100644 index ed82a8dc..00000000 --- a/lib/app/app_router.gr.dart +++ /dev/null @@ -1,720 +0,0 @@ -// ************************************************************************** -// AutoRouteGenerator -// ************************************************************************** - -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// AutoRouteGenerator -// ************************************************************************** -// -// ignore_for_file: type=lint - -part of 'app_router.dart'; - -class _$AppRouter extends RootStackRouter { - _$AppRouter([GlobalKey? navigatorKey]) : super(navigatorKey); - - @override - final Map pagesMap = { - RootRouter.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const EmptyRouterPage(), - ); - }, - NowPlayingRoute.name: (routeData) { - return CustomPage( - routeData: routeData, - child: const NowPlayingPage(), - transitionsBuilder: TransitionsBuilders.slideBottom, - durationInMilliseconds: 200, - reverseDurationInMilliseconds: 160, - opaque: true, - barrierDismissible: false, - ); - }, - BottomNavTabsRoute.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const BottomNavTabsPage(), - ); - }, - LibraryRouter.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const EmptyRouterPage(), - ); - }, - BrowseRouter.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const EmptyRouterPage(), - ); - }, - SearchRouter.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const EmptyRouterPage(), - ); - }, - SettingsRouter.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const EmptyRouterPage(), - ); - }, - LibraryTabsRoute.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const LibraryTabsPage(), - ); - }, - AlbumSongsRoute.name: (routeData) { - final pathParams = routeData.inheritedPathParams; - final args = routeData.argsAs( - orElse: () => AlbumSongsRouteArgs(id: pathParams.getString('id'))); - return CustomPage( - routeData: routeData, - child: AlbumSongsPage( - key: args.key, - id: args.id, - ), - transitionsBuilder: TransitionsBuilders.slideRightWithFade, - durationInMilliseconds: 160, - reverseDurationInMilliseconds: 160, - opaque: true, - barrierDismissible: false, - ); - }, - ArtistRoute.name: (routeData) { - final pathParams = routeData.inheritedPathParams; - final args = routeData.argsAs( - orElse: () => ArtistRouteArgs(id: pathParams.getString('id'))); - return CustomPage( - routeData: routeData, - child: ArtistPage( - key: args.key, - id: args.id, - ), - transitionsBuilder: TransitionsBuilders.slideRightWithFade, - durationInMilliseconds: 160, - reverseDurationInMilliseconds: 160, - opaque: true, - barrierDismissible: false, - ); - }, - PlaylistSongsRoute.name: (routeData) { - final pathParams = routeData.inheritedPathParams; - final args = routeData.argsAs( - orElse: () => PlaylistSongsRouteArgs(id: pathParams.getString('id'))); - return CustomPage( - routeData: routeData, - child: PlaylistSongsPage( - key: args.key, - id: args.id, - ), - transitionsBuilder: TransitionsBuilders.slideRightWithFade, - durationInMilliseconds: 160, - reverseDurationInMilliseconds: 160, - opaque: true, - barrierDismissible: false, - ); - }, - GenreSongsRoute.name: (routeData) { - final pathParams = routeData.inheritedPathParams; - final args = routeData.argsAs( - orElse: () => - GenreSongsRouteArgs(genre: pathParams.getString('genre'))); - return CustomPage( - routeData: routeData, - child: GenreSongsPage( - key: args.key, - genre: args.genre, - ), - transitionsBuilder: TransitionsBuilders.slideRightWithFade, - durationInMilliseconds: 160, - reverseDurationInMilliseconds: 160, - opaque: true, - barrierDismissible: false, - ); - }, - LibraryAlbumsRoute.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const LibraryAlbumsPage(), - ); - }, - LibraryArtistsRoute.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const LibraryArtistsPage(), - ); - }, - LibraryPlaylistsRoute.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const LibraryPlaylistsPage(), - ); - }, - LibrarySongsRoute.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const LibrarySongsPage(), - ); - }, - BrowseRoute.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const BrowsePage(), - ); - }, - SearchRoute.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const SearchPage(), - ); - }, - SettingsRoute.name: (routeData) { - return MaterialPageX( - routeData: routeData, - child: const SettingsPage(), - ); - }, - SourceRoute.name: (routeData) { - final pathParams = routeData.inheritedPathParams; - final args = routeData.argsAs( - orElse: () => SourceRouteArgs(id: pathParams.optInt('id'))); - return CustomPage( - routeData: routeData, - child: SourcePage( - key: args.key, - id: args.id, - ), - transitionsBuilder: TransitionsBuilders.slideRightWithFade, - durationInMilliseconds: 160, - reverseDurationInMilliseconds: 160, - opaque: true, - barrierDismissible: false, - ); - }, - }; - - @override - List get routes => [ - RouteConfig( - RootRouter.name, - path: '/', - children: [ - RouteConfig( - BottomNavTabsRoute.name, - path: '', - parent: RootRouter.name, - children: [ - RouteConfig( - LibraryRouter.name, - path: 'library', - parent: BottomNavTabsRoute.name, - children: [ - RouteConfig( - LibraryTabsRoute.name, - path: '', - parent: LibraryRouter.name, - children: [ - RouteConfig( - LibraryAlbumsRoute.name, - path: 'albums', - parent: LibraryTabsRoute.name, - ), - RouteConfig( - LibraryArtistsRoute.name, - path: 'artists', - parent: LibraryTabsRoute.name, - ), - RouteConfig( - LibraryPlaylistsRoute.name, - path: 'playlists', - parent: LibraryTabsRoute.name, - ), - RouteConfig( - LibrarySongsRoute.name, - path: 'songs', - parent: LibraryTabsRoute.name, - ), - ], - ), - RouteConfig( - AlbumSongsRoute.name, - path: 'album/:id', - parent: LibraryRouter.name, - ), - RouteConfig( - ArtistRoute.name, - path: 'artist/:id', - parent: LibraryRouter.name, - ), - RouteConfig( - PlaylistSongsRoute.name, - path: 'playlist/:id', - parent: LibraryRouter.name, - ), - RouteConfig( - GenreSongsRoute.name, - path: 'genre/:genre', - parent: LibraryRouter.name, - ), - ], - ), - RouteConfig( - BrowseRouter.name, - path: 'browse', - parent: BottomNavTabsRoute.name, - children: [ - RouteConfig( - BrowseRoute.name, - path: '', - parent: BrowseRouter.name, - ), - RouteConfig( - AlbumSongsRoute.name, - path: 'album/:id', - parent: BrowseRouter.name, - ), - RouteConfig( - ArtistRoute.name, - path: 'artist/:id', - parent: BrowseRouter.name, - ), - RouteConfig( - PlaylistSongsRoute.name, - path: 'playlist/:id', - parent: BrowseRouter.name, - ), - RouteConfig( - GenreSongsRoute.name, - path: 'genre/:genre', - parent: BrowseRouter.name, - ), - ], - ), - RouteConfig( - SearchRouter.name, - path: 'search', - parent: BottomNavTabsRoute.name, - children: [ - RouteConfig( - SearchRoute.name, - path: '', - parent: SearchRouter.name, - ), - RouteConfig( - AlbumSongsRoute.name, - path: 'album/:id', - parent: SearchRouter.name, - ), - RouteConfig( - ArtistRoute.name, - path: 'artist/:id', - parent: SearchRouter.name, - ), - RouteConfig( - PlaylistSongsRoute.name, - path: 'playlist/:id', - parent: SearchRouter.name, - ), - RouteConfig( - GenreSongsRoute.name, - path: 'genre/:genre', - parent: SearchRouter.name, - ), - ], - ), - RouteConfig( - SettingsRouter.name, - path: 'settings', - parent: BottomNavTabsRoute.name, - children: [ - RouteConfig( - SettingsRoute.name, - path: '', - parent: SettingsRouter.name, - ), - RouteConfig( - SourceRoute.name, - path: 'source/:id', - parent: SettingsRouter.name, - ), - ], - ), - ], - ) - ], - ), - RouteConfig( - NowPlayingRoute.name, - path: '/now-playing', - ), - ]; -} - -/// generated route for -/// [EmptyRouterPage] -class RootRouter extends PageRouteInfo { - const RootRouter({List? children}) - : super( - RootRouter.name, - path: '/', - initialChildren: children, - ); - - static const String name = 'RootRouter'; -} - -/// generated route for -/// [NowPlayingPage] -class NowPlayingRoute extends PageRouteInfo { - const NowPlayingRoute() - : super( - NowPlayingRoute.name, - path: '/now-playing', - ); - - static const String name = 'NowPlayingRoute'; -} - -/// generated route for -/// [BottomNavTabsPage] -class BottomNavTabsRoute extends PageRouteInfo { - const BottomNavTabsRoute({List? children}) - : super( - BottomNavTabsRoute.name, - path: '', - initialChildren: children, - ); - - static const String name = 'BottomNavTabsRoute'; -} - -/// generated route for -/// [EmptyRouterPage] -class LibraryRouter extends PageRouteInfo { - const LibraryRouter({List? children}) - : super( - LibraryRouter.name, - path: 'library', - initialChildren: children, - ); - - static const String name = 'LibraryRouter'; -} - -/// generated route for -/// [EmptyRouterPage] -class BrowseRouter extends PageRouteInfo { - const BrowseRouter({List? children}) - : super( - BrowseRouter.name, - path: 'browse', - initialChildren: children, - ); - - static const String name = 'BrowseRouter'; -} - -/// generated route for -/// [EmptyRouterPage] -class SearchRouter extends PageRouteInfo { - const SearchRouter({List? children}) - : super( - SearchRouter.name, - path: 'search', - initialChildren: children, - ); - - static const String name = 'SearchRouter'; -} - -/// generated route for -/// [EmptyRouterPage] -class SettingsRouter extends PageRouteInfo { - const SettingsRouter({List? children}) - : super( - SettingsRouter.name, - path: 'settings', - initialChildren: children, - ); - - static const String name = 'SettingsRouter'; -} - -/// generated route for -/// [LibraryTabsPage] -class LibraryTabsRoute extends PageRouteInfo { - const LibraryTabsRoute({List? children}) - : super( - LibraryTabsRoute.name, - path: '', - initialChildren: children, - ); - - static const String name = 'LibraryTabsRoute'; -} - -/// generated route for -/// [AlbumSongsPage] -class AlbumSongsRoute extends PageRouteInfo { - AlbumSongsRoute({ - Key? key, - required String id, - }) : super( - AlbumSongsRoute.name, - path: 'album/:id', - args: AlbumSongsRouteArgs( - key: key, - id: id, - ), - rawPathParams: {'id': id}, - ); - - static const String name = 'AlbumSongsRoute'; -} - -class AlbumSongsRouteArgs { - const AlbumSongsRouteArgs({ - this.key, - required this.id, - }); - - final Key? key; - - final String id; - - @override - String toString() { - return 'AlbumSongsRouteArgs{key: $key, id: $id}'; - } -} - -/// generated route for -/// [ArtistPage] -class ArtistRoute extends PageRouteInfo { - ArtistRoute({ - Key? key, - required String id, - }) : super( - ArtistRoute.name, - path: 'artist/:id', - args: ArtistRouteArgs( - key: key, - id: id, - ), - rawPathParams: {'id': id}, - ); - - static const String name = 'ArtistRoute'; -} - -class ArtistRouteArgs { - const ArtistRouteArgs({ - this.key, - required this.id, - }); - - final Key? key; - - final String id; - - @override - String toString() { - return 'ArtistRouteArgs{key: $key, id: $id}'; - } -} - -/// generated route for -/// [PlaylistSongsPage] -class PlaylistSongsRoute extends PageRouteInfo { - PlaylistSongsRoute({ - Key? key, - required String id, - }) : super( - PlaylistSongsRoute.name, - path: 'playlist/:id', - args: PlaylistSongsRouteArgs( - key: key, - id: id, - ), - rawPathParams: {'id': id}, - ); - - static const String name = 'PlaylistSongsRoute'; -} - -class PlaylistSongsRouteArgs { - const PlaylistSongsRouteArgs({ - this.key, - required this.id, - }); - - final Key? key; - - final String id; - - @override - String toString() { - return 'PlaylistSongsRouteArgs{key: $key, id: $id}'; - } -} - -/// generated route for -/// [GenreSongsPage] -class GenreSongsRoute extends PageRouteInfo { - GenreSongsRoute({ - Key? key, - required String genre, - }) : super( - GenreSongsRoute.name, - path: 'genre/:genre', - args: GenreSongsRouteArgs( - key: key, - genre: genre, - ), - rawPathParams: {'genre': genre}, - ); - - static const String name = 'GenreSongsRoute'; -} - -class GenreSongsRouteArgs { - const GenreSongsRouteArgs({ - this.key, - required this.genre, - }); - - final Key? key; - - final String genre; - - @override - String toString() { - return 'GenreSongsRouteArgs{key: $key, genre: $genre}'; - } -} - -/// generated route for -/// [LibraryAlbumsPage] -class LibraryAlbumsRoute extends PageRouteInfo { - const LibraryAlbumsRoute() - : super( - LibraryAlbumsRoute.name, - path: 'albums', - ); - - static const String name = 'LibraryAlbumsRoute'; -} - -/// generated route for -/// [LibraryArtistsPage] -class LibraryArtistsRoute extends PageRouteInfo { - const LibraryArtistsRoute() - : super( - LibraryArtistsRoute.name, - path: 'artists', - ); - - static const String name = 'LibraryArtistsRoute'; -} - -/// generated route for -/// [LibraryPlaylistsPage] -class LibraryPlaylistsRoute extends PageRouteInfo { - const LibraryPlaylistsRoute() - : super( - LibraryPlaylistsRoute.name, - path: 'playlists', - ); - - static const String name = 'LibraryPlaylistsRoute'; -} - -/// generated route for -/// [LibrarySongsPage] -class LibrarySongsRoute extends PageRouteInfo { - const LibrarySongsRoute() - : super( - LibrarySongsRoute.name, - path: 'songs', - ); - - static const String name = 'LibrarySongsRoute'; -} - -/// generated route for -/// [BrowsePage] -class BrowseRoute extends PageRouteInfo { - const BrowseRoute() - : super( - BrowseRoute.name, - path: '', - ); - - static const String name = 'BrowseRoute'; -} - -/// generated route for -/// [SearchPage] -class SearchRoute extends PageRouteInfo { - const SearchRoute() - : super( - SearchRoute.name, - path: '', - ); - - static const String name = 'SearchRoute'; -} - -/// generated route for -/// [SettingsPage] -class SettingsRoute extends PageRouteInfo { - const SettingsRoute() - : super( - SettingsRoute.name, - path: '', - ); - - static const String name = 'SettingsRoute'; -} - -/// generated route for -/// [SourcePage] -class SourceRoute extends PageRouteInfo { - SourceRoute({ - Key? key, - int? id, - }) : super( - SourceRoute.name, - path: 'source/:id', - args: SourceRouteArgs( - key: key, - id: id, - ), - rawPathParams: {'id': id}, - ); - - static const String name = 'SourceRoute'; -} - -class SourceRouteArgs { - const SourceRouteArgs({ - this.key, - this.id, - }); - - final Key? key; - - final int? id; - - @override - String toString() { - return 'SourceRouteArgs{key: $key, id: $id}'; - } -} diff --git a/lib/app/buttons.dart b/lib/app/buttons.dart deleted file mode 100644 index f40fa965..00000000 --- a/lib/app/buttons.dart +++ /dev/null @@ -1,63 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -class ShuffleFab extends StatelessWidget { - final void Function()? onPressed; - - const ShuffleFab({ - super.key, - this.onPressed, - }); - - @override - Widget build(BuildContext context) { - final l = AppLocalizations.of(context); - - return FloatingActionButton( - heroTag: null, - onPressed: onPressed, - tooltip: l.actionsCancel, - child: const Icon(Icons.shuffle_rounded), - ); - } -} - -class RadioPlayFab extends StatelessWidget { - final void Function()? onPressed; - - const RadioPlayFab({ - super.key, - this.onPressed, - }); - - @override - Widget build(BuildContext context) { - return FloatingActionButton( - heroTag: null, - onPressed: onPressed, - child: Stack( - clipBehavior: Clip.none, - children: [ - const Icon(Icons.radio_rounded), - Positioned( - bottom: -11, - right: -10, - child: Icon( - Icons.play_arrow_rounded, - color: Theme.of(context).colorScheme.primaryContainer, - size: 26, - ), - ), - const Positioned( - bottom: -6, - right: -5, - child: Icon( - Icons.play_arrow_rounded, - size: 16, - ), - ), - ], - ), - ); - } -} diff --git a/lib/app/context_menus.dart b/lib/app/context_menus.dart deleted file mode 100644 index c051d13c..00000000 --- a/lib/app/context_menus.dart +++ /dev/null @@ -1,414 +0,0 @@ -// ignore_for_file: use_build_context_synchronously - -import 'dart:async'; - -import 'package:auto_route/auto_route.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -import '../models/music.dart'; -import '../services/cache_service.dart'; -import '../state/theme.dart'; -import 'app_router.dart'; -import 'hooks/use_download_actions.dart'; -import 'images.dart'; - -enum MenuSize { - small, - medium, -} - -Future showContextMenu({ - required BuildContext context, - required WidgetRef ref, - required WidgetBuilder builder, -}) { - return showModalBottomSheet( - backgroundColor: ref.read(baseThemeProvider).theme.colorScheme.background, - useRootNavigator: true, - isScrollControlled: true, - context: context, - builder: builder, - ); -} - -class BottomSheetMenu extends HookConsumerWidget { - final Widget child; - final MenuSize size; - - const BottomSheetMenu({ - super.key, - required this.child, - this.size = MenuSize.medium, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final theme = ref.watch(baseThemeProvider); - final height = size == MenuSize.medium ? 0.4 : 0.25; - - return Theme( - data: theme.theme, - child: DraggableScrollableSheet( - expand: false, - initialChildSize: height, - maxChildSize: height, - minChildSize: height - 0.05, - snap: true, - snapSizes: [height - 0.05, height], - builder: (context, scrollController) { - return PrimaryScrollController( - controller: scrollController, - child: SizedBox( - child: Padding( - padding: const EdgeInsets.only(top: 8), - child: child, - ), - ), - ); - }, - ), - ); - } -} - -class AlbumContextMenu extends HookConsumerWidget { - final Album album; - - const AlbumContextMenu({ - super.key, - required this.album, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final downloadActions = useAlbumDownloadActions( - context: context, - ref: ref, - album: album, - ); - - return ListView( - children: [ - _AlbumHeader(album: album), - const SizedBox(height: 8), - const _Star(), - if (album.artistId != null) _ViewArtist(id: album.artistId!), - for (var action in downloadActions) - _DownloadAction(key: ValueKey(action.type), downloadAction: action), - ], - ); - } -} - -class SongContextMenu extends HookConsumerWidget { - final Song song; - - const SongContextMenu({ - super.key, - required this.song, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return ListView( - children: [ - _SongHeader(song: song), - const SizedBox(height: 8), - const _Star(), - if (song.artistId != null) _ViewArtist(id: song.artistId!), - if (song.albumId != null) _ViewAlbum(id: song.albumId!), - // const _DownloadAction(), - ], - ); - } -} - -class ArtistContextMenu extends HookConsumerWidget { - final Artist artist; - - const ArtistContextMenu({ - super.key, - required this.artist, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return ListView( - children: [ - _ArtistHeader(artist: artist), - const SizedBox(height: 8), - const _Star(), - // const _Download(), - ], - ); - } -} - -class PlaylistContextMenu extends HookConsumerWidget { - final Playlist playlist; - - const PlaylistContextMenu({ - super.key, - required this.playlist, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final downloadActions = usePlaylistDownloadActions( - context: context, - ref: ref, - playlist: playlist, - ); - - return ListView( - children: [ - _PlaylistHeader(playlist: playlist), - const SizedBox(height: 8), - for (var action in downloadActions) - _DownloadAction(key: ValueKey(action.type), downloadAction: action), - ], - ); - } -} - -class _AlbumHeader extends HookConsumerWidget { - final Album album; - - const _AlbumHeader({ - required this.album, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final cache = ref.watch(cacheServiceProvider); - - return _Header( - title: album.name, - subtitle: album.albumArtist, - image: CardClip( - child: UriCacheInfoImage( - cache: cache.albumArt(album, thumbnail: true), - ), - ), - ); - } -} - -class _SongHeader extends HookConsumerWidget { - final Song song; - - const _SongHeader({ - required this.song, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return _Header( - title: song.title, - subtitle: song.artist, - image: SongAlbumArt(song: song, square: false), - ); - } -} - -class _ArtistHeader extends HookConsumerWidget { - final Artist artist; - - const _ArtistHeader({ - required this.artist, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - return _Header( - title: artist.name, - subtitle: l.resourcesAlbumCount(artist.albumCount), - image: CircleClip(child: ArtistArtImage(artistId: artist.id)), - ); - } -} - -class _PlaylistHeader extends HookConsumerWidget { - final Playlist playlist; - - const _PlaylistHeader({ - required this.playlist, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final cache = ref.watch(cacheServiceProvider); - final l = AppLocalizations.of(context); - return _Header( - title: playlist.name, - subtitle: l.resourcesSongCount(playlist.songCount), - image: CardClip( - child: UriCacheInfoImage( - cache: cache.playlistArt(playlist, thumbnail: true), - ), - ), - ); - } -} - -class _Header extends HookConsumerWidget { - final String title; - final String? subtitle; - final Widget image; - - const _Header({ - required this.title, - this.subtitle, - required this.image, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final theme = Theme.of(context); - - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 80, width: 80, child: image), - const SizedBox(width: 16), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(title, style: theme.textTheme.titleLarge), - if (subtitle != null) - Text(subtitle!, style: theme.textTheme.titleSmall), - ], - ), - ) - ], - ), - ); - } -} - -class _Star extends HookConsumerWidget { - const _Star(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - return _MenuItem( - title: l.actionsStar, - icon: const Icon(Icons.star_outline_rounded), - onTap: () {}, - ); - } -} - -class _DownloadAction extends HookConsumerWidget { - final DownloadAction downloadAction; - - const _DownloadAction({ - super.key, - required this.downloadAction, - }); - - String _actionText(AppLocalizations l) { - switch (downloadAction.type) { - case DownloadActionType.download: - return l.actionsDownload; - case DownloadActionType.cancel: - return l.actionsDownloadCancel; - case DownloadActionType.delete: - return l.actionsDownloadDelete; - } - } - - @override - Widget build(BuildContext context, WidgetRef ref) { - return _MenuItem( - title: _actionText(AppLocalizations.of(context)), - icon: downloadAction.iconBuilder(context), - onTap: downloadAction.action, - ); - } -} - -class _ViewArtist extends HookConsumerWidget { - final String id; - - const _ViewArtist({ - required this.id, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - return _MenuItem( - title: l.resourcesArtistActionsView, - icon: const Icon(Icons.person_rounded), - onTap: () async { - final router = context.router; - - await router.pop(); - if (router.currentPath == '/now-playing') { - await router.pop(); - await router.navigate(const LibraryRouter()); - } - await router.navigate(ArtistRoute(id: id)); - }, - ); - } -} - -class _ViewAlbum extends HookConsumerWidget { - final String id; - - const _ViewAlbum({ - required this.id, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - return _MenuItem( - title: l.resourcesAlbumActionsView, - icon: const Icon(Icons.album_rounded), - onTap: () async { - final router = context.router; - - await router.pop(); - if (router.currentPath == '/now-playing') { - await router.pop(); - await router.navigate(const LibraryRouter()); - } - await router.navigate(AlbumSongsRoute(id: id)); - }, - ); - } -} - -class _MenuItem extends StatelessWidget { - final String title; - final Widget icon; - final FutureOr Function()? onTap; - - const _MenuItem({ - required this.title, - required this.icon, - this.onTap, - }); - - @override - Widget build(BuildContext context) { - return ListTile( - title: Text(title), - leading: Padding( - padding: const EdgeInsetsDirectional.only(start: 8), - child: icon, - ), - onTap: onTap, - ); - } -} diff --git a/lib/app/dialogs.dart b/lib/app/dialogs.dart deleted file mode 100644 index 218aa0c5..00000000 --- a/lib/app/dialogs.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -import '../models/support.dart'; -import '../state/theme.dart'; - -class DeleteDialog extends HookConsumerWidget { - const DeleteDialog({ - super.key, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final theme = ref.watch(baseThemeProvider); - - final l = AppLocalizations.of(context); - - return Theme( - data: theme.theme, - child: AlertDialog( - title: Text(l.resourcesSongListDeleteAllTitle), - content: Text(l.resourcesSongListDeleteAllContent), - actions: [ - FilledButton.tonal( - onPressed: () => Navigator.pop(context, false), - child: Text(l.actionsCancel), - ), - FilledButton.icon( - onPressed: () => Navigator.pop(context, true), - label: Text(l.actionsDelete), - icon: const Icon(Icons.delete_forever_rounded), - ), - ], - ), - ); - } -} - -class MultipleChoiceDialog extends HookConsumerWidget { - final String title; - final T current; - final IList options; - - const MultipleChoiceDialog({ - super.key, - required this.title, - required this.current, - required this.options, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - final state = useState(current); - - List choices = []; - for (var opt in options) { - final value = opt.map( - (value) => null, - int: (value) => value.option, - string: (value) => value.option, - ) as T; - choices.add(RadioListTile( - value: value, - groupValue: state.value, - title: Text(opt.title), - onChanged: (value) => state.value = value as T, - )); - } - - return AlertDialog( - title: Text(title), - contentPadding: const EdgeInsets.symmetric(vertical: 20), - content: Material( - type: MaterialType.transparency, - child: SingleChildScrollView( - child: Column(children: choices), - ), - ), - actions: [ - FilledButton.tonal( - onPressed: () => Navigator.pop(context, null), - child: Text(l.actionsCancel), - ), - FilledButton.icon( - onPressed: () => Navigator.pop(context, state.value), - label: Text(l.actionsOk), - icon: const Icon(Icons.check_rounded), - ), - ], - ); - } -} diff --git a/lib/app/gradient.dart b/lib/app/gradient.dart deleted file mode 100644 index b589fa89..00000000 --- a/lib/app/gradient.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -import '../models/support.dart'; -import '../state/theme.dart'; - -class MediaItemGradient extends ConsumerWidget { - const MediaItemGradient({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final colors = ref.watch(mediaItemThemeProvider).valueOrNull; - return BackgroundGradient(colors: colors); - } -} - -class AlbumArtGradient extends ConsumerWidget { - final String id; - - const AlbumArtGradient({ - super.key, - required this.id, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final colors = ref.watch(albumArtThemeProvider(id)).valueOrNull; - return BackgroundGradient(colors: colors); - } -} - -class PlaylistArtGradient extends ConsumerWidget { - final String id; - - const PlaylistArtGradient({ - super.key, - required this.id, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final colors = ref.watch(playlistArtThemeProvider(id)).valueOrNull; - return BackgroundGradient(colors: colors); - } -} - -class BackgroundGradient extends HookConsumerWidget { - final ColorTheme? colors; - - const BackgroundGradient({ - super.key, - this.colors, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final base = ref.watch(baseThemeProvider); - - return SizedBox( - width: double.infinity, - height: MediaQuery.of(context).size.height, - child: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - colors?.gradientHigh ?? base.gradientHigh, - colors?.gradientLow ?? base.gradientLow, - ], - ), - ), - ), - ); - } -} diff --git a/lib/app/hooks/use_download_actions.dart b/lib/app/hooks/use_download_actions.dart deleted file mode 100644 index 4d2aa70f..00000000 --- a/lib/app/hooks/use_download_actions.dart +++ /dev/null @@ -1,149 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -import '../../models/music.dart'; -import '../../models/support.dart'; -import '../../services/download_service.dart'; -import '../../state/music.dart'; -import '../../state/settings.dart'; -import '../dialogs.dart'; - -enum DownloadActionType { - download, - cancel, - delete, -} - -class DownloadAction { - final DownloadActionType type; - final WidgetBuilder iconBuilder; - final FutureOr Function()? action; - - const DownloadAction({ - required this.type, - required this.iconBuilder, - this.action, - }); -} - -List useAlbumDownloadActions({ - required BuildContext context, - required WidgetRef ref, - required Album album, -}) { - final status = ref.watch(albumDownloadStatusProvider(album.id)).valueOrNull; - - return useListDownloadActions( - context: context, - ref: ref, - list: album, - status: status, - onDownload: () => - ref.read(downloadServiceProvider.notifier).downloadAlbum(album), - onDelete: () => - ref.read(downloadServiceProvider.notifier).deleteAlbum(album), - onCancel: () => - ref.read(downloadServiceProvider.notifier).cancelAlbum(album), - ); -} - -List usePlaylistDownloadActions({ - required BuildContext context, - required WidgetRef ref, - required Playlist playlist, -}) { - final status = - ref.watch(playlistDownloadStatusProvider(playlist.id)).valueOrNull; - - return useListDownloadActions( - context: context, - ref: ref, - list: playlist, - status: status, - onDownload: () => - ref.read(downloadServiceProvider.notifier).downloadPlaylist(playlist), - onDelete: () => - ref.read(downloadServiceProvider.notifier).deletePlaylist(playlist), - onCancel: () => - ref.read(downloadServiceProvider.notifier).cancelPlaylist(playlist), - ); -} - -List useListDownloadActions({ - required BuildContext context, - required WidgetRef ref, - required SourceIdentifiable list, - required ListDownloadStatus? status, - required FutureOr Function() onDelete, - required FutureOr Function() onCancel, - required FutureOr Function() onDownload, -}) { - status ??= const ListDownloadStatus(total: 0, downloaded: 0, downloading: 0); - - final sourceId = SourceId.from(list); - final offline = ref.watch(offlineModeProvider); - final listDownloadInProgress = ref.watch(downloadServiceProvider - .select((value) => value.listDownloads.contains(sourceId))); - final listDeleteInProgress = ref.watch(downloadServiceProvider - .select((value) => value.deletes.contains(sourceId))); - final listCancelInProgress = ref.watch(downloadServiceProvider - .select((value) => value.listCancels.contains(sourceId))); - - DownloadAction delete() { - return DownloadAction( - type: DownloadActionType.delete, - iconBuilder: (context) => const Icon(Icons.delete_forever_rounded), - action: listDeleteInProgress - ? null - : () async { - final ok = await showDialog( - context: context, - builder: (context) => const DeleteDialog(), - ); - if (ok == true) { - await onDelete(); - } - }, - ); - } - - DownloadAction cancel() { - return DownloadAction( - type: DownloadActionType.cancel, - iconBuilder: (context) => Stack( - alignment: Alignment.center, - children: const [ - Icon(Icons.cancel_rounded), - SizedBox( - height: 32, - width: 32, - child: CircularProgressIndicator( - strokeWidth: 3, - ), - ), - ], - ), - action: listCancelInProgress ? null : onCancel, - ); - } - - DownloadAction download() { - return DownloadAction( - type: DownloadActionType.download, - iconBuilder: (context) => const Icon(Icons.download_rounded), - action: !offline ? onDownload : null, - ); - } - - if (status.total == status.downloaded) { - return [delete()]; - } else if (status.downloading == 0 && status.downloaded > 0) { - return [download(), delete()]; - } else if (listDownloadInProgress || status.downloading > 0) { - return [cancel()]; - } else { - return [download()]; - } -} diff --git a/lib/app/hooks/use_list_query_paging_controller.dart b/lib/app/hooks/use_list_query_paging_controller.dart deleted file mode 100644 index c44d6f18..00000000 --- a/lib/app/hooks/use_list_query_paging_controller.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'dart:async'; - -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; - -import '../../models/query.dart'; -import '../../services/sync_service.dart'; -import '../../state/settings.dart'; -import '../pages/library_page.dart'; -import 'use_paging_controller.dart'; - -PagingController useLibraryPagingController( - WidgetRef ref, { - required int libraryTabIndex, - required FutureOr> Function(ListQuery query) getItems, -}) { - final queryProvider = libraryListQueryProvider(libraryTabIndex).select( - (value) => value.query, - ); - final query = useState(ref.read(queryProvider)); - - final onPageRequest = useCallback( - (int pageKey, PagingController pagingController) => - _pageRequest(getItems, query.value, pageKey, pagingController), - [query.value], - ); - - final pagingController = usePagingController( - firstPageKey: query.value.page.offset, - onPageRequest: onPageRequest, - ); - - ref.listen(queryProvider, (_, next) { - query.value = next; - pagingController.refresh(); - }); - - ref.listen(syncServiceProvider, (_, __) => pagingController.refresh()); - ref.listen(sourceIdProvider, (_, __) => pagingController.refresh()); - ref.listen(offlineModeProvider, (_, __) => pagingController.refresh()); - - return pagingController; -} - -PagingController useListQueryPagingController( - WidgetRef ref, { - required ListQuery query, - required FutureOr> Function(ListQuery query) getItems, -}) { - final onPageRequest = useCallback( - (int pageKey, PagingController pagingController) => - _pageRequest(getItems, query, pageKey, pagingController), - [query], - ); - - final pagingController = usePagingController( - firstPageKey: query.page.offset, - onPageRequest: onPageRequest, - ); - - return pagingController; -} - -Future _pageRequest( - FutureOr> Function(ListQuery query) getItems, - ListQuery query, - int pageKey, - PagingController pagingController, -) async { - try { - final newItems = await getItems(query.copyWith.page(offset: pageKey)); - - final isFirstPage = newItems.isNotEmpty && pageKey == 0; - final alreadyHasItems = pagingController.itemList != null && - pagingController.itemList!.isNotEmpty; - if (isFirstPage && alreadyHasItems) { - return; - } - - final isLastPage = newItems.length < query.page.limit; - if (isLastPage) { - pagingController.appendLastPage(newItems); - } else { - final nextPageKey = pageKey + newItems.length; - pagingController.appendPage(newItems, nextPageKey); - } - } catch (error) { - pagingController.error = error; - } -} diff --git a/lib/app/hooks/use_paging_controller.dart b/lib/app/hooks/use_paging_controller.dart deleted file mode 100644 index fd37700d..00000000 --- a/lib/app/hooks/use_paging_controller.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; - -PagingController - usePagingController({ - required final PageKeyType firstPageKey, - final int? invisibleItemsThreshold, - List? keys, - FutureOr Function(PageKeyType pageKey, - PagingController pagingController)? - onPageRequest, -}) { - final controller = use( - _PagingControllerHook( - firstPageKey: firstPageKey, - invisibleItemsThreshold: invisibleItemsThreshold, - keys: keys, - ), - ); - - useEffect(() { - listener(PageKeyType pageKey) => onPageRequest?.call(pageKey, controller); - controller.addPageRequestListener(listener); - return () => controller.removePageRequestListener(listener); - }, [onPageRequest]); - - return controller; -} - -class _PagingControllerHook - extends Hook> { - const _PagingControllerHook({ - required this.firstPageKey, - this.invisibleItemsThreshold, - List? keys, - }) : super(keys: keys); - - final PageKeyType firstPageKey; - final int? invisibleItemsThreshold; - - @override - HookState, - Hook>> - createState() => _PagingControllerHookState(); -} - -class _PagingControllerHookState extends HookState< - PagingController, - _PagingControllerHook> { - late final controller = PagingController( - firstPageKey: hook.firstPageKey, - invisibleItemsThreshold: hook.invisibleItemsThreshold); - - @override - PagingController build(BuildContext context) => - controller; - - @override - void dispose() => controller.dispose(); - - @override - String get debugLabel => 'usePagingController'; -} diff --git a/lib/app/images.dart b/lib/app/images.dart deleted file mode 100644 index c1585706..00000000 --- a/lib/app/images.dart +++ /dev/null @@ -1,368 +0,0 @@ -import 'package:cached_network_image/cached_network_image.dart'; -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../models/music.dart'; -import '../models/support.dart'; -import '../services/cache_service.dart'; -import '../state/music.dart'; -import '../state/settings.dart'; -import '../state/theme.dart'; - -part 'images.g.dart'; - -@riverpod -CacheInfo _artistArtCacheInfo( - _ArtistArtCacheInfoRef ref, { - required String artistId, - bool thumbnail = true, -}) { - final cache = ref.watch(cacheServiceProvider); - return cache.artistArtCacheInfo(artistId, thumbnail: thumbnail); -} - -@riverpod -FutureOr _artistArtCachedUrl( - _ArtistArtCachedUrlRef ref, { - required String artistId, - bool thumbnail = true, -}) async { - final cache = ref.watch(_artistArtCacheInfoProvider( - artistId: artistId, - thumbnail: thumbnail, - )); - final file = await cache.cacheManager.getFileFromCache(cache.cacheKey); - return file?.originalUrl; -} - -@riverpod -FutureOr _artistArtUriCacheInfo( - _ArtistArtUriCacheInfoRef ref, { - required String artistId, - bool thumbnail = true, -}) async { - final cache = ref.watch(cacheServiceProvider); - final info = ref.watch(_artistArtCacheInfoProvider( - artistId: artistId, - thumbnail: thumbnail, - )); - final cachedUrl = await ref.watch(_artistArtCachedUrlProvider( - artistId: artistId, - thumbnail: thumbnail, - ).future); - final offline = ref.watch(offlineModeProvider); - - // already cached, don't try to get the real url again - if (cachedUrl != null) { - return UriCacheInfo( - uri: Uri.parse(cachedUrl), - cacheKey: info.cacheKey, - cacheManager: info.cacheManager, - ); - } - - if (offline) { - final file = await cache.imageCache.getFileFromCache(info.cacheKey); - if (file != null) { - return UriCacheInfo( - uri: Uri.parse(file.originalUrl), - cacheKey: info.cacheKey, - cacheManager: info.cacheManager, - ); - } else { - return cache.placeholder(thumbnail: thumbnail); - } - } - - // assume the url is good or let this fail - return UriCacheInfo( - uri: (await cache.artistArtUri(artistId, thumbnail: thumbnail))!, - cacheKey: info.cacheKey, - cacheManager: info.cacheManager, - ); -} - -class ArtistArtImage extends HookConsumerWidget { - final String artistId; - final bool thumbnail; - final BoxFit fit; - final PlaceholderStyle placeholderStyle; - final double? height; - final double? width; - - const ArtistArtImage({ - super.key, - required this.artistId, - this.thumbnail = true, - this.fit = BoxFit.cover, - this.placeholderStyle = PlaceholderStyle.color, - this.height, - this.width, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final cache = ref.watch(_artistArtUriCacheInfoProvider( - artistId: artistId, - thumbnail: thumbnail, - )); - - // TODO: figure out how to animate this without messing up with boxfit/ratio - return cache.when( - data: (data) => UriCacheInfoImage( - cache: data, - fit: fit, - placeholderStyle: placeholderStyle, - height: height, - width: width, - ), - error: (_, __) => Container( - color: Colors.red, - height: height, - width: width, - ), - loading: () => Container( - color: Theme.of(context).colorScheme.secondaryContainer, - height: height, - width: width, - ), - ); - } -} - -class SongAlbumArt extends HookConsumerWidget { - final Song song; - final bool square; - - const SongAlbumArt({ - super.key, - required this.song, - this.square = true, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final album = ref.watch(albumProvider(song.albumId!)).valueOrNull; - - return AnimatedSwitcher( - duration: const Duration(milliseconds: 150), - child: album != null ? AlbumArt(album: album) : const PlaceholderImage(), - ); - } -} - -class AlbumArt extends HookConsumerWidget { - final Album album; - final bool square; - - const AlbumArt({ - super.key, - required this.album, - this.square = true, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - // generate the palette used in other views ahead of time - ref.watch(albumArtPaletteProvider(album.id)); - final cache = ref.watch(cacheServiceProvider); - - Widget image = UriCacheInfoImage(cache: cache.albumArt(album)); - - if (square) { - image = AspectRatio(aspectRatio: 1.0, child: image); - } - - return CardClip(child: image); - } -} - -class CircleClip extends StatelessWidget { - final Widget child; - - const CircleClip({ - super.key, - required this.child, - }); - - @override - Widget build(BuildContext context) { - return ClipOval( - clipBehavior: Clip.antiAlias, - child: AspectRatio( - aspectRatio: 1.0, - child: child, - ), - ); - } -} - -class CardClip extends StatelessWidget { - final Widget child; - final bool square; - - const CardClip({ - super.key, - required this.child, - this.square = true, - }); - - @override - Widget build(BuildContext context) { - final cardShape = Theme.of(context).cardTheme.shape; - return ClipRRect( - borderRadius: - cardShape is RoundedRectangleBorder ? cardShape.borderRadius : null, - child: !square - ? child - : AspectRatio( - aspectRatio: 1.0, - child: child, - ), - ); - } -} - -enum PlaceholderStyle { - color, - spinner, -} - -class UriCacheInfoImage extends StatelessWidget { - final UriCacheInfo cache; - final BoxFit fit; - final PlaceholderStyle placeholderStyle; - final double? height; - final double? width; - - const UriCacheInfoImage({ - super.key, - required this.cache, - this.fit = BoxFit.cover, - this.placeholderStyle = PlaceholderStyle.color, - this.height, - this.width, - }); - - @override - Widget build(BuildContext context) { - return CachedNetworkImage( - imageUrl: cache.uri.toString(), - cacheKey: cache.cacheKey, - cacheManager: cache.cacheManager, - fit: fit, - height: height, - width: width, - fadeInDuration: const Duration(milliseconds: 300), - fadeOutDuration: const Duration(milliseconds: 500), - placeholder: (context, url) => - placeholderStyle == PlaceholderStyle.spinner - ? Container() - : Container( - color: Theme.of(context).colorScheme.secondaryContainer, - ), - errorWidget: (context, url, error) => PlaceholderImage( - fit: fit, - height: height, - width: width, - ), - ); - } -} - -class PlaceholderImage extends HookConsumerWidget { - final BoxFit fit; - final double? height; - final double? width; - final bool thumbnail; - - const PlaceholderImage({ - super.key, - this.fit = BoxFit.cover, - this.height, - this.width, - this.thumbnail = true, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return Image.asset( - thumbnail ? 'assets/placeholder_thumb.png' : 'assets/placeholder.png', - fit: fit, - height: height, - width: width, - ); - } -} - -class _ExpandedRatio extends StatelessWidget { - final Widget child; - final double aspectRatio; - - const _ExpandedRatio({ - required this.child, - this.aspectRatio = 1.0, - }); - - @override - Widget build(BuildContext context) { - return Expanded( - child: AspectRatio( - aspectRatio: aspectRatio, - child: child, - ), - ); - } -} - -class MultiImage extends HookConsumerWidget { - final Iterable cacheInfo; - - const MultiImage({ - super.key, - required this.cacheInfo, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final images = cacheInfo.map((cache) => UriCacheInfoImage(cache: cache)); - - final row1 = []; - final row2 = []; - - if (images.length >= 4) { - row1.addAll([ - _ExpandedRatio(child: images.elementAt(0)), - _ExpandedRatio(child: images.elementAt(1)), - ]); - row2.addAll([ - _ExpandedRatio(child: images.elementAt(2)), - _ExpandedRatio(child: images.elementAt(3)), - ]); - } - if (images.length == 3) { - row1.addAll([ - _ExpandedRatio(child: images.elementAt(0)), - _ExpandedRatio(child: images.elementAt(1)), - ]); - row2.addAll([ - _ExpandedRatio(aspectRatio: 2.0, child: images.elementAt(2)), - ]); - } - if (images.length == 2) { - row1.add(_ExpandedRatio(aspectRatio: 2.0, child: images.elementAt(0))); - row2.add(_ExpandedRatio(aspectRatio: 2.0, child: images.elementAt(1))); - } - if (images.length == 1) { - row1.addAll([_ExpandedRatio(child: images.elementAt(0))]); - } - - return Column( - children: [ - Row(children: row1), - Row(children: row2), - ], - ); - } -} diff --git a/lib/app/images.g.dart b/lib/app/images.g.dart deleted file mode 100644 index f4f84e52..00000000 --- a/lib/app/images.g.dart +++ /dev/null @@ -1,307 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'images.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$artistArtCacheInfoHash() => - r'f82d3e91aa1596939e376c6a7ea7d3e974c6f0fc'; - -/// Copied from Dart SDK -class _SystemHash { - _SystemHash._(); - - static int combine(int hash, int value) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + value); - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - return hash ^ (hash >> 6); - } - - static int finish(int hash) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - // ignore: parameter_assignments - hash = hash ^ (hash >> 11); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } -} - -typedef _ArtistArtCacheInfoRef = AutoDisposeProviderRef; - -/// See also [_artistArtCacheInfo]. -@ProviderFor(_artistArtCacheInfo) -const _artistArtCacheInfoProvider = _ArtistArtCacheInfoFamily(); - -/// See also [_artistArtCacheInfo]. -class _ArtistArtCacheInfoFamily extends Family { - /// See also [_artistArtCacheInfo]. - const _ArtistArtCacheInfoFamily(); - - /// See also [_artistArtCacheInfo]. - _ArtistArtCacheInfoProvider call({ - required String artistId, - bool thumbnail = true, - }) { - return _ArtistArtCacheInfoProvider( - artistId: artistId, - thumbnail: thumbnail, - ); - } - - @override - _ArtistArtCacheInfoProvider getProviderOverride( - covariant _ArtistArtCacheInfoProvider provider, - ) { - return call( - artistId: provider.artistId, - thumbnail: provider.thumbnail, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'_artistArtCacheInfoProvider'; -} - -/// See also [_artistArtCacheInfo]. -class _ArtistArtCacheInfoProvider extends AutoDisposeProvider { - /// See also [_artistArtCacheInfo]. - _ArtistArtCacheInfoProvider({ - required this.artistId, - this.thumbnail = true, - }) : super.internal( - (ref) => _artistArtCacheInfo( - ref, - artistId: artistId, - thumbnail: thumbnail, - ), - from: _artistArtCacheInfoProvider, - name: r'_artistArtCacheInfoProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$artistArtCacheInfoHash, - dependencies: _ArtistArtCacheInfoFamily._dependencies, - allTransitiveDependencies: - _ArtistArtCacheInfoFamily._allTransitiveDependencies, - ); - - final String artistId; - final bool thumbnail; - - @override - bool operator ==(Object other) { - return other is _ArtistArtCacheInfoProvider && - other.artistId == artistId && - other.thumbnail == thumbnail; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, artistId.hashCode); - hash = _SystemHash.combine(hash, thumbnail.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$artistArtCachedUrlHash() => - r'2a5e0fea614ff12a1d562faccec6cfe98394af42'; -typedef _ArtistArtCachedUrlRef = AutoDisposeFutureProviderRef; - -/// See also [_artistArtCachedUrl]. -@ProviderFor(_artistArtCachedUrl) -const _artistArtCachedUrlProvider = _ArtistArtCachedUrlFamily(); - -/// See also [_artistArtCachedUrl]. -class _ArtistArtCachedUrlFamily extends Family> { - /// See also [_artistArtCachedUrl]. - const _ArtistArtCachedUrlFamily(); - - /// See also [_artistArtCachedUrl]. - _ArtistArtCachedUrlProvider call({ - required String artistId, - bool thumbnail = true, - }) { - return _ArtistArtCachedUrlProvider( - artistId: artistId, - thumbnail: thumbnail, - ); - } - - @override - _ArtistArtCachedUrlProvider getProviderOverride( - covariant _ArtistArtCachedUrlProvider provider, - ) { - return call( - artistId: provider.artistId, - thumbnail: provider.thumbnail, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'_artistArtCachedUrlProvider'; -} - -/// See also [_artistArtCachedUrl]. -class _ArtistArtCachedUrlProvider extends AutoDisposeFutureProvider { - /// See also [_artistArtCachedUrl]. - _ArtistArtCachedUrlProvider({ - required this.artistId, - this.thumbnail = true, - }) : super.internal( - (ref) => _artistArtCachedUrl( - ref, - artistId: artistId, - thumbnail: thumbnail, - ), - from: _artistArtCachedUrlProvider, - name: r'_artistArtCachedUrlProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$artistArtCachedUrlHash, - dependencies: _ArtistArtCachedUrlFamily._dependencies, - allTransitiveDependencies: - _ArtistArtCachedUrlFamily._allTransitiveDependencies, - ); - - final String artistId; - final bool thumbnail; - - @override - bool operator ==(Object other) { - return other is _ArtistArtCachedUrlProvider && - other.artistId == artistId && - other.thumbnail == thumbnail; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, artistId.hashCode); - hash = _SystemHash.combine(hash, thumbnail.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$artistArtUriCacheInfoHash() => - r'9bdc0f5654882265236ef746ea697a6d107a4b6f'; -typedef _ArtistArtUriCacheInfoRef = AutoDisposeFutureProviderRef; - -/// See also [_artistArtUriCacheInfo]. -@ProviderFor(_artistArtUriCacheInfo) -const _artistArtUriCacheInfoProvider = _ArtistArtUriCacheInfoFamily(); - -/// See also [_artistArtUriCacheInfo]. -class _ArtistArtUriCacheInfoFamily extends Family> { - /// See also [_artistArtUriCacheInfo]. - const _ArtistArtUriCacheInfoFamily(); - - /// See also [_artistArtUriCacheInfo]. - _ArtistArtUriCacheInfoProvider call({ - required String artistId, - bool thumbnail = true, - }) { - return _ArtistArtUriCacheInfoProvider( - artistId: artistId, - thumbnail: thumbnail, - ); - } - - @override - _ArtistArtUriCacheInfoProvider getProviderOverride( - covariant _ArtistArtUriCacheInfoProvider provider, - ) { - return call( - artistId: provider.artistId, - thumbnail: provider.thumbnail, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'_artistArtUriCacheInfoProvider'; -} - -/// See also [_artistArtUriCacheInfo]. -class _ArtistArtUriCacheInfoProvider - extends AutoDisposeFutureProvider { - /// See also [_artistArtUriCacheInfo]. - _ArtistArtUriCacheInfoProvider({ - required this.artistId, - this.thumbnail = true, - }) : super.internal( - (ref) => _artistArtUriCacheInfo( - ref, - artistId: artistId, - thumbnail: thumbnail, - ), - from: _artistArtUriCacheInfoProvider, - name: r'_artistArtUriCacheInfoProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$artistArtUriCacheInfoHash, - dependencies: _ArtistArtUriCacheInfoFamily._dependencies, - allTransitiveDependencies: - _ArtistArtUriCacheInfoFamily._allTransitiveDependencies, - ); - - final String artistId; - final bool thumbnail; - - @override - bool operator ==(Object other) { - return other is _ArtistArtUriCacheInfoProvider && - other.artistId == artistId && - other.thumbnail == thumbnail; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, artistId.hashCode); - hash = _SystemHash.combine(hash, thumbnail.hashCode); - - return _SystemHash.finish(hash); - } -} -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/app/items.dart b/lib/app/items.dart deleted file mode 100644 index 82d23731..00000000 --- a/lib/app/items.dart +++ /dev/null @@ -1,433 +0,0 @@ -import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -import '../models/music.dart'; -import '../services/cache_service.dart'; -import '../services/download_service.dart'; -import '../state/audio.dart'; -import '../state/music.dart'; -import '../state/theme.dart'; -import 'context_menus.dart'; -import 'images.dart'; -import 'pages/songs_page.dart'; - -enum CardStyle { - imageOnly, - withText, -} - -enum AlbumSubtitle { - artist, - year, -} - -class AlbumCard extends HookConsumerWidget { - final Album album; - final void Function()? onTap; - final CardStyle style; - final AlbumSubtitle subtitle; - - const AlbumCard({ - super.key, - required this.album, - this.onTap, - this.style = CardStyle.withText, - this.subtitle = AlbumSubtitle.artist, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - // generate the palette used in other views ahead of time - ref.watch(albumArtPaletteProvider(album.id)); - final cache = ref.watch(cacheServiceProvider); - final info = cache.albumArt(album); - - final image = CardClip(child: UriCacheInfoImage(cache: info)); - Widget content; - if (style == CardStyle.imageOnly) { - content = image; - } else { - content = Column( - children: [ - image, - _AlbumCardText(album: album, subtitle: subtitle), - ], - ); - } - - return ImageCard( - onTap: onTap, - onLongPress: () { - showContextMenu( - context: context, - ref: ref, - builder: (context) => BottomSheetMenu( - child: AlbumContextMenu(album: album), - ), - ); - }, - child: content, - ); - } -} - -class ImageCard extends StatelessWidget { - final Widget child; - final void Function()? onTap; - final void Function()? onLongPress; - - const ImageCard({ - super.key, - required this.child, - this.onTap, - this.onLongPress, - }); - - @override - Widget build(BuildContext context) { - return Card( - surfaceTintColor: Colors.transparent, - margin: const EdgeInsets.all(0), - child: Stack( - fit: StackFit.passthrough, - alignment: Alignment.bottomCenter, - children: [ - child, - Positioned.fill( - child: Material( - color: Colors.transparent, - child: InkWell( - onTap: onTap, - onLongPress: onLongPress, - ), - ), - ), - ], - ), - ); - } -} - -class _AlbumCardText extends StatelessWidget { - final Album album; - final AlbumSubtitle subtitle; - - const _AlbumCardText({ - required this.album, - required this.subtitle, - }); - - @override - Widget build(BuildContext context) { - final textTheme = Theme.of(context).textTheme; - - return Container( - padding: const EdgeInsets.only(top: 4, bottom: 8), - width: double.infinity, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - width: double.infinity, - child: Text( - album.name, - maxLines: 1, - softWrap: false, - overflow: TextOverflow.fade, - textAlign: TextAlign.start, - style: textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.bold, - ), - ), - ), - Text( - (subtitle == AlbumSubtitle.artist - ? album.albumArtist - : album.year?.toString()) ?? - '', - maxLines: 1, - softWrap: false, - overflow: TextOverflow.fade, - textAlign: TextAlign.start, - style: textTheme.bodySmall, - ), - ], - ), - ); - } -} - -class AlbumListTile extends HookConsumerWidget { - final Album album; - final void Function()? onTap; - - const AlbumListTile({ - super.key, - required this.album, - this.onTap, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final artist = ref.watch(albumProvider(album.artistId!)).valueOrNull; - - return ListTile( - leading: AlbumArt(album: album), - title: Text(album.name), - subtitle: Text(album.albumArtist ?? artist!.name), - onTap: onTap, - onLongPress: () { - showContextMenu( - context: context, - ref: ref, - builder: (context) => BottomSheetMenu( - size: MenuSize.small, - child: AlbumContextMenu(album: album), - ), - ); - }, - ); - } -} - -class ArtistListTile extends HookConsumerWidget { - final Artist artist; - final void Function()? onTap; - - const ArtistListTile({ - super.key, - required this.artist, - this.onTap, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return ListTile( - leading: CircleClip( - child: ArtistArtImage(artistId: artist.id), - ), - title: Text(artist.name), - subtitle: Text(AppLocalizations.of(context).resourcesAlbumCount( - artist.albumCount, - )), - onTap: onTap, - onLongPress: () { - showContextMenu( - context: context, - ref: ref, - builder: (context) => BottomSheetMenu( - size: MenuSize.small, - child: ArtistContextMenu(artist: artist), - ), - ); - }, - ); - } -} - -class PlaylistListTile extends HookConsumerWidget { - final Playlist playlist; - final void Function()? onTap; - - const PlaylistListTile({ - super.key, - required this.playlist, - this.onTap, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - // generate the palette used in other views ahead of time - ref.watch(playlistArtPaletteProvider(playlist.id)); - final cache = ref.watch(cacheServiceProvider).playlistArt(playlist); - - return ListTile( - leading: CardClip( - child: UriCacheInfoImage(cache: cache), - ), - title: Text(playlist.name), - subtitle: Text(AppLocalizations.of(context).resourcesSongCount( - playlist.songCount, - )), - onTap: onTap, - onLongPress: () { - showContextMenu( - context: context, - ref: ref, - builder: (context) => BottomSheetMenu( - size: MenuSize.small, - child: PlaylistContextMenu(playlist: playlist), - ), - ); - }, - ); - } -} - -class SongListTile extends HookConsumerWidget { - final Song song; - final void Function()? onTap; - final bool image; - - const SongListTile({ - super.key, - required this.song, - this.onTap, - this.image = false, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return Material( - type: MaterialType.transparency, - child: ListTile( - title: _SongTitle(song: song), - subtitle: _SongSubtitle(song: song), - leading: image ? SongAlbumArt(song: song) : null, - trailing: IconButton( - icon: const Icon( - Icons.star_outline_rounded, - size: 36, - ), - onPressed: () {}, - ), - onTap: onTap, - onLongPress: () { - showContextMenu( - context: context, - ref: ref, - builder: (context) => BottomSheetMenu( - child: SongContextMenu(song: song), - ), - ); - }, - ), - ); - } -} - -class _SongSubtitle extends HookConsumerWidget { - final Song song; - - const _SongSubtitle({ - required this.song, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final downloadTaskId = ref.watch(songProvider(song.id).select( - (value) => value.valueOrNull?.downloadTaskId, - )); - final downloadFilePath = ref.watch(songProvider(song.id).select( - (value) => value.valueOrNull?.downloadFilePath, - )); - final download = ref.watch(downloadServiceProvider.select( - (value) => value.downloads.firstWhereOrNull( - (e) => e.taskId == downloadTaskId, - ), - )); - - final inheritedStyle = DefaultTextStyle.of(context).style; - - Widget? downloadIndicator; - if (downloadFilePath != null) { - downloadIndicator = const Padding( - padding: EdgeInsetsDirectional.only(end: 3), - child: Icon( - Icons.download_done_rounded, - size: 20, - ), - ); - } else if (downloadTaskId != null || download != null) { - downloadIndicator = Padding( - padding: const EdgeInsetsDirectional.only(start: 4, end: 9), - child: SizedBox( - height: 10, - width: 10, - child: CircularProgressIndicator( - strokeWidth: 2, - value: download != null && download.progress > 0 - ? download.progress / 100 - : null, - ), - ), - ); - } - - return Row( - children: [ - if (downloadIndicator != null) downloadIndicator, - Expanded( - child: Text( - song.artist ?? song.album ?? '', - maxLines: 1, - softWrap: false, - overflow: TextOverflow.fade, - style: TextStyle( - color: inheritedStyle.color, - ), - ), - ), - ], - ); - } -} - -class _SongTitle extends HookConsumerWidget { - final Song song; - - const _SongTitle({ - required this.song, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final mediaItem = ref.watch(mediaItemProvider).valueOrNull; - final mediaItemData = ref.watch(mediaItemDataProvider); - final inheritedStyle = DefaultTextStyle.of(context).style; - final theme = Theme.of(context); - final queueContext = QueueContext.maybeOf(context); - - final playing = mediaItem != null && - mediaItemData != null && - mediaItem.id == song.id && - mediaItemData.contextId == queueContext?.id && - mediaItemData.contextType == queueContext?.type; - - return Row( - children: [ - if (playing) - Padding( - padding: const EdgeInsetsDirectional.only(end: 2), - child: Icon( - Icons.play_arrow_rounded, - size: 18, - color: theme.colorScheme.primary, - ), - ), - Expanded( - child: Text( - song.title, - maxLines: 1, - softWrap: false, - overflow: TextOverflow.fade, - style: TextStyle( - color: playing ? theme.colorScheme.primary : inheritedStyle.color, - ), - ), - ), - ], - ); - } -} - -class FabPadding extends StatelessWidget { - const FabPadding({super.key}); - - @override - Widget build(BuildContext context) { - return const SizedBox(height: 86); - } -} diff --git a/lib/app/lists.dart b/lib/app/lists.dart deleted file mode 100644 index 3b5c552c..00000000 --- a/lib/app/lists.dart +++ /dev/null @@ -1,136 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; - -import '../services/sync_service.dart'; -import 'items.dart'; -import 'snackbars.dart'; - -class PagedListQueryView extends HookConsumerWidget { - final PagingController pagingController; - final bool refreshSyncAll; - final bool fabPadding; - final bool useSliver; - final Widget Function(BuildContext context, T item, int index) itemBuilder; - - const PagedListQueryView({ - super.key, - required this.pagingController, - this.refreshSyncAll = false, - this.fabPadding = true, - this.useSliver = false, - required this.itemBuilder, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final builderDelegate = PagedChildBuilderDelegate( - itemBuilder: (context, item, index) => itemBuilder(context, item, index), - noMoreItemsIndicatorBuilder: - fabPadding ? (context) => const FabPadding() : null, - ); - - final listView = useSliver - ? PagedSliverList( - pagingController: pagingController, - builderDelegate: builderDelegate, - ) - : PagedListView( - pagingController: pagingController, - builderDelegate: builderDelegate, - ); - - if (refreshSyncAll) { - return SyncAllRefresh(child: listView); - } else { - return listView; - } - } -} - -enum GridSize { - small, - large, -} - -class PagedGridQueryView extends HookConsumerWidget { - final PagingController pagingController; - final bool refreshSyncAll; - final bool fabPadding; - final GridSize size; - final Widget Function(BuildContext context, T item, int index, GridSize size) - itemBuilder; - - const PagedGridQueryView({ - super.key, - required this.pagingController, - this.refreshSyncAll = false, - this.fabPadding = true, - this.size = GridSize.small, - required this.itemBuilder, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - SliverGridDelegate gridDelegate; - double spacing; - - if (size == GridSize.small) { - spacing = 4; - gridDelegate = SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - mainAxisSpacing: spacing, - crossAxisSpacing: spacing, - ); - } else { - spacing = 12; - gridDelegate = SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - mainAxisSpacing: spacing, - crossAxisSpacing: spacing, - ); - } - - final listView = PagedGridView( - padding: MediaQuery.of(context).padding + EdgeInsets.all(spacing), - pagingController: pagingController, - builderDelegate: PagedChildBuilderDelegate( - itemBuilder: (context, item, index) => - itemBuilder(context, item, index, size), - noMoreItemsIndicatorBuilder: - fabPadding ? (context) => const FabPadding() : null, - ), - gridDelegate: gridDelegate, - showNoMoreItemsIndicatorAsGridChild: false, - ); - - if (refreshSyncAll) { - return SyncAllRefresh(child: listView); - } else { - return listView; - } - } -} - -class SyncAllRefresh extends HookConsumerWidget { - final Widget child; - - const SyncAllRefresh({ - super.key, - required this.child, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return RefreshIndicator( - onRefresh: () async { - try { - await ref.read(syncServiceProvider.notifier).syncAll(); - } catch (e) { - showErrorSnackbar(context, e.toString()); - } - }, - child: child, - ); - } -} diff --git a/lib/app/now_playing_bar.dart b/lib/app/now_playing_bar.dart deleted file mode 100644 index ba5300ae..00000000 --- a/lib/app/now_playing_bar.dart +++ /dev/null @@ -1,226 +0,0 @@ -import 'package:audio_service/audio_service.dart'; -import 'package:auto_route/auto_route.dart'; -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -import '../cache/image_cache.dart'; -import '../models/support.dart'; -import '../services/audio_service.dart'; -import '../state/audio.dart'; -import '../state/theme.dart'; -import 'app_router.dart'; -import 'images.dart'; -import 'pages/now_playing_page.dart'; - -class NowPlayingBar extends HookConsumerWidget { - const NowPlayingBar({ - super.key, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final colors = ref.watch(mediaItemThemeProvider).valueOrNull; - final noItem = ref.watch(mediaItemProvider).valueOrNull == null; - - final widget = GestureDetector( - onTap: () { - context.navigateTo(const NowPlayingRoute()); - }, - child: Material( - elevation: 3, - color: colors?.darkBackground, - // surfaceTintColor: theme?.colorScheme.background, - child: Column( - children: [ - SizedBox( - height: 70, - child: Row( - mainAxisSize: MainAxisSize.max, - children: const [ - Padding( - padding: EdgeInsets.all(10), - child: _ArtImage(), - ), - Expanded( - child: Padding( - padding: EdgeInsets.only(right: 4), - child: _TrackInfo(), - ), - ), - Padding( - padding: EdgeInsets.only(right: 16, top: 2), - child: PlayPauseButton(size: 48), - ), - ], - ), - ), - const _ProgressBar(), - ], - ), - ), - ); - - if (noItem) { - return Container(); - } - - if (colors != null) { - return Theme(data: colors.theme, child: widget); - } else { - return widget; - } - } -} - -class _ArtImage extends HookConsumerWidget { - const _ArtImage(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final imageCache = ref.watch(imageCacheProvider); - final uri = - ref.watch(mediaItemProvider.select((e) => e.valueOrNull?.artUri)); - final cacheKey = ref.watch(mediaItemDataProvider.select( - (value) => value?.artCache?.thumbnailArtCacheKey, - )); - - UriCacheInfo? cache; - if (uri != null && cacheKey != null) { - cache = UriCacheInfo( - uri: uri, - cacheKey: cacheKey, - cacheManager: imageCache, - ); - } - - return AnimatedSwitcher( - duration: const Duration(milliseconds: 150), - child: CardClip( - key: ValueKey(cacheKey ?? 'default'), - child: cache == null - ? const PlaceholderImage() - : UriCacheInfoImage( - cache: cache, - ), - ), - ); - } -} - -class _TrackInfo extends HookConsumerWidget { - const _TrackInfo(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final item = ref.watch(mediaItemProvider); - - return Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ...item.when( - data: (data) => [ - // Text( - // data?.title ?? 'Nothing!!!', - // maxLines: 1, - // softWrap: false, - // overflow: TextOverflow.fade, - // style: Theme.of(context).textTheme.labelLarge, - // ), - ScrollableText( - data?.title ?? 'Nothing!!!', - style: Theme.of(context).textTheme.labelLarge, - ), - const SizedBox(height: 2), - Text( - data?.artist ?? 'Nothing!!!', - maxLines: 1, - softWrap: false, - overflow: TextOverflow.fade, - style: Theme.of(context).textTheme.labelMedium, - ), - ], - error: (_, __) => const [Text('Error!')], - loading: () => const [Text('loading.....')], - ), - ], - ); - } -} - -class PlayPauseButton extends HookConsumerWidget { - final double size; - - const PlayPauseButton({ - super.key, - required this.size, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final playing = ref.watch(playingProvider); - final state = ref.watch(processingStateProvider); - - Widget icon; - if (state == AudioProcessingState.loading || - state == AudioProcessingState.buffering) { - icon = Stack( - alignment: Alignment.center, - children: [ - const Icon(Icons.circle), - SizedBox( - height: size / 3, - width: size / 3, - child: CircularProgressIndicator( - strokeWidth: size / 16, - color: Theme.of(context).colorScheme.background, - ), - ), - ], - ); - } else if (playing) { - icon = const Icon(Icons.pause_circle_rounded); - } else { - icon = const Icon(Icons.play_circle_rounded); - } - - return IconButton( - iconSize: size, - padding: EdgeInsets.zero, - onPressed: () { - if (playing) { - ref.read(audioControlProvider).pause(); - } else { - ref.read(audioControlProvider).play(); - } - }, - icon: icon, - color: Theme.of(context).colorScheme.onBackground, - ); - } -} - -class _ProgressBar extends HookConsumerWidget { - const _ProgressBar(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final colors = ref.watch(mediaItemThemeProvider).valueOrNull; - final position = ref.watch(positionProvider); - final duration = ref.watch(durationProvider); - - return Container( - height: 4, - color: colors?.darkerBackground, - child: Row( - children: [ - Flexible( - flex: position, - child: Container(color: colors?.onDarkerBackground), - ), - Flexible(flex: duration - position, child: Container()), - ], - ), - ); - } -} diff --git a/lib/app/pages/artist_page.dart b/lib/app/pages/artist_page.dart deleted file mode 100644 index eafba279..00000000 --- a/lib/app/pages/artist_page.dart +++ /dev/null @@ -1,152 +0,0 @@ -import 'dart:math'; - -import 'package:auto_route/auto_route.dart'; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -import '../../database/database.dart'; -import '../../models/query.dart'; -import '../../models/support.dart'; -import '../../services/audio_service.dart'; -import '../../state/music.dart'; -import '../../state/settings.dart'; -import '../app_router.dart'; -import '../buttons.dart'; -import '../images.dart'; -import '../items.dart'; - -class ArtistPage extends HookConsumerWidget { - final String id; - - const ArtistPage({ - super.key, - @pathParam required this.id, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - ref.listen(sourceIdProvider, (_, __) => context.router.popUntilRoot()); - - final artist = ref.watch(artistProvider(id)); - final albums = ref.watch(albumsByArtistIdProvider(id)); - - return Scaffold( - floatingActionButton: RadioPlayFab( - onPressed: () => artist.hasValue - ? ref.read(audioControlProvider).playRadio( - context: QueueContextType.artist, - contextId: artist.valueOrNull!.id, - query: ListQuery( - filters: IList([ - FilterWith.equals( - column: 'artist_id', - value: artist.valueOrNull!.id, - ) - ]), - ), - getSongs: (query) => ref - .read(databaseProvider) - .songsList(ref.read(sourceIdProvider), query) - .get(), - ) - : null, - ), - body: CustomScrollView( - slivers: [ - SliverToBoxAdapter( - child: Stack( - alignment: Alignment.bottomCenter, - fit: StackFit.passthrough, - children: [ - ArtistArtImage( - artistId: id, - thumbnail: false, - height: 400, - ), - Padding( - padding: const EdgeInsets.all(12), - child: _Title(text: artist.valueOrNull?.name ?? ''), - ), - ], - ), - ), - albums.when( - data: (albums) { - albums = albums.sort((a, b) => (b.year ?? 0) - (a.year ?? 0)); - return SliverPadding( - padding: - const EdgeInsets.symmetric(horizontal: 24, vertical: 24), - sliver: SliverAlignedGrid.count( - crossAxisCount: 2, - mainAxisSpacing: 12, - crossAxisSpacing: 24, - itemCount: albums.length, - itemBuilder: (context, i) { - final album = albums.elementAt(i); - return AlbumCard( - album: album, - subtitle: AlbumSubtitle.year, - onTap: () => context.navigateTo(AlbumSongsRoute( - id: album.id, - )), - ); - }, - ), - ); - }, - error: (_, __) => SliverToBoxAdapter( - child: Container(color: Colors.red), - ), - loading: () => const SliverToBoxAdapter( - child: CircularProgressIndicator(), - ), - ), - ], - ), - ); - } -} - -class _Title extends StatelessWidget { - final String text; - - const _Title({ - required this.text, - }); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.displayMedium!.copyWith( - fontWeight: FontWeight.bold, - color: Colors.white, - shadows: [ - Shadow( - offset: Offset.fromDirection(pi / 4, 3), - blurRadius: 16, - color: Colors.black26, - ), - Shadow( - offset: Offset.fromDirection(3 * pi / 4, 3), - blurRadius: 16, - color: Colors.black26, - ), - Shadow( - offset: Offset.fromDirection(5 * pi / 4, 3), - blurRadius: 16, - color: Colors.black26, - ), - Shadow( - offset: Offset.fromDirection(7 * pi / 4, 3), - blurRadius: 16, - color: Colors.black26, - ), - ], - ), - ); - } -} diff --git a/lib/app/pages/bottom_nav_page.dart b/lib/app/pages/bottom_nav_page.dart deleted file mode 100644 index 5a5a3be8..00000000 --- a/lib/app/pages/bottom_nav_page.dart +++ /dev/null @@ -1,216 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../../database/database.dart'; -import '../../services/settings_service.dart'; -import '../../state/settings.dart'; -import '../app_router.dart'; -import '../now_playing_bar.dart'; - -part 'bottom_nav_page.g.dart'; - -@Riverpod(keepAlive: true) -TabObserver bottomTabObserver(BottomTabObserverRef ref) { - return TabObserver(); -} - -@Riverpod(keepAlive: true) -Stream bottomTabPath(BottomTabPathRef ref) async* { - final observer = ref.watch(bottomTabObserverProvider); - await for (var tab in observer.path) { - yield tab; - } -} - -@Riverpod(keepAlive: true) -class LastBottomNavStateService extends _$LastBottomNavStateService { - @override - Future build() async { - final db = ref.watch(databaseProvider); - final tab = ref.watch(bottomTabPathProvider).valueOrNull; - if (tab == null || tab == 'settings' || tab == 'search') { - return; - } - - await db.saveLastBottomNavState(LastBottomNavStateData(id: 1, tab: tab)); - } -} - -class BottomNavTabsPage extends HookConsumerWidget { - const BottomNavTabsPage({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final observer = ref.watch(bottomTabObserverProvider); - const navElevation = 3.0; - - return AutoTabsRouter( - lazyLoad: false, - inheritNavigatorObservers: false, - navigatorObservers: () => [observer], - routes: const [ - LibraryRouter(), - BrowseRouter(), - SearchRouter(), - SettingsRouter(), - ], - builder: (context, child, animation) { - return AnnotatedRegion( - value: SystemUiOverlayStyle.light.copyWith( - systemNavigationBarColor: ElevationOverlay.applySurfaceTint( - Theme.of(context).colorScheme.surface, - Theme.of(context).colorScheme.surfaceTint, - navElevation, - ), - statusBarColor: Colors.transparent, - ), - child: Scaffold( - body: Stack( - alignment: AlignmentDirectional.bottomStart, - children: [ - FadeTransition( - opacity: animation, - child: child, - ), - const OfflineIndicator(), - ], - ), - bottomNavigationBar: const _BottomNavBar( - navElevation: navElevation, - ), - ), - ); - }, - ); - } -} - -class OfflineIndicator extends HookConsumerWidget { - const OfflineIndicator({ - super.key, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final offline = ref.watch(offlineModeProvider); - final testing = useState(false); - - if (!offline) { - return Container(); - } - - return Padding( - padding: const EdgeInsetsDirectional.only( - start: 20, - bottom: 20, - ), - child: FilledButton.tonal( - style: const ButtonStyle( - padding: MaterialStatePropertyAll( - EdgeInsets.zero, - ), - fixedSize: MaterialStatePropertyAll( - Size(42, 42), - ), - minimumSize: MaterialStatePropertyAll( - Size(42, 42), - ), - ), - onPressed: () async { - testing.value = true; - await ref.read(offlineModeProvider.notifier).setMode(false); - testing.value = false; - }, - child: testing.value - ? const SizedBox( - height: 16, - width: 16, - child: CircularProgressIndicator(strokeWidth: 2.5), - ) - : const Padding( - padding: EdgeInsets.only(left: 2, bottom: 2), - child: Icon( - Icons.cloud_off_rounded, - // color: Theme.of(context).colorScheme.secondary, - size: 20, - ), - ), - ), - ); - } -} - -class _BottomNavBar extends HookConsumerWidget { - final double navElevation; - - const _BottomNavBar({ - required this.navElevation, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final tabsRouter = AutoTabsRouter.of(context); - - useListenableSelector(tabsRouter, () => tabsRouter.activeIndex); - - return Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - const NowPlayingBar(), - NavigationBar( - elevation: navElevation, - height: 50, - labelBehavior: NavigationDestinationLabelBehavior.alwaysHide, - selectedIndex: tabsRouter.activeIndex, - onDestinationSelected: (index) { - // TODO: replace this with a proper first-time setup flow - final hasActiveSource = ref.read(settingsServiceProvider.select( - (value) => value.activeSource != null, - )); - - if (!hasActiveSource) { - tabsRouter.setActiveIndex(3); - } else { - tabsRouter.setActiveIndex(index); - } - }, - destinations: [ - const NavigationDestination( - icon: Icon(Icons.music_note), - label: 'Library', - ), - NavigationDestination( - icon: Builder(builder: (context) { - return SvgPicture.asset( - 'assets/tag_FILL0_wght400_GRAD0_opsz24.svg', - colorFilter: ColorFilter.mode( - IconTheme.of(context).color!.withOpacity( - IconTheme.of(context).opacity ?? 1, - ), - BlendMode.srcIn, - ), - height: 28, - ); - }), - label: 'Browse', - ), - const NavigationDestination( - icon: Icon(Icons.search_rounded), - label: 'Search', - ), - const NavigationDestination( - icon: Icon(Icons.settings_rounded), - label: 'Settings', - ), - ], - ), - ], - ); - } -} diff --git a/lib/app/pages/bottom_nav_page.g.dart b/lib/app/pages/bottom_nav_page.g.dart deleted file mode 100644 index 3980e963..00000000 --- a/lib/app/pages/bottom_nav_page.g.dart +++ /dev/null @@ -1,56 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'bottom_nav_page.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$bottomTabObserverHash() => r'e10c0b870f9b9052ad85fea4342569932edfeefb'; - -/// See also [bottomTabObserver]. -@ProviderFor(bottomTabObserver) -final bottomTabObserverProvider = Provider.internal( - bottomTabObserver, - name: r'bottomTabObserverProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$bottomTabObserverHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef BottomTabObserverRef = ProviderRef; -String _$bottomTabPathHash() => r'62539f7bf5b8f7e5f0531f564e634228ba1506bf'; - -/// See also [bottomTabPath]. -@ProviderFor(bottomTabPath) -final bottomTabPathProvider = StreamProvider.internal( - bottomTabPath, - name: r'bottomTabPathProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$bottomTabPathHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef BottomTabPathRef = StreamProviderRef; -String _$lastBottomNavStateServiceHash() => - r'487cb94cbb70884642c05a72524eb6fd7a4d12ce'; - -/// See also [LastBottomNavStateService]. -@ProviderFor(LastBottomNavStateService) -final lastBottomNavStateServiceProvider = - AsyncNotifierProvider.internal( - LastBottomNavStateService.new, - name: r'lastBottomNavStateServiceProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$lastBottomNavStateServiceHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$LastBottomNavStateService = AsyncNotifier; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/app/pages/browse_page.dart b/lib/app/pages/browse_page.dart deleted file mode 100644 index 0ead47b1..00000000 --- a/lib/app/pages/browse_page.dart +++ /dev/null @@ -1,281 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; -import 'package:sliver_tools/sliver_tools.dart'; - -import '../../database/database.dart'; -import '../../models/music.dart'; -import '../../models/query.dart'; -import '../../models/support.dart'; -import '../../services/audio_service.dart'; -import '../../services/cache_service.dart'; -import '../../state/music.dart'; -import '../../state/settings.dart'; -import '../app_router.dart'; -import '../buttons.dart'; -import '../images.dart'; -import '../items.dart'; - -part 'browse_page.g.dart'; - -@riverpod -Stream> albumsCategoryList( - AlbumsCategoryListRef ref, - ListQuery opt, -) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.albumsList(sourceId, opt).watch(); -} - -class BrowsePage extends HookConsumerWidget { - const BrowsePage({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - - final frequent = ref - .watch(albumsCategoryListProvider(const ListQuery( - page: Pagination(limit: 20), - sort: SortBy(column: 'frequent_rank'), - filters: IListConst([ - FilterWith.isNull(column: 'frequent_rank', invert: true), - ]), - ))) - .valueOrNull; - final recent = ref - .watch(albumsCategoryListProvider(const ListQuery( - page: Pagination(limit: 20), - sort: SortBy(column: 'recent_rank'), - filters: IListConst([ - FilterWith.isNull(column: 'recent_rank', invert: true), - ]), - ))) - .valueOrNull; - final starred = ref - .watch(albumsCategoryListProvider(const ListQuery( - page: Pagination(limit: 20), - sort: SortBy(column: 'starred'), - filters: IListConst([ - FilterWith.isNull(column: 'starred', invert: true), - ]), - ))) - .valueOrNull; - final random = ref - .watch(albumsCategoryListProvider(const ListQuery( - page: Pagination(limit: 20), - sort: SortBy(column: 'RANDOM()'), - ))) - .valueOrNull; - - final genres = ref - .watch(albumGenresProvider(const Pagination( - limit: 20, - ))) - .valueOrNull; - - return Scaffold( - floatingActionButton: RadioPlayFab( - onPressed: () { - ref.read(audioControlProvider).playRadio( - context: QueueContextType.library, - getSongs: (query) => ref - .read(databaseProvider) - .songsList(ref.read(sourceIdProvider), query) - .get(), - ); - }, - ), - body: CustomScrollView( - slivers: [ - const SliverSafeArea( - sliver: SliverPadding(padding: EdgeInsets.only(top: 8)), - ), - _GenreCategory( - title: 'Genres', - items: genres?.toList() ?? [], - ), - _AlbumCategory( - title: l.resourcesSortByFrequentlyPlayed, - items: frequent ?? [], - ), - _AlbumCategory( - title: l.resourcesSortByRecentlyPlayed, - items: recent ?? [], - ), - _AlbumCategory( - title: l.resourcesFilterStarred, - items: starred ?? [], - ), - _AlbumCategory( - title: l.resourcesSortByRandom, - items: random ?? [], - ), - const SliverToBoxAdapter(child: FabPadding()), - ], - ), - ); - } -} - -class _GenreCategory extends HookConsumerWidget { - final String title; - final List items; - - const _GenreCategory({ - required this.title, - required this.items, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return SliverPadding( - padding: const EdgeInsets.only(bottom: 16), - sliver: _Category( - title: title, - height: 140, - itemWidth: 140, - items: items.map((genre) => _GenreItem(genre: genre)).toList(), - ), - ); - } -} - -class _GenreItem extends HookConsumerWidget { - final String genre; - - const _GenreItem({ - required this.genre, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final albums = ref - .watch(albumsByGenreProvider( - genre, - const Pagination(limit: 4), - )) - .valueOrNull; - final cache = ref.watch(cacheServiceProvider); - - final theme = Theme.of(context); - - if (albums == null) { - return Container(); - } - - return ImageCard( - onTap: () { - context.navigateTo(GenreSongsRoute(genre: genre)); - }, - child: Stack( - alignment: AlignmentDirectional.center, - children: [ - CardClip( - child: MultiImage( - cacheInfo: albums.map((album) => cache.albumArt(album)), - ), - ), - Material( - type: MaterialType.canvas, - color: theme.colorScheme.secondaryContainer, - elevation: 5, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 1), - child: SizedBox( - width: double.infinity, - child: Text( - genre, - textAlign: TextAlign.center, - style: theme.textTheme.labelLarge, - ), - ), - ), - ), - ], - ), - ); - } -} - -class _AlbumCategory extends HookConsumerWidget { - final String title; - final List items; - - const _AlbumCategory({ - required this.title, - required this.items, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return _Category( - title: title, - height: 190, - itemWidth: 140, - items: items - .map( - (album) => AlbumCard( - album: album, - onTap: () => context.navigateTo( - AlbumSongsRoute( - id: album.id, - ), - ), - ), - ) - .toList(), - ); - } -} - -class _Category extends HookConsumerWidget { - final String title; - final List items; - final double height; - final double itemWidth; - - const _Category({ - required this.title, - required this.items, - required this.height, - required this.itemWidth, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return MultiSliver( - children: [ - SliverToBoxAdapter( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: Text( - title, - style: Theme.of(context).textTheme.headlineMedium, - ), - ), - ), - SliverToBoxAdapter( - child: SizedBox( - height: height, - child: ListView.separated( - padding: const EdgeInsets.symmetric(horizontal: 16), - scrollDirection: Axis.horizontal, - itemCount: items.length, - itemBuilder: (context, index) => SizedBox( - width: itemWidth, - child: items[index], - ), - separatorBuilder: (context, index) => const SizedBox(width: 8), - ), - ), - ), - ], - ); - } -} diff --git a/lib/app/pages/browse_page.g.dart b/lib/app/pages/browse_page.g.dart deleted file mode 100644 index b5f0cb98..00000000 --- a/lib/app/pages/browse_page.g.dart +++ /dev/null @@ -1,114 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'browse_page.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$albumsCategoryListHash() => - r'e0516a585bf39e8140c72c08fd41f33a817c747d'; - -/// Copied from Dart SDK -class _SystemHash { - _SystemHash._(); - - static int combine(int hash, int value) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + value); - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - return hash ^ (hash >> 6); - } - - static int finish(int hash) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - // ignore: parameter_assignments - hash = hash ^ (hash >> 11); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } -} - -typedef AlbumsCategoryListRef = AutoDisposeStreamProviderRef>; - -/// See also [albumsCategoryList]. -@ProviderFor(albumsCategoryList) -const albumsCategoryListProvider = AlbumsCategoryListFamily(); - -/// See also [albumsCategoryList]. -class AlbumsCategoryListFamily extends Family>> { - /// See also [albumsCategoryList]. - const AlbumsCategoryListFamily(); - - /// See also [albumsCategoryList]. - AlbumsCategoryListProvider call( - ListQuery opt, - ) { - return AlbumsCategoryListProvider( - opt, - ); - } - - @override - AlbumsCategoryListProvider getProviderOverride( - covariant AlbumsCategoryListProvider provider, - ) { - return call( - provider.opt, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'albumsCategoryListProvider'; -} - -/// See also [albumsCategoryList]. -class AlbumsCategoryListProvider - extends AutoDisposeStreamProvider> { - /// See also [albumsCategoryList]. - AlbumsCategoryListProvider( - this.opt, - ) : super.internal( - (ref) => albumsCategoryList( - ref, - opt, - ), - from: albumsCategoryListProvider, - name: r'albumsCategoryListProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$albumsCategoryListHash, - dependencies: AlbumsCategoryListFamily._dependencies, - allTransitiveDependencies: - AlbumsCategoryListFamily._allTransitiveDependencies, - ); - - final ListQuery opt; - - @override - bool operator ==(Object other) { - return other is AlbumsCategoryListProvider && other.opt == opt; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, opt.hashCode); - - return _SystemHash.finish(hash); - } -} -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/app/pages/library_albums_page.dart b/lib/app/pages/library_albums_page.dart deleted file mode 100644 index b8434a97..00000000 --- a/lib/app/pages/library_albums_page.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -import '../../database/database.dart'; -import '../../state/settings.dart'; -import '../app_router.dart'; -import '../hooks/use_list_query_paging_controller.dart'; -import '../items.dart'; -import '../lists.dart'; - -class LibraryAlbumsPage extends HookConsumerWidget { - const LibraryAlbumsPage({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final pagingController = useLibraryPagingController( - ref, - libraryTabIndex: 0, - getItems: (query) { - final db = ref.read(databaseProvider); - final sourceId = ref.read(sourceIdProvider); - - return ref.read(offlineModeProvider) - ? db.albumsListDownloaded(sourceId, query).get() - : db.albumsList(sourceId, query).get(); - }, - ); - - return PagedGridQueryView( - pagingController: pagingController, - refreshSyncAll: true, - itemBuilder: (context, item, index, size) => AlbumCard( - album: item, - style: - size == GridSize.small ? CardStyle.imageOnly : CardStyle.withText, - onTap: () => context.navigateTo(AlbumSongsRoute(id: item.id)), - ), - ); - } -} diff --git a/lib/app/pages/library_artists_page.dart b/lib/app/pages/library_artists_page.dart deleted file mode 100644 index eb206305..00000000 --- a/lib/app/pages/library_artists_page.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -import '../../database/database.dart'; -import '../../state/settings.dart'; -import '../app_router.dart'; -import '../hooks/use_list_query_paging_controller.dart'; -import '../items.dart'; -import '../lists.dart'; - -class LibraryArtistsPage extends HookConsumerWidget { - const LibraryArtistsPage({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final pagingController = useLibraryPagingController( - ref, - libraryTabIndex: 1, - getItems: (query) { - final db = ref.read(databaseProvider); - final sourceId = ref.read(sourceIdProvider); - - return ref.read(offlineModeProvider) - ? db.artistsListDownloaded(sourceId, query).get() - : db.artistsList(sourceId, query).get(); - }, - ); - - return PagedListQueryView( - pagingController: pagingController, - refreshSyncAll: true, - itemBuilder: (context, item, index) => ArtistListTile( - artist: item, - onTap: () => context.navigateTo(ArtistRoute(id: item.id)), - ), - ); - } -} diff --git a/lib/app/pages/library_page.dart b/lib/app/pages/library_page.dart deleted file mode 100644 index 37c5eb68..00000000 --- a/lib/app/pages/library_page.dart +++ /dev/null @@ -1,635 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:collection/collection.dart'; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../../database/database.dart'; -import '../../models/query.dart'; -import '../app_router.dart'; -import '../context_menus.dart'; - -part 'library_page.g.dart'; - -@Riverpod(keepAlive: true) -TabObserver libraryTabObserver(LibraryTabObserverRef ref) { - return TabObserver(); -} - -@Riverpod(keepAlive: true) -Stream libraryTabPath(LibraryTabPathRef ref) async* { - final observer = ref.watch(libraryTabObserverProvider); - await for (var tab in observer.path) { - yield tab; - } -} - -@Riverpod(keepAlive: true) -class LastLibraryStateService extends _$LastLibraryStateService { - @override - Future build() async { - final db = ref.watch(databaseProvider); - final tab = await ref.watch(libraryTabPathProvider.future); - - await db.saveLastLibraryState(LastLibraryStateData( - id: 1, - tab: tab, - albumsList: ref.watch(libraryListQueryProvider(0)).query, - artistsList: ref.watch(libraryListQueryProvider(1)).query, - playlistsList: ref.watch(libraryListQueryProvider(2)).query, - songsList: ref.watch(libraryListQueryProvider(3)).query, - )); - } -} - -@Riverpod(keepAlive: true) -class LibraryLists extends _$LibraryLists { - @override - IList build() { - return const IListConst([ - /// Albums - LibraryListQuery( - options: ListQueryOptions( - sortColumns: IListConst([ - 'albums.name', - 'albums.created', - 'albums.album_artist', - 'albums.year', - ]), - filterColumns: IListConst([ - 'albums.starred', - 'albums.album_artist', - 'albums.year', - 'albums.genre', - ]), - ), - query: ListQuery( - page: Pagination(limit: 60), - sort: SortBy(column: 'albums.name'), - ), - ), - - /// Artists - LibraryListQuery( - options: ListQueryOptions( - sortColumns: IListConst([ - 'artists.name', - 'artists.album_count', - ]), - filterColumns: IListConst([ - 'artists.starred', - ]), - ), - query: ListQuery( - page: Pagination(limit: 30), - sort: SortBy(column: 'artists.name'), - ), - ), - - /// Playlists - LibraryListQuery( - options: ListQueryOptions( - sortColumns: IListConst([ - 'playlists.name', - 'playlists.created', - 'playlists.changed', - ]), - filterColumns: IListConst([ - 'playlists.owner', - ]), - ), - query: ListQuery( - page: Pagination(limit: 30), - sort: SortBy(column: 'playlists.name'), - ), - ), - - /// Songs - LibraryListQuery( - options: ListQueryOptions( - sortColumns: IListConst([ - 'songs.album', - 'songs.artist', - 'songs.created', - 'songs.title', - 'songs.year', - ]), - filterColumns: IListConst([ - 'songs.starred', - 'songs.artist', - 'songs.album', - 'songs.year', - 'songs.genre', - ]), - ), - query: ListQuery( - page: Pagination(limit: 30), - sort: SortBy(column: 'songs.album'), - ), - ), - ]); - } - - Future init() async { - final db = ref.read(databaseProvider); - final last = await db.getLastLibraryState().getSingleOrNull(); - if (last == null) { - return; - } - - state = state - .replace(0, state[0].copyWith(query: last.albumsList)) - .replace(1, state[1].copyWith(query: last.artistsList)) - .replace(2, state[2].copyWith(query: last.playlistsList)) - .replace(3, state[3].copyWith(query: last.songsList)); - } - - void setSortColumn(int index, String column) { - state = state.replace( - index, - state[index].copyWith.query.sort!(column: column), - ); - } - - void toggleDirection(int index) { - final toggled = state[index].query.sort?.dir == SortDirection.asc - ? SortDirection.desc - : SortDirection.asc; - state = state.replace( - index, - state[index].copyWith.query.sort!(dir: toggled), - ); - } - - void setFilter(int index, FilterWith filter) { - state = state.replace( - index, - state[index].copyWith.query( - filters: state[index].query.filters.updateById( - [filter], - (e) => e.column, - ), - ), - ); - } - - void removeFilter(int index, String column) { - state = state.replace( - index, - state[index].copyWith.query( - filters: state[index] - .query - .filters - .removeWhere((f) => f.column == column)), - ); - } - - void clearFilters(int index) { - state = state.replace(index, state[index].copyWith.query(filters: IList())); - } -} - -@Riverpod(keepAlive: true) -LibraryListQuery libraryListQuery(LibraryListQueryRef ref, int index) { - return ref.watch(libraryListsProvider.select((value) => value[index])); -} - -class LibraryTabsPage extends HookConsumerWidget { - const LibraryTabsPage({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final observer = ref.watch(libraryTabObserverProvider); - - return AutoTabsRouter.tabBar( - inheritNavigatorObservers: false, - navigatorObservers: () => [observer], - routes: const [ - LibraryAlbumsRoute(), - LibraryArtistsRoute(), - LibraryPlaylistsRoute(), - LibrarySongsRoute(), - ], - builder: (context, child, tabController) { - return Scaffold( - body: child, - floatingActionButton: const _LibraryFilterFab(), - ); - }, - ); - } -} - -class _LibraryFilterFab extends HookConsumerWidget { - const _LibraryFilterFab(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final tabsRouter = AutoTabsRouter.of(context); - final activeIndex = - useListenableSelector(tabsRouter, () => tabsRouter.activeIndex); - final tabHasFilters = ref.watch(libraryListQueryProvider(activeIndex) - .select((value) => value.query.filters.isNotEmpty)); - - List dot = []; - if (tabHasFilters) { - dot.addAll([ - PositionedDirectional( - top: 3, - end: 0, - child: Icon( - Icons.circle, - color: Theme.of(context).colorScheme.primaryContainer, - size: 11, - ), - ), - const PositionedDirectional( - top: 5, - end: 1, - child: Icon( - Icons.circle, - size: 7, - ), - ), - ]); - } - - return FloatingActionButton( - heroTag: null, - onPressed: () async { - showContextMenu( - context: context, - ref: ref, - builder: (context) => BottomSheetMenu( - child: LibraryMenu( - tabsRouter: tabsRouter, - ), - ), - ); - }, - tooltip: 'List', - child: Stack( - children: [ - const Icon( - Icons.sort_rounded, - size: 28, - ), - ...dot, - ], - ), - ); - } -} - -class LibraryMenu extends HookConsumerWidget { - final TabsRouter tabsRouter; - - const LibraryMenu({ - super.key, - required this.tabsRouter, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return CustomScrollView( - slivers: [ - SliverPadding( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - sliver: SliverToBoxAdapter( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Row( - children: [ - FilterChip( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(100), - ), - onSelected: (value) {}, - selected: true, - label: const Icon( - Icons.grid_on, - size: 20, - ), - ), - const SizedBox(width: 6), - FilterChip( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(100), - ), - onSelected: (value) {}, - label: const Icon( - Icons.grid_view_outlined, - size: 20, - ), - ), - const SizedBox(width: 6), - FilterChip( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(100), - ), - onSelected: (value) {}, - label: const Icon( - Icons.format_list_bulleted, - size: 20, - ), - ), - ], - ), - _FilterToggleButton(tabsRouter: tabsRouter), - ], - ), - ), - ), - const SliverPadding(padding: EdgeInsets.only(top: 8)), - ListSortFilterOptions(index: tabsRouter.activeIndex), - const SliverPadding(padding: EdgeInsets.only(top: 16)), - ], - ); - } -} - -class _FilterToggleButton extends HookConsumerWidget { - final TabsRouter tabsRouter; - - const _FilterToggleButton({ - required this.tabsRouter, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final tabHasFilters = ref.watch( - libraryListQueryProvider(tabsRouter.activeIndex) - .select((value) => value.query.filters.isNotEmpty)); - - return FilledButton( - onPressed: tabHasFilters - ? () { - ref - .read(libraryListsProvider.notifier) - .clearFilters(tabsRouter.activeIndex); - } - : null, - child: const Icon(Icons.filter_list_off_rounded), - ); - } -} - -class ListSortFilterOptions extends HookConsumerWidget { - final int index; - - const ListSortFilterOptions({ - super.key, - required this.index, - }); - - void Function()? _filterOnEdit( - String column, - BuildContext context, - WidgetRef ref, - ) { - final type = column.split('.').last; - switch (type) { - case 'year': - return () { - // TODO: year filter dialog - // showDialog( - // context: context, - // builder: (context) { - // return Dialog( - // child: Text('adsf'), - // ); - // }, - // ); - }; - case 'genre': - case 'album_artist': - case 'owner': - case 'album': - case 'artist': - // TODO: other filter dialogs - return () {}; - default: - return null; - } - } - - void Function(bool? value)? _filterOnChanged(String column, WidgetRef ref) { - final type = column.split('.').last; - switch (type) { - case 'starred': - return (value) { - if (value!) { - ref.read(libraryListsProvider.notifier).setFilter( - index, - FilterWith.isNull(column: column, invert: true), - ); - } else { - ref.read(libraryListsProvider.notifier).removeFilter(index, column); - } - }; - case 'year': - // TODO: add/remove filter - return null; - case 'genre': - case 'album_artist': - case 'owner': - case 'album': - case 'artist': - // TODO: add/remove filter - return null; - default: - return null; - } - } - - @override - Widget build(BuildContext context, WidgetRef ref) { - final list = ref.watch(libraryListQueryProvider(index)); - - return SliverList( - delegate: SliverChildListDelegate.fixed([ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Text( - 'Sort by', - style: Theme.of(context).textTheme.titleLarge, - ), - ), - const SizedBox(height: 8), - for (var column in list.options.sortColumns) - SortOptionTile( - column: column, - value: list.query.sort!.copyWith(column: column), - groupValue: list.query.sort!, - onColumnChanged: (column) { - if (column != null) { - ref - .read(libraryListsProvider.notifier) - .setSortColumn(index, column); - } - }, - onDirectionToggle: () => - ref.read(libraryListsProvider.notifier).toggleDirection(index), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: Text( - 'Filter', - style: Theme.of(context).textTheme.titleLarge, - ), - ), - for (var column in list.options.filterColumns) - FilterOptionTile( - column: column, - state: list.query.filters.singleWhereOrNull( - (e) => e.column == column, - ), - onEdit: _filterOnEdit(column, context, ref), - onChanged: _filterOnChanged(column, ref), - ) - ]), - ); - } -} - -class SortOptionTile extends HookConsumerWidget { - final String column; - final SortBy value; - final SortBy groupValue; - final void Function(String? value) onColumnChanged; - final void Function() onDirectionToggle; - - const SortOptionTile({ - super.key, - required this.column, - required this.value, - required this.groupValue, - required this.onColumnChanged, - required this.onDirectionToggle, - }); - - String _sortTitle(AppLocalizations l, String type) { - type = type.split('.').last; - switch (type) { - case 'name': - return l.resourcesSortByName; - case 'album_artist': - return l.resourcesSortByArtist; - case 'created': - return l.resourcesSortByAdded; - case 'year': - return l.resourcesSortByYear; - case 'album_count': - return l.resourcesSortByAlbumCount; - case 'changed': - return l.resourcesSortByUpdated; - case 'album': - return l.resourcesSortByAlbum; - case 'artist': - return l.resourcesSortByArtist; - case 'title': - return l.resourcesSortByTitle; - default: - return ''; - } - } - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - - return RadioListTile( - value: value.column, - groupValue: groupValue.column, - onChanged: onColumnChanged, - selected: value.column == groupValue.column, - title: Text(_sortTitle(l, column)), - secondary: value.column == groupValue.column - ? IconButton( - icon: Icon( - value.dir == SortDirection.desc - ? Icons.arrow_upward_rounded - : Icons.arrow_downward_rounded, - ), - onPressed: onDirectionToggle, - ) - : null, - ); - } -} - -class FilterOptionTile extends HookConsumerWidget { - final String column; - final FilterWith? state; - final void Function(bool? value)? onChanged; - final void Function()? onEdit; - - const FilterOptionTile({ - super.key, - required this.column, - required this.state, - required this.onChanged, - this.onEdit, - }); - - String _filterTitle(AppLocalizations l, String type) { - type = type.split('.').last; - switch (type) { - case 'starred': - return l.resourcesFilterStarred; - case 'year': - return l.resourcesFilterYear; - case 'genre': - return l.resourcesFilterGenre; - case 'album_artist': - return l.resourcesFilterArtist; - case 'owner': - return l.resourcesFilterOwner; - case 'album': - return l.resourcesFilterAlbum; - case 'artist': - return l.resourcesFilterArtist; - default: - return ''; - } - } - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - - return CheckboxListTile( - value: state == null - ? false - : state!.map( - equals: (value) => value.invert ? null : true, - greaterThan: (value) => true, - isNull: (_) => true, - betweenInt: (_) => true, - isIn: (value) => value.invert ? null : true, - ), - tristate: state?.map( - equals: (value) => true, - greaterThan: (value) => false, - isNull: (_) => false, - betweenInt: (_) => false, - isIn: (_) => true, - ) ?? - false, - title: Text(_filterTitle(l, column)), - secondary: onEdit == null - ? null - : IconButton( - icon: const Icon(Icons.edit_rounded), - onPressed: onEdit, - ), - controlAffinity: ListTileControlAffinity.leading, - onChanged: onChanged, - ); - } -} diff --git a/lib/app/pages/library_page.g.dart b/lib/app/pages/library_page.g.dart deleted file mode 100644 index 65ddfa2f..00000000 --- a/lib/app/pages/library_page.g.dart +++ /dev/null @@ -1,176 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'library_page.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$libraryTabObserverHash() => - r'a976ea55e2168e4684114c47592f25a2b187f15f'; - -/// See also [libraryTabObserver]. -@ProviderFor(libraryTabObserver) -final libraryTabObserverProvider = Provider.internal( - libraryTabObserver, - name: r'libraryTabObserverProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$libraryTabObserverHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef LibraryTabObserverRef = ProviderRef; -String _$libraryTabPathHash() => r'fe60984ea9d629683d344f809749b1b9362735fa'; - -/// See also [libraryTabPath]. -@ProviderFor(libraryTabPath) -final libraryTabPathProvider = StreamProvider.internal( - libraryTabPath, - name: r'libraryTabPathProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$libraryTabPathHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef LibraryTabPathRef = StreamProviderRef; -String _$libraryListQueryHash() => r'6079338e19e0249aaa09868dd405fd3aefc42c2b'; - -/// Copied from Dart SDK -class _SystemHash { - _SystemHash._(); - - static int combine(int hash, int value) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + value); - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - return hash ^ (hash >> 6); - } - - static int finish(int hash) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - // ignore: parameter_assignments - hash = hash ^ (hash >> 11); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } -} - -typedef LibraryListQueryRef = ProviderRef; - -/// See also [libraryListQuery]. -@ProviderFor(libraryListQuery) -const libraryListQueryProvider = LibraryListQueryFamily(); - -/// See also [libraryListQuery]. -class LibraryListQueryFamily extends Family { - /// See also [libraryListQuery]. - const LibraryListQueryFamily(); - - /// See also [libraryListQuery]. - LibraryListQueryProvider call( - int index, - ) { - return LibraryListQueryProvider( - index, - ); - } - - @override - LibraryListQueryProvider getProviderOverride( - covariant LibraryListQueryProvider provider, - ) { - return call( - provider.index, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'libraryListQueryProvider'; -} - -/// See also [libraryListQuery]. -class LibraryListQueryProvider extends Provider { - /// See also [libraryListQuery]. - LibraryListQueryProvider( - this.index, - ) : super.internal( - (ref) => libraryListQuery( - ref, - index, - ), - from: libraryListQueryProvider, - name: r'libraryListQueryProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$libraryListQueryHash, - dependencies: LibraryListQueryFamily._dependencies, - allTransitiveDependencies: - LibraryListQueryFamily._allTransitiveDependencies, - ); - - final int index; - - @override - bool operator ==(Object other) { - return other is LibraryListQueryProvider && other.index == index; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, index.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$lastLibraryStateServiceHash() => - r'a49e26b5dc0fcb0f697ec2def08e7336f64c4cb3'; - -/// See also [LastLibraryStateService]. -@ProviderFor(LastLibraryStateService) -final lastLibraryStateServiceProvider = - AsyncNotifierProvider.internal( - LastLibraryStateService.new, - name: r'lastLibraryStateServiceProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$lastLibraryStateServiceHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$LastLibraryStateService = AsyncNotifier; -String _$libraryListsHash() => r'7c9fd1ca3b0d70253e0f5d8197abf18b3a18c995'; - -/// See also [LibraryLists]. -@ProviderFor(LibraryLists) -final libraryListsProvider = - NotifierProvider>.internal( - LibraryLists.new, - name: r'libraryListsProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$libraryListsHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$LibraryLists = Notifier>; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/app/pages/library_playlists_page.dart b/lib/app/pages/library_playlists_page.dart deleted file mode 100644 index d4e472b1..00000000 --- a/lib/app/pages/library_playlists_page.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -import '../../database/database.dart'; -import '../../state/settings.dart'; -import '../app_router.dart'; -import '../hooks/use_list_query_paging_controller.dart'; -import '../items.dart'; -import '../lists.dart'; - -class LibraryPlaylistsPage extends HookConsumerWidget { - const LibraryPlaylistsPage({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final pagingController = useLibraryPagingController( - ref, - libraryTabIndex: 2, - getItems: (query) { - final db = ref.read(databaseProvider); - final sourceId = ref.read(sourceIdProvider); - - return ref.read(offlineModeProvider) - ? db.playlistsListDownloaded(sourceId, query).get() - : db.playlistsList(sourceId, query).get(); - }, - ); - - return PagedListQueryView( - pagingController: pagingController, - refreshSyncAll: true, - itemBuilder: (context, item, index) => PlaylistListTile( - playlist: item, - onTap: () => context.navigateTo(PlaylistSongsRoute(id: item.id)), - ), - ); - } -} diff --git a/lib/app/pages/library_songs_page.dart b/lib/app/pages/library_songs_page.dart deleted file mode 100644 index e3b884ce..00000000 --- a/lib/app/pages/library_songs_page.dart +++ /dev/null @@ -1,81 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../../database/database.dart'; -import '../../models/music.dart'; -import '../../models/query.dart'; -import '../../models/support.dart'; -import '../../services/audio_service.dart'; -import '../../state/settings.dart'; -import '../hooks/use_list_query_paging_controller.dart'; -import '../items.dart'; -import '../lists.dart'; -import 'library_page.dart'; -import 'songs_page.dart'; - -part 'library_songs_page.g.dart'; - -@riverpod -Future> songsList(SongsListRef ref, ListQuery opt) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.songsList(sourceId, opt).get(); -} - -class LibrarySongsPage extends HookConsumerWidget { - const LibrarySongsPage({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final audio = ref.watch(audioControlProvider); - - final query = ref.watch(libraryListQueryProvider(3).select( - (value) => value.query, - )); - - final getSongs = useCallback( - (ListQuery query) { - final db = ref.read(databaseProvider); - final sourceId = ref.read(sourceIdProvider); - - return ref.read(offlineModeProvider) - ? db.songsListDownloaded(sourceId, query).get() - : db.songsList(sourceId, query).get(); - }, - [], - ); - - final play = useCallback( - ({int? index, bool? shuffle}) => audio.playSongs( - query: query, - getSongs: getSongs, - startIndex: index, - context: QueueContextType.song, - shuffle: shuffle, - ), - [query, getSongs], - ); - - final pagingController = useLibraryPagingController( - ref, - libraryTabIndex: 3, - getItems: getSongs, - ); - - return PagedListQueryView( - pagingController: pagingController, - refreshSyncAll: true, - itemBuilder: (context, item, index) => QueueContext( - type: QueueContextType.song, - child: SongListTile( - song: item, - image: true, - onTap: () => play(index: index), - ), - ), - ); - } -} diff --git a/lib/app/pages/library_songs_page.g.dart b/lib/app/pages/library_songs_page.g.dart deleted file mode 100644 index 11190d5d..00000000 --- a/lib/app/pages/library_songs_page.g.dart +++ /dev/null @@ -1,111 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'library_songs_page.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$songsListHash() => r'a3149eb61f8f1ff326e9b1de0ac1c02d7baa831f'; - -/// Copied from Dart SDK -class _SystemHash { - _SystemHash._(); - - static int combine(int hash, int value) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + value); - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - return hash ^ (hash >> 6); - } - - static int finish(int hash) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - // ignore: parameter_assignments - hash = hash ^ (hash >> 11); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } -} - -typedef SongsListRef = AutoDisposeFutureProviderRef>; - -/// See also [songsList]. -@ProviderFor(songsList) -const songsListProvider = SongsListFamily(); - -/// See also [songsList]. -class SongsListFamily extends Family>> { - /// See also [songsList]. - const SongsListFamily(); - - /// See also [songsList]. - SongsListProvider call( - ListQuery opt, - ) { - return SongsListProvider( - opt, - ); - } - - @override - SongsListProvider getProviderOverride( - covariant SongsListProvider provider, - ) { - return call( - provider.opt, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'songsListProvider'; -} - -/// See also [songsList]. -class SongsListProvider extends AutoDisposeFutureProvider> { - /// See also [songsList]. - SongsListProvider( - this.opt, - ) : super.internal( - (ref) => songsList( - ref, - opt, - ), - from: songsListProvider, - name: r'songsListProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$songsListHash, - dependencies: SongsListFamily._dependencies, - allTransitiveDependencies: SongsListFamily._allTransitiveDependencies, - ); - - final ListQuery opt; - - @override - bool operator ==(Object other) { - return other is SongsListProvider && other.opt == opt; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, opt.hashCode); - - return _SystemHash.finish(hash); - } -} -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/app/pages/now_playing_page.dart b/lib/app/pages/now_playing_page.dart deleted file mode 100644 index 8eecb004..00000000 --- a/lib/app/pages/now_playing_page.dart +++ /dev/null @@ -1,429 +0,0 @@ -import 'dart:math'; - -import 'package:audio_service/audio_service.dart'; -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:text_scroll/text_scroll.dart'; - -import '../../cache/image_cache.dart'; -import '../../models/support.dart'; -import '../../services/audio_service.dart'; -import '../../state/audio.dart'; -import '../../state/theme.dart'; -import '../context_menus.dart'; -import '../gradient.dart'; -import '../images.dart'; -import '../now_playing_bar.dart'; - -class NowPlayingPage extends HookConsumerWidget { - const NowPlayingPage({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final colors = ref.watch(mediaItemThemeProvider).valueOrNull; - final itemData = ref.watch(mediaItemDataProvider); - - final theme = Theme.of(context); - - final scaffold = AnnotatedRegion( - value: SystemUiOverlayStyle.light.copyWith( - systemNavigationBarColor: colors?.gradientLow, - statusBarColor: Colors.transparent, - ), - child: Scaffold( - appBar: AppBar( - title: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - itemData?.contextType.value ?? '', - style: theme.textTheme.labelMedium, - maxLines: 1, - softWrap: false, - overflow: TextOverflow.fade, - ), - // Text( - // itemData?.contextTitle ?? '', - // style: theme.textTheme.titleMedium, - // maxLines: 1, - // softWrap: false, - // overflow: TextOverflow.fade, - // ), - ], - ), - ), - body: Stack( - children: [ - const MediaItemGradient(), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8), - child: Column( - children: const [ - Expanded( - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 16), - child: _Art(), - ), - ), - SizedBox(height: 24), - Padding( - padding: EdgeInsets.symmetric(horizontal: 16), - child: _TrackInfo(), - ), - SizedBox(height: 8), - _Progress(), - Padding( - padding: EdgeInsets.symmetric(horizontal: 16), - child: _Controls(), - ), - SizedBox(height: 64), - ], - ), - ), - ], - ), - ), - ); - - if (colors != null) { - return Theme(data: colors.theme, child: scaffold); - } else { - return scaffold; - } - } -} - -class _Art extends HookConsumerWidget { - const _Art(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final itemData = ref.watch(mediaItemDataProvider); - final imageCache = ref.watch(imageCacheProvider); - - UriCacheInfo? cacheInfo; - if (itemData?.artCache != null) { - cacheInfo = UriCacheInfo( - uri: itemData!.artCache!.fullArtUri, - cacheKey: itemData.artCache!.fullArtCacheKey, - cacheManager: imageCache, - ); - } - - return AnimatedSwitcher( - duration: const Duration(milliseconds: 150), - child: CardClip( - key: ValueKey(cacheInfo?.cacheKey ?? 'default'), - child: cacheInfo != null - ? CardClip( - square: false, - child: UriCacheInfoImage( - // height: 300, - fit: BoxFit.contain, - placeholderStyle: PlaceholderStyle.spinner, - cache: cacheInfo, - ), - ) - : const PlaceholderImage(thumbnail: false), - ), - ); - } -} - -class _TrackInfo extends HookConsumerWidget { - const _TrackInfo(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final item = ref.watch(mediaItemProvider).valueOrNull; - final theme = Theme.of(context); - - return Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ScrollableText( - item?.title ?? '', - style: theme.textTheme.headlineSmall, - speed: 50, - ), - Text( - item?.artist ?? '', - style: theme.textTheme.titleMedium!, - maxLines: 1, - softWrap: false, - overflow: TextOverflow.fade, - ), - ], - ), - ), - IconButton( - icon: const Icon( - Icons.star_outline_rounded, - size: 36, - ), - onPressed: () {}, - ), - ], - ); - } -} - -class ScrollableText extends StatelessWidget { - final String text; - final TextStyle? style; - final double speed; - - const ScrollableText( - this.text, { - super.key, - this.style, - this.speed = 35, - }); - - @override - Widget build(BuildContext context) { - final defaultStyle = DefaultTextStyle.of(context); - - return AutoSizeText( - text, - presetFontSizes: style != null && style?.fontSize != null - ? [style!.fontSize!] - : [defaultStyle.style.fontSize ?? 12], - style: style, - maxLines: 1, - // softWrap: false, - overflowReplacement: TextScroll( - '$text ', - style: style, - delayBefore: const Duration(seconds: 3), - pauseBetween: const Duration(seconds: 4), - mode: TextScrollMode.endless, - velocity: Velocity(pixelsPerSecond: Offset(speed, 0)), - ), - ); - } -} - -class _Progress extends HookConsumerWidget { - const _Progress(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final colors = ref.watch(mediaItemThemeProvider).valueOrNull; - final position = ref.watch(positionProvider); - final duration = ref.watch(durationProvider); - final audio = ref.watch(audioControlProvider); - - final changeValue = useState(position.toDouble()); - final changing = useState(false); - - return Column( - children: [ - Slider( - value: changing.value ? changeValue.value : position.toDouble(), - min: 0, - max: max(duration.toDouble(), position.toDouble()), - thumbColor: colors?.theme.colorScheme.onBackground, - activeColor: colors?.theme.colorScheme.onBackground, - inactiveColor: colors?.theme.colorScheme.surface, - onChanged: (value) { - changeValue.value = value; - }, - onChangeStart: (value) { - changing.value = true; - }, - onChangeEnd: (value) { - changing.value = false; - audio.seek(Duration(seconds: value.toInt())); - }, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24), - child: DefaultTextStyle( - style: Theme.of(context).textTheme.titleMedium!, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(Duration( - seconds: changing.value - ? changeValue.value.toInt() - : position) - .toString() - .substring(2, 7)), - Text(Duration(seconds: duration).toString().substring(2, 7)), - ], - ), - ), - ) - ], - ); - } -} - -class RepeatButton extends HookConsumerWidget { - final double size; - - const RepeatButton({ - super.key, - required this.size, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final audio = ref.watch(audioControlProvider); - final repeat = ref.watch(repeatModeProvider); - - IconData icon; - void Function() action; - - switch (repeat) { - case AudioServiceRepeatMode.all: - case AudioServiceRepeatMode.group: - icon = Icons.repeat_on_rounded; - action = () => audio.setRepeatMode(AudioServiceRepeatMode.one); - break; - case AudioServiceRepeatMode.one: - icon = Icons.repeat_one_on_rounded; - action = () => audio.setRepeatMode(AudioServiceRepeatMode.none); - break; - default: - icon = Icons.repeat_rounded; - action = () => audio.setRepeatMode(AudioServiceRepeatMode.all); - break; - } - - return IconButton( - icon: Icon(icon), - padding: EdgeInsets.zero, - iconSize: 30, - onPressed: action, - ); - } -} - -class ShuffleButton extends HookConsumerWidget { - final double size; - - const ShuffleButton({ - super.key, - required this.size, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final audio = ref.watch(audioControlProvider); - final shuffle = ref.watch(shuffleModeProvider); - final queueMode = ref.watch(queueModeProvider).valueOrNull; - - IconData icon; - void Function() action; - - switch (shuffle) { - case AudioServiceShuffleMode.all: - case AudioServiceShuffleMode.group: - icon = Icons.shuffle_on_rounded; - action = () => audio.setShuffleMode(AudioServiceShuffleMode.none); - break; - default: - icon = Icons.shuffle_rounded; - action = () => audio.setShuffleMode(AudioServiceShuffleMode.all); - break; - } - - return IconButton( - icon: Icon(queueMode == QueueMode.radio ? Icons.radio_rounded : icon), - padding: EdgeInsets.zero, - iconSize: 30, - onPressed: queueMode == QueueMode.radio ? null : action, - ); - } -} - -class _Controls extends HookConsumerWidget { - const _Controls(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final base = ref.watch(baseThemeProvider); - final audio = ref.watch(audioControlProvider); - - return IconTheme( - data: IconThemeData(color: base.theme.colorScheme.onBackground), - child: Column( - children: [ - SizedBox( - height: 100, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const RepeatButton(size: 30), - IconButton( - icon: const Icon(Icons.skip_previous_rounded), - padding: EdgeInsets.zero, - iconSize: 60, - onPressed: () => audio.skipToPrevious(), - ), - const PlayPauseButton(size: 90), - IconButton( - icon: const Icon(Icons.skip_next_rounded), - padding: EdgeInsets.zero, - iconSize: 60, - onPressed: () => audio.skipToNext(), - ), - const ShuffleButton(size: 30), - ], - ), - ), - SizedBox( - height: 40, - child: Row( - // crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - IconButton( - icon: const Icon(Icons.queue_music_rounded), - padding: EdgeInsets.zero, - iconSize: 30, - onPressed: () {}, - ), - const _MoreButton(), - ], - ), - ), - ], - ), - ); - } -} - -class _MoreButton extends HookConsumerWidget { - const _MoreButton(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final song = ref.watch(mediaItemSongProvider).valueOrNull; - - return IconButton( - icon: const Icon(Icons.more_horiz), - padding: EdgeInsets.zero, - iconSize: 30, - onPressed: song != null - ? () { - showContextMenu( - context: context, - ref: ref, - builder: (context) => BottomSheetMenu( - child: SongContextMenu(song: song), - ), - ); - } - : null, - ); - } -} diff --git a/lib/app/pages/search_page.dart b/lib/app/pages/search_page.dart deleted file mode 100644 index 8759443c..00000000 --- a/lib/app/pages/search_page.dart +++ /dev/null @@ -1,247 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../../database/database.dart'; -import '../../models/music.dart'; -import '../../models/query.dart'; -import '../../models/support.dart'; -import '../../services/audio_service.dart'; -import '../../state/music.dart'; -import '../../state/settings.dart'; -import '../app_router.dart'; -import '../items.dart'; -import 'songs_page.dart'; - -part 'search_page.g.dart'; - -@riverpod -class SearchQuery extends _$SearchQuery { - @override - String? build() { - return null; - } - - void setQuery(String query) { - state = query; - } -} - -@riverpod -FutureOr searchResult(SearchResultRef ref) async { - final query = ref.watch(searchQueryProvider); - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - final ftsQuery = '(source_id : $sourceId) AND (- source_id : "$query"*)'; - - final songRowIds = await db.searchSongs(ftsQuery, 5, 0).get(); - final songs = await db.songsInRowIds(songRowIds).get(); - final albumRowIds = await db.searchAlbums(ftsQuery, 5, 0).get(); - final albums = await db.albumsInRowIds(albumRowIds).get(); - final artistRowIds = await db.searchArtists(ftsQuery, 5, 0).get(); - final artists = await db.artistsInRowIds(artistRowIds).get(); - - return SearchResults( - songs: songs.lock, - albums: albums.lock, - artists: artists.lock, - ); -} - -class SearchPage extends HookConsumerWidget { - const SearchPage({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final results = ref.watch(searchResultProvider).valueOrNull; - - return KeyboardDismissOnTap( - dismissOnCapturedTaps: true, - child: Scaffold( - body: SafeArea( - child: CustomScrollView( - reverse: true, - slivers: [ - const SliverToBoxAdapter(child: _SearchBar()), - if (results != null && results.songs.isNotEmpty) - _SongsSection(songs: results.songs), - if (results != null && results.albums.isNotEmpty) - _AlbumsSection(albums: results.albums), - if (results != null && results.artists.isNotEmpty) - _ArtistsSection(artists: results.artists), - if (results != null) - const SliverPadding(padding: EdgeInsets.only(top: 96)) - ], - ), - ), - ), - ); - } -} - -class _SearchBar extends HookConsumerWidget { - const _SearchBar(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final controller = useTextEditingController(text: ''); - - final theme = Theme.of(context); - final l = AppLocalizations.of(context); - - return Container( - color: ElevationOverlay.applySurfaceTint( - theme.colorScheme.surface, - theme.colorScheme.surfaceTint, - 1, - ), - child: Padding( - padding: const EdgeInsets.only( - right: 24, - left: 24, - bottom: 24, - top: 8, - ), - child: IgnoreKeyboardDismiss( - child: TextFormField( - controller: controller, - decoration: InputDecoration( - hintText: l.searchInputPlaceholder, - ), - onChanged: (value) { - ref.read(searchQueryProvider.notifier).setQuery(value); - }, - ), - ), - ), - ); - } -} - -class _SectionHeader extends HookConsumerWidget { - final String title; - - const _SectionHeader({required this.title}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final theme = Theme.of(context).textTheme; - - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: Text(title, style: theme.headlineMedium), - ); - } -} - -class _Section extends HookConsumerWidget { - final String title; - final Iterable children; - - const _Section({ - required this.title, - required this.children, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return SliverList( - delegate: SliverChildListDelegate([ - const SizedBox(height: 16), - ...children.toList().reversed, - _SectionHeader(title: title), - ]), - ); - } -} - -class _SongsSection extends HookConsumerWidget { - final IList? songs; - - const _SongsSection({required this.songs}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - - return _Section( - title: l.resourcesSongName(100), - children: (songs ?? []).map( - (song) => QueueContext( - type: QueueContextType.album, - id: song.albumId!, - child: SongListTile( - song: song, - image: true, - onTap: () async { - const query = ListQuery( - sort: SortBy(column: 'disc, track'), - ); - final albumSongs = await ref.read( - albumSongsListProvider(song.albumId!, query).future, - ); - - ref.read(audioControlProvider).playSongs( - context: QueueContextType.album, - contextId: song.albumId!, - shuffle: true, - startIndex: albumSongs.indexOf(song), - query: query, - getSongs: (query) => ref.read( - albumSongsListProvider(song.albumId!, query).future), - ); - }, - ), - ), - ), - ); - } -} - -class _AlbumsSection extends HookConsumerWidget { - final IList? albums; - - const _AlbumsSection({required this.albums}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - - return _Section( - title: l.resourcesAlbumName(100), - children: (albums ?? []).map( - (album) => AlbumListTile( - album: album, - onTap: () => context.navigateTo(AlbumSongsRoute(id: album.id)), - ), - ), - ); - } -} - -class _ArtistsSection extends HookConsumerWidget { - final IList? artists; - - const _ArtistsSection({required this.artists}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - - return _Section( - title: l.resourcesArtistName(100), - children: (artists ?? []).map( - (artist) => ArtistListTile( - artist: artist, - onTap: () => context.navigateTo(ArtistRoute(id: artist.id)), - ), - ), - ); - } -} diff --git a/lib/app/pages/search_page.g.dart b/lib/app/pages/search_page.g.dart deleted file mode 100644 index 4a0b6749..00000000 --- a/lib/app/pages/search_page.g.dart +++ /dev/null @@ -1,38 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'search_page.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$searchResultHash() => r'e5240c0c51937e1e946138d27aeaea93dc0231c3'; - -/// See also [searchResult]. -@ProviderFor(searchResult) -final searchResultProvider = AutoDisposeFutureProvider.internal( - searchResult, - name: r'searchResultProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$searchResultHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef SearchResultRef = AutoDisposeFutureProviderRef; -String _$searchQueryHash() => r'f7624215b3d5a8b917cb0af239666a19a18d91d5'; - -/// See also [SearchQuery]. -@ProviderFor(SearchQuery) -final searchQueryProvider = - AutoDisposeNotifierProvider.internal( - SearchQuery.new, - name: r'searchQueryProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$searchQueryHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$SearchQuery = AutoDisposeNotifier; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/app/pages/settings_page.dart b/lib/app/pages/settings_page.dart deleted file mode 100644 index ab90bdf6..00000000 --- a/lib/app/pages/settings_page.dart +++ /dev/null @@ -1,448 +0,0 @@ -import 'dart:math'; - -import 'package:auto_route/auto_route.dart'; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:path/path.dart' as p; -import 'package:share_plus/share_plus.dart'; -import 'package:url_launcher/url_launcher.dart'; - -import '../../log.dart'; -import '../../models/support.dart'; -import '../../services/settings_service.dart'; -import '../../state/init.dart'; -import '../../state/settings.dart'; -import '../app_router.dart'; -import '../dialogs.dart'; - -const kHorizontalPadding = 16.0; - -class SettingsPage extends HookConsumerWidget { - const SettingsPage({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - // final downloads = ref.watch(downloadServiceProvider.select( - // (value) => value.downloads, - // )); - - return Scaffold( - body: ListView( - children: [ - const SizedBox(height: 96), - _SectionHeader(l.settingsServersName), - const _Sources(), - _SectionHeader(l.settingsNetworkName), - const _Network(), - _SectionHeader(l.settingsAboutName), - _About(), - // const _SectionHeader('Downloads'), - // _Section( - // children: downloads - // .map( - // (e) => ListTile( - // isThreeLine: true, - // title: Text(e.filename ?? e.url), - // subtitle: Column( - // mainAxisAlignment: MainAxisAlignment.start, - // children: [ - // Row(children: [Text('Progress: ${e.progress}%')]), - // Row(children: [Text('Status: ${e.status})')]), - // Text('Status: ${e.savedDir}'), - // ], - // ), - // trailing: - // CircularProgressIndicator(value: e.progress / 100), - // ), - // ) - // .toList(), - // ), - ], - ), - ); - } -} - -class _Section extends StatelessWidget { - final List children; - - const _Section({required this.children}); - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - ...children, - const SizedBox(height: 32), - ], - ); - } -} - -class _SectionHeader extends StatelessWidget { - final String title; - - const _SectionHeader(this.title); - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - - return Column( - children: [ - SizedBox( - width: double.infinity, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: kHorizontalPadding), - child: Text( - title, - style: theme.textTheme.displaySmall, - ), - ), - ), - const SizedBox(height: 12), - ], - ); - } -} - -class _Network extends StatelessWidget { - const _Network(); - - @override - Widget build(BuildContext context) { - return const _Section( - children: [ - _OfflineMode(), - _MaxBitrateWifi(), - _MaxBitrateMobile(), - _StreamFormat(), - ], - ); - } -} - -class _About extends HookConsumerWidget { - _About(); - - final _homepage = Uri.parse('https://github.com/austinried/subtracks'); - final _donate = Uri.parse('https://ko-fi.com/austinried'); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - final pkg = ref.watch(packageInfoProvider).requireValue; - - return _Section( - children: [ - ListTile( - title: const Text('subtracks'), - subtitle: Text(l.settingsAboutVersion(pkg.version)), - ), - ListTile( - title: Text(l.settingsAboutActionsLicenses), - // trailing: const Icon(Icons.open_in_new_rounded), - onTap: () {}, - ), - ListTile( - title: Text(l.settingsAboutActionsProjectHomepage), - subtitle: Text(_homepage.toString()), - trailing: const Icon(Icons.open_in_new_rounded), - onTap: () => launchUrl( - _homepage, - mode: LaunchMode.externalApplication, - ), - ), - ListTile( - title: Text(l.settingsAboutActionsSupport), - subtitle: Text(_donate.toString()), - trailing: const Icon(Icons.open_in_new_rounded), - onTap: () => launchUrl( - _donate, - mode: LaunchMode.externalApplication, - ), - ), - const SizedBox(height: 12), - const _ShareLogsButton(), - ], - ); - } -} - -class _ShareLogsButton extends StatelessWidget { - const _ShareLogsButton(); - - @override - Widget build(BuildContext context) { - final l = AppLocalizations.of(context); - - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - OutlinedButton.icon( - icon: const Icon(Icons.share), - label: Text(l.settingsAboutShareLogs), - onPressed: () async { - final files = await logFiles(); - if (files.isEmpty) return; - - // ignore: use_build_context_synchronously - final value = await showDialog( - context: context, - builder: (context) => MultipleChoiceDialog( - title: l.settingsAboutChooseLog, - current: files.first.path, - options: files - .map((e) => MultiChoiceOption.string( - title: p.basename(e.path), - option: e.path, - )) - .toIList(), - ), - ); - - if (value == null) return; - Share.shareXFiles( - [XFile(value, mimeType: 'text/plain')], - subject: 'Logs from subtracks: ${String.fromCharCodes( - List.generate(8, (_) => Random().nextInt(26) + 65), - )}', - ); - }, - ), - ], - ); - } -} - -class _MaxBitrateWifi extends HookConsumerWidget { - const _MaxBitrateWifi(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final bitrate = ref.watch(settingsServiceProvider.select( - (value) => value.app.maxBitrateWifi, - )); - final l = AppLocalizations.of(context); - - return _MaxBitrateOption( - title: l.settingsNetworkOptionsMaxBitrateWifiTitle, - bitrate: bitrate, - onChange: (value) { - ref.read(settingsServiceProvider.notifier).setMaxBitrateWifi(value); - }, - ); - } -} - -class _MaxBitrateMobile extends HookConsumerWidget { - const _MaxBitrateMobile(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final bitrate = ref.watch(settingsServiceProvider.select( - (value) => value.app.maxBitrateMobile, - )); - final l = AppLocalizations.of(context); - - return _MaxBitrateOption( - title: l.settingsNetworkOptionsMaxBitrateMobileTitle, - bitrate: bitrate, - onChange: (value) { - ref.read(settingsServiceProvider.notifier).setMaxBitrateMobile(value); - }, - ); - } -} - -class _MaxBitrateOption extends HookConsumerWidget { - final String title; - final int bitrate; - final void Function(int value) onChange; - - const _MaxBitrateOption({ - required this.title, - required this.bitrate, - required this.onChange, - }); - - static const options = [0, 24, 32, 64, 96, 128, 192, 256, 320]; - - String _bitrateText(AppLocalizations l, int bitrate) { - return bitrate == 0 - ? l.settingsNetworkValuesUnlimitedKbps - : l.settingsNetworkValuesKbps(bitrate.toString()); - } - - @override - Widget build(BuildContext context, WidgetRef ref) { - final l = AppLocalizations.of(context); - - return ListTile( - title: Text(title), - subtitle: Text(_bitrateText(l, bitrate)), - onTap: () async { - final value = await showDialog( - context: context, - builder: (context) => MultipleChoiceDialog( - title: title, - current: bitrate, - options: options - .map((opt) => MultiChoiceOption.int( - title: _bitrateText(l, opt), - option: opt, - )) - .toIList(), - ), - ); - - if (value != null) { - onChange(value); - } - }, - ); - } -} - -class _StreamFormat extends HookConsumerWidget { - const _StreamFormat(); - - static const options = ['', 'mp3', 'opus', 'ogg']; - - @override - Widget build(BuildContext context, WidgetRef ref) { - final streamFormat = ref.watch( - settingsServiceProvider.select((value) => value.app.streamFormat), - ); - final l = AppLocalizations.of(context); - - return ListTile( - title: Text(l.settingsNetworkOptionsStreamFormat), - subtitle: Text( - streamFormat ?? l.settingsNetworkOptionsStreamFormatServerDefault, - ), - onTap: () async { - final value = await showDialog( - context: context, - builder: (context) => MultipleChoiceDialog( - title: l.settingsNetworkOptionsStreamFormat, - current: streamFormat ?? '', - options: options - .map((opt) => MultiChoiceOption.string( - title: opt == '' - ? l.settingsNetworkOptionsStreamFormatServerDefault - : opt, - option: opt, - )) - .toIList(), - ), - ); - - if (value != null) { - ref - .read(settingsServiceProvider.notifier) - .setStreamFormat(value == '' ? null : value); - } - }, - ); - } -} - -class _OfflineMode extends HookConsumerWidget { - const _OfflineMode(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final offline = ref.watch(offlineModeProvider); - final l = AppLocalizations.of(context); - - return SwitchListTile( - value: offline, - title: Text(l.settingsNetworkOptionsOfflineMode), - subtitle: offline - ? Text(l.settingsNetworkOptionsOfflineModeOn) - : Text(l.settingsNetworkOptionsOfflineModeOff), - onChanged: (value) { - ref.read(offlineModeProvider.notifier).setMode(value); - }, - ); - } -} - -class _Sources extends HookConsumerWidget { - const _Sources(); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final sources = ref.watch(settingsServiceProvider.select( - (value) => value.sources, - )); - final activeSource = ref.watch(settingsServiceProvider.select( - (value) => value.activeSource, - )); - - final l = AppLocalizations.of(context); - - return _Section( - children: [ - for (var source in sources) - RadioListTile( - value: source.id, - groupValue: activeSource?.id, - onChanged: (value) { - ref - .read(settingsServiceProvider.notifier) - .setActiveSource(source.id); - }, - title: Text(source.name), - subtitle: Text( - source.address.toString(), - maxLines: 1, - softWrap: false, - overflow: TextOverflow.fade, - ), - secondary: IconButton( - icon: const Icon(Icons.edit_rounded), - onPressed: () { - context.pushRoute(SourceRoute(id: source.id)); - }, - ), - ), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - OutlinedButton.icon( - icon: const Icon(Icons.add_rounded), - label: Text(l.settingsServersActionsAdd), - onPressed: () { - context.pushRoute(SourceRoute()); - }, - ), - ], - ), - // TODO: remove - if (kDebugMode) - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - OutlinedButton.icon( - icon: const Icon(Icons.add_rounded), - label: const Text('Add TEST'), - onPressed: () { - ref - .read(settingsServiceProvider.notifier) - .addTestSource('TEST'); - }, - ), - ], - ), - ], - ); - } -} diff --git a/lib/app/pages/songs_page.dart b/lib/app/pages/songs_page.dart deleted file mode 100644 index b6cbd581..00000000 --- a/lib/app/pages/songs_page.dart +++ /dev/null @@ -1,511 +0,0 @@ -import 'dart:async'; - -import 'package:auto_route/auto_route.dart'; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:sliver_tools/sliver_tools.dart'; - -import '../../models/music.dart'; -import '../../models/query.dart'; -import '../../models/support.dart'; -import '../../services/audio_service.dart'; -import '../../services/cache_service.dart'; -import '../../state/music.dart'; -import '../../state/settings.dart'; -import '../../state/theme.dart'; -import '../buttons.dart'; -import '../context_menus.dart'; -import '../gradient.dart'; -import '../hooks/use_download_actions.dart'; -import '../hooks/use_list_query_paging_controller.dart'; -import '../images.dart'; -import '../items.dart'; -import '../lists.dart'; - -class AlbumSongsPage extends HookConsumerWidget { - final String id; - - const AlbumSongsPage({ - super.key, - @pathParam required this.id, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final album = ref.watch(albumProvider(id)).valueOrNull; - final audio = ref.watch(audioControlProvider); - final colors = ref.watch(albumArtThemeProvider(id)).valueOrNull; - final key = useState(GlobalKey()); - - if (album == null) { - return Container(); - } - - final query = useMemoized(() => const ListQuery( - page: Pagination(limit: 30), - sort: SortBy(column: 'disc, track'), - )); - - final getSongs = useCallback( - (ListQuery query) => ref.read(albumSongsListProvider(id, query).future), - [id], - ); - - final play = useCallback( - ({int? index, bool? shuffle}) => audio.playSongs( - query: query, - getSongs: getSongs, - startIndex: index, - context: QueueContextType.album, - contextId: id, - shuffle: shuffle, - ), - [id, query, getSongs], - ); - - return QueueContext( - id: id, - type: QueueContextType.album, - child: _SongsPage( - query: query, - getSongs: getSongs, - fab: ShuffleFab(onPressed: () => play(shuffle: true)), - onSongTap: (song, index) => play(index: index), - background: AlbumArtGradient(key: key.value, id: id), - colors: colors, - header: _AlbumHeader( - album: album, - play: () => play(shuffle: false), - ), - ), - ); - } -} - -class _AlbumHeader extends HookConsumerWidget { - final Album album; - final void Function() play; - - const _AlbumHeader({ - required this.album, - required this.play, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final cache = ref.watch(cacheServiceProvider); - - final downloadActions = useAlbumDownloadActions( - context: context, - ref: ref, - album: album, - ); - - final l = AppLocalizations.of(context); - - return _Header( - title: album.name, - subtitle: album.albumArtist, - imageCache: cache.albumArt(album, thumbnail: false), - playText: l.resourcesAlbumActionsPlay, - onPlay: play, - onMore: () => showContextMenu( - context: context, - ref: ref, - builder: (context) => BottomSheetMenu( - child: AlbumContextMenu(album: album), - ), - ), - downloadActions: downloadActions, - ); - } -} - -class PlaylistSongsPage extends HookConsumerWidget { - final String id; - - const PlaylistSongsPage({ - super.key, - @pathParam required this.id, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final playlist = ref.watch(playlistProvider(id)).valueOrNull; - final audio = ref.watch(audioControlProvider); - final colors = ref.watch(playlistArtThemeProvider(id)).valueOrNull; - - if (playlist == null) { - return Container(); - } - - final query = useMemoized(() => const ListQuery( - page: Pagination(limit: 30), - sort: SortBy(column: 'playlist_songs.position'), - )); - - final getSongs = useCallback( - (ListQuery query) => - ref.read(playlistSongsListProvider(id, query).future), - [id], - ); - - final play = useCallback( - ({int? index, bool? shuffle}) => audio.playSongs( - query: query, - getSongs: getSongs, - startIndex: index, - context: QueueContextType.playlist, - contextId: id, - shuffle: shuffle, - ), - [id, query, getSongs], - ); - - return QueueContext( - id: id, - type: QueueContextType.playlist, - child: _SongsPage( - query: query, - getSongs: getSongs, - fab: ShuffleFab(onPressed: () => play(shuffle: true)), - onSongTap: (song, index) => play(index: index), - songImage: true, - background: PlaylistArtGradient(id: id), - colors: colors, - header: _PlaylistHeader( - playlist: playlist, - play: () => play(shuffle: false), - ), - ), - ); - } -} - -class _PlaylistHeader extends HookConsumerWidget { - final Playlist playlist; - final void Function() play; - - const _PlaylistHeader({ - required this.playlist, - required this.play, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final cache = ref.watch(cacheServiceProvider); - - final downloadActions = usePlaylistDownloadActions( - context: context, - ref: ref, - playlist: playlist, - ); - - final l = AppLocalizations.of(context); - - return _Header( - title: playlist.name, - subtitle: playlist.comment, - imageCache: cache.playlistArt(playlist, thumbnail: false), - playText: l.resourcesPlaylistActionsPlay, - onPlay: play, - onMore: () { - showContextMenu( - context: context, - ref: ref, - builder: (context) => BottomSheetMenu( - size: MenuSize.small, - child: PlaylistContextMenu(playlist: playlist), - ), - ); - }, - downloadActions: downloadActions, - ); - } -} - -class GenreSongsPage extends HookConsumerWidget { - final String genre; - - const GenreSongsPage({ - super.key, - @pathParam required this.genre, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final query = useMemoized( - () => ListQuery( - page: const Pagination(limit: 30), - sort: const SortBy( - column: 'albums.created DESC, albums.name, songs.disc, songs.track', - ), - filters: IList( - [FilterWith.equals(column: 'songs.genre', value: genre)], - ), - ), - [genre], - ); - - final getSongs = useCallback( - (ListQuery query) => ref.read(songsByAlbumListProvider(query).future), - [], - ); - - final play = useCallback( - ({int? index, bool? shuffle}) => ref.read(audioControlProvider).playRadio( - context: QueueContextType.genre, - contextId: genre, - query: query, - getSongs: getSongs, - ), - [query, getSongs], - ); - - return QueueContext( - id: genre, - type: QueueContextType.album, - child: _SongsPage( - query: query, - getSongs: getSongs, - // onSongTap: (song, index) => play(index: index), - songImage: true, - background: const BackgroundGradient(), - fab: RadioPlayFab( - onPressed: () => play(), - ), - header: _GenreHeader(genre: genre), - ), - ); - } -} - -class _GenreHeader extends HookConsumerWidget { - final String genre; - - const _GenreHeader({ - required this.genre, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final count = ref.watch(songsByGenreCountProvider(genre)).valueOrNull ?? 0; - - final l = AppLocalizations.of(context); - - return _Header( - title: genre, - subtitle: l.resourcesSongCount(count), - downloadActions: const [], - ); - } -} - -class QueueContext extends InheritedWidget { - final QueueContextType type; - final String? id; - - const QueueContext({ - super.key, - required this.type, - this.id, - required super.child, - }); - - static QueueContext? maybeOf(BuildContext context) { - return context.dependOnInheritedWidgetOfExactType(); - } - - static QueueContext of(BuildContext context) { - final QueueContext? result = maybeOf(context); - assert(result != null, 'No QueueContext found in context'); - return result!; - } - - @override - bool updateShouldNotify(covariant QueueContext oldWidget) => - oldWidget.id != id || oldWidget.type != type; -} - -class _SongsPage extends HookConsumerWidget { - final ListQuery query; - final FutureOr> Function(ListQuery query) getSongs; - final void Function(Song song, int index)? onSongTap; - final bool songImage; - final Widget background; - final Widget fab; - final ColorTheme? colors; - final Widget header; - - const _SongsPage({ - required this.query, - required this.getSongs, - this.onSongTap, - this.songImage = false, - required this.background, - required this.fab, - this.colors, - required this.header, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final base = ref.watch(baseThemeProvider); - ref.listen(musicSourceProvider, (previous, next) { - if (next.id != previous?.id) { - context.router.popUntilRoot(); - } - }); - - final pagingController = useListQueryPagingController( - ref, - query: query, - getItems: getSongs, - ); - - final widget = Scaffold( - floatingActionButton: fab, - body: CustomScrollView( - slivers: [ - SliverStack( - children: [ - SliverPositioned.fill( - child: Container( - color: base.gradientLow, - ), - ), - SliverPositioned.directional( - textDirection: TextDirection.ltr, - start: 0, - end: 0, - top: 0, - child: background, - ), - MultiSliver( - children: [ - SliverSafeArea( - sliver: SliverToBoxAdapter( - child: Material( - type: MaterialType.transparency, - child: Padding( - padding: const EdgeInsets.all(16), - child: header, - ), - ), - ), - ), - PagedListQueryView( - pagingController: pagingController, - useSliver: true, - itemBuilder: (context, item, index) => SongListTile( - song: item, - image: songImage, - onTap: () => - onSongTap != null ? onSongTap!(item, index) : null, - ), - ), - ], - ), - ], - ), - ], - ), - ); - - if (colors != null) { - return Theme(data: colors!.theme, child: widget); - } else { - return widget; - } - } -} - -class _Header extends HookConsumerWidget { - final UriCacheInfo? imageCache; - final String title; - final String? subtitle; - final String? playText; - final void Function()? onPlay; - final FutureOr Function()? onMore; - final List downloadActions; - - const _Header({ - this.imageCache, - required this.title, - this.subtitle, - this.playText, - this.onPlay, - this.onMore, - required this.downloadActions, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final inheritedStyle = DefaultTextStyle.of(context).style; - final theme = Theme.of(context); - - return Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const SizedBox(height: 10), - if (imageCache != null) - CardClip( - square: false, - child: UriCacheInfoImage( - height: 300, - fit: BoxFit.contain, - placeholderStyle: PlaceholderStyle.spinner, - cache: imageCache!, - ), - ), - const SizedBox(height: 16), - Column( - children: [ - Text( - title, - style: theme.textTheme.titleLarge!.copyWith( - color: inheritedStyle.color, - fontWeight: FontWeight.w500, - ), - textAlign: TextAlign.center, - ), - Text( - subtitle ?? '', - style: theme.textTheme.titleMedium!.copyWith( - color: inheritedStyle.color, - ), - textAlign: TextAlign.center, - ), - ], - ), - const SizedBox(height: 16), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - if (downloadActions.isNotEmpty) - IconButton( - onPressed: downloadActions.first.action, - icon: downloadActions.first.type == DownloadActionType.delete - ? const Icon(Icons.download_done_rounded) - : downloadActions.first.iconBuilder(context), - ), - if (onPlay != null) - FilledButton.icon( - onPressed: onPlay, - icon: const Icon(Icons.play_arrow_rounded), - label: Text(playText ?? ''), - ), - if (onMore != null) - IconButton( - onPressed: onMore, - icon: const Icon(Icons.more_horiz), - ) - ], - ), - ], - ); - } -} diff --git a/lib/app/pages/source_page.dart b/lib/app/pages/source_page.dart deleted file mode 100644 index 8e635c28..00000000 --- a/lib/app/pages/source_page.dart +++ /dev/null @@ -1,283 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:collection/collection.dart'; -import 'package:drift/drift.dart' show Value; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -import '../../database/database.dart'; -import '../../log.dart'; -import '../../models/settings.dart'; -import '../../services/settings_service.dart'; -import '../items.dart'; -import '../snackbars.dart'; - -class SourcePage extends HookConsumerWidget { - final int? id; - - const SourcePage({ - super.key, - @pathParam this.id, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final source = ref.watch(settingsServiceProvider.select( - (value) => value.sources.singleWhereOrNull((e) => e.id == id) - as SubsonicSettings?, - )); - final form = useState(GlobalKey()).value; - final theme = Theme.of(context); - final l = AppLocalizations.of(context); - final isSaving = useState(false); - final isDeleting = useState(false); - - final name = LabeledTextField( - label: l.settingsServersFieldsName, - initialValue: source?.name, - required: true, - ); - final address = LabeledTextField( - label: l.settingsServersFieldsAddress, - initialValue: source?.address.toString(), - keyboardType: TextInputType.url, - autofillHints: const [AutofillHints.url], - required: true, - validator: (value, label) { - if (!value!.contains(RegExp(r'https?:\/\/'))) { - return '$label must be a valid URL'; - } - return null; - }, - ); - final username = LabeledTextField( - label: l.settingsServersFieldsUsername, - initialValue: source?.username, - autofillHints: const [AutofillHints.username], - required: true, - ); - final password = LabeledTextField( - label: l.settingsServersFieldsPassword, - initialValue: source?.password, - obscureText: true, - autofillHints: const [AutofillHints.password], - required: true, - ); - - final forcePlaintextPassword = useState(!(source?.useTokenAuth ?? true)); - final forcePlaintextSwitch = SwitchListTile( - value: forcePlaintextPassword.value, - title: Text(l.settingsServersOptionsForcePlaintextPasswordTitle), - subtitle: forcePlaintextPassword.value - ? Text(l.settingsServersOptionsForcePlaintextPasswordDescriptionOn) - : Text(l.settingsServersOptionsForcePlaintextPasswordDescriptionOff), - onChanged: (value) => forcePlaintextPassword.value = value, - ); - - return WillPopScope( - onWillPop: () async => !isSaving.value && !isDeleting.value, - child: Scaffold( - appBar: AppBar(), - floatingActionButton: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - if (source != null && source.isActive != true) - FloatingActionButton( - backgroundColor: theme.colorScheme.tertiaryContainer, - foregroundColor: theme.colorScheme.onTertiaryContainer, - onPressed: !isSaving.value && !isDeleting.value - ? () async { - final router = context.router; - - try { - isDeleting.value = true; - await ref - .read(settingsServiceProvider.notifier) - .deleteSource(source.id); - } finally { - isDeleting.value = false; - } - - router.pop(); - } - : null, - child: isDeleting.value - ? SizedBox( - height: 24, - width: 24, - child: CircularProgressIndicator( - color: theme.colorScheme.onTertiaryContainer, - ), - ) - : const Icon(Icons.delete_forever_rounded), - ), - const SizedBox(width: 12), - FloatingActionButton.extended( - heroTag: null, - icon: isSaving.value - ? const SizedBox( - height: 24, - width: 24, - child: CircularProgressIndicator(), - ) - : const Icon(Icons.save_rounded), - label: Text(l.settingsServersActionsSave), - onPressed: !isSaving.value && !isDeleting.value - ? () async { - final router = context.router; - if (!form.currentState!.validate()) { - return; - } - - var error = false; - try { - isSaving.value = true; - if (source != null) { - await ref - .read(settingsServiceProvider.notifier) - .updateSource( - source.copyWith( - name: name.value, - address: Uri.parse(address.value), - username: username.value, - password: password.value, - useTokenAuth: !forcePlaintextPassword.value, - ), - ); - } else { - await ref - .read(settingsServiceProvider.notifier) - .createSource( - SourcesCompanion.insert( - name: name.value, - address: Uri.parse(address.value), - ), - SubsonicSourcesCompanion.insert( - features: IList(), - username: username.value, - password: password.value, - useTokenAuth: - Value(!forcePlaintextPassword.value), - ), - ); - } - } catch (e, st) { - showErrorSnackbar(context, e.toString()); - log.severe('Saving source', e, st); - error = true; - } finally { - isSaving.value = false; - } - - if (!error) { - router.pop(); - } - } - : null, - ), - ], - ), - body: Form( - key: form, - child: AutofillGroup( - child: ListView( - children: [ - const SizedBox(height: 96 - kToolbarHeight), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Text( - source == null - ? l.settingsServersActionsAdd - : l.settingsServersActionsEdit, - style: theme.textTheme.displaySmall, - ), - ), - name, - address, - username, - password, - const SizedBox(height: 24), - forcePlaintextSwitch, - const FabPadding(), - ], - ), - ), - ), - ), - ); - } -} - -class LabeledTextField extends HookConsumerWidget { - final String label; - final String? initialValue; - final bool obscureText; - final bool required; - final TextInputType? keyboardType; - final Iterable? autofillHints; - final String? Function(String? value, String label)? validator; - - // ignore: prefer_const_constructors_in_immutables - LabeledTextField({ - super.key, - required this.label, - this.initialValue, - this.obscureText = false, - this.keyboardType, - this.validator, - this.autofillHints, - this.required = false, - }); - - late final TextEditingController _controller; - - String get value => _controller.text; - - String? _requiredValidator(String? value) { - if (value == null || value.isEmpty) { - return '$label is required'; - } - - return null; - } - - @override - Widget build(BuildContext context, WidgetRef ref) { - final theme = Theme.of(context); - _controller = useTextEditingController(text: initialValue); - - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const SizedBox(height: 24), - Text(label, style: theme.textTheme.titleMedium), - TextFormField( - controller: _controller, - obscureText: obscureText, - keyboardType: keyboardType, - autofillHints: autofillHints, - validator: (value) { - String? error; - - if (required) { - error = _requiredValidator(value); - if (error != null) { - return error; - } - } - - if (validator != null) { - return validator!(value, label); - } - return null; - }, - ), - ], - ), - ); - } -} diff --git a/lib/app/snackbars.dart b/lib/app/snackbars.dart deleted file mode 100644 index ffc0bd4f..00000000 --- a/lib/app/snackbars.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -void showErrorSnackbar(BuildContext context, String message) { - final colors = Theme.of(context).colorScheme; - - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text(message, style: TextStyle(color: colors.onErrorContainer)), - backgroundColor: colors.errorContainer, - showCloseIcon: true, - closeIconColor: colors.onErrorContainer, - behavior: SnackBarBehavior.floating, - duration: const Duration(seconds: 10), - )); -} diff --git a/lib/cache/image_cache.dart b/lib/cache/image_cache.dart deleted file mode 100644 index 57ff7feb..00000000 --- a/lib/cache/image_cache.dart +++ /dev/null @@ -1,30 +0,0 @@ -// ignore_for_file: implementation_imports - -import 'package:flutter_cache_manager/flutter_cache_manager.dart'; -import 'package:flutter_cache_manager/src/storage/file_system/file_system_io.dart'; -import 'package:http/http.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../http/client.dart'; - -part 'image_cache.g.dart'; - -CacheManager _openImageCache(BaseClient httpClient) { - const key = 'images'; - return CacheManager( - Config( - key, - stalePeriod: const Duration(days: 2147483647), - maxNrOfCacheObjects: 2147483647, - repo: JsonCacheInfoRepository(databaseName: key), - fileSystem: IOFileSystem(key), - fileService: HttpFileService(httpClient: httpClient), - ), - ); -} - -@Riverpod(keepAlive: true) -CacheManager imageCache(ImageCacheRef ref) { - final http = ref.watch(httpClientProvider); - return _openImageCache(http); -} diff --git a/lib/cache/image_cache.g.dart b/lib/cache/image_cache.g.dart deleted file mode 100644 index 9534c052..00000000 --- a/lib/cache/image_cache.g.dart +++ /dev/null @@ -1,23 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'image_cache.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$imageCacheHash() => r'aaeb74898734c2776f594e05eb82262af20e079f'; - -/// See also [imageCache]. -@ProviderFor(imageCache) -final imageCacheProvider = Provider.internal( - imageCache, - name: r'imageCacheProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$imageCacheHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef ImageCacheRef = ProviderRef; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/database/converters.dart b/lib/database/converters.dart deleted file mode 100644 index 418d8c43..00000000 --- a/lib/database/converters.dart +++ /dev/null @@ -1,72 +0,0 @@ -import 'dart:convert'; - -import 'package:drift/drift.dart'; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; - -import '../models/query.dart'; -import '../models/settings.dart'; - -class DurationSecondsConverter extends TypeConverter { - const DurationSecondsConverter(); - - @override - Duration fromSql(int fromDb) => Duration(seconds: fromDb); - - @override - int toSql(Duration value) => value.inSeconds; -} - -class UriConverter extends TypeConverter { - const UriConverter(); - - @override - Uri fromSql(String fromDb) => Uri.parse(fromDb); - - @override - String toSql(Uri value) => value.toString(); -} - -class ListQueryConverter extends TypeConverter { - const ListQueryConverter(); - - @override - ListQuery fromSql(String fromDb) => ListQuery.fromJson(jsonDecode(fromDb)); - - @override - String toSql(ListQuery value) => jsonEncode(value.toJson()); -} - -class SubsonicFeatureListConverter - extends TypeConverter, String> { - const SubsonicFeatureListConverter(); - - @override - IList fromSql(String fromDb) { - return IList.fromJson( - jsonDecode(fromDb), - (item) => SubsonicFeature.values.byName(item as String), - ); - } - - @override - String toSql(IList value) { - return jsonEncode(value.toJson((e) => e.toString())); - } -} - -class IListIntConverter extends TypeConverter, String> { - const IListIntConverter(); - - @override - IList fromSql(String fromDb) { - return IList.fromJson( - jsonDecode(fromDb), - (item) => int.parse(item as String), - ); - } - - @override - String toSql(IList value) { - return jsonEncode(value.toJson((e) => jsonEncode(e))); - } -} diff --git a/lib/database/database.dart b/lib/database/database.dart deleted file mode 100644 index d623cf41..00000000 --- a/lib/database/database.dart +++ /dev/null @@ -1,681 +0,0 @@ -import 'dart:io'; - -import 'package:collection/collection.dart'; -import 'package:drift/drift.dart'; -import 'package:drift/isolate.dart'; -import 'package:drift/native.dart'; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:path/path.dart' as p; -import 'package:path_provider/path_provider.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../log.dart'; -import '../models/music.dart'; -import '../models/query.dart'; -import '../models/settings.dart'; -import '../models/support.dart'; -import 'converters.dart'; -import 'error_logging_database.dart'; - -part 'database.g.dart'; - -// don't exceed SQLITE_MAX_VARIABLE_NUMBER (32766 for version >= 3.32.0) -// https://www.sqlite.org/limits.html -const kSqliteMaxVariableNumber = 32766; - -@DriftDatabase(include: {'tables.drift'}) -class SubtracksDatabase extends _$SubtracksDatabase { - SubtracksDatabase() : super(_openConnection()); - SubtracksDatabase.connection(QueryExecutor e) : super(e); - - @override - int get schemaVersion => 1; - - @override - MigrationStrategy get migration { - return MigrationStrategy( - beforeOpen: (details) async { - await customStatement('PRAGMA foreign_keys = ON'); - }, - ); - } - - /// Runs a database opertion in a background isolate. - /// - /// **Only pass top-level functions to [computation]!** - /// - /// **Do not use non-serializable data inside [computation]!** - Future background( - FutureOr Function(SubtracksDatabase) computation, - ) async { - return computeWithDatabase( - connect: SubtracksDatabase.connection, - computation: computation, - ); - } - - MultiSelectable albumsList(int sourceId, ListQuery opt) { - return filterAlbums( - (_) => _filterPredicate('albums', sourceId, opt), - (_) => _filterOrderBy(opt), - (_) => _filterLimit(opt), - ); - } - - MultiSelectable albumsListDownloaded(int sourceId, ListQuery opt) { - return filterAlbumsDownloaded( - (_, __) => _filterPredicate('albums', sourceId, opt), - (_, __) => _filterOrderBy(opt), - (_, __) => _filterLimit(opt), - ); - } - - MultiSelectable artistsList(int sourceId, ListQuery opt) { - return filterArtists( - (_) => _filterPredicate('artists', sourceId, opt), - (_) => _filterOrderBy(opt), - (_) => _filterLimit(opt), - ); - } - - MultiSelectable artistsListDownloaded(int sourceId, ListQuery opt) { - return filterArtistsDownloaded( - (_, __, ___) => _filterPredicate('artists', sourceId, opt), - (_, __, ___) => _filterOrderBy(opt), - (_, __, ___) => _filterLimit(opt), - ); - } - - MultiSelectable playlistsList(int sourceId, ListQuery opt) { - return filterPlaylists( - (_) => _filterPredicate('playlists', sourceId, opt), - (_) => _filterOrderBy(opt), - (_) => _filterLimit(opt), - ); - } - - MultiSelectable playlistsListDownloaded( - int sourceId, ListQuery opt) { - return filterPlaylistsDownloaded( - (_, __, ___) => _filterPredicate('playlists', sourceId, opt), - (_, __, ___) => _filterOrderBy(opt), - (_, __, ___) => _filterLimit(opt), - ); - } - - MultiSelectable songsList(int sourceId, ListQuery opt) { - return filterSongs( - (_) => _filterPredicate('songs', sourceId, opt), - (_) => _filterOrderBy(opt), - (_) => _filterLimit(opt), - ); - } - - MultiSelectable songsListDownloaded(int sourceId, ListQuery opt) { - return filterSongsDownloaded( - (_) => _filterPredicate('songs', sourceId, opt), - (_) => _filterOrderBy(opt), - (_) => _filterLimit(opt), - ); - } - - Expression _filterPredicate(String table, int sourceId, ListQuery opt) { - return opt.filters.map((filter) => buildFilter(filter)).fold( - CustomExpression('$table.source_id = $sourceId'), - (previousValue, element) => previousValue & element, - ); - } - - OrderBy _filterOrderBy(ListQuery opt) { - return opt.sort != null - ? OrderBy([_buildOrder(opt.sort!)]) - : const OrderBy.nothing(); - } - - Limit _filterLimit(ListQuery opt) { - return Limit(opt.page.limit, opt.page.offset); - } - - MultiSelectable albumSongsList(SourceId sid, ListQuery opt) { - return listQuery( - select(songs) - ..where((tbl) => - tbl.sourceId.equals(sid.sourceId) & tbl.albumId.equals(sid.id)), - opt, - ); - } - - MultiSelectable songsByAlbumList(int sourceId, ListQuery opt) { - return filterSongsByGenre( - (_, __) => _filterPredicate('songs', sourceId, opt), - (_, __) => _filterOrderBy(opt), - (_, __) => _filterLimit(opt), - ); - } - - MultiSelectable playlistSongsList(SourceId sid, ListQuery opt) { - return listQueryJoined( - select(songs).join([ - innerJoin( - playlistSongs, - playlistSongs.sourceId.equalsExp(songs.sourceId) & - playlistSongs.songId.equalsExp(songs.id), - useColumns: false, - ), - ]) - ..where(playlistSongs.sourceId.equals(sid.sourceId) & - playlistSongs.playlistId.equals(sid.id)), - opt, - ).map((row) => row.readTable(songs)); - } - - Future saveArtists(Iterable artists) async { - await batch((batch) { - batch.insertAllOnConflictUpdate(this.artists, artists); - }); - } - - Future deleteArtistsNotIn(int sourceId, Set ids) { - return transaction(() async { - final allIds = (await (selectOnly(artists) - ..addColumns([artists.id]) - ..where(artists.sourceId.equals(sourceId))) - .map((row) => row.read(artists.id)) - .get()) - .whereNotNull() - .toSet(); - final downloadIds = (await artistIdsWithDownloadStatus(sourceId).get()) - .whereNotNull() - .toSet(); - - final diff = allIds.difference(downloadIds).difference(ids); - for (var slice in diff.slices(kSqliteMaxVariableNumber)) { - await (delete(artists) - ..where( - (tbl) => tbl.sourceId.equals(sourceId) & tbl.id.isIn(slice))) - .go(); - } - }); - } - - Future saveAlbums(Iterable albums) async { - await batch((batch) { - batch.insertAllOnConflictUpdate(this.albums, albums); - }); - } - - Future deleteAlbumsNotIn(int sourceId, Set ids) { - return transaction(() async { - final allIds = (await (selectOnly(albums) - ..addColumns([albums.id]) - ..where(albums.sourceId.equals(sourceId))) - .map((row) => row.read(albums.id)) - .get()) - .whereNotNull() - .toSet(); - final downloadIds = (await albumIdsWithDownloadStatus(sourceId).get()) - .whereNotNull() - .toSet(); - - final diff = allIds.difference(downloadIds).difference(ids); - for (var slice in diff.slices(kSqliteMaxVariableNumber)) { - await (delete(albums) - ..where( - (tbl) => tbl.sourceId.equals(sourceId) & tbl.id.isIn(slice))) - .go(); - } - }); - } - - Future savePlaylists( - Iterable playlistsWithSongs, - ) async { - final playlists = playlistsWithSongs.map((e) => e.playist); - final playlistSongs = playlistsWithSongs.expand((e) => e.songs); - final sourceId = playlists.first.sourceId.value; - - await (delete(this.playlistSongs) - ..where( - (tbl) => - tbl.sourceId.equals(sourceId) & - tbl.playlistId.isIn(playlists.map((e) => e.id.value)), - )) - .go(); - - await batch((batch) { - batch.insertAllOnConflictUpdate(this.playlists, playlists); - batch.insertAllOnConflictUpdate(this.playlistSongs, playlistSongs); - }); - } - - Future deletePlaylistsNotIn(int sourceId, Set ids) { - return transaction(() async { - final allIds = (await (selectOnly(playlists) - ..addColumns([playlists.id]) - ..where(playlists.sourceId.equals(sourceId))) - .map((row) => row.read(playlists.id)) - .get()) - .whereNotNull() - .toSet(); - final downloadIds = (await playlistIdsWithDownloadStatus(sourceId).get()) - .whereNotNull() - .toSet(); - - final diff = allIds.difference(downloadIds).difference(ids); - for (var slice in diff.slices(kSqliteMaxVariableNumber)) { - await (delete(playlists) - ..where( - (tbl) => tbl.sourceId.equals(sourceId) & tbl.id.isIn(slice))) - .go(); - await (delete(playlistSongs) - ..where((tbl) => - tbl.sourceId.equals(sourceId) & tbl.playlistId.isIn(slice))) - .go(); - } - }); - } - - Future savePlaylistSongs( - int sourceId, - List ids, - Iterable playlistSongs, - ) async { - await (delete(this.playlistSongs) - ..where( - (tbl) => tbl.sourceId.equals(sourceId) & tbl.playlistId.isIn(ids), - )) - .go(); - await batch((batch) { - batch.insertAllOnConflictUpdate(this.playlistSongs, playlistSongs); - }); - } - - Future saveSongs(Iterable songs) async { - await batch((batch) { - batch.insertAllOnConflictUpdate(this.songs, songs); - }); - } - - Future deleteSongsNotIn(int sourceId, Set ids) { - return transaction(() async { - final allIds = (await (selectOnly(songs) - ..addColumns([songs.id]) - ..where( - songs.sourceId.equals(sourceId) & - songs.downloadFilePath.isNull() & - songs.downloadTaskId.isNull(), - )) - .map((row) => row.read(songs.id)) - .get()) - .whereNotNull() - .toSet(); - - final diff = allIds.difference(ids); - for (var slice in diff.slices(kSqliteMaxVariableNumber)) { - await (delete(songs) - ..where( - (tbl) => tbl.sourceId.equals(sourceId) & tbl.id.isIn(slice))) - .go(); - await (delete(playlistSongs) - ..where( - (tbl) => tbl.sourceId.equals(sourceId) & tbl.songId.isIn(slice), - )) - .go(); - } - }); - } - - Selectable getLastBottomNavState() { - return select(lastBottomNavState)..where((tbl) => tbl.id.equals(1)); - } - - Future saveLastBottomNavState(LastBottomNavStateData update) { - return into(lastBottomNavState).insertOnConflictUpdate(update); - } - - Selectable getLastLibraryState() { - return select(lastLibraryState)..where((tbl) => tbl.id.equals(1)); - } - - Future saveLastLibraryState(LastLibraryStateData update) { - return into(lastLibraryState).insertOnConflictUpdate(update); - } - - Selectable getLastAudioState() { - return select(lastAudioState)..where((tbl) => tbl.id.equals(1)); - } - - Future saveLastAudioState(LastAudioStateCompanion update) { - return into(lastAudioState).insertOnConflictUpdate(update); - } - - Future insertQueue(Iterable songs) async { - await batch((batch) { - batch.insertAll(queue, songs); - }); - } - - Future clearQueue() async { - await delete(queue).go(); - } - - Future setCurrentTrack(int index) async { - await transaction(() async { - await (update(queue)..where((tbl) => tbl.index.equals(index).not())) - .write(const QueueCompanion(currentTrack: Value(null))); - await (update(queue)..where((tbl) => tbl.index.equals(index))) - .write(const QueueCompanion(currentTrack: Value(true))); - }); - } - - Future createSource( - SourcesCompanion source, - SubsonicSourcesCompanion subsonic, - ) async { - await transaction(() async { - final count = await sourcesCount().getSingle(); - if (count == 0) { - source = source.copyWith(isActive: const Value(true)); - } - - final id = await into(sources).insert(source); - subsonic = subsonic.copyWith(sourceId: Value(id)); - await into(subsonicSources).insert(subsonic); - }); - } - - Future updateSource(SubsonicSettings source) async { - await transaction(() async { - await into(sources).insertOnConflictUpdate(source.toSourceInsertable()); - await into(subsonicSources) - .insertOnConflictUpdate(source.toSubsonicInsertable()); - }); - } - - Future deleteSource(int sourceId) async { - await transaction(() async { - await (delete(subsonicSources) - ..where((tbl) => tbl.sourceId.equals(sourceId))) - .go(); - await (delete(sources)..where((tbl) => tbl.id.equals(sourceId))).go(); - - await (delete(songs)..where((tbl) => tbl.sourceId.equals(sourceId))).go(); - await (delete(albums)..where((tbl) => tbl.sourceId.equals(sourceId))) - .go(); - await (delete(artists)..where((tbl) => tbl.sourceId.equals(sourceId))) - .go(); - await (delete(playlistSongs) - ..where((tbl) => tbl.sourceId.equals(sourceId))) - .go(); - await (delete(playlists)..where((tbl) => tbl.sourceId.equals(sourceId))) - .go(); - }); - } - - Future setActiveSource(int id) async { - await batch((batch) { - batch.update( - sources, - const SourcesCompanion(isActive: Value(null)), - where: (t) => t.id.isNotValue(id), - ); - batch.update( - sources, - const SourcesCompanion(isActive: Value(true)), - where: (t) => t.id.equals(id), - ); - }); - } - - Future updateSettings(AppSettingsCompanion settings) async { - await into(appSettings).insertOnConflictUpdate(settings); - } -} - -LazyDatabase _openConnection() { - return LazyDatabase(() async { - final dbFolder = await getApplicationDocumentsDirectory(); - final file = File(p.join(dbFolder.path, 'subtracks.sqlite')); - // return NativeDatabase.createInBackground(file, logStatements: true); - - return ErrorLoggingDatabase( - NativeDatabase.createInBackground(file), - (e, s) => log.severe('SQL error', e, s), - ); - }); -} - -@Riverpod(keepAlive: true) -SubtracksDatabase database(DatabaseRef ref) { - return SubtracksDatabase(); -} - -OrderingTerm _buildOrder(SortBy sort) { - OrderingMode? mode = - sort.dir == SortDirection.asc ? OrderingMode.asc : OrderingMode.desc; - return OrderingTerm( - expression: CustomExpression(sort.column), - mode: mode, - ); -} - -SimpleSelectStatement listQuery( - SimpleSelectStatement query, - ListQuery opt, -) { - if (opt.page.limit > 0) { - query.limit(opt.page.limit, offset: opt.page.offset); - } - - if (opt.sort != null) { - OrderingMode? mode = opt.sort != null && opt.sort!.dir == SortDirection.asc - ? OrderingMode.asc - : OrderingMode.desc; - query.orderBy([ - (t) => OrderingTerm( - expression: CustomExpression(opt.sort!.column), - mode: mode, - ) - ]); - } - - for (var filter in opt.filters) { - query.where((tbl) => buildFilter(filter)); - } - - return query; -} - -JoinedSelectStatement listQueryJoined( - JoinedSelectStatement query, - ListQuery opt, -) { - if (opt.page.limit > 0) { - query.limit(opt.page.limit, offset: opt.page.offset); - } - - if (opt.sort != null) { - OrderingMode? mode = opt.sort != null && opt.sort!.dir == SortDirection.asc - ? OrderingMode.asc - : OrderingMode.desc; - query.orderBy([ - OrderingTerm( - expression: CustomExpression(opt.sort!.column), - mode: mode, - ) - ]); - } - - for (var filter in opt.filters) { - query.where(buildFilter(filter)); - } - - return query; -} - -CustomExpression buildFilter( - FilterWith filter, -) { - return filter.when( - equals: (column, value, invert) => CustomExpression( - '$column ${invert ? '<>' : '='} \'$value\'', - ), - greaterThan: (column, value, orEquals) => CustomExpression( - '$column ${orEquals ? '>=' : '>'} $value', - ), - isNull: (column, invert) => CustomExpression( - '$column ${invert ? 'IS NOT' : 'IS'} NULL', - ), - betweenInt: (column, from, to) => CustomExpression( - '$column BETWEEN $from AND $to', - ), - isIn: (column, invert, values) => CustomExpression( - '$column ${invert ? 'NOT IN' : 'IN'} (${values.join(',')})', - ), - ); -} - -class AlbumSongsCompanion { - final AlbumsCompanion album; - final Iterable songs; - - AlbumSongsCompanion(this.album, this.songs); -} - -class ArtistAlbumsCompanion { - final ArtistsCompanion artist; - final Iterable albums; - - ArtistAlbumsCompanion(this.artist, this.albums); -} - -class PlaylistWithSongsCompanion { - final PlaylistsCompanion playist; - final Iterable songs; - - PlaylistWithSongsCompanion(this.playist, this.songs); -} - -// Future saveArtist( -// SubtracksDatabase db, -// ArtistAlbumsCompanion artistAlbums, -// ) async { -// return db.background((db) async { -// final artist = artistAlbums.artist; -// final albums = artistAlbums.albums; - -// await db.batch((batch) { -// batch.insertAllOnConflictUpdate(db.artists, [artist]); -// batch.insertAllOnConflictUpdate(db.albums, albums); - -// // remove this artistId from albums not found in source -// // don't delete them since they coud have been moved to another artist -// // that we haven't synced yet -// final albumIds = {for (var a in albums) a.id.value}; -// batch.update( -// db.albums, -// const AlbumsCompanion(artistId: Value(null)), -// where: (tbl) => -// tbl.sourceId.equals(artist.sourceId.value) & -// tbl.artistId.equals(artist.id.value) & -// tbl.id.isNotIn(albumIds), -// ); -// }); -// }); -// } - -// Future saveAlbum( -// SubtracksDatabase db, -// AlbumSongsCompanion albumSongs, -// ) async { -// return db.background((db) async { -// final album = albumSongs.album.copyWith(synced: Value(DateTime.now())); -// final songs = albumSongs.songs; - -// final songIds = {for (var a in songs) a.id.value}; -// final hardDeletedSongIds = (await (db.selectOnly(db.songs) -// ..addColumns([db.songs.id]) -// ..where( -// db.songs.sourceId.equals(album.sourceId.value) & -// db.songs.albumId.equals(album.id.value) & -// db.songs.id.isNotIn(songIds) & -// db.songs.downloadFilePath.isNull() & -// db.songs.downloadTaskId.isNull(), -// )) -// .map((row) => row.read(db.songs.id)) -// .get()) -// .whereNotNull(); - -// await db.batch((batch) { -// batch.insertAllOnConflictUpdate(db.albums, [album]); -// batch.insertAllOnConflictUpdate(db.songs, songs); - -// // soft delete songs that have been downloaded so that the user -// // can decide to keep or remove them later -// // TODO: add a setting to skip soft delete and just remove download too -// batch.update( -// db.songs, -// const SongsCompanion(isDeleted: Value(true)), -// where: (tbl) => -// tbl.sourceId.equals(album.sourceId.value) & -// tbl.albumId.equals(album.id.value) & -// tbl.id.isNotIn(songIds) & -// (tbl.downloadFilePath.isNotNull() | tbl.downloadTaskId.isNotNull()), -// ); - -// // safe to hard delete songs that have not been downloaded -// batch.deleteWhere( -// db.songs, -// (tbl) => -// tbl.sourceId.equals(album.sourceId.value) & -// tbl.id.isIn(hardDeletedSongIds), -// ); - -// // also need to remove these songs from any playlists that contain them -// batch.deleteWhere( -// db.playlistSongs, -// (tbl) => -// tbl.sourceId.equals(album.sourceId.value) & -// tbl.songId.isIn(hardDeletedSongIds), -// ); -// }); -// }); -// } - -// Future savePlaylist( -// SubtracksDatabase db, -// PlaylistWithSongsCompanion playlistWithSongs, -// ) async { -// return db.background((db) async { -// final playlist = -// playlistWithSongs.playist.copyWith(synced: Value(DateTime.now())); -// final songs = playlistWithSongs.songs; - -// await db.batch((batch) { -// batch.insertAllOnConflictUpdate(db.playlists, [playlist]); -// batch.insertAllOnConflictUpdate(db.songs, songs); - -// batch.insertAllOnConflictUpdate( -// db.playlistSongs, -// songs.mapIndexed( -// (index, song) => PlaylistSongsCompanion.insert( -// sourceId: playlist.sourceId.value, -// playlistId: playlist.id.value, -// songId: song.id.value, -// position: index, -// ), -// ), -// ); - -// // the new playlist could be shorter than the old one, so we delete -// // playlist songs above our new playlist's length -// batch.deleteWhere( -// db.playlistSongs, -// (tbl) => -// tbl.sourceId.equals(playlist.sourceId.value) & -// tbl.playlistId.equals(playlist.id.value) & -// tbl.position.isBiggerOrEqualValue(songs.length), -// ); -// }); -// }); -// } diff --git a/lib/database/database.g.dart b/lib/database/database.g.dart deleted file mode 100644 index a379beab..00000000 --- a/lib/database/database.g.dart +++ /dev/null @@ -1,5573 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'database.dart'; - -// ignore_for_file: type=lint -class Queue extends Table with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - Queue(this.attachedDatabase, [this._alias]); - static const VerificationMeta _indexMeta = const VerificationMeta('index'); - late final GeneratedColumn index = GeneratedColumn( - 'index', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: 'NOT NULL PRIMARY KEY UNIQUE'); - static const VerificationMeta _sourceIdMeta = - const VerificationMeta('sourceId'); - late final GeneratedColumn sourceId = GeneratedColumn( - 'source_id', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _contextMeta = - const VerificationMeta('context'); - late final GeneratedColumnWithTypeConverter - context = GeneratedColumn('context', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL') - .withConverter(Queue.$convertercontext); - static const VerificationMeta _contextIdMeta = - const VerificationMeta('contextId'); - late final GeneratedColumn contextId = GeneratedColumn( - 'context_id', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _currentTrackMeta = - const VerificationMeta('currentTrack'); - late final GeneratedColumn currentTrack = GeneratedColumn( - 'current_track', aliasedName, true, - type: DriftSqlType.bool, - requiredDuringInsert: false, - $customConstraints: 'UNIQUE'); - @override - List get $columns => - [index, sourceId, id, context, contextId, currentTrack]; - @override - String get aliasedName => _alias ?? 'queue'; - @override - String get actualTableName => 'queue'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('index')) { - context.handle( - _indexMeta, index.isAcceptableOrUnknown(data['index']!, _indexMeta)); - } - if (data.containsKey('source_id')) { - context.handle(_sourceIdMeta, - sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta)); - } else if (isInserting) { - context.missing(_sourceIdMeta); - } - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } else if (isInserting) { - context.missing(_idMeta); - } - context.handle(_contextMeta, const VerificationResult.success()); - if (data.containsKey('context_id')) { - context.handle(_contextIdMeta, - contextId.isAcceptableOrUnknown(data['context_id']!, _contextIdMeta)); - } - if (data.containsKey('current_track')) { - context.handle( - _currentTrackMeta, - currentTrack.isAcceptableOrUnknown( - data['current_track']!, _currentTrackMeta)); - } - return context; - } - - @override - Set get $primaryKey => {index}; - @override - QueueData map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return QueueData( - index: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}index'])!, - sourceId: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}source_id'])!, - id: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}id'])!, - context: Queue.$convertercontext.fromSql(attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}context'])!), - contextId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}context_id']), - currentTrack: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}current_track']), - ); - } - - @override - Queue createAlias(String alias) { - return Queue(attachedDatabase, alias); - } - - static JsonTypeConverter2 - $convertercontext = - const EnumNameConverter(QueueContextType.values); - @override - bool get dontWriteConstraints => true; -} - -class QueueData extends DataClass implements Insertable { - final int index; - final int sourceId; - final String id; - final QueueContextType context; - final String? contextId; - final bool? currentTrack; - const QueueData( - {required this.index, - required this.sourceId, - required this.id, - required this.context, - this.contextId, - this.currentTrack}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['index'] = Variable(index); - map['source_id'] = Variable(sourceId); - map['id'] = Variable(id); - { - final converter = Queue.$convertercontext; - map['context'] = Variable(converter.toSql(context)); - } - if (!nullToAbsent || contextId != null) { - map['context_id'] = Variable(contextId); - } - if (!nullToAbsent || currentTrack != null) { - map['current_track'] = Variable(currentTrack); - } - return map; - } - - QueueCompanion toCompanion(bool nullToAbsent) { - return QueueCompanion( - index: Value(index), - sourceId: Value(sourceId), - id: Value(id), - context: Value(context), - contextId: contextId == null && nullToAbsent - ? const Value.absent() - : Value(contextId), - currentTrack: currentTrack == null && nullToAbsent - ? const Value.absent() - : Value(currentTrack), - ); - } - - factory QueueData.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return QueueData( - index: serializer.fromJson(json['index']), - sourceId: serializer.fromJson(json['source_id']), - id: serializer.fromJson(json['id']), - context: Queue.$convertercontext - .fromJson(serializer.fromJson(json['context'])), - contextId: serializer.fromJson(json['context_id']), - currentTrack: serializer.fromJson(json['current_track']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'index': serializer.toJson(index), - 'source_id': serializer.toJson(sourceId), - 'id': serializer.toJson(id), - 'context': - serializer.toJson(Queue.$convertercontext.toJson(context)), - 'context_id': serializer.toJson(contextId), - 'current_track': serializer.toJson(currentTrack), - }; - } - - QueueData copyWith( - {int? index, - int? sourceId, - String? id, - QueueContextType? context, - Value contextId = const Value.absent(), - Value currentTrack = const Value.absent()}) => - QueueData( - index: index ?? this.index, - sourceId: sourceId ?? this.sourceId, - id: id ?? this.id, - context: context ?? this.context, - contextId: contextId.present ? contextId.value : this.contextId, - currentTrack: - currentTrack.present ? currentTrack.value : this.currentTrack, - ); - @override - String toString() { - return (StringBuffer('QueueData(') - ..write('index: $index, ') - ..write('sourceId: $sourceId, ') - ..write('id: $id, ') - ..write('context: $context, ') - ..write('contextId: $contextId, ') - ..write('currentTrack: $currentTrack') - ..write(')')) - .toString(); - } - - @override - int get hashCode => - Object.hash(index, sourceId, id, context, contextId, currentTrack); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is QueueData && - other.index == this.index && - other.sourceId == this.sourceId && - other.id == this.id && - other.context == this.context && - other.contextId == this.contextId && - other.currentTrack == this.currentTrack); -} - -class QueueCompanion extends UpdateCompanion { - final Value index; - final Value sourceId; - final Value id; - final Value context; - final Value contextId; - final Value currentTrack; - const QueueCompanion({ - this.index = const Value.absent(), - this.sourceId = const Value.absent(), - this.id = const Value.absent(), - this.context = const Value.absent(), - this.contextId = const Value.absent(), - this.currentTrack = const Value.absent(), - }); - QueueCompanion.insert({ - this.index = const Value.absent(), - required int sourceId, - required String id, - required QueueContextType context, - this.contextId = const Value.absent(), - this.currentTrack = const Value.absent(), - }) : sourceId = Value(sourceId), - id = Value(id), - context = Value(context); - static Insertable custom({ - Expression? index, - Expression? sourceId, - Expression? id, - Expression? context, - Expression? contextId, - Expression? currentTrack, - }) { - return RawValuesInsertable({ - if (index != null) 'index': index, - if (sourceId != null) 'source_id': sourceId, - if (id != null) 'id': id, - if (context != null) 'context': context, - if (contextId != null) 'context_id': contextId, - if (currentTrack != null) 'current_track': currentTrack, - }); - } - - QueueCompanion copyWith( - {Value? index, - Value? sourceId, - Value? id, - Value? context, - Value? contextId, - Value? currentTrack}) { - return QueueCompanion( - index: index ?? this.index, - sourceId: sourceId ?? this.sourceId, - id: id ?? this.id, - context: context ?? this.context, - contextId: contextId ?? this.contextId, - currentTrack: currentTrack ?? this.currentTrack, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (index.present) { - map['index'] = Variable(index.value); - } - if (sourceId.present) { - map['source_id'] = Variable(sourceId.value); - } - if (id.present) { - map['id'] = Variable(id.value); - } - if (context.present) { - final converter = Queue.$convertercontext; - map['context'] = Variable(converter.toSql(context.value)); - } - if (contextId.present) { - map['context_id'] = Variable(contextId.value); - } - if (currentTrack.present) { - map['current_track'] = Variable(currentTrack.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('QueueCompanion(') - ..write('index: $index, ') - ..write('sourceId: $sourceId, ') - ..write('id: $id, ') - ..write('context: $context, ') - ..write('contextId: $contextId, ') - ..write('currentTrack: $currentTrack') - ..write(')')) - .toString(); - } -} - -class LastAudioState extends Table - with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - LastAudioState(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: 'NOT NULL PRIMARY KEY'); - static const VerificationMeta _queueModeMeta = - const VerificationMeta('queueMode'); - late final GeneratedColumnWithTypeConverter queueMode = - GeneratedColumn('queue_mode', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL') - .withConverter(LastAudioState.$converterqueueMode); - static const VerificationMeta _shuffleIndiciesMeta = - const VerificationMeta('shuffleIndicies'); - late final GeneratedColumnWithTypeConverter?, String> - shuffleIndicies = GeneratedColumn( - 'shuffle_indicies', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: '') - .withConverter?>( - LastAudioState.$convertershuffleIndiciesn); - static const VerificationMeta _repeatMeta = const VerificationMeta('repeat'); - late final GeneratedColumnWithTypeConverter repeat = - GeneratedColumn('repeat', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL') - .withConverter(LastAudioState.$converterrepeat); - @override - List get $columns => - [id, queueMode, shuffleIndicies, repeat]; - @override - String get aliasedName => _alias ?? 'last_audio_state'; - @override - String get actualTableName => 'last_audio_state'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } - context.handle(_queueModeMeta, const VerificationResult.success()); - context.handle(_shuffleIndiciesMeta, const VerificationResult.success()); - context.handle(_repeatMeta, const VerificationResult.success()); - return context; - } - - @override - Set get $primaryKey => {id}; - @override - LastAudioStateData map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return LastAudioStateData( - id: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}id'])!, - queueMode: LastAudioState.$converterqueueMode.fromSql(attachedDatabase - .typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}queue_mode'])!), - shuffleIndicies: LastAudioState.$convertershuffleIndiciesn.fromSql( - attachedDatabase.typeMapping.read( - DriftSqlType.string, data['${effectivePrefix}shuffle_indicies'])), - repeat: LastAudioState.$converterrepeat.fromSql(attachedDatabase - .typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}repeat'])!), - ); - } - - @override - LastAudioState createAlias(String alias) { - return LastAudioState(attachedDatabase, alias); - } - - static JsonTypeConverter2 $converterqueueMode = - const EnumIndexConverter(QueueMode.values); - static TypeConverter, String> $convertershuffleIndicies = - const IListIntConverter(); - static TypeConverter?, String?> $convertershuffleIndiciesn = - NullAwareTypeConverter.wrap($convertershuffleIndicies); - static JsonTypeConverter2 $converterrepeat = - const EnumIndexConverter(RepeatMode.values); - @override - bool get dontWriteConstraints => true; -} - -class LastAudioStateData extends DataClass - implements Insertable { - final int id; - final QueueMode queueMode; - final IList? shuffleIndicies; - final RepeatMode repeat; - const LastAudioStateData( - {required this.id, - required this.queueMode, - this.shuffleIndicies, - required this.repeat}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['id'] = Variable(id); - { - final converter = LastAudioState.$converterqueueMode; - map['queue_mode'] = Variable(converter.toSql(queueMode)); - } - if (!nullToAbsent || shuffleIndicies != null) { - final converter = LastAudioState.$convertershuffleIndiciesn; - map['shuffle_indicies'] = - Variable(converter.toSql(shuffleIndicies)); - } - { - final converter = LastAudioState.$converterrepeat; - map['repeat'] = Variable(converter.toSql(repeat)); - } - return map; - } - - LastAudioStateCompanion toCompanion(bool nullToAbsent) { - return LastAudioStateCompanion( - id: Value(id), - queueMode: Value(queueMode), - shuffleIndicies: shuffleIndicies == null && nullToAbsent - ? const Value.absent() - : Value(shuffleIndicies), - repeat: Value(repeat), - ); - } - - factory LastAudioStateData.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return LastAudioStateData( - id: serializer.fromJson(json['id']), - queueMode: LastAudioState.$converterqueueMode - .fromJson(serializer.fromJson(json['queue_mode'])), - shuffleIndicies: - serializer.fromJson?>(json['shuffle_indicies']), - repeat: LastAudioState.$converterrepeat - .fromJson(serializer.fromJson(json['repeat'])), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'id': serializer.toJson(id), - 'queue_mode': serializer - .toJson(LastAudioState.$converterqueueMode.toJson(queueMode)), - 'shuffle_indicies': serializer.toJson?>(shuffleIndicies), - 'repeat': serializer - .toJson(LastAudioState.$converterrepeat.toJson(repeat)), - }; - } - - LastAudioStateData copyWith( - {int? id, - QueueMode? queueMode, - Value?> shuffleIndicies = const Value.absent(), - RepeatMode? repeat}) => - LastAudioStateData( - id: id ?? this.id, - queueMode: queueMode ?? this.queueMode, - shuffleIndicies: shuffleIndicies.present - ? shuffleIndicies.value - : this.shuffleIndicies, - repeat: repeat ?? this.repeat, - ); - @override - String toString() { - return (StringBuffer('LastAudioStateData(') - ..write('id: $id, ') - ..write('queueMode: $queueMode, ') - ..write('shuffleIndicies: $shuffleIndicies, ') - ..write('repeat: $repeat') - ..write(')')) - .toString(); - } - - @override - int get hashCode => Object.hash(id, queueMode, shuffleIndicies, repeat); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is LastAudioStateData && - other.id == this.id && - other.queueMode == this.queueMode && - other.shuffleIndicies == this.shuffleIndicies && - other.repeat == this.repeat); -} - -class LastAudioStateCompanion extends UpdateCompanion { - final Value id; - final Value queueMode; - final Value?> shuffleIndicies; - final Value repeat; - const LastAudioStateCompanion({ - this.id = const Value.absent(), - this.queueMode = const Value.absent(), - this.shuffleIndicies = const Value.absent(), - this.repeat = const Value.absent(), - }); - LastAudioStateCompanion.insert({ - this.id = const Value.absent(), - required QueueMode queueMode, - this.shuffleIndicies = const Value.absent(), - required RepeatMode repeat, - }) : queueMode = Value(queueMode), - repeat = Value(repeat); - static Insertable custom({ - Expression? id, - Expression? queueMode, - Expression? shuffleIndicies, - Expression? repeat, - }) { - return RawValuesInsertable({ - if (id != null) 'id': id, - if (queueMode != null) 'queue_mode': queueMode, - if (shuffleIndicies != null) 'shuffle_indicies': shuffleIndicies, - if (repeat != null) 'repeat': repeat, - }); - } - - LastAudioStateCompanion copyWith( - {Value? id, - Value? queueMode, - Value?>? shuffleIndicies, - Value? repeat}) { - return LastAudioStateCompanion( - id: id ?? this.id, - queueMode: queueMode ?? this.queueMode, - shuffleIndicies: shuffleIndicies ?? this.shuffleIndicies, - repeat: repeat ?? this.repeat, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } - if (queueMode.present) { - final converter = LastAudioState.$converterqueueMode; - map['queue_mode'] = Variable(converter.toSql(queueMode.value)); - } - if (shuffleIndicies.present) { - final converter = LastAudioState.$convertershuffleIndiciesn; - map['shuffle_indicies'] = - Variable(converter.toSql(shuffleIndicies.value)); - } - if (repeat.present) { - final converter = LastAudioState.$converterrepeat; - map['repeat'] = Variable(converter.toSql(repeat.value)); - } - return map; - } - - @override - String toString() { - return (StringBuffer('LastAudioStateCompanion(') - ..write('id: $id, ') - ..write('queueMode: $queueMode, ') - ..write('shuffleIndicies: $shuffleIndicies, ') - ..write('repeat: $repeat') - ..write(')')) - .toString(); - } -} - -class LastBottomNavState extends Table - with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - LastBottomNavState(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: 'NOT NULL PRIMARY KEY'); - static const VerificationMeta _tabMeta = const VerificationMeta('tab'); - late final GeneratedColumn tab = GeneratedColumn( - 'tab', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - @override - List get $columns => [id, tab]; - @override - String get aliasedName => _alias ?? 'last_bottom_nav_state'; - @override - String get actualTableName => 'last_bottom_nav_state'; - @override - VerificationContext validateIntegrity( - Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } - if (data.containsKey('tab')) { - context.handle( - _tabMeta, tab.isAcceptableOrUnknown(data['tab']!, _tabMeta)); - } else if (isInserting) { - context.missing(_tabMeta); - } - return context; - } - - @override - Set get $primaryKey => {id}; - @override - LastBottomNavStateData map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return LastBottomNavStateData( - id: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}id'])!, - tab: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}tab'])!, - ); - } - - @override - LastBottomNavState createAlias(String alias) { - return LastBottomNavState(attachedDatabase, alias); - } - - @override - bool get dontWriteConstraints => true; -} - -class LastBottomNavStateData extends DataClass - implements Insertable { - final int id; - final String tab; - const LastBottomNavStateData({required this.id, required this.tab}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['id'] = Variable(id); - map['tab'] = Variable(tab); - return map; - } - - LastBottomNavStateCompanion toCompanion(bool nullToAbsent) { - return LastBottomNavStateCompanion( - id: Value(id), - tab: Value(tab), - ); - } - - factory LastBottomNavStateData.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return LastBottomNavStateData( - id: serializer.fromJson(json['id']), - tab: serializer.fromJson(json['tab']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'id': serializer.toJson(id), - 'tab': serializer.toJson(tab), - }; - } - - LastBottomNavStateData copyWith({int? id, String? tab}) => - LastBottomNavStateData( - id: id ?? this.id, - tab: tab ?? this.tab, - ); - @override - String toString() { - return (StringBuffer('LastBottomNavStateData(') - ..write('id: $id, ') - ..write('tab: $tab') - ..write(')')) - .toString(); - } - - @override - int get hashCode => Object.hash(id, tab); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is LastBottomNavStateData && - other.id == this.id && - other.tab == this.tab); -} - -class LastBottomNavStateCompanion - extends UpdateCompanion { - final Value id; - final Value tab; - const LastBottomNavStateCompanion({ - this.id = const Value.absent(), - this.tab = const Value.absent(), - }); - LastBottomNavStateCompanion.insert({ - this.id = const Value.absent(), - required String tab, - }) : tab = Value(tab); - static Insertable custom({ - Expression? id, - Expression? tab, - }) { - return RawValuesInsertable({ - if (id != null) 'id': id, - if (tab != null) 'tab': tab, - }); - } - - LastBottomNavStateCompanion copyWith({Value? id, Value? tab}) { - return LastBottomNavStateCompanion( - id: id ?? this.id, - tab: tab ?? this.tab, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } - if (tab.present) { - map['tab'] = Variable(tab.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('LastBottomNavStateCompanion(') - ..write('id: $id, ') - ..write('tab: $tab') - ..write(')')) - .toString(); - } -} - -class LastLibraryState extends Table - with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - LastLibraryState(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: 'NOT NULL PRIMARY KEY'); - static const VerificationMeta _tabMeta = const VerificationMeta('tab'); - late final GeneratedColumn tab = GeneratedColumn( - 'tab', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _albumsListMeta = - const VerificationMeta('albumsList'); - late final GeneratedColumnWithTypeConverter albumsList = - GeneratedColumn('albums_list', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL') - .withConverter(LastLibraryState.$converteralbumsList); - static const VerificationMeta _artistsListMeta = - const VerificationMeta('artistsList'); - late final GeneratedColumnWithTypeConverter artistsList = - GeneratedColumn('artists_list', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL') - .withConverter(LastLibraryState.$converterartistsList); - static const VerificationMeta _playlistsListMeta = - const VerificationMeta('playlistsList'); - late final GeneratedColumnWithTypeConverter playlistsList = - GeneratedColumn('playlists_list', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL') - .withConverter(LastLibraryState.$converterplaylistsList); - static const VerificationMeta _songsListMeta = - const VerificationMeta('songsList'); - late final GeneratedColumnWithTypeConverter songsList = - GeneratedColumn('songs_list', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL') - .withConverter(LastLibraryState.$convertersongsList); - @override - List get $columns => - [id, tab, albumsList, artistsList, playlistsList, songsList]; - @override - String get aliasedName => _alias ?? 'last_library_state'; - @override - String get actualTableName => 'last_library_state'; - @override - VerificationContext validateIntegrity( - Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } - if (data.containsKey('tab')) { - context.handle( - _tabMeta, tab.isAcceptableOrUnknown(data['tab']!, _tabMeta)); - } else if (isInserting) { - context.missing(_tabMeta); - } - context.handle(_albumsListMeta, const VerificationResult.success()); - context.handle(_artistsListMeta, const VerificationResult.success()); - context.handle(_playlistsListMeta, const VerificationResult.success()); - context.handle(_songsListMeta, const VerificationResult.success()); - return context; - } - - @override - Set get $primaryKey => {id}; - @override - LastLibraryStateData map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return LastLibraryStateData( - id: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}id'])!, - tab: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}tab'])!, - albumsList: LastLibraryState.$converteralbumsList.fromSql(attachedDatabase - .typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}albums_list'])!), - artistsList: LastLibraryState.$converterartistsList.fromSql( - attachedDatabase.typeMapping.read( - DriftSqlType.string, data['${effectivePrefix}artists_list'])!), - playlistsList: LastLibraryState.$converterplaylistsList.fromSql( - attachedDatabase.typeMapping.read( - DriftSqlType.string, data['${effectivePrefix}playlists_list'])!), - songsList: LastLibraryState.$convertersongsList.fromSql(attachedDatabase - .typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}songs_list'])!), - ); - } - - @override - LastLibraryState createAlias(String alias) { - return LastLibraryState(attachedDatabase, alias); - } - - static TypeConverter $converteralbumsList = - const ListQueryConverter(); - static TypeConverter $converterartistsList = - const ListQueryConverter(); - static TypeConverter $converterplaylistsList = - const ListQueryConverter(); - static TypeConverter $convertersongsList = - const ListQueryConverter(); - @override - bool get dontWriteConstraints => true; -} - -class LastLibraryStateData extends DataClass - implements Insertable { - final int id; - final String tab; - final ListQuery albumsList; - final ListQuery artistsList; - final ListQuery playlistsList; - final ListQuery songsList; - const LastLibraryStateData( - {required this.id, - required this.tab, - required this.albumsList, - required this.artistsList, - required this.playlistsList, - required this.songsList}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['id'] = Variable(id); - map['tab'] = Variable(tab); - { - final converter = LastLibraryState.$converteralbumsList; - map['albums_list'] = Variable(converter.toSql(albumsList)); - } - { - final converter = LastLibraryState.$converterartistsList; - map['artists_list'] = Variable(converter.toSql(artistsList)); - } - { - final converter = LastLibraryState.$converterplaylistsList; - map['playlists_list'] = Variable(converter.toSql(playlistsList)); - } - { - final converter = LastLibraryState.$convertersongsList; - map['songs_list'] = Variable(converter.toSql(songsList)); - } - return map; - } - - LastLibraryStateCompanion toCompanion(bool nullToAbsent) { - return LastLibraryStateCompanion( - id: Value(id), - tab: Value(tab), - albumsList: Value(albumsList), - artistsList: Value(artistsList), - playlistsList: Value(playlistsList), - songsList: Value(songsList), - ); - } - - factory LastLibraryStateData.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return LastLibraryStateData( - id: serializer.fromJson(json['id']), - tab: serializer.fromJson(json['tab']), - albumsList: serializer.fromJson(json['albums_list']), - artistsList: serializer.fromJson(json['artists_list']), - playlistsList: serializer.fromJson(json['playlists_list']), - songsList: serializer.fromJson(json['songs_list']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'id': serializer.toJson(id), - 'tab': serializer.toJson(tab), - 'albums_list': serializer.toJson(albumsList), - 'artists_list': serializer.toJson(artistsList), - 'playlists_list': serializer.toJson(playlistsList), - 'songs_list': serializer.toJson(songsList), - }; - } - - LastLibraryStateData copyWith( - {int? id, - String? tab, - ListQuery? albumsList, - ListQuery? artistsList, - ListQuery? playlistsList, - ListQuery? songsList}) => - LastLibraryStateData( - id: id ?? this.id, - tab: tab ?? this.tab, - albumsList: albumsList ?? this.albumsList, - artistsList: artistsList ?? this.artistsList, - playlistsList: playlistsList ?? this.playlistsList, - songsList: songsList ?? this.songsList, - ); - @override - String toString() { - return (StringBuffer('LastLibraryStateData(') - ..write('id: $id, ') - ..write('tab: $tab, ') - ..write('albumsList: $albumsList, ') - ..write('artistsList: $artistsList, ') - ..write('playlistsList: $playlistsList, ') - ..write('songsList: $songsList') - ..write(')')) - .toString(); - } - - @override - int get hashCode => - Object.hash(id, tab, albumsList, artistsList, playlistsList, songsList); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is LastLibraryStateData && - other.id == this.id && - other.tab == this.tab && - other.albumsList == this.albumsList && - other.artistsList == this.artistsList && - other.playlistsList == this.playlistsList && - other.songsList == this.songsList); -} - -class LastLibraryStateCompanion extends UpdateCompanion { - final Value id; - final Value tab; - final Value albumsList; - final Value artistsList; - final Value playlistsList; - final Value songsList; - const LastLibraryStateCompanion({ - this.id = const Value.absent(), - this.tab = const Value.absent(), - this.albumsList = const Value.absent(), - this.artistsList = const Value.absent(), - this.playlistsList = const Value.absent(), - this.songsList = const Value.absent(), - }); - LastLibraryStateCompanion.insert({ - this.id = const Value.absent(), - required String tab, - required ListQuery albumsList, - required ListQuery artistsList, - required ListQuery playlistsList, - required ListQuery songsList, - }) : tab = Value(tab), - albumsList = Value(albumsList), - artistsList = Value(artistsList), - playlistsList = Value(playlistsList), - songsList = Value(songsList); - static Insertable custom({ - Expression? id, - Expression? tab, - Expression? albumsList, - Expression? artistsList, - Expression? playlistsList, - Expression? songsList, - }) { - return RawValuesInsertable({ - if (id != null) 'id': id, - if (tab != null) 'tab': tab, - if (albumsList != null) 'albums_list': albumsList, - if (artistsList != null) 'artists_list': artistsList, - if (playlistsList != null) 'playlists_list': playlistsList, - if (songsList != null) 'songs_list': songsList, - }); - } - - LastLibraryStateCompanion copyWith( - {Value? id, - Value? tab, - Value? albumsList, - Value? artistsList, - Value? playlistsList, - Value? songsList}) { - return LastLibraryStateCompanion( - id: id ?? this.id, - tab: tab ?? this.tab, - albumsList: albumsList ?? this.albumsList, - artistsList: artistsList ?? this.artistsList, - playlistsList: playlistsList ?? this.playlistsList, - songsList: songsList ?? this.songsList, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } - if (tab.present) { - map['tab'] = Variable(tab.value); - } - if (albumsList.present) { - final converter = LastLibraryState.$converteralbumsList; - map['albums_list'] = Variable(converter.toSql(albumsList.value)); - } - if (artistsList.present) { - final converter = LastLibraryState.$converterartistsList; - map['artists_list'] = - Variable(converter.toSql(artistsList.value)); - } - if (playlistsList.present) { - final converter = LastLibraryState.$converterplaylistsList; - map['playlists_list'] = - Variable(converter.toSql(playlistsList.value)); - } - if (songsList.present) { - final converter = LastLibraryState.$convertersongsList; - map['songs_list'] = Variable(converter.toSql(songsList.value)); - } - return map; - } - - @override - String toString() { - return (StringBuffer('LastLibraryStateCompanion(') - ..write('id: $id, ') - ..write('tab: $tab, ') - ..write('albumsList: $albumsList, ') - ..write('artistsList: $artistsList, ') - ..write('playlistsList: $playlistsList, ') - ..write('songsList: $songsList') - ..write(')')) - .toString(); - } -} - -class AppSettingsTable extends Table - with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - AppSettingsTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: 'NOT NULL PRIMARY KEY'); - static const VerificationMeta _maxBitrateWifiMeta = - const VerificationMeta('maxBitrateWifi'); - late final GeneratedColumn maxBitrateWifi = GeneratedColumn( - 'max_bitrate_wifi', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _maxBitrateMobileMeta = - const VerificationMeta('maxBitrateMobile'); - late final GeneratedColumn maxBitrateMobile = GeneratedColumn( - 'max_bitrate_mobile', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _streamFormatMeta = - const VerificationMeta('streamFormat'); - late final GeneratedColumn streamFormat = GeneratedColumn( - 'stream_format', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: ''); - @override - List get $columns => - [id, maxBitrateWifi, maxBitrateMobile, streamFormat]; - @override - String get aliasedName => _alias ?? 'app_settings'; - @override - String get actualTableName => 'app_settings'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } - if (data.containsKey('max_bitrate_wifi')) { - context.handle( - _maxBitrateWifiMeta, - maxBitrateWifi.isAcceptableOrUnknown( - data['max_bitrate_wifi']!, _maxBitrateWifiMeta)); - } else if (isInserting) { - context.missing(_maxBitrateWifiMeta); - } - if (data.containsKey('max_bitrate_mobile')) { - context.handle( - _maxBitrateMobileMeta, - maxBitrateMobile.isAcceptableOrUnknown( - data['max_bitrate_mobile']!, _maxBitrateMobileMeta)); - } else if (isInserting) { - context.missing(_maxBitrateMobileMeta); - } - if (data.containsKey('stream_format')) { - context.handle( - _streamFormatMeta, - streamFormat.isAcceptableOrUnknown( - data['stream_format']!, _streamFormatMeta)); - } - return context; - } - - @override - Set get $primaryKey => {id}; - @override - AppSettings map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return AppSettings( - maxBitrateWifi: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}max_bitrate_wifi'])!, - maxBitrateMobile: attachedDatabase.typeMapping.read( - DriftSqlType.int, data['${effectivePrefix}max_bitrate_mobile'])!, - streamFormat: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}stream_format']), - ); - } - - @override - AppSettingsTable createAlias(String alias) { - return AppSettingsTable(attachedDatabase, alias); - } - - @override - bool get dontWriteConstraints => true; -} - -class AppSettingsCompanion extends UpdateCompanion { - final Value id; - final Value maxBitrateWifi; - final Value maxBitrateMobile; - final Value streamFormat; - const AppSettingsCompanion({ - this.id = const Value.absent(), - this.maxBitrateWifi = const Value.absent(), - this.maxBitrateMobile = const Value.absent(), - this.streamFormat = const Value.absent(), - }); - AppSettingsCompanion.insert({ - this.id = const Value.absent(), - required int maxBitrateWifi, - required int maxBitrateMobile, - this.streamFormat = const Value.absent(), - }) : maxBitrateWifi = Value(maxBitrateWifi), - maxBitrateMobile = Value(maxBitrateMobile); - static Insertable custom({ - Expression? id, - Expression? maxBitrateWifi, - Expression? maxBitrateMobile, - Expression? streamFormat, - }) { - return RawValuesInsertable({ - if (id != null) 'id': id, - if (maxBitrateWifi != null) 'max_bitrate_wifi': maxBitrateWifi, - if (maxBitrateMobile != null) 'max_bitrate_mobile': maxBitrateMobile, - if (streamFormat != null) 'stream_format': streamFormat, - }); - } - - AppSettingsCompanion copyWith( - {Value? id, - Value? maxBitrateWifi, - Value? maxBitrateMobile, - Value? streamFormat}) { - return AppSettingsCompanion( - id: id ?? this.id, - maxBitrateWifi: maxBitrateWifi ?? this.maxBitrateWifi, - maxBitrateMobile: maxBitrateMobile ?? this.maxBitrateMobile, - streamFormat: streamFormat ?? this.streamFormat, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } - if (maxBitrateWifi.present) { - map['max_bitrate_wifi'] = Variable(maxBitrateWifi.value); - } - if (maxBitrateMobile.present) { - map['max_bitrate_mobile'] = Variable(maxBitrateMobile.value); - } - if (streamFormat.present) { - map['stream_format'] = Variable(streamFormat.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('AppSettingsCompanion(') - ..write('id: $id, ') - ..write('maxBitrateWifi: $maxBitrateWifi, ') - ..write('maxBitrateMobile: $maxBitrateMobile, ') - ..write('streamFormat: $streamFormat') - ..write(')')) - .toString(); - } -} - -class Sources extends Table with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - Sources(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - hasAutoIncrement: true, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: 'NOT NULL PRIMARY KEY AUTOINCREMENT'); - static const VerificationMeta _nameMeta = const VerificationMeta('name'); - late final GeneratedColumn name = GeneratedColumn( - 'name', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL COLLATE NOCASE'); - static const VerificationMeta _addressMeta = - const VerificationMeta('address'); - late final GeneratedColumnWithTypeConverter address = - GeneratedColumn('address', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL') - .withConverter(Sources.$converteraddress); - static const VerificationMeta _isActiveMeta = - const VerificationMeta('isActive'); - late final GeneratedColumn isActive = GeneratedColumn( - 'is_active', aliasedName, true, - type: DriftSqlType.bool, - requiredDuringInsert: false, - $customConstraints: 'UNIQUE'); - static const VerificationMeta _createdAtMeta = - const VerificationMeta('createdAt'); - late final GeneratedColumn createdAt = GeneratedColumn( - 'created_at', aliasedName, false, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - $customConstraints: - 'NOT NULL DEFAULT (strftime(\'%s\', CURRENT_TIMESTAMP))', - defaultValue: - const CustomExpression('strftime(\'%s\', CURRENT_TIMESTAMP)')); - @override - List get $columns => - [id, name, address, isActive, createdAt]; - @override - String get aliasedName => _alias ?? 'sources'; - @override - String get actualTableName => 'sources'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } - if (data.containsKey('name')) { - context.handle( - _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); - } else if (isInserting) { - context.missing(_nameMeta); - } - context.handle(_addressMeta, const VerificationResult.success()); - if (data.containsKey('is_active')) { - context.handle(_isActiveMeta, - isActive.isAcceptableOrUnknown(data['is_active']!, _isActiveMeta)); - } - if (data.containsKey('created_at')) { - context.handle(_createdAtMeta, - createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); - } - return context; - } - - @override - Set get $primaryKey => {id}; - @override - Source map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return Source( - id: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}id'])!, - name: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}name'])!, - address: Sources.$converteraddress.fromSql(attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}address'])!), - isActive: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}is_active']), - createdAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, - ); - } - - @override - Sources createAlias(String alias) { - return Sources(attachedDatabase, alias); - } - - static TypeConverter $converteraddress = const UriConverter(); - @override - bool get dontWriteConstraints => true; -} - -class Source extends DataClass implements Insertable { - final int id; - final String name; - final Uri address; - final bool? isActive; - final DateTime createdAt; - const Source( - {required this.id, - required this.name, - required this.address, - this.isActive, - required this.createdAt}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['id'] = Variable(id); - map['name'] = Variable(name); - { - final converter = Sources.$converteraddress; - map['address'] = Variable(converter.toSql(address)); - } - if (!nullToAbsent || isActive != null) { - map['is_active'] = Variable(isActive); - } - map['created_at'] = Variable(createdAt); - return map; - } - - SourcesCompanion toCompanion(bool nullToAbsent) { - return SourcesCompanion( - id: Value(id), - name: Value(name), - address: Value(address), - isActive: isActive == null && nullToAbsent - ? const Value.absent() - : Value(isActive), - createdAt: Value(createdAt), - ); - } - - factory Source.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return Source( - id: serializer.fromJson(json['id']), - name: serializer.fromJson(json['name']), - address: serializer.fromJson(json['address']), - isActive: serializer.fromJson(json['is_active']), - createdAt: serializer.fromJson(json['created_at']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'id': serializer.toJson(id), - 'name': serializer.toJson(name), - 'address': serializer.toJson(address), - 'is_active': serializer.toJson(isActive), - 'created_at': serializer.toJson(createdAt), - }; - } - - Source copyWith( - {int? id, - String? name, - Uri? address, - Value isActive = const Value.absent(), - DateTime? createdAt}) => - Source( - id: id ?? this.id, - name: name ?? this.name, - address: address ?? this.address, - isActive: isActive.present ? isActive.value : this.isActive, - createdAt: createdAt ?? this.createdAt, - ); - @override - String toString() { - return (StringBuffer('Source(') - ..write('id: $id, ') - ..write('name: $name, ') - ..write('address: $address, ') - ..write('isActive: $isActive, ') - ..write('createdAt: $createdAt') - ..write(')')) - .toString(); - } - - @override - int get hashCode => Object.hash(id, name, address, isActive, createdAt); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is Source && - other.id == this.id && - other.name == this.name && - other.address == this.address && - other.isActive == this.isActive && - other.createdAt == this.createdAt); -} - -class SourcesCompanion extends UpdateCompanion { - final Value id; - final Value name; - final Value address; - final Value isActive; - final Value createdAt; - const SourcesCompanion({ - this.id = const Value.absent(), - this.name = const Value.absent(), - this.address = const Value.absent(), - this.isActive = const Value.absent(), - this.createdAt = const Value.absent(), - }); - SourcesCompanion.insert({ - this.id = const Value.absent(), - required String name, - required Uri address, - this.isActive = const Value.absent(), - this.createdAt = const Value.absent(), - }) : name = Value(name), - address = Value(address); - static Insertable custom({ - Expression? id, - Expression? name, - Expression? address, - Expression? isActive, - Expression? createdAt, - }) { - return RawValuesInsertable({ - if (id != null) 'id': id, - if (name != null) 'name': name, - if (address != null) 'address': address, - if (isActive != null) 'is_active': isActive, - if (createdAt != null) 'created_at': createdAt, - }); - } - - SourcesCompanion copyWith( - {Value? id, - Value? name, - Value? address, - Value? isActive, - Value? createdAt}) { - return SourcesCompanion( - id: id ?? this.id, - name: name ?? this.name, - address: address ?? this.address, - isActive: isActive ?? this.isActive, - createdAt: createdAt ?? this.createdAt, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } - if (name.present) { - map['name'] = Variable(name.value); - } - if (address.present) { - final converter = Sources.$converteraddress; - map['address'] = Variable(converter.toSql(address.value)); - } - if (isActive.present) { - map['is_active'] = Variable(isActive.value); - } - if (createdAt.present) { - map['created_at'] = Variable(createdAt.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('SourcesCompanion(') - ..write('id: $id, ') - ..write('name: $name, ') - ..write('address: $address, ') - ..write('isActive: $isActive, ') - ..write('createdAt: $createdAt') - ..write(')')) - .toString(); - } -} - -class SubsonicSources extends Table - with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - SubsonicSources(this.attachedDatabase, [this._alias]); - static const VerificationMeta _sourceIdMeta = - const VerificationMeta('sourceId'); - late final GeneratedColumn sourceId = GeneratedColumn( - 'source_id', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: 'NOT NULL PRIMARY KEY'); - static const VerificationMeta _featuresMeta = - const VerificationMeta('features'); - late final GeneratedColumnWithTypeConverter, String> - features = GeneratedColumn('features', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL') - .withConverter>( - SubsonicSources.$converterfeatures); - static const VerificationMeta _usernameMeta = - const VerificationMeta('username'); - late final GeneratedColumn username = GeneratedColumn( - 'username', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _passwordMeta = - const VerificationMeta('password'); - late final GeneratedColumn password = GeneratedColumn( - 'password', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _useTokenAuthMeta = - const VerificationMeta('useTokenAuth'); - late final GeneratedColumn useTokenAuth = GeneratedColumn( - 'use_token_auth', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - $customConstraints: 'NOT NULL DEFAULT 1', - defaultValue: const CustomExpression('1')); - @override - List get $columns => - [sourceId, features, username, password, useTokenAuth]; - @override - String get aliasedName => _alias ?? 'subsonic_sources'; - @override - String get actualTableName => 'subsonic_sources'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('source_id')) { - context.handle(_sourceIdMeta, - sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta)); - } - context.handle(_featuresMeta, const VerificationResult.success()); - if (data.containsKey('username')) { - context.handle(_usernameMeta, - username.isAcceptableOrUnknown(data['username']!, _usernameMeta)); - } else if (isInserting) { - context.missing(_usernameMeta); - } - if (data.containsKey('password')) { - context.handle(_passwordMeta, - password.isAcceptableOrUnknown(data['password']!, _passwordMeta)); - } else if (isInserting) { - context.missing(_passwordMeta); - } - if (data.containsKey('use_token_auth')) { - context.handle( - _useTokenAuthMeta, - useTokenAuth.isAcceptableOrUnknown( - data['use_token_auth']!, _useTokenAuthMeta)); - } - return context; - } - - @override - Set get $primaryKey => {sourceId}; - @override - SubsonicSource map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return SubsonicSource( - sourceId: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}source_id'])!, - features: SubsonicSources.$converterfeatures.fromSql(attachedDatabase - .typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}features'])!), - username: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}username'])!, - password: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}password'])!, - useTokenAuth: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}use_token_auth'])!, - ); - } - - @override - SubsonicSources createAlias(String alias) { - return SubsonicSources(attachedDatabase, alias); - } - - static TypeConverter, String> $converterfeatures = - const SubsonicFeatureListConverter(); - @override - List get customConstraints => - const ['FOREIGN KEY(source_id)REFERENCES sources(id)ON DELETE CASCADE']; - @override - bool get dontWriteConstraints => true; -} - -class SubsonicSource extends DataClass implements Insertable { - final int sourceId; - final IList features; - final String username; - final String password; - final bool useTokenAuth; - const SubsonicSource( - {required this.sourceId, - required this.features, - required this.username, - required this.password, - required this.useTokenAuth}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['source_id'] = Variable(sourceId); - { - final converter = SubsonicSources.$converterfeatures; - map['features'] = Variable(converter.toSql(features)); - } - map['username'] = Variable(username); - map['password'] = Variable(password); - map['use_token_auth'] = Variable(useTokenAuth); - return map; - } - - SubsonicSourcesCompanion toCompanion(bool nullToAbsent) { - return SubsonicSourcesCompanion( - sourceId: Value(sourceId), - features: Value(features), - username: Value(username), - password: Value(password), - useTokenAuth: Value(useTokenAuth), - ); - } - - factory SubsonicSource.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return SubsonicSource( - sourceId: serializer.fromJson(json['source_id']), - features: serializer.fromJson>(json['features']), - username: serializer.fromJson(json['username']), - password: serializer.fromJson(json['password']), - useTokenAuth: serializer.fromJson(json['use_token_auth']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'source_id': serializer.toJson(sourceId), - 'features': serializer.toJson>(features), - 'username': serializer.toJson(username), - 'password': serializer.toJson(password), - 'use_token_auth': serializer.toJson(useTokenAuth), - }; - } - - SubsonicSource copyWith( - {int? sourceId, - IList? features, - String? username, - String? password, - bool? useTokenAuth}) => - SubsonicSource( - sourceId: sourceId ?? this.sourceId, - features: features ?? this.features, - username: username ?? this.username, - password: password ?? this.password, - useTokenAuth: useTokenAuth ?? this.useTokenAuth, - ); - @override - String toString() { - return (StringBuffer('SubsonicSource(') - ..write('sourceId: $sourceId, ') - ..write('features: $features, ') - ..write('username: $username, ') - ..write('password: $password, ') - ..write('useTokenAuth: $useTokenAuth') - ..write(')')) - .toString(); - } - - @override - int get hashCode => - Object.hash(sourceId, features, username, password, useTokenAuth); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is SubsonicSource && - other.sourceId == this.sourceId && - other.features == this.features && - other.username == this.username && - other.password == this.password && - other.useTokenAuth == this.useTokenAuth); -} - -class SubsonicSourcesCompanion extends UpdateCompanion { - final Value sourceId; - final Value> features; - final Value username; - final Value password; - final Value useTokenAuth; - const SubsonicSourcesCompanion({ - this.sourceId = const Value.absent(), - this.features = const Value.absent(), - this.username = const Value.absent(), - this.password = const Value.absent(), - this.useTokenAuth = const Value.absent(), - }); - SubsonicSourcesCompanion.insert({ - this.sourceId = const Value.absent(), - required IList features, - required String username, - required String password, - this.useTokenAuth = const Value.absent(), - }) : features = Value(features), - username = Value(username), - password = Value(password); - static Insertable custom({ - Expression? sourceId, - Expression? features, - Expression? username, - Expression? password, - Expression? useTokenAuth, - }) { - return RawValuesInsertable({ - if (sourceId != null) 'source_id': sourceId, - if (features != null) 'features': features, - if (username != null) 'username': username, - if (password != null) 'password': password, - if (useTokenAuth != null) 'use_token_auth': useTokenAuth, - }); - } - - SubsonicSourcesCompanion copyWith( - {Value? sourceId, - Value>? features, - Value? username, - Value? password, - Value? useTokenAuth}) { - return SubsonicSourcesCompanion( - sourceId: sourceId ?? this.sourceId, - features: features ?? this.features, - username: username ?? this.username, - password: password ?? this.password, - useTokenAuth: useTokenAuth ?? this.useTokenAuth, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (sourceId.present) { - map['source_id'] = Variable(sourceId.value); - } - if (features.present) { - final converter = SubsonicSources.$converterfeatures; - map['features'] = Variable(converter.toSql(features.value)); - } - if (username.present) { - map['username'] = Variable(username.value); - } - if (password.present) { - map['password'] = Variable(password.value); - } - if (useTokenAuth.present) { - map['use_token_auth'] = Variable(useTokenAuth.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('SubsonicSourcesCompanion(') - ..write('sourceId: $sourceId, ') - ..write('features: $features, ') - ..write('username: $username, ') - ..write('password: $password, ') - ..write('useTokenAuth: $useTokenAuth') - ..write(')')) - .toString(); - } -} - -class Artists extends Table with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - Artists(this.attachedDatabase, [this._alias]); - static const VerificationMeta _sourceIdMeta = - const VerificationMeta('sourceId'); - late final GeneratedColumn sourceId = GeneratedColumn( - 'source_id', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _nameMeta = const VerificationMeta('name'); - late final GeneratedColumn name = GeneratedColumn( - 'name', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL COLLATE NOCASE'); - static const VerificationMeta _albumCountMeta = - const VerificationMeta('albumCount'); - late final GeneratedColumn albumCount = GeneratedColumn( - 'album_count', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _starredMeta = - const VerificationMeta('starred'); - late final GeneratedColumn starred = GeneratedColumn( - 'starred', aliasedName, true, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _updatedMeta = - const VerificationMeta('updated'); - late final GeneratedColumn updated = GeneratedColumn( - 'updated', aliasedName, false, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - $customConstraints: - 'NOT NULL DEFAULT (strftime(\'%s\', CURRENT_TIMESTAMP))', - defaultValue: - const CustomExpression('strftime(\'%s\', CURRENT_TIMESTAMP)')); - @override - List get $columns => - [sourceId, id, name, albumCount, starred, updated]; - @override - String get aliasedName => _alias ?? 'artists'; - @override - String get actualTableName => 'artists'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('source_id')) { - context.handle(_sourceIdMeta, - sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta)); - } else if (isInserting) { - context.missing(_sourceIdMeta); - } - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } else if (isInserting) { - context.missing(_idMeta); - } - if (data.containsKey('name')) { - context.handle( - _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); - } else if (isInserting) { - context.missing(_nameMeta); - } - if (data.containsKey('album_count')) { - context.handle( - _albumCountMeta, - albumCount.isAcceptableOrUnknown( - data['album_count']!, _albumCountMeta)); - } else if (isInserting) { - context.missing(_albumCountMeta); - } - if (data.containsKey('starred')) { - context.handle(_starredMeta, - starred.isAcceptableOrUnknown(data['starred']!, _starredMeta)); - } - if (data.containsKey('updated')) { - context.handle(_updatedMeta, - updated.isAcceptableOrUnknown(data['updated']!, _updatedMeta)); - } - return context; - } - - @override - Set get $primaryKey => {sourceId, id}; - @override - Artist map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return Artist( - sourceId: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}source_id'])!, - id: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}id'])!, - name: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}name'])!, - albumCount: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}album_count'])!, - starred: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}starred']), - ); - } - - @override - Artists createAlias(String alias) { - return Artists(attachedDatabase, alias); - } - - @override - List get customConstraints => const [ - 'PRIMARY KEY(source_id, id)', - 'FOREIGN KEY(source_id)REFERENCES sources(id)ON DELETE CASCADE' - ]; - @override - bool get dontWriteConstraints => true; -} - -class ArtistsCompanion extends UpdateCompanion { - final Value sourceId; - final Value id; - final Value name; - final Value albumCount; - final Value starred; - final Value updated; - final Value rowid; - const ArtistsCompanion({ - this.sourceId = const Value.absent(), - this.id = const Value.absent(), - this.name = const Value.absent(), - this.albumCount = const Value.absent(), - this.starred = const Value.absent(), - this.updated = const Value.absent(), - this.rowid = const Value.absent(), - }); - ArtistsCompanion.insert({ - required int sourceId, - required String id, - required String name, - required int albumCount, - this.starred = const Value.absent(), - this.updated = const Value.absent(), - this.rowid = const Value.absent(), - }) : sourceId = Value(sourceId), - id = Value(id), - name = Value(name), - albumCount = Value(albumCount); - static Insertable custom({ - Expression? sourceId, - Expression? id, - Expression? name, - Expression? albumCount, - Expression? starred, - Expression? updated, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (sourceId != null) 'source_id': sourceId, - if (id != null) 'id': id, - if (name != null) 'name': name, - if (albumCount != null) 'album_count': albumCount, - if (starred != null) 'starred': starred, - if (updated != null) 'updated': updated, - if (rowid != null) 'rowid': rowid, - }); - } - - ArtistsCompanion copyWith( - {Value? sourceId, - Value? id, - Value? name, - Value? albumCount, - Value? starred, - Value? updated, - Value? rowid}) { - return ArtistsCompanion( - sourceId: sourceId ?? this.sourceId, - id: id ?? this.id, - name: name ?? this.name, - albumCount: albumCount ?? this.albumCount, - starred: starred ?? this.starred, - updated: updated ?? this.updated, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (sourceId.present) { - map['source_id'] = Variable(sourceId.value); - } - if (id.present) { - map['id'] = Variable(id.value); - } - if (name.present) { - map['name'] = Variable(name.value); - } - if (albumCount.present) { - map['album_count'] = Variable(albumCount.value); - } - if (starred.present) { - map['starred'] = Variable(starred.value); - } - if (updated.present) { - map['updated'] = Variable(updated.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('ArtistsCompanion(') - ..write('sourceId: $sourceId, ') - ..write('id: $id, ') - ..write('name: $name, ') - ..write('albumCount: $albumCount, ') - ..write('starred: $starred, ') - ..write('updated: $updated, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - -class ArtistsFts extends Table - with - TableInfo, - VirtualTableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - ArtistsFts(this.attachedDatabase, [this._alias]); - static const VerificationMeta _sourceIdMeta = - const VerificationMeta('sourceId'); - late final GeneratedColumn sourceId = GeneratedColumn( - 'source_id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: ''); - static const VerificationMeta _nameMeta = const VerificationMeta('name'); - late final GeneratedColumn name = GeneratedColumn( - 'name', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: ''); - @override - List get $columns => [sourceId, name]; - @override - String get aliasedName => _alias ?? 'artists_fts'; - @override - String get actualTableName => 'artists_fts'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('source_id')) { - context.handle(_sourceIdMeta, - sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta)); - } else if (isInserting) { - context.missing(_sourceIdMeta); - } - if (data.containsKey('name')) { - context.handle( - _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); - } else if (isInserting) { - context.missing(_nameMeta); - } - return context; - } - - @override - Set get $primaryKey => const {}; - @override - ArtistsFt map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return ArtistsFt( - sourceId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}source_id'])!, - name: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}name'])!, - ); - } - - @override - ArtistsFts createAlias(String alias) { - return ArtistsFts(attachedDatabase, alias); - } - - @override - bool get dontWriteConstraints => true; - @override - String get moduleAndArgs => - 'fts5(source_id, name, content=artists, content_rowid=rowid)'; -} - -class ArtistsFt extends DataClass implements Insertable { - final String sourceId; - final String name; - const ArtistsFt({required this.sourceId, required this.name}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['source_id'] = Variable(sourceId); - map['name'] = Variable(name); - return map; - } - - ArtistsFtsCompanion toCompanion(bool nullToAbsent) { - return ArtistsFtsCompanion( - sourceId: Value(sourceId), - name: Value(name), - ); - } - - factory ArtistsFt.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return ArtistsFt( - sourceId: serializer.fromJson(json['source_id']), - name: serializer.fromJson(json['name']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'source_id': serializer.toJson(sourceId), - 'name': serializer.toJson(name), - }; - } - - ArtistsFt copyWith({String? sourceId, String? name}) => ArtistsFt( - sourceId: sourceId ?? this.sourceId, - name: name ?? this.name, - ); - @override - String toString() { - return (StringBuffer('ArtistsFt(') - ..write('sourceId: $sourceId, ') - ..write('name: $name') - ..write(')')) - .toString(); - } - - @override - int get hashCode => Object.hash(sourceId, name); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is ArtistsFt && - other.sourceId == this.sourceId && - other.name == this.name); -} - -class ArtistsFtsCompanion extends UpdateCompanion { - final Value sourceId; - final Value name; - final Value rowid; - const ArtistsFtsCompanion({ - this.sourceId = const Value.absent(), - this.name = const Value.absent(), - this.rowid = const Value.absent(), - }); - ArtistsFtsCompanion.insert({ - required String sourceId, - required String name, - this.rowid = const Value.absent(), - }) : sourceId = Value(sourceId), - name = Value(name); - static Insertable custom({ - Expression? sourceId, - Expression? name, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (sourceId != null) 'source_id': sourceId, - if (name != null) 'name': name, - if (rowid != null) 'rowid': rowid, - }); - } - - ArtistsFtsCompanion copyWith( - {Value? sourceId, Value? name, Value? rowid}) { - return ArtistsFtsCompanion( - sourceId: sourceId ?? this.sourceId, - name: name ?? this.name, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (sourceId.present) { - map['source_id'] = Variable(sourceId.value); - } - if (name.present) { - map['name'] = Variable(name.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('ArtistsFtsCompanion(') - ..write('sourceId: $sourceId, ') - ..write('name: $name, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - -class Albums extends Table with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - Albums(this.attachedDatabase, [this._alias]); - static const VerificationMeta _sourceIdMeta = - const VerificationMeta('sourceId'); - late final GeneratedColumn sourceId = GeneratedColumn( - 'source_id', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _artistIdMeta = - const VerificationMeta('artistId'); - late final GeneratedColumn artistId = GeneratedColumn( - 'artist_id', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _nameMeta = const VerificationMeta('name'); - late final GeneratedColumn name = GeneratedColumn( - 'name', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL COLLATE NOCASE'); - static const VerificationMeta _albumArtistMeta = - const VerificationMeta('albumArtist'); - late final GeneratedColumn albumArtist = GeneratedColumn( - 'album_artist', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: 'COLLATE NOCASE'); - static const VerificationMeta _createdMeta = - const VerificationMeta('created'); - late final GeneratedColumn created = GeneratedColumn( - 'created', aliasedName, false, - type: DriftSqlType.dateTime, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _coverArtMeta = - const VerificationMeta('coverArt'); - late final GeneratedColumn coverArt = GeneratedColumn( - 'cover_art', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _genreMeta = const VerificationMeta('genre'); - late final GeneratedColumn genre = GeneratedColumn( - 'genre', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _yearMeta = const VerificationMeta('year'); - late final GeneratedColumn year = GeneratedColumn( - 'year', aliasedName, true, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _starredMeta = - const VerificationMeta('starred'); - late final GeneratedColumn starred = GeneratedColumn( - 'starred', aliasedName, true, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _songCountMeta = - const VerificationMeta('songCount'); - late final GeneratedColumn songCount = GeneratedColumn( - 'song_count', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _frequentRankMeta = - const VerificationMeta('frequentRank'); - late final GeneratedColumn frequentRank = GeneratedColumn( - 'frequent_rank', aliasedName, true, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _recentRankMeta = - const VerificationMeta('recentRank'); - late final GeneratedColumn recentRank = GeneratedColumn( - 'recent_rank', aliasedName, true, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _isDeletedMeta = - const VerificationMeta('isDeleted'); - late final GeneratedColumn isDeleted = GeneratedColumn( - 'is_deleted', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - $customConstraints: 'NOT NULL DEFAULT 0', - defaultValue: const CustomExpression('0')); - static const VerificationMeta _updatedMeta = - const VerificationMeta('updated'); - late final GeneratedColumn updated = GeneratedColumn( - 'updated', aliasedName, false, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - $customConstraints: - 'NOT NULL DEFAULT (strftime(\'%s\', CURRENT_TIMESTAMP))', - defaultValue: - const CustomExpression('strftime(\'%s\', CURRENT_TIMESTAMP)')); - @override - List get $columns => [ - sourceId, - id, - artistId, - name, - albumArtist, - created, - coverArt, - genre, - year, - starred, - songCount, - frequentRank, - recentRank, - isDeleted, - updated - ]; - @override - String get aliasedName => _alias ?? 'albums'; - @override - String get actualTableName => 'albums'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('source_id')) { - context.handle(_sourceIdMeta, - sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta)); - } else if (isInserting) { - context.missing(_sourceIdMeta); - } - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } else if (isInserting) { - context.missing(_idMeta); - } - if (data.containsKey('artist_id')) { - context.handle(_artistIdMeta, - artistId.isAcceptableOrUnknown(data['artist_id']!, _artistIdMeta)); - } - if (data.containsKey('name')) { - context.handle( - _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); - } else if (isInserting) { - context.missing(_nameMeta); - } - if (data.containsKey('album_artist')) { - context.handle( - _albumArtistMeta, - albumArtist.isAcceptableOrUnknown( - data['album_artist']!, _albumArtistMeta)); - } - if (data.containsKey('created')) { - context.handle(_createdMeta, - created.isAcceptableOrUnknown(data['created']!, _createdMeta)); - } else if (isInserting) { - context.missing(_createdMeta); - } - if (data.containsKey('cover_art')) { - context.handle(_coverArtMeta, - coverArt.isAcceptableOrUnknown(data['cover_art']!, _coverArtMeta)); - } - if (data.containsKey('genre')) { - context.handle( - _genreMeta, genre.isAcceptableOrUnknown(data['genre']!, _genreMeta)); - } - if (data.containsKey('year')) { - context.handle( - _yearMeta, year.isAcceptableOrUnknown(data['year']!, _yearMeta)); - } - if (data.containsKey('starred')) { - context.handle(_starredMeta, - starred.isAcceptableOrUnknown(data['starred']!, _starredMeta)); - } - if (data.containsKey('song_count')) { - context.handle(_songCountMeta, - songCount.isAcceptableOrUnknown(data['song_count']!, _songCountMeta)); - } else if (isInserting) { - context.missing(_songCountMeta); - } - if (data.containsKey('frequent_rank')) { - context.handle( - _frequentRankMeta, - frequentRank.isAcceptableOrUnknown( - data['frequent_rank']!, _frequentRankMeta)); - } - if (data.containsKey('recent_rank')) { - context.handle( - _recentRankMeta, - recentRank.isAcceptableOrUnknown( - data['recent_rank']!, _recentRankMeta)); - } - if (data.containsKey('is_deleted')) { - context.handle(_isDeletedMeta, - isDeleted.isAcceptableOrUnknown(data['is_deleted']!, _isDeletedMeta)); - } - if (data.containsKey('updated')) { - context.handle(_updatedMeta, - updated.isAcceptableOrUnknown(data['updated']!, _updatedMeta)); - } - return context; - } - - @override - Set get $primaryKey => {sourceId, id}; - @override - Album map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return Album( - sourceId: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}source_id'])!, - id: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}id'])!, - name: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}name'])!, - artistId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}artist_id']), - albumArtist: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}album_artist']), - created: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}created'])!, - coverArt: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}cover_art']), - year: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}year']), - starred: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}starred']), - genre: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}genre']), - songCount: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}song_count'])!, - isDeleted: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}is_deleted'])!, - frequentRank: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}frequent_rank']), - recentRank: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}recent_rank']), - ); - } - - @override - Albums createAlias(String alias) { - return Albums(attachedDatabase, alias); - } - - @override - List get customConstraints => const [ - 'PRIMARY KEY(source_id, id)', - 'FOREIGN KEY(source_id)REFERENCES sources(id)ON DELETE CASCADE' - ]; - @override - bool get dontWriteConstraints => true; -} - -class AlbumsCompanion extends UpdateCompanion { - final Value sourceId; - final Value id; - final Value artistId; - final Value name; - final Value albumArtist; - final Value created; - final Value coverArt; - final Value genre; - final Value year; - final Value starred; - final Value songCount; - final Value frequentRank; - final Value recentRank; - final Value isDeleted; - final Value updated; - final Value rowid; - const AlbumsCompanion({ - this.sourceId = const Value.absent(), - this.id = const Value.absent(), - this.artistId = const Value.absent(), - this.name = const Value.absent(), - this.albumArtist = const Value.absent(), - this.created = const Value.absent(), - this.coverArt = const Value.absent(), - this.genre = const Value.absent(), - this.year = const Value.absent(), - this.starred = const Value.absent(), - this.songCount = const Value.absent(), - this.frequentRank = const Value.absent(), - this.recentRank = const Value.absent(), - this.isDeleted = const Value.absent(), - this.updated = const Value.absent(), - this.rowid = const Value.absent(), - }); - AlbumsCompanion.insert({ - required int sourceId, - required String id, - this.artistId = const Value.absent(), - required String name, - this.albumArtist = const Value.absent(), - required DateTime created, - this.coverArt = const Value.absent(), - this.genre = const Value.absent(), - this.year = const Value.absent(), - this.starred = const Value.absent(), - required int songCount, - this.frequentRank = const Value.absent(), - this.recentRank = const Value.absent(), - this.isDeleted = const Value.absent(), - this.updated = const Value.absent(), - this.rowid = const Value.absent(), - }) : sourceId = Value(sourceId), - id = Value(id), - name = Value(name), - created = Value(created), - songCount = Value(songCount); - static Insertable custom({ - Expression? sourceId, - Expression? id, - Expression? artistId, - Expression? name, - Expression? albumArtist, - Expression? created, - Expression? coverArt, - Expression? genre, - Expression? year, - Expression? starred, - Expression? songCount, - Expression? frequentRank, - Expression? recentRank, - Expression? isDeleted, - Expression? updated, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (sourceId != null) 'source_id': sourceId, - if (id != null) 'id': id, - if (artistId != null) 'artist_id': artistId, - if (name != null) 'name': name, - if (albumArtist != null) 'album_artist': albumArtist, - if (created != null) 'created': created, - if (coverArt != null) 'cover_art': coverArt, - if (genre != null) 'genre': genre, - if (year != null) 'year': year, - if (starred != null) 'starred': starred, - if (songCount != null) 'song_count': songCount, - if (frequentRank != null) 'frequent_rank': frequentRank, - if (recentRank != null) 'recent_rank': recentRank, - if (isDeleted != null) 'is_deleted': isDeleted, - if (updated != null) 'updated': updated, - if (rowid != null) 'rowid': rowid, - }); - } - - AlbumsCompanion copyWith( - {Value? sourceId, - Value? id, - Value? artistId, - Value? name, - Value? albumArtist, - Value? created, - Value? coverArt, - Value? genre, - Value? year, - Value? starred, - Value? songCount, - Value? frequentRank, - Value? recentRank, - Value? isDeleted, - Value? updated, - Value? rowid}) { - return AlbumsCompanion( - sourceId: sourceId ?? this.sourceId, - id: id ?? this.id, - artistId: artistId ?? this.artistId, - name: name ?? this.name, - albumArtist: albumArtist ?? this.albumArtist, - created: created ?? this.created, - coverArt: coverArt ?? this.coverArt, - genre: genre ?? this.genre, - year: year ?? this.year, - starred: starred ?? this.starred, - songCount: songCount ?? this.songCount, - frequentRank: frequentRank ?? this.frequentRank, - recentRank: recentRank ?? this.recentRank, - isDeleted: isDeleted ?? this.isDeleted, - updated: updated ?? this.updated, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (sourceId.present) { - map['source_id'] = Variable(sourceId.value); - } - if (id.present) { - map['id'] = Variable(id.value); - } - if (artistId.present) { - map['artist_id'] = Variable(artistId.value); - } - if (name.present) { - map['name'] = Variable(name.value); - } - if (albumArtist.present) { - map['album_artist'] = Variable(albumArtist.value); - } - if (created.present) { - map['created'] = Variable(created.value); - } - if (coverArt.present) { - map['cover_art'] = Variable(coverArt.value); - } - if (genre.present) { - map['genre'] = Variable(genre.value); - } - if (year.present) { - map['year'] = Variable(year.value); - } - if (starred.present) { - map['starred'] = Variable(starred.value); - } - if (songCount.present) { - map['song_count'] = Variable(songCount.value); - } - if (frequentRank.present) { - map['frequent_rank'] = Variable(frequentRank.value); - } - if (recentRank.present) { - map['recent_rank'] = Variable(recentRank.value); - } - if (isDeleted.present) { - map['is_deleted'] = Variable(isDeleted.value); - } - if (updated.present) { - map['updated'] = Variable(updated.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('AlbumsCompanion(') - ..write('sourceId: $sourceId, ') - ..write('id: $id, ') - ..write('artistId: $artistId, ') - ..write('name: $name, ') - ..write('albumArtist: $albumArtist, ') - ..write('created: $created, ') - ..write('coverArt: $coverArt, ') - ..write('genre: $genre, ') - ..write('year: $year, ') - ..write('starred: $starred, ') - ..write('songCount: $songCount, ') - ..write('frequentRank: $frequentRank, ') - ..write('recentRank: $recentRank, ') - ..write('isDeleted: $isDeleted, ') - ..write('updated: $updated, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - -class AlbumsFts extends Table - with TableInfo, VirtualTableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - AlbumsFts(this.attachedDatabase, [this._alias]); - static const VerificationMeta _sourceIdMeta = - const VerificationMeta('sourceId'); - late final GeneratedColumn sourceId = GeneratedColumn( - 'source_id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: ''); - static const VerificationMeta _nameMeta = const VerificationMeta('name'); - late final GeneratedColumn name = GeneratedColumn( - 'name', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: ''); - @override - List get $columns => [sourceId, name]; - @override - String get aliasedName => _alias ?? 'albums_fts'; - @override - String get actualTableName => 'albums_fts'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('source_id')) { - context.handle(_sourceIdMeta, - sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta)); - } else if (isInserting) { - context.missing(_sourceIdMeta); - } - if (data.containsKey('name')) { - context.handle( - _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); - } else if (isInserting) { - context.missing(_nameMeta); - } - return context; - } - - @override - Set get $primaryKey => const {}; - @override - AlbumsFt map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return AlbumsFt( - sourceId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}source_id'])!, - name: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}name'])!, - ); - } - - @override - AlbumsFts createAlias(String alias) { - return AlbumsFts(attachedDatabase, alias); - } - - @override - bool get dontWriteConstraints => true; - @override - String get moduleAndArgs => - 'fts5(source_id, name, content=albums, content_rowid=rowid)'; -} - -class AlbumsFt extends DataClass implements Insertable { - final String sourceId; - final String name; - const AlbumsFt({required this.sourceId, required this.name}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['source_id'] = Variable(sourceId); - map['name'] = Variable(name); - return map; - } - - AlbumsFtsCompanion toCompanion(bool nullToAbsent) { - return AlbumsFtsCompanion( - sourceId: Value(sourceId), - name: Value(name), - ); - } - - factory AlbumsFt.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return AlbumsFt( - sourceId: serializer.fromJson(json['source_id']), - name: serializer.fromJson(json['name']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'source_id': serializer.toJson(sourceId), - 'name': serializer.toJson(name), - }; - } - - AlbumsFt copyWith({String? sourceId, String? name}) => AlbumsFt( - sourceId: sourceId ?? this.sourceId, - name: name ?? this.name, - ); - @override - String toString() { - return (StringBuffer('AlbumsFt(') - ..write('sourceId: $sourceId, ') - ..write('name: $name') - ..write(')')) - .toString(); - } - - @override - int get hashCode => Object.hash(sourceId, name); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is AlbumsFt && - other.sourceId == this.sourceId && - other.name == this.name); -} - -class AlbumsFtsCompanion extends UpdateCompanion { - final Value sourceId; - final Value name; - final Value rowid; - const AlbumsFtsCompanion({ - this.sourceId = const Value.absent(), - this.name = const Value.absent(), - this.rowid = const Value.absent(), - }); - AlbumsFtsCompanion.insert({ - required String sourceId, - required String name, - this.rowid = const Value.absent(), - }) : sourceId = Value(sourceId), - name = Value(name); - static Insertable custom({ - Expression? sourceId, - Expression? name, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (sourceId != null) 'source_id': sourceId, - if (name != null) 'name': name, - if (rowid != null) 'rowid': rowid, - }); - } - - AlbumsFtsCompanion copyWith( - {Value? sourceId, Value? name, Value? rowid}) { - return AlbumsFtsCompanion( - sourceId: sourceId ?? this.sourceId, - name: name ?? this.name, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (sourceId.present) { - map['source_id'] = Variable(sourceId.value); - } - if (name.present) { - map['name'] = Variable(name.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('AlbumsFtsCompanion(') - ..write('sourceId: $sourceId, ') - ..write('name: $name, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - -class Playlists extends Table with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - Playlists(this.attachedDatabase, [this._alias]); - static const VerificationMeta _sourceIdMeta = - const VerificationMeta('sourceId'); - late final GeneratedColumn sourceId = GeneratedColumn( - 'source_id', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _nameMeta = const VerificationMeta('name'); - late final GeneratedColumn name = GeneratedColumn( - 'name', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL COLLATE NOCASE'); - static const VerificationMeta _commentMeta = - const VerificationMeta('comment'); - late final GeneratedColumn comment = GeneratedColumn( - 'comment', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: 'COLLATE NOCASE'); - static const VerificationMeta _coverArtMeta = - const VerificationMeta('coverArt'); - late final GeneratedColumn coverArt = GeneratedColumn( - 'cover_art', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _songCountMeta = - const VerificationMeta('songCount'); - late final GeneratedColumn songCount = GeneratedColumn( - 'song_count', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _createdMeta = - const VerificationMeta('created'); - late final GeneratedColumn created = GeneratedColumn( - 'created', aliasedName, false, - type: DriftSqlType.dateTime, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _updatedMeta = - const VerificationMeta('updated'); - late final GeneratedColumn updated = GeneratedColumn( - 'updated', aliasedName, false, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - $customConstraints: - 'NOT NULL DEFAULT (strftime(\'%s\', CURRENT_TIMESTAMP))', - defaultValue: - const CustomExpression('strftime(\'%s\', CURRENT_TIMESTAMP)')); - @override - List get $columns => - [sourceId, id, name, comment, coverArt, songCount, created, updated]; - @override - String get aliasedName => _alias ?? 'playlists'; - @override - String get actualTableName => 'playlists'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('source_id')) { - context.handle(_sourceIdMeta, - sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta)); - } else if (isInserting) { - context.missing(_sourceIdMeta); - } - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } else if (isInserting) { - context.missing(_idMeta); - } - if (data.containsKey('name')) { - context.handle( - _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); - } else if (isInserting) { - context.missing(_nameMeta); - } - if (data.containsKey('comment')) { - context.handle(_commentMeta, - comment.isAcceptableOrUnknown(data['comment']!, _commentMeta)); - } - if (data.containsKey('cover_art')) { - context.handle(_coverArtMeta, - coverArt.isAcceptableOrUnknown(data['cover_art']!, _coverArtMeta)); - } - if (data.containsKey('song_count')) { - context.handle(_songCountMeta, - songCount.isAcceptableOrUnknown(data['song_count']!, _songCountMeta)); - } else if (isInserting) { - context.missing(_songCountMeta); - } - if (data.containsKey('created')) { - context.handle(_createdMeta, - created.isAcceptableOrUnknown(data['created']!, _createdMeta)); - } else if (isInserting) { - context.missing(_createdMeta); - } - if (data.containsKey('updated')) { - context.handle(_updatedMeta, - updated.isAcceptableOrUnknown(data['updated']!, _updatedMeta)); - } - return context; - } - - @override - Set get $primaryKey => {sourceId, id}; - @override - Playlist map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return Playlist( - sourceId: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}source_id'])!, - id: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}id'])!, - name: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}name'])!, - comment: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}comment']), - coverArt: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}cover_art']), - songCount: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}song_count'])!, - created: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}created'])!, - ); - } - - @override - Playlists createAlias(String alias) { - return Playlists(attachedDatabase, alias); - } - - @override - List get customConstraints => const [ - 'PRIMARY KEY(source_id, id)', - 'FOREIGN KEY(source_id)REFERENCES sources(id)ON DELETE CASCADE' - ]; - @override - bool get dontWriteConstraints => true; -} - -class PlaylistsCompanion extends UpdateCompanion { - final Value sourceId; - final Value id; - final Value name; - final Value comment; - final Value coverArt; - final Value songCount; - final Value created; - final Value updated; - final Value rowid; - const PlaylistsCompanion({ - this.sourceId = const Value.absent(), - this.id = const Value.absent(), - this.name = const Value.absent(), - this.comment = const Value.absent(), - this.coverArt = const Value.absent(), - this.songCount = const Value.absent(), - this.created = const Value.absent(), - this.updated = const Value.absent(), - this.rowid = const Value.absent(), - }); - PlaylistsCompanion.insert({ - required int sourceId, - required String id, - required String name, - this.comment = const Value.absent(), - this.coverArt = const Value.absent(), - required int songCount, - required DateTime created, - this.updated = const Value.absent(), - this.rowid = const Value.absent(), - }) : sourceId = Value(sourceId), - id = Value(id), - name = Value(name), - songCount = Value(songCount), - created = Value(created); - static Insertable custom({ - Expression? sourceId, - Expression? id, - Expression? name, - Expression? comment, - Expression? coverArt, - Expression? songCount, - Expression? created, - Expression? updated, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (sourceId != null) 'source_id': sourceId, - if (id != null) 'id': id, - if (name != null) 'name': name, - if (comment != null) 'comment': comment, - if (coverArt != null) 'cover_art': coverArt, - if (songCount != null) 'song_count': songCount, - if (created != null) 'created': created, - if (updated != null) 'updated': updated, - if (rowid != null) 'rowid': rowid, - }); - } - - PlaylistsCompanion copyWith( - {Value? sourceId, - Value? id, - Value? name, - Value? comment, - Value? coverArt, - Value? songCount, - Value? created, - Value? updated, - Value? rowid}) { - return PlaylistsCompanion( - sourceId: sourceId ?? this.sourceId, - id: id ?? this.id, - name: name ?? this.name, - comment: comment ?? this.comment, - coverArt: coverArt ?? this.coverArt, - songCount: songCount ?? this.songCount, - created: created ?? this.created, - updated: updated ?? this.updated, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (sourceId.present) { - map['source_id'] = Variable(sourceId.value); - } - if (id.present) { - map['id'] = Variable(id.value); - } - if (name.present) { - map['name'] = Variable(name.value); - } - if (comment.present) { - map['comment'] = Variable(comment.value); - } - if (coverArt.present) { - map['cover_art'] = Variable(coverArt.value); - } - if (songCount.present) { - map['song_count'] = Variable(songCount.value); - } - if (created.present) { - map['created'] = Variable(created.value); - } - if (updated.present) { - map['updated'] = Variable(updated.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('PlaylistsCompanion(') - ..write('sourceId: $sourceId, ') - ..write('id: $id, ') - ..write('name: $name, ') - ..write('comment: $comment, ') - ..write('coverArt: $coverArt, ') - ..write('songCount: $songCount, ') - ..write('created: $created, ') - ..write('updated: $updated, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - -class PlaylistSongs extends Table with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - PlaylistSongs(this.attachedDatabase, [this._alias]); - static const VerificationMeta _sourceIdMeta = - const VerificationMeta('sourceId'); - late final GeneratedColumn sourceId = GeneratedColumn( - 'source_id', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _playlistIdMeta = - const VerificationMeta('playlistId'); - late final GeneratedColumn playlistId = GeneratedColumn( - 'playlist_id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _songIdMeta = const VerificationMeta('songId'); - late final GeneratedColumn songId = GeneratedColumn( - 'song_id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _positionMeta = - const VerificationMeta('position'); - late final GeneratedColumn position = GeneratedColumn( - 'position', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _updatedMeta = - const VerificationMeta('updated'); - late final GeneratedColumn updated = GeneratedColumn( - 'updated', aliasedName, false, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - $customConstraints: - 'NOT NULL DEFAULT (strftime(\'%s\', CURRENT_TIMESTAMP))', - defaultValue: - const CustomExpression('strftime(\'%s\', CURRENT_TIMESTAMP)')); - @override - List get $columns => - [sourceId, playlistId, songId, position, updated]; - @override - String get aliasedName => _alias ?? 'playlist_songs'; - @override - String get actualTableName => 'playlist_songs'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('source_id')) { - context.handle(_sourceIdMeta, - sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta)); - } else if (isInserting) { - context.missing(_sourceIdMeta); - } - if (data.containsKey('playlist_id')) { - context.handle( - _playlistIdMeta, - playlistId.isAcceptableOrUnknown( - data['playlist_id']!, _playlistIdMeta)); - } else if (isInserting) { - context.missing(_playlistIdMeta); - } - if (data.containsKey('song_id')) { - context.handle(_songIdMeta, - songId.isAcceptableOrUnknown(data['song_id']!, _songIdMeta)); - } else if (isInserting) { - context.missing(_songIdMeta); - } - if (data.containsKey('position')) { - context.handle(_positionMeta, - position.isAcceptableOrUnknown(data['position']!, _positionMeta)); - } else if (isInserting) { - context.missing(_positionMeta); - } - if (data.containsKey('updated')) { - context.handle(_updatedMeta, - updated.isAcceptableOrUnknown(data['updated']!, _updatedMeta)); - } - return context; - } - - @override - Set get $primaryKey => {sourceId, playlistId, position}; - @override - PlaylistSong map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return PlaylistSong( - sourceId: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}source_id'])!, - playlistId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}playlist_id'])!, - songId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}song_id'])!, - position: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}position'])!, - updated: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}updated'])!, - ); - } - - @override - PlaylistSongs createAlias(String alias) { - return PlaylistSongs(attachedDatabase, alias); - } - - @override - List get customConstraints => const [ - 'PRIMARY KEY(source_id, playlist_id, position)', - 'FOREIGN KEY(source_id)REFERENCES sources(id)ON DELETE CASCADE' - ]; - @override - bool get dontWriteConstraints => true; -} - -class PlaylistSong extends DataClass implements Insertable { - final int sourceId; - final String playlistId; - final String songId; - final int position; - final DateTime updated; - const PlaylistSong( - {required this.sourceId, - required this.playlistId, - required this.songId, - required this.position, - required this.updated}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['source_id'] = Variable(sourceId); - map['playlist_id'] = Variable(playlistId); - map['song_id'] = Variable(songId); - map['position'] = Variable(position); - map['updated'] = Variable(updated); - return map; - } - - PlaylistSongsCompanion toCompanion(bool nullToAbsent) { - return PlaylistSongsCompanion( - sourceId: Value(sourceId), - playlistId: Value(playlistId), - songId: Value(songId), - position: Value(position), - updated: Value(updated), - ); - } - - factory PlaylistSong.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return PlaylistSong( - sourceId: serializer.fromJson(json['source_id']), - playlistId: serializer.fromJson(json['playlist_id']), - songId: serializer.fromJson(json['song_id']), - position: serializer.fromJson(json['position']), - updated: serializer.fromJson(json['updated']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'source_id': serializer.toJson(sourceId), - 'playlist_id': serializer.toJson(playlistId), - 'song_id': serializer.toJson(songId), - 'position': serializer.toJson(position), - 'updated': serializer.toJson(updated), - }; - } - - PlaylistSong copyWith( - {int? sourceId, - String? playlistId, - String? songId, - int? position, - DateTime? updated}) => - PlaylistSong( - sourceId: sourceId ?? this.sourceId, - playlistId: playlistId ?? this.playlistId, - songId: songId ?? this.songId, - position: position ?? this.position, - updated: updated ?? this.updated, - ); - @override - String toString() { - return (StringBuffer('PlaylistSong(') - ..write('sourceId: $sourceId, ') - ..write('playlistId: $playlistId, ') - ..write('songId: $songId, ') - ..write('position: $position, ') - ..write('updated: $updated') - ..write(')')) - .toString(); - } - - @override - int get hashCode => - Object.hash(sourceId, playlistId, songId, position, updated); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is PlaylistSong && - other.sourceId == this.sourceId && - other.playlistId == this.playlistId && - other.songId == this.songId && - other.position == this.position && - other.updated == this.updated); -} - -class PlaylistSongsCompanion extends UpdateCompanion { - final Value sourceId; - final Value playlistId; - final Value songId; - final Value position; - final Value updated; - final Value rowid; - const PlaylistSongsCompanion({ - this.sourceId = const Value.absent(), - this.playlistId = const Value.absent(), - this.songId = const Value.absent(), - this.position = const Value.absent(), - this.updated = const Value.absent(), - this.rowid = const Value.absent(), - }); - PlaylistSongsCompanion.insert({ - required int sourceId, - required String playlistId, - required String songId, - required int position, - this.updated = const Value.absent(), - this.rowid = const Value.absent(), - }) : sourceId = Value(sourceId), - playlistId = Value(playlistId), - songId = Value(songId), - position = Value(position); - static Insertable custom({ - Expression? sourceId, - Expression? playlistId, - Expression? songId, - Expression? position, - Expression? updated, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (sourceId != null) 'source_id': sourceId, - if (playlistId != null) 'playlist_id': playlistId, - if (songId != null) 'song_id': songId, - if (position != null) 'position': position, - if (updated != null) 'updated': updated, - if (rowid != null) 'rowid': rowid, - }); - } - - PlaylistSongsCompanion copyWith( - {Value? sourceId, - Value? playlistId, - Value? songId, - Value? position, - Value? updated, - Value? rowid}) { - return PlaylistSongsCompanion( - sourceId: sourceId ?? this.sourceId, - playlistId: playlistId ?? this.playlistId, - songId: songId ?? this.songId, - position: position ?? this.position, - updated: updated ?? this.updated, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (sourceId.present) { - map['source_id'] = Variable(sourceId.value); - } - if (playlistId.present) { - map['playlist_id'] = Variable(playlistId.value); - } - if (songId.present) { - map['song_id'] = Variable(songId.value); - } - if (position.present) { - map['position'] = Variable(position.value); - } - if (updated.present) { - map['updated'] = Variable(updated.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('PlaylistSongsCompanion(') - ..write('sourceId: $sourceId, ') - ..write('playlistId: $playlistId, ') - ..write('songId: $songId, ') - ..write('position: $position, ') - ..write('updated: $updated, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - -class PlaylistsFts extends Table - with - TableInfo, - VirtualTableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - PlaylistsFts(this.attachedDatabase, [this._alias]); - static const VerificationMeta _sourceIdMeta = - const VerificationMeta('sourceId'); - late final GeneratedColumn sourceId = GeneratedColumn( - 'source_id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: ''); - static const VerificationMeta _nameMeta = const VerificationMeta('name'); - late final GeneratedColumn name = GeneratedColumn( - 'name', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: ''); - @override - List get $columns => [sourceId, name]; - @override - String get aliasedName => _alias ?? 'playlists_fts'; - @override - String get actualTableName => 'playlists_fts'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('source_id')) { - context.handle(_sourceIdMeta, - sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta)); - } else if (isInserting) { - context.missing(_sourceIdMeta); - } - if (data.containsKey('name')) { - context.handle( - _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); - } else if (isInserting) { - context.missing(_nameMeta); - } - return context; - } - - @override - Set get $primaryKey => const {}; - @override - PlaylistsFt map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return PlaylistsFt( - sourceId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}source_id'])!, - name: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}name'])!, - ); - } - - @override - PlaylistsFts createAlias(String alias) { - return PlaylistsFts(attachedDatabase, alias); - } - - @override - bool get dontWriteConstraints => true; - @override - String get moduleAndArgs => - 'fts5(source_id, name, content=playlists, content_rowid=rowid)'; -} - -class PlaylistsFt extends DataClass implements Insertable { - final String sourceId; - final String name; - const PlaylistsFt({required this.sourceId, required this.name}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['source_id'] = Variable(sourceId); - map['name'] = Variable(name); - return map; - } - - PlaylistsFtsCompanion toCompanion(bool nullToAbsent) { - return PlaylistsFtsCompanion( - sourceId: Value(sourceId), - name: Value(name), - ); - } - - factory PlaylistsFt.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return PlaylistsFt( - sourceId: serializer.fromJson(json['source_id']), - name: serializer.fromJson(json['name']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'source_id': serializer.toJson(sourceId), - 'name': serializer.toJson(name), - }; - } - - PlaylistsFt copyWith({String? sourceId, String? name}) => PlaylistsFt( - sourceId: sourceId ?? this.sourceId, - name: name ?? this.name, - ); - @override - String toString() { - return (StringBuffer('PlaylistsFt(') - ..write('sourceId: $sourceId, ') - ..write('name: $name') - ..write(')')) - .toString(); - } - - @override - int get hashCode => Object.hash(sourceId, name); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is PlaylistsFt && - other.sourceId == this.sourceId && - other.name == this.name); -} - -class PlaylistsFtsCompanion extends UpdateCompanion { - final Value sourceId; - final Value name; - final Value rowid; - const PlaylistsFtsCompanion({ - this.sourceId = const Value.absent(), - this.name = const Value.absent(), - this.rowid = const Value.absent(), - }); - PlaylistsFtsCompanion.insert({ - required String sourceId, - required String name, - this.rowid = const Value.absent(), - }) : sourceId = Value(sourceId), - name = Value(name); - static Insertable custom({ - Expression? sourceId, - Expression? name, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (sourceId != null) 'source_id': sourceId, - if (name != null) 'name': name, - if (rowid != null) 'rowid': rowid, - }); - } - - PlaylistsFtsCompanion copyWith( - {Value? sourceId, Value? name, Value? rowid}) { - return PlaylistsFtsCompanion( - sourceId: sourceId ?? this.sourceId, - name: name ?? this.name, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (sourceId.present) { - map['source_id'] = Variable(sourceId.value); - } - if (name.present) { - map['name'] = Variable(name.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('PlaylistsFtsCompanion(') - ..write('sourceId: $sourceId, ') - ..write('name: $name, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - -class Songs extends Table with TableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - Songs(this.attachedDatabase, [this._alias]); - static const VerificationMeta _sourceIdMeta = - const VerificationMeta('sourceId'); - late final GeneratedColumn sourceId = GeneratedColumn( - 'source_id', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL'); - static const VerificationMeta _albumIdMeta = - const VerificationMeta('albumId'); - late final GeneratedColumn albumId = GeneratedColumn( - 'album_id', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _artistIdMeta = - const VerificationMeta('artistId'); - late final GeneratedColumn artistId = GeneratedColumn( - 'artist_id', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _titleMeta = const VerificationMeta('title'); - late final GeneratedColumn title = GeneratedColumn( - 'title', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: 'NOT NULL COLLATE NOCASE'); - static const VerificationMeta _albumMeta = const VerificationMeta('album'); - late final GeneratedColumn album = GeneratedColumn( - 'album', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: 'COLLATE NOCASE'); - static const VerificationMeta _artistMeta = const VerificationMeta('artist'); - late final GeneratedColumn artist = GeneratedColumn( - 'artist', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: 'COLLATE NOCASE'); - static const VerificationMeta _durationMeta = - const VerificationMeta('duration'); - late final GeneratedColumnWithTypeConverter duration = - GeneratedColumn('duration', aliasedName, true, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: '') - .withConverter(Songs.$converterdurationn); - static const VerificationMeta _trackMeta = const VerificationMeta('track'); - late final GeneratedColumn track = GeneratedColumn( - 'track', aliasedName, true, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _discMeta = const VerificationMeta('disc'); - late final GeneratedColumn disc = GeneratedColumn( - 'disc', aliasedName, true, - type: DriftSqlType.int, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _starredMeta = - const VerificationMeta('starred'); - late final GeneratedColumn starred = GeneratedColumn( - 'starred', aliasedName, true, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _genreMeta = const VerificationMeta('genre'); - late final GeneratedColumn genre = GeneratedColumn( - 'genre', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: ''); - static const VerificationMeta _downloadTaskIdMeta = - const VerificationMeta('downloadTaskId'); - late final GeneratedColumn downloadTaskId = GeneratedColumn( - 'download_task_id', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: 'UNIQUE'); - static const VerificationMeta _downloadFilePathMeta = - const VerificationMeta('downloadFilePath'); - late final GeneratedColumn downloadFilePath = GeneratedColumn( - 'download_file_path', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - $customConstraints: 'UNIQUE'); - static const VerificationMeta _isDeletedMeta = - const VerificationMeta('isDeleted'); - late final GeneratedColumn isDeleted = GeneratedColumn( - 'is_deleted', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - $customConstraints: 'NOT NULL DEFAULT 0', - defaultValue: const CustomExpression('0')); - static const VerificationMeta _updatedMeta = - const VerificationMeta('updated'); - late final GeneratedColumn updated = GeneratedColumn( - 'updated', aliasedName, false, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - $customConstraints: - 'NOT NULL DEFAULT (strftime(\'%s\', CURRENT_TIMESTAMP))', - defaultValue: - const CustomExpression('strftime(\'%s\', CURRENT_TIMESTAMP)')); - @override - List get $columns => [ - sourceId, - id, - albumId, - artistId, - title, - album, - artist, - duration, - track, - disc, - starred, - genre, - downloadTaskId, - downloadFilePath, - isDeleted, - updated - ]; - @override - String get aliasedName => _alias ?? 'songs'; - @override - String get actualTableName => 'songs'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('source_id')) { - context.handle(_sourceIdMeta, - sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta)); - } else if (isInserting) { - context.missing(_sourceIdMeta); - } - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } else if (isInserting) { - context.missing(_idMeta); - } - if (data.containsKey('album_id')) { - context.handle(_albumIdMeta, - albumId.isAcceptableOrUnknown(data['album_id']!, _albumIdMeta)); - } - if (data.containsKey('artist_id')) { - context.handle(_artistIdMeta, - artistId.isAcceptableOrUnknown(data['artist_id']!, _artistIdMeta)); - } - if (data.containsKey('title')) { - context.handle( - _titleMeta, title.isAcceptableOrUnknown(data['title']!, _titleMeta)); - } else if (isInserting) { - context.missing(_titleMeta); - } - if (data.containsKey('album')) { - context.handle( - _albumMeta, album.isAcceptableOrUnknown(data['album']!, _albumMeta)); - } - if (data.containsKey('artist')) { - context.handle(_artistMeta, - artist.isAcceptableOrUnknown(data['artist']!, _artistMeta)); - } - context.handle(_durationMeta, const VerificationResult.success()); - if (data.containsKey('track')) { - context.handle( - _trackMeta, track.isAcceptableOrUnknown(data['track']!, _trackMeta)); - } - if (data.containsKey('disc')) { - context.handle( - _discMeta, disc.isAcceptableOrUnknown(data['disc']!, _discMeta)); - } - if (data.containsKey('starred')) { - context.handle(_starredMeta, - starred.isAcceptableOrUnknown(data['starred']!, _starredMeta)); - } - if (data.containsKey('genre')) { - context.handle( - _genreMeta, genre.isAcceptableOrUnknown(data['genre']!, _genreMeta)); - } - if (data.containsKey('download_task_id')) { - context.handle( - _downloadTaskIdMeta, - downloadTaskId.isAcceptableOrUnknown( - data['download_task_id']!, _downloadTaskIdMeta)); - } - if (data.containsKey('download_file_path')) { - context.handle( - _downloadFilePathMeta, - downloadFilePath.isAcceptableOrUnknown( - data['download_file_path']!, _downloadFilePathMeta)); - } - if (data.containsKey('is_deleted')) { - context.handle(_isDeletedMeta, - isDeleted.isAcceptableOrUnknown(data['is_deleted']!, _isDeletedMeta)); - } - if (data.containsKey('updated')) { - context.handle(_updatedMeta, - updated.isAcceptableOrUnknown(data['updated']!, _updatedMeta)); - } - return context; - } - - @override - Set get $primaryKey => {sourceId, id}; - @override - Song map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return Song( - sourceId: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}source_id'])!, - id: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}id'])!, - albumId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}album_id']), - artistId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}artist_id']), - title: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}title'])!, - artist: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}artist']), - album: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}album']), - duration: Songs.$converterdurationn.fromSql(attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}duration'])), - track: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}track']), - disc: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}disc']), - starred: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}starred']), - genre: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}genre']), - downloadTaskId: attachedDatabase.typeMapping.read( - DriftSqlType.string, data['${effectivePrefix}download_task_id']), - downloadFilePath: attachedDatabase.typeMapping.read( - DriftSqlType.string, data['${effectivePrefix}download_file_path']), - isDeleted: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}is_deleted'])!, - ); - } - - @override - Songs createAlias(String alias) { - return Songs(attachedDatabase, alias); - } - - static TypeConverter $converterduration = - const DurationSecondsConverter(); - static TypeConverter $converterdurationn = - NullAwareTypeConverter.wrap($converterduration); - @override - List get customConstraints => const [ - 'PRIMARY KEY(source_id, id)', - 'FOREIGN KEY(source_id)REFERENCES sources(id)ON DELETE CASCADE' - ]; - @override - bool get dontWriteConstraints => true; -} - -class SongsCompanion extends UpdateCompanion { - final Value sourceId; - final Value id; - final Value albumId; - final Value artistId; - final Value title; - final Value album; - final Value artist; - final Value duration; - final Value track; - final Value disc; - final Value starred; - final Value genre; - final Value downloadTaskId; - final Value downloadFilePath; - final Value isDeleted; - final Value updated; - final Value rowid; - const SongsCompanion({ - this.sourceId = const Value.absent(), - this.id = const Value.absent(), - this.albumId = const Value.absent(), - this.artistId = const Value.absent(), - this.title = const Value.absent(), - this.album = const Value.absent(), - this.artist = const Value.absent(), - this.duration = const Value.absent(), - this.track = const Value.absent(), - this.disc = const Value.absent(), - this.starred = const Value.absent(), - this.genre = const Value.absent(), - this.downloadTaskId = const Value.absent(), - this.downloadFilePath = const Value.absent(), - this.isDeleted = const Value.absent(), - this.updated = const Value.absent(), - this.rowid = const Value.absent(), - }); - SongsCompanion.insert({ - required int sourceId, - required String id, - this.albumId = const Value.absent(), - this.artistId = const Value.absent(), - required String title, - this.album = const Value.absent(), - this.artist = const Value.absent(), - this.duration = const Value.absent(), - this.track = const Value.absent(), - this.disc = const Value.absent(), - this.starred = const Value.absent(), - this.genre = const Value.absent(), - this.downloadTaskId = const Value.absent(), - this.downloadFilePath = const Value.absent(), - this.isDeleted = const Value.absent(), - this.updated = const Value.absent(), - this.rowid = const Value.absent(), - }) : sourceId = Value(sourceId), - id = Value(id), - title = Value(title); - static Insertable custom({ - Expression? sourceId, - Expression? id, - Expression? albumId, - Expression? artistId, - Expression? title, - Expression? album, - Expression? artist, - Expression? duration, - Expression? track, - Expression? disc, - Expression? starred, - Expression? genre, - Expression? downloadTaskId, - Expression? downloadFilePath, - Expression? isDeleted, - Expression? updated, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (sourceId != null) 'source_id': sourceId, - if (id != null) 'id': id, - if (albumId != null) 'album_id': albumId, - if (artistId != null) 'artist_id': artistId, - if (title != null) 'title': title, - if (album != null) 'album': album, - if (artist != null) 'artist': artist, - if (duration != null) 'duration': duration, - if (track != null) 'track': track, - if (disc != null) 'disc': disc, - if (starred != null) 'starred': starred, - if (genre != null) 'genre': genre, - if (downloadTaskId != null) 'download_task_id': downloadTaskId, - if (downloadFilePath != null) 'download_file_path': downloadFilePath, - if (isDeleted != null) 'is_deleted': isDeleted, - if (updated != null) 'updated': updated, - if (rowid != null) 'rowid': rowid, - }); - } - - SongsCompanion copyWith( - {Value? sourceId, - Value? id, - Value? albumId, - Value? artistId, - Value? title, - Value? album, - Value? artist, - Value? duration, - Value? track, - Value? disc, - Value? starred, - Value? genre, - Value? downloadTaskId, - Value? downloadFilePath, - Value? isDeleted, - Value? updated, - Value? rowid}) { - return SongsCompanion( - sourceId: sourceId ?? this.sourceId, - id: id ?? this.id, - albumId: albumId ?? this.albumId, - artistId: artistId ?? this.artistId, - title: title ?? this.title, - album: album ?? this.album, - artist: artist ?? this.artist, - duration: duration ?? this.duration, - track: track ?? this.track, - disc: disc ?? this.disc, - starred: starred ?? this.starred, - genre: genre ?? this.genre, - downloadTaskId: downloadTaskId ?? this.downloadTaskId, - downloadFilePath: downloadFilePath ?? this.downloadFilePath, - isDeleted: isDeleted ?? this.isDeleted, - updated: updated ?? this.updated, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (sourceId.present) { - map['source_id'] = Variable(sourceId.value); - } - if (id.present) { - map['id'] = Variable(id.value); - } - if (albumId.present) { - map['album_id'] = Variable(albumId.value); - } - if (artistId.present) { - map['artist_id'] = Variable(artistId.value); - } - if (title.present) { - map['title'] = Variable(title.value); - } - if (album.present) { - map['album'] = Variable(album.value); - } - if (artist.present) { - map['artist'] = Variable(artist.value); - } - if (duration.present) { - final converter = Songs.$converterdurationn; - map['duration'] = Variable(converter.toSql(duration.value)); - } - if (track.present) { - map['track'] = Variable(track.value); - } - if (disc.present) { - map['disc'] = Variable(disc.value); - } - if (starred.present) { - map['starred'] = Variable(starred.value); - } - if (genre.present) { - map['genre'] = Variable(genre.value); - } - if (downloadTaskId.present) { - map['download_task_id'] = Variable(downloadTaskId.value); - } - if (downloadFilePath.present) { - map['download_file_path'] = Variable(downloadFilePath.value); - } - if (isDeleted.present) { - map['is_deleted'] = Variable(isDeleted.value); - } - if (updated.present) { - map['updated'] = Variable(updated.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('SongsCompanion(') - ..write('sourceId: $sourceId, ') - ..write('id: $id, ') - ..write('albumId: $albumId, ') - ..write('artistId: $artistId, ') - ..write('title: $title, ') - ..write('album: $album, ') - ..write('artist: $artist, ') - ..write('duration: $duration, ') - ..write('track: $track, ') - ..write('disc: $disc, ') - ..write('starred: $starred, ') - ..write('genre: $genre, ') - ..write('downloadTaskId: $downloadTaskId, ') - ..write('downloadFilePath: $downloadFilePath, ') - ..write('isDeleted: $isDeleted, ') - ..write('updated: $updated, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - -class SongsFts extends Table - with TableInfo, VirtualTableInfo { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - SongsFts(this.attachedDatabase, [this._alias]); - static const VerificationMeta _sourceIdMeta = - const VerificationMeta('sourceId'); - late final GeneratedColumn sourceId = GeneratedColumn( - 'source_id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: ''); - static const VerificationMeta _titleMeta = const VerificationMeta('title'); - late final GeneratedColumn title = GeneratedColumn( - 'title', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - $customConstraints: ''); - @override - List get $columns => [sourceId, title]; - @override - String get aliasedName => _alias ?? 'songs_fts'; - @override - String get actualTableName => 'songs_fts'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('source_id')) { - context.handle(_sourceIdMeta, - sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta)); - } else if (isInserting) { - context.missing(_sourceIdMeta); - } - if (data.containsKey('title')) { - context.handle( - _titleMeta, title.isAcceptableOrUnknown(data['title']!, _titleMeta)); - } else if (isInserting) { - context.missing(_titleMeta); - } - return context; - } - - @override - Set get $primaryKey => const {}; - @override - SongsFt map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return SongsFt( - sourceId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}source_id'])!, - title: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}title'])!, - ); - } - - @override - SongsFts createAlias(String alias) { - return SongsFts(attachedDatabase, alias); - } - - @override - bool get dontWriteConstraints => true; - @override - String get moduleAndArgs => - 'fts5(source_id, title, content=songs, content_rowid=rowid)'; -} - -class SongsFt extends DataClass implements Insertable { - final String sourceId; - final String title; - const SongsFt({required this.sourceId, required this.title}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['source_id'] = Variable(sourceId); - map['title'] = Variable(title); - return map; - } - - SongsFtsCompanion toCompanion(bool nullToAbsent) { - return SongsFtsCompanion( - sourceId: Value(sourceId), - title: Value(title), - ); - } - - factory SongsFt.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return SongsFt( - sourceId: serializer.fromJson(json['source_id']), - title: serializer.fromJson(json['title']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'source_id': serializer.toJson(sourceId), - 'title': serializer.toJson(title), - }; - } - - SongsFt copyWith({String? sourceId, String? title}) => SongsFt( - sourceId: sourceId ?? this.sourceId, - title: title ?? this.title, - ); - @override - String toString() { - return (StringBuffer('SongsFt(') - ..write('sourceId: $sourceId, ') - ..write('title: $title') - ..write(')')) - .toString(); - } - - @override - int get hashCode => Object.hash(sourceId, title); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is SongsFt && - other.sourceId == this.sourceId && - other.title == this.title); -} - -class SongsFtsCompanion extends UpdateCompanion { - final Value sourceId; - final Value title; - final Value rowid; - const SongsFtsCompanion({ - this.sourceId = const Value.absent(), - this.title = const Value.absent(), - this.rowid = const Value.absent(), - }); - SongsFtsCompanion.insert({ - required String sourceId, - required String title, - this.rowid = const Value.absent(), - }) : sourceId = Value(sourceId), - title = Value(title); - static Insertable custom({ - Expression? sourceId, - Expression? title, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (sourceId != null) 'source_id': sourceId, - if (title != null) 'title': title, - if (rowid != null) 'rowid': rowid, - }); - } - - SongsFtsCompanion copyWith( - {Value? sourceId, Value? title, Value? rowid}) { - return SongsFtsCompanion( - sourceId: sourceId ?? this.sourceId, - title: title ?? this.title, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (sourceId.present) { - map['source_id'] = Variable(sourceId.value); - } - if (title.present) { - map['title'] = Variable(title.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('SongsFtsCompanion(') - ..write('sourceId: $sourceId, ') - ..write('title: $title, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - -abstract class _$SubtracksDatabase extends GeneratedDatabase { - _$SubtracksDatabase(QueryExecutor e) : super(e); - late final Queue queue = Queue(this); - late final Index queueIndex = - Index('queue_index', 'CREATE INDEX queue_index ON queue ("index")'); - late final Index queueCurrentTrack = Index('queue_current_track', - 'CREATE INDEX queue_current_track ON queue (current_track)'); - late final LastAudioState lastAudioState = LastAudioState(this); - late final LastBottomNavState lastBottomNavState = LastBottomNavState(this); - late final LastLibraryState lastLibraryState = LastLibraryState(this); - late final AppSettingsTable appSettings = AppSettingsTable(this); - late final Sources sources = Sources(this); - late final SubsonicSources subsonicSources = SubsonicSources(this); - late final Artists artists = Artists(this); - late final Index artistsSourceId = Index('artists_source_id', - 'CREATE INDEX artists_source_id ON artists (source_id)'); - late final ArtistsFts artistsFts = ArtistsFts(this); - late final Trigger artistsAi = Trigger( - 'CREATE TRIGGER artists_ai AFTER INSERT ON artists BEGIN INSERT INTO artists_fts ("rowid", source_id, name) VALUES (new."rowid", new.source_id, new.name);END', - 'artists_ai'); - late final Trigger artistsAd = Trigger( - 'CREATE TRIGGER artists_ad AFTER DELETE ON artists BEGIN INSERT INTO artists_fts (artists_fts, "rowid", source_id, name) VALUES (\'delete\', old."rowid", old.source_id, old.name);END', - 'artists_ad'); - late final Trigger artistsAu = Trigger( - 'CREATE TRIGGER artists_au AFTER UPDATE ON artists BEGIN INSERT INTO artists_fts (artists_fts, "rowid", source_id, name) VALUES (\'delete\', old."rowid", old.source_id, old.name);INSERT INTO artists_fts ("rowid", source_id, name) VALUES (new."rowid", new.source_id, new.name);END', - 'artists_au'); - late final Albums albums = Albums(this); - late final Index albumsSourceId = Index('albums_source_id', - 'CREATE INDEX albums_source_id ON albums (source_id)'); - late final Index albumsSourceIdArtistIdIdx = Index( - 'albums_source_id_artist_id_idx', - 'CREATE INDEX albums_source_id_artist_id_idx ON albums (source_id, artist_id)'); - late final AlbumsFts albumsFts = AlbumsFts(this); - late final Trigger albumsAi = Trigger( - 'CREATE TRIGGER albums_ai AFTER INSERT ON albums BEGIN INSERT INTO albums_fts ("rowid", source_id, name) VALUES (new."rowid", new.source_id, new.name);END', - 'albums_ai'); - late final Trigger albumsAd = Trigger( - 'CREATE TRIGGER albums_ad AFTER DELETE ON albums BEGIN INSERT INTO albums_fts (albums_fts, "rowid", source_id, name) VALUES (\'delete\', old."rowid", old.source_id, old.name);END', - 'albums_ad'); - late final Trigger albumsAu = Trigger( - 'CREATE TRIGGER albums_au AFTER UPDATE ON albums BEGIN INSERT INTO albums_fts (albums_fts, "rowid", source_id, name) VALUES (\'delete\', old."rowid", old.source_id, old.name);INSERT INTO albums_fts ("rowid", source_id, name) VALUES (new."rowid", new.source_id, new.name);END', - 'albums_au'); - late final Playlists playlists = Playlists(this); - late final Index playlistsSourceId = Index('playlists_source_id', - 'CREATE INDEX playlists_source_id ON playlists (source_id)'); - late final PlaylistSongs playlistSongs = PlaylistSongs(this); - late final Index playlistSongsSourceIdPlaylistIdIdx = Index( - 'playlist_songs_source_id_playlist_id_idx', - 'CREATE INDEX playlist_songs_source_id_playlist_id_idx ON playlist_songs (source_id, playlist_id)'); - late final Index playlistSongsSourceIdSongIdIdx = Index( - 'playlist_songs_source_id_song_id_idx', - 'CREATE INDEX playlist_songs_source_id_song_id_idx ON playlist_songs (source_id, song_id)'); - late final PlaylistsFts playlistsFts = PlaylistsFts(this); - late final Trigger playlistsAi = Trigger( - 'CREATE TRIGGER playlists_ai AFTER INSERT ON playlists BEGIN INSERT INTO playlists_fts ("rowid", source_id, name) VALUES (new."rowid", new.source_id, new.name);END', - 'playlists_ai'); - late final Trigger playlistsAd = Trigger( - 'CREATE TRIGGER playlists_ad AFTER DELETE ON playlists BEGIN INSERT INTO playlists_fts (playlists_fts, "rowid", source_id, name) VALUES (\'delete\', old."rowid", old.source_id, old.name);END', - 'playlists_ad'); - late final Trigger playlistsAu = Trigger( - 'CREATE TRIGGER playlists_au AFTER UPDATE ON playlists BEGIN INSERT INTO playlists_fts (playlists_fts, "rowid", source_id, name) VALUES (\'delete\', old."rowid", old.source_id, old.name);INSERT INTO playlists_fts ("rowid", source_id, name) VALUES (new."rowid", new.source_id, new.name);END', - 'playlists_au'); - late final Songs songs = Songs(this); - late final Index songsSourceIdAlbumIdIdx = Index( - 'songs_source_id_album_id_idx', - 'CREATE INDEX songs_source_id_album_id_idx ON songs (source_id, album_id)'); - late final Index songsSourceIdArtistIdIdx = Index( - 'songs_source_id_artist_id_idx', - 'CREATE INDEX songs_source_id_artist_id_idx ON songs (source_id, artist_id)'); - late final Index songsDownloadTaskIdIdx = Index('songs_download_task_id_idx', - 'CREATE INDEX songs_download_task_id_idx ON songs (download_task_id)'); - late final SongsFts songsFts = SongsFts(this); - late final Trigger songsAi = Trigger( - 'CREATE TRIGGER songs_ai AFTER INSERT ON songs BEGIN INSERT INTO songs_fts ("rowid", source_id, title) VALUES (new."rowid", new.source_id, new.title);END', - 'songs_ai'); - late final Trigger songsAd = Trigger( - 'CREATE TRIGGER songs_ad AFTER DELETE ON songs BEGIN INSERT INTO songs_fts (songs_fts, "rowid", source_id, title) VALUES (\'delete\', old."rowid", old.source_id, old.title);END', - 'songs_ad'); - late final Trigger songsAu = Trigger( - 'CREATE TRIGGER songs_au AFTER UPDATE ON songs BEGIN INSERT INTO songs_fts (songs_fts, "rowid", source_id, title) VALUES (\'delete\', old."rowid", old.source_id, old.title);INSERT INTO songs_fts ("rowid", source_id, title) VALUES (new."rowid", new.source_id, new.title);END', - 'songs_au'); - Selectable sourcesCount() { - return customSelect('SELECT COUNT(*) AS _c0 FROM sources', - variables: [], - readsFrom: { - sources, - }).map((QueryRow row) => row.read('_c0')); - } - - Selectable allSubsonicSources() { - return customSelect( - 'SELECT sources.id, sources.name, sources.address, sources.is_active, sources.created_at, subsonic_sources.features, subsonic_sources.username, subsonic_sources.password, subsonic_sources.use_token_auth FROM sources JOIN subsonic_sources ON subsonic_sources.source_id = sources.id', - variables: [], - readsFrom: { - sources, - subsonicSources, - }).map((QueryRow row) => SubsonicSettings( - id: row.read('id'), - features: SubsonicSources.$converterfeatures - .fromSql(row.read('features')), - name: row.read('name'), - address: - Sources.$converteraddress.fromSql(row.read('address')), - isActive: row.readNullable('is_active'), - createdAt: row.read('created_at'), - username: row.read('username'), - password: row.read('password'), - useTokenAuth: row.read('use_token_auth'), - )); - } - - Selectable albumIdsWithDownloadStatus(int sourceId) { - return customSelect( - 'SELECT albums.id FROM albums JOIN songs ON songs.source_id = albums.source_id AND songs.album_id = albums.id WHERE albums.source_id = ?1 AND(songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)GROUP BY albums.id', - variables: [ - Variable(sourceId) - ], - readsFrom: { - albums, - songs, - }).map((QueryRow row) => row.read('id')); - } - - Selectable artistIdsWithDownloadStatus(int sourceId) { - return customSelect( - 'SELECT artists.id FROM artists LEFT JOIN albums ON artists.source_id = albums.source_id AND artists.id = albums.artist_id LEFT JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id WHERE artists.source_id = ?1 AND(songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)GROUP BY artists.id', - variables: [ - Variable(sourceId) - ], - readsFrom: { - artists, - albums, - songs, - }).map((QueryRow row) => row.read('id')); - } - - Selectable playlistIdsWithDownloadStatus(int sourceId) { - return customSelect( - 'SELECT playlists.id FROM playlists LEFT JOIN playlist_songs ON playlist_songs.source_id = playlists.source_id AND playlist_songs.playlist_id = playlists.id LEFT JOIN songs ON playlist_songs.source_id = songs.source_id AND playlist_songs.song_id = songs.id WHERE playlists.source_id = ?1 AND(songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL)GROUP BY playlists.id', - variables: [ - Variable(sourceId) - ], - readsFrom: { - playlists, - playlistSongs, - songs, - }).map((QueryRow row) => row.read('id')); - } - - Selectable searchArtists(String query, int limit, int offset) { - return customSelect( - 'SELECT "rowid" FROM artists_fts WHERE artists_fts MATCH ?1 ORDER BY rank LIMIT ?2 OFFSET ?3', - variables: [ - Variable(query), - Variable(limit), - Variable(offset) - ], - readsFrom: { - artistsFts, - }).map((QueryRow row) => row.read('rowid')); - } - - Selectable searchAlbums(String query, int limit, int offset) { - return customSelect( - 'SELECT "rowid" FROM albums_fts WHERE albums_fts MATCH ?1 ORDER BY rank LIMIT ?2 OFFSET ?3', - variables: [ - Variable(query), - Variable(limit), - Variable(offset) - ], - readsFrom: { - albumsFts, - }).map((QueryRow row) => row.read('rowid')); - } - - Selectable searchPlaylists(String query, int limit, int offset) { - return customSelect( - 'SELECT "rowid" FROM playlists_fts WHERE playlists_fts MATCH ?1 ORDER BY rank LIMIT ?2 OFFSET ?3', - variables: [ - Variable(query), - Variable(limit), - Variable(offset) - ], - readsFrom: { - playlistsFts, - }).map((QueryRow row) => row.read('rowid')); - } - - Selectable searchSongs(String query, int limit, int offset) { - return customSelect( - 'SELECT "rowid" FROM songs_fts WHERE songs_fts MATCH ?1 ORDER BY rank LIMIT ?2 OFFSET ?3', - variables: [ - Variable(query), - Variable(limit), - Variable(offset) - ], - readsFrom: { - songsFts, - }).map((QueryRow row) => row.read('rowid')); - } - - Selectable artistById(int sourceId, String id) { - return customSelect( - 'SELECT * FROM artists WHERE source_id = ?1 AND id = ?2', - variables: [ - Variable(sourceId), - Variable(id) - ], - readsFrom: { - artists, - }).asyncMap(artists.mapFromRow); - } - - Selectable albumById(int sourceId, String id) { - return customSelect('SELECT * FROM albums WHERE source_id = ?1 AND id = ?2', - variables: [ - Variable(sourceId), - Variable(id) - ], - readsFrom: { - albums, - }).asyncMap(albums.mapFromRow); - } - - Selectable albumsByArtistId(int sourceId, String? artistId) { - return customSelect( - 'SELECT * FROM albums WHERE source_id = ?1 AND artist_id = ?2', - variables: [ - Variable(sourceId), - Variable(artistId) - ], - readsFrom: { - albums, - }).asyncMap(albums.mapFromRow); - } - - Selectable albumsInIds(int sourceId, List ids) { - var $arrayStartIndex = 2; - final expandedids = $expandVar($arrayStartIndex, ids.length); - $arrayStartIndex += ids.length; - return customSelect( - 'SELECT * FROM albums WHERE source_id = ?1 AND id IN ($expandedids)', - variables: [ - Variable(sourceId), - for (var $ in ids) Variable($) - ], - readsFrom: { - albums, - }).asyncMap(albums.mapFromRow); - } - - Selectable playlistById(int sourceId, String id) { - return customSelect( - 'SELECT * FROM playlists WHERE source_id = ?1 AND id = ?2', - variables: [ - Variable(sourceId), - Variable(id) - ], - readsFrom: { - playlists, - }).asyncMap(playlists.mapFromRow); - } - - Selectable songById(int sourceId, String id) { - return customSelect('SELECT * FROM songs WHERE source_id = ?1 AND id = ?2', - variables: [ - Variable(sourceId), - Variable(id) - ], - readsFrom: { - songs, - }).asyncMap(songs.mapFromRow); - } - - Selectable albumGenres(int sourceId, int limit, int offset) { - return customSelect( - 'SELECT genre FROM albums WHERE genre IS NOT NULL AND source_id = ?1 GROUP BY genre ORDER BY COUNT(genre) DESC LIMIT ?2 OFFSET ?3', - variables: [ - Variable(sourceId), - Variable(limit), - Variable(offset) - ], - readsFrom: { - albums, - }).map((QueryRow row) => row.readNullable('genre')); - } - - Selectable albumsByGenre( - int sourceId, String? genre, int limit, int offset) { - return customSelect( - 'SELECT albums.* FROM albums JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id WHERE songs.source_id = ?1 AND songs.genre = ?2 GROUP BY albums.id ORDER BY albums.created DESC, albums.name LIMIT ?3 OFFSET ?4', - variables: [ - Variable(sourceId), - Variable(genre), - Variable(limit), - Variable(offset) - ], - readsFrom: { - albums, - songs, - }).asyncMap(albums.mapFromRow); - } - - Selectable filterSongsByGenre(FilterSongsByGenre$predicate predicate, - FilterSongsByGenre$order order, FilterSongsByGenre$limit limit) { - var $arrayStartIndex = 1; - final generatedpredicate = $write(predicate(this.songs, this.albums), - hasMultipleTables: true, startIndex: $arrayStartIndex); - $arrayStartIndex += generatedpredicate.amountOfVariables; - final generatedorder = $write( - order?.call(this.songs, this.albums) ?? const OrderBy.nothing(), - hasMultipleTables: true, - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedorder.amountOfVariables; - final generatedlimit = $write(limit(this.songs, this.albums), - hasMultipleTables: true, startIndex: $arrayStartIndex); - $arrayStartIndex += generatedlimit.amountOfVariables; - return customSelect( - 'SELECT songs.* FROM songs JOIN albums ON albums.source_id = songs.source_id AND albums.id = songs.album_id WHERE ${generatedpredicate.sql} ${generatedorder.sql} ${generatedlimit.sql}', - variables: [ - ...generatedpredicate.introducedVariables, - ...generatedorder.introducedVariables, - ...generatedlimit.introducedVariables - ], - readsFrom: { - songs, - albums, - ...generatedpredicate.watchedTables, - ...generatedorder.watchedTables, - ...generatedlimit.watchedTables, - }).asyncMap(songs.mapFromRow); - } - - Selectable songsByGenreCount(int sourceId, String? genre) { - return customSelect( - 'SELECT COUNT(*) AS _c0 FROM songs WHERE songs.source_id = ?1 AND songs.genre = ?2', - variables: [ - Variable(sourceId), - Variable(genre) - ], - readsFrom: { - songs, - }).map((QueryRow row) => row.read('_c0')); - } - - Selectable songsWithDownloadTasks() { - return customSelect( - 'SELECT * FROM songs WHERE download_task_id IS NOT NULL', - variables: [], - readsFrom: { - songs, - }).asyncMap(songs.mapFromRow); - } - - Selectable songByDownloadTask(String? taskId) { - return customSelect('SELECT * FROM songs WHERE download_task_id = ?1', - variables: [ - Variable(taskId) - ], - readsFrom: { - songs, - }).asyncMap(songs.mapFromRow); - } - - Future clearSongDownloadTaskBySong(int sourceId, String id) { - return customUpdate( - 'UPDATE songs SET download_task_id = NULL WHERE source_id = ?1 AND id = ?2', - variables: [Variable(sourceId), Variable(id)], - updates: {songs}, - updateKind: UpdateKind.update, - ); - } - - Future completeSongDownload(String? filePath, String? taskId) { - return customUpdate( - 'UPDATE songs SET download_task_id = NULL, download_file_path = ?1 WHERE download_task_id = ?2', - variables: [Variable(filePath), Variable(taskId)], - updates: {songs}, - updateKind: UpdateKind.update, - ); - } - - Future clearSongDownloadTask(String? taskId) { - return customUpdate( - 'UPDATE songs SET download_task_id = NULL, download_file_path = NULL WHERE download_task_id = ?1', - variables: [Variable(taskId)], - updates: {songs}, - updateKind: UpdateKind.update, - ); - } - - Future updateSongDownloadTask(String? taskId, int sourceId, String id) { - return customUpdate( - 'UPDATE songs SET download_task_id = ?1 WHERE source_id = ?2 AND id = ?3', - variables: [ - Variable(taskId), - Variable(sourceId), - Variable(id) - ], - updates: {songs}, - updateKind: UpdateKind.update, - ); - } - - Future deleteSongDownloadFile(int sourceId, String id) { - return customUpdate( - 'UPDATE songs SET download_task_id = NULL, download_file_path = NULL WHERE source_id = ?1 AND id = ?2', - variables: [Variable(sourceId), Variable(id)], - updates: {songs}, - updateKind: UpdateKind.update, - ); - } - - Selectable albumDownloadStatus(int sourceId, String id) { - return customSelect( - 'SELECT COUNT(*) AS total, COUNT(CASE WHEN songs.download_file_path IS NOT NULL THEN songs.id ELSE NULL END) AS downloaded, COUNT(CASE WHEN songs.download_task_id IS NOT NULL THEN songs.id ELSE NULL END) AS downloading FROM albums JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id WHERE albums.source_id = ?1 AND albums.id = ?2', - variables: [ - Variable(sourceId), - Variable(id) - ], - readsFrom: { - songs, - albums, - }).map((QueryRow row) => ListDownloadStatus( - total: row.read('total'), - downloaded: row.read('downloaded'), - downloading: row.read('downloading'), - )); - } - - Selectable playlistDownloadStatus( - int sourceId, String id) { - return customSelect( - 'SELECT COUNT(DISTINCT songs.id) AS total, COUNT(DISTINCT CASE WHEN songs.download_file_path IS NOT NULL THEN songs.id ELSE NULL END) AS downloaded, COUNT(DISTINCT CASE WHEN songs.download_task_id IS NOT NULL THEN songs.id ELSE NULL END) AS downloading FROM playlists JOIN playlist_songs ON playlist_songs.source_id = playlists.source_id AND playlist_songs.playlist_id = playlists.id JOIN songs ON songs.source_id = playlist_songs.source_id AND songs.id = playlist_songs.song_id WHERE playlists.source_id = ?1 AND playlists.id = ?2', - variables: [ - Variable(sourceId), - Variable(id) - ], - readsFrom: { - songs, - playlists, - playlistSongs, - }).map((QueryRow row) => ListDownloadStatus( - total: row.read('total'), - downloaded: row.read('downloaded'), - downloading: row.read('downloading'), - )); - } - - Selectable filterAlbums(FilterAlbums$predicate predicate, - FilterAlbums$order order, FilterAlbums$limit limit) { - var $arrayStartIndex = 1; - final generatedpredicate = - $write(predicate(this.albums), startIndex: $arrayStartIndex); - $arrayStartIndex += generatedpredicate.amountOfVariables; - final generatedorder = $write( - order?.call(this.albums) ?? const OrderBy.nothing(), - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedorder.amountOfVariables; - final generatedlimit = - $write(limit(this.albums), startIndex: $arrayStartIndex); - $arrayStartIndex += generatedlimit.amountOfVariables; - return customSelect( - 'SELECT albums.* FROM albums WHERE ${generatedpredicate.sql} ${generatedorder.sql} ${generatedlimit.sql}', - variables: [ - ...generatedpredicate.introducedVariables, - ...generatedorder.introducedVariables, - ...generatedlimit.introducedVariables - ], - readsFrom: { - albums, - ...generatedpredicate.watchedTables, - ...generatedorder.watchedTables, - ...generatedlimit.watchedTables, - }).asyncMap(albums.mapFromRow); - } - - Selectable filterAlbumsDownloaded( - FilterAlbumsDownloaded$predicate predicate, - FilterAlbumsDownloaded$order order, - FilterAlbumsDownloaded$limit limit) { - var $arrayStartIndex = 1; - final generatedpredicate = $write(predicate(this.albums, this.songs), - hasMultipleTables: true, startIndex: $arrayStartIndex); - $arrayStartIndex += generatedpredicate.amountOfVariables; - final generatedorder = $write( - order?.call(this.albums, this.songs) ?? const OrderBy.nothing(), - hasMultipleTables: true, - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedorder.amountOfVariables; - final generatedlimit = $write(limit(this.albums, this.songs), - hasMultipleTables: true, startIndex: $arrayStartIndex); - $arrayStartIndex += generatedlimit.amountOfVariables; - return customSelect( - 'SELECT albums.* FROM albums LEFT JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id WHERE ${generatedpredicate.sql} GROUP BY albums.source_id, albums.id HAVING SUM(CASE WHEN songs.download_file_path IS NOT NULL THEN 1 ELSE 0 END) > 0 ${generatedorder.sql} ${generatedlimit.sql}', - variables: [ - ...generatedpredicate.introducedVariables, - ...generatedorder.introducedVariables, - ...generatedlimit.introducedVariables - ], - readsFrom: { - albums, - songs, - ...generatedpredicate.watchedTables, - ...generatedorder.watchedTables, - ...generatedlimit.watchedTables, - }).asyncMap(albums.mapFromRow); - } - - Selectable filterArtists(FilterArtists$predicate predicate, - FilterArtists$order order, FilterArtists$limit limit) { - var $arrayStartIndex = 1; - final generatedpredicate = - $write(predicate(this.artists), startIndex: $arrayStartIndex); - $arrayStartIndex += generatedpredicate.amountOfVariables; - final generatedorder = $write( - order?.call(this.artists) ?? const OrderBy.nothing(), - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedorder.amountOfVariables; - final generatedlimit = - $write(limit(this.artists), startIndex: $arrayStartIndex); - $arrayStartIndex += generatedlimit.amountOfVariables; - return customSelect( - 'SELECT artists.* FROM artists WHERE ${generatedpredicate.sql} ${generatedorder.sql} ${generatedlimit.sql}', - variables: [ - ...generatedpredicate.introducedVariables, - ...generatedorder.introducedVariables, - ...generatedlimit.introducedVariables - ], - readsFrom: { - artists, - ...generatedpredicate.watchedTables, - ...generatedorder.watchedTables, - ...generatedlimit.watchedTables, - }).asyncMap(artists.mapFromRow); - } - - Selectable filterArtistsDownloaded( - FilterArtistsDownloaded$predicate predicate, - FilterArtistsDownloaded$order order, - FilterArtistsDownloaded$limit limit) { - var $arrayStartIndex = 1; - final generatedpredicate = $write( - predicate(this.artists, this.albums, this.songs), - hasMultipleTables: true, - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedpredicate.amountOfVariables; - final generatedorder = $write( - order?.call(this.artists, this.albums, this.songs) ?? - const OrderBy.nothing(), - hasMultipleTables: true, - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedorder.amountOfVariables; - final generatedlimit = $write(limit(this.artists, this.albums, this.songs), - hasMultipleTables: true, startIndex: $arrayStartIndex); - $arrayStartIndex += generatedlimit.amountOfVariables; - return customSelect( - 'SELECT artists.*, COUNT(DISTINCT CASE WHEN songs.download_file_path IS NOT NULL THEN songs.album_id ELSE NULL END) AS album_count FROM artists LEFT JOIN albums ON artists.source_id = albums.source_id AND artists.id = albums.artist_id LEFT JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id WHERE ${generatedpredicate.sql} GROUP BY artists.source_id, artists.id HAVING SUM(CASE WHEN songs.download_file_path IS NOT NULL THEN 1 ELSE 0 END) > 0 ${generatedorder.sql} ${generatedlimit.sql}', - variables: [ - ...generatedpredicate.introducedVariables, - ...generatedorder.introducedVariables, - ...generatedlimit.introducedVariables - ], - readsFrom: { - songs, - artists, - albums, - ...generatedpredicate.watchedTables, - ...generatedorder.watchedTables, - ...generatedlimit.watchedTables, - }).map((QueryRow row) => Artist( - sourceId: row.read('source_id'), - id: row.read('id'), - name: row.read('name'), - albumCount: row.read('album_count'), - starred: row.readNullable('starred'), - )); - } - - Selectable filterPlaylists(FilterPlaylists$predicate predicate, - FilterPlaylists$order order, FilterPlaylists$limit limit) { - var $arrayStartIndex = 1; - final generatedpredicate = - $write(predicate(this.playlists), startIndex: $arrayStartIndex); - $arrayStartIndex += generatedpredicate.amountOfVariables; - final generatedorder = $write( - order?.call(this.playlists) ?? const OrderBy.nothing(), - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedorder.amountOfVariables; - final generatedlimit = - $write(limit(this.playlists), startIndex: $arrayStartIndex); - $arrayStartIndex += generatedlimit.amountOfVariables; - return customSelect( - 'SELECT playlists.* FROM playlists WHERE ${generatedpredicate.sql} ${generatedorder.sql} ${generatedlimit.sql}', - variables: [ - ...generatedpredicate.introducedVariables, - ...generatedorder.introducedVariables, - ...generatedlimit.introducedVariables - ], - readsFrom: { - playlists, - ...generatedpredicate.watchedTables, - ...generatedorder.watchedTables, - ...generatedlimit.watchedTables, - }).asyncMap(playlists.mapFromRow); - } - - Selectable filterPlaylistsDownloaded( - FilterPlaylistsDownloaded$predicate predicate, - FilterPlaylistsDownloaded$order order, - FilterPlaylistsDownloaded$limit limit) { - var $arrayStartIndex = 1; - final generatedpredicate = $write( - predicate(this.playlists, this.playlistSongs, this.songs), - hasMultipleTables: true, - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedpredicate.amountOfVariables; - final generatedorder = $write( - order?.call(this.playlists, this.playlistSongs, this.songs) ?? - const OrderBy.nothing(), - hasMultipleTables: true, - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedorder.amountOfVariables; - final generatedlimit = $write( - limit(this.playlists, this.playlistSongs, this.songs), - hasMultipleTables: true, - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedlimit.amountOfVariables; - return customSelect( - 'SELECT playlists.*, COUNT(CASE WHEN songs.download_file_path IS NOT NULL THEN songs.id ELSE NULL END) AS song_count FROM playlists LEFT JOIN playlist_songs ON playlist_songs.source_id = playlists.source_id AND playlist_songs.playlist_id = playlists.id LEFT JOIN songs ON playlist_songs.source_id = songs.source_id AND playlist_songs.song_id = songs.id WHERE ${generatedpredicate.sql} GROUP BY playlists.source_id, playlists.id HAVING SUM(CASE WHEN songs.download_file_path IS NOT NULL THEN 1 ELSE 0 END) > 0 ${generatedorder.sql} ${generatedlimit.sql}', - variables: [ - ...generatedpredicate.introducedVariables, - ...generatedorder.introducedVariables, - ...generatedlimit.introducedVariables - ], - readsFrom: { - songs, - playlists, - playlistSongs, - ...generatedpredicate.watchedTables, - ...generatedorder.watchedTables, - ...generatedlimit.watchedTables, - }).map((QueryRow row) => Playlist( - sourceId: row.read('source_id'), - id: row.read('id'), - name: row.read('name'), - comment: row.readNullable('comment'), - coverArt: row.readNullable('cover_art'), - songCount: row.read('song_count'), - created: row.read('created'), - )); - } - - Selectable filterSongs(FilterSongs$predicate predicate, - FilterSongs$order order, FilterSongs$limit limit) { - var $arrayStartIndex = 1; - final generatedpredicate = - $write(predicate(this.songs), startIndex: $arrayStartIndex); - $arrayStartIndex += generatedpredicate.amountOfVariables; - final generatedorder = $write( - order?.call(this.songs) ?? const OrderBy.nothing(), - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedorder.amountOfVariables; - final generatedlimit = - $write(limit(this.songs), startIndex: $arrayStartIndex); - $arrayStartIndex += generatedlimit.amountOfVariables; - return customSelect( - 'SELECT songs.* FROM songs WHERE ${generatedpredicate.sql} ${generatedorder.sql} ${generatedlimit.sql}', - variables: [ - ...generatedpredicate.introducedVariables, - ...generatedorder.introducedVariables, - ...generatedlimit.introducedVariables - ], - readsFrom: { - songs, - ...generatedpredicate.watchedTables, - ...generatedorder.watchedTables, - ...generatedlimit.watchedTables, - }).asyncMap(songs.mapFromRow); - } - - Selectable filterSongsDownloaded( - FilterSongsDownloaded$predicate predicate, - FilterSongsDownloaded$order order, - FilterSongsDownloaded$limit limit) { - var $arrayStartIndex = 1; - final generatedpredicate = - $write(predicate(this.songs), startIndex: $arrayStartIndex); - $arrayStartIndex += generatedpredicate.amountOfVariables; - final generatedorder = $write( - order?.call(this.songs) ?? const OrderBy.nothing(), - startIndex: $arrayStartIndex); - $arrayStartIndex += generatedorder.amountOfVariables; - final generatedlimit = - $write(limit(this.songs), startIndex: $arrayStartIndex); - $arrayStartIndex += generatedlimit.amountOfVariables; - return customSelect( - 'SELECT songs.* FROM songs WHERE ${generatedpredicate.sql} AND songs.download_file_path IS NOT NULL ${generatedorder.sql} ${generatedlimit.sql}', - variables: [ - ...generatedpredicate.introducedVariables, - ...generatedorder.introducedVariables, - ...generatedlimit.introducedVariables - ], - readsFrom: { - songs, - ...generatedpredicate.watchedTables, - ...generatedorder.watchedTables, - ...generatedlimit.watchedTables, - }).asyncMap(songs.mapFromRow); - } - - Selectable playlistIsDownloaded(int sourceId, String id) { - return customSelect( - 'SELECT COUNT(*) = 0 AS _c0 FROM playlists JOIN playlist_songs ON playlist_songs.source_id = playlists.source_id AND playlist_songs.playlist_id = playlists.id JOIN songs ON songs.source_id = playlist_songs.source_id AND songs.id = playlist_songs.song_id WHERE playlists.source_id = ?1 AND playlists.id = ?2 AND songs.download_file_path IS NULL', - variables: [ - Variable(sourceId), - Variable(id) - ], - readsFrom: { - playlists, - playlistSongs, - songs, - }).map((QueryRow row) => row.read('_c0')); - } - - Selectable playlistHasDownloadsInProgress(int sourceId, String id) { - return customSelect( - 'SELECT COUNT(*) > 0 AS _c0 FROM playlists JOIN playlist_songs ON playlist_songs.source_id = playlists.source_id AND playlist_songs.playlist_id = playlists.id JOIN songs ON songs.source_id = playlist_songs.source_id AND songs.id = playlist_songs.song_id WHERE playlists.source_id = ?1 AND playlists.id = ?2 AND songs.download_task_id IS NOT NULL', - variables: [ - Variable(sourceId), - Variable(id) - ], - readsFrom: { - playlists, - playlistSongs, - songs, - }).map((QueryRow row) => row.read('_c0')); - } - - Selectable songsInIds(int sourceId, List ids) { - var $arrayStartIndex = 2; - final expandedids = $expandVar($arrayStartIndex, ids.length); - $arrayStartIndex += ids.length; - return customSelect( - 'SELECT * FROM songs WHERE source_id = ?1 AND id IN ($expandedids)', - variables: [ - Variable(sourceId), - for (var $ in ids) Variable($) - ], - readsFrom: { - songs, - }).asyncMap(songs.mapFromRow); - } - - Selectable songsInRowIds(List rowIds) { - var $arrayStartIndex = 1; - final expandedrowIds = $expandVar($arrayStartIndex, rowIds.length); - $arrayStartIndex += rowIds.length; - return customSelect( - 'SELECT * FROM songs WHERE "ROWID" IN ($expandedrowIds)', - variables: [ - for (var $ in rowIds) Variable($) - ], - readsFrom: { - songs, - }).asyncMap(songs.mapFromRow); - } - - Selectable albumsInRowIds(List rowIds) { - var $arrayStartIndex = 1; - final expandedrowIds = $expandVar($arrayStartIndex, rowIds.length); - $arrayStartIndex += rowIds.length; - return customSelect( - 'SELECT * FROM albums WHERE "ROWID" IN ($expandedrowIds)', - variables: [ - for (var $ in rowIds) Variable($) - ], - readsFrom: { - albums, - }).asyncMap(albums.mapFromRow); - } - - Selectable artistsInRowIds(List rowIds) { - var $arrayStartIndex = 1; - final expandedrowIds = $expandVar($arrayStartIndex, rowIds.length); - $arrayStartIndex += rowIds.length; - return customSelect( - 'SELECT * FROM artists WHERE "ROWID" IN ($expandedrowIds)', - variables: [ - for (var $ in rowIds) Variable($) - ], - readsFrom: { - artists, - }).asyncMap(artists.mapFromRow); - } - - Selectable playlistsInRowIds(List rowIds) { - var $arrayStartIndex = 1; - final expandedrowIds = $expandVar($arrayStartIndex, rowIds.length); - $arrayStartIndex += rowIds.length; - return customSelect( - 'SELECT * FROM playlists WHERE "ROWID" IN ($expandedrowIds)', - variables: [ - for (var $ in rowIds) Variable($) - ], - readsFrom: { - playlists, - }).asyncMap(playlists.mapFromRow); - } - - Selectable currentTrackIndex() { - return customSelect( - 'SELECT queue."index" FROM queue WHERE queue.current_track = 1', - variables: [], - readsFrom: { - queue, - }).map((QueryRow row) => row.read('index')); - } - - Selectable queueLength() { - return customSelect('SELECT COUNT(*) AS _c0 FROM queue', - variables: [], - readsFrom: { - queue, - }).map((QueryRow row) => row.read('_c0')); - } - - Selectable queueInIndicies(List indicies) { - var $arrayStartIndex = 1; - final expandedindicies = $expandVar($arrayStartIndex, indicies.length); - $arrayStartIndex += indicies.length; - return customSelect( - 'SELECT * FROM queue WHERE queue."index" IN ($expandedindicies)', - variables: [ - for (var $ in indicies) Variable($) - ], - readsFrom: { - queue, - }).asyncMap(queue.mapFromRow); - } - - Selectable getAppSettings() { - return customSelect('SELECT * FROM app_settings WHERE id = 1', - variables: [], - readsFrom: { - appSettings, - }).asyncMap(appSettings.mapFromRow); - } - - @override - Iterable> get allTables => - allSchemaEntities.whereType>(); - @override - List get allSchemaEntities => [ - queue, - queueIndex, - queueCurrentTrack, - lastAudioState, - lastBottomNavState, - lastLibraryState, - appSettings, - sources, - subsonicSources, - artists, - artistsSourceId, - artistsFts, - artistsAi, - artistsAd, - artistsAu, - albums, - albumsSourceId, - albumsSourceIdArtistIdIdx, - albumsFts, - albumsAi, - albumsAd, - albumsAu, - playlists, - playlistsSourceId, - playlistSongs, - playlistSongsSourceIdPlaylistIdIdx, - playlistSongsSourceIdSongIdIdx, - playlistsFts, - playlistsAi, - playlistsAd, - playlistsAu, - songs, - songsSourceIdAlbumIdIdx, - songsSourceIdArtistIdIdx, - songsDownloadTaskIdIdx, - songsFts, - songsAi, - songsAd, - songsAu - ]; - @override - StreamQueryUpdateRules get streamUpdateRules => const StreamQueryUpdateRules( - [ - WritePropagation( - on: TableUpdateQuery.onTableName('sources', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('subsonic_sources', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('sources', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('artists', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('artists', - limitUpdateKind: UpdateKind.insert), - result: [ - TableUpdate('artists_fts', kind: UpdateKind.insert), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('artists', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('artists_fts', kind: UpdateKind.insert), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('artists', - limitUpdateKind: UpdateKind.update), - result: [ - TableUpdate('artists_fts', kind: UpdateKind.insert), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('sources', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('albums', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('albums', - limitUpdateKind: UpdateKind.insert), - result: [ - TableUpdate('albums_fts', kind: UpdateKind.insert), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('albums', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('albums_fts', kind: UpdateKind.insert), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('albums', - limitUpdateKind: UpdateKind.update), - result: [ - TableUpdate('albums_fts', kind: UpdateKind.insert), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('sources', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('playlists', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('sources', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('playlist_songs', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('playlists', - limitUpdateKind: UpdateKind.insert), - result: [ - TableUpdate('playlists_fts', kind: UpdateKind.insert), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('playlists', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('playlists_fts', kind: UpdateKind.insert), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('playlists', - limitUpdateKind: UpdateKind.update), - result: [ - TableUpdate('playlists_fts', kind: UpdateKind.insert), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('sources', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('songs', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('songs', - limitUpdateKind: UpdateKind.insert), - result: [ - TableUpdate('songs_fts', kind: UpdateKind.insert), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('songs', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('songs_fts', kind: UpdateKind.insert), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('songs', - limitUpdateKind: UpdateKind.update), - result: [ - TableUpdate('songs_fts', kind: UpdateKind.insert), - ], - ), - ], - ); -} - -typedef FilterSongsByGenre$predicate = Expression Function( - Songs songs, Albums albums); -typedef FilterSongsByGenre$order = OrderBy Function(Songs songs, Albums albums); -typedef FilterSongsByGenre$limit = Limit Function(Songs songs, Albums albums); -typedef FilterAlbums$predicate = Expression Function(Albums albums); -typedef FilterAlbums$order = OrderBy Function(Albums albums); -typedef FilterAlbums$limit = Limit Function(Albums albums); -typedef FilterAlbumsDownloaded$predicate = Expression Function( - Albums albums, Songs songs); -typedef FilterAlbumsDownloaded$order = OrderBy Function( - Albums albums, Songs songs); -typedef FilterAlbumsDownloaded$limit = Limit Function( - Albums albums, Songs songs); -typedef FilterArtists$predicate = Expression Function(Artists artists); -typedef FilterArtists$order = OrderBy Function(Artists artists); -typedef FilterArtists$limit = Limit Function(Artists artists); -typedef FilterArtistsDownloaded$predicate = Expression Function( - Artists artists, Albums albums, Songs songs); -typedef FilterArtistsDownloaded$order = OrderBy Function( - Artists artists, Albums albums, Songs songs); -typedef FilterArtistsDownloaded$limit = Limit Function( - Artists artists, Albums albums, Songs songs); -typedef FilterPlaylists$predicate = Expression Function( - Playlists playlists); -typedef FilterPlaylists$order = OrderBy Function(Playlists playlists); -typedef FilterPlaylists$limit = Limit Function(Playlists playlists); -typedef FilterPlaylistsDownloaded$predicate = Expression Function( - Playlists playlists, PlaylistSongs playlist_songs, Songs songs); -typedef FilterPlaylistsDownloaded$order = OrderBy Function( - Playlists playlists, PlaylistSongs playlist_songs, Songs songs); -typedef FilterPlaylistsDownloaded$limit = Limit Function( - Playlists playlists, PlaylistSongs playlist_songs, Songs songs); -typedef FilterSongs$predicate = Expression Function(Songs songs); -typedef FilterSongs$order = OrderBy Function(Songs songs); -typedef FilterSongs$limit = Limit Function(Songs songs); -typedef FilterSongsDownloaded$predicate = Expression Function( - Songs songs); -typedef FilterSongsDownloaded$order = OrderBy Function(Songs songs); -typedef FilterSongsDownloaded$limit = Limit Function(Songs songs); - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$databaseHash() => r'04ae05f49039a6c77afa45892f4e5e0fad7d20c6'; - -/// See also [database]. -@ProviderFor(database) -final databaseProvider = Provider.internal( - database, - name: r'databaseProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$databaseHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef DatabaseRef = ProviderRef; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/database/error_logging_database.dart b/lib/database/error_logging_database.dart deleted file mode 100644 index 6789bd05..00000000 --- a/lib/database/error_logging_database.dart +++ /dev/null @@ -1,94 +0,0 @@ -import 'dart:async'; - -import 'package:drift/drift.dart'; -import 'package:drift/isolate.dart'; - -/// https://github.com/simolus3/drift/issues/2326#issuecomment-1445138730 -class ErrorLoggingDatabase implements QueryExecutor { - final QueryExecutor inner; - final void Function(Object, StackTrace) onError; - - ErrorLoggingDatabase(this.inner, this.onError); - - Future _handleErrors(Future Function() body) { - return Future.sync(body) - .onError((error, stackTrace) { - onError(error, error.trace ?? stackTrace); - throw error; - }).onError((error, stackTrace) { - onError(error, error.remoteStackTrace ?? stackTrace); - throw error; - }); - } - - @override - TransactionExecutor beginTransaction() { - return _ErrorLoggingTransactionExecutor(inner.beginTransaction(), onError); - } - - @override - Future close() { - return _handleErrors(inner.close); - } - - @override - SqlDialect get dialect => inner.dialect; - - @override - Future ensureOpen(QueryExecutorUser user) { - return _handleErrors(() => inner.ensureOpen(user)); - } - - @override - Future runBatched(BatchedStatements statements) { - return _handleErrors(() => inner.runBatched(statements)); - } - - @override - Future runCustom(String statement, [List? args]) { - return _handleErrors(() => inner.runCustom(statement, args)); - } - - @override - Future runDelete(String statement, List args) { - return _handleErrors(() => inner.runDelete(statement, args)); - } - - @override - Future runInsert(String statement, List args) { - return _handleErrors(() => inner.runInsert(statement, args)); - } - - @override - Future>> runSelect( - String statement, List args) { - return _handleErrors(() => inner.runSelect(statement, args)); - } - - @override - Future runUpdate(String statement, List args) { - return _handleErrors(() => inner.runUpdate(statement, args)); - } -} - -class _ErrorLoggingTransactionExecutor extends ErrorLoggingDatabase - implements TransactionExecutor { - final TransactionExecutor transaction; - - _ErrorLoggingTransactionExecutor( - this.transaction, void Function(Object, StackTrace) onError) - : super(transaction, onError); - - @override - Future rollback() { - return _handleErrors(transaction.rollback); - } - - @override - Future send() { - return _handleErrors(transaction.send); - } - - @override - bool get supportsNestedTransactions => transaction.supportsNestedTransactions; -} diff --git a/lib/database/tables.drift b/lib/database/tables.drift deleted file mode 100644 index d013027d..00000000 --- a/lib/database/tables.drift +++ /dev/null @@ -1,567 +0,0 @@ -import '../models/music.dart'; -import '../models/settings.dart'; -import '../models/support.dart'; -import 'converters.dart'; - --- --- SCHEMA --- - -CREATE TABLE queue( - "index" INT NOT NULL PRIMARY KEY UNIQUE, - source_id INT NOT NULL, - id TEXT NOT NULL, - context ENUM(QueueContextType) NOT NULL, - context_id TEXT, - current_track BOOLEAN UNIQUE -); -CREATE INDEX queue_index ON queue ("index"); -CREATE INDEX queue_current_track ON queue ("current_track"); - -CREATE TABLE last_audio_state( - id INT NOT NULL PRIMARY KEY, - queue_mode ENUM(QueueMode) NOT NULL, - shuffle_indicies TEXT MAPPED BY `const IListIntConverter()`, - repeat ENUM(RepeatMode) NOT NULL -); - -CREATE TABLE last_bottom_nav_state( - id INT NOT NULL PRIMARY KEY, - tab TEXT NOT NULL -); - -CREATE TABLE last_library_state( - id INT NOT NULL PRIMARY KEY, - tab TEXT NOT NULL, - albums_list TEXT NOT NULL MAPPED BY `const ListQueryConverter()`, - artists_list TEXT NOT NULL MAPPED BY `const ListQueryConverter()`, - playlists_list TEXT NOT NULL MAPPED BY `const ListQueryConverter()`, - songs_list TEXT NOT NULL MAPPED BY `const ListQueryConverter()` -); - -CREATE TABLE app_settings( - id INT NOT NULL PRIMARY KEY, - max_bitrate_wifi INT NOT NULL, - max_bitrate_mobile INT NOT NULL, - stream_format TEXT -) WITH AppSettings; - -CREATE TABLE sources( - id INT NOT NULL PRIMARY KEY AUTOINCREMENT, - name TEXT NOT NULL COLLATE NOCASE, - address TEXT NOT NULL MAPPED BY `const UriConverter()`, - is_active BOOLEAN UNIQUE, - created_at DATETIME NOT NULL DEFAULT (strftime('%s', CURRENT_TIMESTAMP)) -); - -CREATE TABLE subsonic_sources( - source_id INT NOT NULL PRIMARY KEY, - features TEXT NOT NULL MAPPED BY `const SubsonicFeatureListConverter()`, - username TEXT NOT NULL, - password TEXT NOT NULL, - use_token_auth BOOLEAN NOT NULL DEFAULT 1, - FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE -); - -CREATE TABLE artists( - source_id INT NOT NULL, - id TEXT NOT NULL, - name TEXT NOT NULL COLLATE NOCASE, - album_count INT NOT NULL, - starred DATETIME, - updated DATETIME NOT NULL DEFAULT (strftime('%s', CURRENT_TIMESTAMP)), - PRIMARY KEY (source_id, id), - FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE -) WITH Artist; -CREATE INDEX artists_source_id ON artists (source_id); - -CREATE VIRTUAL TABLE artists_fts USING fts5(source_id, name, content=artists, content_rowid=rowid); - -CREATE TRIGGER artists_ai AFTER INSERT ON artists BEGIN - INSERT INTO artists_fts(rowid, source_id, name) - VALUES (new.rowid, new.source_id, new.name); -END; - -CREATE TRIGGER artists_ad AFTER DELETE ON artists BEGIN - INSERT INTO artists_fts(artists_fts, rowid, source_id, name) - VALUES('delete', old.rowid, old.source_id, old.name); -END; - -CREATE TRIGGER artists_au AFTER UPDATE ON artists BEGIN - INSERT INTO artists_fts(artists_fts, rowid, source_id, name) - VALUES('delete', old.rowid, old.source_id, old.name); - INSERT INTO artists_fts(rowid, source_id, name) - VALUES (new.rowid, new.source_id, new.name); -END; - -CREATE TABLE albums( - source_id INT NOT NULL, - id TEXT NOT NULL, - artist_id TEXT, - name TEXT NOT NULL COLLATE NOCASE, - album_artist TEXT COLLATE NOCASE, - created DATETIME NOT NULL, - cover_art TEXT, - genre TEXT, - year INT, - starred DATETIME, - song_count INT NOT NULL, - frequent_rank INT, - recent_rank INT, - is_deleted BOOLEAN NOT NULL DEFAULT 0, - updated DATETIME NOT NULL DEFAULT (strftime('%s', CURRENT_TIMESTAMP)), - PRIMARY KEY (source_id, id), - FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE -) WITH Album; -CREATE INDEX albums_source_id ON albums (source_id); -CREATE INDEX albums_source_id_artist_id_idx ON albums (source_id, artist_id); - -CREATE VIRTUAL TABLE albums_fts USING fts5(source_id, name, content=albums, content_rowid=rowid); - -CREATE TRIGGER albums_ai AFTER INSERT ON albums BEGIN - INSERT INTO albums_fts(rowid, source_id, name) - VALUES (new.rowid, new.source_id, new.name); -END; - -CREATE TRIGGER albums_ad AFTER DELETE ON albums BEGIN - INSERT INTO albums_fts(albums_fts, rowid, source_id, name) - VALUES('delete', old.rowid, old.source_id, old.name); -END; - -CREATE TRIGGER albums_au AFTER UPDATE ON albums BEGIN - INSERT INTO albums_fts(albums_fts, rowid, source_id, name) - VALUES('delete', old.rowid, old.source_id, old.name); - INSERT INTO albums_fts(rowid, source_id, name) - VALUES (new.rowid, new.source_id, new.name); -END; - -CREATE TABLE playlists( - source_id INT NOT NULL, - id TEXT NOT NULL, - name TEXT NOT NULL COLLATE NOCASE, - comment TEXT COLLATE NOCASE, - cover_art TEXT, - song_count INT NOT NULL, - created DATETIME NOT NULL, - updated DATETIME NOT NULL DEFAULT (strftime('%s', CURRENT_TIMESTAMP)), - PRIMARY KEY (source_id, id), - FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE -) WITH Playlist; -CREATE INDEX playlists_source_id ON playlists (source_id); -CREATE TABLE playlist_songs( - source_id INT NOT NULL, - playlist_id TEXT NOT NULL, - song_id TEXT NOT NULL, - position INT NOT NULL, - updated DATETIME NOT NULL DEFAULT (strftime('%s', CURRENT_TIMESTAMP)), - PRIMARY KEY (source_id, playlist_id, position), - FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE -); -CREATE INDEX playlist_songs_source_id_playlist_id_idx ON playlist_songs (source_id, playlist_id); -CREATE INDEX playlist_songs_source_id_song_id_idx ON playlist_songs (source_id, song_id); - -CREATE VIRTUAL TABLE playlists_fts USING fts5(source_id, name, content=playlists, content_rowid=rowid); - -CREATE TRIGGER playlists_ai AFTER INSERT ON playlists BEGIN - INSERT INTO playlists_fts(rowid, source_id, name) - VALUES (new.rowid, new.source_id, new.name); -END; - -CREATE TRIGGER playlists_ad AFTER DELETE ON playlists BEGIN - INSERT INTO playlists_fts(playlists_fts, rowid, source_id, name) - VALUES('delete', old.rowid, old.source_id, old.name); -END; - -CREATE TRIGGER playlists_au AFTER UPDATE ON playlists BEGIN - INSERT INTO playlists_fts(playlists_fts, rowid, source_id, name) - VALUES('delete', old.rowid, old.source_id, old.name); - INSERT INTO playlists_fts(rowid, source_id, name) - VALUES (new.rowid, new.source_id, new.name); -END; - -CREATE TABLE songs( - source_id INT NOT NULL, - id TEXT NOT NULL, - album_id TEXT, - artist_id TEXT, - title TEXT NOT NULL COLLATE NOCASE, - album TEXT COLLATE NOCASE, - artist TEXT COLLATE NOCASE, - duration INT MAPPED BY `const DurationSecondsConverter()`, - track INT, - disc INT, - starred DATETIME, - genre TEXT, - download_task_id TEXT UNIQUE, - download_file_path TEXT UNIQUE, - is_deleted BOOLEAN NOT NULL DEFAULT 0, - updated DATETIME NOT NULL DEFAULT (strftime('%s', CURRENT_TIMESTAMP)), - PRIMARY KEY (source_id, id), - FOREIGN KEY (source_id) REFERENCES sources (id) ON DELETE CASCADE -) WITH Song; -CREATE INDEX songs_source_id_album_id_idx ON songs (source_id, album_id); -CREATE INDEX songs_source_id_artist_id_idx ON songs (source_id, artist_id); -CREATE INDEX songs_download_task_id_idx ON songs (download_task_id); - -CREATE VIRTUAL TABLE songs_fts USING fts5(source_id, title, content=songs, content_rowid=rowid); - -CREATE TRIGGER songs_ai AFTER INSERT ON songs BEGIN - INSERT INTO songs_fts(rowid, source_id, title) - VALUES (new.rowid, new.source_id, new.title); -END; - -CREATE TRIGGER songs_ad AFTER DELETE ON songs BEGIN - INSERT INTO songs_fts(songs_fts, rowid, source_id, title) - VALUES('delete', old.rowid, old.source_id, old.title); -END; - -CREATE TRIGGER songs_au AFTER UPDATE ON songs BEGIN - INSERT INTO songs_fts(songs_fts, rowid, source_id, title) - VALUES('delete', old.rowid, old.source_id, old.title); - INSERT INTO songs_fts(rowid, source_id, title) - VALUES (new.rowid, new.source_id, new.title); -END; - --- --- QUERIES --- - -sourcesCount: - SELECT COUNT(*) - FROM sources; - -allSubsonicSources WITH SubsonicSettings: - SELECT - sources.id, - sources.name, - sources.address, - sources.is_active, - sources.created_at, - subsonic_sources.features, - subsonic_sources.username, - subsonic_sources.password, - subsonic_sources.use_token_auth - FROM sources - JOIN subsonic_sources ON subsonic_sources.source_id = sources.id; - -albumIdsWithDownloadStatus: - SELECT albums.id - FROM albums - JOIN songs on songs.source_id = albums.source_id AND songs.album_id = albums.id - WHERE - albums.source_id = :source_id - AND (songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL) - GROUP BY albums.id; - -artistIdsWithDownloadStatus: - SELECT artists.id - FROM artists - LEFT JOIN albums ON artists.source_id = albums.source_id AND artists.id = albums.artist_id - LEFT JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id - WHERE - artists.source_id = :source_id - AND (songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL) - GROUP BY artists.id; - -playlistIdsWithDownloadStatus: - SELECT playlists.id - FROM playlists - LEFT JOIN playlist_songs ON playlist_songs.source_id = playlists.source_id AND playlist_songs.playlist_id = playlists.id - LEFT JOIN songs ON playlist_songs.source_id = songs.source_id AND playlist_songs.song_id = songs.id - WHERE - playlists.source_id = :source_id - AND (songs.download_file_path IS NOT NULL OR songs.download_task_id IS NOT NULL) - GROUP BY playlists.id; - -searchArtists: - SELECT rowid - FROM artists_fts - WHERE artists_fts MATCH :query - ORDER BY rank - LIMIT :limit OFFSET :offset; - -searchAlbums: - SELECT rowid - FROM albums_fts - WHERE albums_fts MATCH :query - ORDER BY rank - LIMIT :limit OFFSET :offset; - -searchPlaylists: - SELECT rowid - FROM playlists_fts - WHERE playlists_fts MATCH :query - ORDER BY rank - LIMIT :limit OFFSET :offset; - -searchSongs: - SELECT rowid - FROM songs_fts - WHERE songs_fts MATCH :query - ORDER BY rank - LIMIT :limit OFFSET :offset; - -artistById: - SELECT * FROM artists - WHERE source_id = :source_id AND id = :id; - -albumById: - SELECT * FROM albums - WHERE source_id = :source_id AND id = :id; - -albumsByArtistId: - SELECT * FROM albums - WHERE source_id = :source_id AND artist_id = :artist_id; - -albumsInIds: - SELECT * FROM albums - WHERE source_id = :source_id AND id IN :ids; - -playlistById: - SELECT * FROM playlists - WHERE source_id = :source_id AND id = :id; - -songById: - SELECT * FROM songs - WHERE source_id = :source_id AND id = :id; - -albumGenres: - SELECT - genre - FROM albums - WHERE genre IS NOT NULL AND source_id = :source_id - GROUP BY genre - ORDER BY COUNT(genre) DESC - LIMIT :limit OFFSET :offset; - -albumsByGenre: - SELECT - albums.* - FROM albums - JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id - WHERE songs.source_id = :source_id AND songs.genre = :genre - GROUP BY albums.id - ORDER BY albums.created DESC, albums.name - LIMIT :limit OFFSET :offset; - -filterSongsByGenre: - SELECT - songs.* - FROM songs - JOIN albums ON albums.source_id = songs.source_id AND albums.id = songs.album_id - WHERE $predicate - ORDER BY $order - LIMIT $limit; - -songsByGenreCount: - SELECT - COUNT(*) - FROM songs - WHERE songs.source_id = :source_id AND songs.genre = :genre; - -songsWithDownloadTasks: - SELECT * FROM songs - WHERE download_task_id IS NOT NULL; - -songByDownloadTask: - SELECT * FROM songs - WHERE download_task_id = :task_id; - -clearSongDownloadTaskBySong: - UPDATE songs SET - download_task_id = NULL - WHERE source_id = :source_id AND id = :id; - -completeSongDownload: - UPDATE songs SET - download_task_id = NULL, - download_file_path = :file_path - WHERE download_task_id = :task_id; - -clearSongDownloadTask: - UPDATE songs SET - download_task_id = NULL, - download_file_path = NULL - WHERE download_task_id = :task_id; - -updateSongDownloadTask: - UPDATE songs SET - download_task_id = :task_id - WHERE source_id = :source_id AND id = :id; - -deleteSongDownloadFile: - UPDATE songs SET - download_task_id = NULL, - download_file_path = NULL - WHERE source_id = :source_id AND id = :id; - -albumDownloadStatus WITH ListDownloadStatus: - SELECT - COUNT(*) as total, - COUNT(CASE WHEN songs.download_file_path IS NOT NULL THEN songs.id ELSE NULL END) AS downloaded, - COUNT(CASE WHEN songs.download_task_id IS NOT NULL THEN songs.id ELSE NULL END) AS downloading - FROM albums - JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id - WHERE albums.source_id = :source_id AND albums.id = :id; - -playlistDownloadStatus WITH ListDownloadStatus: - SELECT - COUNT(DISTINCT songs.id) as total, - COUNT(DISTINCT CASE WHEN songs.download_file_path IS NOT NULL THEN songs.id ELSE NULL END) AS downloaded, - COUNT(DISTINCT CASE WHEN songs.download_task_id IS NOT NULL THEN songs.id ELSE NULL END) AS downloading - FROM playlists - JOIN playlist_songs ON - playlist_songs.source_id = playlists.source_id - AND playlist_songs.playlist_id = playlists.id - JOIN songs ON - songs.source_id = playlist_songs.source_id - AND songs.id = playlist_songs.song_id - WHERE - playlists.source_id = :source_id AND playlists.id = :id; - -filterAlbums: - SELECT - albums.* - FROM albums - WHERE $predicate - ORDER BY $order - LIMIT $limit; - -filterAlbumsDownloaded: - SELECT - albums.* - FROM albums - LEFT JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id - WHERE $predicate - GROUP BY albums.source_id, albums.id - HAVING SUM(CASE WHEN songs.download_file_path IS NOT NULL THEN 1 ELSE 0 END) > 0 - ORDER BY $order - LIMIT $limit; - -filterArtists: - SELECT - artists.* - FROM artists - WHERE $predicate - ORDER BY $order - LIMIT $limit; - -filterArtistsDownloaded WITH Artist: - SELECT - artists.*, - COUNT(DISTINCT CASE WHEN songs.download_file_path IS NOT NULL THEN songs.album_id ELSE NULL END) AS album_count - FROM artists - LEFT JOIN albums ON artists.source_id = albums.source_id AND artists.id = albums.artist_id - LEFT JOIN songs ON albums.source_id = songs.source_id AND albums.id = songs.album_id - WHERE $predicate - GROUP BY artists.source_id, artists.id - HAVING SUM(CASE WHEN songs.download_file_path IS NOT NULL THEN 1 ELSE 0 END) > 0 - ORDER BY $order - LIMIT $limit; - -filterPlaylists: - SELECT - playlists.* - FROM playlists - WHERE $predicate - ORDER BY $order - LIMIT $limit; - -filterPlaylistsDownloaded WITH Playlist: - SELECT - playlists.*, - COUNT(CASE WHEN songs.download_file_path IS NOT NULL THEN songs.id ELSE NULL END) AS song_count - FROM playlists - LEFT JOIN playlist_songs ON playlist_songs.source_id = playlists.source_id AND playlist_songs.playlist_id = playlists.id - LEFT JOIN songs ON playlist_songs.source_id = songs.source_id AND playlist_songs.song_id = songs.id - WHERE $predicate - GROUP BY playlists.source_id, playlists.id - HAVING SUM(CASE WHEN songs.download_file_path IS NOT NULL THEN 1 ELSE 0 END) > 0 - ORDER BY $order - LIMIT $limit; - -filterSongs: - SELECT - songs.* - FROM songs - WHERE $predicate - ORDER BY $order - LIMIT $limit; - -filterSongsDownloaded: - SELECT - songs.* - FROM songs - WHERE $predicate AND songs.download_file_path IS NOT NULL - ORDER BY $order - LIMIT $limit; - -playlistIsDownloaded: - SELECT - COUNT(*) = 0 - FROM playlists - JOIN playlist_songs ON - playlist_songs.source_id = playlists.source_id - AND playlist_songs.playlist_id = playlists.id - JOIN songs ON - songs.source_id = playlist_songs.source_id - AND songs.id = playlist_songs.song_id - WHERE - playlists.source_id = :source_id AND playlists.id = :id - AND songs.download_file_path IS NULL; - -playlistHasDownloadsInProgress: - SELECT - COUNT(*) > 0 - FROM playlists - JOIN playlist_songs ON - playlist_songs.source_id = playlists.source_id - AND playlist_songs.playlist_id = playlists.id - JOIN songs ON - songs.source_id = playlist_songs.source_id - AND songs.id = playlist_songs.song_id - WHERE playlists.source_id = :source_id AND playlists.id = :id - AND songs.download_task_id IS NOT NULL; - -songsInIds: - SELECT * - FROM songs - WHERE source_id = :source_id AND id IN :ids; - -songsInRowIds: - SELECT * - FROM songs - WHERE ROWID IN :row_ids; - -albumsInRowIds: - SELECT * - FROM albums - WHERE ROWID IN :row_ids; - -artistsInRowIds: - SELECT * - FROM artists - WHERE ROWID IN :row_ids; - -playlistsInRowIds: - SELECT * - FROM playlists - WHERE ROWID IN :row_ids; - -currentTrackIndex: - SELECT - queue."index" - FROM queue - WHERE queue.current_track = 1; - -queueLength: - SELECT COUNT(*) FROM queue; - -queueInIndicies: - SELECT * - FROM queue - WHERE queue."index" IN :indicies; - -getAppSettings: - SELECT * FROM app_settings - WHERE id = 1; diff --git a/lib/database/util.dart b/lib/database/util.dart deleted file mode 100644 index 2ea659c2..00000000 --- a/lib/database/util.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:intl/intl.dart'; -import 'package:path/path.dart'; -import 'package:path_provider/path_provider.dart'; - -Future datapasePath(String database) async => - join((await getApplicationSupportDirectory()).path, 'databases', database); - -extension DateTimeExt on DateTime { - String toDb() => DateFormat('yyyy-MM-dd hh:mm:ss').format(toUtc()); - - static DateTime parseUtc(Object? obj) { - final str = obj.toString(); - return DateTime.parse(hasTimeZone(str) ? str : '${obj}Z').toLocal(); - } - - static DateTime? tryParseUtc(Object? obj) { - final str = obj.toString(); - return DateTime.tryParse(hasTimeZone(str) ? str : '${obj}Z')?.toLocal(); - } - - static bool hasTimeZone(String str) => - RegExp(r'(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])').hasMatch(str); -} diff --git a/lib/http/client.dart b/lib/http/client.dart deleted file mode 100644 index c4daa58f..00000000 --- a/lib/http/client.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:http/http.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../log.dart'; - -part 'client.g.dart'; - -const Map subtracksHeaders = { - 'user-agent': 'subtracks/android', -}; - -class SubtracksHttpClient extends BaseClient { - SubtracksHttpClient(); - - @override - Future send(BaseRequest request) { - request.headers.addAll(subtracksHeaders); - log.info('${request.method} ${request.url}'); - - try { - return request.send(); - } catch (e, st) { - log.severe('HTTP client: ${request.method} ${request.url}', e, st); - rethrow; - } - } -} - -@Riverpod(keepAlive: true) -BaseClient httpClient(HttpClientRef ref) { - return SubtracksHttpClient(); -} diff --git a/lib/http/client.g.dart b/lib/http/client.g.dart deleted file mode 100644 index 36e59860..00000000 --- a/lib/http/client.g.dart +++ /dev/null @@ -1,23 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'client.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$httpClientHash() => r'78f604dbc249a854728d71bde8289d48f6700be7'; - -/// See also [httpClient]. -@ProviderFor(httpClient) -final httpClientProvider = Provider.internal( - httpClient, - name: r'httpClientProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$httpClientHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef HttpClientRef = ProviderRef; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb deleted file mode 100644 index eed53190..00000000 --- a/lib/l10n/app_ar.arb +++ /dev/null @@ -1,196 +0,0 @@ -{ - "actionsStar": "مميز", - "@actionsStar": {}, - "actionsUnstar": "ازل التمييز", - "@actionsUnstar": {}, - "messagesNothingHere": "لا شيء هنا…", - "@messagesNothingHere": {}, - "navigationTabsHome": "الرئيسية", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "المكتبة", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "بحث", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "الإعدادات", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "شَغل الألبوم", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "أعرض الألبوم", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "فرز الألبومات", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{} few{ألبوم} many{} other{}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "أظهر الفنان", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "فرز الفنانين", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{} few{فنان} many{فنانان} other{فنانان}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "حسب النوع", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "موسوم", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "شغل قائمة التشغيل", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{} few{قائمة تشغيل} many{قائمتان تشغيل} other{قائمتان تشغيل}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{} few{صف} many{صفين} other{صفين}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "أشهر الأغاني", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{} few{أُغْنِيَة} many{} other{}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "أضيف حديثا", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "حسب الفنان/ة", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "مشغل كثيرا", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "حسب الاسم", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "عشوائي", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "شغل حديثا", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "حسب السنة", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "بحث: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "بحث", - "@searchInputPlaceholder": {}, - "searchMoreResults": "المزيد…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "نتائج البحث", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "الرخص", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "موقع المشروع", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "حول", - "@settingsAboutName": {}, - "settingsAboutVersion": "الإصدار {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "موسيقى", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "لا تستورد سجل التشغيل", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "استيراد سجل التشغيل", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "استيراد سجل التشغيل", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "الشبكة", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "أقصى معدل نقل بيانات (mobile)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "أقصى معدل نقل بيانات (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "الحد الأقصى من وقت التخزين المؤقت", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "الحد الأدنى من وقت التخزين المؤقت", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value} كيلو بايت في الثانية", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} ثواني", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "غير محدود", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "مسح ذاكرة التخزين المؤقت للصور", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "إعادة ضبط", - "@settingsResetName": {}, - "settingsServersActionsAdd": "أضف سيرفر", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "حذف", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "عدل السيرفر", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "حفظ", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "أخبر الأتصال", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "العناوين", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "كلمة المرور", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "إسم المستخدم", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "الأتصال ب {address} فشل، ابحث في الإعدادات او السيرفر", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "الأتصال ب {address} جيد!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "السيرفرات", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "أرسل كلمة المرور على شكل توكِن", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "أرسل كلمة المرور بنص عادي (قديم ، تأكد من أن اتصالك آمن!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "أظهر كلمة المرور", - "@settingsServersOptionsForcePlaintextPasswordTitle": {} -} \ No newline at end of file diff --git a/lib/l10n/app_ca.arb b/lib/l10n/app_ca.arb deleted file mode 100644 index 84f77cac..00000000 --- a/lib/l10n/app_ca.arb +++ /dev/null @@ -1,196 +0,0 @@ -{ - "actionsStar": "Afegir als favorits", - "@actionsStar": {}, - "actionsUnstar": "Retirar estrella", - "@actionsUnstar": {}, - "messagesNothingHere": "Aquí no hi ha res…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Inici", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Biblioteca", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Cercar", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Paràmetres", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Reproduir l'àlbum", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Veure l'àlbum", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Ordenar els àlbums", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Àlbum} other{Àlbums}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Veure l'artista", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Ordenar els artistes", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Artista} other{Artistes}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Per gènere", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "Favorits", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "Reproduir la llista de reproducció", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Llista de reproducció} other{Llistes de reproducció}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Cua} other{Cues}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Millors cançons", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Cançó} other{Cançons}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Afegit recentment", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "Per artista", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Escoltat freqüentment", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "Pel nom", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Aleatori", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Reproduït recentment", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "Per any", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Cercar: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Cercar", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Més…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Resultats de la cerca", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Llicències", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Pàgina d'inici del projecte", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "Quant a", - "@settingsAboutName": {}, - "settingsAboutVersion": "versió {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Música", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "No capturar l'historial de reproducció", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Capturar l'historial de reproduccions", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Capturar la lectura", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Xarxa", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Taxa de bits màxima (mòbil)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Taxa de bits màxima (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Temps màxim en memòria intermèdia", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Temps mínim en memòria intermèdia", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value} kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} segons", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Il·limitat", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Esborrar la memòria cau d'imatges", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Reinicialitzar", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Afegir un servidor", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Esborrar", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Editar el servidor", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Desar", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Comprovar la connexió", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Adreça", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Contrasenya", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Nom d’usuari", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "La connexió a {address} ha fallat, comprova la configuració o el servidor", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Connexió a {address} OK!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Servidors", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Enviar contrasenya com a token + salt", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Enviar la contrasenya en text sense format (obsolet, assegura't que la teva connexió sigui segura!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Forçar la contrasenya de text sense format", - "@settingsServersOptionsForcePlaintextPasswordTitle": {} -} \ No newline at end of file diff --git a/lib/l10n/app_cs.arb b/lib/l10n/app_cs.arb deleted file mode 100644 index 36d6adb4..00000000 --- a/lib/l10n/app_cs.arb +++ /dev/null @@ -1,226 +0,0 @@ -{ - "actionsStar": "Ohodnotit", - "@actionsStar": {}, - "actionsUnstar": "Zrušit hodnocení", - "@actionsUnstar": {}, - "messagesNothingHere": "Zde nic není…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Domů", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Knihovna", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Hledat", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Nastavení", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Přehrát album", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Zobrazit album", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Seřadit alba", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Album} few{Alba} many{Alba} other{Alba}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Zobrazit umělce", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Seřadit umělce", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Umělec} few{Umělci} many{Umělci} other{Umělci}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Podle žánru", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "Ohodnocené", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "Přehrát seznam skladeb", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Seznam skladeb} few{Seznamy skladeb} many{Seznamy skladeb} other{Seznamy skladeb}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Fronta} few{Fronty} many{Fronty} other{Fronty}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Top skladby", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Skladba} few{Skladby} many{Skladby} other{Skladby}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Nedávno přidané", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "Umělce", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Často přehrávané", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "Názvu", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Náhodně", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Často přehrávané", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "Roku", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Hledat: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Hledat", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Více…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Výsledky hledání", - "@searchNowPlayingContext": {}, - "settingsNetworkName": "Síť", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Maximální datový tok (mobil)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Maximální datový tok (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} sekund", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Neomezeno", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsServersActionsAdd": "Přidat server", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Odstranit", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Upravit server", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Uložit", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Otestovat spojení", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Adresa", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Heslo", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Uživ. jméno", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Připojení k {address} selhalo, zkontrolujte nastavení nebo server", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Připojení k {address} je OK!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Servery", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Posílat heslo jako token + salt", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Posílat heslo v prostém textu (zastaralé, ujistěte se, že je vaše připojení zabezpečené!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Vynutit heslo ve formátu prostého textu", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "actionsDownloadDelete": "Smazat stažené", - "@actionsDownloadDelete": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "actionsCancel": "Zrušit", - "@actionsCancel": {}, - "actionsDownload": "Stáhnout", - "@actionsDownload": {}, - "controlsShuffle": "Náhodně", - "@controlsShuffle": {}, - "resourcesFilterAlbum": "Album", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "Umělec", - "@resourcesFilterArtist": {}, - "resourcesFilterYear": "Rok", - "@resourcesFilterYear": {}, - "resourcesFilterOwner": "Majitele", - "@resourcesFilterOwner": {}, - "resourcesSongListDeleteAllTitle": "Smazat stažené?", - "@resourcesSongListDeleteAllTitle": {}, - "resourcesSongListDeleteAllContent": "Toto odstraní všechny stažené soubory s hudbou.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSortByUpdated": "Naposledy upravené", - "@resourcesSortByUpdated": {}, - "resourcesSortByAlbum": "Alba", - "@resourcesSortByAlbum": {}, - "resourcesSortByAlbumCount": "Počtu alb", - "@resourcesSortByAlbumCount": {}, - "resourcesSortByTitle": "Názvu", - "@resourcesSortByTitle": {}, - "settingsAboutActionsLicenses": "Licence", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Stránka projektu", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutActionsSupport": "Podpořit vývojáře 💜", - "@settingsAboutActionsSupport": {}, - "settingsAboutVersion": "verze {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsNetworkOptionsStreamFormat": "Preferovaný formát pro streamování", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Použít nastavení serveru", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsResetActionsClearImageCache": "Smazat mezipaměť obrázků", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Resetovat", - "@settingsResetName": {}, - "settingsServersFieldsName": "Jméno", - "@settingsServersFieldsName": {}, - "settingsAboutName": "O aplikaci", - "@settingsAboutName": {}, - "actionsDownloadCancel": "Zrušit stahování", - "@actionsDownloadCancel": {}, - "actionsDelete": "Smazat", - "@actionsDelete": {} -} diff --git a/lib/l10n/app_da.arb b/lib/l10n/app_da.arb deleted file mode 100644 index b3ee3b5f..00000000 --- a/lib/l10n/app_da.arb +++ /dev/null @@ -1,186 +0,0 @@ -{ - "messagesNothingHere": "Intet her…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Hjem", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Bibliotek", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Søg", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Indstillinger", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Afspil album", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Se album", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Sortér albums", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Album} other{Albums}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Se kunstnere", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Sortér kunstnere", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Kunstner} other{Kunstnere}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Efter genre", - "@resourcesFilterGenre": {}, - "resourcesPlaylistActionsPlay": "Afspil spilleliste", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Spilleliste} other{Spillelister}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Kø} other{Køer}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Top sange", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Sang} other{Sange}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByArtist": "Efter kunstner", - "@resourcesSortByArtist": {}, - "resourcesSortByName": "Efter navn", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Tilfældig", - "@resourcesSortByRandom": {}, - "resourcesSortByYear": "Efter år", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Søg: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Søg", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Mere…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Søgeresultater", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Licenser", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Projekt hjemmeside", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "Omkring", - "@settingsAboutName": {}, - "settingsAboutVersion": "version {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Musik", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Scrobble afspilningshistorik", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Scrobble afspilninger", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Netværk", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Maksimum bitrate (mobil)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Maksimum bitrate (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Maksimum buffertid", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Minimum buffertid", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} sekunder", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Ubegrænset", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Ryd billede cache", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Nulstil", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Tilføj server", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Slet", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Redigér server", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Gem", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Test forbindelse", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Adresse", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Adgangskode", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Brugernavn", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Forbindelse til {address} mislykkedes, tjek indstillinger eller server", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Forbindelse til {address} OK!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Servere", - "@settingsServersName": {}, - "actionsDownload": "Hent", - "@actionsDownload": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "actionsDelete": "Slet", - "@actionsDelete": {}, - "actionsCancel": "Afbryd", - "@actionsCancel": {}, - "actionsDownloadCancel": "Afbryd download", - "@actionsDownloadCancel": {} -} diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb deleted file mode 100644 index a292233f..00000000 --- a/lib/l10n/app_de.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsStar": "Markieren", - "@actionsStar": {}, - "actionsUnstar": "Markierung entfernen", - "@actionsUnstar": {}, - "messagesNothingHere": "Hier ist nichts…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Startseite", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Bibliothek", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Suche", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Einstellungen", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Album abspielen", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Album anzeigen", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Alben sortieren", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Album} other{Alben}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Interpret anzeigen", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Interpreten sortieren", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Interpret} other{Interpreten}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Nach Genre", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "Favoriten", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "Wiedergabeliste abspielen", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Wiedergabeliste} other{Wiedergabelisten}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Warteschlange} other{Warteschlangen}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Top Lieder", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Lied} other{Lieder}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Kürzlich hinzugefügt", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "Nach Interpreten", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Häufig abgespielt", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "Nach Name", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Zufällig", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Kürzlich abgespielt", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "Nach Jahr", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Suche: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Suche", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Mehr…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Suchergebnis", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Lizenzen", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Projektseite", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "Über", - "@settingsAboutName": {}, - "settingsAboutVersion": "Version {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Musik", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Kein Scrobble für Wiedergabeverlauf", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Scrobble Wiedergabeverlauf", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Scrobble Wiedergabe", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Netzwerk", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Maximale Bitrate (Mobil)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Maximale Bitrate (WLAN)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Maximale Pufferzeit", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Minimale Pufferzeit", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} Sekunden", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Unbegrenzt", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Bildzwischenspeicher löschen", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Zurücksetzen", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Server hinzufügen", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Löschen", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Server bearbeiten", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Speichern", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Verbindung testen", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Adresse", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Passwort", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Nutzername", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Verbindung zu {address} fehlgeschlagen, überprüfe Einstellungen oder Server", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Verbindung zu {address} ist OK!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Server", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Sende Passwort als Token + Salt", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Passwort als Klartext senden (Veraltet, stellen Sie sicher, dass Ihre Verbindung sicher ist!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Erzwinge Klartextpasswort", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "actionsDelete": "Löschen", - "@actionsDelete": {}, - "actionsDownload": "Herunterladen", - "@actionsDownload": {}, - "actionsDownloadCancel": "Download abbrechen", - "@actionsDownloadCancel": {}, - "controlsShuffle": "Zufall", - "@controlsShuffle": {}, - "actionsCancel": "Abbrechen", - "@actionsCancel": {}, - "actionsDownloadDelete": "Heruntergeladene Inhalte löschen", - "@actionsDownloadDelete": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} Album} other{{count} Alben}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterAlbum": "Album", - "@resourcesFilterAlbum": {}, - "resourcesArtistCount": "{count,plural, =1{{count} Künstler} other{{count} Künstler}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterArtist": "Künstler", - "@resourcesFilterArtist": {}, - "resourcesFilterOwner": "Besitzer", - "@resourcesFilterOwner": {}, - "resourcesFilterYear": "Jahr", - "@resourcesFilterYear": {}, - "resourcesPlaylistCount": "{count,plural, =1{{count} Playlist} other{{count} Playlists}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{{count} Song} other{{count} Songs}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "Hierdurch werden alle heruntergeladenen Inhalte entfernt.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSortByAlbum": "Album", - "@resourcesSortByAlbum": {}, - "resourcesSortByAlbumCount": "Albenanzahl", - "@resourcesSortByAlbumCount": {}, - "resourcesSortByTitle": "Titel", - "@resourcesSortByTitle": {}, - "resourcesSortByUpdated": "Kürzlich aktualisiert", - "@resourcesSortByUpdated": {}, - "settingsAboutActionsSupport": "Den Entwickler unterstützen", - "@settingsAboutActionsSupport": {}, - "settingsNetworkOptionsOfflineMode": "Offline Modus", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsOfflineModeOff": "Nutze das Internet um Musik zu synchronisieren.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsOfflineModeOn": "Nutze nicht das Internet um Musik zu synchronisieren.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsNetworkOptionsStreamFormat": "Bevorzugtes Streaming-Format", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsServersFieldsName": "Name", - "@settingsServersFieldsName": {}, - "resourcesSongListDeleteAllTitle": "Downloads löschen?", - "@resourcesSongListDeleteAllTitle": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Standardserver verwenden", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsAboutShareLogs": "Protokolle teilen", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "Wählen Sie eine Protokolldatei", - "@settingsAboutChooseLog": {} -} diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb deleted file mode 100644 index cfb09eaf..00000000 --- a/lib/l10n/app_en.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsCancel": "Cancel", - "@actionsCancel": {}, - "actionsDelete": "Delete", - "@actionsDelete": {}, - "actionsDownload": "Download", - "@actionsDownload": {}, - "actionsDownloadCancel": "Cancel download", - "@actionsDownloadCancel": {}, - "actionsDownloadDelete": "Delete downloaded", - "@actionsDownloadDelete": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "actionsStar": "Star", - "@actionsStar": {}, - "actionsUnstar": "Unstar", - "@actionsUnstar": {}, - "controlsShuffle": "Shuffle", - "@controlsShuffle": {}, - "messagesNothingHere": "Nothing here…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Home", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Library", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Search", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Settings", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Play album", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "View album", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} album} other{{count} albums}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesAlbumListsSort": "Sort albums", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Album} other{Albums}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "View artist", - "@resourcesArtistActionsView": {}, - "resourcesArtistCount": "{count,plural, =1{{count} artist} other{{count} artists}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistListsSort": "Sort artists", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Artist} other{Artists}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterAlbum": "Album", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "Artist", - "@resourcesFilterArtist": {}, - "resourcesFilterGenre": "Genre", - "@resourcesFilterGenre": {}, - "resourcesFilterOwner": "Owner", - "@resourcesFilterOwner": {}, - "resourcesFilterStarred": "Starred", - "@resourcesFilterStarred": {}, - "resourcesFilterYear": "Year", - "@resourcesFilterYear": {}, - "resourcesPlaylistActionsPlay": "Play playlist", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistCount": "{count,plural, =1{{count} playlist} other{{count} playlists}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesPlaylistName": "{count,plural, =1{Playlist} other{Playlists}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Queue} other{Queues}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{{count} song} other{{count} songs}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "This will remove all downloaded song files.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSongListDeleteAllTitle": "Delete downloads?", - "@resourcesSongListDeleteAllTitle": {}, - "resourcesSongListsArtistTopSongs": "Top Songs", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Song} other{Songs}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Recently added", - "@resourcesSortByAdded": {}, - "resourcesSortByAlbum": "Album", - "@resourcesSortByAlbum": {}, - "resourcesSortByAlbumCount": "Album count", - "@resourcesSortByAlbumCount": {}, - "resourcesSortByArtist": "Artist", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Frequently played", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "Name", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Random", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Recently played", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByTitle": "Title", - "@resourcesSortByTitle": {}, - "resourcesSortByUpdated": "Recently updated", - "@resourcesSortByUpdated": {}, - "resourcesSortByYear": "Year", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Search: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Search", - "@searchInputPlaceholder": {}, - "searchMoreResults": "More…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Search results", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Licenses", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Project homepage", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutActionsSupport": "Support the developer 💜", - "@settingsAboutActionsSupport": {}, - "settingsAboutName": "About", - "@settingsAboutName": {}, - "settingsAboutShareLogs": "Share logs", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "Choose a log file", - "@settingsAboutChooseLog": {}, - "settingsAboutVersion": "version {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Music", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Don't scrobble play history", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Scrobble play history", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Scrobble plays", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Network", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Maximum bitrate (mobile data)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Maximum bitrate (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Maximum buffer time", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Minimum buffer time", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkOptionsOfflineMode": "Offline mode", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsOfflineModeOff": "Use the internet to sync music.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsOfflineModeOn": "Don't use the internet to sync or play music.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsNetworkOptionsStreamFormat": "Preferred stream format", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Use server default", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} seconds", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Unlimited", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Clear Image Cache", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Reset", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Add source", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Delete", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Edit source", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Save", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Test connection", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Address", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsName": "Name", - "@settingsServersFieldsName": {}, - "settingsServersFieldsPassword": "Password", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Username", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Connection to {address} failed, check settings or server", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Connection to {address} OK!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Sources", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Send password as token + salt", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Send password in plaintext (legacy, make sure your connection is secure!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Force plaintext password", - "@settingsServersOptionsForcePlaintextPasswordTitle": {} -} diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb deleted file mode 100644 index d6c71398..00000000 --- a/lib/l10n/app_es.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsStar": "Favorito", - "@actionsStar": {}, - "actionsUnstar": "Retirar favorito", - "@actionsUnstar": {}, - "messagesNothingHere": "Nada aquí…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Inicio", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Biblioteca", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Buscar", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Configuración", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Reproducir Álbum", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Ver Álbum", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Ordenar Álbumes", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Álbum} other{Álbumes}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Ver Artista", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Oredenar Artistas", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Artista} other{Artistas}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Género", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "Estrellas", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "Reproducir lista de reproducción", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Lista de reproducción} other{Listas de reproducción}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Cola} other{Colas}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Mejores Canciones", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Cancion} other{Canciones}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Recientemente Añadido", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "Por Artista", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Escuchado frecuentemente", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "Por Nombre", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Aleatorio", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Escuchado recientemente", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "Por Año", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Buscar: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Buscar", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Más…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Resultados de la búsqueda", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Licencias", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Página de inicio del proyecto", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "Información", - "@settingsAboutName": {}, - "settingsAboutVersion": "versión {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Música", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "No hacer historial de reproducción de scrobble", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Historial de reproducción de scrobble", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Obras de teatro de Scrobble", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Sitio", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Tasa de bits máxima (mobile)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Tasa de bits máxima (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Máxima de buffer tiempo", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Mínimo de buffer tiempo", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value} kilobytes por segundo", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} segundos", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Ilimitados", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Caché de imágenes claras", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Reinicializar", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Agregar Servidor", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Eliminar", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Editar Servidor", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Guardar", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Probar conexión", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Dirección", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Contraseña", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Nombre de usuario", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "La conexión a {address} falló, verifique la configuracón o el servidor", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "¡Conexión con {address} Ok!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Servidores", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Enviar contraseña como token + sal", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Enviar contraseña en texto plano (¡legado, asegúrese de que su conexión sea segura!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Forzar contraseña como texto sin formato", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "actionsDelete": "Borrar", - "@actionsDelete": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "actionsDownload": "Descargar", - "@actionsDownload": {}, - "actionsDownloadCancel": "Anular descarga", - "@actionsDownloadCancel": {}, - "controlsShuffle": "Reproducir aleatoriamente", - "@controlsShuffle": {}, - "actionsCancel": "Cancelar", - "@actionsCancel": {}, - "actionsDownloadDelete": "Eliminar descargado", - "@actionsDownloadDelete": {}, - "settingsNetworkOptionsOfflineModeOn": "No se usa internet para sincronizar o reproducir música.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Utilizar predeterminado del servidor", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsAboutShareLogs": "Compartir registros", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "Escoger un archivo de registro", - "@settingsAboutChooseLog": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} Álbum} other{{count} Álbumes}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterAlbum": "Álbum", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "Artista", - "@resourcesFilterArtist": {}, - "resourcesPlaylistCount": "{count,plural, =1{{count} Lista de reproducción} other{{count} Listas de reproducción}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{{count} Canción} other{{count} Canciones}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "Esto eliminará todos los archivos de las canciones descargadas.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSongListDeleteAllTitle": "¿Eliminar descargas?", - "@resourcesSongListDeleteAllTitle": {}, - "resourcesSortByAlbum": "Álbum", - "@resourcesSortByAlbum": {}, - "resourcesSortByAlbumCount": "Número de álbumes", - "@resourcesSortByAlbumCount": {}, - "resourcesSortByTitle": "Título", - "@resourcesSortByTitle": {}, - "resourcesSortByUpdated": "Actualizado recientemente", - "@resourcesSortByUpdated": {}, - "settingsAboutActionsSupport": "Apoya al desarrollador 💜", - "@settingsAboutActionsSupport": {}, - "settingsNetworkOptionsOfflineMode": "Modo sin conexión", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsOfflineModeOff": "Se usa internet para sincronizar música.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsStreamFormat": "Formato de reproducción favorito", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsServersFieldsName": "Nombre", - "@settingsServersFieldsName": {}, - "resourcesFilterOwner": "Dueño", - "@resourcesFilterOwner": {}, - "resourcesFilterYear": "Año", - "@resourcesFilterYear": {}, - "resourcesArtistCount": "{count,plural, =1{{count} artista} other{{count} artistas}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - } -} diff --git a/lib/l10n/app_eu.arb b/lib/l10n/app_eu.arb deleted file mode 100644 index 0104bcf5..00000000 --- a/lib/l10n/app_eu.arb +++ /dev/null @@ -1,200 +0,0 @@ -{ - "actionsCancel": "Utzi", - "@actionsCancel": {}, - "actionsDelete": "Ezabatu", - "@actionsDelete": {}, - "actionsDownload": "Deskargatu", - "@actionsDownload": {}, - "actionsDownloadCancel": "Utzi deskargatzeari", - "@actionsDownloadCancel": {}, - "actionsDownloadDelete": "Ezabatu deskargak", - "@actionsDownloadDelete": {}, - "actionsOk": "Ados", - "@actionsOk": {}, - "actionsStar": "Gogokoetan sartu", - "@actionsStar": {}, - "actionsUnstar": "Gogokoetatik kendu", - "@actionsUnstar": {}, - "controlsShuffle": "Nahastu", - "@controlsShuffle": {}, - "messagesNothingHere": "Kilkerrak besterik ez hemen…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Hasiera", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Liburutegia", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Bilatu", - "@navigationTabsSearch": {}, - "resourcesAlbumActionsPlay": "Jarri albuma", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Ikusi albuma", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumCount": "{count,plural, =1{Album bat} other{{count} album}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesAlbumName": "{count,plural, =1{Albuma} other{Albumak}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistListsSort": "Ordenatu musikariak", - "@resourcesArtistListsSort": {}, - "resourcesAlbumListsSort": "Ordenatu albumak", - "@resourcesAlbumListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Musikaria} other{Musikariak}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterAlbum": "Albuma", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "Musikaria", - "@resourcesFilterArtist": {}, - "resourcesFilterGenre": "Generoa", - "@resourcesFilterGenre": {}, - "resourcesFilterOwner": "Jabea", - "@resourcesFilterOwner": {}, - "resourcesFilterStarred": "Gogokoak", - "@resourcesFilterStarred": {}, - "resourcesFilterYear": "Urtea", - "@resourcesFilterYear": {}, - "resourcesPlaylistActionsPlay": "Jarri zerrenda", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistCount": "{count,plural, =1{Zerrenda bat} other{{count} zerrenda}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesPlaylistName": "{count,plural, =1{Zerrenda} other{Zerrendak}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Ilara} other{Ilarak}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{Kanta bat} other{{count} kanta}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "Deskargatutako musika-fitxategi guztiak ezabatuko dira.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSongListDeleteAllTitle": "Deskargak ezabatu nahi?", - "@resourcesSongListDeleteAllTitle": {}, - "resourcesSongListsArtistTopSongs": "Kanta onenak", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Kanta} other{Kantak}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Berriki gehituak", - "@resourcesSortByAdded": {}, - "resourcesSortByAlbum": "Albuma", - "@resourcesSortByAlbum": {}, - "resourcesSortByAlbumCount": "Album kopurua", - "@resourcesSortByAlbumCount": {}, - "resourcesSortByArtist": "Musikaria", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Askotan jarritakoak", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByRandom": "Ausaz", - "@resourcesSortByRandom": {}, - "resourcesSortByName": "Alfabetikoki", - "@resourcesSortByName": {}, - "resourcesSortByRecentlyPlayed": "Duela gutxi jarritakoak", - "@resourcesSortByRecentlyPlayed": {}, - "searchHeaderTitle": "Bilatu... {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Bilatu", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Gehiago ikusi", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Bilaketaren emaitzak", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Lizentziak", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Proiektuaren webgunea", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutActionsSupport": "Lagundu garatzaileari 💜", - "@settingsAboutActionsSupport": {}, - "settingsAboutShareLogs": "Partekatu erregistroak", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "Aukeratu erregistro-fitxategi bat", - "@settingsAboutChooseLog": {}, - "settingsMusicName": "Musika", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Ez igo internetera erreprodukzio-erregistroa", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Igo internetera erreprodukzio-erregistroa", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Igo internetera erreprodukzio-erregistroa", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Sarea", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Gehienezko bitrate-a (wifiz)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Gehienezko bitrate-a (datu mugikorretan)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "navigationTabsSettings": "Ezarpenak", - "@navigationTabsSettings": {}, - "resourcesArtistActionsView": "Ikusi musikaria", - "@resourcesArtistActionsView": {}, - "resourcesArtistCount": "{count,plural, =1{Musikari bat} other{{count} musikari}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByUpdated": "Duela gutxi gehituak", - "@resourcesSortByUpdated": {}, - "resourcesSortByYear": "Urtearen arabera", - "@resourcesSortByYear": {}, - "settingsAboutName": "Honi buruz", - "@settingsAboutName": {}, - "settingsAboutVersion": "{version} bertsioa", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - } -} diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb deleted file mode 100644 index 79fb864f..00000000 --- a/lib/l10n/app_fr.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsStar": "Ajouter aux favoris", - "@actionsStar": {}, - "actionsUnstar": "Enlever des favoris", - "@actionsUnstar": {}, - "messagesNothingHere": "Rien ici…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Accueil", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Bibliothèque", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Recherche", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Paramètres", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Jouer l'album", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Voir l'album", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Trier les albums", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Album} other{Albums}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Voir l'artiste", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Trier les artistes", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Artiste} other{Artistes}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Par Genre", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "Favoris", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "Lire la playlist", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Playlist} other{Playlists}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{File d'attente} other{Files d'attente}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Meilleures Chansons", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Chanson} other{Chansons}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Récemment Ajouté", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "Artiste", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Fréquemment Joué", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "Nom", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Aléatoire", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Récemment Joué", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "Année", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Recherche : {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Recherche", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Plus…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Résultats de recherche", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Licences", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Page d'accueil du projet", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "À propos", - "@settingsAboutName": {}, - "settingsAboutVersion": "version {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Musique", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Ne pas scrobbler l'historique de lecture", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Scrobbler l'historique de lecture", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Scrobbler la lecture", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Réseau", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Débit binaire maximum (mobile)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Débit binaire maximum (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Temps maximum en mémoire tampon", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Temps minimum en mémoire tampon", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value}kbit/s", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} secondes", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Illimité", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Vider le cache d'images", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Réinitialiser", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Ajouter un serveur", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Supprimer", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Modifier le serveur", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Sauvegarder", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Tester la connexion", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Adresse", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Mot de passe", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Nom d'utilisateur", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Échec de la connexion à {address}, vérifiez les paramètres ou le serveur", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Connexion à {address} OK !", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Serveurs", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Envoyer le mot de passe sous forme de jeton + salage", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Envoyer le mot de passe en test clair (héritage, assurez-vous que la connexion est sécurisée !)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Forcer le mot de passe en texte clair", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "settingsAboutShareLogs": "Partager les logs", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "Choisir un fichier de logs", - "@settingsAboutChooseLog": {}, - "actionsCancel": "Annuler", - "@actionsCancel": {}, - "actionsDownloadCancel": "Annuler le téléchargement", - "@actionsDownloadCancel": {}, - "actionsDownloadDelete": "Supprimer le(s) téléchargement(s)", - "@actionsDownloadDelete": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "resourcesFilterAlbum": "Album", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "Artiste", - "@resourcesFilterArtist": {}, - "resourcesFilterYear": "Année", - "@resourcesFilterYear": {}, - "resourcesSortByAlbum": "Album", - "@resourcesSortByAlbum": {}, - "resourcesSortByTitle": "Titre", - "@resourcesSortByTitle": {}, - "settingsAboutActionsSupport": "Soutenir le développeur 💜", - "@settingsAboutActionsSupport": {}, - "settingsNetworkOptionsOfflineMode": "Mode hors-ligne", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsOfflineModeOff": "Se connecter à internet pour synchroniser la musique.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsStreamFormat": "Format de stream préféré", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsServersFieldsName": "Nom", - "@settingsServersFieldsName": {}, - "actionsDelete": "Supprimer", - "@actionsDelete": {}, - "actionsDownload": "Télécharger", - "@actionsDownload": {}, - "resourcesSongListDeleteAllContent": "Tous les fichiers de musique téléchargés vont être supprimés.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSongListDeleteAllTitle": "Supprimer les téléchargements ?", - "@resourcesSongListDeleteAllTitle": {}, - "controlsShuffle": "Aléatoire", - "@controlsShuffle": {}, - "resourcesSortByUpdated": "Récemment mis à jour", - "@resourcesSortByUpdated": {}, - "settingsNetworkOptionsOfflineModeOn": "Ne pas se connecter à internet pour synchroniser ou jouer de la musique.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} album} other{{count} albums}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistCount": "{count,plural, =1{{count} artiste} other{{count} artistes}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterOwner": "Propriétaire", - "@resourcesFilterOwner": {}, - "resourcesPlaylistCount": "{count,plural, =1{{count} playlist} other{{count} playlists}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{{count} chanson} other{{count} chansons}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "settingsNetworkOptionsStreamFormatServerDefault": "Utiliser les paramètres par défaut du serveur", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "resourcesSortByAlbumCount": "Nombre d'albums", - "@resourcesSortByAlbumCount": {} -} diff --git a/lib/l10n/app_gl.arb b/lib/l10n/app_gl.arb deleted file mode 100644 index dee8c690..00000000 --- a/lib/l10n/app_gl.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsStar": "Estrela", - "@actionsStar": {}, - "actionsUnstar": "Retirar", - "@actionsUnstar": {}, - "messagesNothingHere": "Nada por aquí…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Inicio", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Biblioteca", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Buscar", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Axustes", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Reproducir", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Ver Álbum", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Ordenar Álbums", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Álbum} other{Álbums}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Ver Artista", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Ordenar Artistas", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Artista} other{Artistas}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Por xénero", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "Favoritas", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "Reproducir lista", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Listaxe} other{Listaxes}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Fila} other{Filas}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Máis reproducidas", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Canción} other{Cancións}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Últimas engadidas", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "Por artista", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Reproducidas a miúdo", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "Por nome", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Ao chou", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Reproducidas recente", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "Por ano", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Buscar: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Buscar", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Máis…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Resultados", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Licenzas", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Web do Proxecto", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "Acerca de", - "@settingsAboutName": {}, - "settingsAboutVersion": "versión {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Música", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Non rexistrar o historial de reprodución", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Rexistrar o historial de reprodución", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Rexistrar reprodución", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Rede", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Bitrate máx. (móbil)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Bitrate máx. (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Tempo máximo na memoria", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Tempo mínimo na memoria", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} segundos", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Sen límite", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Limpar a caché de imaxes", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Restablecer", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Engadir Servidor", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Eliminar", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Editar Servidor", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Gardar", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Comprobar Conexión", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Enderezo", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Contrasinal", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Identificador", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Fallou a conexión a {address}, comproba os axustes", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Conexión con {address} OK!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Servidores", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Enviar contrasinal como token + salt", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Enviar contrasinal en texto plano (herdado, pon coidado en que a conexión sexa segura!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Forzar contrasinal en texto plano", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "actionsCancel": "Cancelar", - "@actionsCancel": {}, - "actionsDelete": "Eliminar", - "@actionsDelete": {}, - "actionsDownload": "Descargar", - "@actionsDownload": {}, - "actionsDownloadCancel": "Cancelar a descarga", - "@actionsDownloadCancel": {}, - "actionsDownloadDelete": "Eliminar o descargado", - "@actionsDownloadDelete": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "controlsShuffle": "Barallar", - "@controlsShuffle": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} álbum} other{{count} álbums}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistCount": "{count,plural, =1{{count} artista} other{{count} artistas}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterAlbum": "Álbum", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "Artista", - "@resourcesFilterArtist": {}, - "resourcesFilterOwner": "Dono", - "@resourcesFilterOwner": {}, - "resourcesFilterYear": "Ano", - "@resourcesFilterYear": {}, - "resourcesPlaylistCount": "{count,plural, =1{{count} lista} other{{count} listas}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{{count} canción} other{{count} cancións}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "Vas eliminar todas as cancións descargadas.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSongListDeleteAllTitle": "Eliminar descargas?", - "@resourcesSongListDeleteAllTitle": {}, - "resourcesSortByAlbum": "Álbum", - "@resourcesSortByAlbum": {}, - "resourcesSortByAlbumCount": "Número de álbums", - "@resourcesSortByAlbumCount": {}, - "settingsAboutActionsSupport": "Axuda ao desenvolvemento 💜", - "@settingsAboutActionsSupport": {}, - "settingsNetworkOptionsOfflineMode": "Modo sen conexión", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsOfflineModeOff": "Usa internet para sincr. música.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsOfflineModeOn": "Non usar internet para sincr. ou reproducir música.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsNetworkOptionsStreamFormat": "Modo de reprodución preferido", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Usar por defecto do servidor", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsServersFieldsName": "Nome", - "@settingsServersFieldsName": {}, - "resourcesSortByTitle": "Título", - "@resourcesSortByTitle": {}, - "resourcesSortByUpdated": "Actualizado recentemente", - "@resourcesSortByUpdated": {}, - "settingsAboutShareLogs": "Compartir rexistros", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "Escolle un ficheiro de rexistro", - "@settingsAboutChooseLog": {} -} diff --git a/lib/l10n/app_hu.arb b/lib/l10n/app_hu.arb deleted file mode 100644 index b2e057c0..00000000 --- a/lib/l10n/app_hu.arb +++ /dev/null @@ -1,224 +0,0 @@ -{ - "settingsServersActionsEdit": "Forrás szerkesztése", - "@settingsServersActionsEdit": {}, - "actionsCancel": "Mégsem", - "@actionsCancel": {}, - "actionsDelete": "Törlés", - "@actionsDelete": {}, - "actionsDownload": "Letöltés", - "@actionsDownload": {}, - "actionsDownloadCancel": "Letöltés visszavonása", - "@actionsDownloadCancel": {}, - "actionsDownloadDelete": "Letöltések törlése", - "@actionsDownloadDelete": {}, - "actionsOk": "Rendben", - "@actionsOk": {}, - "actionsStar": "Kedvencekhez adás", - "@actionsStar": {}, - "resourcesAlbumActionsView": "Album megtekintése", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Albumok rendezése", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Album} other{Album}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "actionsUnstar": "Kedvencekből törlés", - "@actionsUnstar": {}, - "navigationTabsHome": "Kezdőoldal", - "@navigationTabsHome": {}, - "messagesNothingHere": "Nincs itt semmi…", - "@messagesNothingHere": {}, - "controlsShuffle": "Véletlen sorrend", - "@controlsShuffle": {}, - "resourcesArtistActionsView": "Előadó megtekintése", - "@resourcesArtistActionsView": {}, - "resourcesFilterAlbum": "Album", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "Előadó", - "@resourcesFilterArtist": {}, - "resourcesArtistName": "{count,plural, =1{Előadó} other{Előadó}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistCount": "{count,plural, =1{{count} előadó} other{{count} előadó}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterYear": "Év", - "@resourcesFilterYear": {}, - "resourcesFilterStarred": "Kedvencek között", - "@resourcesFilterStarred": {}, - "resourcesSongListDeleteAllContent": "Ezzel törlöd az összes letöltött zenefájlt.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSortByAdded": "Legutóbb hozzáadva", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "Előadó", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Gyakran játszott", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByRandom": "Véletlenszerű", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Legutóbb játszott", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByUpdated": "Legutóbb frissült", - "@resourcesSortByUpdated": {}, - "searchNowPlayingContext": "Keresés eredménye", - "@searchNowPlayingContext": {}, - "searchMoreResults": "Tovább…", - "@searchMoreResults": {}, - "settingsAboutActionsLicenses": "Licenszek", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsSupport": "Támogasd a fejlesztőt 💜", - "@settingsAboutActionsSupport": {}, - "settingsAboutVersion": "{version} verzió", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsAboutName": "Az alkalmazásról", - "@settingsAboutName": {}, - "settingsAboutShareLogs": "Logfájlok megosztása", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "Logfájl kiválasztása", - "@settingsAboutChooseLog": {}, - "settingsMusicName": "Zene", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Ne scrobble-ozza a lejátszási előzményeket", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsNetworkOptionsOfflineMode": "Offline mód", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Maximum bitráta (mobil adattal)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Maximum bitráta (Wi-Fi-n)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Minimum bufferelési idő", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Maximum bufferelési idő", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Szerver alapértelmezés használata", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Lejátszási előzmények scrobble-ozása", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Scrobble lejátszások", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Hálózat", - "@settingsNetworkName": {}, - "settingsServersActionsSave": "Mentés", - "@settingsServersActionsSave": {}, - "settingsNetworkValuesSeconds": "{value} másodperc", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Korlátlan", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Kép Gyorsítótár Ürítése", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Alaphelyzet", - "@settingsResetName": {}, - "settingsServersFieldsAddress": "Cím", - "@settingsServersFieldsAddress": {}, - "settingsServersMessagesConnectionOk": "Csatlakozás a {address} címhez rendben!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Források", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Jelszó küldése egyszerű szövegként (elavult, győződj meg róla hogy a kapcsolat biztonságos!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Egyszerű szöveges jelszó kényszerítése", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "resourcesFilterGenre": "Stílus", - "@resourcesFilterGenre": {}, - "navigationTabsSearch": "Keresés", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Beállítások", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Album lejátszása", - "@resourcesAlbumActionsPlay": {}, - "resourcesSortByName": "Név", - "@resourcesSortByName": {}, - "resourcesSortByTitle": "Cím", - "@resourcesSortByTitle": {}, - "resourcesSortByYear": "Év", - "@resourcesSortByYear": {}, - "settingsAboutActionsProjectHomepage": "Projekt weboldal", - "@settingsAboutActionsProjectHomepage": {}, - "searchHeaderTitle": "Keresés erre: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Keresés", - "@searchInputPlaceholder": {}, - "settingsServersActionsDelete": "Törlés", - "@settingsServersActionsDelete": {}, - "settingsServersActionsTestConnection": "Kapcsolat tesztelése", - "@settingsServersActionsTestConnection": {}, - "resourcesSortByAlbum": "Album", - "@resourcesSortByAlbum": {}, - "resourcesSortByAlbumCount": "Albumok száma", - "@resourcesSortByAlbumCount": {}, - "settingsServersActionsAdd": "Forrás hozzáadása", - "@settingsServersActionsAdd": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} album} other{{count} album}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsServersFieldsName": "Név", - "@settingsServersFieldsName": {}, - "settingsServersFieldsPassword": "Jelszó", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Felhasználónév", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Csatlakozás a {address} címhez sikertelen, ellenőrizd a beállításokat vagy a szervert", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "resourcesArtistListsSort": "Előadók rendezése", - "@resourcesArtistListsSort": {}, - "resourcesSongListDeleteAllTitle": "Törlöd a letöltéseket?", - "@resourcesSongListDeleteAllTitle": {} -} diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb deleted file mode 100644 index c46e840c..00000000 --- a/lib/l10n/app_it.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsStar": "Aggiungi ai preferiti", - "@actionsStar": {}, - "actionsUnstar": "Rimuovi dai preferiti", - "@actionsUnstar": {}, - "messagesNothingHere": "Non c'è niente qui…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Home", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Libreria", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Cerca", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Impostazioni", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Riproduci album", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Vedi album", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Ordina album", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Album} other{Album}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Vedi artista", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Ordina artisti", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Artista} other{Artisti}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Per genere", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "Preferiti", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "Riproduci playlist", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Playlist} other{Playlist}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Coda} other{Code}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Brani più popolari", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Brano} other{Brani}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Aggiunti di recente", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "Per artista", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Ascoltati frequentemente", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "Per nome", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Casuale", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Ascoltati di recente", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "Per anno", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Ricerca: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Ricerca", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Mostra di più…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Risultati della ricerca", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Licenze", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Pagina principale del progetto", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "Informazioni", - "@settingsAboutName": {}, - "settingsAboutVersion": "versione {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Musica", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Non eseguire lo scrobbling della cronologia d'ascolto", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Scrobbling della cronologia di ascolto", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Scrobbling delle riproduzioni", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Rete", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Bitrate massimo (rete dati)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Bitrate massimo (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Tempo di buffer massimo", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Tempo di buffer minimo", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} secondi", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Illimitato", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Pulisci la cache delle immagini", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Reimposta", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Aggiungi server", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Rimuovi", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Modifica server", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Salva", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Prova connessione", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Indirizzo", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Password", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Nome utente", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Connessione a {address} fallita, controlla le impostazioni o il server", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Connesso a {address} con successo!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Server", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Invia la password come token + salt", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Invia password in chiaro (deprecato, assicurati che la tua connessione sia sicura!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Forza password in chiaro", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "resourcesFilterYear": "Anno", - "@resourcesFilterYear": {}, - "resourcesSortByAlbum": "Album", - "@resourcesSortByAlbum": {}, - "actionsCancel": "Annulla", - "@actionsCancel": {}, - "actionsDelete": "Elimina", - "@actionsDelete": {}, - "actionsDownload": "Scarica", - "@actionsDownload": {}, - "actionsDownloadCancel": "Annulla download", - "@actionsDownloadCancel": {}, - "controlsShuffle": "Casuale", - "@controlsShuffle": {}, - "actionsDownloadDelete": "Elimina download", - "@actionsDownloadDelete": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} album} other{{count} album}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistCount": "{count,plural, =1{{count} artista} other{{count} artisti}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterAlbum": "Album", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "Artista", - "@resourcesFilterArtist": {}, - "resourcesFilterOwner": "Proprietario", - "@resourcesFilterOwner": {}, - "resourcesPlaylistCount": "{count,plural, =1{{count} playlist} other{{count} playlist}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{{count} brano} other{{count} brani}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "Questo rimuoverà tutti i file musicali scaricati.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSongListDeleteAllTitle": "Eliminare i download?", - "@resourcesSongListDeleteAllTitle": {}, - "settingsNetworkOptionsOfflineMode": "Modalità Offline", - "@settingsNetworkOptionsOfflineMode": {}, - "resourcesSortByAlbumCount": "Numero di Album", - "@resourcesSortByAlbumCount": {}, - "settingsNetworkOptionsStreamFormat": "Formato di streaming preferito", - "@settingsNetworkOptionsStreamFormat": {}, - "resourcesSortByUpdated": "Aggiornato di recente", - "@resourcesSortByUpdated": {}, - "resourcesSortByTitle": "Titolo", - "@resourcesSortByTitle": {}, - "settingsAboutActionsSupport": "Sostieni lo sviluppatore 💜", - "@settingsAboutActionsSupport": {}, - "settingsAboutShareLogs": "Condividi i log", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "Scegli un file log", - "@settingsAboutChooseLog": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Usa il server predefinito", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsNetworkOptionsOfflineModeOff": "Usa internet per sincronizzare la musica.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsOfflineModeOn": "Non usare internet per sincronizzare o riprodurre la musica.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsServersFieldsName": "Nome", - "@settingsServersFieldsName": {} -} diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb deleted file mode 100644 index af5e7db1..00000000 --- a/lib/l10n/app_ja.arb +++ /dev/null @@ -1,88 +0,0 @@ -{ - "navigationTabsHome": "ホーム", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "ライブラリ", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "検索", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "設定", - "@navigationTabsSettings": {}, - "resourcesAlbumName": "{count,plural, other{アルバム}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistName": "{count,plural, other{アーティスト}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterStarred": "星付きアルバム", - "@resourcesFilterStarred": {}, - "resourcesPlaylistName": "{count,plural, other{プレイリスト}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "人気曲", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, other{歌}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByFrequentlyPlayed": "よく聴くアルバム", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByRandom": "ランダムアルバム", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "最近再生した", - "@resourcesSortByRecentlyPlayed": {}, - "searchInputPlaceholder": "検索", - "@searchInputPlaceholder": {}, - "settingsAboutActionsProjectHomepage": "ホームページ", - "@settingsAboutActionsProjectHomepage": {}, - "settingsMusicName": "音楽", - "@settingsMusicName": {}, - "settingsNetworkName": "ネット", - "@settingsNetworkName": {}, - "settingsResetName": "リセット", - "@settingsResetName": {}, - "settingsServersName": "サーバ", - "@settingsServersName": {}, - "settingsServersFieldsPassword": "パスワルド", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "ウーザ名", - "@settingsServersFieldsUsername": {}, - "actionsDelete": "削除", - "@actionsDelete": {}, - "actionsCancel": "キャンセル", - "@actionsCancel": {}, - "actionsOk": "はい", - "@actionsOk": {}, - "resourcesFilterYear": "年", - "@resourcesFilterYear": {}, - "resourcesFilterAlbum": "アルブム", - "@resourcesFilterAlbum": {}, - "settingsServersActionsDelete": "削除", - "@settingsServersActionsDelete": {}, - "settingsServersFieldsName": "名前", - "@settingsServersFieldsName": {}, - "actionsDownloadCancel": "ダウンロードをキャンセル", - "@actionsDownloadCancel": {}, - "actionsDownloadDelete": "ダウンロード削除", - "@actionsDownloadDelete": {}, - "actionsDownload": "ダウンロード", - "@actionsDownload": {} -} diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb deleted file mode 100644 index 331ca66a..00000000 --- a/lib/l10n/app_ko.arb +++ /dev/null @@ -1,189 +0,0 @@ -{ - "actionsDelete": "삭제", - "actionsCancel": "취소", - "actionsDownload": "다운로드", - "actionsDownloadCancel": "다운로드 중단", - "actionsDownloadDelete": "다운로드된 파일 삭제", - "actionsOk": "확인", - "actionsStar": "별점", - "actionsUnstar": "별점 제거", - "controlsShuffle": "무작위 재생", - "messagesNothingHere": "항목 없음…", - "navigationTabsHome": "홈", - "navigationTabsLibrary": "라이브러리", - "navigationTabsSearch": "검색", - "navigationTabsSettings": "설정", - "resourcesAlbumActionsPlay": "앨범 재생", - "resourcesAlbumActionsView": "앨범 보기", - "resourcesAlbumCount": "{count,plural, other{{count}개 앨범}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesAlbumListsSort": "앨범 정렬", - "resourcesAlbumName": "{count,plural, other{앨범}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "아티스트 보기", - "resourcesArtistCount": "{count,plural, other{{count} 아티스트}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistListsSort": "아티스트 정렬", - "resourcesArtistName": "{count,plural, other{아티스트}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterAlbum": "앨범", - "resourcesFilterArtist": "아티스트", - "resourcesFilterGenre": "장르", - "resourcesFilterOwner": "소유자", - "resourcesFilterStarred": "평가됨", - "resourcesFilterYear": "년", - "resourcesPlaylistActionsPlay": "재생목록 재생", - "resourcesPlaylistCount": "{count,plural, other{{count} 재생목록}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesPlaylistName": "{count,plural, other{재생목록}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, other{대기열}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, other{{count} 노래}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "다운로드한 모든 노래를 삭제합니다.", - "resourcesSongListDeleteAllTitle": "다운로드한 노래를 삭제하시겠습니까?", - "resourcesSongName": "{count,plural, other{노래}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "새로 추가됨", - "resourcesSortByAlbum": "앨범", - "resourcesSortByAlbumCount": "앨범 개수", - "resourcesSortByArtist": "아티스트", - "resourcesSortByFrequentlyPlayed": "자주 듣는 노래", - "resourcesSortByName": "이름", - "resourcesSortByRandom": "랜덤", - "resourcesSortByRecentlyPlayed": "최근 재생된 순", - "resourcesSortByTitle": "곡명", - "resourcesSortByUpdated": "수정된 날짜", - "resourcesSortByYear": "년", - "searchHeaderTitle": "검색: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "검색", - "searchMoreResults": "더 보기…", - "searchNowPlayingContext": "검색 결과", - "settingsAboutActionsLicenses": "저작권", - "settingsAboutActionsProjectHomepage": "프로젝트 홈페이지", - "settingsAboutActionsSupport": "개발자 지원하기💜", - "settingsAboutName": "subtracks에 대하여", - "settingsAboutShareLogs": "로그 공유", - "settingsAboutChooseLog": "로그 파일을 선택해주세요", - "settingsAboutVersion": "버전: {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "음악", - "settingsNetworkName": "네트워크", - "settingsNetworkOptionsMaxBitrateMobileTitle": "최대 비트레이트 (모바일 데이터 사용 시)", - "settingsNetworkOptionsMaxBitrateWifiTitle": "최대 비트레이트 (와이파이 사용 시)", - "settingsNetworkOptionsMaxBufferTitle": "최대 버퍼 시간", - "settingsNetworkOptionsMinBufferTitle": "최소 버퍼 시간", - "settingsNetworkOptionsOfflineMode": "오프라인 모드", - "settingsNetworkOptionsOfflineModeOff": "노래를 동기화하기 위해 인터넷을 사용합니다.", - "settingsNetworkOptionsOfflineModeOn": "노래를 듣거나 동기화하기 위해 인터넷을 사용하지 않습니다.", - "settingsNetworkOptionsStreamFormat": "선호하는 스트리밍 포맷", - "settingsNetworkOptionsStreamFormatServerDefault": "서버를 우선하여 사용합니다", - "settingsNetworkValuesSeconds": "{value} 초", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "제한하지 않음", - "settingsResetActionsClearImageCache": "이미지 캐시 비우기", - "settingsResetName": "초기화", - "settingsServersActionsAdd": "서버 추가", - "settingsServersActionsDelete": "삭제", - "settingsServersActionsEdit": "서버 수정", - "settingsServersActionsSave": "저장", - "settingsServersActionsTestConnection": "연결 테스트", - "settingsServersFieldsAddress": "주소", - "settingsServersFieldsName": "이름", - "settingsServersFieldsPassword": "비밀번호", - "settingsServersFieldsUsername": "사용자 이름", - "settingsServersMessagesConnectionFailed": "{address}에 연결하지 못했습니다. 서버 구성이 올바른지 확인해주세요", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "{address}에 연결했습니다", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "서버", - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "비밀번호를 토큰과 솔트로 전달", - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "평문으로 비밀번호 전송(legacy, 보안연결 사용 시에만 사용하세요)", - "settingsServersOptionsForcePlaintextPasswordTitle": "비밀번호를 평문으로 보내기" -} diff --git a/lib/l10n/app_nb.arb b/lib/l10n/app_nb.arb deleted file mode 100644 index 0e515ead..00000000 --- a/lib/l10n/app_nb.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsStar": "Stjernemerk", - "@actionsStar": {}, - "actionsUnstar": "Fjern stjernemerking", - "@actionsUnstar": {}, - "messagesNothingHere": "Ingenting her …", - "@messagesNothingHere": {}, - "navigationTabsHome": "Hjem", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Bibliotek", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Søk", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Innstillinger", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Spill album", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Vis album", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Sorter album", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Album} other{Album}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Vis artist", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Sorter artister", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Artist} other{Artister}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Etter sjanger", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "Stjernemerket", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "Spill av spilleliste", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Spilleliste} other{Spillelister}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Kø} other{Køer}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Toppspor", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Spor} other{Spor}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Nylig tillagt", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "Etter artist", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Ofte spilt", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "Etter navn", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Tilfeldig", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Nylig spilt", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "Etter år", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Søk: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Søk", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Mer …", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Søkeresultater", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Lisenser", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Prosjekthjemmeside", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "Om", - "@settingsAboutName": {}, - "settingsAboutVersion": "versjon {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Musikk", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Ikke utfør sporinfodeling av avspillingshistorikk", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Sporinfodelings-avspillinghistorikk", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Sporinfodelingsavspillinger", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Nettverk", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Maksimal bitrate (mobil)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Maksimal bitrate (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Maksimal mellomlagringstid", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Minimal mellomlagringstid", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value} kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} sekunder", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Ubegrenset", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Tøm bildehurtiglager", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Tilbakestill", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Legg til tjener", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Slett", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Rediger tjener", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Lagre", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Test tilkobling", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Adresse", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Passord", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Brukernavn", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Tilkobling til {address} mislyktes. Sjekk innstillingene eller tjeneren.", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Tilkobling til {address} OK.", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Tjenere", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Send passord som symbol + salt", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Send passord i klartekst (Foreldet. Forsikre deg om at tilkoblingen er sikker.)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Påtving klartekstspassord", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "actionsDownload": "Last ned", - "@actionsDownload": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "actionsDelete": "Slett", - "@actionsDelete": {}, - "resourcesFilterAlbum": "Album", - "@resourcesFilterAlbum": {}, - "resourcesFilterOwner": "Eier", - "@resourcesFilterOwner": {}, - "resourcesSongListDeleteAllTitle": "Slette nedlastinger?", - "@resourcesSongListDeleteAllTitle": {}, - "actionsDownloadDelete": "Slett nedlastet", - "@actionsDownloadDelete": {}, - "actionsCancel": "Avbryt", - "@actionsCancel": {}, - "resourcesFilterArtist": "Artist", - "@resourcesFilterArtist": {}, - "resourcesSortByUpdated": "Nylig oppdatert", - "@resourcesSortByUpdated": {}, - "settingsNetworkOptionsOfflineModeOn": "Bruk ikke Internett til å synkronisere eller spille av musikk.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "resourcesPlaylistCount": "{count,plural, =1{{count} spilleliste} other{{count} spillelister}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByTitle": "Tittel", - "@resourcesSortByTitle": {}, - "actionsDownloadCancel": "Avbryt nedlasting", - "@actionsDownloadCancel": {}, - "settingsServersFieldsName": "Navn", - "@settingsServersFieldsName": {}, - "controlsShuffle": "Miks", - "@controlsShuffle": {}, - "settingsNetworkOptionsStreamFormat": "Foretrukket streamingformat", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsAboutActionsSupport": "Støtt utvikleren 💜", - "@settingsAboutActionsSupport": {}, - "resourcesArtistCount": "{count,plural, =1{{count} artist} other{{count} artister}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterYear": "År", - "@resourcesFilterYear": {}, - "settingsNetworkOptionsOfflineModeOff": "Bruk Internett til å synkronisere musikk.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsAboutChooseLog": "Velg en loggfil", - "@settingsAboutChooseLog": {}, - "settingsAboutShareLogs": "Dele logger", - "@settingsAboutShareLogs": {}, - "resourcesSortByAlbumCount": "Albumantall", - "@resourcesSortByAlbumCount": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Bruk serverens standardinnstilling", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "resourcesSortByAlbum": "Album", - "@resourcesSortByAlbum": {}, - "settingsNetworkOptionsOfflineMode": "Offline-modus", - "@settingsNetworkOptionsOfflineMode": {}, - "resourcesSongListDeleteAllContent": "Dette fjerner alle nedlastede sangfiler.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} album} other{{count} album}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{{count} sang} other{{count} sanger}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - } -} diff --git a/lib/l10n/app_pa.arb b/lib/l10n/app_pa.arb deleted file mode 100644 index 9555378d..00000000 --- a/lib/l10n/app_pa.arb +++ /dev/null @@ -1,196 +0,0 @@ -{ - "actionsStar": "ਤਾਰਾ", - "@actionsStar": {}, - "actionsUnstar": "ਤਾਰਾ ਹਟਾਓ", - "@actionsUnstar": {}, - "messagesNothingHere": "ਇੱਥੇ ਕੁਝ ਨਹੀਂ ਹੈ…", - "@messagesNothingHere": {}, - "navigationTabsHome": "ਘਰ", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "ਲਾਇਬ੍ਰੇਰੀ", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "ਖੋਜ", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "ਸੈਟਿੰਗਾਂ", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "ਐਲਬਮ ਚਲਾਓ", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "ਐਲਬਮ ਦੇਖੋ", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "ਐਲਬਮਾਂ ਨੂੰ ਕਰਮਬੱਧ ਕਰੋ", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{ਐਲਬਮ} other{ਐਲਬਮਾਂ}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "ਕਲਾਕਾਰ ਦੇਖੋ", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "ਕਲਾਕਾਰਾਂ ਦੀ ਛਾਂਟੀ", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{ਕਲਾਕਾਰ} other{ਕਲਾਕਾਰਾਂ}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "ਸ਼ੈਲੀ ਦੁਆਰਾ", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "ਸਟਾਰ ਕੀਤੇ ਗਏ", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "ਪਲੇਲਿਸਟ ਚਲਾਓ", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{ਪਲੇਲਿਸਟ} other{ਪਲੇਲਿਸਟਸ}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{ਕਤਾਰ} other{ਕਤਾਰਾਂ}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "ਉੱਤਮ ਗਾਣੇ", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{ਗਾਣਾ} other{ਗਾਣੇ}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "ਤਾਜ਼ਾ ਸ਼ਾਮਿਲ", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "ਕਲਾਕਾਰ ਦੁਆਰਾ", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "ਅਕਸਰ ਚਲਾਏ ਗਏ", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "ਨਾਮ ਦੁਆਰਾ", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "ਅਟਕਲ-ਪੱਚੂ", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "ਹਾਲ ਹੀ ਵਿੱਚ ਚਲਾਏ ਗਏ", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "ਸਾਲ ਦੁਆਰਾ", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "ਖੋਜ: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "ਖੋਜੋ", - "@searchInputPlaceholder": {}, - "searchMoreResults": "ਹੋਰ…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "ਖੋਜ ਨਤੀਜੇ", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "ਲਾਇਸੰਸ", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "ਪ੍ਰੋਜੈਕਟ ਹੋਮਪੇਜ", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "ਬਾਰੇ", - "@settingsAboutName": {}, - "settingsAboutVersion": "ਸੰਸਕਰਣ {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "ਸੰਗੀਤ", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "ਸੁਣੇ ਹੋਏ ਗਾਣੇ ਸਕ੍ਰੋਬਲ ਨਾ ਕਰੋ", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "ਸੁਣੇ ਹੋਏ ਗਾਣੇ ਸਕ੍ਰੋਬਲ ਕਰੋ", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "ਗਾਣੇ ਸਕ੍ਰੋਬਲ ਕਰੋ", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "ਨੈੱਟਵਰਕ", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "ਵੱਧ ਤੋਂ ਵੱਧ ਬਿੱਟਰੇਟ (ਮੋਬਾਈਲ)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "ਵੱਧ ਤੋਂ ਵੱਧ ਬਿੱਟਰੇਟ (ਵਾਈ-ਫਾਈ)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "ਵੱਧ ਤੋਂ ਵੱਧ ਬਫਰ ਸਮਾਂ", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "ਘੱਟੋ-ਘੱਟ ਬਫਰ ਸਮਾਂ", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} ਸਕਿੰਟ", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "ਅਸੀਮਿਤ", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "ਚਿੱਤਰ ਕੈਸ਼ ਸਾਫ਼ ਕਰੋ", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "ਰੀਸੈਟ ਕਰੋ", - "@settingsResetName": {}, - "settingsServersActionsAdd": "ਸਰਵਰ ਸ਼ਾਮਲ ਕਰੋ", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "ਮਿਟਾਓ", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "ਸਰਵਰ ਦਾ ਸੰਪਾਦਨ", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "ਸੇਵ ਕਰੋ", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "ਟੈਸਟ ਕਨੈਕਸ਼ਨ", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "ਪਤਾ", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "ਪਾਸਵਰਡ", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "ਯੂਜ਼ਰਨੇਮ", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "{address} ਨਾਲ ਕਨੈਕਸ਼ਨ ਅਸਫਲ, ਸੈਟਿੰਗਾਂ ਜਾਂ ਸਰਵਰ ਦੀ ਜਾਂਚ ਕਰੋ", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "{address} ਨਾਲ ਕਨੈਕਸ਼ਨ ਠੀਕ ਹੈ!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "ਸਰਵਰ", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "ਪਾਸਵਰਡ ਨੂੰ ਟੋਕਨ + ਸਾਲ੍ਟ ਵਜੋਂ ਭੇਜੋ", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "ਪਾਸਵਰਡ ਨੂੰ ਸਾਦੇ ਟੈਕਸਟ ਵਿੱਚ ਭੇਜੋ (ਪੁਰਾਣਾ, ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਤੁਹਾਡਾ ਕਨੈਕਸ਼ਨ ਸੁਰੱਖਿਅਤ ਹੈ!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "ਸਾਦੇ ਪਾਸਵਰਡ ਨੂੰ ਜਬਰੀ ਕਰੋ", - "@settingsServersOptionsForcePlaintextPasswordTitle": {} -} \ No newline at end of file diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb deleted file mode 100644 index a319d462..00000000 --- a/lib/l10n/app_pl.arb +++ /dev/null @@ -1,232 +0,0 @@ -{ - "actionsStar": "Ulubione", - "@actionsStar": {}, - "actionsUnstar": "Usuń ulubione", - "@actionsUnstar": {}, - "messagesNothingHere": "Pusto tu…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Strona główna", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Kolekcja", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Wyszukaj", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Ustawienia", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Otwarzaj album", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Zobacz album", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Sortowanie albumów", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Album} few{Albumy} many{Albumów} other{Albumów}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Zobacz wykonawcę", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Sortowanie wykonawców", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Wykonawca} few{Wykonawcy} many{Wykonawców} other{Wykonawców}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Wg gatunku", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "Ulubione", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "Odtwarzaj playlistę", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Playlista} few{Playlisty} many{Playlist} other{Playlist}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Kolejka} few{Kolejki} many{Kolejek} other{Kolejek}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Najpopularniejsze utwory", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Utwór} few{Utwory} many{Utworów} other{Utworów}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Ostatnio dodane", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "Wg wykonawcy", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Często odtwarzane", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "Wg nazwy", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Losowo", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Ostatnio odtwarzane", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "Wg roku", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Szukaj: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Szukaj", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Więcej…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Wyniki wyszukiwania", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Licencje", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Strona główna projektu", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "Informacje o projekcie", - "@settingsAboutName": {}, - "settingsAboutVersion": "wersja {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Muzyka", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Nie śledź swojej historii odtwarzania", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Śledź swoją histrorię odtwarzania", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Śledzenie odtworzeń", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Sieć", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Maksymalny bitrate (sieć komórkowa)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Maksymalny bitrate (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Maksymalny czas buforowania", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Minimalny czas buforowania", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} sekund", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Bez ograniczeń", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Wyczyść pamięć podręczną obrazów", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Przywracanie", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Dodaj serwer", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Usuń", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Edytuj serwer", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Zapisz", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Przetestuj połączenie", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Adres serwera", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Hasło", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Nazwa użytkownika", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Błąd połączenia z {address}, sprawdź ustawienia lub serwer", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Połączeno poprawnie z {address}!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Serwery", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Wyślij hasło jako token i ciąg zaburzający", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Wyślij hasło jako tekst (przestarzałe, upewnij się, że Twoje połączenie jest zabezpieczone)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Wymuś hasło jako tekst (plaintext)", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "actionsDownload": "Pobierz", - "@actionsDownload": {}, - "actionsOk": "Ok", - "@actionsOk": {}, - "actionsDelete": "Usuń", - "@actionsDelete": {}, - "resourcesFilterAlbum": "Album", - "@resourcesFilterAlbum": {}, - "resourcesFilterOwner": "Posiadacz", - "@resourcesFilterOwner": {}, - "resourcesSongListDeleteAllTitle": "Usunąć pobrane?", - "@resourcesSongListDeleteAllTitle": {}, - "actionsDownloadDelete": "Usuń pobrane", - "@actionsDownloadDelete": {}, - "actionsCancel": "Anuluj", - "@actionsCancel": {}, - "resourcesFilterArtist": "Artysta", - "@resourcesFilterArtist": {}, - "resourcesSortByUpdated": "Ostatnio zaktualizowane", - "@resourcesSortByUpdated": {}, - "resourcesSortByTitle": "Tytuł", - "@resourcesSortByTitle": {}, - "actionsDownloadCancel": "Anuluj pobieranie", - "@actionsDownloadCancel": {}, - "settingsServersFieldsName": "Nazwa", - "@settingsServersFieldsName": {}, - "controlsShuffle": "Losowo", - "@controlsShuffle": {}, - "settingsNetworkOptionsStreamFormat": "Preferowany format streamów", - "@settingsNetworkOptionsStreamFormat": {}, - "resourcesFilterYear": "Rok", - "@resourcesFilterYear": {}, - "resourcesSortByAlbum": "Album", - "@resourcesSortByAlbum": {}, - "settingsNetworkOptionsOfflineMode": "Tryb offline", - "@settingsNetworkOptionsOfflineMode": {} -} diff --git a/lib/l10n/app_pt-BR.arb b/lib/l10n/app_pt-BR.arb deleted file mode 100644 index cb0bb7a7..00000000 --- a/lib/l10n/app_pt-BR.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsDelete": "Deletar", - "@actionsDelete": {}, - "actionsDownload": "Download", - "@actionsDownload": {}, - "actionsDownloadCancel": "Cancelar download", - "@actionsDownloadCancel": {}, - "actionsDownloadDelete": "Excluir arquivos baixados", - "@actionsDownloadDelete": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "actionsStar": "Estrela", - "@actionsStar": {}, - "controlsShuffle": "Misturar", - "@controlsShuffle": {}, - "messagesNothingHere": "Nada aqui…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Home", - "@navigationTabsHome": {}, - "navigationTabsSearch": "Procurar", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Configurações", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Tocar álbum", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Ver álbum", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Classificar álbuns", - "@resourcesAlbumListsSort": {}, - "resourcesArtistActionsView": "Ver artistas", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Classificar artistas", - "@resourcesArtistListsSort": {}, - "resourcesFilterArtist": "Artista", - "@resourcesFilterArtist": {}, - "resourcesFilterGenre": "Gênero", - "@resourcesFilterGenre": {}, - "resourcesFilterOwner": "Proprietário", - "@resourcesFilterOwner": {}, - "resourcesFilterStarred": "Estrelado por", - "@resourcesFilterStarred": {}, - "resourcesFilterYear": "Ano", - "@resourcesFilterYear": {}, - "resourcesPlaylistActionsPlay": "Tocar lista", - "@resourcesPlaylistActionsPlay": {}, - "resourcesSongListDeleteAllTitle": "Deletar arquivos baixados?", - "@resourcesSongListDeleteAllTitle": {}, - "resourcesSongListsArtistTopSongs": "Melhores músicas", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSortByAdded": "Adicionado recentemente", - "@resourcesSortByAdded": {}, - "resourcesSortByAlbum": "Álbum", - "@resourcesSortByAlbum": {}, - "resourcesSortByAlbumCount": "Contagem de álbuns", - "@resourcesSortByAlbumCount": {}, - "resourcesSortByArtist": "Artista", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Mais tocados", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByRandom": "Aleatório", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Tocado recentemente", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByTitle": "Título", - "@resourcesSortByTitle": {}, - "resourcesSortByUpdated": "Atualizado recentemente", - "@resourcesSortByUpdated": {}, - "actionsUnstar": "Sem estrela", - "@actionsUnstar": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} album} other{{count} albums}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongName": "{count,plural, =1{Song} other{Songs}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "searchInputPlaceholder": "Pesquisar", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Mais…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Resultado da pesquisa", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Licenças", - "@settingsAboutActionsLicenses": {}, - "settingsAboutName": "Sobre", - "@settingsAboutName": {}, - "settingsAboutShareLogs": "Compartilhar logs", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "Escolha um arquivo de log", - "@settingsAboutChooseLog": {}, - "settingsNetworkName": "Rede", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Qualidade máxima (rede móvel)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Qualidade máxima (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Tempo máximo de buffer", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Tempo mínimo de buffer", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkOptionsOfflineMode": "Modo off-line", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsOfflineModeOff": "Usar a internet para sincronizar as músicas.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsStreamFormat": "Formato preferido para stream", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Usar servidor padrão", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsNetworkValuesUnlimitedKbps": "Ilimitado", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Limpar cache de imagens", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Resetar", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Adicionar fonte", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Deletar", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Editar fonte", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Salvar", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Testar conexão", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Endereço", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Senha", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Usuário", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "A conexão com {address} falhou, verifique as configurações ou servidor", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Conexãocom {address} feita com sucesso!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Fontes", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Enviar senha como token + salt", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "searchHeaderTitle": "Pesquisa: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "settingsAboutActionsProjectHomepage": "Página do projeto", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutVersion": "Versão {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicOptionsScrobbleDescriptionOff": "Não fazer scrobble do histórico de reproduções", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Scrobble do histórico de reproduções", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Fazer scrobble das reproduções", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} segundos", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "actionsCancel": "Cancelar", - "@actionsCancel": {}, - "navigationTabsLibrary": "Biblioteca", - "@navigationTabsLibrary": {}, - "resourcesFilterAlbum": "Álbum", - "@resourcesFilterAlbum": {}, - "resourcesSongListDeleteAllContent": "Isso irá remover todos os arquivos de músicas baixados.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSortByName": "Nome", - "@resourcesSortByName": {}, - "resourcesSortByYear": "Ano", - "@resourcesSortByYear": {}, - "settingsAboutActionsSupport": "Apoie o desenvolvedor 💜", - "@settingsAboutActionsSupport": {}, - "settingsMusicName": "Música", - "@settingsMusicName": {}, - "settingsServersFieldsName": "Nome", - "@settingsServersFieldsName": {}, - "settingsNetworkOptionsOfflineModeOn": "Não usar a Internet para sincronizar ou tocar músicas.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Forçar senha em texto simples", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Enviar senha em texto simples (tenha certeza que sua conexão é segura!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "resourcesAlbumName": "{count,plural, =1{Album} other{Albums}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistCount": "{count,plural, =1{{count} artist} other{{count} artists}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesPlaylistCount": "{count,plural, =1{{count} playlist} other{{count} playlists}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Queue} other{Queues}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistName": "{count,plural, =1{Artist} other{Artists}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesPlaylistName": "{count,plural, =1{Playlist} other{Playlists}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{{count} song} other{{count} songs}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - } -} diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb deleted file mode 100644 index aa03173d..00000000 --- a/lib/l10n/app_pt.arb +++ /dev/null @@ -1,230 +0,0 @@ -{ - "actionsStar": "Favorito", - "@actionsStar": {}, - "actionsUnstar": "Remover favorito", - "@actionsUnstar": {}, - "messagesNothingHere": "Não existe nada…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Início", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Biblioteca", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Procurar", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Definições", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Tocar Álbum", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Ver Álbum", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Ordenar Álbuns", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Álbum} other{Álbuns}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Ver Artista", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Ordenar Artistas", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Artista} other{Artistas}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Por Género", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "Favoritos", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "Tocar Playlist", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Lista} other{Listas}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Fila} other{Filas}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Top Músicas", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Música} other{Músicas}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Adicionado recentemente", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "Por Artista", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Mais Tocado", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "Por Nome", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Aleatório", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Ouviu recentemente", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "Por Ano", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Procurar: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Procurar", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Mais…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Resultados da Pesquisa", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Licenças", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Página do Projeto", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "Acerca", - "@settingsAboutName": {}, - "settingsAboutVersion": "versão {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Música", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Não enviar histórico de reproduções por scrobble", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Enviar histórico de reproduções por scrobble", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Enviar reproduções por scrobble", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Rede", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Bitrate Máximo (móvel)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Bitrate Máximo (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Tempo de buffer máximo", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Tempo de buffer mínimo", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} segundos", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Ilimitado", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Limpar cache de Imagens", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Redefinir", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Adicionar Servidor", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Apagar", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Editar Servidor", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Guardar", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Testar Ligação", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Endereço", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Senha", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Nome de utilizador", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Ligação a {address} falhou, verifique definições ou servidor", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Ligação a {address} OK!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Servidores", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Enviar senha como token + sal", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Enviar senha em texto simples (antigo, certifique-se que a sua ligação é segura!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Forçar password em texto simples", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "actionsCancel": "Cancelar", - "@actionsCancel": {}, - "actionsDelete": "Apagar", - "@actionsDelete": {}, - "actionsDownload": "Descarregar", - "@actionsDownload": {}, - "actionsDownloadCancel": "Cancelar descarga", - "@actionsDownloadCancel": {}, - "actionsDownloadDelete": "Apagar descarga", - "@actionsDownloadDelete": {}, - "resourcesFilterAlbum": "Álbum", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "Artista", - "@resourcesFilterArtist": {}, - "resourcesFilterYear": "Ano", - "@resourcesFilterYear": {}, - "resourcesSortByAlbum": "Álbum", - "@resourcesSortByAlbum": {}, - "settingsAboutActionsSupport": "Apoie o programador 💜", - "@settingsAboutActionsSupport": {}, - "settingsNetworkOptionsOfflineMode": "Modo offline", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsOfflineModeOff": "Usar a internet para sincronizar música.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsOfflineModeOn": "Não usar a internet para sincronizar ou tocar música.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsNetworkOptionsStreamFormat": "Formato preferido de streaming", - "@settingsNetworkOptionsStreamFormat": {}, - "resourcesSortByTitle": "Título", - "@resourcesSortByTitle": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "controlsShuffle": "Aleatório", - "@controlsShuffle": {} -} diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb deleted file mode 100644 index 01eadfeb..00000000 --- a/lib/l10n/app_ru.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsStar": "Избранное", - "@actionsStar": {}, - "actionsUnstar": "Убрать из избранного", - "@actionsUnstar": {}, - "messagesNothingHere": "Здесь ничего нет…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Главная", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "Библиотека", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "Поиск", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "Настройки", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Воспроизвести альбом", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "Посмотреть альбом", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "Сортировка альбомов", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{Альбом} few{Альбомов} many{Альбомов} other{Альбомы}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Посмотреть исполнителя", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Сортировать исполнителей", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{Исполнитель} few{Исполнителей} many{Исполнителей} other{Исполнители}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "По жанру", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "Избранные", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "Воспроизвести плейлист", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, =1{Плейлист} few{Плейлистов} many{Плейлистов} other{Плейлисты}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Очередь} few{Очередей} many{Очередей} other{Очереди}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Лучшие треки", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{Трек} few{Треков} many{Треков} other{Треки}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Недавно добавленные", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "По исполнителям", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "Часто проигрываемые", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "По имени", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "Случайно", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "Недавно проигранные", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "По году", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "Поиск: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Поиск", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Больше…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "Результаты поиска", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Лицензии", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "Сайт проекта", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "О Subtracks", - "@settingsAboutName": {}, - "settingsAboutVersion": "версия {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Музыка", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Не отправлять историю воспроизведений", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Скробблинг истории воспроизведения", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "Скробблинг", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "Сеть", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Максимальный битрейт (мобильный интернет)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Максимальный битрейт (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "Максимальное время буферизации", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Минимальное время буферизации", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value} кбит/с", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} секунд", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Без ограничений", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "Очистить кэш изображения", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "Сброс", - "@settingsResetName": {}, - "settingsServersActionsAdd": "Добавить сервер", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "Удалить", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "Редактировать сервер", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "Сохранить", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Проверить подключение", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "Адрес", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "Пароль", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Имя пользователя", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Не удалось подключиться к {address}, проверьте настройки или сервер", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Подключение к {address} установлено!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Серверы", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Отправить пароль в виде токена", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Отправить пароль в виде текста (устарело, убедитесь, что ваше соединение безопасно!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Принудительно использовать текстовой пароль", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "settingsAboutShareLogs": "Поделиться журналами", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "Выбрать файл журнала", - "@settingsAboutChooseLog": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Использовать сервер по умолчанию", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "actionsDownload": "Скачать", - "@actionsDownload": {}, - "actionsDownloadCancel": "Отменить загрузку", - "@actionsDownloadCancel": {}, - "actionsCancel": "Отменить", - "@actionsCancel": {}, - "resourcesSongCount": "{count,plural, =1{{count} трек} few{{count} треков} many{{count} треков} other{{count} треки}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAlbum": "По альбомам", - "@resourcesSortByAlbum": {}, - "resourcesSortByTitle": "По заголовку", - "@resourcesSortByTitle": {}, - "resourcesSortByUpdated": "По недавно обновленному", - "@resourcesSortByUpdated": {}, - "resourcesSortByAlbumCount": "По количеству альбомов", - "@resourcesSortByAlbumCount": {}, - "settingsNetworkOptionsOfflineMode": "Автономный режим", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsOfflineModeOff": "Использовать интернет для синхронизации музыки.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsServersFieldsName": "Имя", - "@settingsServersFieldsName": {}, - "actionsDelete": "Удалить", - "@actionsDelete": {}, - "actionsDownloadDelete": "Удалить загруженное", - "@actionsDownloadDelete": {}, - "actionsOk": "ОК", - "@actionsOk": {}, - "controlsShuffle": "Перемешать", - "@controlsShuffle": {}, - "resourcesFilterArtist": "По исполнителю", - "@resourcesFilterArtist": {}, - "resourcesFilterAlbum": "По альбомам", - "@resourcesFilterAlbum": {}, - "resourcesFilterYear": "По годам", - "@resourcesFilterYear": {}, - "resourcesFilterOwner": "По владельцу", - "@resourcesFilterOwner": {}, - "resourcesSongListDeleteAllContent": "Это удалит все загруженные файлы песен.", - "@resourcesSongListDeleteAllContent": {}, - "settingsNetworkOptionsStreamFormat": "Предпочтительный формат потока", - "@settingsNetworkOptionsStreamFormat": {}, - "resourcesSongListDeleteAllTitle": "Удалить загрузки?", - "@resourcesSongListDeleteAllTitle": {}, - "settingsNetworkOptionsOfflineModeOn": "Не использовать интернет для синхронизации или воспроизведения музыки.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsAboutActionsSupport": "Поддержать разработчика", - "@settingsAboutActionsSupport": {}, - "resourcesArtistCount": "{count,plural, =1{{count} исполнитель} other{{count} исполнители}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesPlaylistCount": "{count,plural, =1{{count} плейлист} other{{count} плейлисты}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesAlbumCount": "{count,plural, =1{{count} альбом} other{{count} альбомы}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - } -} diff --git a/lib/l10n/app_sv.arb b/lib/l10n/app_sv.arb deleted file mode 100644 index 02ac8c33..00000000 --- a/lib/l10n/app_sv.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsDownload": "Ladda ned", - "@actionsDownload": {}, - "actionsOk": "OK", - "@actionsOk": {}, - "resourcesQueueName": "{count,plural, =1{Kö} other{Köer}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "settingsMusicOptionsScrobbleDescriptionOff": "Skrobbla ej spelhistorik", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsNetworkValuesSeconds": "{value} sekunder", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "resourcesSongListsArtistTopSongs": "Topplåtar", - "@resourcesSongListsArtistTopSongs": {}, - "navigationTabsSettings": "Inställningar", - "@navigationTabsSettings": {}, - "actionsStar": "Markera", - "@actionsStar": {}, - "resourcesSortByName": "Namn", - "@resourcesSortByName": {}, - "settingsServersActionsAdd": "Lägg till källa", - "@settingsServersActionsAdd": {}, - "resourcesArtistActionsView": "Visa artist", - "@resourcesArtistActionsView": {}, - "resourcesFilterStarred": "Markerad", - "@resourcesFilterStarred": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Maximal bitrate (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "actionsDelete": "Radera", - "@actionsDelete": {}, - "settingsAboutName": "Om", - "@settingsAboutName": {}, - "resourcesFilterAlbum": "Album", - "@resourcesFilterAlbum": {}, - "resourcesFilterOwner": "Ägare", - "@resourcesFilterOwner": {}, - "navigationTabsSearch": "Sök", - "@navigationTabsSearch": {}, - "resourcesSongListDeleteAllTitle": "Radera nedladdningar?", - "@resourcesSongListDeleteAllTitle": {}, - "settingsServersMessagesConnectionFailed": "Anslutning till {adress} misslyckades, kontrollera inställningar eller server", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "actionsDownloadDelete": "Radera nedladdat", - "@actionsDownloadDelete": {}, - "actionsCancel": "Avbryt", - "@actionsCancel": {}, - "settingsAboutActionsProjectHomepage": "Projekthemsida", - "@settingsAboutActionsProjectHomepage": {}, - "resourcesFilterArtist": "Artist", - "@resourcesFilterArtist": {}, - "resourcesAlbumListsSort": "Sortera album", - "@resourcesAlbumListsSort": {}, - "settingsNetworkOptionsMaxBufferTitle": "Maximal bufferttid", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsServersActionsSave": "Spara", - "@settingsServersActionsSave": {}, - "settingsNetworkOptionsMinBufferTitle": "Minimum buffertid", - "@settingsNetworkOptionsMinBufferTitle": {}, - "resourcesSortByFrequentlyPlayed": "Spelas oftast", - "@resourcesSortByFrequentlyPlayed": {}, - "settingsResetName": "Återställ", - "@settingsResetName": {}, - "searchMoreResults": "Mer …", - "@searchMoreResults": {}, - "navigationTabsHome": "Hem", - "@navigationTabsHome": {}, - "resourcesArtistName": "{count,plural, =1{Artist} other{Artister}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByUpdated": "Nyligen uppdaterade", - "@resourcesSortByUpdated": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkOptionsOfflineModeOn": "Använd inte internet för att uppdatera eller spela upp musik.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "resourcesAlbumName": "{count,plural, =1{Album} other{Album}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "settingsResetActionsClearImageCache": "Rensa bildcache", - "@settingsResetActionsClearImageCache": {}, - "searchInputPlaceholder": "Sök", - "@searchInputPlaceholder": {}, - "settingsAboutVersion": "version {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "resourcesSortByAdded": "Nyligen tillagda", - "@resourcesSortByAdded": {}, - "settingsNetworkValuesUnlimitedKbps": "Obegränsad", - "@settingsNetworkValuesUnlimitedKbps": {}, - "resourcesFilterGenre": "Genre", - "@resourcesFilterGenre": {}, - "settingsServersFieldsPassword": "Lösenord", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Användarnamn", - "@settingsServersFieldsUsername": {}, - "searchHeaderTitle": "Sök: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "actionsUnstar": "Omarkera", - "@actionsUnstar": {}, - "resourcesPlaylistCount": "{count,plural, =1{{count} spellista} other{{count} spellistor}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByYear": "Efter år", - "@resourcesSortByYear": {}, - "resourcesSortByTitle": "Titel", - "@resourcesSortByTitle": {}, - "actionsDownloadCancel": "Avbryt Nedladdning", - "@actionsDownloadCancel": {}, - "settingsServersActionsDelete": "Radera", - "@settingsServersActionsDelete": {}, - "settingsServersFieldsName": "Namn", - "@settingsServersFieldsName": {}, - "resourcesPlaylistName": "{count,plural, =1{Spellista} other{Spellistor}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Skicka lösenord som token + salt", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "resourcesArtistListsSort": "Sortera artister", - "@resourcesArtistListsSort": {}, - "controlsShuffle": "Blanda", - "@controlsShuffle": {}, - "searchNowPlayingContext": "Sökresultat", - "@searchNowPlayingContext": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Skicka lösenord i klartext (Föråldrat. Se till att din uppkoppling är säker!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "messagesNothingHere": "Inget här…", - "@messagesNothingHere": {}, - "settingsNetworkOptionsStreamFormat": "Föredraget streamformat", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsAboutActionsSupport": "Stöd utvecklaren 💜", - "@settingsAboutActionsSupport": {}, - "resourcesArtistCount": "{count,plural, =1{{count} artist} other{{count} artister}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesAlbumActionsPlay": "Spela album", - "@resourcesAlbumActionsPlay": {}, - "resourcesSortByRandom": "Slumpmässig", - "@resourcesSortByRandom": {}, - "navigationTabsLibrary": "Bibliotek", - "@navigationTabsLibrary": {}, - "resourcesFilterYear": "År", - "@resourcesFilterYear": {}, - "settingsNetworkOptionsOfflineModeOff": "Använd internet för att uppdatera musik.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsServersFieldsAddress": "Adress", - "@settingsServersFieldsAddress": {}, - "settingsMusicName": "Musik", - "@settingsMusicName": {}, - "settingsAboutChooseLog": "Välj en loggfil", - "@settingsAboutChooseLog": {}, - "resourcesSortByArtist": "Konstnär", - "@resourcesSortByArtist": {}, - "settingsServersMessagesConnectionOk": "Anslutning till {adress} OK!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsAboutShareLogs": "Dela loggarna", - "@settingsAboutShareLogs": {}, - "settingsServersActionsEdit": "Redigera källa", - "@settingsServersActionsEdit": {}, - "resourcesPlaylistActionsPlay": "Spela upp spellista", - "@resourcesPlaylistActionsPlay": {}, - "resourcesSortByRecentlyPlayed": "Senast spelade", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSongName": "{count,plural, =1{Låt} other{Låtar}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAlbumCount": "Albumantal", - "@resourcesSortByAlbumCount": {}, - "settingsMusicOptionsScrobbleTitle": "Skrobbla uppspelningar", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsAboutActionsLicenses": "Licenser", - "@settingsAboutActionsLicenses": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Använd serverns standardinställning", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Skrobbla spelhistorik", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "resourcesSortByAlbum": "Album", - "@resourcesSortByAlbum": {}, - "settingsNetworkOptionsOfflineMode": "Offline-läge", - "@settingsNetworkOptionsOfflineMode": {}, - "resourcesSongListDeleteAllContent": "Detta tar bort alla nedladdade låtfiler.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesAlbumActionsView": "Visa album", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} album} other{{count} album}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Maximal bitrate (mobilnätverk)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkName": "Nätverk", - "@settingsNetworkName": {}, - "settingsServersActionsTestConnection": "Testanslutning", - "@settingsServersActionsTestConnection": {}, - "settingsServersName": "Källor", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Tvinga lösenord i klartext", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "resourcesSongCount": "{count,plural, =1{{count} låt} other{{count} låtar}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - } -} diff --git a/lib/l10n/app_ta.arb b/lib/l10n/app_ta.arb deleted file mode 100644 index eadfc4cd..00000000 --- a/lib/l10n/app_ta.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "resourcesAlbumActionsPlay": "தொகுப்பு இயக்கு", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "ஆல்பத்தைக் காண்க", - "@resourcesAlbumActionsView": {}, - "resourcesSortByFrequentlyPlayed": "அடிக்கடி விளையாடியது", - "@resourcesSortByFrequentlyPlayed": {}, - "settingsAboutActionsProjectHomepage": "திட்ட முகப்புப்பக்கம்", - "@settingsAboutActionsProjectHomepage": {}, - "settingsMusicName": "இசை", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "நாடக வரலாற்றை வெல்ல வேண்டாம்", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsServersName": "மூலங்கள்", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "கடவுச்சொல்லை எளிய உரையில் அனுப்பவும் (மரபு, உங்கள் இணைப்பு பாதுகாப்பானது என்பதை உறுதிப்படுத்திக் கொள்ளுங்கள்!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "actionsOk": "சரி", - "@actionsOk": {}, - "actionsStar": "விண்மீன்", - "@actionsStar": {}, - "actionsUnstar": "ச்டார்", - "@actionsUnstar": {}, - "controlsShuffle": "கலக்கு", - "@controlsShuffle": {}, - "messagesNothingHere": "இங்கே எதுவும் இல்லை…", - "@messagesNothingHere": {}, - "navigationTabsHome": "வீடு", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "நூலகம்", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "தேடல்", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "அமைப்புகள்", - "@navigationTabsSettings": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} செருகேடு} other{{count} செருகேடுகள்}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesAlbumListsSort": "ஆல்பங்களை வரிசைப்படுத்துங்கள்", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, =1{செருகேடு} other{செருகேடுகள்}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "கலைஞரைக் காண்க", - "@resourcesArtistActionsView": {}, - "resourcesArtistCount": "{count,plural, =1{{count} கலைஞர்} other{{count} கலைஞர்கள்}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistListsSort": "கலைஞர்களை வரிசைப்படுத்துங்கள்", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, =1{கலைஞர்} other{கலைஞர்கள்}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterAlbum": "ஆல்பம்", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "கலைஞர்", - "@resourcesFilterArtist": {}, - "resourcesFilterGenre": "வகை", - "@resourcesFilterGenre": {}, - "resourcesFilterOwner": "உரிமையாளர்", - "@resourcesFilterOwner": {}, - "resourcesFilterStarred": "நடித்தார்", - "@resourcesFilterStarred": {}, - "resourcesFilterYear": "ஆண்டு", - "@resourcesFilterYear": {}, - "resourcesPlaylistActionsPlay": "பிளேலிச்ட்டை விளையாடுங்கள்", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistCount": "{count,plural, =1{{count} இசைப்பட்டியல்} other{{count} இசைப்பட்டியல்கள்}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesPlaylistName": "{count,plural, =1{இசைப்பட்டியல்} other{இசைப்பட்டியல்கள்}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{வரிசை} other{வரிசைகள்}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "இது பதிவிறக்கம் செய்யப்பட்ட அனைத்து பாடல் கோப்புகளையும் அகற்றும்.", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSongListDeleteAllTitle": "பதிவிறக்கங்களை நீக்கவா?", - "@resourcesSongListDeleteAllTitle": {}, - "resourcesSongCount": "{count,plural, =1{{count} பாடல்} other{{count} பாடல்கள்}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "சிறந்த பாடல்கள்", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, =1{பாடல்} other{பாடல்கள்}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "அண்மைக் காலத்தில் சேர்க்கப்பட்டது", - "@resourcesSortByAdded": {}, - "resourcesSortByAlbum": "ஆல்பம்", - "@resourcesSortByAlbum": {}, - "resourcesSortByAlbumCount": "ஆல்பம் எண்ணிக்கை", - "@resourcesSortByAlbumCount": {}, - "resourcesSortByArtist": "கலைஞர்", - "@resourcesSortByArtist": {}, - "resourcesSortByName": "பெயர்", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "சீரற்ற", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "அண்மைக் காலத்தில் விளையாடியது", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByTitle": "தலைப்பு", - "@resourcesSortByTitle": {}, - "resourcesSortByUpdated": "அண்மைக் காலத்தில் புதுப்பிக்கப்பட்டது", - "@resourcesSortByUpdated": {}, - "resourcesSortByYear": "ஆண்டு", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "தேடல்: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "தேடல்", - "@searchInputPlaceholder": {}, - "searchMoreResults": "மேலும்…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "தேடல் முடிவுகள்", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "உரிமங்கள்", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsSupport": "டெவலப்பரை ஆதரிக்கவும்", - "@settingsAboutActionsSupport": {}, - "settingsAboutName": "பற்றி", - "@settingsAboutName": {}, - "settingsAboutShareLogs": "பதிவுகளைப் பகிரவும்", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "பதிவு கோப்பைத் தேர்வுசெய்க", - "@settingsAboutChooseLog": {}, - "settingsAboutVersion": "பதிப்பு {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicOptionsScrobbleDescriptionOn": "ச்க்ரோபல் ப்ளே வரலாறு", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "ச்க்ரோபில் நாடகங்கள்", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "பிணையம்", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "அதிகபட்ச பிட்ரேட் (மொபைல் தரவு)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "அதிகபட்ச பிட்ரேட் (வைஃபை)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "குறைந்தபட்ச இடையக நேரம்", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "அதிகபட்ச இடையக நேரம்", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsOfflineMode": "இணைப்பில்லாத பயன்முறை", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsOfflineModeOff": "இசையை ஒத்திசைக்க இணையத்தைப் பயன்படுத்தவும்.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsOfflineModeOn": "இசையை ஒத்திசைக்க அல்லது இசைக்க இணையத்தைப் பயன்படுத்த வேண்டாம்.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsNetworkOptionsStreamFormat": "விருப்பமான ச்ட்ரீம் வடிவம்", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "சேவையக இயல்புநிலையைப் பயன்படுத்தவும்", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsNetworkValuesKbps": "{value} kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} விநாடிகள்", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "வரம்பற்றது", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "தெளிவான பட தற்காலிக சேமிப்பு", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "மீட்டமை", - "@settingsResetName": {}, - "settingsServersActionsAdd": "மூலத்தைச் சேர்க்கவும்", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "நீக்கு", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "மூலத்தைத் திருத்து", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "சேமி", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "சோதனை இணைப்பு", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "முகவரி", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsName": "பெயர்", - "@settingsServersFieldsName": {}, - "settingsServersFieldsPassword": "கடவுச்சொல்", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "பயனர்பெயர்", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "{address} தோல்வியுற்றது, அமைப்புகள் அல்லது சேவையகத்தை சரிபார்க்கவும்", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "{address} சரி!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "கடவுச்சொல்லை கிள்ளாக்கு + உப்பு என அனுப்பவும்", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "எளிய கடவுச்சொல்லை கட்டாயப்படுத்துங்கள்", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "actionsCancel": "ரத்துசெய்", - "@actionsCancel": {}, - "actionsDelete": "நீக்கு", - "@actionsDelete": {}, - "actionsDownload": "பதிவிறக்கம்", - "@actionsDownload": {}, - "actionsDownloadCancel": "பதிவிறக்கத்தை ரத்துசெய்", - "@actionsDownloadCancel": {}, - "actionsDownloadDelete": "பதிவிறக்கம் செய்யப்பட்டதை நீக்கு", - "@actionsDownloadDelete": {} -} diff --git a/lib/l10n/app_th.arb b/lib/l10n/app_th.arb deleted file mode 100644 index 1bdc23e3..00000000 --- a/lib/l10n/app_th.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsStar": "ดาว", - "@actionsStar": {}, - "settingsNetworkValuesKbps": "{value}{value}กิโลบิตต่อวินาที (kbps)", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "actionsDelete": "ลบ", - "@actionsDelete": {}, - "resourcesAlbumCount": "{count,plural, other{{count} อัลบั้ม}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "actionsDownload": "ดาวน์โหลด", - "@actionsDownload": {}, - "actionsDownloadCancel": "ยกเลิกการดาวน์โหลด", - "@actionsDownloadCancel": {}, - "actionsDownloadDelete": "ลบรายการที่ดาวน์โหลดเสร็จแล้ว", - "@actionsDownloadDelete": {}, - "actionsOk": "ตกลง", - "@actionsOk": {}, - "actionsUnstar": "ยกเลิกดาว", - "@actionsUnstar": {}, - "controlsShuffle": "เล่นแบบสุ่ม", - "@controlsShuffle": {}, - "navigationTabsHome": "หน้าหลัก", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "ห้องสมุด", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "ค้นหา", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "การตั้งค่า", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsView": "ดูอัลบั้ม", - "@resourcesAlbumActionsView": {}, - "resourcesArtistActionsView": "ดูศิลปิน", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "จัดเรียงศิลปิน", - "@resourcesArtistListsSort": {}, - "resourcesAlbumName": "{count,plural, other{อัลบั้ม}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterAlbum": "อัลบั้ม", - "@resourcesFilterAlbum": {}, - "resourcesFilterOwner": "เจ้าของ", - "@resourcesFilterOwner": {}, - "resourcesFilterStarred": "ให้ดาว", - "@resourcesFilterStarred": {}, - "resourcesFilterYear": "ปี", - "@resourcesFilterYear": {}, - "resourcesPlaylistActionsPlay": "เล่นเพลย์ลิส", - "@resourcesPlaylistActionsPlay": {}, - "resourcesQueueName": "{count,plural, =1{คิว} other{คิว}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{{count} เพลง} other{{count} เพลง}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllTitle": "ต้องการลบดาวน์โหลด?", - "@resourcesSongListDeleteAllTitle": {}, - "resourcesSongListsArtistTopSongs": "เพลงยอดนิยม", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSortByAdded": "เพลงที่เพิ่มล่าสุด", - "@resourcesSortByAdded": {}, - "resourcesSortByAlbum": "อัลบั้ม", - "@resourcesSortByAlbum": {}, - "resourcesSortByName": "ชื่อเพลง", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "สุ่มเพลง", - "@resourcesSortByRandom": {}, - "resourcesSortByYear": "ปี", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "ค้นหา: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "ค้นหา", - "@searchInputPlaceholder": {}, - "searchMoreResults": "เพิ่มเติม…", - "@searchMoreResults": {}, - "settingsAboutActionsLicenses": "ใบอนุญาต", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "โฮมเพจของโครงการ", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutActionsSupport": "ให้การสนับสนุนผู้พัฒนา 💜", - "@settingsAboutActionsSupport": {}, - "settingsAboutName": "เกี่ยวกับ", - "@settingsAboutName": {}, - "settingsAboutShareLogs": "แบ่งปันล็อกไฟล์", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "เลือก log ไฟล์", - "@settingsAboutChooseLog": {}, - "settingsAboutVersion": "เวอร์ชั่น {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicOptionsScrobbleDescriptionOn": "เปิด scrobble การเล่นเพลงในอดีต", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "เล่น scrobble", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "เคลือข่าย", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "บิทเรตสูงสุด (ไวไฟ)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "บัฟเฟอร์เวลาต่ำสุด", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkOptionsOfflineModeOn": "ปิดใช้อินเตอร์เน็ตเพื่อให้ข้อมูลเพลงเหมือนกันหรือเล่นเพลง", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsNetworkOptionsStreamFormat": "รูปแบบการสตรีมเพลงที่ต้องการ", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "ใช้ค่าเริ่มต้นของเซิร์ฟเวอร์", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsNetworkValuesSeconds": "{value} วินาที", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "ไม่จำกัด", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetName": "เริ่มใหม่", - "@settingsResetName": {}, - "settingsServersActionsAdd": "เพิ่มเซิร์ฟเวอร์", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "ลบ", - "@settingsServersActionsDelete": {}, - "settingsServersActionsSave": "บันทึก", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "ทดสอบการเชื่อมต่อ", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsName": "ชื่อ", - "@settingsServersFieldsName": {}, - "settingsServersFieldsPassword": "รหัสผ่าน", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "ชื่อผู้ใช้", - "@settingsServersFieldsUsername": {}, - "settingsServersName": "เซิร์ฟเวอร์", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "บังคับใช้รหัสผ่านแบบข้อความ", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "actionsCancel": "ยกเลิก", - "@actionsCancel": {}, - "resourcesAlbumListsSort": "จัดเรียงอัลบั้ม", - "@resourcesAlbumListsSort": {}, - "settingsServersActionsEdit": "แก้ไขเซิร์ฟเวอร์", - "@settingsServersActionsEdit": {}, - "resourcesSongListDeleteAllContent": "นำเพลงที่ดาวน์โหลดมาทั้งหมดออก", - "@resourcesSongListDeleteAllContent": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "บิทเรตสูงสุด (อินเตอร์เน็ตมือถือ)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "resourcesArtistCount": "{count,plural, other{{count} ศิลปิน}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesPlaylistName": "{count,plural, =1{เพลย์ลิส} other{เพลย์ลิส}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistName": "{count,plural, other{ศิลปิน}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterArtist": "ศิลปิน", - "@resourcesFilterArtist": {}, - "resourcesFilterGenre": "ประเภท", - "@resourcesFilterGenre": {}, - "resourcesSortByRecentlyPlayed": "เล่นล่าสุด", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByTitle": "ชื่อเพลง", - "@resourcesSortByTitle": {}, - "settingsServersFieldsAddress": "ที่อยู่ไอพี", - "@settingsServersFieldsAddress": {}, - "settingsNetworkOptionsOfflineMode": "โหมดอ๊อฟไลน์", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsMaxBufferTitle": "บัฟเฟอร์เวลาสูงสุด", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsServersMessagesConnectionOk": "เชื่อต่อกับ {address} สำเร็จ!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "ส่งรหัสผ่านเป็นโทเคน", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "messagesNothingHere": "ไม่มีอะไรที่นี่…", - "@messagesNothingHere": {}, - "resourcesSortByFrequentlyPlayed": "เพลงที่เล่นบ่อย", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByAlbumCount": "จำนวนอัลบัม", - "@resourcesSortByAlbumCount": {}, - "resourcesSortByArtist": "ศิลปิน", - "@resourcesSortByArtist": {}, - "resourcesSortByUpdated": "อัพเดทล่าสุด", - "@resourcesSortByUpdated": {}, - "settingsMusicName": "ดนตรี", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "ปิดการ scrobble การเล่นเพลงในอดีต", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsServersMessagesConnectionFailed": "เชื่อต่อกับ {address} ล้มเหลว, ตรวจสอบการตั้งค่าหรือเซิร์ฟเวอร์", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "searchNowPlayingContext": "ผลการค้นหา", - "@searchNowPlayingContext": {}, - "settingsResetActionsClearImageCache": "ลบแคชของรูปภาพ", - "@settingsResetActionsClearImageCache": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "ส่งรหัสผ่านเป็นข้อความ (ล้าสมัย ต้องแน่ใจว่าการเชื่อมต่อของคุณปลอดภัย)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "resourcesAlbumActionsPlay": "เล่นอัลบั้ม", - "@resourcesAlbumActionsPlay": {}, - "resourcesPlaylistCount": "{count,plural, =1{{count} เพลย์ลิส} other{{count} เพลย์ลิส}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongName": "{count,plural, =1{เพลง} other{เพลง}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "settingsNetworkOptionsOfflineModeOff": "เปิดใช้อินเตอร์เน็ตเพื่อให้ข้อมูลเพลงเหมือนกัน", - "@settingsNetworkOptionsOfflineModeOff": {} -} diff --git a/lib/l10n/app_tr.arb b/lib/l10n/app_tr.arb deleted file mode 100644 index a5c5a06f..00000000 --- a/lib/l10n/app_tr.arb +++ /dev/null @@ -1,201 +0,0 @@ -{ - "actionsStar": "Yıldızla", - "actionsUnstar": "Yıldızı Kaldır", - "messagesNothingHere": "Burada bir şey yok …", - "navigationTabsHome": "Giriş", - "navigationTabsLibrary": "Kütüphane", - "navigationTabsSearch": "Arama", - "navigationTabsSettings": "Ayarlar", - "resourcesAlbumActionsPlay": "Albümü Çal", - "resourcesAlbumActionsView": "Albüme Git", - "resourcesAlbumListsSort": "Albümleri Sırala", - "resourcesAlbumName": "{count,plural, =1{Albüm} other{Albümler}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Sanatçıya Git", - "resourcesArtistListsSort": "Sanatçıları Sırala", - "resourcesArtistName": "{count,plural, =1{Sanatçı} other{Sanatçılar}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Türe göre", - "resourcesFilterStarred": "Yıldızlı", - "resourcesPlaylistActionsPlay": "Listeyi Çal", - "resourcesPlaylistName": "{count,plural, =1{Çalma Listesi} other{Çalma Listeleri}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Sıra} other{Sıralar}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "En İyi Şarkılar", - "resourcesSongName": "{count,plural, =1{Şarkı} other{Şarkılar}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Son Eklenenler", - "resourcesSortByArtist": "Sanatçıya Göre", - "resourcesSortByFrequentlyPlayed": "Sık Dinlenenler", - "resourcesSortByName": "İsme göre", - "resourcesSortByRandom": "Rastgele", - "resourcesSortByRecentlyPlayed": "Yeni Dinleneler", - "resourcesSortByYear": "Yıla göre", - "searchHeaderTitle": "Aranan: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Ara", - "searchMoreResults": "Tüm Sonuçlar …", - "searchNowPlayingContext": "Arama Sonuçları", - "settingsAboutActionsLicenses": "Lisanslar", - "settingsAboutActionsProjectHomepage": "Proje Ana Sayfası", - "settingsAboutName": "Hakkında", - "settingsAboutVersion": "sürüm {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Müzik", - "settingsMusicOptionsScrobbleDescriptionOff": "Müzik geçmişini profilime ekleme", - "settingsMusicOptionsScrobbleDescriptionOn": "Müzik geçmişini profilime ekle", - "settingsMusicOptionsScrobbleTitle": "Çalan müziği profilime ekle", - "settingsNetworkName": "Ağ", - "settingsNetworkOptionsMaxBitrateMobileTitle": "Azami bithızı (mobil veri)", - "settingsNetworkOptionsMaxBitrateWifiTitle": "Azami bithızı (Wi-Fi)", - "settingsNetworkOptionsMaxBufferTitle": "Azami arabellek süresi", - "settingsNetworkOptionsMinBufferTitle": "Asgari arabellek süresi", - "settingsNetworkValuesKbps": "{value}kb/sn", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} saniye", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Sınırsız", - "settingsResetActionsClearImageCache": "Görüntü Önbelleğini Temizle", - "settingsResetName": "Sıfırlama", - "settingsServersActionsAdd": "Sunucu Ekle", - "settingsServersActionsDelete": "Kaldır", - "settingsServersActionsEdit": "Sunucu Ayarı", - "settingsServersActionsSave": "Kaydet", - "settingsServersActionsTestConnection": "Bağlantıyı Sına", - "settingsServersFieldsAddress": "Adres", - "settingsServersFieldsPassword": "Şifre", - "settingsServersFieldsUsername": "Kullanıcı Adı", - "settingsServersMessagesConnectionFailed": "{address} ile bağlantı kurulamadı; ayarları veya sunucuyu gözden geçirin", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "{address} ile bağlantı başarılı!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Sunucular", - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Şifreyi dizgecik ve tuz karışımı olarak gönder", - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Şifreyi düz metin olarak gönderir (eski yöntem, bağlantının güvenli olduğu sunucularda kullanın!)", - "settingsServersOptionsForcePlaintextPasswordTitle": "Düzyazı şifre kullanmayı zorla", - "actionsCancel": "İptal", - "actionsDelete": "Sil", - "actionsDownload": "İndir", - "actionsDownloadCancel": "İndirmeyi iptal et", - "actionsDownloadDelete": "İndirilenleri sil", - "actionsOk": "Tamam", - "controlsShuffle": "Karıştır", - "resourcesAlbumCount": "{count,plural, =1{{count} album} other{{count} album}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistCount": "{count,plural, =1{{count} sanatçı} other{{count} sanatçı}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterAlbum": "Albüm", - "resourcesFilterArtist": "Sanatçı", - "resourcesFilterOwner": "Sahibi", - "resourcesFilterYear": "Yıl", - "resourcesPlaylistCount": "{count,plural, =1{{count} çalma listesi} other{{count} çalma listesi}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{{count} şarkı} other{{count} şarkı}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "Bu, indirilen tüm şarkı dosyalarını silecek.", - "resourcesSongListDeleteAllTitle": "İndirilenler silinsin mi?", - "resourcesSortByAlbum": "Albüm", - "resourcesSortByAlbumCount": "Albüm sayısı", - "resourcesSortByTitle": "Başlık", - "resourcesSortByUpdated": "Son güncellenen", - "settingsAboutActionsSupport": "Geliştiriciyi destekleyin 💜", - "settingsAboutShareLogs": "Günlükleri paylaş", - "settingsAboutChooseLog": "Günlük dosyası seçin", - "settingsNetworkOptionsOfflineMode": "Çevrim dışı mod", - "settingsNetworkOptionsOfflineModeOff": "İnterneti kullanarak müzikleri eşzamanla.", - "settingsNetworkOptionsOfflineModeOn": "İnterneti müzikleri eşzamanlamak veya çalmak için kullanma.", - "settingsNetworkOptionsStreamFormat": "Tercih edilen akış biçimi", - "settingsNetworkOptionsStreamFormatServerDefault": "Sunucu öntanımlı değerini kullan", - "settingsServersFieldsName": "Ad" -} diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb deleted file mode 100644 index 723f79b6..00000000 --- a/lib/l10n/app_uk.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsStar": "Зірка", - "@actionsStar": {}, - "navigationTabsSearch": "Пошук", - "@navigationTabsSearch": {}, - "settingsServersFieldsPassword": "Пароль", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "Ім'я користувача", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "Не вдалося підключитися до {address}, перевірте налаштування або сервер", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Підключення до {address} вдале!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Джерела", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Надішліть пароль як токен + сіль", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Надішліть пароль у відкритому тексті (застарілий, переконайтеся, що ваше з'єднання захищене!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "Примусове введення простого текстового пароля", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "navigationTabsSettings": "Налаштування", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "Відтворити альбом", - "@resourcesAlbumActionsPlay": {}, - "searchHeaderTitle": "Пошук: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "settingsMusicOptionsScrobbleTitle": "Відстеження відтворення", - "@settingsMusicOptionsScrobbleTitle": {}, - "actionsCancel": "Скасувати", - "@actionsCancel": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "Слідкувати за історією відтворення", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "resourcesArtistCount": "{count,plural, =1{{count} виконавець} other{{count} виконавці}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByUpdated": "Нещодавно оновлені", - "@resourcesSortByUpdated": {}, - "actionsDelete": "Видалити", - "@actionsDelete": {}, - "resourcesSortByAlbum": "Альбом", - "@resourcesSortByAlbum": {}, - "resourcesSortByName": "Ім'я", - "@resourcesSortByName": {}, - "resourcesSortByRecentlyPlayed": "Нещодавно відворені", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByFrequentlyPlayed": "Часто відтворювані", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSongListsArtistTopSongs": "Найкращі пісні", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSortByYear": "Рік", - "@resourcesSortByYear": {}, - "resourcesFilterStarred": "Улюблене", - "@resourcesFilterStarred": {}, - "resourcesFilterYear": "Рік", - "@resourcesFilterYear": {}, - "actionsDownloadDelete": "Видалити завантажене", - "@actionsDownloadDelete": {}, - "resourcesAlbumName": "{count,plural, =1{Альбом} other{Альбоми}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "actionsOk": "OK", - "@actionsOk": {}, - "actionsDownload": "Завантажити", - "@actionsDownload": {}, - "controlsShuffle": "Перемішати", - "@controlsShuffle": {}, - "actionsDownloadCancel": "Скасувати завантаження", - "@actionsDownloadCancel": {}, - "actionsUnstar": "Зняти зірку", - "@actionsUnstar": {}, - "navigationTabsLibrary": "Бібліотека", - "@navigationTabsLibrary": {}, - "messagesNothingHere": "Тут нічого немає…", - "@messagesNothingHere": {}, - "navigationTabsHome": "Головна", - "@navigationTabsHome": {}, - "resourcesArtistName": "{count,plural, =1{Виконавець} other{Виконавці}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesAlbumActionsView": "Переглянути альбом", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumCount": "{count,plural, =1{{count} альбом} other{{count} альбоми}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesAlbumListsSort": "Сортувати альбоми", - "@resourcesAlbumListsSort": {}, - "resourcesFilterGenre": "Жанр", - "@resourcesFilterGenre": {}, - "resourcesArtistActionsView": "Переглянути виконавця", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "Сортувати виконавців", - "@resourcesArtistListsSort": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "Максимальний бітрейт (мобільні дані)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "resourcesSongCount": "{count,plural, =1{{count} пісня} other{{count} пісні}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "Це призведе до видалення всіх завантажених файлів пісень.", - "@resourcesSongListDeleteAllContent": {}, - "settingsNetworkName": "Мережа", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBufferTitle": "Максимальний час буферизації", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "Мінімальний час буферизації", - "@settingsNetworkOptionsMinBufferTitle": {}, - "resourcesFilterAlbum": "Альбом", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "Виконавець", - "@resourcesFilterArtist": {}, - "resourcesFilterOwner": "Власник", - "@resourcesFilterOwner": {}, - "resourcesPlaylistActionsPlay": "Відтворити плейлист", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistCount": "{count,plural, =1{{count} плейлист} other{{count} плейлисти}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesPlaylistName": "{count,plural, =1{Плейлист} other{Плейлисти}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllTitle": "Видалити завантаження?", - "@resourcesSongListDeleteAllTitle": {}, - "settingsAboutName": "Про застосунок", - "@settingsAboutName": {}, - "settingsAboutShareLogs": "Поділитися журналами", - "@settingsAboutShareLogs": {}, - "resourcesQueueName": "{count,plural, =1{Черга} other{Черги}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongName": "{count,plural, =1{Пісня} other{Пісні}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Нещодавно додані", - "@resourcesSortByAdded": {}, - "resourcesSortByAlbumCount": "Кількість альбомів", - "@resourcesSortByAlbumCount": {}, - "resourcesSortByArtist": "Виконавець", - "@resourcesSortByArtist": {}, - "resourcesSortByRandom": "Випадково", - "@resourcesSortByRandom": {}, - "resourcesSortByTitle": "Назва", - "@resourcesSortByTitle": {}, - "searchInputPlaceholder": "Введіть заголовок/опис", - "@searchInputPlaceholder": {}, - "searchMoreResults": "Більше…", - "@searchMoreResults": {}, - "settingsAboutActionsProjectHomepage": "Головна сторінка проєкту", - "@settingsAboutActionsProjectHomepage": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "Не слідкувати за історією відтворення", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "searchNowPlayingContext": "Результати пошуку", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "Ліцензії", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsSupport": "Підтримайте розробника 💜", - "@settingsAboutActionsSupport": {}, - "settingsNetworkOptionsOfflineMode": "Автономний режим", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsAboutChooseLog": "Виберіть файл журналу", - "@settingsAboutChooseLog": {}, - "settingsAboutVersion": "версія {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Музика", - "@settingsMusicName": {}, - "settingsNetworkOptionsOfflineModeOn": "Не використовувати інтернет для синхронізації або відтворення музики.", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "Максимальний бітрейт (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsOfflineModeOff": "Використовувати інтернет для синхронізації музики.", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "Використовувати сервер за замовчуванням", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsNetworkOptionsStreamFormat": "Бажаний формат потоку", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsNetworkValuesKbps": "{value}кбіт/с", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} секунд", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Необмежено", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsServersActionsAdd": "Додати джерело", - "@settingsServersActionsAdd": {}, - "settingsResetActionsClearImageCache": "Очистити кеш зображень", - "@settingsResetActionsClearImageCache": {}, - "settingsServersActionsSave": "Зберегти", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "Тестове підключення", - "@settingsServersActionsTestConnection": {}, - "settingsServersActionsEdit": "Редагувати джерело", - "@settingsServersActionsEdit": {}, - "settingsServersFieldsAddress": "Адреса", - "@settingsServersFieldsAddress": {}, - "settingsResetName": "Скинути", - "@settingsResetName": {}, - "settingsServersActionsDelete": "Видалити", - "@settingsServersActionsDelete": {}, - "settingsServersFieldsName": "Ім'я", - "@settingsServersFieldsName": {} -} diff --git a/lib/l10n/app_vi.arb b/lib/l10n/app_vi.arb deleted file mode 100644 index dea3b6ce..00000000 --- a/lib/l10n/app_vi.arb +++ /dev/null @@ -1,201 +0,0 @@ -{ - "actionsStar": "Yêu thích", - "actionsUnstar": "Bỏ yêu thích", - "messagesNothingHere": "Không có gì ở đây…", - "navigationTabsHome": "Trang chủ", - "navigationTabsLibrary": "Thư viện", - "navigationTabsSearch": "Tìm kiếm", - "navigationTabsSettings": "Cài đặt", - "resourcesAlbumActionsPlay": "Phát album", - "resourcesAlbumActionsView": "Xem album", - "resourcesAlbumListsSort": "Sắp xếp album", - "resourcesAlbumName": "{count,plural, =1{album} other{album}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "Xem nghệ sĩ", - "resourcesArtistListsSort": "Sắp xếp nghệ sĩ", - "resourcesArtistName": "{count,plural, =1{Nghệ sĩ} other{Nghệ sĩ}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "Theo thể loại", - "resourcesFilterStarred": "Theo yêu thích", - "resourcesPlaylistActionsPlay": "Phát playlist", - "resourcesPlaylistName": "{count,plural, =1{Playlist} other{Playlist}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, =1{Danh sách chờ} other{Danh sách chờ}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "Những bài hát thịnh hành", - "resourcesSongName": "{count,plural, =1{Bài hát} other{Bài hát}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "Vừa thêm", - "resourcesSortByArtist": "Nghệ sĩ", - "resourcesSortByFrequentlyPlayed": "Thường nghe", - "resourcesSortByName": "Tên", - "resourcesSortByRandom": "Ngẫu nhiên", - "resourcesSortByRecentlyPlayed": "Đã phát gần đây", - "resourcesSortByYear": "Năm", - "searchHeaderTitle": "Tìm kiếm: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "Tìm kiếm", - "searchMoreResults": "Thêm…", - "searchNowPlayingContext": "Kết quả tìm kiếm", - "settingsAboutActionsLicenses": "Bản quyền", - "settingsAboutActionsProjectHomepage": "Trang chủ dự án", - "settingsAboutName": "Về ứng dụng", - "settingsAboutVersion": "phiên bản {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "Nhạc", - "settingsMusicOptionsScrobbleDescriptionOff": "Không đồng bộ lịch sử phát nhạc", - "settingsMusicOptionsScrobbleDescriptionOn": "Đồng bộ lịch sử phát nhạc", - "settingsMusicOptionsScrobbleTitle": "Đồng bộ lượt nghe", - "settingsNetworkName": "Mạng", - "settingsNetworkOptionsMaxBitrateMobileTitle": "Bitrate tối đa (mạng di động)", - "settingsNetworkOptionsMaxBitrateWifiTitle": "Bitrate tối đa (Wi-Fi)", - "settingsNetworkOptionsMaxBufferTitle": "Thời gian đệm tối đa", - "settingsNetworkOptionsMinBufferTitle": "Thời gian đệm tối thiểu", - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} giây", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "Vô giới hạn", - "settingsResetActionsClearImageCache": "Xóa cache ảnh", - "settingsResetName": "Cài đặt lại", - "settingsServersActionsAdd": "Thêm máy chủ", - "settingsServersActionsDelete": "Xóa", - "settingsServersActionsEdit": "Chỉnh sửa máy chủ", - "settingsServersActionsSave": "Lưu", - "settingsServersActionsTestConnection": "Kiểm tra kết nối", - "settingsServersFieldsAddress": "Địa chỉ", - "settingsServersFieldsPassword": "Mật khẩu", - "settingsServersFieldsUsername": "Tên đăng nhập", - "settingsServersMessagesConnectionFailed": "Kết nối với {address} không thành công, hãy kiểm tra cài đặt hoặc máy chủ", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "Kết nối với {address} OK!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "Máy chủ", - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Gửi mật khẩu dưới dạng token + salt", - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Gửi mật khẩu không mã hóa (tính năng cũ, đảm bảo kết nối an toàn!)", - "settingsServersOptionsForcePlaintextPasswordTitle": "Buộc mật khẩu không mã hóa", - "actionsCancel": "Hủy", - "actionsDelete": "Xóa", - "actionsDownload": "Tải xuống", - "actionsDownloadCancel": "Hủy tải xuống", - "actionsOk": "OK", - "controlsShuffle": "Phát ngẫu nhiên", - "resourcesFilterAlbum": "Theo album", - "resourcesFilterArtist": "Theo nghệ sĩ", - "resourcesFilterYear": "Theo năm", - "actionsDownloadDelete": "Xóa khỏi máy", - "resourcesAlbumCount": "{count,plural, =1{{count} album} other{{count} album}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistCount": "{count,plural, =1{{count} nghệ sĩ} other{{count} nghệ sĩ}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterOwner": "Theo người tải lên", - "resourcesPlaylistCount": "{count,plural, =1{{count} playlist} other{{count} playlist}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, =1{{count} bài hát} other{{count} bài hát}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "Thao tác này sẽ xóa tất cả những bài hát đã tải về.", - "resourcesSongListDeleteAllTitle": "Xóa nhạc đã tải?", - "resourcesSortByAlbum": "Album", - "resourcesSortByAlbumCount": "Lượng album", - "resourcesSortByTitle": "Tiêu đề", - "resourcesSortByUpdated": "Mới cập nhật", - "settingsAboutActionsSupport": "Hỗ trợ nhà phát triển 💜", - "settingsAboutShareLogs": "Chia sẻ log", - "settingsAboutChooseLog": "Chọn file log", - "settingsNetworkOptionsOfflineMode": "Chế độ ngoại tuyến", - "settingsNetworkOptionsOfflineModeOff": "Đồng bộ nhạc qua mạng.", - "settingsNetworkOptionsOfflineModeOn": "Không dùng internet để đồng bô hoặc phát nhạc.", - "settingsNetworkOptionsStreamFormat": "Định dạng phát nhạc mặc định", - "settingsNetworkOptionsStreamFormatServerDefault": "Theo mặc định máy chủ", - "settingsServersFieldsName": "Tên" -} diff --git a/lib/l10n/app_zh-Hant.arb b/lib/l10n/app_zh-Hant.arb deleted file mode 100644 index 1c502060..00000000 --- a/lib/l10n/app_zh-Hant.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "messagesNothingHere": "什麼都沒有…", - "@messagesNothingHere": {}, - "resourcesFilterYear": "年份", - "@resourcesFilterYear": {}, - "settingsServersFieldsPassword": "密碼", - "@settingsServersFieldsPassword": {}, - "actionsDownloadDelete": "刪除已下載", - "@actionsDownloadDelete": {}, - "actionsOk": "確定", - "@actionsOk": {}, - "actionsStar": "收藏", - "@actionsStar": {}, - "actionsCancel": "取消", - "@actionsCancel": {}, - "actionsDelete": "刪除", - "@actionsDelete": {}, - "actionsDownload": "下載", - "@actionsDownload": {}, - "actionsDownloadCancel": "取消下載", - "@actionsDownloadCancel": {}, - "actionsUnstar": "移除收藏", - "@actionsUnstar": {}, - "controlsShuffle": "隨機播放", - "@controlsShuffle": {}, - "navigationTabsHome": "首頁", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "所有", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "搜尋", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "設定", - "@navigationTabsSettings": {}, - "resourcesArtistActionsView": "查看歌手", - "@resourcesArtistActionsView": {}, - "resourcesAlbumActionsPlay": "播放專輯", - "@resourcesAlbumActionsPlay": {}, - "resourcesArtistCount": "{count,plural, other{{count} 位歌手}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesAlbumActionsView": "查看專輯", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumCount": "{count,plural, other{{count} 張專輯}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesAlbumListsSort": "專輯排序", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, other{專輯}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistListsSort": "歌手排序", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, other{歌手}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterOwner": "所有者", - "@resourcesFilterOwner": {}, - "resourcesFilterStarred": "已收藏", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "全部播放", - "@resourcesPlaylistActionsPlay": {}, - "resourcesFilterAlbum": "專輯", - "@resourcesFilterAlbum": {}, - "resourcesFilterArtist": "歌手", - "@resourcesFilterArtist": {}, - "resourcesFilterGenre": "根據類型", - "@resourcesFilterGenre": {}, - "resourcesPlaylistCount": "{count,plural, other{{count} 張播放清單}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesPlaylistName": "{count,plural, other{播放清單}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, other{佇列}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "熱門歌曲", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongCount": "{count,plural, other{{count} 首歌曲}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListDeleteAllContent": "此操作會刪除所有已下載的歌曲檔。", - "@resourcesSongListDeleteAllContent": {}, - "resourcesSongListDeleteAllTitle": "刪除下載的內容?", - "@resourcesSongListDeleteAllTitle": {}, - "resourcesSongName": "{count,plural, other{歌曲}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "最近新增", - "@resourcesSortByAdded": {}, - "resourcesSortByAlbum": "專輯", - "@resourcesSortByAlbum": {}, - "resourcesSortByAlbumCount": "專輯數量", - "@resourcesSortByAlbumCount": {}, - "resourcesSortByArtist": "根據歌手", - "@resourcesSortByArtist": {}, - "resourcesSortByName": "根據名稱", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "隨機", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "最近播放", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByFrequentlyPlayed": "最常播放", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByTitle": "標題", - "@resourcesSortByTitle": {}, - "resourcesSortByUpdated": "最近新增", - "@resourcesSortByUpdated": {}, - "resourcesSortByYear": "根據年份", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "搜尋: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "搜尋", - "@searchInputPlaceholder": {}, - "searchMoreResults": "更多…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "搜尋結果", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "許可", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "專案首頁", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutActionsSupport": "支援開發者", - "@settingsAboutActionsSupport": {}, - "settingsAboutName": "關於", - "@settingsAboutName": {}, - "settingsAboutShareLogs": "分享日誌", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "選擇一份日誌檔", - "@settingsAboutChooseLog": {}, - "settingsAboutVersion": "版本 {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "音樂", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "不記錄您的播放歷史", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "記錄您的播放歷史", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "記錄播放歷史", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "網路", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "最大位元速率 (行動流量)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "最大位元速率 (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "最大緩衝時間", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "最小緩衝時間", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkOptionsOfflineMode": "離線模式", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsOfflineModeOff": "使用網際網路同步音樂。", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsStreamFormat": "偏好的串流媒體格式", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "使用伺服器預設設定", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsNetworkOptionsOfflineModeOn": "不使用網際網路同步或播放音樂。", - "@settingsNetworkOptionsOfflineModeOn": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} 秒", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "不限制", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "清除圖片暫存", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "重置", - "@settingsResetName": {}, - "settingsServersActionsAdd": "新增伺服器", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "刪除", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "編輯伺服器", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "保存", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "測試連線", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "地址", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsName": "名稱", - "@settingsServersFieldsName": {}, - "settingsServersFieldsUsername": "用戶名稱", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "連接到 {address} 失敗,檢查設定或伺服器", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "連接到 {address} 正常!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "伺服器", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "密碼以 token + salt 加密發送", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "密碼以明文發送(不推薦,注意網路連線安全!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "強制使用純文字密碼", - "@settingsServersOptionsForcePlaintextPasswordTitle": {} -} diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb deleted file mode 100644 index 3d33a93f..00000000 --- a/lib/l10n/app_zh.arb +++ /dev/null @@ -1,280 +0,0 @@ -{ - "actionsStar": "收藏", - "@actionsStar": {}, - "actionsUnstar": "移除收藏", - "@actionsUnstar": {}, - "messagesNothingHere": "什么都没有…", - "@messagesNothingHere": {}, - "navigationTabsHome": "首页", - "@navigationTabsHome": {}, - "navigationTabsLibrary": "所有", - "@navigationTabsLibrary": {}, - "navigationTabsSearch": "搜索", - "@navigationTabsSearch": {}, - "navigationTabsSettings": "设置", - "@navigationTabsSettings": {}, - "resourcesAlbumActionsPlay": "播放专辑", - "@resourcesAlbumActionsPlay": {}, - "resourcesAlbumActionsView": "查看专辑", - "@resourcesAlbumActionsView": {}, - "resourcesAlbumListsSort": "专辑排序", - "@resourcesAlbumListsSort": {}, - "resourcesAlbumName": "{count,plural, other{专辑}}", - "@resourcesAlbumName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistActionsView": "查看歌手", - "@resourcesArtistActionsView": {}, - "resourcesArtistListsSort": "歌手排序", - "@resourcesArtistListsSort": {}, - "resourcesArtistName": "{count,plural, other{歌手}}", - "@resourcesArtistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesFilterGenre": "根据类型", - "@resourcesFilterGenre": {}, - "resourcesFilterStarred": "已收藏", - "@resourcesFilterStarred": {}, - "resourcesPlaylistActionsPlay": "全部播放", - "@resourcesPlaylistActionsPlay": {}, - "resourcesPlaylistName": "{count,plural, other{播放列表}}", - "@resourcesPlaylistName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesQueueName": "{count,plural, other{队列}}", - "@resourcesQueueName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongListsArtistTopSongs": "热门歌曲", - "@resourcesSongListsArtistTopSongs": {}, - "resourcesSongName": "{count,plural, other{歌曲}}", - "@resourcesSongName": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSortByAdded": "最近添加", - "@resourcesSortByAdded": {}, - "resourcesSortByArtist": "根据歌手", - "@resourcesSortByArtist": {}, - "resourcesSortByFrequentlyPlayed": "播放最多", - "@resourcesSortByFrequentlyPlayed": {}, - "resourcesSortByName": "根据名称", - "@resourcesSortByName": {}, - "resourcesSortByRandom": "随机", - "@resourcesSortByRandom": {}, - "resourcesSortByRecentlyPlayed": "最近播放", - "@resourcesSortByRecentlyPlayed": {}, - "resourcesSortByYear": "根据年份", - "@resourcesSortByYear": {}, - "searchHeaderTitle": "搜索: {query}", - "@searchHeaderTitle": { - "placeholders": { - "query": { - "type": "String" - } - } - }, - "searchInputPlaceholder": "搜索", - "@searchInputPlaceholder": {}, - "searchMoreResults": "更多…", - "@searchMoreResults": {}, - "searchNowPlayingContext": "搜索结果", - "@searchNowPlayingContext": {}, - "settingsAboutActionsLicenses": "许可", - "@settingsAboutActionsLicenses": {}, - "settingsAboutActionsProjectHomepage": "项目地址", - "@settingsAboutActionsProjectHomepage": {}, - "settingsAboutName": "关于", - "@settingsAboutName": {}, - "settingsAboutVersion": "版本 {version}", - "@settingsAboutVersion": { - "placeholders": { - "version": { - "type": "String" - } - } - }, - "settingsMusicName": "音乐", - "@settingsMusicName": {}, - "settingsMusicOptionsScrobbleDescriptionOff": "不记录你的播放历史", - "@settingsMusicOptionsScrobbleDescriptionOff": {}, - "settingsMusicOptionsScrobbleDescriptionOn": "记录你的播放历史", - "@settingsMusicOptionsScrobbleDescriptionOn": {}, - "settingsMusicOptionsScrobbleTitle": "记录播放历史", - "@settingsMusicOptionsScrobbleTitle": {}, - "settingsNetworkName": "网络", - "@settingsNetworkName": {}, - "settingsNetworkOptionsMaxBitrateMobileTitle": "最大比特率 (移动数据/流量)", - "@settingsNetworkOptionsMaxBitrateMobileTitle": {}, - "settingsNetworkOptionsMaxBitrateWifiTitle": "最大比特率 (Wi-Fi)", - "@settingsNetworkOptionsMaxBitrateWifiTitle": {}, - "settingsNetworkOptionsMaxBufferTitle": "最大缓冲时间", - "@settingsNetworkOptionsMaxBufferTitle": {}, - "settingsNetworkOptionsMinBufferTitle": "最小缓冲时间", - "@settingsNetworkOptionsMinBufferTitle": {}, - "settingsNetworkValuesKbps": "{value}kbps", - "@settingsNetworkValuesKbps": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesSeconds": "{value} 秒", - "@settingsNetworkValuesSeconds": { - "placeholders": { - "value": { - "type": "String" - } - } - }, - "settingsNetworkValuesUnlimitedKbps": "不限制", - "@settingsNetworkValuesUnlimitedKbps": {}, - "settingsResetActionsClearImageCache": "清除图片缓存", - "@settingsResetActionsClearImageCache": {}, - "settingsResetName": "重置", - "@settingsResetName": {}, - "settingsServersActionsAdd": "添加服务器", - "@settingsServersActionsAdd": {}, - "settingsServersActionsDelete": "删除", - "@settingsServersActionsDelete": {}, - "settingsServersActionsEdit": "编辑服务器", - "@settingsServersActionsEdit": {}, - "settingsServersActionsSave": "保存", - "@settingsServersActionsSave": {}, - "settingsServersActionsTestConnection": "测试连接", - "@settingsServersActionsTestConnection": {}, - "settingsServersFieldsAddress": "地址", - "@settingsServersFieldsAddress": {}, - "settingsServersFieldsPassword": "密码", - "@settingsServersFieldsPassword": {}, - "settingsServersFieldsUsername": "用户名", - "@settingsServersFieldsUsername": {}, - "settingsServersMessagesConnectionFailed": "连接到 {address} 失败,检查设置或服务器", - "@settingsServersMessagesConnectionFailed": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersMessagesConnectionOk": "连接到 {address} 正常!", - "@settingsServersMessagesConnectionOk": { - "placeholders": { - "address": { - "type": "String" - } - } - }, - "settingsServersName": "服务器", - "@settingsServersName": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "密码以 token + salt 加密发送", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, - "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "密码以明文发送(不推荐,注意链接安全!)", - "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, - "settingsServersOptionsForcePlaintextPasswordTitle": "强制使用明文密码", - "@settingsServersOptionsForcePlaintextPasswordTitle": {}, - "actionsDownload": "下载", - "@actionsDownload": {}, - "actionsDownloadCancel": "取消下载", - "@actionsDownloadCancel": {}, - "actionsDownloadDelete": "删除已下载", - "@actionsDownloadDelete": {}, - "actionsOk": "确定", - "@actionsOk": {}, - "resourcesFilterArtist": "歌手", - "@resourcesFilterArtist": {}, - "resourcesFilterOwner": "所有者", - "@resourcesFilterOwner": {}, - "resourcesSongListDeleteAllTitle": "删除下载的内容?", - "@resourcesSongListDeleteAllTitle": {}, - "resourcesSortByAlbum": "专辑", - "@resourcesSortByAlbum": {}, - "resourcesSortByAlbumCount": "专辑数量", - "@resourcesSortByAlbumCount": {}, - "resourcesSortByUpdated": "最近添加", - "@resourcesSortByUpdated": {}, - "settingsAboutActionsSupport": "支持开发者", - "@settingsAboutActionsSupport": {}, - "resourcesFilterAlbum": "专辑", - "@resourcesFilterAlbum": {}, - "resourcesSortByTitle": "标题", - "@resourcesSortByTitle": {}, - "actionsCancel": "取消", - "@actionsCancel": {}, - "actionsDelete": "删除", - "@actionsDelete": {}, - "resourcesFilterYear": "年份", - "@resourcesFilterYear": {}, - "resourcesSongListDeleteAllContent": "该操作会删除所有已下载的歌曲文件。", - "@resourcesSongListDeleteAllContent": {}, - "settingsAboutShareLogs": "分享日志", - "@settingsAboutShareLogs": {}, - "settingsAboutChooseLog": "选择一份日志文件", - "@settingsAboutChooseLog": {}, - "settingsNetworkOptionsOfflineModeOff": "使用互联网同步音乐。", - "@settingsNetworkOptionsOfflineModeOff": {}, - "settingsNetworkOptionsOfflineModeOn": "不使用互联网同步或播放音乐。", - "@settingsNetworkOptionsOfflineModeOn": {}, - "controlsShuffle": "随机播放", - "@controlsShuffle": {}, - "resourcesAlbumCount": "{count,plural, other{{count} 张专辑}}", - "@resourcesAlbumCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesArtistCount": "{count,plural, other{{count} 位歌手}}", - "@resourcesArtistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "resourcesSongCount": "{count,plural, other{{count} 首歌曲}}", - "@resourcesSongCount": { - "placeholders": { - "count": { - "type": "int" - } - } - }, - "settingsNetworkOptionsOfflineMode": "离线模式", - "@settingsNetworkOptionsOfflineMode": {}, - "settingsNetworkOptionsStreamFormatServerDefault": "使用服务器默认设置", - "@settingsNetworkOptionsStreamFormatServerDefault": {}, - "settingsNetworkOptionsStreamFormat": "偏好的流媒体格式", - "@settingsNetworkOptionsStreamFormat": {}, - "settingsServersFieldsName": "名称", - "@settingsServersFieldsName": {}, - "resourcesPlaylistCount": "{count,plural, other{{count} 张播放列表}}", - "@resourcesPlaylistCount": { - "placeholders": { - "count": { - "type": "int" - } - } - } -} diff --git a/lib/log.dart b/lib/log.dart deleted file mode 100644 index db6f3c2a..00000000 --- a/lib/log.dart +++ /dev/null @@ -1,209 +0,0 @@ -// import 'dart:convert'; - -import 'dart:io'; - -import 'package:collection/collection.dart'; -import 'package:flutter/foundation.dart'; -import 'package:logging/logging.dart'; -import 'package:path/path.dart' as p; -import 'package:path_provider/path_provider.dart'; - -class AnsiColor { - /// ANSI Control Sequence Introducer, signals the terminal for new settings. - static const ansiEsc = '\x1B['; - - /// Reset all colors and options for current SGRs to terminal defaults. - static const ansiDefault = '${ansiEsc}0m'; - - final int? fg; - final int? bg; - final bool color; - - AnsiColor.none() - : fg = null, - bg = null, - color = false; - - AnsiColor.fg(this.fg) - : bg = null, - color = true; - - AnsiColor.bg(this.bg) - : fg = null, - color = true; - - @override - String toString() { - if (fg != null) { - return '${ansiEsc}38;5;${fg}m'; - } else if (bg != null) { - return '${ansiEsc}48;5;${bg}m'; - } else { - return ''; - } - } - - String call(String msg) { - if (color) { - // ignore: unnecessary_brace_in_string_interps - return '${this}$msg$ansiDefault'; - } else { - return msg; - } - } - - AnsiColor toFg() => AnsiColor.fg(bg); - - AnsiColor toBg() => AnsiColor.bg(fg); - - /// Defaults the terminal's foreground color without altering the background. - String get resetForeground => color ? '${ansiEsc}39m' : ''; - - /// Defaults the terminal's background color without altering the foreground. - String get resetBackground => color ? '${ansiEsc}49m' : ''; - - static int grey(double level) => 232 + (level.clamp(0.0, 1.0) * 23).round(); -} - -final levelColors = { - Level.FINEST: AnsiColor.fg(AnsiColor.grey(0.5)), - Level.FINER: AnsiColor.fg(AnsiColor.grey(0.5)), - Level.FINE: AnsiColor.fg(AnsiColor.grey(0.5)), - Level.CONFIG: AnsiColor.fg(81), - Level.INFO: AnsiColor.fg(12), - Level.WARNING: AnsiColor.fg(208), - Level.SEVERE: AnsiColor.fg(196), - Level.SHOUT: AnsiColor.fg(199), -}; - -class LogData { - final String? message; - final Object? data; - - const LogData(this.message, this.data); -} - -String _format( - LogRecord event, { - bool color = false, - bool time = true, - bool level = true, - bool redact = true, -}) { - var message = ''; - if (time) message += '${event.time.toIso8601String()} '; - if (level) message += '${event.level.name} '; - - final object = event.object; - if (object is LogData) { - message += '${object.message}'; - message += '\n${object.data}'; - } else if (object != null) { - message += 'Object'; - message += '\n$object'; - } else { - message += event.message; - } - - if (event.error != null) { - message += '\n${event.error}'; - } - - if (redact) { - message = _redactUrl(message); - } - - if (event.stackTrace != null) { - message += '\n${event.stackTrace}'; - } - - return color - ? message.split('\n').map((e) => levelColors[event.level]!(e)).join('\n') - : message; -} - -String _redactUrl(String message) { - if (!_queryReplace('u').hasMatch(message)) { - return message; - } - - message = _redactParam(message, 'u'); - message = _redactParam(message, 'p'); - message = _redactParam(message, 's'); - message = _redactParam(message, 't'); - - return message; -} - -RegExp _queryReplace(String key) => RegExp('$key=([^&|\\n|\\t\\s]+)'); - -String _redactParam(String url, String key) => - url.replaceAll(_queryReplace(key), '$key=REDACTED'); - -Future logDirectory() async { - return Directory( - p.join((await getApplicationDocumentsDirectory()).path, 'logs'), - ); -} - -Future> logFiles() async { - final dir = await logDirectory(); - return dir.listSync().whereType().toList() - ..sort( - (a, b) => b.statSync().modified.compareTo(a.statSync().modified), - ); -} - -File _currentLogFile(String logDir) { - final now = DateTime.now(); - return File(p.join(logDir, '${now.year}-${now.month}-${now.day}.txt')); -} - -Future _printFile(String event, String logDir) async { - final file = _currentLogFile(logDir); - - if (!event.endsWith('\n')) { - event += '\n'; - } - - await file.writeAsString(event, mode: FileMode.writeOnlyAppend, flush: true); -} - -void _printDebug(LogRecord event) { - // ignore: avoid_print - print(_format(event, color: true, time: false, level: false, redact: false)); -} - -Future _printRelease(LogRecord event, String logDir) async { - await _printFile( - _format(event, color: false, time: true, level: true, redact: true), - logDir, - ); -} - -final log = Logger('default'); - -Future initLogging() async { - final dir = (await logDirectory())..create(); - - final file = _currentLogFile(dir.path); - if (!(await file.exists())) { - await file.create(); - } - - final files = await logFiles(); - if (files.length > 7) { - for (var file in files.slice(7)) { - await file.delete(); - } - } - - Logger.root.level = kDebugMode ? Level.ALL : Level.INFO; - Logger.root.onRecord.asyncMap((event) async { - if (kDebugMode) { - _printDebug(event); - } else { - await _printRelease(event, dir.path); - } - }).listen((_) {}, cancelOnError: false); -} diff --git a/lib/main.dart b/lib/main.dart deleted file mode 100644 index b2a5b298..00000000 --- a/lib/main.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:stack_trace/stack_trace.dart' as stack_trace; -import 'package:worker_manager/worker_manager.dart'; - -import 'app/app.dart'; -import 'log.dart'; - -void main() async { - // TOOD: probably remove before live - // https://stackoverflow.com/a/73770713 - FlutterError.demangleStackTrace = (StackTrace stack) { - if (stack is stack_trace.Trace) return stack.vmTrace; - if (stack is stack_trace.Chain) return stack.toTrace().vmTrace; - return stack; - }; - - // keep some threads warm for background (palette generation) tasks - await Executor().warmUp(); - - WidgetsFlutterBinding.ensureInitialized(); - - await initLogging(); - - runApp(const ProviderScope(child: MyApp())); -} diff --git a/lib/models/music.dart b/lib/models/music.dart deleted file mode 100644 index bcc8cfe0..00000000 --- a/lib/models/music.dart +++ /dev/null @@ -1,115 +0,0 @@ -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:flutter/foundation.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'music.freezed.dart'; - -abstract class SourceIdentifiable { - int get sourceId; - String get id; -} - -abstract class SongList extends SourceIdentifiable { - String get name; - int get songCount; -} - -@freezed -class SourceId with _$SourceId implements SourceIdentifiable { - const factory SourceId({ - required int sourceId, - required String id, - }) = _SourceId; - - factory SourceId.from(SourceIdentifiable item) { - return SourceId(sourceId: item.sourceId, id: item.id); - } -} - -@freezed -class SourceIdSet with _$SourceIdSet { - const factory SourceIdSet({ - required int sourceId, - required ISet ids, - }) = _SourceIdSet; -} - -@freezed -class Artist with _$Artist { - const factory Artist({ - required int sourceId, - required String id, - required String name, - required int albumCount, - DateTime? starred, - // @Default(IListConst([])) IList albums, - }) = _Artist; -} - -@freezed -class Album with _$Album implements SongList { - const factory Album({ - required int sourceId, - required String id, - required String name, - String? artistId, - String? albumArtist, - required DateTime created, - String? coverArt, - int? year, - DateTime? starred, - // DateTime? synced, - String? genre, - required int songCount, - @Default(false) bool isDeleted, - // @Default(IListConst([])) IList songs, - int? frequentRank, - int? recentRank, - }) = _Album; -} - -@freezed -class Playlist with _$Playlist implements SongList { - const factory Playlist({ - required int sourceId, - required String id, - required String name, - String? comment, - String? coverArt, - required int songCount, - required DateTime created, - // DateTime? synced, - // @Default(IListConst([])) IList songs, - }) = _Playlist; -} - -@freezed -class Song with _$Song implements SourceIdentifiable { - const factory Song({ - required int sourceId, - required String id, - String? albumId, - String? artistId, - required String title, - String? artist, - String? album, - Duration? duration, - int? track, - int? disc, - DateTime? starred, - String? genre, - String? downloadTaskId, - String? downloadFilePath, - @Default(false) bool isDeleted, - }) = _Song; -} - -@freezed -class SearchResults with _$SearchResults { - const factory SearchResults({ - String? query, - @Default(IListConst([])) IList songs, - @Default(IListConst([])) IList albums, - @Default(IListConst([])) IList artists, - }) = _SearchResults; -} diff --git a/lib/models/music.freezed.dart b/lib/models/music.freezed.dart deleted file mode 100644 index ff884680..00000000 --- a/lib/models/music.freezed.dart +++ /dev/null @@ -1,1834 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'music.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -/// @nodoc -mixin _$SourceId { - int get sourceId => throw _privateConstructorUsedError; - String get id => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $SourceIdCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $SourceIdCopyWith<$Res> { - factory $SourceIdCopyWith(SourceId value, $Res Function(SourceId) then) = - _$SourceIdCopyWithImpl<$Res, SourceId>; - @useResult - $Res call({int sourceId, String id}); -} - -/// @nodoc -class _$SourceIdCopyWithImpl<$Res, $Val extends SourceId> - implements $SourceIdCopyWith<$Res> { - _$SourceIdCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? id = null, - }) { - return _then(_value.copyWith( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_SourceIdCopyWith<$Res> implements $SourceIdCopyWith<$Res> { - factory _$$_SourceIdCopyWith( - _$_SourceId value, $Res Function(_$_SourceId) then) = - __$$_SourceIdCopyWithImpl<$Res>; - @override - @useResult - $Res call({int sourceId, String id}); -} - -/// @nodoc -class __$$_SourceIdCopyWithImpl<$Res> - extends _$SourceIdCopyWithImpl<$Res, _$_SourceId> - implements _$$_SourceIdCopyWith<$Res> { - __$$_SourceIdCopyWithImpl( - _$_SourceId _value, $Res Function(_$_SourceId) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? id = null, - }) { - return _then(_$_SourceId( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - )); - } -} - -/// @nodoc - -class _$_SourceId with DiagnosticableTreeMixin implements _SourceId { - const _$_SourceId({required this.sourceId, required this.id}); - - @override - final int sourceId; - @override - final String id; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'SourceId(sourceId: $sourceId, id: $id)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'SourceId')) - ..add(DiagnosticsProperty('sourceId', sourceId)) - ..add(DiagnosticsProperty('id', id)); - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_SourceId && - (identical(other.sourceId, sourceId) || - other.sourceId == sourceId) && - (identical(other.id, id) || other.id == id)); - } - - @override - int get hashCode => Object.hash(runtimeType, sourceId, id); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_SourceIdCopyWith<_$_SourceId> get copyWith => - __$$_SourceIdCopyWithImpl<_$_SourceId>(this, _$identity); -} - -abstract class _SourceId implements SourceId { - const factory _SourceId( - {required final int sourceId, required final String id}) = _$_SourceId; - - @override - int get sourceId; - @override - String get id; - @override - @JsonKey(ignore: true) - _$$_SourceIdCopyWith<_$_SourceId> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$SourceIdSet { - int get sourceId => throw _privateConstructorUsedError; - ISet get ids => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $SourceIdSetCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $SourceIdSetCopyWith<$Res> { - factory $SourceIdSetCopyWith( - SourceIdSet value, $Res Function(SourceIdSet) then) = - _$SourceIdSetCopyWithImpl<$Res, SourceIdSet>; - @useResult - $Res call({int sourceId, ISet ids}); -} - -/// @nodoc -class _$SourceIdSetCopyWithImpl<$Res, $Val extends SourceIdSet> - implements $SourceIdSetCopyWith<$Res> { - _$SourceIdSetCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? ids = null, - }) { - return _then(_value.copyWith( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - ids: null == ids - ? _value.ids - : ids // ignore: cast_nullable_to_non_nullable - as ISet, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_SourceIdSetCopyWith<$Res> - implements $SourceIdSetCopyWith<$Res> { - factory _$$_SourceIdSetCopyWith( - _$_SourceIdSet value, $Res Function(_$_SourceIdSet) then) = - __$$_SourceIdSetCopyWithImpl<$Res>; - @override - @useResult - $Res call({int sourceId, ISet ids}); -} - -/// @nodoc -class __$$_SourceIdSetCopyWithImpl<$Res> - extends _$SourceIdSetCopyWithImpl<$Res, _$_SourceIdSet> - implements _$$_SourceIdSetCopyWith<$Res> { - __$$_SourceIdSetCopyWithImpl( - _$_SourceIdSet _value, $Res Function(_$_SourceIdSet) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? ids = null, - }) { - return _then(_$_SourceIdSet( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - ids: null == ids - ? _value.ids - : ids // ignore: cast_nullable_to_non_nullable - as ISet, - )); - } -} - -/// @nodoc - -class _$_SourceIdSet with DiagnosticableTreeMixin implements _SourceIdSet { - const _$_SourceIdSet({required this.sourceId, required this.ids}); - - @override - final int sourceId; - @override - final ISet ids; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'SourceIdSet(sourceId: $sourceId, ids: $ids)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'SourceIdSet')) - ..add(DiagnosticsProperty('sourceId', sourceId)) - ..add(DiagnosticsProperty('ids', ids)); - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_SourceIdSet && - (identical(other.sourceId, sourceId) || - other.sourceId == sourceId) && - const DeepCollectionEquality().equals(other.ids, ids)); - } - - @override - int get hashCode => Object.hash( - runtimeType, sourceId, const DeepCollectionEquality().hash(ids)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_SourceIdSetCopyWith<_$_SourceIdSet> get copyWith => - __$$_SourceIdSetCopyWithImpl<_$_SourceIdSet>(this, _$identity); -} - -abstract class _SourceIdSet implements SourceIdSet { - const factory _SourceIdSet( - {required final int sourceId, - required final ISet ids}) = _$_SourceIdSet; - - @override - int get sourceId; - @override - ISet get ids; - @override - @JsonKey(ignore: true) - _$$_SourceIdSetCopyWith<_$_SourceIdSet> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$Artist { - int get sourceId => throw _privateConstructorUsedError; - String get id => throw _privateConstructorUsedError; - String get name => throw _privateConstructorUsedError; - int get albumCount => throw _privateConstructorUsedError; - DateTime? get starred => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $ArtistCopyWith get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $ArtistCopyWith<$Res> { - factory $ArtistCopyWith(Artist value, $Res Function(Artist) then) = - _$ArtistCopyWithImpl<$Res, Artist>; - @useResult - $Res call( - {int sourceId, - String id, - String name, - int albumCount, - DateTime? starred}); -} - -/// @nodoc -class _$ArtistCopyWithImpl<$Res, $Val extends Artist> - implements $ArtistCopyWith<$Res> { - _$ArtistCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? id = null, - Object? name = null, - Object? albumCount = null, - Object? starred = freezed, - }) { - return _then(_value.copyWith( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - albumCount: null == albumCount - ? _value.albumCount - : albumCount // ignore: cast_nullable_to_non_nullable - as int, - starred: freezed == starred - ? _value.starred - : starred // ignore: cast_nullable_to_non_nullable - as DateTime?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_ArtistCopyWith<$Res> implements $ArtistCopyWith<$Res> { - factory _$$_ArtistCopyWith(_$_Artist value, $Res Function(_$_Artist) then) = - __$$_ArtistCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {int sourceId, - String id, - String name, - int albumCount, - DateTime? starred}); -} - -/// @nodoc -class __$$_ArtistCopyWithImpl<$Res> - extends _$ArtistCopyWithImpl<$Res, _$_Artist> - implements _$$_ArtistCopyWith<$Res> { - __$$_ArtistCopyWithImpl(_$_Artist _value, $Res Function(_$_Artist) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? id = null, - Object? name = null, - Object? albumCount = null, - Object? starred = freezed, - }) { - return _then(_$_Artist( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - albumCount: null == albumCount - ? _value.albumCount - : albumCount // ignore: cast_nullable_to_non_nullable - as int, - starred: freezed == starred - ? _value.starred - : starred // ignore: cast_nullable_to_non_nullable - as DateTime?, - )); - } -} - -/// @nodoc - -class _$_Artist with DiagnosticableTreeMixin implements _Artist { - const _$_Artist( - {required this.sourceId, - required this.id, - required this.name, - required this.albumCount, - this.starred}); - - @override - final int sourceId; - @override - final String id; - @override - final String name; - @override - final int albumCount; - @override - final DateTime? starred; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'Artist(sourceId: $sourceId, id: $id, name: $name, albumCount: $albumCount, starred: $starred)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'Artist')) - ..add(DiagnosticsProperty('sourceId', sourceId)) - ..add(DiagnosticsProperty('id', id)) - ..add(DiagnosticsProperty('name', name)) - ..add(DiagnosticsProperty('albumCount', albumCount)) - ..add(DiagnosticsProperty('starred', starred)); - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_Artist && - (identical(other.sourceId, sourceId) || - other.sourceId == sourceId) && - (identical(other.id, id) || other.id == id) && - (identical(other.name, name) || other.name == name) && - (identical(other.albumCount, albumCount) || - other.albumCount == albumCount) && - (identical(other.starred, starred) || other.starred == starred)); - } - - @override - int get hashCode => - Object.hash(runtimeType, sourceId, id, name, albumCount, starred); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_ArtistCopyWith<_$_Artist> get copyWith => - __$$_ArtistCopyWithImpl<_$_Artist>(this, _$identity); -} - -abstract class _Artist implements Artist { - const factory _Artist( - {required final int sourceId, - required final String id, - required final String name, - required final int albumCount, - final DateTime? starred}) = _$_Artist; - - @override - int get sourceId; - @override - String get id; - @override - String get name; - @override - int get albumCount; - @override - DateTime? get starred; - @override - @JsonKey(ignore: true) - _$$_ArtistCopyWith<_$_Artist> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$Album { - int get sourceId => throw _privateConstructorUsedError; - String get id => throw _privateConstructorUsedError; - String get name => throw _privateConstructorUsedError; - String? get artistId => throw _privateConstructorUsedError; - String? get albumArtist => throw _privateConstructorUsedError; - DateTime get created => throw _privateConstructorUsedError; - String? get coverArt => throw _privateConstructorUsedError; - int? get year => throw _privateConstructorUsedError; - DateTime? get starred => - throw _privateConstructorUsedError; // DateTime? synced, - String? get genre => throw _privateConstructorUsedError; - int get songCount => throw _privateConstructorUsedError; - bool get isDeleted => - throw _privateConstructorUsedError; // @Default(IListConst([])) IList songs, - int? get frequentRank => throw _privateConstructorUsedError; - int? get recentRank => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $AlbumCopyWith get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $AlbumCopyWith<$Res> { - factory $AlbumCopyWith(Album value, $Res Function(Album) then) = - _$AlbumCopyWithImpl<$Res, Album>; - @useResult - $Res call( - {int sourceId, - String id, - String name, - String? artistId, - String? albumArtist, - DateTime created, - String? coverArt, - int? year, - DateTime? starred, - String? genre, - int songCount, - bool isDeleted, - int? frequentRank, - int? recentRank}); -} - -/// @nodoc -class _$AlbumCopyWithImpl<$Res, $Val extends Album> - implements $AlbumCopyWith<$Res> { - _$AlbumCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? id = null, - Object? name = null, - Object? artistId = freezed, - Object? albumArtist = freezed, - Object? created = null, - Object? coverArt = freezed, - Object? year = freezed, - Object? starred = freezed, - Object? genre = freezed, - Object? songCount = null, - Object? isDeleted = null, - Object? frequentRank = freezed, - Object? recentRank = freezed, - }) { - return _then(_value.copyWith( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - artistId: freezed == artistId - ? _value.artistId - : artistId // ignore: cast_nullable_to_non_nullable - as String?, - albumArtist: freezed == albumArtist - ? _value.albumArtist - : albumArtist // ignore: cast_nullable_to_non_nullable - as String?, - created: null == created - ? _value.created - : created // ignore: cast_nullable_to_non_nullable - as DateTime, - coverArt: freezed == coverArt - ? _value.coverArt - : coverArt // ignore: cast_nullable_to_non_nullable - as String?, - year: freezed == year - ? _value.year - : year // ignore: cast_nullable_to_non_nullable - as int?, - starred: freezed == starred - ? _value.starred - : starred // ignore: cast_nullable_to_non_nullable - as DateTime?, - genre: freezed == genre - ? _value.genre - : genre // ignore: cast_nullable_to_non_nullable - as String?, - songCount: null == songCount - ? _value.songCount - : songCount // ignore: cast_nullable_to_non_nullable - as int, - isDeleted: null == isDeleted - ? _value.isDeleted - : isDeleted // ignore: cast_nullable_to_non_nullable - as bool, - frequentRank: freezed == frequentRank - ? _value.frequentRank - : frequentRank // ignore: cast_nullable_to_non_nullable - as int?, - recentRank: freezed == recentRank - ? _value.recentRank - : recentRank // ignore: cast_nullable_to_non_nullable - as int?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_AlbumCopyWith<$Res> implements $AlbumCopyWith<$Res> { - factory _$$_AlbumCopyWith(_$_Album value, $Res Function(_$_Album) then) = - __$$_AlbumCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {int sourceId, - String id, - String name, - String? artistId, - String? albumArtist, - DateTime created, - String? coverArt, - int? year, - DateTime? starred, - String? genre, - int songCount, - bool isDeleted, - int? frequentRank, - int? recentRank}); -} - -/// @nodoc -class __$$_AlbumCopyWithImpl<$Res> extends _$AlbumCopyWithImpl<$Res, _$_Album> - implements _$$_AlbumCopyWith<$Res> { - __$$_AlbumCopyWithImpl(_$_Album _value, $Res Function(_$_Album) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? id = null, - Object? name = null, - Object? artistId = freezed, - Object? albumArtist = freezed, - Object? created = null, - Object? coverArt = freezed, - Object? year = freezed, - Object? starred = freezed, - Object? genre = freezed, - Object? songCount = null, - Object? isDeleted = null, - Object? frequentRank = freezed, - Object? recentRank = freezed, - }) { - return _then(_$_Album( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - artistId: freezed == artistId - ? _value.artistId - : artistId // ignore: cast_nullable_to_non_nullable - as String?, - albumArtist: freezed == albumArtist - ? _value.albumArtist - : albumArtist // ignore: cast_nullable_to_non_nullable - as String?, - created: null == created - ? _value.created - : created // ignore: cast_nullable_to_non_nullable - as DateTime, - coverArt: freezed == coverArt - ? _value.coverArt - : coverArt // ignore: cast_nullable_to_non_nullable - as String?, - year: freezed == year - ? _value.year - : year // ignore: cast_nullable_to_non_nullable - as int?, - starred: freezed == starred - ? _value.starred - : starred // ignore: cast_nullable_to_non_nullable - as DateTime?, - genre: freezed == genre - ? _value.genre - : genre // ignore: cast_nullable_to_non_nullable - as String?, - songCount: null == songCount - ? _value.songCount - : songCount // ignore: cast_nullable_to_non_nullable - as int, - isDeleted: null == isDeleted - ? _value.isDeleted - : isDeleted // ignore: cast_nullable_to_non_nullable - as bool, - frequentRank: freezed == frequentRank - ? _value.frequentRank - : frequentRank // ignore: cast_nullable_to_non_nullable - as int?, - recentRank: freezed == recentRank - ? _value.recentRank - : recentRank // ignore: cast_nullable_to_non_nullable - as int?, - )); - } -} - -/// @nodoc - -class _$_Album with DiagnosticableTreeMixin implements _Album { - const _$_Album( - {required this.sourceId, - required this.id, - required this.name, - this.artistId, - this.albumArtist, - required this.created, - this.coverArt, - this.year, - this.starred, - this.genre, - required this.songCount, - this.isDeleted = false, - this.frequentRank, - this.recentRank}); - - @override - final int sourceId; - @override - final String id; - @override - final String name; - @override - final String? artistId; - @override - final String? albumArtist; - @override - final DateTime created; - @override - final String? coverArt; - @override - final int? year; - @override - final DateTime? starred; -// DateTime? synced, - @override - final String? genre; - @override - final int songCount; - @override - @JsonKey() - final bool isDeleted; -// @Default(IListConst([])) IList songs, - @override - final int? frequentRank; - @override - final int? recentRank; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'Album(sourceId: $sourceId, id: $id, name: $name, artistId: $artistId, albumArtist: $albumArtist, created: $created, coverArt: $coverArt, year: $year, starred: $starred, genre: $genre, songCount: $songCount, isDeleted: $isDeleted, frequentRank: $frequentRank, recentRank: $recentRank)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'Album')) - ..add(DiagnosticsProperty('sourceId', sourceId)) - ..add(DiagnosticsProperty('id', id)) - ..add(DiagnosticsProperty('name', name)) - ..add(DiagnosticsProperty('artistId', artistId)) - ..add(DiagnosticsProperty('albumArtist', albumArtist)) - ..add(DiagnosticsProperty('created', created)) - ..add(DiagnosticsProperty('coverArt', coverArt)) - ..add(DiagnosticsProperty('year', year)) - ..add(DiagnosticsProperty('starred', starred)) - ..add(DiagnosticsProperty('genre', genre)) - ..add(DiagnosticsProperty('songCount', songCount)) - ..add(DiagnosticsProperty('isDeleted', isDeleted)) - ..add(DiagnosticsProperty('frequentRank', frequentRank)) - ..add(DiagnosticsProperty('recentRank', recentRank)); - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_Album && - (identical(other.sourceId, sourceId) || - other.sourceId == sourceId) && - (identical(other.id, id) || other.id == id) && - (identical(other.name, name) || other.name == name) && - (identical(other.artistId, artistId) || - other.artistId == artistId) && - (identical(other.albumArtist, albumArtist) || - other.albumArtist == albumArtist) && - (identical(other.created, created) || other.created == created) && - (identical(other.coverArt, coverArt) || - other.coverArt == coverArt) && - (identical(other.year, year) || other.year == year) && - (identical(other.starred, starred) || other.starred == starred) && - (identical(other.genre, genre) || other.genre == genre) && - (identical(other.songCount, songCount) || - other.songCount == songCount) && - (identical(other.isDeleted, isDeleted) || - other.isDeleted == isDeleted) && - (identical(other.frequentRank, frequentRank) || - other.frequentRank == frequentRank) && - (identical(other.recentRank, recentRank) || - other.recentRank == recentRank)); - } - - @override - int get hashCode => Object.hash( - runtimeType, - sourceId, - id, - name, - artistId, - albumArtist, - created, - coverArt, - year, - starred, - genre, - songCount, - isDeleted, - frequentRank, - recentRank); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_AlbumCopyWith<_$_Album> get copyWith => - __$$_AlbumCopyWithImpl<_$_Album>(this, _$identity); -} - -abstract class _Album implements Album { - const factory _Album( - {required final int sourceId, - required final String id, - required final String name, - final String? artistId, - final String? albumArtist, - required final DateTime created, - final String? coverArt, - final int? year, - final DateTime? starred, - final String? genre, - required final int songCount, - final bool isDeleted, - final int? frequentRank, - final int? recentRank}) = _$_Album; - - @override - int get sourceId; - @override - String get id; - @override - String get name; - @override - String? get artistId; - @override - String? get albumArtist; - @override - DateTime get created; - @override - String? get coverArt; - @override - int? get year; - @override - DateTime? get starred; - @override // DateTime? synced, - String? get genre; - @override - int get songCount; - @override - bool get isDeleted; - @override // @Default(IListConst([])) IList songs, - int? get frequentRank; - @override - int? get recentRank; - @override - @JsonKey(ignore: true) - _$$_AlbumCopyWith<_$_Album> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$Playlist { - int get sourceId => throw _privateConstructorUsedError; - String get id => throw _privateConstructorUsedError; - String get name => throw _privateConstructorUsedError; - String? get comment => throw _privateConstructorUsedError; - String? get coverArt => throw _privateConstructorUsedError; - int get songCount => throw _privateConstructorUsedError; - DateTime get created => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $PlaylistCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $PlaylistCopyWith<$Res> { - factory $PlaylistCopyWith(Playlist value, $Res Function(Playlist) then) = - _$PlaylistCopyWithImpl<$Res, Playlist>; - @useResult - $Res call( - {int sourceId, - String id, - String name, - String? comment, - String? coverArt, - int songCount, - DateTime created}); -} - -/// @nodoc -class _$PlaylistCopyWithImpl<$Res, $Val extends Playlist> - implements $PlaylistCopyWith<$Res> { - _$PlaylistCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? id = null, - Object? name = null, - Object? comment = freezed, - Object? coverArt = freezed, - Object? songCount = null, - Object? created = null, - }) { - return _then(_value.copyWith( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - comment: freezed == comment - ? _value.comment - : comment // ignore: cast_nullable_to_non_nullable - as String?, - coverArt: freezed == coverArt - ? _value.coverArt - : coverArt // ignore: cast_nullable_to_non_nullable - as String?, - songCount: null == songCount - ? _value.songCount - : songCount // ignore: cast_nullable_to_non_nullable - as int, - created: null == created - ? _value.created - : created // ignore: cast_nullable_to_non_nullable - as DateTime, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_PlaylistCopyWith<$Res> implements $PlaylistCopyWith<$Res> { - factory _$$_PlaylistCopyWith( - _$_Playlist value, $Res Function(_$_Playlist) then) = - __$$_PlaylistCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {int sourceId, - String id, - String name, - String? comment, - String? coverArt, - int songCount, - DateTime created}); -} - -/// @nodoc -class __$$_PlaylistCopyWithImpl<$Res> - extends _$PlaylistCopyWithImpl<$Res, _$_Playlist> - implements _$$_PlaylistCopyWith<$Res> { - __$$_PlaylistCopyWithImpl( - _$_Playlist _value, $Res Function(_$_Playlist) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? id = null, - Object? name = null, - Object? comment = freezed, - Object? coverArt = freezed, - Object? songCount = null, - Object? created = null, - }) { - return _then(_$_Playlist( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - comment: freezed == comment - ? _value.comment - : comment // ignore: cast_nullable_to_non_nullable - as String?, - coverArt: freezed == coverArt - ? _value.coverArt - : coverArt // ignore: cast_nullable_to_non_nullable - as String?, - songCount: null == songCount - ? _value.songCount - : songCount // ignore: cast_nullable_to_non_nullable - as int, - created: null == created - ? _value.created - : created // ignore: cast_nullable_to_non_nullable - as DateTime, - )); - } -} - -/// @nodoc - -class _$_Playlist with DiagnosticableTreeMixin implements _Playlist { - const _$_Playlist( - {required this.sourceId, - required this.id, - required this.name, - this.comment, - this.coverArt, - required this.songCount, - required this.created}); - - @override - final int sourceId; - @override - final String id; - @override - final String name; - @override - final String? comment; - @override - final String? coverArt; - @override - final int songCount; - @override - final DateTime created; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'Playlist(sourceId: $sourceId, id: $id, name: $name, comment: $comment, coverArt: $coverArt, songCount: $songCount, created: $created)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'Playlist')) - ..add(DiagnosticsProperty('sourceId', sourceId)) - ..add(DiagnosticsProperty('id', id)) - ..add(DiagnosticsProperty('name', name)) - ..add(DiagnosticsProperty('comment', comment)) - ..add(DiagnosticsProperty('coverArt', coverArt)) - ..add(DiagnosticsProperty('songCount', songCount)) - ..add(DiagnosticsProperty('created', created)); - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_Playlist && - (identical(other.sourceId, sourceId) || - other.sourceId == sourceId) && - (identical(other.id, id) || other.id == id) && - (identical(other.name, name) || other.name == name) && - (identical(other.comment, comment) || other.comment == comment) && - (identical(other.coverArt, coverArt) || - other.coverArt == coverArt) && - (identical(other.songCount, songCount) || - other.songCount == songCount) && - (identical(other.created, created) || other.created == created)); - } - - @override - int get hashCode => Object.hash( - runtimeType, sourceId, id, name, comment, coverArt, songCount, created); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_PlaylistCopyWith<_$_Playlist> get copyWith => - __$$_PlaylistCopyWithImpl<_$_Playlist>(this, _$identity); -} - -abstract class _Playlist implements Playlist { - const factory _Playlist( - {required final int sourceId, - required final String id, - required final String name, - final String? comment, - final String? coverArt, - required final int songCount, - required final DateTime created}) = _$_Playlist; - - @override - int get sourceId; - @override - String get id; - @override - String get name; - @override - String? get comment; - @override - String? get coverArt; - @override - int get songCount; - @override - DateTime get created; - @override - @JsonKey(ignore: true) - _$$_PlaylistCopyWith<_$_Playlist> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$Song { - int get sourceId => throw _privateConstructorUsedError; - String get id => throw _privateConstructorUsedError; - String? get albumId => throw _privateConstructorUsedError; - String? get artistId => throw _privateConstructorUsedError; - String get title => throw _privateConstructorUsedError; - String? get artist => throw _privateConstructorUsedError; - String? get album => throw _privateConstructorUsedError; - Duration? get duration => throw _privateConstructorUsedError; - int? get track => throw _privateConstructorUsedError; - int? get disc => throw _privateConstructorUsedError; - DateTime? get starred => throw _privateConstructorUsedError; - String? get genre => throw _privateConstructorUsedError; - String? get downloadTaskId => throw _privateConstructorUsedError; - String? get downloadFilePath => throw _privateConstructorUsedError; - bool get isDeleted => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $SongCopyWith get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $SongCopyWith<$Res> { - factory $SongCopyWith(Song value, $Res Function(Song) then) = - _$SongCopyWithImpl<$Res, Song>; - @useResult - $Res call( - {int sourceId, - String id, - String? albumId, - String? artistId, - String title, - String? artist, - String? album, - Duration? duration, - int? track, - int? disc, - DateTime? starred, - String? genre, - String? downloadTaskId, - String? downloadFilePath, - bool isDeleted}); -} - -/// @nodoc -class _$SongCopyWithImpl<$Res, $Val extends Song> - implements $SongCopyWith<$Res> { - _$SongCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? id = null, - Object? albumId = freezed, - Object? artistId = freezed, - Object? title = null, - Object? artist = freezed, - Object? album = freezed, - Object? duration = freezed, - Object? track = freezed, - Object? disc = freezed, - Object? starred = freezed, - Object? genre = freezed, - Object? downloadTaskId = freezed, - Object? downloadFilePath = freezed, - Object? isDeleted = null, - }) { - return _then(_value.copyWith( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - albumId: freezed == albumId - ? _value.albumId - : albumId // ignore: cast_nullable_to_non_nullable - as String?, - artistId: freezed == artistId - ? _value.artistId - : artistId // ignore: cast_nullable_to_non_nullable - as String?, - title: null == title - ? _value.title - : title // ignore: cast_nullable_to_non_nullable - as String, - artist: freezed == artist - ? _value.artist - : artist // ignore: cast_nullable_to_non_nullable - as String?, - album: freezed == album - ? _value.album - : album // ignore: cast_nullable_to_non_nullable - as String?, - duration: freezed == duration - ? _value.duration - : duration // ignore: cast_nullable_to_non_nullable - as Duration?, - track: freezed == track - ? _value.track - : track // ignore: cast_nullable_to_non_nullable - as int?, - disc: freezed == disc - ? _value.disc - : disc // ignore: cast_nullable_to_non_nullable - as int?, - starred: freezed == starred - ? _value.starred - : starred // ignore: cast_nullable_to_non_nullable - as DateTime?, - genre: freezed == genre - ? _value.genre - : genre // ignore: cast_nullable_to_non_nullable - as String?, - downloadTaskId: freezed == downloadTaskId - ? _value.downloadTaskId - : downloadTaskId // ignore: cast_nullable_to_non_nullable - as String?, - downloadFilePath: freezed == downloadFilePath - ? _value.downloadFilePath - : downloadFilePath // ignore: cast_nullable_to_non_nullable - as String?, - isDeleted: null == isDeleted - ? _value.isDeleted - : isDeleted // ignore: cast_nullable_to_non_nullable - as bool, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_SongCopyWith<$Res> implements $SongCopyWith<$Res> { - factory _$$_SongCopyWith(_$_Song value, $Res Function(_$_Song) then) = - __$$_SongCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {int sourceId, - String id, - String? albumId, - String? artistId, - String title, - String? artist, - String? album, - Duration? duration, - int? track, - int? disc, - DateTime? starred, - String? genre, - String? downloadTaskId, - String? downloadFilePath, - bool isDeleted}); -} - -/// @nodoc -class __$$_SongCopyWithImpl<$Res> extends _$SongCopyWithImpl<$Res, _$_Song> - implements _$$_SongCopyWith<$Res> { - __$$_SongCopyWithImpl(_$_Song _value, $Res Function(_$_Song) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? id = null, - Object? albumId = freezed, - Object? artistId = freezed, - Object? title = null, - Object? artist = freezed, - Object? album = freezed, - Object? duration = freezed, - Object? track = freezed, - Object? disc = freezed, - Object? starred = freezed, - Object? genre = freezed, - Object? downloadTaskId = freezed, - Object? downloadFilePath = freezed, - Object? isDeleted = null, - }) { - return _then(_$_Song( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - albumId: freezed == albumId - ? _value.albumId - : albumId // ignore: cast_nullable_to_non_nullable - as String?, - artistId: freezed == artistId - ? _value.artistId - : artistId // ignore: cast_nullable_to_non_nullable - as String?, - title: null == title - ? _value.title - : title // ignore: cast_nullable_to_non_nullable - as String, - artist: freezed == artist - ? _value.artist - : artist // ignore: cast_nullable_to_non_nullable - as String?, - album: freezed == album - ? _value.album - : album // ignore: cast_nullable_to_non_nullable - as String?, - duration: freezed == duration - ? _value.duration - : duration // ignore: cast_nullable_to_non_nullable - as Duration?, - track: freezed == track - ? _value.track - : track // ignore: cast_nullable_to_non_nullable - as int?, - disc: freezed == disc - ? _value.disc - : disc // ignore: cast_nullable_to_non_nullable - as int?, - starred: freezed == starred - ? _value.starred - : starred // ignore: cast_nullable_to_non_nullable - as DateTime?, - genre: freezed == genre - ? _value.genre - : genre // ignore: cast_nullable_to_non_nullable - as String?, - downloadTaskId: freezed == downloadTaskId - ? _value.downloadTaskId - : downloadTaskId // ignore: cast_nullable_to_non_nullable - as String?, - downloadFilePath: freezed == downloadFilePath - ? _value.downloadFilePath - : downloadFilePath // ignore: cast_nullable_to_non_nullable - as String?, - isDeleted: null == isDeleted - ? _value.isDeleted - : isDeleted // ignore: cast_nullable_to_non_nullable - as bool, - )); - } -} - -/// @nodoc - -class _$_Song with DiagnosticableTreeMixin implements _Song { - const _$_Song( - {required this.sourceId, - required this.id, - this.albumId, - this.artistId, - required this.title, - this.artist, - this.album, - this.duration, - this.track, - this.disc, - this.starred, - this.genre, - this.downloadTaskId, - this.downloadFilePath, - this.isDeleted = false}); - - @override - final int sourceId; - @override - final String id; - @override - final String? albumId; - @override - final String? artistId; - @override - final String title; - @override - final String? artist; - @override - final String? album; - @override - final Duration? duration; - @override - final int? track; - @override - final int? disc; - @override - final DateTime? starred; - @override - final String? genre; - @override - final String? downloadTaskId; - @override - final String? downloadFilePath; - @override - @JsonKey() - final bool isDeleted; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'Song(sourceId: $sourceId, id: $id, albumId: $albumId, artistId: $artistId, title: $title, artist: $artist, album: $album, duration: $duration, track: $track, disc: $disc, starred: $starred, genre: $genre, downloadTaskId: $downloadTaskId, downloadFilePath: $downloadFilePath, isDeleted: $isDeleted)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'Song')) - ..add(DiagnosticsProperty('sourceId', sourceId)) - ..add(DiagnosticsProperty('id', id)) - ..add(DiagnosticsProperty('albumId', albumId)) - ..add(DiagnosticsProperty('artistId', artistId)) - ..add(DiagnosticsProperty('title', title)) - ..add(DiagnosticsProperty('artist', artist)) - ..add(DiagnosticsProperty('album', album)) - ..add(DiagnosticsProperty('duration', duration)) - ..add(DiagnosticsProperty('track', track)) - ..add(DiagnosticsProperty('disc', disc)) - ..add(DiagnosticsProperty('starred', starred)) - ..add(DiagnosticsProperty('genre', genre)) - ..add(DiagnosticsProperty('downloadTaskId', downloadTaskId)) - ..add(DiagnosticsProperty('downloadFilePath', downloadFilePath)) - ..add(DiagnosticsProperty('isDeleted', isDeleted)); - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_Song && - (identical(other.sourceId, sourceId) || - other.sourceId == sourceId) && - (identical(other.id, id) || other.id == id) && - (identical(other.albumId, albumId) || other.albumId == albumId) && - (identical(other.artistId, artistId) || - other.artistId == artistId) && - (identical(other.title, title) || other.title == title) && - (identical(other.artist, artist) || other.artist == artist) && - (identical(other.album, album) || other.album == album) && - (identical(other.duration, duration) || - other.duration == duration) && - (identical(other.track, track) || other.track == track) && - (identical(other.disc, disc) || other.disc == disc) && - (identical(other.starred, starred) || other.starred == starred) && - (identical(other.genre, genre) || other.genre == genre) && - (identical(other.downloadTaskId, downloadTaskId) || - other.downloadTaskId == downloadTaskId) && - (identical(other.downloadFilePath, downloadFilePath) || - other.downloadFilePath == downloadFilePath) && - (identical(other.isDeleted, isDeleted) || - other.isDeleted == isDeleted)); - } - - @override - int get hashCode => Object.hash( - runtimeType, - sourceId, - id, - albumId, - artistId, - title, - artist, - album, - duration, - track, - disc, - starred, - genre, - downloadTaskId, - downloadFilePath, - isDeleted); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_SongCopyWith<_$_Song> get copyWith => - __$$_SongCopyWithImpl<_$_Song>(this, _$identity); -} - -abstract class _Song implements Song { - const factory _Song( - {required final int sourceId, - required final String id, - final String? albumId, - final String? artistId, - required final String title, - final String? artist, - final String? album, - final Duration? duration, - final int? track, - final int? disc, - final DateTime? starred, - final String? genre, - final String? downloadTaskId, - final String? downloadFilePath, - final bool isDeleted}) = _$_Song; - - @override - int get sourceId; - @override - String get id; - @override - String? get albumId; - @override - String? get artistId; - @override - String get title; - @override - String? get artist; - @override - String? get album; - @override - Duration? get duration; - @override - int? get track; - @override - int? get disc; - @override - DateTime? get starred; - @override - String? get genre; - @override - String? get downloadTaskId; - @override - String? get downloadFilePath; - @override - bool get isDeleted; - @override - @JsonKey(ignore: true) - _$$_SongCopyWith<_$_Song> get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$SearchResults { - String? get query => throw _privateConstructorUsedError; - IList get songs => throw _privateConstructorUsedError; - IList get albums => throw _privateConstructorUsedError; - IList get artists => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $SearchResultsCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $SearchResultsCopyWith<$Res> { - factory $SearchResultsCopyWith( - SearchResults value, $Res Function(SearchResults) then) = - _$SearchResultsCopyWithImpl<$Res, SearchResults>; - @useResult - $Res call( - {String? query, - IList songs, - IList albums, - IList artists}); -} - -/// @nodoc -class _$SearchResultsCopyWithImpl<$Res, $Val extends SearchResults> - implements $SearchResultsCopyWith<$Res> { - _$SearchResultsCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? query = freezed, - Object? songs = null, - Object? albums = null, - Object? artists = null, - }) { - return _then(_value.copyWith( - query: freezed == query - ? _value.query - : query // ignore: cast_nullable_to_non_nullable - as String?, - songs: null == songs - ? _value.songs - : songs // ignore: cast_nullable_to_non_nullable - as IList, - albums: null == albums - ? _value.albums - : albums // ignore: cast_nullable_to_non_nullable - as IList, - artists: null == artists - ? _value.artists - : artists // ignore: cast_nullable_to_non_nullable - as IList, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_SearchResultsCopyWith<$Res> - implements $SearchResultsCopyWith<$Res> { - factory _$$_SearchResultsCopyWith( - _$_SearchResults value, $Res Function(_$_SearchResults) then) = - __$$_SearchResultsCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {String? query, - IList songs, - IList albums, - IList artists}); -} - -/// @nodoc -class __$$_SearchResultsCopyWithImpl<$Res> - extends _$SearchResultsCopyWithImpl<$Res, _$_SearchResults> - implements _$$_SearchResultsCopyWith<$Res> { - __$$_SearchResultsCopyWithImpl( - _$_SearchResults _value, $Res Function(_$_SearchResults) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? query = freezed, - Object? songs = null, - Object? albums = null, - Object? artists = null, - }) { - return _then(_$_SearchResults( - query: freezed == query - ? _value.query - : query // ignore: cast_nullable_to_non_nullable - as String?, - songs: null == songs - ? _value.songs - : songs // ignore: cast_nullable_to_non_nullable - as IList, - albums: null == albums - ? _value.albums - : albums // ignore: cast_nullable_to_non_nullable - as IList, - artists: null == artists - ? _value.artists - : artists // ignore: cast_nullable_to_non_nullable - as IList, - )); - } -} - -/// @nodoc - -class _$_SearchResults with DiagnosticableTreeMixin implements _SearchResults { - const _$_SearchResults( - {this.query, - this.songs = const IListConst([]), - this.albums = const IListConst([]), - this.artists = const IListConst([])}); - - @override - final String? query; - @override - @JsonKey() - final IList songs; - @override - @JsonKey() - final IList albums; - @override - @JsonKey() - final IList artists; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'SearchResults(query: $query, songs: $songs, albums: $albums, artists: $artists)'; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('type', 'SearchResults')) - ..add(DiagnosticsProperty('query', query)) - ..add(DiagnosticsProperty('songs', songs)) - ..add(DiagnosticsProperty('albums', albums)) - ..add(DiagnosticsProperty('artists', artists)); - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_SearchResults && - (identical(other.query, query) || other.query == query) && - const DeepCollectionEquality().equals(other.songs, songs) && - const DeepCollectionEquality().equals(other.albums, albums) && - const DeepCollectionEquality().equals(other.artists, artists)); - } - - @override - int get hashCode => Object.hash( - runtimeType, - query, - const DeepCollectionEquality().hash(songs), - const DeepCollectionEquality().hash(albums), - const DeepCollectionEquality().hash(artists)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_SearchResultsCopyWith<_$_SearchResults> get copyWith => - __$$_SearchResultsCopyWithImpl<_$_SearchResults>(this, _$identity); -} - -abstract class _SearchResults implements SearchResults { - const factory _SearchResults( - {final String? query, - final IList songs, - final IList albums, - final IList artists}) = _$_SearchResults; - - @override - String? get query; - @override - IList get songs; - @override - IList get albums; - @override - IList get artists; - @override - @JsonKey(ignore: true) - _$$_SearchResultsCopyWith<_$_SearchResults> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/models/query.dart b/lib/models/query.dart deleted file mode 100644 index e2112857..00000000 --- a/lib/models/query.dart +++ /dev/null @@ -1,97 +0,0 @@ -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'query.freezed.dart'; -part 'query.g.dart'; - -enum SortDirection { - asc('ASC'), - desc('DESC'); - - const SortDirection(this.value); - final String value; -} - -@freezed -class Pagination with _$Pagination { - const factory Pagination({ - required int limit, - @Default(0) int offset, - }) = _Pagination; - - factory Pagination.fromJson(Map json) => - _$PaginationFromJson(json); -} - -@freezed -class SortBy with _$SortBy { - const factory SortBy({ - required String column, - @Default(SortDirection.asc) SortDirection dir, - }) = _SortBy; - - factory SortBy.fromJson(Map json) => _$SortByFromJson(json); -} - -@freezed -class FilterWith with _$FilterWith { - const factory FilterWith.equals({ - required String column, - required String value, - @Default(false) bool invert, - }) = _FilterWithEquals; - - const factory FilterWith.greaterThan({ - required String column, - required String value, - @Default(false) bool orEquals, - }) = _FilterWithGreaterThan; - - const factory FilterWith.isNull({ - required String column, - @Default(false) bool invert, - }) = _FilterWithIsNull; - - const factory FilterWith.betweenInt({ - required String column, - required int from, - required int to, - }) = _FilterWithBetweenInt; - - const factory FilterWith.isIn({ - required String column, - @Default(false) bool invert, - @Default(IListConst([])) IList values, - }) = _FilterWithIsIn; - - factory FilterWith.fromJson(Map json) => - _$FilterWithFromJson(json); -} - -@freezed -class ListQuery with _$ListQuery { - const factory ListQuery({ - @Default(Pagination(limit: -1, offset: 0)) Pagination page, - SortBy? sort, - @Default(IListConst([])) IList filters, - }) = _ListQuery; - - factory ListQuery.fromJson(Map json) => - _$ListQueryFromJson(json); -} - -@freezed -class ListQueryOptions with _$ListQueryOptions { - const factory ListQueryOptions({ - required IList sortColumns, - required IList filterColumns, - }) = _ListQueryOptions; -} - -@freezed -class LibraryListQuery with _$LibraryListQuery { - const factory LibraryListQuery({ - required ListQueryOptions options, - required ListQuery query, - }) = _LibraryListQuery; -} diff --git a/lib/models/query.freezed.dart b/lib/models/query.freezed.dart deleted file mode 100644 index 5700e4b8..00000000 --- a/lib/models/query.freezed.dart +++ /dev/null @@ -1,1934 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'query.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -Pagination _$PaginationFromJson(Map json) { - return _Pagination.fromJson(json); -} - -/// @nodoc -mixin _$Pagination { - int get limit => throw _privateConstructorUsedError; - int get offset => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $PaginationCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $PaginationCopyWith<$Res> { - factory $PaginationCopyWith( - Pagination value, $Res Function(Pagination) then) = - _$PaginationCopyWithImpl<$Res, Pagination>; - @useResult - $Res call({int limit, int offset}); -} - -/// @nodoc -class _$PaginationCopyWithImpl<$Res, $Val extends Pagination> - implements $PaginationCopyWith<$Res> { - _$PaginationCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? limit = null, - Object? offset = null, - }) { - return _then(_value.copyWith( - limit: null == limit - ? _value.limit - : limit // ignore: cast_nullable_to_non_nullable - as int, - offset: null == offset - ? _value.offset - : offset // ignore: cast_nullable_to_non_nullable - as int, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_PaginationCopyWith<$Res> - implements $PaginationCopyWith<$Res> { - factory _$$_PaginationCopyWith( - _$_Pagination value, $Res Function(_$_Pagination) then) = - __$$_PaginationCopyWithImpl<$Res>; - @override - @useResult - $Res call({int limit, int offset}); -} - -/// @nodoc -class __$$_PaginationCopyWithImpl<$Res> - extends _$PaginationCopyWithImpl<$Res, _$_Pagination> - implements _$$_PaginationCopyWith<$Res> { - __$$_PaginationCopyWithImpl( - _$_Pagination _value, $Res Function(_$_Pagination) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? limit = null, - Object? offset = null, - }) { - return _then(_$_Pagination( - limit: null == limit - ? _value.limit - : limit // ignore: cast_nullable_to_non_nullable - as int, - offset: null == offset - ? _value.offset - : offset // ignore: cast_nullable_to_non_nullable - as int, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$_Pagination implements _Pagination { - const _$_Pagination({required this.limit, this.offset = 0}); - - factory _$_Pagination.fromJson(Map json) => - _$$_PaginationFromJson(json); - - @override - final int limit; - @override - @JsonKey() - final int offset; - - @override - String toString() { - return 'Pagination(limit: $limit, offset: $offset)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_Pagination && - (identical(other.limit, limit) || other.limit == limit) && - (identical(other.offset, offset) || other.offset == offset)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash(runtimeType, limit, offset); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_PaginationCopyWith<_$_Pagination> get copyWith => - __$$_PaginationCopyWithImpl<_$_Pagination>(this, _$identity); - - @override - Map toJson() { - return _$$_PaginationToJson( - this, - ); - } -} - -abstract class _Pagination implements Pagination { - const factory _Pagination({required final int limit, final int offset}) = - _$_Pagination; - - factory _Pagination.fromJson(Map json) = - _$_Pagination.fromJson; - - @override - int get limit; - @override - int get offset; - @override - @JsonKey(ignore: true) - _$$_PaginationCopyWith<_$_Pagination> get copyWith => - throw _privateConstructorUsedError; -} - -SortBy _$SortByFromJson(Map json) { - return _SortBy.fromJson(json); -} - -/// @nodoc -mixin _$SortBy { - String get column => throw _privateConstructorUsedError; - SortDirection get dir => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $SortByCopyWith get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $SortByCopyWith<$Res> { - factory $SortByCopyWith(SortBy value, $Res Function(SortBy) then) = - _$SortByCopyWithImpl<$Res, SortBy>; - @useResult - $Res call({String column, SortDirection dir}); -} - -/// @nodoc -class _$SortByCopyWithImpl<$Res, $Val extends SortBy> - implements $SortByCopyWith<$Res> { - _$SortByCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? column = null, - Object? dir = null, - }) { - return _then(_value.copyWith( - column: null == column - ? _value.column - : column // ignore: cast_nullable_to_non_nullable - as String, - dir: null == dir - ? _value.dir - : dir // ignore: cast_nullable_to_non_nullable - as SortDirection, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_SortByCopyWith<$Res> implements $SortByCopyWith<$Res> { - factory _$$_SortByCopyWith(_$_SortBy value, $Res Function(_$_SortBy) then) = - __$$_SortByCopyWithImpl<$Res>; - @override - @useResult - $Res call({String column, SortDirection dir}); -} - -/// @nodoc -class __$$_SortByCopyWithImpl<$Res> - extends _$SortByCopyWithImpl<$Res, _$_SortBy> - implements _$$_SortByCopyWith<$Res> { - __$$_SortByCopyWithImpl(_$_SortBy _value, $Res Function(_$_SortBy) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? column = null, - Object? dir = null, - }) { - return _then(_$_SortBy( - column: null == column - ? _value.column - : column // ignore: cast_nullable_to_non_nullable - as String, - dir: null == dir - ? _value.dir - : dir // ignore: cast_nullable_to_non_nullable - as SortDirection, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$_SortBy implements _SortBy { - const _$_SortBy({required this.column, this.dir = SortDirection.asc}); - - factory _$_SortBy.fromJson(Map json) => - _$$_SortByFromJson(json); - - @override - final String column; - @override - @JsonKey() - final SortDirection dir; - - @override - String toString() { - return 'SortBy(column: $column, dir: $dir)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_SortBy && - (identical(other.column, column) || other.column == column) && - (identical(other.dir, dir) || other.dir == dir)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash(runtimeType, column, dir); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_SortByCopyWith<_$_SortBy> get copyWith => - __$$_SortByCopyWithImpl<_$_SortBy>(this, _$identity); - - @override - Map toJson() { - return _$$_SortByToJson( - this, - ); - } -} - -abstract class _SortBy implements SortBy { - const factory _SortBy( - {required final String column, final SortDirection dir}) = _$_SortBy; - - factory _SortBy.fromJson(Map json) = _$_SortBy.fromJson; - - @override - String get column; - @override - SortDirection get dir; - @override - @JsonKey(ignore: true) - _$$_SortByCopyWith<_$_SortBy> get copyWith => - throw _privateConstructorUsedError; -} - -FilterWith _$FilterWithFromJson(Map json) { - switch (json['runtimeType']) { - case 'equals': - return _FilterWithEquals.fromJson(json); - case 'greaterThan': - return _FilterWithGreaterThan.fromJson(json); - case 'isNull': - return _FilterWithIsNull.fromJson(json); - case 'betweenInt': - return _FilterWithBetweenInt.fromJson(json); - case 'isIn': - return _FilterWithIsIn.fromJson(json); - - default: - throw CheckedFromJsonException(json, 'runtimeType', 'FilterWith', - 'Invalid union type "${json['runtimeType']}"!'); - } -} - -/// @nodoc -mixin _$FilterWith { - String get column => throw _privateConstructorUsedError; - @optionalTypeArgs - TResult when({ - required TResult Function(String column, String value, bool invert) equals, - required TResult Function(String column, String value, bool orEquals) - greaterThan, - required TResult Function(String column, bool invert) isNull, - required TResult Function(String column, int from, int to) betweenInt, - required TResult Function(String column, bool invert, IList values) - isIn, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(String column, String value, bool invert)? equals, - TResult? Function(String column, String value, bool orEquals)? greaterThan, - TResult? Function(String column, bool invert)? isNull, - TResult? Function(String column, int from, int to)? betweenInt, - TResult? Function(String column, bool invert, IList values)? isIn, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(String column, String value, bool invert)? equals, - TResult Function(String column, String value, bool orEquals)? greaterThan, - TResult Function(String column, bool invert)? isNull, - TResult Function(String column, int from, int to)? betweenInt, - TResult Function(String column, bool invert, IList values)? isIn, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map({ - required TResult Function(_FilterWithEquals value) equals, - required TResult Function(_FilterWithGreaterThan value) greaterThan, - required TResult Function(_FilterWithIsNull value) isNull, - required TResult Function(_FilterWithBetweenInt value) betweenInt, - required TResult Function(_FilterWithIsIn value) isIn, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(_FilterWithEquals value)? equals, - TResult? Function(_FilterWithGreaterThan value)? greaterThan, - TResult? Function(_FilterWithIsNull value)? isNull, - TResult? Function(_FilterWithBetweenInt value)? betweenInt, - TResult? Function(_FilterWithIsIn value)? isIn, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_FilterWithEquals value)? equals, - TResult Function(_FilterWithGreaterThan value)? greaterThan, - TResult Function(_FilterWithIsNull value)? isNull, - TResult Function(_FilterWithBetweenInt value)? betweenInt, - TResult Function(_FilterWithIsIn value)? isIn, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $FilterWithCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $FilterWithCopyWith<$Res> { - factory $FilterWithCopyWith( - FilterWith value, $Res Function(FilterWith) then) = - _$FilterWithCopyWithImpl<$Res, FilterWith>; - @useResult - $Res call({String column}); -} - -/// @nodoc -class _$FilterWithCopyWithImpl<$Res, $Val extends FilterWith> - implements $FilterWithCopyWith<$Res> { - _$FilterWithCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? column = null, - }) { - return _then(_value.copyWith( - column: null == column - ? _value.column - : column // ignore: cast_nullable_to_non_nullable - as String, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_FilterWithEqualsCopyWith<$Res> - implements $FilterWithCopyWith<$Res> { - factory _$$_FilterWithEqualsCopyWith( - _$_FilterWithEquals value, $Res Function(_$_FilterWithEquals) then) = - __$$_FilterWithEqualsCopyWithImpl<$Res>; - @override - @useResult - $Res call({String column, String value, bool invert}); -} - -/// @nodoc -class __$$_FilterWithEqualsCopyWithImpl<$Res> - extends _$FilterWithCopyWithImpl<$Res, _$_FilterWithEquals> - implements _$$_FilterWithEqualsCopyWith<$Res> { - __$$_FilterWithEqualsCopyWithImpl( - _$_FilterWithEquals _value, $Res Function(_$_FilterWithEquals) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? column = null, - Object? value = null, - Object? invert = null, - }) { - return _then(_$_FilterWithEquals( - column: null == column - ? _value.column - : column // ignore: cast_nullable_to_non_nullable - as String, - value: null == value - ? _value.value - : value // ignore: cast_nullable_to_non_nullable - as String, - invert: null == invert - ? _value.invert - : invert // ignore: cast_nullable_to_non_nullable - as bool, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$_FilterWithEquals implements _FilterWithEquals { - const _$_FilterWithEquals( - {required this.column, - required this.value, - this.invert = false, - final String? $type}) - : $type = $type ?? 'equals'; - - factory _$_FilterWithEquals.fromJson(Map json) => - _$$_FilterWithEqualsFromJson(json); - - @override - final String column; - @override - final String value; - @override - @JsonKey() - final bool invert; - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'FilterWith.equals(column: $column, value: $value, invert: $invert)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_FilterWithEquals && - (identical(other.column, column) || other.column == column) && - (identical(other.value, value) || other.value == value) && - (identical(other.invert, invert) || other.invert == invert)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash(runtimeType, column, value, invert); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_FilterWithEqualsCopyWith<_$_FilterWithEquals> get copyWith => - __$$_FilterWithEqualsCopyWithImpl<_$_FilterWithEquals>(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(String column, String value, bool invert) equals, - required TResult Function(String column, String value, bool orEquals) - greaterThan, - required TResult Function(String column, bool invert) isNull, - required TResult Function(String column, int from, int to) betweenInt, - required TResult Function(String column, bool invert, IList values) - isIn, - }) { - return equals(column, value, invert); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(String column, String value, bool invert)? equals, - TResult? Function(String column, String value, bool orEquals)? greaterThan, - TResult? Function(String column, bool invert)? isNull, - TResult? Function(String column, int from, int to)? betweenInt, - TResult? Function(String column, bool invert, IList values)? isIn, - }) { - return equals?.call(column, value, invert); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(String column, String value, bool invert)? equals, - TResult Function(String column, String value, bool orEquals)? greaterThan, - TResult Function(String column, bool invert)? isNull, - TResult Function(String column, int from, int to)? betweenInt, - TResult Function(String column, bool invert, IList values)? isIn, - required TResult orElse(), - }) { - if (equals != null) { - return equals(column, value, invert); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_FilterWithEquals value) equals, - required TResult Function(_FilterWithGreaterThan value) greaterThan, - required TResult Function(_FilterWithIsNull value) isNull, - required TResult Function(_FilterWithBetweenInt value) betweenInt, - required TResult Function(_FilterWithIsIn value) isIn, - }) { - return equals(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(_FilterWithEquals value)? equals, - TResult? Function(_FilterWithGreaterThan value)? greaterThan, - TResult? Function(_FilterWithIsNull value)? isNull, - TResult? Function(_FilterWithBetweenInt value)? betweenInt, - TResult? Function(_FilterWithIsIn value)? isIn, - }) { - return equals?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_FilterWithEquals value)? equals, - TResult Function(_FilterWithGreaterThan value)? greaterThan, - TResult Function(_FilterWithIsNull value)? isNull, - TResult Function(_FilterWithBetweenInt value)? betweenInt, - TResult Function(_FilterWithIsIn value)? isIn, - required TResult orElse(), - }) { - if (equals != null) { - return equals(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$_FilterWithEqualsToJson( - this, - ); - } -} - -abstract class _FilterWithEquals implements FilterWith { - const factory _FilterWithEquals( - {required final String column, - required final String value, - final bool invert}) = _$_FilterWithEquals; - - factory _FilterWithEquals.fromJson(Map json) = - _$_FilterWithEquals.fromJson; - - @override - String get column; - String get value; - bool get invert; - @override - @JsonKey(ignore: true) - _$$_FilterWithEqualsCopyWith<_$_FilterWithEquals> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$_FilterWithGreaterThanCopyWith<$Res> - implements $FilterWithCopyWith<$Res> { - factory _$$_FilterWithGreaterThanCopyWith(_$_FilterWithGreaterThan value, - $Res Function(_$_FilterWithGreaterThan) then) = - __$$_FilterWithGreaterThanCopyWithImpl<$Res>; - @override - @useResult - $Res call({String column, String value, bool orEquals}); -} - -/// @nodoc -class __$$_FilterWithGreaterThanCopyWithImpl<$Res> - extends _$FilterWithCopyWithImpl<$Res, _$_FilterWithGreaterThan> - implements _$$_FilterWithGreaterThanCopyWith<$Res> { - __$$_FilterWithGreaterThanCopyWithImpl(_$_FilterWithGreaterThan _value, - $Res Function(_$_FilterWithGreaterThan) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? column = null, - Object? value = null, - Object? orEquals = null, - }) { - return _then(_$_FilterWithGreaterThan( - column: null == column - ? _value.column - : column // ignore: cast_nullable_to_non_nullable - as String, - value: null == value - ? _value.value - : value // ignore: cast_nullable_to_non_nullable - as String, - orEquals: null == orEquals - ? _value.orEquals - : orEquals // ignore: cast_nullable_to_non_nullable - as bool, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$_FilterWithGreaterThan implements _FilterWithGreaterThan { - const _$_FilterWithGreaterThan( - {required this.column, - required this.value, - this.orEquals = false, - final String? $type}) - : $type = $type ?? 'greaterThan'; - - factory _$_FilterWithGreaterThan.fromJson(Map json) => - _$$_FilterWithGreaterThanFromJson(json); - - @override - final String column; - @override - final String value; - @override - @JsonKey() - final bool orEquals; - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'FilterWith.greaterThan(column: $column, value: $value, orEquals: $orEquals)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_FilterWithGreaterThan && - (identical(other.column, column) || other.column == column) && - (identical(other.value, value) || other.value == value) && - (identical(other.orEquals, orEquals) || - other.orEquals == orEquals)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash(runtimeType, column, value, orEquals); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_FilterWithGreaterThanCopyWith<_$_FilterWithGreaterThan> get copyWith => - __$$_FilterWithGreaterThanCopyWithImpl<_$_FilterWithGreaterThan>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(String column, String value, bool invert) equals, - required TResult Function(String column, String value, bool orEquals) - greaterThan, - required TResult Function(String column, bool invert) isNull, - required TResult Function(String column, int from, int to) betweenInt, - required TResult Function(String column, bool invert, IList values) - isIn, - }) { - return greaterThan(column, value, orEquals); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(String column, String value, bool invert)? equals, - TResult? Function(String column, String value, bool orEquals)? greaterThan, - TResult? Function(String column, bool invert)? isNull, - TResult? Function(String column, int from, int to)? betweenInt, - TResult? Function(String column, bool invert, IList values)? isIn, - }) { - return greaterThan?.call(column, value, orEquals); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(String column, String value, bool invert)? equals, - TResult Function(String column, String value, bool orEquals)? greaterThan, - TResult Function(String column, bool invert)? isNull, - TResult Function(String column, int from, int to)? betweenInt, - TResult Function(String column, bool invert, IList values)? isIn, - required TResult orElse(), - }) { - if (greaterThan != null) { - return greaterThan(column, value, orEquals); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_FilterWithEquals value) equals, - required TResult Function(_FilterWithGreaterThan value) greaterThan, - required TResult Function(_FilterWithIsNull value) isNull, - required TResult Function(_FilterWithBetweenInt value) betweenInt, - required TResult Function(_FilterWithIsIn value) isIn, - }) { - return greaterThan(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(_FilterWithEquals value)? equals, - TResult? Function(_FilterWithGreaterThan value)? greaterThan, - TResult? Function(_FilterWithIsNull value)? isNull, - TResult? Function(_FilterWithBetweenInt value)? betweenInt, - TResult? Function(_FilterWithIsIn value)? isIn, - }) { - return greaterThan?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_FilterWithEquals value)? equals, - TResult Function(_FilterWithGreaterThan value)? greaterThan, - TResult Function(_FilterWithIsNull value)? isNull, - TResult Function(_FilterWithBetweenInt value)? betweenInt, - TResult Function(_FilterWithIsIn value)? isIn, - required TResult orElse(), - }) { - if (greaterThan != null) { - return greaterThan(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$_FilterWithGreaterThanToJson( - this, - ); - } -} - -abstract class _FilterWithGreaterThan implements FilterWith { - const factory _FilterWithGreaterThan( - {required final String column, - required final String value, - final bool orEquals}) = _$_FilterWithGreaterThan; - - factory _FilterWithGreaterThan.fromJson(Map json) = - _$_FilterWithGreaterThan.fromJson; - - @override - String get column; - String get value; - bool get orEquals; - @override - @JsonKey(ignore: true) - _$$_FilterWithGreaterThanCopyWith<_$_FilterWithGreaterThan> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$_FilterWithIsNullCopyWith<$Res> - implements $FilterWithCopyWith<$Res> { - factory _$$_FilterWithIsNullCopyWith( - _$_FilterWithIsNull value, $Res Function(_$_FilterWithIsNull) then) = - __$$_FilterWithIsNullCopyWithImpl<$Res>; - @override - @useResult - $Res call({String column, bool invert}); -} - -/// @nodoc -class __$$_FilterWithIsNullCopyWithImpl<$Res> - extends _$FilterWithCopyWithImpl<$Res, _$_FilterWithIsNull> - implements _$$_FilterWithIsNullCopyWith<$Res> { - __$$_FilterWithIsNullCopyWithImpl( - _$_FilterWithIsNull _value, $Res Function(_$_FilterWithIsNull) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? column = null, - Object? invert = null, - }) { - return _then(_$_FilterWithIsNull( - column: null == column - ? _value.column - : column // ignore: cast_nullable_to_non_nullable - as String, - invert: null == invert - ? _value.invert - : invert // ignore: cast_nullable_to_non_nullable - as bool, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$_FilterWithIsNull implements _FilterWithIsNull { - const _$_FilterWithIsNull( - {required this.column, this.invert = false, final String? $type}) - : $type = $type ?? 'isNull'; - - factory _$_FilterWithIsNull.fromJson(Map json) => - _$$_FilterWithIsNullFromJson(json); - - @override - final String column; - @override - @JsonKey() - final bool invert; - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'FilterWith.isNull(column: $column, invert: $invert)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_FilterWithIsNull && - (identical(other.column, column) || other.column == column) && - (identical(other.invert, invert) || other.invert == invert)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash(runtimeType, column, invert); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_FilterWithIsNullCopyWith<_$_FilterWithIsNull> get copyWith => - __$$_FilterWithIsNullCopyWithImpl<_$_FilterWithIsNull>(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(String column, String value, bool invert) equals, - required TResult Function(String column, String value, bool orEquals) - greaterThan, - required TResult Function(String column, bool invert) isNull, - required TResult Function(String column, int from, int to) betweenInt, - required TResult Function(String column, bool invert, IList values) - isIn, - }) { - return isNull(column, invert); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(String column, String value, bool invert)? equals, - TResult? Function(String column, String value, bool orEquals)? greaterThan, - TResult? Function(String column, bool invert)? isNull, - TResult? Function(String column, int from, int to)? betweenInt, - TResult? Function(String column, bool invert, IList values)? isIn, - }) { - return isNull?.call(column, invert); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(String column, String value, bool invert)? equals, - TResult Function(String column, String value, bool orEquals)? greaterThan, - TResult Function(String column, bool invert)? isNull, - TResult Function(String column, int from, int to)? betweenInt, - TResult Function(String column, bool invert, IList values)? isIn, - required TResult orElse(), - }) { - if (isNull != null) { - return isNull(column, invert); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_FilterWithEquals value) equals, - required TResult Function(_FilterWithGreaterThan value) greaterThan, - required TResult Function(_FilterWithIsNull value) isNull, - required TResult Function(_FilterWithBetweenInt value) betweenInt, - required TResult Function(_FilterWithIsIn value) isIn, - }) { - return isNull(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(_FilterWithEquals value)? equals, - TResult? Function(_FilterWithGreaterThan value)? greaterThan, - TResult? Function(_FilterWithIsNull value)? isNull, - TResult? Function(_FilterWithBetweenInt value)? betweenInt, - TResult? Function(_FilterWithIsIn value)? isIn, - }) { - return isNull?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_FilterWithEquals value)? equals, - TResult Function(_FilterWithGreaterThan value)? greaterThan, - TResult Function(_FilterWithIsNull value)? isNull, - TResult Function(_FilterWithBetweenInt value)? betweenInt, - TResult Function(_FilterWithIsIn value)? isIn, - required TResult orElse(), - }) { - if (isNull != null) { - return isNull(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$_FilterWithIsNullToJson( - this, - ); - } -} - -abstract class _FilterWithIsNull implements FilterWith { - const factory _FilterWithIsNull( - {required final String column, final bool invert}) = _$_FilterWithIsNull; - - factory _FilterWithIsNull.fromJson(Map json) = - _$_FilterWithIsNull.fromJson; - - @override - String get column; - bool get invert; - @override - @JsonKey(ignore: true) - _$$_FilterWithIsNullCopyWith<_$_FilterWithIsNull> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$_FilterWithBetweenIntCopyWith<$Res> - implements $FilterWithCopyWith<$Res> { - factory _$$_FilterWithBetweenIntCopyWith(_$_FilterWithBetweenInt value, - $Res Function(_$_FilterWithBetweenInt) then) = - __$$_FilterWithBetweenIntCopyWithImpl<$Res>; - @override - @useResult - $Res call({String column, int from, int to}); -} - -/// @nodoc -class __$$_FilterWithBetweenIntCopyWithImpl<$Res> - extends _$FilterWithCopyWithImpl<$Res, _$_FilterWithBetweenInt> - implements _$$_FilterWithBetweenIntCopyWith<$Res> { - __$$_FilterWithBetweenIntCopyWithImpl(_$_FilterWithBetweenInt _value, - $Res Function(_$_FilterWithBetweenInt) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? column = null, - Object? from = null, - Object? to = null, - }) { - return _then(_$_FilterWithBetweenInt( - column: null == column - ? _value.column - : column // ignore: cast_nullable_to_non_nullable - as String, - from: null == from - ? _value.from - : from // ignore: cast_nullable_to_non_nullable - as int, - to: null == to - ? _value.to - : to // ignore: cast_nullable_to_non_nullable - as int, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$_FilterWithBetweenInt implements _FilterWithBetweenInt { - const _$_FilterWithBetweenInt( - {required this.column, - required this.from, - required this.to, - final String? $type}) - : $type = $type ?? 'betweenInt'; - - factory _$_FilterWithBetweenInt.fromJson(Map json) => - _$$_FilterWithBetweenIntFromJson(json); - - @override - final String column; - @override - final int from; - @override - final int to; - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'FilterWith.betweenInt(column: $column, from: $from, to: $to)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_FilterWithBetweenInt && - (identical(other.column, column) || other.column == column) && - (identical(other.from, from) || other.from == from) && - (identical(other.to, to) || other.to == to)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash(runtimeType, column, from, to); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_FilterWithBetweenIntCopyWith<_$_FilterWithBetweenInt> get copyWith => - __$$_FilterWithBetweenIntCopyWithImpl<_$_FilterWithBetweenInt>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(String column, String value, bool invert) equals, - required TResult Function(String column, String value, bool orEquals) - greaterThan, - required TResult Function(String column, bool invert) isNull, - required TResult Function(String column, int from, int to) betweenInt, - required TResult Function(String column, bool invert, IList values) - isIn, - }) { - return betweenInt(column, from, to); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(String column, String value, bool invert)? equals, - TResult? Function(String column, String value, bool orEquals)? greaterThan, - TResult? Function(String column, bool invert)? isNull, - TResult? Function(String column, int from, int to)? betweenInt, - TResult? Function(String column, bool invert, IList values)? isIn, - }) { - return betweenInt?.call(column, from, to); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(String column, String value, bool invert)? equals, - TResult Function(String column, String value, bool orEquals)? greaterThan, - TResult Function(String column, bool invert)? isNull, - TResult Function(String column, int from, int to)? betweenInt, - TResult Function(String column, bool invert, IList values)? isIn, - required TResult orElse(), - }) { - if (betweenInt != null) { - return betweenInt(column, from, to); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_FilterWithEquals value) equals, - required TResult Function(_FilterWithGreaterThan value) greaterThan, - required TResult Function(_FilterWithIsNull value) isNull, - required TResult Function(_FilterWithBetweenInt value) betweenInt, - required TResult Function(_FilterWithIsIn value) isIn, - }) { - return betweenInt(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(_FilterWithEquals value)? equals, - TResult? Function(_FilterWithGreaterThan value)? greaterThan, - TResult? Function(_FilterWithIsNull value)? isNull, - TResult? Function(_FilterWithBetweenInt value)? betweenInt, - TResult? Function(_FilterWithIsIn value)? isIn, - }) { - return betweenInt?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_FilterWithEquals value)? equals, - TResult Function(_FilterWithGreaterThan value)? greaterThan, - TResult Function(_FilterWithIsNull value)? isNull, - TResult Function(_FilterWithBetweenInt value)? betweenInt, - TResult Function(_FilterWithIsIn value)? isIn, - required TResult orElse(), - }) { - if (betweenInt != null) { - return betweenInt(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$_FilterWithBetweenIntToJson( - this, - ); - } -} - -abstract class _FilterWithBetweenInt implements FilterWith { - const factory _FilterWithBetweenInt( - {required final String column, - required final int from, - required final int to}) = _$_FilterWithBetweenInt; - - factory _FilterWithBetweenInt.fromJson(Map json) = - _$_FilterWithBetweenInt.fromJson; - - @override - String get column; - int get from; - int get to; - @override - @JsonKey(ignore: true) - _$$_FilterWithBetweenIntCopyWith<_$_FilterWithBetweenInt> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$_FilterWithIsInCopyWith<$Res> - implements $FilterWithCopyWith<$Res> { - factory _$$_FilterWithIsInCopyWith( - _$_FilterWithIsIn value, $Res Function(_$_FilterWithIsIn) then) = - __$$_FilterWithIsInCopyWithImpl<$Res>; - @override - @useResult - $Res call({String column, bool invert, IList values}); -} - -/// @nodoc -class __$$_FilterWithIsInCopyWithImpl<$Res> - extends _$FilterWithCopyWithImpl<$Res, _$_FilterWithIsIn> - implements _$$_FilterWithIsInCopyWith<$Res> { - __$$_FilterWithIsInCopyWithImpl( - _$_FilterWithIsIn _value, $Res Function(_$_FilterWithIsIn) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? column = null, - Object? invert = null, - Object? values = null, - }) { - return _then(_$_FilterWithIsIn( - column: null == column - ? _value.column - : column // ignore: cast_nullable_to_non_nullable - as String, - invert: null == invert - ? _value.invert - : invert // ignore: cast_nullable_to_non_nullable - as bool, - values: null == values - ? _value.values - : values // ignore: cast_nullable_to_non_nullable - as IList, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$_FilterWithIsIn implements _FilterWithIsIn { - const _$_FilterWithIsIn( - {required this.column, - this.invert = false, - this.values = const IListConst([]), - final String? $type}) - : $type = $type ?? 'isIn'; - - factory _$_FilterWithIsIn.fromJson(Map json) => - _$$_FilterWithIsInFromJson(json); - - @override - final String column; - @override - @JsonKey() - final bool invert; - @override - @JsonKey() - final IList values; - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'FilterWith.isIn(column: $column, invert: $invert, values: $values)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_FilterWithIsIn && - (identical(other.column, column) || other.column == column) && - (identical(other.invert, invert) || other.invert == invert) && - const DeepCollectionEquality().equals(other.values, values)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, column, invert, const DeepCollectionEquality().hash(values)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_FilterWithIsInCopyWith<_$_FilterWithIsIn> get copyWith => - __$$_FilterWithIsInCopyWithImpl<_$_FilterWithIsIn>(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(String column, String value, bool invert) equals, - required TResult Function(String column, String value, bool orEquals) - greaterThan, - required TResult Function(String column, bool invert) isNull, - required TResult Function(String column, int from, int to) betweenInt, - required TResult Function(String column, bool invert, IList values) - isIn, - }) { - return isIn(column, invert, values); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(String column, String value, bool invert)? equals, - TResult? Function(String column, String value, bool orEquals)? greaterThan, - TResult? Function(String column, bool invert)? isNull, - TResult? Function(String column, int from, int to)? betweenInt, - TResult? Function(String column, bool invert, IList values)? isIn, - }) { - return isIn?.call(column, invert, values); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(String column, String value, bool invert)? equals, - TResult Function(String column, String value, bool orEquals)? greaterThan, - TResult Function(String column, bool invert)? isNull, - TResult Function(String column, int from, int to)? betweenInt, - TResult Function(String column, bool invert, IList values)? isIn, - required TResult orElse(), - }) { - if (isIn != null) { - return isIn(column, invert, values); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_FilterWithEquals value) equals, - required TResult Function(_FilterWithGreaterThan value) greaterThan, - required TResult Function(_FilterWithIsNull value) isNull, - required TResult Function(_FilterWithBetweenInt value) betweenInt, - required TResult Function(_FilterWithIsIn value) isIn, - }) { - return isIn(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(_FilterWithEquals value)? equals, - TResult? Function(_FilterWithGreaterThan value)? greaterThan, - TResult? Function(_FilterWithIsNull value)? isNull, - TResult? Function(_FilterWithBetweenInt value)? betweenInt, - TResult? Function(_FilterWithIsIn value)? isIn, - }) { - return isIn?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_FilterWithEquals value)? equals, - TResult Function(_FilterWithGreaterThan value)? greaterThan, - TResult Function(_FilterWithIsNull value)? isNull, - TResult Function(_FilterWithBetweenInt value)? betweenInt, - TResult Function(_FilterWithIsIn value)? isIn, - required TResult orElse(), - }) { - if (isIn != null) { - return isIn(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$_FilterWithIsInToJson( - this, - ); - } -} - -abstract class _FilterWithIsIn implements FilterWith { - const factory _FilterWithIsIn( - {required final String column, - final bool invert, - final IList values}) = _$_FilterWithIsIn; - - factory _FilterWithIsIn.fromJson(Map json) = - _$_FilterWithIsIn.fromJson; - - @override - String get column; - bool get invert; - IList get values; - @override - @JsonKey(ignore: true) - _$$_FilterWithIsInCopyWith<_$_FilterWithIsIn> get copyWith => - throw _privateConstructorUsedError; -} - -ListQuery _$ListQueryFromJson(Map json) { - return _ListQuery.fromJson(json); -} - -/// @nodoc -mixin _$ListQuery { - Pagination get page => throw _privateConstructorUsedError; - SortBy? get sort => throw _privateConstructorUsedError; - IList get filters => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $ListQueryCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $ListQueryCopyWith<$Res> { - factory $ListQueryCopyWith(ListQuery value, $Res Function(ListQuery) then) = - _$ListQueryCopyWithImpl<$Res, ListQuery>; - @useResult - $Res call({Pagination page, SortBy? sort, IList filters}); - - $PaginationCopyWith<$Res> get page; - $SortByCopyWith<$Res>? get sort; -} - -/// @nodoc -class _$ListQueryCopyWithImpl<$Res, $Val extends ListQuery> - implements $ListQueryCopyWith<$Res> { - _$ListQueryCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? page = null, - Object? sort = freezed, - Object? filters = null, - }) { - return _then(_value.copyWith( - page: null == page - ? _value.page - : page // ignore: cast_nullable_to_non_nullable - as Pagination, - sort: freezed == sort - ? _value.sort - : sort // ignore: cast_nullable_to_non_nullable - as SortBy?, - filters: null == filters - ? _value.filters - : filters // ignore: cast_nullable_to_non_nullable - as IList, - ) as $Val); - } - - @override - @pragma('vm:prefer-inline') - $PaginationCopyWith<$Res> get page { - return $PaginationCopyWith<$Res>(_value.page, (value) { - return _then(_value.copyWith(page: value) as $Val); - }); - } - - @override - @pragma('vm:prefer-inline') - $SortByCopyWith<$Res>? get sort { - if (_value.sort == null) { - return null; - } - - return $SortByCopyWith<$Res>(_value.sort!, (value) { - return _then(_value.copyWith(sort: value) as $Val); - }); - } -} - -/// @nodoc -abstract class _$$_ListQueryCopyWith<$Res> implements $ListQueryCopyWith<$Res> { - factory _$$_ListQueryCopyWith( - _$_ListQuery value, $Res Function(_$_ListQuery) then) = - __$$_ListQueryCopyWithImpl<$Res>; - @override - @useResult - $Res call({Pagination page, SortBy? sort, IList filters}); - - @override - $PaginationCopyWith<$Res> get page; - @override - $SortByCopyWith<$Res>? get sort; -} - -/// @nodoc -class __$$_ListQueryCopyWithImpl<$Res> - extends _$ListQueryCopyWithImpl<$Res, _$_ListQuery> - implements _$$_ListQueryCopyWith<$Res> { - __$$_ListQueryCopyWithImpl( - _$_ListQuery _value, $Res Function(_$_ListQuery) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? page = null, - Object? sort = freezed, - Object? filters = null, - }) { - return _then(_$_ListQuery( - page: null == page - ? _value.page - : page // ignore: cast_nullable_to_non_nullable - as Pagination, - sort: freezed == sort - ? _value.sort - : sort // ignore: cast_nullable_to_non_nullable - as SortBy?, - filters: null == filters - ? _value.filters - : filters // ignore: cast_nullable_to_non_nullable - as IList, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$_ListQuery implements _ListQuery { - const _$_ListQuery( - {this.page = const Pagination(limit: -1, offset: 0), - this.sort, - this.filters = const IListConst([])}); - - factory _$_ListQuery.fromJson(Map json) => - _$$_ListQueryFromJson(json); - - @override - @JsonKey() - final Pagination page; - @override - final SortBy? sort; - @override - @JsonKey() - final IList filters; - - @override - String toString() { - return 'ListQuery(page: $page, sort: $sort, filters: $filters)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_ListQuery && - (identical(other.page, page) || other.page == page) && - (identical(other.sort, sort) || other.sort == sort) && - const DeepCollectionEquality().equals(other.filters, filters)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, page, sort, const DeepCollectionEquality().hash(filters)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_ListQueryCopyWith<_$_ListQuery> get copyWith => - __$$_ListQueryCopyWithImpl<_$_ListQuery>(this, _$identity); - - @override - Map toJson() { - return _$$_ListQueryToJson( - this, - ); - } -} - -abstract class _ListQuery implements ListQuery { - const factory _ListQuery( - {final Pagination page, - final SortBy? sort, - final IList filters}) = _$_ListQuery; - - factory _ListQuery.fromJson(Map json) = - _$_ListQuery.fromJson; - - @override - Pagination get page; - @override - SortBy? get sort; - @override - IList get filters; - @override - @JsonKey(ignore: true) - _$$_ListQueryCopyWith<_$_ListQuery> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$ListQueryOptions { - IList get sortColumns => throw _privateConstructorUsedError; - IList get filterColumns => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $ListQueryOptionsCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $ListQueryOptionsCopyWith<$Res> { - factory $ListQueryOptionsCopyWith( - ListQueryOptions value, $Res Function(ListQueryOptions) then) = - _$ListQueryOptionsCopyWithImpl<$Res, ListQueryOptions>; - @useResult - $Res call({IList sortColumns, IList filterColumns}); -} - -/// @nodoc -class _$ListQueryOptionsCopyWithImpl<$Res, $Val extends ListQueryOptions> - implements $ListQueryOptionsCopyWith<$Res> { - _$ListQueryOptionsCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sortColumns = null, - Object? filterColumns = null, - }) { - return _then(_value.copyWith( - sortColumns: null == sortColumns - ? _value.sortColumns - : sortColumns // ignore: cast_nullable_to_non_nullable - as IList, - filterColumns: null == filterColumns - ? _value.filterColumns - : filterColumns // ignore: cast_nullable_to_non_nullable - as IList, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_ListQueryOptionsCopyWith<$Res> - implements $ListQueryOptionsCopyWith<$Res> { - factory _$$_ListQueryOptionsCopyWith( - _$_ListQueryOptions value, $Res Function(_$_ListQueryOptions) then) = - __$$_ListQueryOptionsCopyWithImpl<$Res>; - @override - @useResult - $Res call({IList sortColumns, IList filterColumns}); -} - -/// @nodoc -class __$$_ListQueryOptionsCopyWithImpl<$Res> - extends _$ListQueryOptionsCopyWithImpl<$Res, _$_ListQueryOptions> - implements _$$_ListQueryOptionsCopyWith<$Res> { - __$$_ListQueryOptionsCopyWithImpl( - _$_ListQueryOptions _value, $Res Function(_$_ListQueryOptions) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sortColumns = null, - Object? filterColumns = null, - }) { - return _then(_$_ListQueryOptions( - sortColumns: null == sortColumns - ? _value.sortColumns - : sortColumns // ignore: cast_nullable_to_non_nullable - as IList, - filterColumns: null == filterColumns - ? _value.filterColumns - : filterColumns // ignore: cast_nullable_to_non_nullable - as IList, - )); - } -} - -/// @nodoc - -class _$_ListQueryOptions implements _ListQueryOptions { - const _$_ListQueryOptions( - {required this.sortColumns, required this.filterColumns}); - - @override - final IList sortColumns; - @override - final IList filterColumns; - - @override - String toString() { - return 'ListQueryOptions(sortColumns: $sortColumns, filterColumns: $filterColumns)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_ListQueryOptions && - const DeepCollectionEquality() - .equals(other.sortColumns, sortColumns) && - const DeepCollectionEquality() - .equals(other.filterColumns, filterColumns)); - } - - @override - int get hashCode => Object.hash( - runtimeType, - const DeepCollectionEquality().hash(sortColumns), - const DeepCollectionEquality().hash(filterColumns)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_ListQueryOptionsCopyWith<_$_ListQueryOptions> get copyWith => - __$$_ListQueryOptionsCopyWithImpl<_$_ListQueryOptions>(this, _$identity); -} - -abstract class _ListQueryOptions implements ListQueryOptions { - const factory _ListQueryOptions( - {required final IList sortColumns, - required final IList filterColumns}) = _$_ListQueryOptions; - - @override - IList get sortColumns; - @override - IList get filterColumns; - @override - @JsonKey(ignore: true) - _$$_ListQueryOptionsCopyWith<_$_ListQueryOptions> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$LibraryListQuery { - ListQueryOptions get options => throw _privateConstructorUsedError; - ListQuery get query => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $LibraryListQueryCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $LibraryListQueryCopyWith<$Res> { - factory $LibraryListQueryCopyWith( - LibraryListQuery value, $Res Function(LibraryListQuery) then) = - _$LibraryListQueryCopyWithImpl<$Res, LibraryListQuery>; - @useResult - $Res call({ListQueryOptions options, ListQuery query}); - - $ListQueryOptionsCopyWith<$Res> get options; - $ListQueryCopyWith<$Res> get query; -} - -/// @nodoc -class _$LibraryListQueryCopyWithImpl<$Res, $Val extends LibraryListQuery> - implements $LibraryListQueryCopyWith<$Res> { - _$LibraryListQueryCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? options = null, - Object? query = null, - }) { - return _then(_value.copyWith( - options: null == options - ? _value.options - : options // ignore: cast_nullable_to_non_nullable - as ListQueryOptions, - query: null == query - ? _value.query - : query // ignore: cast_nullable_to_non_nullable - as ListQuery, - ) as $Val); - } - - @override - @pragma('vm:prefer-inline') - $ListQueryOptionsCopyWith<$Res> get options { - return $ListQueryOptionsCopyWith<$Res>(_value.options, (value) { - return _then(_value.copyWith(options: value) as $Val); - }); - } - - @override - @pragma('vm:prefer-inline') - $ListQueryCopyWith<$Res> get query { - return $ListQueryCopyWith<$Res>(_value.query, (value) { - return _then(_value.copyWith(query: value) as $Val); - }); - } -} - -/// @nodoc -abstract class _$$_LibraryListQueryCopyWith<$Res> - implements $LibraryListQueryCopyWith<$Res> { - factory _$$_LibraryListQueryCopyWith( - _$_LibraryListQuery value, $Res Function(_$_LibraryListQuery) then) = - __$$_LibraryListQueryCopyWithImpl<$Res>; - @override - @useResult - $Res call({ListQueryOptions options, ListQuery query}); - - @override - $ListQueryOptionsCopyWith<$Res> get options; - @override - $ListQueryCopyWith<$Res> get query; -} - -/// @nodoc -class __$$_LibraryListQueryCopyWithImpl<$Res> - extends _$LibraryListQueryCopyWithImpl<$Res, _$_LibraryListQuery> - implements _$$_LibraryListQueryCopyWith<$Res> { - __$$_LibraryListQueryCopyWithImpl( - _$_LibraryListQuery _value, $Res Function(_$_LibraryListQuery) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? options = null, - Object? query = null, - }) { - return _then(_$_LibraryListQuery( - options: null == options - ? _value.options - : options // ignore: cast_nullable_to_non_nullable - as ListQueryOptions, - query: null == query - ? _value.query - : query // ignore: cast_nullable_to_non_nullable - as ListQuery, - )); - } -} - -/// @nodoc - -class _$_LibraryListQuery implements _LibraryListQuery { - const _$_LibraryListQuery({required this.options, required this.query}); - - @override - final ListQueryOptions options; - @override - final ListQuery query; - - @override - String toString() { - return 'LibraryListQuery(options: $options, query: $query)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_LibraryListQuery && - (identical(other.options, options) || other.options == options) && - (identical(other.query, query) || other.query == query)); - } - - @override - int get hashCode => Object.hash(runtimeType, options, query); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_LibraryListQueryCopyWith<_$_LibraryListQuery> get copyWith => - __$$_LibraryListQueryCopyWithImpl<_$_LibraryListQuery>(this, _$identity); -} - -abstract class _LibraryListQuery implements LibraryListQuery { - const factory _LibraryListQuery( - {required final ListQueryOptions options, - required final ListQuery query}) = _$_LibraryListQuery; - - @override - ListQueryOptions get options; - @override - ListQuery get query; - @override - @JsonKey(ignore: true) - _$$_LibraryListQueryCopyWith<_$_LibraryListQuery> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/models/query.g.dart b/lib/models/query.g.dart deleted file mode 100644 index 1eed329b..00000000 --- a/lib/models/query.g.dart +++ /dev/null @@ -1,143 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'query.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -_$_Pagination _$$_PaginationFromJson(Map json) => - _$_Pagination( - limit: json['limit'] as int, - offset: json['offset'] as int? ?? 0, - ); - -Map _$$_PaginationToJson(_$_Pagination instance) => - { - 'limit': instance.limit, - 'offset': instance.offset, - }; - -_$_SortBy _$$_SortByFromJson(Map json) => _$_SortBy( - column: json['column'] as String, - dir: $enumDecodeNullable(_$SortDirectionEnumMap, json['dir']) ?? - SortDirection.asc, - ); - -Map _$$_SortByToJson(_$_SortBy instance) => { - 'column': instance.column, - 'dir': _$SortDirectionEnumMap[instance.dir]!, - }; - -const _$SortDirectionEnumMap = { - SortDirection.asc: 'asc', - SortDirection.desc: 'desc', -}; - -_$_FilterWithEquals _$$_FilterWithEqualsFromJson(Map json) => - _$_FilterWithEquals( - column: json['column'] as String, - value: json['value'] as String, - invert: json['invert'] as bool? ?? false, - $type: json['runtimeType'] as String?, - ); - -Map _$$_FilterWithEqualsToJson(_$_FilterWithEquals instance) => - { - 'column': instance.column, - 'value': instance.value, - 'invert': instance.invert, - 'runtimeType': instance.$type, - }; - -_$_FilterWithGreaterThan _$$_FilterWithGreaterThanFromJson( - Map json) => - _$_FilterWithGreaterThan( - column: json['column'] as String, - value: json['value'] as String, - orEquals: json['orEquals'] as bool? ?? false, - $type: json['runtimeType'] as String?, - ); - -Map _$$_FilterWithGreaterThanToJson( - _$_FilterWithGreaterThan instance) => - { - 'column': instance.column, - 'value': instance.value, - 'orEquals': instance.orEquals, - 'runtimeType': instance.$type, - }; - -_$_FilterWithIsNull _$$_FilterWithIsNullFromJson(Map json) => - _$_FilterWithIsNull( - column: json['column'] as String, - invert: json['invert'] as bool? ?? false, - $type: json['runtimeType'] as String?, - ); - -Map _$$_FilterWithIsNullToJson(_$_FilterWithIsNull instance) => - { - 'column': instance.column, - 'invert': instance.invert, - 'runtimeType': instance.$type, - }; - -_$_FilterWithBetweenInt _$$_FilterWithBetweenIntFromJson( - Map json) => - _$_FilterWithBetweenInt( - column: json['column'] as String, - from: json['from'] as int, - to: json['to'] as int, - $type: json['runtimeType'] as String?, - ); - -Map _$$_FilterWithBetweenIntToJson( - _$_FilterWithBetweenInt instance) => - { - 'column': instance.column, - 'from': instance.from, - 'to': instance.to, - 'runtimeType': instance.$type, - }; - -_$_FilterWithIsIn _$$_FilterWithIsInFromJson(Map json) => - _$_FilterWithIsIn( - column: json['column'] as String, - invert: json['invert'] as bool? ?? false, - values: json['values'] == null - ? const IListConst([]) - : IList.fromJson(json['values'], (value) => value as String), - $type: json['runtimeType'] as String?, - ); - -Map _$$_FilterWithIsInToJson(_$_FilterWithIsIn instance) => - { - 'column': instance.column, - 'invert': instance.invert, - 'values': instance.values.toJson( - (value) => value, - ), - 'runtimeType': instance.$type, - }; - -_$_ListQuery _$$_ListQueryFromJson(Map json) => _$_ListQuery( - page: json['page'] == null - ? const Pagination(limit: -1, offset: 0) - : Pagination.fromJson(json['page'] as Map), - sort: json['sort'] == null - ? null - : SortBy.fromJson(json['sort'] as Map), - filters: json['filters'] == null - ? const IListConst([]) - : IList.fromJson(json['filters'], - (value) => FilterWith.fromJson(value as Map)), - ); - -Map _$$_ListQueryToJson(_$_ListQuery instance) => - { - 'page': instance.page, - 'sort': instance.sort, - 'filters': instance.filters.toJson( - (value) => value, - ), - }; diff --git a/lib/models/settings.dart b/lib/models/settings.dart deleted file mode 100644 index f800df98..00000000 --- a/lib/models/settings.dart +++ /dev/null @@ -1,120 +0,0 @@ -import 'package:drift/drift.dart' show Value; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; - -import '../database/database.dart'; - -part 'settings.freezed.dart'; - -@freezed -class Settings with _$Settings { - const factory Settings({ - @Default(IListConst([])) IList sources, - SourceSettings? activeSource, - @Default(AppSettings()) AppSettings app, - }) = _Settings; -} - -@freezed -class AppSettings with _$AppSettings { - const AppSettings._(); - - const factory AppSettings({ - @Default(0) int maxBitrateWifi, - @Default(192) int maxBitrateMobile, - @Default('mp3') String? streamFormat, - }) = _AppSettings; - - AppSettingsCompanion toCompanion() { - return AppSettingsCompanion.insert( - id: const Value(1), - maxBitrateWifi: maxBitrateWifi, - maxBitrateMobile: maxBitrateMobile, - streamFormat: Value(streamFormat), - ); - } -} - -class ParentChild { - final T parent; - final T child; - - ParentChild(this.parent, this.child); -} - -abstract class SourceSettings { - const SourceSettings(); - - int get id; - String get name; - Uri get address; - bool? get isActive; - DateTime get createdAt; -} - -enum SubsonicFeature { - emptyQuerySearch('emptyQuerySearch'); - - const SubsonicFeature(this.value); - final String value; - - @override - String toString() => value; -} - -@freezed -class SubsonicSettings with _$SubsonicSettings implements SourceSettings { - const SubsonicSettings._(); - - const factory SubsonicSettings({ - required int id, - @Default(IListConst([])) IList features, - required String name, - required Uri address, - required bool? isActive, - required DateTime createdAt, - required String username, - required String password, - @Default(true) bool useTokenAuth, - }) = _SubsonicSettings; - - SourcesCompanion toSourceInsertable() { - return SourcesCompanion( - id: Value(id), - name: Value(name), - address: Value(address), - createdAt: Value(createdAt), - ); - } - - SubsonicSourcesCompanion toSubsonicInsertable() { - return SubsonicSourcesCompanion( - sourceId: Value(id), - features: Value(features), - username: Value(username), - password: Value(password), - useTokenAuth: Value(useTokenAuth), - ); - } -} - -@freezed -class SubsonicSourceSettings with _$SubsonicSourceSettings { - const SubsonicSourceSettings._(); - - const factory SubsonicSourceSettings({ - required SourceSettings source, - required SubsonicSettings subsonic, - }) = _SubsonicSourceSettings; -} - -enum NetworkMode { - mobile('mobile'), - wifi('wifi'); - - const NetworkMode(this.value); - final String value; - - @override - String toString() => value; -} diff --git a/lib/models/settings.freezed.dart b/lib/models/settings.freezed.dart deleted file mode 100644 index 833cc1b4..00000000 --- a/lib/models/settings.freezed.dart +++ /dev/null @@ -1,810 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'settings.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -/// @nodoc -mixin _$Settings { - IList get sources => throw _privateConstructorUsedError; - SourceSettings? get activeSource => throw _privateConstructorUsedError; - AppSettings get app => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $SettingsCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $SettingsCopyWith<$Res> { - factory $SettingsCopyWith(Settings value, $Res Function(Settings) then) = - _$SettingsCopyWithImpl<$Res, Settings>; - @useResult - $Res call( - {IList sources, - SourceSettings? activeSource, - AppSettings app}); - - $AppSettingsCopyWith<$Res> get app; -} - -/// @nodoc -class _$SettingsCopyWithImpl<$Res, $Val extends Settings> - implements $SettingsCopyWith<$Res> { - _$SettingsCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sources = null, - Object? activeSource = freezed, - Object? app = null, - }) { - return _then(_value.copyWith( - sources: null == sources - ? _value.sources - : sources // ignore: cast_nullable_to_non_nullable - as IList, - activeSource: freezed == activeSource - ? _value.activeSource - : activeSource // ignore: cast_nullable_to_non_nullable - as SourceSettings?, - app: null == app - ? _value.app - : app // ignore: cast_nullable_to_non_nullable - as AppSettings, - ) as $Val); - } - - @override - @pragma('vm:prefer-inline') - $AppSettingsCopyWith<$Res> get app { - return $AppSettingsCopyWith<$Res>(_value.app, (value) { - return _then(_value.copyWith(app: value) as $Val); - }); - } -} - -/// @nodoc -abstract class _$$_SettingsCopyWith<$Res> implements $SettingsCopyWith<$Res> { - factory _$$_SettingsCopyWith( - _$_Settings value, $Res Function(_$_Settings) then) = - __$$_SettingsCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {IList sources, - SourceSettings? activeSource, - AppSettings app}); - - @override - $AppSettingsCopyWith<$Res> get app; -} - -/// @nodoc -class __$$_SettingsCopyWithImpl<$Res> - extends _$SettingsCopyWithImpl<$Res, _$_Settings> - implements _$$_SettingsCopyWith<$Res> { - __$$_SettingsCopyWithImpl( - _$_Settings _value, $Res Function(_$_Settings) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sources = null, - Object? activeSource = freezed, - Object? app = null, - }) { - return _then(_$_Settings( - sources: null == sources - ? _value.sources - : sources // ignore: cast_nullable_to_non_nullable - as IList, - activeSource: freezed == activeSource - ? _value.activeSource - : activeSource // ignore: cast_nullable_to_non_nullable - as SourceSettings?, - app: null == app - ? _value.app - : app // ignore: cast_nullable_to_non_nullable - as AppSettings, - )); - } -} - -/// @nodoc - -class _$_Settings implements _Settings { - const _$_Settings( - {this.sources = const IListConst([]), - this.activeSource, - this.app = const AppSettings()}); - - @override - @JsonKey() - final IList sources; - @override - final SourceSettings? activeSource; - @override - @JsonKey() - final AppSettings app; - - @override - String toString() { - return 'Settings(sources: $sources, activeSource: $activeSource, app: $app)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_Settings && - const DeepCollectionEquality().equals(other.sources, sources) && - (identical(other.activeSource, activeSource) || - other.activeSource == activeSource) && - (identical(other.app, app) || other.app == app)); - } - - @override - int get hashCode => Object.hash(runtimeType, - const DeepCollectionEquality().hash(sources), activeSource, app); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_SettingsCopyWith<_$_Settings> get copyWith => - __$$_SettingsCopyWithImpl<_$_Settings>(this, _$identity); -} - -abstract class _Settings implements Settings { - const factory _Settings( - {final IList sources, - final SourceSettings? activeSource, - final AppSettings app}) = _$_Settings; - - @override - IList get sources; - @override - SourceSettings? get activeSource; - @override - AppSettings get app; - @override - @JsonKey(ignore: true) - _$$_SettingsCopyWith<_$_Settings> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$AppSettings { - int get maxBitrateWifi => throw _privateConstructorUsedError; - int get maxBitrateMobile => throw _privateConstructorUsedError; - String? get streamFormat => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $AppSettingsCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $AppSettingsCopyWith<$Res> { - factory $AppSettingsCopyWith( - AppSettings value, $Res Function(AppSettings) then) = - _$AppSettingsCopyWithImpl<$Res, AppSettings>; - @useResult - $Res call({int maxBitrateWifi, int maxBitrateMobile, String? streamFormat}); -} - -/// @nodoc -class _$AppSettingsCopyWithImpl<$Res, $Val extends AppSettings> - implements $AppSettingsCopyWith<$Res> { - _$AppSettingsCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? maxBitrateWifi = null, - Object? maxBitrateMobile = null, - Object? streamFormat = freezed, - }) { - return _then(_value.copyWith( - maxBitrateWifi: null == maxBitrateWifi - ? _value.maxBitrateWifi - : maxBitrateWifi // ignore: cast_nullable_to_non_nullable - as int, - maxBitrateMobile: null == maxBitrateMobile - ? _value.maxBitrateMobile - : maxBitrateMobile // ignore: cast_nullable_to_non_nullable - as int, - streamFormat: freezed == streamFormat - ? _value.streamFormat - : streamFormat // ignore: cast_nullable_to_non_nullable - as String?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_AppSettingsCopyWith<$Res> - implements $AppSettingsCopyWith<$Res> { - factory _$$_AppSettingsCopyWith( - _$_AppSettings value, $Res Function(_$_AppSettings) then) = - __$$_AppSettingsCopyWithImpl<$Res>; - @override - @useResult - $Res call({int maxBitrateWifi, int maxBitrateMobile, String? streamFormat}); -} - -/// @nodoc -class __$$_AppSettingsCopyWithImpl<$Res> - extends _$AppSettingsCopyWithImpl<$Res, _$_AppSettings> - implements _$$_AppSettingsCopyWith<$Res> { - __$$_AppSettingsCopyWithImpl( - _$_AppSettings _value, $Res Function(_$_AppSettings) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? maxBitrateWifi = null, - Object? maxBitrateMobile = null, - Object? streamFormat = freezed, - }) { - return _then(_$_AppSettings( - maxBitrateWifi: null == maxBitrateWifi - ? _value.maxBitrateWifi - : maxBitrateWifi // ignore: cast_nullable_to_non_nullable - as int, - maxBitrateMobile: null == maxBitrateMobile - ? _value.maxBitrateMobile - : maxBitrateMobile // ignore: cast_nullable_to_non_nullable - as int, - streamFormat: freezed == streamFormat - ? _value.streamFormat - : streamFormat // ignore: cast_nullable_to_non_nullable - as String?, - )); - } -} - -/// @nodoc - -class _$_AppSettings extends _AppSettings { - const _$_AppSettings( - {this.maxBitrateWifi = 0, - this.maxBitrateMobile = 192, - this.streamFormat = 'mp3'}) - : super._(); - - @override - @JsonKey() - final int maxBitrateWifi; - @override - @JsonKey() - final int maxBitrateMobile; - @override - @JsonKey() - final String? streamFormat; - - @override - String toString() { - return 'AppSettings(maxBitrateWifi: $maxBitrateWifi, maxBitrateMobile: $maxBitrateMobile, streamFormat: $streamFormat)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_AppSettings && - (identical(other.maxBitrateWifi, maxBitrateWifi) || - other.maxBitrateWifi == maxBitrateWifi) && - (identical(other.maxBitrateMobile, maxBitrateMobile) || - other.maxBitrateMobile == maxBitrateMobile) && - (identical(other.streamFormat, streamFormat) || - other.streamFormat == streamFormat)); - } - - @override - int get hashCode => - Object.hash(runtimeType, maxBitrateWifi, maxBitrateMobile, streamFormat); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_AppSettingsCopyWith<_$_AppSettings> get copyWith => - __$$_AppSettingsCopyWithImpl<_$_AppSettings>(this, _$identity); -} - -abstract class _AppSettings extends AppSettings { - const factory _AppSettings( - {final int maxBitrateWifi, - final int maxBitrateMobile, - final String? streamFormat}) = _$_AppSettings; - const _AppSettings._() : super._(); - - @override - int get maxBitrateWifi; - @override - int get maxBitrateMobile; - @override - String? get streamFormat; - @override - @JsonKey(ignore: true) - _$$_AppSettingsCopyWith<_$_AppSettings> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$SubsonicSettings { - int get id => throw _privateConstructorUsedError; - IList get features => throw _privateConstructorUsedError; - String get name => throw _privateConstructorUsedError; - Uri get address => throw _privateConstructorUsedError; - bool? get isActive => throw _privateConstructorUsedError; - DateTime get createdAt => throw _privateConstructorUsedError; - String get username => throw _privateConstructorUsedError; - String get password => throw _privateConstructorUsedError; - bool get useTokenAuth => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $SubsonicSettingsCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $SubsonicSettingsCopyWith<$Res> { - factory $SubsonicSettingsCopyWith( - SubsonicSettings value, $Res Function(SubsonicSettings) then) = - _$SubsonicSettingsCopyWithImpl<$Res, SubsonicSettings>; - @useResult - $Res call( - {int id, - IList features, - String name, - Uri address, - bool? isActive, - DateTime createdAt, - String username, - String password, - bool useTokenAuth}); -} - -/// @nodoc -class _$SubsonicSettingsCopyWithImpl<$Res, $Val extends SubsonicSettings> - implements $SubsonicSettingsCopyWith<$Res> { - _$SubsonicSettingsCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? id = null, - Object? features = null, - Object? name = null, - Object? address = null, - Object? isActive = freezed, - Object? createdAt = null, - Object? username = null, - Object? password = null, - Object? useTokenAuth = null, - }) { - return _then(_value.copyWith( - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as int, - features: null == features - ? _value.features - : features // ignore: cast_nullable_to_non_nullable - as IList, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - address: null == address - ? _value.address - : address // ignore: cast_nullable_to_non_nullable - as Uri, - isActive: freezed == isActive - ? _value.isActive - : isActive // ignore: cast_nullable_to_non_nullable - as bool?, - createdAt: null == createdAt - ? _value.createdAt - : createdAt // ignore: cast_nullable_to_non_nullable - as DateTime, - username: null == username - ? _value.username - : username // ignore: cast_nullable_to_non_nullable - as String, - password: null == password - ? _value.password - : password // ignore: cast_nullable_to_non_nullable - as String, - useTokenAuth: null == useTokenAuth - ? _value.useTokenAuth - : useTokenAuth // ignore: cast_nullable_to_non_nullable - as bool, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_SubsonicSettingsCopyWith<$Res> - implements $SubsonicSettingsCopyWith<$Res> { - factory _$$_SubsonicSettingsCopyWith( - _$_SubsonicSettings value, $Res Function(_$_SubsonicSettings) then) = - __$$_SubsonicSettingsCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {int id, - IList features, - String name, - Uri address, - bool? isActive, - DateTime createdAt, - String username, - String password, - bool useTokenAuth}); -} - -/// @nodoc -class __$$_SubsonicSettingsCopyWithImpl<$Res> - extends _$SubsonicSettingsCopyWithImpl<$Res, _$_SubsonicSettings> - implements _$$_SubsonicSettingsCopyWith<$Res> { - __$$_SubsonicSettingsCopyWithImpl( - _$_SubsonicSettings _value, $Res Function(_$_SubsonicSettings) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? id = null, - Object? features = null, - Object? name = null, - Object? address = null, - Object? isActive = freezed, - Object? createdAt = null, - Object? username = null, - Object? password = null, - Object? useTokenAuth = null, - }) { - return _then(_$_SubsonicSettings( - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as int, - features: null == features - ? _value.features - : features // ignore: cast_nullable_to_non_nullable - as IList, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - address: null == address - ? _value.address - : address // ignore: cast_nullable_to_non_nullable - as Uri, - isActive: freezed == isActive - ? _value.isActive - : isActive // ignore: cast_nullable_to_non_nullable - as bool?, - createdAt: null == createdAt - ? _value.createdAt - : createdAt // ignore: cast_nullable_to_non_nullable - as DateTime, - username: null == username - ? _value.username - : username // ignore: cast_nullable_to_non_nullable - as String, - password: null == password - ? _value.password - : password // ignore: cast_nullable_to_non_nullable - as String, - useTokenAuth: null == useTokenAuth - ? _value.useTokenAuth - : useTokenAuth // ignore: cast_nullable_to_non_nullable - as bool, - )); - } -} - -/// @nodoc - -class _$_SubsonicSettings extends _SubsonicSettings { - const _$_SubsonicSettings( - {required this.id, - this.features = const IListConst([]), - required this.name, - required this.address, - required this.isActive, - required this.createdAt, - required this.username, - required this.password, - this.useTokenAuth = true}) - : super._(); - - @override - final int id; - @override - @JsonKey() - final IList features; - @override - final String name; - @override - final Uri address; - @override - final bool? isActive; - @override - final DateTime createdAt; - @override - final String username; - @override - final String password; - @override - @JsonKey() - final bool useTokenAuth; - - @override - String toString() { - return 'SubsonicSettings(id: $id, features: $features, name: $name, address: $address, isActive: $isActive, createdAt: $createdAt, username: $username, password: $password, useTokenAuth: $useTokenAuth)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_SubsonicSettings && - (identical(other.id, id) || other.id == id) && - const DeepCollectionEquality().equals(other.features, features) && - (identical(other.name, name) || other.name == name) && - (identical(other.address, address) || other.address == address) && - (identical(other.isActive, isActive) || - other.isActive == isActive) && - (identical(other.createdAt, createdAt) || - other.createdAt == createdAt) && - (identical(other.username, username) || - other.username == username) && - (identical(other.password, password) || - other.password == password) && - (identical(other.useTokenAuth, useTokenAuth) || - other.useTokenAuth == useTokenAuth)); - } - - @override - int get hashCode => Object.hash( - runtimeType, - id, - const DeepCollectionEquality().hash(features), - name, - address, - isActive, - createdAt, - username, - password, - useTokenAuth); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_SubsonicSettingsCopyWith<_$_SubsonicSettings> get copyWith => - __$$_SubsonicSettingsCopyWithImpl<_$_SubsonicSettings>(this, _$identity); -} - -abstract class _SubsonicSettings extends SubsonicSettings { - const factory _SubsonicSettings( - {required final int id, - final IList features, - required final String name, - required final Uri address, - required final bool? isActive, - required final DateTime createdAt, - required final String username, - required final String password, - final bool useTokenAuth}) = _$_SubsonicSettings; - const _SubsonicSettings._() : super._(); - - @override - int get id; - @override - IList get features; - @override - String get name; - @override - Uri get address; - @override - bool? get isActive; - @override - DateTime get createdAt; - @override - String get username; - @override - String get password; - @override - bool get useTokenAuth; - @override - @JsonKey(ignore: true) - _$$_SubsonicSettingsCopyWith<_$_SubsonicSettings> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$SubsonicSourceSettings { - SourceSettings get source => throw _privateConstructorUsedError; - SubsonicSettings get subsonic => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $SubsonicSourceSettingsCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $SubsonicSourceSettingsCopyWith<$Res> { - factory $SubsonicSourceSettingsCopyWith(SubsonicSourceSettings value, - $Res Function(SubsonicSourceSettings) then) = - _$SubsonicSourceSettingsCopyWithImpl<$Res, SubsonicSourceSettings>; - @useResult - $Res call({SourceSettings source, SubsonicSettings subsonic}); - - $SubsonicSettingsCopyWith<$Res> get subsonic; -} - -/// @nodoc -class _$SubsonicSourceSettingsCopyWithImpl<$Res, - $Val extends SubsonicSourceSettings> - implements $SubsonicSourceSettingsCopyWith<$Res> { - _$SubsonicSourceSettingsCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? source = null, - Object? subsonic = null, - }) { - return _then(_value.copyWith( - source: null == source - ? _value.source - : source // ignore: cast_nullable_to_non_nullable - as SourceSettings, - subsonic: null == subsonic - ? _value.subsonic - : subsonic // ignore: cast_nullable_to_non_nullable - as SubsonicSettings, - ) as $Val); - } - - @override - @pragma('vm:prefer-inline') - $SubsonicSettingsCopyWith<$Res> get subsonic { - return $SubsonicSettingsCopyWith<$Res>(_value.subsonic, (value) { - return _then(_value.copyWith(subsonic: value) as $Val); - }); - } -} - -/// @nodoc -abstract class _$$_SubsonicSourceSettingsCopyWith<$Res> - implements $SubsonicSourceSettingsCopyWith<$Res> { - factory _$$_SubsonicSourceSettingsCopyWith(_$_SubsonicSourceSettings value, - $Res Function(_$_SubsonicSourceSettings) then) = - __$$_SubsonicSourceSettingsCopyWithImpl<$Res>; - @override - @useResult - $Res call({SourceSettings source, SubsonicSettings subsonic}); - - @override - $SubsonicSettingsCopyWith<$Res> get subsonic; -} - -/// @nodoc -class __$$_SubsonicSourceSettingsCopyWithImpl<$Res> - extends _$SubsonicSourceSettingsCopyWithImpl<$Res, - _$_SubsonicSourceSettings> - implements _$$_SubsonicSourceSettingsCopyWith<$Res> { - __$$_SubsonicSourceSettingsCopyWithImpl(_$_SubsonicSourceSettings _value, - $Res Function(_$_SubsonicSourceSettings) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? source = null, - Object? subsonic = null, - }) { - return _then(_$_SubsonicSourceSettings( - source: null == source - ? _value.source - : source // ignore: cast_nullable_to_non_nullable - as SourceSettings, - subsonic: null == subsonic - ? _value.subsonic - : subsonic // ignore: cast_nullable_to_non_nullable - as SubsonicSettings, - )); - } -} - -/// @nodoc - -class _$_SubsonicSourceSettings extends _SubsonicSourceSettings { - const _$_SubsonicSourceSettings( - {required this.source, required this.subsonic}) - : super._(); - - @override - final SourceSettings source; - @override - final SubsonicSettings subsonic; - - @override - String toString() { - return 'SubsonicSourceSettings(source: $source, subsonic: $subsonic)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_SubsonicSourceSettings && - (identical(other.source, source) || other.source == source) && - (identical(other.subsonic, subsonic) || - other.subsonic == subsonic)); - } - - @override - int get hashCode => Object.hash(runtimeType, source, subsonic); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_SubsonicSourceSettingsCopyWith<_$_SubsonicSourceSettings> get copyWith => - __$$_SubsonicSourceSettingsCopyWithImpl<_$_SubsonicSourceSettings>( - this, _$identity); -} - -abstract class _SubsonicSourceSettings extends SubsonicSourceSettings { - const factory _SubsonicSourceSettings( - {required final SourceSettings source, - required final SubsonicSettings subsonic}) = _$_SubsonicSourceSettings; - const _SubsonicSourceSettings._() : super._(); - - @override - SourceSettings get source; - @override - SubsonicSettings get subsonic; - @override - @JsonKey(ignore: true) - _$$_SubsonicSourceSettingsCopyWith<_$_SubsonicSourceSettings> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/models/support.dart b/lib/models/support.dart deleted file mode 100644 index b9c022db..00000000 --- a/lib/models/support.dart +++ /dev/null @@ -1,187 +0,0 @@ -import 'package:audio_service/audio_service.dart' show MediaItem; -import 'package:flutter/material.dart'; -import 'package:flutter_cache_manager/flutter_cache_manager.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:palette_generator/palette_generator.dart'; - -part 'support.freezed.dart'; -part 'support.g.dart'; - -@freezed -class UriCacheInfo with _$UriCacheInfo { - const factory UriCacheInfo({ - required Uri uri, - required String cacheKey, - required CacheManager cacheManager, - }) = _UriCacheInfo; -} - -@freezed -class CacheInfo with _$CacheInfo { - const factory CacheInfo({ - required String cacheKey, - required CacheManager cacheManager, - }) = _CacheInfo; -} - -@freezed -class Palette with _$Palette { - const Palette._(); - - const factory Palette({ - PaletteColor? vibrantColor, - PaletteColor? dominantColor, - PaletteColor? mutedColor, - PaletteColor? darkMutedColor, - PaletteColor? darkVibrantColor, - PaletteColor? lightMutedColor, - PaletteColor? lightVibrantColor, - }) = _Palette; - - factory Palette.fromPaletteGenerator(PaletteGenerator generator) { - return Palette( - vibrantColor: generator.vibrantColor, - dominantColor: generator.dominantColor, - mutedColor: generator.mutedColor, - darkMutedColor: generator.darkMutedColor, - darkVibrantColor: generator.darkVibrantColor, - lightMutedColor: generator.lightMutedColor, - lightVibrantColor: generator.lightVibrantColor, - ); - } -} - -@freezed -class ColorTheme with _$ColorTheme { - const factory ColorTheme({ - required ThemeData theme, - required Color gradientHigh, - required Color gradientLow, - required Color darkBackground, - required Color darkerBackground, - required Color onDarkerBackground, - }) = _ColorTheme; -} - -enum QueueContextType { - song('song'), - album('album'), - playlist('playlist'), - library('library'), - genre('genre'), - artist('artist'); - - const QueueContextType(this.value); - final String value; - - @override - String toString() => value; -} - -enum QueueMode { - user('user'), - radio('radio'); - - const QueueMode(this.value); - final String value; - - @override - String toString() => value; -} - -enum RepeatMode { - none('none'), - all('all'), - one('one'); - - const RepeatMode(this.value); - final String value; - - @override - String toString() => value; -} - -@freezed -class QueueItemState with _$QueueItemState { - const factory QueueItemState({ - required String id, - required QueueContextType contextType, - String? contextId, - String? contextTitle, - }) = _QueueItemState; - - factory QueueItemState.fromJson(Map json) => - _$QueueItemStateFromJson(json); -} - -@freezed -class MediaItemData with _$MediaItemData { - const factory MediaItemData({ - required int sourceId, - String? albumId, - @MediaItemArtCacheConverter() MediaItemArtCache? artCache, - required QueueContextType contextType, - String? contextId, - }) = _MediaItemData; - - factory MediaItemData.fromJson(Map json) => - _$MediaItemDataFromJson(json); -} - -@freezed -class MediaItemArtCache with _$MediaItemArtCache { - const factory MediaItemArtCache({ - required Uri fullArtUri, - required String fullArtCacheKey, - required Uri thumbnailArtUri, - required String thumbnailArtCacheKey, - }) = _MediaItemArtCache; - - factory MediaItemArtCache.fromJson(Map json) => - _$MediaItemArtCacheFromJson(json); -} - -class MediaItemArtCacheConverter - implements JsonConverter> { - const MediaItemArtCacheConverter(); - - @override - MediaItemArtCache fromJson(Map json) => - MediaItemArtCache.fromJson(json); - - @override - Map toJson(MediaItemArtCache object) => object.toJson(); -} - -extension MediaItemPlus on MediaItem { - MediaItemData get data => MediaItemData.fromJson(extras!['data']); - set data(MediaItemData data) { - extras!['data'] = data.toJson(); - } -} - -@freezed -class ListDownloadStatus with _$ListDownloadStatus { - const factory ListDownloadStatus({ - required int total, - required int downloaded, - required int downloading, - }) = _ListDownloadStatus; -} - -@freezed -class MultiChoiceOption with _$MultiChoiceOption { - const factory MultiChoiceOption({ - required String title, - }) = _MultiChoiceOption; - - factory MultiChoiceOption.int({ - required String title, - required int option, - }) = _MultiChoiceOptionInt; - - factory MultiChoiceOption.string({ - required String title, - required String option, - }) = _MultiChoiceOptionString; -} diff --git a/lib/models/support.freezed.dart b/lib/models/support.freezed.dart deleted file mode 100644 index 655aa66c..00000000 --- a/lib/models/support.freezed.dart +++ /dev/null @@ -1,2141 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'support.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -/// @nodoc -mixin _$UriCacheInfo { - Uri get uri => throw _privateConstructorUsedError; - String get cacheKey => throw _privateConstructorUsedError; - CacheManager get cacheManager => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $UriCacheInfoCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $UriCacheInfoCopyWith<$Res> { - factory $UriCacheInfoCopyWith( - UriCacheInfo value, $Res Function(UriCacheInfo) then) = - _$UriCacheInfoCopyWithImpl<$Res, UriCacheInfo>; - @useResult - $Res call({Uri uri, String cacheKey, CacheManager cacheManager}); -} - -/// @nodoc -class _$UriCacheInfoCopyWithImpl<$Res, $Val extends UriCacheInfo> - implements $UriCacheInfoCopyWith<$Res> { - _$UriCacheInfoCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? uri = null, - Object? cacheKey = null, - Object? cacheManager = null, - }) { - return _then(_value.copyWith( - uri: null == uri - ? _value.uri - : uri // ignore: cast_nullable_to_non_nullable - as Uri, - cacheKey: null == cacheKey - ? _value.cacheKey - : cacheKey // ignore: cast_nullable_to_non_nullable - as String, - cacheManager: null == cacheManager - ? _value.cacheManager - : cacheManager // ignore: cast_nullable_to_non_nullable - as CacheManager, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_UriCacheInfoCopyWith<$Res> - implements $UriCacheInfoCopyWith<$Res> { - factory _$$_UriCacheInfoCopyWith( - _$_UriCacheInfo value, $Res Function(_$_UriCacheInfo) then) = - __$$_UriCacheInfoCopyWithImpl<$Res>; - @override - @useResult - $Res call({Uri uri, String cacheKey, CacheManager cacheManager}); -} - -/// @nodoc -class __$$_UriCacheInfoCopyWithImpl<$Res> - extends _$UriCacheInfoCopyWithImpl<$Res, _$_UriCacheInfo> - implements _$$_UriCacheInfoCopyWith<$Res> { - __$$_UriCacheInfoCopyWithImpl( - _$_UriCacheInfo _value, $Res Function(_$_UriCacheInfo) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? uri = null, - Object? cacheKey = null, - Object? cacheManager = null, - }) { - return _then(_$_UriCacheInfo( - uri: null == uri - ? _value.uri - : uri // ignore: cast_nullable_to_non_nullable - as Uri, - cacheKey: null == cacheKey - ? _value.cacheKey - : cacheKey // ignore: cast_nullable_to_non_nullable - as String, - cacheManager: null == cacheManager - ? _value.cacheManager - : cacheManager // ignore: cast_nullable_to_non_nullable - as CacheManager, - )); - } -} - -/// @nodoc - -class _$_UriCacheInfo implements _UriCacheInfo { - const _$_UriCacheInfo( - {required this.uri, required this.cacheKey, required this.cacheManager}); - - @override - final Uri uri; - @override - final String cacheKey; - @override - final CacheManager cacheManager; - - @override - String toString() { - return 'UriCacheInfo(uri: $uri, cacheKey: $cacheKey, cacheManager: $cacheManager)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_UriCacheInfo && - (identical(other.uri, uri) || other.uri == uri) && - (identical(other.cacheKey, cacheKey) || - other.cacheKey == cacheKey) && - (identical(other.cacheManager, cacheManager) || - other.cacheManager == cacheManager)); - } - - @override - int get hashCode => Object.hash(runtimeType, uri, cacheKey, cacheManager); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_UriCacheInfoCopyWith<_$_UriCacheInfo> get copyWith => - __$$_UriCacheInfoCopyWithImpl<_$_UriCacheInfo>(this, _$identity); -} - -abstract class _UriCacheInfo implements UriCacheInfo { - const factory _UriCacheInfo( - {required final Uri uri, - required final String cacheKey, - required final CacheManager cacheManager}) = _$_UriCacheInfo; - - @override - Uri get uri; - @override - String get cacheKey; - @override - CacheManager get cacheManager; - @override - @JsonKey(ignore: true) - _$$_UriCacheInfoCopyWith<_$_UriCacheInfo> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$CacheInfo { - String get cacheKey => throw _privateConstructorUsedError; - CacheManager get cacheManager => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $CacheInfoCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $CacheInfoCopyWith<$Res> { - factory $CacheInfoCopyWith(CacheInfo value, $Res Function(CacheInfo) then) = - _$CacheInfoCopyWithImpl<$Res, CacheInfo>; - @useResult - $Res call({String cacheKey, CacheManager cacheManager}); -} - -/// @nodoc -class _$CacheInfoCopyWithImpl<$Res, $Val extends CacheInfo> - implements $CacheInfoCopyWith<$Res> { - _$CacheInfoCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? cacheKey = null, - Object? cacheManager = null, - }) { - return _then(_value.copyWith( - cacheKey: null == cacheKey - ? _value.cacheKey - : cacheKey // ignore: cast_nullable_to_non_nullable - as String, - cacheManager: null == cacheManager - ? _value.cacheManager - : cacheManager // ignore: cast_nullable_to_non_nullable - as CacheManager, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_CacheInfoCopyWith<$Res> implements $CacheInfoCopyWith<$Res> { - factory _$$_CacheInfoCopyWith( - _$_CacheInfo value, $Res Function(_$_CacheInfo) then) = - __$$_CacheInfoCopyWithImpl<$Res>; - @override - @useResult - $Res call({String cacheKey, CacheManager cacheManager}); -} - -/// @nodoc -class __$$_CacheInfoCopyWithImpl<$Res> - extends _$CacheInfoCopyWithImpl<$Res, _$_CacheInfo> - implements _$$_CacheInfoCopyWith<$Res> { - __$$_CacheInfoCopyWithImpl( - _$_CacheInfo _value, $Res Function(_$_CacheInfo) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? cacheKey = null, - Object? cacheManager = null, - }) { - return _then(_$_CacheInfo( - cacheKey: null == cacheKey - ? _value.cacheKey - : cacheKey // ignore: cast_nullable_to_non_nullable - as String, - cacheManager: null == cacheManager - ? _value.cacheManager - : cacheManager // ignore: cast_nullable_to_non_nullable - as CacheManager, - )); - } -} - -/// @nodoc - -class _$_CacheInfo implements _CacheInfo { - const _$_CacheInfo({required this.cacheKey, required this.cacheManager}); - - @override - final String cacheKey; - @override - final CacheManager cacheManager; - - @override - String toString() { - return 'CacheInfo(cacheKey: $cacheKey, cacheManager: $cacheManager)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_CacheInfo && - (identical(other.cacheKey, cacheKey) || - other.cacheKey == cacheKey) && - (identical(other.cacheManager, cacheManager) || - other.cacheManager == cacheManager)); - } - - @override - int get hashCode => Object.hash(runtimeType, cacheKey, cacheManager); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_CacheInfoCopyWith<_$_CacheInfo> get copyWith => - __$$_CacheInfoCopyWithImpl<_$_CacheInfo>(this, _$identity); -} - -abstract class _CacheInfo implements CacheInfo { - const factory _CacheInfo( - {required final String cacheKey, - required final CacheManager cacheManager}) = _$_CacheInfo; - - @override - String get cacheKey; - @override - CacheManager get cacheManager; - @override - @JsonKey(ignore: true) - _$$_CacheInfoCopyWith<_$_CacheInfo> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$Palette { - PaletteColor? get vibrantColor => throw _privateConstructorUsedError; - PaletteColor? get dominantColor => throw _privateConstructorUsedError; - PaletteColor? get mutedColor => throw _privateConstructorUsedError; - PaletteColor? get darkMutedColor => throw _privateConstructorUsedError; - PaletteColor? get darkVibrantColor => throw _privateConstructorUsedError; - PaletteColor? get lightMutedColor => throw _privateConstructorUsedError; - PaletteColor? get lightVibrantColor => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $PaletteCopyWith get copyWith => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $PaletteCopyWith<$Res> { - factory $PaletteCopyWith(Palette value, $Res Function(Palette) then) = - _$PaletteCopyWithImpl<$Res, Palette>; - @useResult - $Res call( - {PaletteColor? vibrantColor, - PaletteColor? dominantColor, - PaletteColor? mutedColor, - PaletteColor? darkMutedColor, - PaletteColor? darkVibrantColor, - PaletteColor? lightMutedColor, - PaletteColor? lightVibrantColor}); -} - -/// @nodoc -class _$PaletteCopyWithImpl<$Res, $Val extends Palette> - implements $PaletteCopyWith<$Res> { - _$PaletteCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? vibrantColor = freezed, - Object? dominantColor = freezed, - Object? mutedColor = freezed, - Object? darkMutedColor = freezed, - Object? darkVibrantColor = freezed, - Object? lightMutedColor = freezed, - Object? lightVibrantColor = freezed, - }) { - return _then(_value.copyWith( - vibrantColor: freezed == vibrantColor - ? _value.vibrantColor - : vibrantColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - dominantColor: freezed == dominantColor - ? _value.dominantColor - : dominantColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - mutedColor: freezed == mutedColor - ? _value.mutedColor - : mutedColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - darkMutedColor: freezed == darkMutedColor - ? _value.darkMutedColor - : darkMutedColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - darkVibrantColor: freezed == darkVibrantColor - ? _value.darkVibrantColor - : darkVibrantColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - lightMutedColor: freezed == lightMutedColor - ? _value.lightMutedColor - : lightMutedColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - lightVibrantColor: freezed == lightVibrantColor - ? _value.lightVibrantColor - : lightVibrantColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_PaletteCopyWith<$Res> implements $PaletteCopyWith<$Res> { - factory _$$_PaletteCopyWith( - _$_Palette value, $Res Function(_$_Palette) then) = - __$$_PaletteCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {PaletteColor? vibrantColor, - PaletteColor? dominantColor, - PaletteColor? mutedColor, - PaletteColor? darkMutedColor, - PaletteColor? darkVibrantColor, - PaletteColor? lightMutedColor, - PaletteColor? lightVibrantColor}); -} - -/// @nodoc -class __$$_PaletteCopyWithImpl<$Res> - extends _$PaletteCopyWithImpl<$Res, _$_Palette> - implements _$$_PaletteCopyWith<$Res> { - __$$_PaletteCopyWithImpl(_$_Palette _value, $Res Function(_$_Palette) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? vibrantColor = freezed, - Object? dominantColor = freezed, - Object? mutedColor = freezed, - Object? darkMutedColor = freezed, - Object? darkVibrantColor = freezed, - Object? lightMutedColor = freezed, - Object? lightVibrantColor = freezed, - }) { - return _then(_$_Palette( - vibrantColor: freezed == vibrantColor - ? _value.vibrantColor - : vibrantColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - dominantColor: freezed == dominantColor - ? _value.dominantColor - : dominantColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - mutedColor: freezed == mutedColor - ? _value.mutedColor - : mutedColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - darkMutedColor: freezed == darkMutedColor - ? _value.darkMutedColor - : darkMutedColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - darkVibrantColor: freezed == darkVibrantColor - ? _value.darkVibrantColor - : darkVibrantColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - lightMutedColor: freezed == lightMutedColor - ? _value.lightMutedColor - : lightMutedColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - lightVibrantColor: freezed == lightVibrantColor - ? _value.lightVibrantColor - : lightVibrantColor // ignore: cast_nullable_to_non_nullable - as PaletteColor?, - )); - } -} - -/// @nodoc - -class _$_Palette extends _Palette { - const _$_Palette( - {this.vibrantColor, - this.dominantColor, - this.mutedColor, - this.darkMutedColor, - this.darkVibrantColor, - this.lightMutedColor, - this.lightVibrantColor}) - : super._(); - - @override - final PaletteColor? vibrantColor; - @override - final PaletteColor? dominantColor; - @override - final PaletteColor? mutedColor; - @override - final PaletteColor? darkMutedColor; - @override - final PaletteColor? darkVibrantColor; - @override - final PaletteColor? lightMutedColor; - @override - final PaletteColor? lightVibrantColor; - - @override - String toString() { - return 'Palette(vibrantColor: $vibrantColor, dominantColor: $dominantColor, mutedColor: $mutedColor, darkMutedColor: $darkMutedColor, darkVibrantColor: $darkVibrantColor, lightMutedColor: $lightMutedColor, lightVibrantColor: $lightVibrantColor)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_Palette && - (identical(other.vibrantColor, vibrantColor) || - other.vibrantColor == vibrantColor) && - (identical(other.dominantColor, dominantColor) || - other.dominantColor == dominantColor) && - (identical(other.mutedColor, mutedColor) || - other.mutedColor == mutedColor) && - (identical(other.darkMutedColor, darkMutedColor) || - other.darkMutedColor == darkMutedColor) && - (identical(other.darkVibrantColor, darkVibrantColor) || - other.darkVibrantColor == darkVibrantColor) && - (identical(other.lightMutedColor, lightMutedColor) || - other.lightMutedColor == lightMutedColor) && - (identical(other.lightVibrantColor, lightVibrantColor) || - other.lightVibrantColor == lightVibrantColor)); - } - - @override - int get hashCode => Object.hash( - runtimeType, - vibrantColor, - dominantColor, - mutedColor, - darkMutedColor, - darkVibrantColor, - lightMutedColor, - lightVibrantColor); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_PaletteCopyWith<_$_Palette> get copyWith => - __$$_PaletteCopyWithImpl<_$_Palette>(this, _$identity); -} - -abstract class _Palette extends Palette { - const factory _Palette( - {final PaletteColor? vibrantColor, - final PaletteColor? dominantColor, - final PaletteColor? mutedColor, - final PaletteColor? darkMutedColor, - final PaletteColor? darkVibrantColor, - final PaletteColor? lightMutedColor, - final PaletteColor? lightVibrantColor}) = _$_Palette; - const _Palette._() : super._(); - - @override - PaletteColor? get vibrantColor; - @override - PaletteColor? get dominantColor; - @override - PaletteColor? get mutedColor; - @override - PaletteColor? get darkMutedColor; - @override - PaletteColor? get darkVibrantColor; - @override - PaletteColor? get lightMutedColor; - @override - PaletteColor? get lightVibrantColor; - @override - @JsonKey(ignore: true) - _$$_PaletteCopyWith<_$_Palette> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$ColorTheme { - ThemeData get theme => throw _privateConstructorUsedError; - Color get gradientHigh => throw _privateConstructorUsedError; - Color get gradientLow => throw _privateConstructorUsedError; - Color get darkBackground => throw _privateConstructorUsedError; - Color get darkerBackground => throw _privateConstructorUsedError; - Color get onDarkerBackground => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $ColorThemeCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $ColorThemeCopyWith<$Res> { - factory $ColorThemeCopyWith( - ColorTheme value, $Res Function(ColorTheme) then) = - _$ColorThemeCopyWithImpl<$Res, ColorTheme>; - @useResult - $Res call( - {ThemeData theme, - Color gradientHigh, - Color gradientLow, - Color darkBackground, - Color darkerBackground, - Color onDarkerBackground}); -} - -/// @nodoc -class _$ColorThemeCopyWithImpl<$Res, $Val extends ColorTheme> - implements $ColorThemeCopyWith<$Res> { - _$ColorThemeCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? theme = null, - Object? gradientHigh = null, - Object? gradientLow = null, - Object? darkBackground = null, - Object? darkerBackground = null, - Object? onDarkerBackground = null, - }) { - return _then(_value.copyWith( - theme: null == theme - ? _value.theme - : theme // ignore: cast_nullable_to_non_nullable - as ThemeData, - gradientHigh: null == gradientHigh - ? _value.gradientHigh - : gradientHigh // ignore: cast_nullable_to_non_nullable - as Color, - gradientLow: null == gradientLow - ? _value.gradientLow - : gradientLow // ignore: cast_nullable_to_non_nullable - as Color, - darkBackground: null == darkBackground - ? _value.darkBackground - : darkBackground // ignore: cast_nullable_to_non_nullable - as Color, - darkerBackground: null == darkerBackground - ? _value.darkerBackground - : darkerBackground // ignore: cast_nullable_to_non_nullable - as Color, - onDarkerBackground: null == onDarkerBackground - ? _value.onDarkerBackground - : onDarkerBackground // ignore: cast_nullable_to_non_nullable - as Color, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_ColorThemeCopyWith<$Res> - implements $ColorThemeCopyWith<$Res> { - factory _$$_ColorThemeCopyWith( - _$_ColorTheme value, $Res Function(_$_ColorTheme) then) = - __$$_ColorThemeCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {ThemeData theme, - Color gradientHigh, - Color gradientLow, - Color darkBackground, - Color darkerBackground, - Color onDarkerBackground}); -} - -/// @nodoc -class __$$_ColorThemeCopyWithImpl<$Res> - extends _$ColorThemeCopyWithImpl<$Res, _$_ColorTheme> - implements _$$_ColorThemeCopyWith<$Res> { - __$$_ColorThemeCopyWithImpl( - _$_ColorTheme _value, $Res Function(_$_ColorTheme) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? theme = null, - Object? gradientHigh = null, - Object? gradientLow = null, - Object? darkBackground = null, - Object? darkerBackground = null, - Object? onDarkerBackground = null, - }) { - return _then(_$_ColorTheme( - theme: null == theme - ? _value.theme - : theme // ignore: cast_nullable_to_non_nullable - as ThemeData, - gradientHigh: null == gradientHigh - ? _value.gradientHigh - : gradientHigh // ignore: cast_nullable_to_non_nullable - as Color, - gradientLow: null == gradientLow - ? _value.gradientLow - : gradientLow // ignore: cast_nullable_to_non_nullable - as Color, - darkBackground: null == darkBackground - ? _value.darkBackground - : darkBackground // ignore: cast_nullable_to_non_nullable - as Color, - darkerBackground: null == darkerBackground - ? _value.darkerBackground - : darkerBackground // ignore: cast_nullable_to_non_nullable - as Color, - onDarkerBackground: null == onDarkerBackground - ? _value.onDarkerBackground - : onDarkerBackground // ignore: cast_nullable_to_non_nullable - as Color, - )); - } -} - -/// @nodoc - -class _$_ColorTheme implements _ColorTheme { - const _$_ColorTheme( - {required this.theme, - required this.gradientHigh, - required this.gradientLow, - required this.darkBackground, - required this.darkerBackground, - required this.onDarkerBackground}); - - @override - final ThemeData theme; - @override - final Color gradientHigh; - @override - final Color gradientLow; - @override - final Color darkBackground; - @override - final Color darkerBackground; - @override - final Color onDarkerBackground; - - @override - String toString() { - return 'ColorTheme(theme: $theme, gradientHigh: $gradientHigh, gradientLow: $gradientLow, darkBackground: $darkBackground, darkerBackground: $darkerBackground, onDarkerBackground: $onDarkerBackground)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_ColorTheme && - (identical(other.theme, theme) || other.theme == theme) && - (identical(other.gradientHigh, gradientHigh) || - other.gradientHigh == gradientHigh) && - (identical(other.gradientLow, gradientLow) || - other.gradientLow == gradientLow) && - (identical(other.darkBackground, darkBackground) || - other.darkBackground == darkBackground) && - (identical(other.darkerBackground, darkerBackground) || - other.darkerBackground == darkerBackground) && - (identical(other.onDarkerBackground, onDarkerBackground) || - other.onDarkerBackground == onDarkerBackground)); - } - - @override - int get hashCode => Object.hash(runtimeType, theme, gradientHigh, gradientLow, - darkBackground, darkerBackground, onDarkerBackground); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_ColorThemeCopyWith<_$_ColorTheme> get copyWith => - __$$_ColorThemeCopyWithImpl<_$_ColorTheme>(this, _$identity); -} - -abstract class _ColorTheme implements ColorTheme { - const factory _ColorTheme( - {required final ThemeData theme, - required final Color gradientHigh, - required final Color gradientLow, - required final Color darkBackground, - required final Color darkerBackground, - required final Color onDarkerBackground}) = _$_ColorTheme; - - @override - ThemeData get theme; - @override - Color get gradientHigh; - @override - Color get gradientLow; - @override - Color get darkBackground; - @override - Color get darkerBackground; - @override - Color get onDarkerBackground; - @override - @JsonKey(ignore: true) - _$$_ColorThemeCopyWith<_$_ColorTheme> get copyWith => - throw _privateConstructorUsedError; -} - -QueueItemState _$QueueItemStateFromJson(Map json) { - return _QueueItemState.fromJson(json); -} - -/// @nodoc -mixin _$QueueItemState { - String get id => throw _privateConstructorUsedError; - QueueContextType get contextType => throw _privateConstructorUsedError; - String? get contextId => throw _privateConstructorUsedError; - String? get contextTitle => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $QueueItemStateCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $QueueItemStateCopyWith<$Res> { - factory $QueueItemStateCopyWith( - QueueItemState value, $Res Function(QueueItemState) then) = - _$QueueItemStateCopyWithImpl<$Res, QueueItemState>; - @useResult - $Res call( - {String id, - QueueContextType contextType, - String? contextId, - String? contextTitle}); -} - -/// @nodoc -class _$QueueItemStateCopyWithImpl<$Res, $Val extends QueueItemState> - implements $QueueItemStateCopyWith<$Res> { - _$QueueItemStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? id = null, - Object? contextType = null, - Object? contextId = freezed, - Object? contextTitle = freezed, - }) { - return _then(_value.copyWith( - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - contextType: null == contextType - ? _value.contextType - : contextType // ignore: cast_nullable_to_non_nullable - as QueueContextType, - contextId: freezed == contextId - ? _value.contextId - : contextId // ignore: cast_nullable_to_non_nullable - as String?, - contextTitle: freezed == contextTitle - ? _value.contextTitle - : contextTitle // ignore: cast_nullable_to_non_nullable - as String?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_QueueItemStateCopyWith<$Res> - implements $QueueItemStateCopyWith<$Res> { - factory _$$_QueueItemStateCopyWith( - _$_QueueItemState value, $Res Function(_$_QueueItemState) then) = - __$$_QueueItemStateCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {String id, - QueueContextType contextType, - String? contextId, - String? contextTitle}); -} - -/// @nodoc -class __$$_QueueItemStateCopyWithImpl<$Res> - extends _$QueueItemStateCopyWithImpl<$Res, _$_QueueItemState> - implements _$$_QueueItemStateCopyWith<$Res> { - __$$_QueueItemStateCopyWithImpl( - _$_QueueItemState _value, $Res Function(_$_QueueItemState) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? id = null, - Object? contextType = null, - Object? contextId = freezed, - Object? contextTitle = freezed, - }) { - return _then(_$_QueueItemState( - id: null == id - ? _value.id - : id // ignore: cast_nullable_to_non_nullable - as String, - contextType: null == contextType - ? _value.contextType - : contextType // ignore: cast_nullable_to_non_nullable - as QueueContextType, - contextId: freezed == contextId - ? _value.contextId - : contextId // ignore: cast_nullable_to_non_nullable - as String?, - contextTitle: freezed == contextTitle - ? _value.contextTitle - : contextTitle // ignore: cast_nullable_to_non_nullable - as String?, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$_QueueItemState implements _QueueItemState { - const _$_QueueItemState( - {required this.id, - required this.contextType, - this.contextId, - this.contextTitle}); - - factory _$_QueueItemState.fromJson(Map json) => - _$$_QueueItemStateFromJson(json); - - @override - final String id; - @override - final QueueContextType contextType; - @override - final String? contextId; - @override - final String? contextTitle; - - @override - String toString() { - return 'QueueItemState(id: $id, contextType: $contextType, contextId: $contextId, contextTitle: $contextTitle)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_QueueItemState && - (identical(other.id, id) || other.id == id) && - (identical(other.contextType, contextType) || - other.contextType == contextType) && - (identical(other.contextId, contextId) || - other.contextId == contextId) && - (identical(other.contextTitle, contextTitle) || - other.contextTitle == contextTitle)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => - Object.hash(runtimeType, id, contextType, contextId, contextTitle); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_QueueItemStateCopyWith<_$_QueueItemState> get copyWith => - __$$_QueueItemStateCopyWithImpl<_$_QueueItemState>(this, _$identity); - - @override - Map toJson() { - return _$$_QueueItemStateToJson( - this, - ); - } -} - -abstract class _QueueItemState implements QueueItemState { - const factory _QueueItemState( - {required final String id, - required final QueueContextType contextType, - final String? contextId, - final String? contextTitle}) = _$_QueueItemState; - - factory _QueueItemState.fromJson(Map json) = - _$_QueueItemState.fromJson; - - @override - String get id; - @override - QueueContextType get contextType; - @override - String? get contextId; - @override - String? get contextTitle; - @override - @JsonKey(ignore: true) - _$$_QueueItemStateCopyWith<_$_QueueItemState> get copyWith => - throw _privateConstructorUsedError; -} - -MediaItemData _$MediaItemDataFromJson(Map json) { - return _MediaItemData.fromJson(json); -} - -/// @nodoc -mixin _$MediaItemData { - int get sourceId => throw _privateConstructorUsedError; - String? get albumId => throw _privateConstructorUsedError; - @MediaItemArtCacheConverter() - MediaItemArtCache? get artCache => throw _privateConstructorUsedError; - QueueContextType get contextType => throw _privateConstructorUsedError; - String? get contextId => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $MediaItemDataCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $MediaItemDataCopyWith<$Res> { - factory $MediaItemDataCopyWith( - MediaItemData value, $Res Function(MediaItemData) then) = - _$MediaItemDataCopyWithImpl<$Res, MediaItemData>; - @useResult - $Res call( - {int sourceId, - String? albumId, - @MediaItemArtCacheConverter() MediaItemArtCache? artCache, - QueueContextType contextType, - String? contextId}); - - $MediaItemArtCacheCopyWith<$Res>? get artCache; -} - -/// @nodoc -class _$MediaItemDataCopyWithImpl<$Res, $Val extends MediaItemData> - implements $MediaItemDataCopyWith<$Res> { - _$MediaItemDataCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? albumId = freezed, - Object? artCache = freezed, - Object? contextType = null, - Object? contextId = freezed, - }) { - return _then(_value.copyWith( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - albumId: freezed == albumId - ? _value.albumId - : albumId // ignore: cast_nullable_to_non_nullable - as String?, - artCache: freezed == artCache - ? _value.artCache - : artCache // ignore: cast_nullable_to_non_nullable - as MediaItemArtCache?, - contextType: null == contextType - ? _value.contextType - : contextType // ignore: cast_nullable_to_non_nullable - as QueueContextType, - contextId: freezed == contextId - ? _value.contextId - : contextId // ignore: cast_nullable_to_non_nullable - as String?, - ) as $Val); - } - - @override - @pragma('vm:prefer-inline') - $MediaItemArtCacheCopyWith<$Res>? get artCache { - if (_value.artCache == null) { - return null; - } - - return $MediaItemArtCacheCopyWith<$Res>(_value.artCache!, (value) { - return _then(_value.copyWith(artCache: value) as $Val); - }); - } -} - -/// @nodoc -abstract class _$$_MediaItemDataCopyWith<$Res> - implements $MediaItemDataCopyWith<$Res> { - factory _$$_MediaItemDataCopyWith( - _$_MediaItemData value, $Res Function(_$_MediaItemData) then) = - __$$_MediaItemDataCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {int sourceId, - String? albumId, - @MediaItemArtCacheConverter() MediaItemArtCache? artCache, - QueueContextType contextType, - String? contextId}); - - @override - $MediaItemArtCacheCopyWith<$Res>? get artCache; -} - -/// @nodoc -class __$$_MediaItemDataCopyWithImpl<$Res> - extends _$MediaItemDataCopyWithImpl<$Res, _$_MediaItemData> - implements _$$_MediaItemDataCopyWith<$Res> { - __$$_MediaItemDataCopyWithImpl( - _$_MediaItemData _value, $Res Function(_$_MediaItemData) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? sourceId = null, - Object? albumId = freezed, - Object? artCache = freezed, - Object? contextType = null, - Object? contextId = freezed, - }) { - return _then(_$_MediaItemData( - sourceId: null == sourceId - ? _value.sourceId - : sourceId // ignore: cast_nullable_to_non_nullable - as int, - albumId: freezed == albumId - ? _value.albumId - : albumId // ignore: cast_nullable_to_non_nullable - as String?, - artCache: freezed == artCache - ? _value.artCache - : artCache // ignore: cast_nullable_to_non_nullable - as MediaItemArtCache?, - contextType: null == contextType - ? _value.contextType - : contextType // ignore: cast_nullable_to_non_nullable - as QueueContextType, - contextId: freezed == contextId - ? _value.contextId - : contextId // ignore: cast_nullable_to_non_nullable - as String?, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$_MediaItemData implements _MediaItemData { - const _$_MediaItemData( - {required this.sourceId, - this.albumId, - @MediaItemArtCacheConverter() this.artCache, - required this.contextType, - this.contextId}); - - factory _$_MediaItemData.fromJson(Map json) => - _$$_MediaItemDataFromJson(json); - - @override - final int sourceId; - @override - final String? albumId; - @override - @MediaItemArtCacheConverter() - final MediaItemArtCache? artCache; - @override - final QueueContextType contextType; - @override - final String? contextId; - - @override - String toString() { - return 'MediaItemData(sourceId: $sourceId, albumId: $albumId, artCache: $artCache, contextType: $contextType, contextId: $contextId)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_MediaItemData && - (identical(other.sourceId, sourceId) || - other.sourceId == sourceId) && - (identical(other.albumId, albumId) || other.albumId == albumId) && - (identical(other.artCache, artCache) || - other.artCache == artCache) && - (identical(other.contextType, contextType) || - other.contextType == contextType) && - (identical(other.contextId, contextId) || - other.contextId == contextId)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, sourceId, albumId, artCache, contextType, contextId); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_MediaItemDataCopyWith<_$_MediaItemData> get copyWith => - __$$_MediaItemDataCopyWithImpl<_$_MediaItemData>(this, _$identity); - - @override - Map toJson() { - return _$$_MediaItemDataToJson( - this, - ); - } -} - -abstract class _MediaItemData implements MediaItemData { - const factory _MediaItemData( - {required final int sourceId, - final String? albumId, - @MediaItemArtCacheConverter() final MediaItemArtCache? artCache, - required final QueueContextType contextType, - final String? contextId}) = _$_MediaItemData; - - factory _MediaItemData.fromJson(Map json) = - _$_MediaItemData.fromJson; - - @override - int get sourceId; - @override - String? get albumId; - @override - @MediaItemArtCacheConverter() - MediaItemArtCache? get artCache; - @override - QueueContextType get contextType; - @override - String? get contextId; - @override - @JsonKey(ignore: true) - _$$_MediaItemDataCopyWith<_$_MediaItemData> get copyWith => - throw _privateConstructorUsedError; -} - -MediaItemArtCache _$MediaItemArtCacheFromJson(Map json) { - return _MediaItemArtCache.fromJson(json); -} - -/// @nodoc -mixin _$MediaItemArtCache { - Uri get fullArtUri => throw _privateConstructorUsedError; - String get fullArtCacheKey => throw _privateConstructorUsedError; - Uri get thumbnailArtUri => throw _privateConstructorUsedError; - String get thumbnailArtCacheKey => throw _privateConstructorUsedError; - - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $MediaItemArtCacheCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $MediaItemArtCacheCopyWith<$Res> { - factory $MediaItemArtCacheCopyWith( - MediaItemArtCache value, $Res Function(MediaItemArtCache) then) = - _$MediaItemArtCacheCopyWithImpl<$Res, MediaItemArtCache>; - @useResult - $Res call( - {Uri fullArtUri, - String fullArtCacheKey, - Uri thumbnailArtUri, - String thumbnailArtCacheKey}); -} - -/// @nodoc -class _$MediaItemArtCacheCopyWithImpl<$Res, $Val extends MediaItemArtCache> - implements $MediaItemArtCacheCopyWith<$Res> { - _$MediaItemArtCacheCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? fullArtUri = null, - Object? fullArtCacheKey = null, - Object? thumbnailArtUri = null, - Object? thumbnailArtCacheKey = null, - }) { - return _then(_value.copyWith( - fullArtUri: null == fullArtUri - ? _value.fullArtUri - : fullArtUri // ignore: cast_nullable_to_non_nullable - as Uri, - fullArtCacheKey: null == fullArtCacheKey - ? _value.fullArtCacheKey - : fullArtCacheKey // ignore: cast_nullable_to_non_nullable - as String, - thumbnailArtUri: null == thumbnailArtUri - ? _value.thumbnailArtUri - : thumbnailArtUri // ignore: cast_nullable_to_non_nullable - as Uri, - thumbnailArtCacheKey: null == thumbnailArtCacheKey - ? _value.thumbnailArtCacheKey - : thumbnailArtCacheKey // ignore: cast_nullable_to_non_nullable - as String, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_MediaItemArtCacheCopyWith<$Res> - implements $MediaItemArtCacheCopyWith<$Res> { - factory _$$_MediaItemArtCacheCopyWith(_$_MediaItemArtCache value, - $Res Function(_$_MediaItemArtCache) then) = - __$$_MediaItemArtCacheCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {Uri fullArtUri, - String fullArtCacheKey, - Uri thumbnailArtUri, - String thumbnailArtCacheKey}); -} - -/// @nodoc -class __$$_MediaItemArtCacheCopyWithImpl<$Res> - extends _$MediaItemArtCacheCopyWithImpl<$Res, _$_MediaItemArtCache> - implements _$$_MediaItemArtCacheCopyWith<$Res> { - __$$_MediaItemArtCacheCopyWithImpl( - _$_MediaItemArtCache _value, $Res Function(_$_MediaItemArtCache) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? fullArtUri = null, - Object? fullArtCacheKey = null, - Object? thumbnailArtUri = null, - Object? thumbnailArtCacheKey = null, - }) { - return _then(_$_MediaItemArtCache( - fullArtUri: null == fullArtUri - ? _value.fullArtUri - : fullArtUri // ignore: cast_nullable_to_non_nullable - as Uri, - fullArtCacheKey: null == fullArtCacheKey - ? _value.fullArtCacheKey - : fullArtCacheKey // ignore: cast_nullable_to_non_nullable - as String, - thumbnailArtUri: null == thumbnailArtUri - ? _value.thumbnailArtUri - : thumbnailArtUri // ignore: cast_nullable_to_non_nullable - as Uri, - thumbnailArtCacheKey: null == thumbnailArtCacheKey - ? _value.thumbnailArtCacheKey - : thumbnailArtCacheKey // ignore: cast_nullable_to_non_nullable - as String, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$_MediaItemArtCache implements _MediaItemArtCache { - const _$_MediaItemArtCache( - {required this.fullArtUri, - required this.fullArtCacheKey, - required this.thumbnailArtUri, - required this.thumbnailArtCacheKey}); - - factory _$_MediaItemArtCache.fromJson(Map json) => - _$$_MediaItemArtCacheFromJson(json); - - @override - final Uri fullArtUri; - @override - final String fullArtCacheKey; - @override - final Uri thumbnailArtUri; - @override - final String thumbnailArtCacheKey; - - @override - String toString() { - return 'MediaItemArtCache(fullArtUri: $fullArtUri, fullArtCacheKey: $fullArtCacheKey, thumbnailArtUri: $thumbnailArtUri, thumbnailArtCacheKey: $thumbnailArtCacheKey)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_MediaItemArtCache && - (identical(other.fullArtUri, fullArtUri) || - other.fullArtUri == fullArtUri) && - (identical(other.fullArtCacheKey, fullArtCacheKey) || - other.fullArtCacheKey == fullArtCacheKey) && - (identical(other.thumbnailArtUri, thumbnailArtUri) || - other.thumbnailArtUri == thumbnailArtUri) && - (identical(other.thumbnailArtCacheKey, thumbnailArtCacheKey) || - other.thumbnailArtCacheKey == thumbnailArtCacheKey)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash(runtimeType, fullArtUri, fullArtCacheKey, - thumbnailArtUri, thumbnailArtCacheKey); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_MediaItemArtCacheCopyWith<_$_MediaItemArtCache> get copyWith => - __$$_MediaItemArtCacheCopyWithImpl<_$_MediaItemArtCache>( - this, _$identity); - - @override - Map toJson() { - return _$$_MediaItemArtCacheToJson( - this, - ); - } -} - -abstract class _MediaItemArtCache implements MediaItemArtCache { - const factory _MediaItemArtCache( - {required final Uri fullArtUri, - required final String fullArtCacheKey, - required final Uri thumbnailArtUri, - required final String thumbnailArtCacheKey}) = _$_MediaItemArtCache; - - factory _MediaItemArtCache.fromJson(Map json) = - _$_MediaItemArtCache.fromJson; - - @override - Uri get fullArtUri; - @override - String get fullArtCacheKey; - @override - Uri get thumbnailArtUri; - @override - String get thumbnailArtCacheKey; - @override - @JsonKey(ignore: true) - _$$_MediaItemArtCacheCopyWith<_$_MediaItemArtCache> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$ListDownloadStatus { - int get total => throw _privateConstructorUsedError; - int get downloaded => throw _privateConstructorUsedError; - int get downloading => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $ListDownloadStatusCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $ListDownloadStatusCopyWith<$Res> { - factory $ListDownloadStatusCopyWith( - ListDownloadStatus value, $Res Function(ListDownloadStatus) then) = - _$ListDownloadStatusCopyWithImpl<$Res, ListDownloadStatus>; - @useResult - $Res call({int total, int downloaded, int downloading}); -} - -/// @nodoc -class _$ListDownloadStatusCopyWithImpl<$Res, $Val extends ListDownloadStatus> - implements $ListDownloadStatusCopyWith<$Res> { - _$ListDownloadStatusCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? total = null, - Object? downloaded = null, - Object? downloading = null, - }) { - return _then(_value.copyWith( - total: null == total - ? _value.total - : total // ignore: cast_nullable_to_non_nullable - as int, - downloaded: null == downloaded - ? _value.downloaded - : downloaded // ignore: cast_nullable_to_non_nullable - as int, - downloading: null == downloading - ? _value.downloading - : downloading // ignore: cast_nullable_to_non_nullable - as int, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_ListDownloadStatusCopyWith<$Res> - implements $ListDownloadStatusCopyWith<$Res> { - factory _$$_ListDownloadStatusCopyWith(_$_ListDownloadStatus value, - $Res Function(_$_ListDownloadStatus) then) = - __$$_ListDownloadStatusCopyWithImpl<$Res>; - @override - @useResult - $Res call({int total, int downloaded, int downloading}); -} - -/// @nodoc -class __$$_ListDownloadStatusCopyWithImpl<$Res> - extends _$ListDownloadStatusCopyWithImpl<$Res, _$_ListDownloadStatus> - implements _$$_ListDownloadStatusCopyWith<$Res> { - __$$_ListDownloadStatusCopyWithImpl( - _$_ListDownloadStatus _value, $Res Function(_$_ListDownloadStatus) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? total = null, - Object? downloaded = null, - Object? downloading = null, - }) { - return _then(_$_ListDownloadStatus( - total: null == total - ? _value.total - : total // ignore: cast_nullable_to_non_nullable - as int, - downloaded: null == downloaded - ? _value.downloaded - : downloaded // ignore: cast_nullable_to_non_nullable - as int, - downloading: null == downloading - ? _value.downloading - : downloading // ignore: cast_nullable_to_non_nullable - as int, - )); - } -} - -/// @nodoc - -class _$_ListDownloadStatus implements _ListDownloadStatus { - const _$_ListDownloadStatus( - {required this.total, - required this.downloaded, - required this.downloading}); - - @override - final int total; - @override - final int downloaded; - @override - final int downloading; - - @override - String toString() { - return 'ListDownloadStatus(total: $total, downloaded: $downloaded, downloading: $downloading)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_ListDownloadStatus && - (identical(other.total, total) || other.total == total) && - (identical(other.downloaded, downloaded) || - other.downloaded == downloaded) && - (identical(other.downloading, downloading) || - other.downloading == downloading)); - } - - @override - int get hashCode => Object.hash(runtimeType, total, downloaded, downloading); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_ListDownloadStatusCopyWith<_$_ListDownloadStatus> get copyWith => - __$$_ListDownloadStatusCopyWithImpl<_$_ListDownloadStatus>( - this, _$identity); -} - -abstract class _ListDownloadStatus implements ListDownloadStatus { - const factory _ListDownloadStatus( - {required final int total, - required final int downloaded, - required final int downloading}) = _$_ListDownloadStatus; - - @override - int get total; - @override - int get downloaded; - @override - int get downloading; - @override - @JsonKey(ignore: true) - _$$_ListDownloadStatusCopyWith<_$_ListDownloadStatus> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$MultiChoiceOption { - String get title => throw _privateConstructorUsedError; - @optionalTypeArgs - TResult when( - TResult Function(String title) $default, { - required TResult Function(String title, int option) int, - required TResult Function(String title, String option) string, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(String title)? $default, { - TResult? Function(String title, int option)? int, - TResult? Function(String title, String option)? string, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen( - TResult Function(String title)? $default, { - TResult Function(String title, int option)? int, - TResult Function(String title, String option)? string, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map( - TResult Function(_MultiChoiceOption value) $default, { - required TResult Function(_MultiChoiceOptionInt value) int, - required TResult Function(_MultiChoiceOptionString value) string, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_MultiChoiceOption value)? $default, { - TResult? Function(_MultiChoiceOptionInt value)? int, - TResult? Function(_MultiChoiceOptionString value)? string, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap( - TResult Function(_MultiChoiceOption value)? $default, { - TResult Function(_MultiChoiceOptionInt value)? int, - TResult Function(_MultiChoiceOptionString value)? string, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $MultiChoiceOptionCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $MultiChoiceOptionCopyWith<$Res> { - factory $MultiChoiceOptionCopyWith( - MultiChoiceOption value, $Res Function(MultiChoiceOption) then) = - _$MultiChoiceOptionCopyWithImpl<$Res, MultiChoiceOption>; - @useResult - $Res call({String title}); -} - -/// @nodoc -class _$MultiChoiceOptionCopyWithImpl<$Res, $Val extends MultiChoiceOption> - implements $MultiChoiceOptionCopyWith<$Res> { - _$MultiChoiceOptionCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? title = null, - }) { - return _then(_value.copyWith( - title: null == title - ? _value.title - : title // ignore: cast_nullable_to_non_nullable - as String, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_MultiChoiceOptionCopyWith<$Res> - implements $MultiChoiceOptionCopyWith<$Res> { - factory _$$_MultiChoiceOptionCopyWith(_$_MultiChoiceOption value, - $Res Function(_$_MultiChoiceOption) then) = - __$$_MultiChoiceOptionCopyWithImpl<$Res>; - @override - @useResult - $Res call({String title}); -} - -/// @nodoc -class __$$_MultiChoiceOptionCopyWithImpl<$Res> - extends _$MultiChoiceOptionCopyWithImpl<$Res, _$_MultiChoiceOption> - implements _$$_MultiChoiceOptionCopyWith<$Res> { - __$$_MultiChoiceOptionCopyWithImpl( - _$_MultiChoiceOption _value, $Res Function(_$_MultiChoiceOption) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? title = null, - }) { - return _then(_$_MultiChoiceOption( - title: null == title - ? _value.title - : title // ignore: cast_nullable_to_non_nullable - as String, - )); - } -} - -/// @nodoc - -class _$_MultiChoiceOption implements _MultiChoiceOption { - const _$_MultiChoiceOption({required this.title}); - - @override - final String title; - - @override - String toString() { - return 'MultiChoiceOption(title: $title)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_MultiChoiceOption && - (identical(other.title, title) || other.title == title)); - } - - @override - int get hashCode => Object.hash(runtimeType, title); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_MultiChoiceOptionCopyWith<_$_MultiChoiceOption> get copyWith => - __$$_MultiChoiceOptionCopyWithImpl<_$_MultiChoiceOption>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function(String title) $default, { - required TResult Function(String title, int option) int, - required TResult Function(String title, String option) string, - }) { - return $default(title); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(String title)? $default, { - TResult? Function(String title, int option)? int, - TResult? Function(String title, String option)? string, - }) { - return $default?.call(title); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function(String title)? $default, { - TResult Function(String title, int option)? int, - TResult Function(String title, String option)? string, - required TResult orElse(), - }) { - if ($default != null) { - return $default(title); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_MultiChoiceOption value) $default, { - required TResult Function(_MultiChoiceOptionInt value) int, - required TResult Function(_MultiChoiceOptionString value) string, - }) { - return $default(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_MultiChoiceOption value)? $default, { - TResult? Function(_MultiChoiceOptionInt value)? int, - TResult? Function(_MultiChoiceOptionString value)? string, - }) { - return $default?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_MultiChoiceOption value)? $default, { - TResult Function(_MultiChoiceOptionInt value)? int, - TResult Function(_MultiChoiceOptionString value)? string, - required TResult orElse(), - }) { - if ($default != null) { - return $default(this); - } - return orElse(); - } -} - -abstract class _MultiChoiceOption implements MultiChoiceOption { - const factory _MultiChoiceOption({required final String title}) = - _$_MultiChoiceOption; - - @override - String get title; - @override - @JsonKey(ignore: true) - _$$_MultiChoiceOptionCopyWith<_$_MultiChoiceOption> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$_MultiChoiceOptionIntCopyWith<$Res> - implements $MultiChoiceOptionCopyWith<$Res> { - factory _$$_MultiChoiceOptionIntCopyWith(_$_MultiChoiceOptionInt value, - $Res Function(_$_MultiChoiceOptionInt) then) = - __$$_MultiChoiceOptionIntCopyWithImpl<$Res>; - @override - @useResult - $Res call({String title, int option}); -} - -/// @nodoc -class __$$_MultiChoiceOptionIntCopyWithImpl<$Res> - extends _$MultiChoiceOptionCopyWithImpl<$Res, _$_MultiChoiceOptionInt> - implements _$$_MultiChoiceOptionIntCopyWith<$Res> { - __$$_MultiChoiceOptionIntCopyWithImpl(_$_MultiChoiceOptionInt _value, - $Res Function(_$_MultiChoiceOptionInt) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? title = null, - Object? option = null, - }) { - return _then(_$_MultiChoiceOptionInt( - title: null == title - ? _value.title - : title // ignore: cast_nullable_to_non_nullable - as String, - option: null == option - ? _value.option - : option // ignore: cast_nullable_to_non_nullable - as int, - )); - } -} - -/// @nodoc - -class _$_MultiChoiceOptionInt implements _MultiChoiceOptionInt { - _$_MultiChoiceOptionInt({required this.title, required this.option}); - - @override - final String title; - @override - final int option; - - @override - String toString() { - return 'MultiChoiceOption.int(title: $title, option: $option)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_MultiChoiceOptionInt && - (identical(other.title, title) || other.title == title) && - (identical(other.option, option) || other.option == option)); - } - - @override - int get hashCode => Object.hash(runtimeType, title, option); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_MultiChoiceOptionIntCopyWith<_$_MultiChoiceOptionInt> get copyWith => - __$$_MultiChoiceOptionIntCopyWithImpl<_$_MultiChoiceOptionInt>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function(String title) $default, { - required TResult Function(String title, int option) int, - required TResult Function(String title, String option) string, - }) { - return int(title, option); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(String title)? $default, { - TResult? Function(String title, int option)? int, - TResult? Function(String title, String option)? string, - }) { - return int?.call(title, option); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function(String title)? $default, { - TResult Function(String title, int option)? int, - TResult Function(String title, String option)? string, - required TResult orElse(), - }) { - if (int != null) { - return int(title, option); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_MultiChoiceOption value) $default, { - required TResult Function(_MultiChoiceOptionInt value) int, - required TResult Function(_MultiChoiceOptionString value) string, - }) { - return int(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_MultiChoiceOption value)? $default, { - TResult? Function(_MultiChoiceOptionInt value)? int, - TResult? Function(_MultiChoiceOptionString value)? string, - }) { - return int?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_MultiChoiceOption value)? $default, { - TResult Function(_MultiChoiceOptionInt value)? int, - TResult Function(_MultiChoiceOptionString value)? string, - required TResult orElse(), - }) { - if (int != null) { - return int(this); - } - return orElse(); - } -} - -abstract class _MultiChoiceOptionInt implements MultiChoiceOption { - factory _MultiChoiceOptionInt( - {required final String title, - required final int option}) = _$_MultiChoiceOptionInt; - - @override - String get title; - int get option; - @override - @JsonKey(ignore: true) - _$$_MultiChoiceOptionIntCopyWith<_$_MultiChoiceOptionInt> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$_MultiChoiceOptionStringCopyWith<$Res> - implements $MultiChoiceOptionCopyWith<$Res> { - factory _$$_MultiChoiceOptionStringCopyWith(_$_MultiChoiceOptionString value, - $Res Function(_$_MultiChoiceOptionString) then) = - __$$_MultiChoiceOptionStringCopyWithImpl<$Res>; - @override - @useResult - $Res call({String title, String option}); -} - -/// @nodoc -class __$$_MultiChoiceOptionStringCopyWithImpl<$Res> - extends _$MultiChoiceOptionCopyWithImpl<$Res, _$_MultiChoiceOptionString> - implements _$$_MultiChoiceOptionStringCopyWith<$Res> { - __$$_MultiChoiceOptionStringCopyWithImpl(_$_MultiChoiceOptionString _value, - $Res Function(_$_MultiChoiceOptionString) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? title = null, - Object? option = null, - }) { - return _then(_$_MultiChoiceOptionString( - title: null == title - ? _value.title - : title // ignore: cast_nullable_to_non_nullable - as String, - option: null == option - ? _value.option - : option // ignore: cast_nullable_to_non_nullable - as String, - )); - } -} - -/// @nodoc - -class _$_MultiChoiceOptionString implements _MultiChoiceOptionString { - _$_MultiChoiceOptionString({required this.title, required this.option}); - - @override - final String title; - @override - final String option; - - @override - String toString() { - return 'MultiChoiceOption.string(title: $title, option: $option)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_MultiChoiceOptionString && - (identical(other.title, title) || other.title == title) && - (identical(other.option, option) || other.option == option)); - } - - @override - int get hashCode => Object.hash(runtimeType, title, option); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_MultiChoiceOptionStringCopyWith<_$_MultiChoiceOptionString> - get copyWith => - __$$_MultiChoiceOptionStringCopyWithImpl<_$_MultiChoiceOptionString>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function(String title) $default, { - required TResult Function(String title, int option) int, - required TResult Function(String title, String option) string, - }) { - return string(title, option); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function(String title)? $default, { - TResult? Function(String title, int option)? int, - TResult? Function(String title, String option)? string, - }) { - return string?.call(title, option); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function(String title)? $default, { - TResult Function(String title, int option)? int, - TResult Function(String title, String option)? string, - required TResult orElse(), - }) { - if (string != null) { - return string(title, option); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(_MultiChoiceOption value) $default, { - required TResult Function(_MultiChoiceOptionInt value) int, - required TResult Function(_MultiChoiceOptionString value) string, - }) { - return string(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(_MultiChoiceOption value)? $default, { - TResult? Function(_MultiChoiceOptionInt value)? int, - TResult? Function(_MultiChoiceOptionString value)? string, - }) { - return string?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(_MultiChoiceOption value)? $default, { - TResult Function(_MultiChoiceOptionInt value)? int, - TResult Function(_MultiChoiceOptionString value)? string, - required TResult orElse(), - }) { - if (string != null) { - return string(this); - } - return orElse(); - } -} - -abstract class _MultiChoiceOptionString implements MultiChoiceOption { - factory _MultiChoiceOptionString( - {required final String title, - required final String option}) = _$_MultiChoiceOptionString; - - @override - String get title; - String get option; - @override - @JsonKey(ignore: true) - _$$_MultiChoiceOptionStringCopyWith<_$_MultiChoiceOptionString> - get copyWith => throw _privateConstructorUsedError; -} diff --git a/lib/models/support.g.dart b/lib/models/support.g.dart deleted file mode 100644 index e0dbf0e3..00000000 --- a/lib/models/support.g.dart +++ /dev/null @@ -1,83 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'support.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -_$_QueueItemState _$$_QueueItemStateFromJson(Map json) => - _$_QueueItemState( - id: json['id'] as String, - contextType: $enumDecode(_$QueueContextTypeEnumMap, json['contextType']), - contextId: json['contextId'] as String?, - contextTitle: json['contextTitle'] as String?, - ); - -Map _$$_QueueItemStateToJson(_$_QueueItemState instance) => - { - 'id': instance.id, - 'contextType': _$QueueContextTypeEnumMap[instance.contextType]!, - 'contextId': instance.contextId, - 'contextTitle': instance.contextTitle, - }; - -const _$QueueContextTypeEnumMap = { - QueueContextType.song: 'song', - QueueContextType.album: 'album', - QueueContextType.playlist: 'playlist', - QueueContextType.library: 'library', - QueueContextType.genre: 'genre', - QueueContextType.artist: 'artist', -}; - -_$_MediaItemData _$$_MediaItemDataFromJson(Map json) => - _$_MediaItemData( - sourceId: json['sourceId'] as int, - albumId: json['albumId'] as String?, - artCache: - _$JsonConverterFromJson, MediaItemArtCache>( - json['artCache'], const MediaItemArtCacheConverter().fromJson), - contextType: $enumDecode(_$QueueContextTypeEnumMap, json['contextType']), - contextId: json['contextId'] as String?, - ); - -Map _$$_MediaItemDataToJson(_$_MediaItemData instance) => - { - 'sourceId': instance.sourceId, - 'albumId': instance.albumId, - 'artCache': - _$JsonConverterToJson, MediaItemArtCache>( - instance.artCache, const MediaItemArtCacheConverter().toJson), - 'contextType': _$QueueContextTypeEnumMap[instance.contextType]!, - 'contextId': instance.contextId, - }; - -Value? _$JsonConverterFromJson( - Object? json, - Value? Function(Json json) fromJson, -) => - json == null ? null : fromJson(json as Json); - -Json? _$JsonConverterToJson( - Value? value, - Json? Function(Value value) toJson, -) => - value == null ? null : toJson(value); - -_$_MediaItemArtCache _$$_MediaItemArtCacheFromJson(Map json) => - _$_MediaItemArtCache( - fullArtUri: Uri.parse(json['fullArtUri'] as String), - fullArtCacheKey: json['fullArtCacheKey'] as String, - thumbnailArtUri: Uri.parse(json['thumbnailArtUri'] as String), - thumbnailArtCacheKey: json['thumbnailArtCacheKey'] as String, - ); - -Map _$$_MediaItemArtCacheToJson( - _$_MediaItemArtCache instance) => - { - 'fullArtUri': instance.fullArtUri.toString(), - 'fullArtCacheKey': instance.fullArtCacheKey, - 'thumbnailArtUri': instance.thumbnailArtUri.toString(), - 'thumbnailArtCacheKey': instance.thumbnailArtCacheKey, - }; diff --git a/lib/services/audio_service.dart b/lib/services/audio_service.dart deleted file mode 100644 index 8a8ce808..00000000 --- a/lib/services/audio_service.dart +++ /dev/null @@ -1,703 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:audio_service/audio_service.dart'; -import 'package:collection/collection.dart'; -import 'package:drift/drift.dart' show Value; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:just_audio/just_audio.dart'; -import 'package:pool/pool.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; -import 'package:rxdart/rxdart.dart'; -import 'package:synchronized/synchronized.dart'; - -import '../cache/image_cache.dart'; -import '../database/database.dart'; -import '../log.dart'; -import '../models/music.dart'; -import '../models/query.dart'; -import '../models/support.dart'; -import '../sources/music_source.dart'; -import '../state/settings.dart'; -import 'cache_service.dart'; -import 'settings_service.dart'; - -part 'audio_service.g.dart'; - -class QueueSourceItem { - final MediaItem mediaItem; - final UriAudioSource audioSource; - final QueueData queueData; - - const QueueSourceItem({ - required this.mediaItem, - required this.audioSource, - required this.queueData, - }); -} - -class QueueSlice { - final QueueSourceItem? prev; - final QueueSourceItem? current; - final QueueSourceItem? next; - - const QueueSlice(this.prev, this.current, this.next); -} - -@Riverpod(keepAlive: true) -FutureOr audioControlInit(AudioControlInitRef ref) async { - final imageCache = ref.watch(imageCacheProvider); - - return AudioService.init( - builder: () => AudioControl(AudioPlayer(), ref), - config: const AudioServiceConfig( - androidNotificationChannelId: 'com.subtracks2.channel.audio', - androidNotificationChannelName: 'Music playback', - androidNotificationIcon: 'drawable/ic_stat_name', - ), - cacheManager: imageCache, - cacheKeyResolver: (mediaItem) => - mediaItem.data.artCache?.thumbnailArtCacheKey ?? '', - ); -} - -@Riverpod(keepAlive: true) -AudioControl audioControl(AudioControlRef ref) { - return ref.watch(audioControlInitProvider).requireValue; -} - -class AudioControl extends BaseAudioHandler with QueueHandler, SeekHandler { - static const radioLength = 10; - - Stream get position => _player.positionStream; - - BehaviorSubject queueMode = BehaviorSubject.seeded(QueueMode.user); - BehaviorSubject?> shuffleIndicies = BehaviorSubject.seeded(null); - BehaviorSubject repeatMode = - BehaviorSubject.seeded(AudioServiceRepeatMode.none); - - final Ref _ref; - final AudioPlayer _player; - - int? _queueLength; - int? _previousCurrentTrackIndex; - - final _syncPool = Pool(1); - final _playLock = Lock(); - final _currentIndexIgnore = [null, 0]; - - final ConcatenatingAudioSource _audioSource = - ConcatenatingAudioSource(children: []); - - SubtracksDatabase get _db => _ref.read(databaseProvider); - CacheService get _cache => _ref.read(cacheServiceProvider); - MusicSource get _source => _ref.read(musicSourceProvider); - int get _sourceId => _ref.read(sourceIdProvider); - - AudioControl(this._player, this._ref) { - _player.playbackEventStream.listen((PlaybackEvent event) { - final playing = _player.playing; - playbackState.add(playbackState.value.copyWith( - controls: [ - MediaControl.skipToPrevious, - if (playing) MediaControl.pause else MediaControl.play, - MediaControl.stop, - MediaControl.skipToNext, - ], - systemActions: const { - MediaAction.seek, - }, - androidCompactActionIndices: const [0, 1, 3], - processingState: const { - ProcessingState.idle: AudioProcessingState.idle, - ProcessingState.loading: AudioProcessingState.loading, - ProcessingState.buffering: AudioProcessingState.buffering, - ProcessingState.ready: AudioProcessingState.ready, - ProcessingState.completed: AudioProcessingState.completed, - }[_player.processingState]!, - playing: playing, - updatePosition: _player.position, - bufferedPosition: _player.bufferedPosition, - queueIndex: event.currentIndex, - )); - }); - - _player.playbackEventStream.doOnError((e, st) async { - log.warning('playbackEventStream', e, st); - }); - - shuffleIndicies.listen((value) { - playbackState.add(playbackState.value.copyWith( - shuffleMode: value != null - ? AudioServiceShuffleMode.all - : AudioServiceShuffleMode.none, - )); - }); - - repeatMode.listen((value) { - playbackState.add(playbackState.value.copyWith(repeatMode: value)); - }); - - _player.processingStateStream.listen((event) async { - if (event == ProcessingState.completed) { - if (_audioSource.length > 0) { - log.fine('completed'); - await stop(); - await seek(Duration.zero); - } - } - }); - - _ref.listen(sourceIdProvider, (_, __) async { - await _clearAudioSource(true); - await _db.clearQueue(); - }); - - _ref.listen(maxBitrateProvider, (prev, next) async { - if (prev?.valueOrNull != next.valueOrNull) { - await _resyncQueue(true); - } - }); - - _ref.listen( - settingsServiceProvider.select((value) => value.app.streamFormat), - (prev, next) async { - await _resyncQueue(true); - }); - - _player.durationStream.listen((duration) { - if (mediaItem.valueOrNull == null) return; - - final index = queue.valueOrNull?.indexOf(mediaItem.value!); - - final updated = mediaItem.value!.copyWith(duration: duration); - mediaItem.add(updated); - - if (index != null) { - queue.add(queue.value..replaceRange(index, index + 1, [updated])); - } - }); - - _player.currentIndexStream.listen((index) async { - if (_currentIndexIgnore.contains(index)) { - _currentIndexIgnore.remove(index); - return; - } - if (index == null || index >= _audioSource.sequence.length) return; - - final queueIndex = _audioSource.sequence[index].tag; - if (queueIndex != null) { - await _db.setCurrentTrack(queueIndex); - } - }); - - _db.currentTrackIndex().watchSingleOrNull().listen((index) { - // distict() except for when in loop one mode - if (repeatMode.value != AudioServiceRepeatMode.one && - _previousCurrentTrackIndex == index) { - return; - } - - _previousCurrentTrackIndex = index; - _syncPool.withResource(() => _syncQueue(index)); - }); - } - - Future init() async { - await _player.setAudioSource(_audioSource, preload: false); - - final last = await _db.getLastAudioState().getSingleOrNull(); - if (last == null) return; - - _queueLength = await _db.queueLength().getSingleOrNull(); - final repeat = { - RepeatMode.none: AudioServiceRepeatMode.none, - RepeatMode.all: AudioServiceRepeatMode.all, - RepeatMode.one: AudioServiceRepeatMode.one, - }[last.repeat]!; - repeatMode.add(repeat); - await repeatMode.firstWhere((e) => e == repeat); - - queueMode.add(last.queueMode); - await queueMode.firstWhere((e) => e == last.queueMode); - - if (last.shuffleIndicies != null) { - final indicies = last.shuffleIndicies!.unlock; - shuffleIndicies.add(indicies); - await shuffleIndicies.firstWhere((e) => e == indicies); - } - - final startIndex = await _db.currentTrackIndex().getSingleOrNull(); - - if (startIndex != null && _queueLength != null) { - await _preparePlayer(startIndex); - } - } - - Future playSongs({ - QueueMode mode = QueueMode.user, - required QueueContextType context, - String? contextId, - required ListQuery query, - required FutureOr> Function(ListQuery query) getSongs, - int? startIndex, - bool? shuffle, - }) async { - if (!_playLock.locked) { - return _playLock.synchronized( - () => _playSongs( - mode: mode, - context: context, - contextId: contextId, - query: query, - getSongs: getSongs, - startIndex: startIndex, - shuffle: shuffle, - ), - ); - } - } - - Future playRadio({ - required QueueContextType context, - String? contextId, - ListQuery query = const ListQuery(), - required FutureOr> Function(ListQuery query) getSongs, - }) async { - await playSongs( - mode: QueueMode.radio, - context: QueueContextType.library, - contextId: contextId, - query: query.copyWith( - sort: SortBy( - column: 'SIN(songs.ROWID + ${Random().nextInt(10000)})', - ), - ), - getSongs: getSongs, - startIndex: 0, - ); - } - - Future _playSongs({ - QueueMode mode = QueueMode.user, - required QueueContextType context, - String? contextId, - required ListQuery query, - required FutureOr> Function(ListQuery query) getSongs, - int? startIndex, - bool? shuffle, - }) async { - shuffle = shuffle ?? shuffleIndicies.valueOrNull != null; - queueMode.add(mode); - - if (mode == QueueMode.radio) { - if (repeatMode.value != AudioServiceRepeatMode.none) { - await _loop(AudioServiceRepeatMode.none); - } - if (shuffleIndicies.value != null) { - await _shuffle(unshuffle: true); - } - } - - await _clearAudioSource(); - - const limit = 500; - _queueLength = 0; - - if ((startIndex == null || startIndex >= limit) && shuffle) { - startIndex = Random().nextInt(limit); - } else { - startIndex ??= 0; - } - - // clear the queue and load the initial songs only up to the startIndex - await _db.transaction(() async { - await _db.clearQueue(); - - while (_queueLength! <= startIndex!) { - final songs = await getSongs(query.copyWith( - page: Pagination(limit: limit, offset: _queueLength!), - )); - await _loadQueueSongs(songs, _queueLength!, context, contextId); - if (songs.length < limit) { - break; - } - } - }); - - // if there are less songs than the limit and we're shuffling, - // choose a new random startIndex - if (startIndex >= _queueLength!) { - startIndex = Random().nextInt(_queueLength!); - } - - await _preparePlayer(startIndex, shuffle); - await _db.setCurrentTrack(startIndex); - play(); - - const maxLength = 10000; - - // no need to do extra loading if we've already loaded everything - if (_queueLength! < limit) return; - while (true) { - final songs = await getSongs(query.copyWith( - page: Pagination(limit: limit, offset: _queueLength!), - )); - await _loadQueueSongs(songs, _queueLength!, context, contextId); - if (songs.length < limit || _queueLength! >= maxLength) { - break; - } - } - } - - Future _loadQueueSongs( - Iterable songs, - int total, - QueueContextType context, - String? contextId, - ) async { - await _db.insertQueue(songs.mapIndexed( - (i, song) => QueueCompanion.insert( - index: Value(i + (_queueLength ?? 0)), - sourceId: song.sourceId, - id: song.id, - context: context, - contextId: Value(contextId), - ), - )); - - _queueLength = (_queueLength ?? 0) + songs.length; - if (shuffleIndicies.valueOrNull != null) { - await _generateShuffleIndicies(startIndex: _player.currentIndex); - } - } - - Future _preparePlayer(int startIndex, [bool? shuffle]) async { - if (shuffle == true) { - await _shuffle(startIndex: startIndex); - } else if (shuffle == false) { - await _shuffle(unshuffle: true); - } - - final slice = await _getQueueSlice(startIndex); - if (slice == null) { - throw StateError('Could not get queue slice!'); - } - - final list = - [slice.prev, slice.current, slice.next].whereNotNull().toList(); - - mediaItem.add(slice.current!.mediaItem); - queue.add(list.map((e) => e.mediaItem).toList()); - - log.fine('addAll'); - await _audioSource.addAll(list.map((e) => e.audioSource).toList()); - await _player.seek(Duration.zero, index: list.indexOf(slice.current!)); - } - - Future _syncQueue(int? index) async { - if (index == null || _queueLength == null) return; - - final slice = await _getQueueSlice(index); - if (slice == null || slice.current == null) return; - - mediaItem.add(slice.current!.mediaItem); - queue.add( - [slice.prev, slice.current, slice.next] - .map((e) => e?.mediaItem) - .whereNotNull() - .toList(), - ); - - final sourceIndex = _player.currentIndex; - final sourceNeedsNext = sourceIndex == _audioSource.length - 1; - final sourceNeedsPrev = sourceIndex == 0; - - if (sourceNeedsNext && slice.next != null) { - log.fine('add'); - await _audioSource.add(slice.next!.audioSource); - } - if (sourceNeedsPrev && slice.prev != null) { - await _insertFirstAudioSource(slice.prev!.audioSource); - } - } - - Future _loop(AudioServiceRepeatMode mode) async { - repeatMode.add(mode); - await repeatMode.firstWhere((e) => e == mode); - - await _resyncQueue(); - } - - Future _generateShuffleIndicies({ - bool unshuffle = false, - int? startIndex, - }) async { - final indicies = unshuffle - ? null - : (List.generate(_queueLength!, (i) => i + 1) - ..insert(0, 0) - ..removeLast() - ..shuffle()); - - if (indicies != null && startIndex != null) { - indicies.removeAt(indicies.indexOf(startIndex)); - indicies.insert(0, startIndex); - } - shuffleIndicies.add(indicies); - await shuffleIndicies.firstWhere((e) => e == indicies); - } - - Future _shuffle({bool unshuffle = false, int? startIndex}) async { - await _generateShuffleIndicies( - unshuffle: unshuffle, - startIndex: startIndex, - ); - - await _resyncQueue(); - } - - Future _resyncQueue([bool reloadCurrent = false]) async { - return _syncPool.withResource(() async { - final currentSource = - _player.sequenceState?.currentSource as UriAudioSource?; - if (currentSource == null) return; - - final currentSourceIndex = _player.sequence!.indexOf(currentSource); - await _pruneAudioSources(currentSourceIndex); - - if (reloadCurrent && !currentSource.uri.isScheme('file')) { - final position = _player.position; - - final item = (await _getQueueItems([currentSource.tag]))[0]; - - await _audioSource.clear(); - await _audioSource.add(item.audioSource); - await seek(position); - } - - await _syncQueue(currentSource.tag); - }); - } - - int _realIndex(int index) { - if (shuffleIndicies.valueOrNull == null) { - return index; - } - - if (index < 0 || index >= shuffleIndicies.value!.length) { - return -1; - } - - return shuffleIndicies.value![index]; - } - - int _effectiveIndex(int index) { - if (shuffleIndicies.valueOrNull == null) { - return index; - } - - return shuffleIndicies.value!.indexOf(index); - } - - Future _insertFirstAudioSource(AudioSource source) { - log.fine('insert'); - final wait = _audioSource.insert(0, source); - _currentIndexIgnore.add(1); - return wait; - } - - Future _pruneAudioSources(int keepIndex) async { - if (keepIndex > 0) { - log.fine('removeRange 0'); - final wait = _audioSource.removeRange(0, keepIndex); - _currentIndexIgnore.add(0); - await wait; - } - if (_audioSource.length > 1) { - log.fine('removeRange 1'); - await _audioSource.removeRange(1, _audioSource.length); - } - } - - Future _clearAudioSource([bool clearMetadata = false]) async { - // await _player.stop(); - log.fine('_clearAudioSource'); - await _audioSource.clear(); - - if (clearMetadata) { - mediaItem.add(null); - queue.add([]); - queueTitle.add(''); - } - } - - Future _getQueueSlice(int index) async { - if (_queueLength == null) { - return null; - } - - final effectiveIndex = _effectiveIndex(index); - - int nextIndex; - int prevIndex; - if (repeatMode.value == AudioServiceRepeatMode.none) { - nextIndex = _realIndex(effectiveIndex + 1); - prevIndex = _realIndex(effectiveIndex - 1); - } else if (repeatMode.value == AudioServiceRepeatMode.one) { - nextIndex = index; - prevIndex = index; - } else { - nextIndex = _realIndex( - effectiveIndex + 1 >= _queueLength! ? 0 : effectiveIndex + 1, - ); - prevIndex = _realIndex( - effectiveIndex - 1 < 0 ? _queueLength! - 1 : effectiveIndex - 1, - ); - } - - final slice = await _getQueueItems([prevIndex, index, nextIndex]); - final current = slice.firstWhereOrNull( - (e) => e.queueData.index == index, - ); - final next = slice.firstWhereOrNull((e) => e.queueData.index == nextIndex); - final prev = slice.firstWhereOrNull((e) => e.queueData.index == prevIndex); - - return QueueSlice(prev, current, next); - } - - Future> _getQueueItems(List indexes) async { - final slice = await _db.queueInIndicies(indexes).get(); - final songs = - await _db.songsInIds(_sourceId, slice.map((e) => e.id).toList()).get(); - final songMap = {for (var song in songs) song.id: song}; - - final albumIds = songs.map((e) => e.albumId).whereNotNull().toSet(); - final albums = await _db.albumsInIds(_sourceId, albumIds.toList()).get(); - final albumArtMap = { - for (var album in albums) album.id: _mapArtCache(album) - }; - - final queueItems = slice.map( - (item) => _mapSong( - songMap[item.id]!, - MediaItemData( - sourceId: item.sourceId, - contextType: item.context, - contextId: item.contextId, - artCache: albumArtMap[songMap[item.id]!.albumId], - ), - item, - ), - ); - - return queueItems.toList(); - } - - QueueSourceItem _mapSong(Song song, MediaItemData data, QueueData queueData) { - final item = MediaItem( - id: song.id, - title: song.title, - artist: song.artist, - album: song.album, - duration: song.duration, - artUri: data.artCache?.thumbnailArtUri ?? _cache.placeholderThumbImageUri, - extras: {}, - ); - item.data = data; - - return QueueSourceItem( - mediaItem: item, - audioSource: song.downloadFilePath != null - ? AudioSource.file(song.downloadFilePath!, tag: queueData.index) - : AudioSource.uri(_source.streamUri(song.id), tag: queueData.index), - queueData: queueData, - ); - } - - MediaItemArtCache _mapArtCache(Album album) { - final full = _cache.albumArt(album, thumbnail: false); - final thumbnail = _cache.albumArt(album, thumbnail: true); - return MediaItemArtCache( - fullArtUri: full.uri, - fullArtCacheKey: full.cacheKey, - thumbnailArtUri: thumbnail.uri, - thumbnailArtCacheKey: thumbnail.cacheKey, - ); - } - - /// - /// AudioHandler - /// - - @override - Future play() async { - await _player.play(); - } - - @override - Future pause() async { - await _player.pause(); - } - - @override - Future stop() async { - await _player.stop(); - } - - @override - Future seek(Duration position) async { - await _player.seek(position); - } - - @override - Future skipToNext() => _player.seekToNext(); - - @override - Future skipToPrevious() => _player.seekToPrevious(); - - @override - Future skipToQueueItem(int index) async { - if (_player.effectiveIndices == null || _player.effectiveIndices!.isEmpty) { - return; - } - - index = _player.effectiveIndices![index]; - if (index < 0 || index >= queue.value.length) { - return; - } - - await _player.seek(Duration.zero, index: index); - } - - @override - Future setRepeatMode(AudioServiceRepeatMode repeatMode) async { - if (queueMode.value == QueueMode.radio) { - switch (repeatMode) { - case AudioServiceRepeatMode.all: - case AudioServiceRepeatMode.group: - case AudioServiceRepeatMode.one: - return _loop(AudioServiceRepeatMode.one); - default: - return _loop(AudioServiceRepeatMode.none); - } - } - - return _loop(repeatMode); - } - - @override - Future setShuffleMode(AudioServiceShuffleMode shuffleMode) async { - if (queueMode.value == QueueMode.radio) { - return; - } - - switch (shuffleMode) { - case AudioServiceShuffleMode.all: - case AudioServiceShuffleMode.group: - return _shuffle(startIndex: _player.sequenceState?.currentSource?.tag); - case AudioServiceShuffleMode.none: - return _shuffle(unshuffle: true); - } - } -} diff --git a/lib/services/audio_service.g.dart b/lib/services/audio_service.g.dart deleted file mode 100644 index 34628974..00000000 --- a/lib/services/audio_service.g.dart +++ /dev/null @@ -1,38 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'audio_service.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$audioControlInitHash() => r'ecde06a9f4f7be5ca28e1f5f3c1f3e7fb2ce8dc5'; - -/// See also [audioControlInit]. -@ProviderFor(audioControlInit) -final audioControlInitProvider = FutureProvider.internal( - audioControlInit, - name: r'audioControlInitProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$audioControlInitHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef AudioControlInitRef = FutureProviderRef; -String _$audioControlHash() => r'ea50108f29366182238a5e68d6cdcd1d874e4ba2'; - -/// See also [audioControl]. -@ProviderFor(audioControl) -final audioControlProvider = Provider.internal( - audioControl, - name: r'audioControlProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$audioControlHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef AudioControlRef = ProviderRef; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/services/cache_service.dart b/lib/services/cache_service.dart deleted file mode 100644 index f9e231ba..00000000 --- a/lib/services/cache_service.dart +++ /dev/null @@ -1,112 +0,0 @@ -import 'package:flutter_cache_manager/flutter_cache_manager.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../cache/image_cache.dart'; -import '../models/music.dart'; -import '../models/support.dart'; -import '../sources/music_source.dart'; -import '../state/init.dart'; -import '../state/settings.dart'; - -part 'cache_service.g.dart'; - -String _cacheKey( - String type, - int sourceId, - String albumId, [ - bool thumbnail = false, -]) { - return '$type${thumbnail ? 'Thumb' : ''}-$sourceId-$albumId'; -} - -String albumArtCacheKey( - int sourceId, - String albumId, - bool thumbnail, -) { - return _cacheKey('albumArt', sourceId, albumId, thumbnail); -} - -String playlistArtCacheKey( - int sourceId, - String albumId, - bool thumbnail, -) { - return _cacheKey('playlistArt', sourceId, albumId, thumbnail); -} - -String artistArtCacheKey( - int sourceId, - String albumId, - bool thumbnail, -) { - return _cacheKey('artistArt', sourceId, albumId, thumbnail); -} - -@Riverpod(keepAlive: true) -CacheService cacheService(CacheServiceRef ref) { - final imageCache = ref.watch(imageCacheProvider); - final source = ref.watch(musicSourceProvider); - final placeholderImageUri = - ref.watch(placeholderImageUriProvider).requireValue; - final placeholderThumbImageUri = - ref.watch(placeholderThumbImageUriProvider).requireValue; - - return CacheService( - imageCache: imageCache, - source: source, - placeholderImageUri: placeholderImageUri, - placeholderThumbImageUri: placeholderThumbImageUri, - ); -} - -class CacheService { - final CacheManager imageCache; - final MusicSource source; - final Uri placeholderImageUri; - final Uri placeholderThumbImageUri; - - CacheService({ - required this.imageCache, - required this.source, - required this.placeholderImageUri, - required this.placeholderThumbImageUri, - }); - - UriCacheInfo albumArt(Album album, {bool thumbnail = true}) { - final id = album.coverArt ?? album.id; - return UriCacheInfo( - uri: source.coverArtUri(id, thumbnail: thumbnail), - cacheKey: albumArtCacheKey(source.id, album.id, thumbnail), - cacheManager: imageCache, - ); - } - - UriCacheInfo playlistArt(Playlist playlist, {bool thumbnail = true}) { - final id = playlist.coverArt ?? playlist.id; - return UriCacheInfo( - uri: source.coverArtUri(id), - cacheKey: playlistArtCacheKey(source.id, playlist.id, thumbnail), - cacheManager: imageCache); - } - - UriCacheInfo placeholder({bool thumbnail = true}) { - final uri = thumbnail ? placeholderThumbImageUri : placeholderImageUri; - return UriCacheInfo( - uri: uri, - cacheKey: uri.toString(), - cacheManager: imageCache, - ); - } - - Future artistArtUri(String artistId, {bool thumbnail = true}) { - return source.artistArtUri(artistId, thumbnail: thumbnail); - } - - CacheInfo artistArtCacheInfo(String artistId, {bool thumbnail = true}) { - return CacheInfo( - cacheKey: artistArtCacheKey(source.id, artistId, thumbnail), - cacheManager: imageCache, - ); - } -} diff --git a/lib/services/cache_service.g.dart b/lib/services/cache_service.g.dart deleted file mode 100644 index 7b6a2a91..00000000 --- a/lib/services/cache_service.g.dart +++ /dev/null @@ -1,23 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'cache_service.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$cacheServiceHash() => r'5e83011fbdfc5a962d43e3311b666dde2c455e24'; - -/// See also [cacheService]. -@ProviderFor(cacheService) -final cacheServiceProvider = Provider.internal( - cacheService, - name: r'cacheServiceProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$cacheServiceHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef CacheServiceRef = ProviderRef; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/services/download_service.dart b/lib/services/download_service.dart deleted file mode 100644 index 79559445..00000000 --- a/lib/services/download_service.dart +++ /dev/null @@ -1,589 +0,0 @@ -import 'dart:io'; -import 'dart:isolate'; -import 'dart:ui'; - -import 'package:collection/collection.dart'; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:flutter_downloader/flutter_downloader.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:mime/mime.dart'; -import 'package:path/path.dart' as path; -import 'package:path_provider/path_provider.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../database/database.dart'; -import '../http/client.dart'; -import '../models/music.dart'; -import '../models/query.dart'; -import '../models/support.dart'; -import '../state/music.dart'; -import '../state/settings.dart'; -import 'cache_service.dart'; - -part 'download_service.freezed.dart'; -part 'download_service.g.dart'; - -@freezed -class DownloadState with _$DownloadState { - const factory DownloadState({ - @Default(IListConst([])) IList downloads, - @Default(IListConst([])) IList deletes, - @Default(IListConst([])) IList listDownloads, - @Default(IListConst([])) IList listCancels, - required String saveDir, - }) = _DownloadState; -} - -@freezed -class Download with _$Download { - const Download._(); - - const factory Download({ - required String taskId, - required DownloadTaskStatus status, - required int progress, - required String url, - required String? filename, - required String savedDir, - required int timeCreated, - required bool allowCellular, - }) = _Download; - - factory Download.fromTask(DownloadTask task) { - return Download( - taskId: task.taskId, - status: task.status, - progress: task.progress, - url: task.url, - filename: task.filename, - savedDir: task.savedDir, - timeCreated: task.timeCreated, - allowCellular: task.allowCellular, - ); - } - - DownloadTask toTask() { - return DownloadTask( - taskId: taskId, - status: status, - progress: progress, - url: url, - filename: filename, - savedDir: savedDir, - timeCreated: timeCreated, - allowCellular: allowCellular, - ); - } -} - -enum SongDownloadState { - none, - inProgress, - completed, -} - -@Riverpod(keepAlive: true) -class DownloadService extends _$DownloadService { - static final ReceivePort _port = ReceivePort(); - - @override - DownloadState build() { - return const DownloadState(saveDir: ''); - } - - Future init() async { - await FlutterDownloader.initialize( - // debug: true, - ignoreSsl: true, - ); - - state = state.copyWith( - saveDir: path.join( - (await getApplicationDocumentsDirectory()).path, - 'downloads', - ), - ); - - _bindBackgroundIsolate(); - await _syncDownloadTasks(); - - FlutterDownloader.registerCallback(downloadCallback, step: 1); - } - - Future downloadAlbum(Album album) async { - return _downloadList(album, () async { - final cache = ref.read(cacheServiceProvider); - await Future.wait([ - _cacheArtistArt(album.sourceId, album.artistId, false), - _cacheArtistArt(album.sourceId, album.artistId, true), - _cacheImage(cache.albumArt(album, thumbnail: false)), - _cacheImage(cache.albumArt(album, thumbnail: true)), - ]); - if (_isCanceled(album)) return; - - final songs = await _albumSongs(album, SongDownloadState.none); - if (_isCanceled(album)) return; - - for (var song in songs) { - await _downloadSong(song); - if (_isCanceled(album)) return; - } - }); - } - - Future downloadPlaylist(Playlist playlist) async { - return _downloadList(playlist, () async { - final songs = await _playlistSongs(playlist, SongDownloadState.none); - if (_isCanceled(playlist)) return; - - final albumIds = songs.map((e) => e.albumId).whereNotNull().toSet(); - final albums = - await ref.read(albumsInIdsProvider(albumIds.toIList()).future); - final artistIds = albums.map((e) => e.artistId).whereNotNull().toSet(); - - final cache = ref.read(cacheServiceProvider); - await Future.wait([ - _cacheImage(cache.playlistArt(playlist, thumbnail: true)), - _cacheImage(cache.playlistArt(playlist, thumbnail: false)), - ...albums.map((a) => _cacheImage(cache.albumArt(a, thumbnail: true))), - ...albums.map((a) => _cacheImage(cache.albumArt(a, thumbnail: false))), - ...artistIds.map( - (artistId) => _cacheArtistArt(playlist.sourceId, artistId, true), - ), - ...artistIds.map( - (artistId) => _cacheArtistArt(playlist.sourceId, artistId, false), - ), - ]); - if (_isCanceled(playlist)) return; - - for (var song in songs) { - await _downloadSong(song); - if (_isCanceled(playlist)) return; - } - }); - } - - Future cancelAlbum(Album album) async { - return _cancelList(album, () async { - final songs = await _albumSongs(album, SongDownloadState.inProgress); - for (var song in songs) { - try { - await FlutterDownloader.cancel(taskId: song.downloadTaskId!); - } catch (e) { - // - } - } - }); - } - - Future cancelPlaylist(Playlist playlist) async { - return _cancelList(playlist, () async { - final songs = - await _playlistSongs(playlist, SongDownloadState.inProgress); - for (var song in songs) { - await FlutterDownloader.cancel(taskId: song.downloadTaskId!); - } - }); - } - - Future deleteAlbum(Album album) async { - return _deleteList(album, () async { - final db = ref.read(databaseProvider); - final songs = await _albumSongs(album, SongDownloadState.completed); - - for (var song in songs) { - await _tryDeleteFile(song.downloadFilePath!); - await db.deleteSongDownloadFile(song.sourceId, song.id); - } - }); - } - - Future deletePlaylist(Playlist playlist) async { - return _deleteList(playlist, () async { - final db = ref.read(databaseProvider); - final songs = await _playlistSongs(playlist, SongDownloadState.completed); - - for (var song in songs) { - if (await _tryDeleteFile(song.downloadFilePath!)) { - await db.deleteSongDownloadFile(song.sourceId, song.id); - } - } - }); - } - - Future deleteAll(int sourceId) async { - final db = ref.read(databaseProvider); - - final albumIds = await db.albumIdsWithDownloadStatus(sourceId).get(); - for (var id in albumIds) { - await deleteAlbum(await (db.albumById(sourceId, id)).getSingle()); - } - } - - Future _downloadList( - SourceIdentifiable list, - Future Function() callback, - ) async { - final sourceId = SourceId.from(list); - if (state.listDownloads.contains(sourceId)) { - return; - } - state = state.copyWith(listDownloads: state.listDownloads.add(sourceId)); - - try { - await callback(); - } finally { - state = state.copyWith( - listDownloads: state.listDownloads.remove(sourceId), - ); - } - } - - Future _cancelList( - SourceIdentifiable list, - Future Function() callback, - ) async { - final sourceId = SourceId.from(list); - if (state.listCancels.contains(sourceId)) return; - state = state.copyWith( - listCancels: state.listCancels.add(sourceId), - ); - - if (state.listDownloads.contains(sourceId)) { - var tries = 0; - while (tries < 60) { - await Future.delayed(const Duration(seconds: 1)); - if (!state.listDownloads.contains(sourceId)) { - break; - } - } - } - - try { - await callback(); - } finally { - state = state.copyWith( - listCancels: state.listCancels.remove(sourceId), - ); - } - } - - Future _deleteList( - SourceIdentifiable list, - Future Function() callback, - ) async { - final sourceId = SourceId.from(list); - if (state.deletes.contains(sourceId)) { - return; - } - state = state.copyWith(deletes: state.deletes.add(sourceId)); - - try { - await callback(); - } finally { - state = state.copyWith(deletes: state.deletes.remove(sourceId)); - } - } - - Future _downloadSong(Song song) async { - if (song.downloadFilePath != null || song.downloadTaskId != null) { - return; - } - - final source = ref.read(musicSourceProvider); - final db = ref.read(databaseProvider); - final http = ref.read(httpClientProvider); - - final uri = source.downloadUri(song.id); - final head = await http.head(uri); - - final contentType = head.headers['content-type']; - if (contentType == null) { - throw StateError('Bad HTTP response from HEAD during download'); - } - - final mime = contentType.split(';').first.toLowerCase(); - if (!mime.startsWith('audio') && !mime.startsWith('application')) { - throw StateError('Download error: MIME-type $mime is not audio'); - } - - String? ext = extensionFromMime(mime); - if (ext == mime) { - ext = null; - } - - final saveDir = Directory( - path.join(state.saveDir, song.sourceId.toString()), - ); - await saveDir.create(recursive: true); - - final taskId = await FlutterDownloader.enqueue( - url: source.downloadUri(song.id).toString(), - savedDir: saveDir.path, - fileName: ext != null ? '${song.id}.$ext' : song.id, - headers: subtracksHeaders, - openFileFromNotification: false, - showNotification: false, - ); - await db.updateSongDownloadTask(taskId, song.sourceId, song.id); - } - - Future _cacheImage(UriCacheInfo cache) async { - final cachedFile = await cache.cacheManager.getFileFromCache( - cache.cacheKey, - ignoreMemCache: true, - ); - if (cachedFile == null) { - try { - await cache.cacheManager.getSingleFile( - cache.uri.toString(), - key: cache.cacheKey, - ); - } catch (_) {} - } - } - - Future _cacheArtistArt( - int sourceId, - String? artistId, - bool thumbnail, - ) async { - if (artistId == null) { - return; - } - - final cache = ref.read(cacheServiceProvider); - try { - final uri = await cache.artistArtUri(artistId, thumbnail: thumbnail); - if (uri == null) { - return; - } - - await _cacheImage(UriCacheInfo( - uri: uri, - cacheKey: - cache.artistArtCacheInfo(artistId, thumbnail: thumbnail).cacheKey, - cacheManager: cache.imageCache, - )); - } catch (_) {} - } - - bool _isCanceled(SourceIdentifiable item) { - return state.listCancels.contains(SourceId.from(item)); - } - - List _downloadFilters(SongDownloadState state) { - switch (state) { - case SongDownloadState.none: - return [ - const FilterWith.isNull(column: 'download_task_id'), - const FilterWith.isNull(column: 'download_file_path'), - ]; - case SongDownloadState.completed: - return [ - const FilterWith.isNull(column: 'download_file_path', invert: true), - ]; - case SongDownloadState.inProgress: - return [ - const FilterWith.isNull(column: 'download_task_id', invert: true), - ]; - } - } - - Future> _albumSongs( - Album album, - SongDownloadState state, - ) { - return ref - .read(databaseProvider) - .albumSongsList( - SourceId.from(album), - ListQuery( - sort: const SortBy(column: 'disc, track'), - filters: _downloadFilters(state).lock, - ), - ) - .get(); - } - - Future> _playlistSongs( - Playlist playlist, - SongDownloadState state, - ) { - return ref - .read(databaseProvider) - .playlistSongsList( - SourceId.from(playlist), - ListQuery( - sort: const SortBy(column: 'playlist_songs.position'), - filters: _downloadFilters(state).lock, - ), - ) - .get(); - } - - Future _syncDownloadTasks() async { - final tasks = await FlutterDownloader.loadTasks() ?? []; - final downloads = tasks.map((e) => Download.fromTask(e)).toIList(); - - state = state.copyWith(downloads: downloads); - - final db = ref.read(databaseProvider); - final songs = await db.songsWithDownloadTasks().get(); - - await _deleteTasksNotIn(songs.map((e) => e.downloadTaskId!).toList()); - - final deleteTaskStatus = [ - DownloadTaskStatus.canceled, - DownloadTaskStatus.failed, - DownloadTaskStatus.undefined, - ]; - - for (var song in songs) { - final download = downloads.firstWhereOrNull( - (t) => t.taskId == song.downloadTaskId, - ); - - if (download == null) { - await db.clearSongDownloadTaskBySong(song.sourceId, song.id); - continue; - } - - if (deleteTaskStatus.anyIs(download.status)) { - await _clearFailedDownload(download); - } else if (download.status == DownloadTaskStatus.complete) { - await _completeDownload(download); - } - } - } - - Future _tryDeleteFile(String filePath) async { - try { - final file = File(filePath); - await file.delete(); - return true; - } catch (_) { - return false; - } - } - - Future _deleteTasksNotIn(List taskIds) async { - if (taskIds.isEmpty) { - return; - } - await FlutterDownloader.loadTasksWithRawQuery( - query: 'DELETE FROM task WHERE task_id NOT IN ' - '(${taskIds.map((e) => "'$e'").join(',')})', - ); - } - - Future _deleteTask(String taskId) async { - await FlutterDownloader.loadTasksWithRawQuery( - query: 'DELETE FROM task WHERE task_id = \'$taskId\'', - ); - } - - Future _getTask(String taskId) async { - return (await FlutterDownloader.loadTasksWithRawQuery( - query: 'SELECT * FROM task WHERE task_id = \'$taskId\'', - )) - ?.firstOrNull; - } - - Future _completeDownload(Download download) async { - final db = ref.read(databaseProvider); - await db.completeSongDownload( - path.join(download.savedDir, download.filename), - download.taskId, - ); - await _deleteTask(download.taskId); - - state = state.copyWith( - downloads: state.downloads.removeWhere( - (d) => d.taskId == download.taskId, - ), - ); - } - - Future _clearFailedDownload(Download download) async { - final db = ref.read(databaseProvider); - await db.clearSongDownloadTask(download.taskId); - await _deleteTask(download.taskId); - await _tryDeleteFile(path.join(download.savedDir, download.filename)); - - state = state.copyWith( - downloads: state.downloads.removeWhere( - (d) => d.taskId == download.taskId, - ), - ); - } - - void _bindBackgroundIsolate([retry = 0]) { - final isSuccess = IsolateNameServer.registerPortWithName( - _port.sendPort, - 'downloader_send_port', - ); - - if (!isSuccess && retry < 100) { - _unbindBackgroundIsolate(); - _bindBackgroundIsolate(retry + 1); - return; - } else if (retry >= 100) { - throw StateError('Could not bind background isolate for downloads'); - } - - _port.asyncMap((dynamic data) async { - final taskId = (data as List)[0] as String; - final status = DownloadTaskStatus(data[1] as int); - final progress = data[2] as int; - - var download = state.downloads.firstWhereOrNull( - (task) => task.taskId == taskId, - ); - if (download == null) { - final task = await _getTask(taskId); - if (task == null) { - return; - } - download = Download.fromTask(task); - } - - download = download.copyWith(status: status, progress: progress); - - state = state.copyWith( - downloads: state.downloads.replaceFirstWhere( - (d) => d.taskId == taskId, - (d) => download!, - addIfNotFound: true, - ), - ); - - final deleteTaskStatus = [ - DownloadTaskStatus.canceled, - DownloadTaskStatus.failed, - DownloadTaskStatus.undefined, - ]; - - if (status == DownloadTaskStatus.complete) { - await _completeDownload(download); - } else if (deleteTaskStatus.anyIs(status)) { - await _clearFailedDownload(download); - } - }).listen((_) {}); - } - - void _unbindBackgroundIsolate() { - IsolateNameServer.removePortNameMapping('downloader_send_port'); - } - - @pragma('vm:entry-point') - static void downloadCallback( - String id, - DownloadTaskStatus status, - int progress, - ) { - IsolateNameServer.lookupPortByName('downloader_send_port')?.send( - [id, status.value, progress], - ); - } -} diff --git a/lib/services/download_service.freezed.dart b/lib/services/download_service.freezed.dart deleted file mode 100644 index 22528b08..00000000 --- a/lib/services/download_service.freezed.dart +++ /dev/null @@ -1,495 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark - -part of 'download_service.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -/// @nodoc -mixin _$DownloadState { - IList get downloads => throw _privateConstructorUsedError; - IList get deletes => throw _privateConstructorUsedError; - IList get listDownloads => throw _privateConstructorUsedError; - IList get listCancels => throw _privateConstructorUsedError; - String get saveDir => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $DownloadStateCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $DownloadStateCopyWith<$Res> { - factory $DownloadStateCopyWith( - DownloadState value, $Res Function(DownloadState) then) = - _$DownloadStateCopyWithImpl<$Res, DownloadState>; - @useResult - $Res call( - {IList downloads, - IList deletes, - IList listDownloads, - IList listCancels, - String saveDir}); -} - -/// @nodoc -class _$DownloadStateCopyWithImpl<$Res, $Val extends DownloadState> - implements $DownloadStateCopyWith<$Res> { - _$DownloadStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? downloads = null, - Object? deletes = null, - Object? listDownloads = null, - Object? listCancels = null, - Object? saveDir = null, - }) { - return _then(_value.copyWith( - downloads: null == downloads - ? _value.downloads - : downloads // ignore: cast_nullable_to_non_nullable - as IList, - deletes: null == deletes - ? _value.deletes - : deletes // ignore: cast_nullable_to_non_nullable - as IList, - listDownloads: null == listDownloads - ? _value.listDownloads - : listDownloads // ignore: cast_nullable_to_non_nullable - as IList, - listCancels: null == listCancels - ? _value.listCancels - : listCancels // ignore: cast_nullable_to_non_nullable - as IList, - saveDir: null == saveDir - ? _value.saveDir - : saveDir // ignore: cast_nullable_to_non_nullable - as String, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_DownloadStateCopyWith<$Res> - implements $DownloadStateCopyWith<$Res> { - factory _$$_DownloadStateCopyWith( - _$_DownloadState value, $Res Function(_$_DownloadState) then) = - __$$_DownloadStateCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {IList downloads, - IList deletes, - IList listDownloads, - IList listCancels, - String saveDir}); -} - -/// @nodoc -class __$$_DownloadStateCopyWithImpl<$Res> - extends _$DownloadStateCopyWithImpl<$Res, _$_DownloadState> - implements _$$_DownloadStateCopyWith<$Res> { - __$$_DownloadStateCopyWithImpl( - _$_DownloadState _value, $Res Function(_$_DownloadState) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? downloads = null, - Object? deletes = null, - Object? listDownloads = null, - Object? listCancels = null, - Object? saveDir = null, - }) { - return _then(_$_DownloadState( - downloads: null == downloads - ? _value.downloads - : downloads // ignore: cast_nullable_to_non_nullable - as IList, - deletes: null == deletes - ? _value.deletes - : deletes // ignore: cast_nullable_to_non_nullable - as IList, - listDownloads: null == listDownloads - ? _value.listDownloads - : listDownloads // ignore: cast_nullable_to_non_nullable - as IList, - listCancels: null == listCancels - ? _value.listCancels - : listCancels // ignore: cast_nullable_to_non_nullable - as IList, - saveDir: null == saveDir - ? _value.saveDir - : saveDir // ignore: cast_nullable_to_non_nullable - as String, - )); - } -} - -/// @nodoc - -class _$_DownloadState implements _DownloadState { - const _$_DownloadState( - {this.downloads = const IListConst([]), - this.deletes = const IListConst([]), - this.listDownloads = const IListConst([]), - this.listCancels = const IListConst([]), - required this.saveDir}); - - @override - @JsonKey() - final IList downloads; - @override - @JsonKey() - final IList deletes; - @override - @JsonKey() - final IList listDownloads; - @override - @JsonKey() - final IList listCancels; - @override - final String saveDir; - - @override - String toString() { - return 'DownloadState(downloads: $downloads, deletes: $deletes, listDownloads: $listDownloads, listCancels: $listCancels, saveDir: $saveDir)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_DownloadState && - const DeepCollectionEquality().equals(other.downloads, downloads) && - const DeepCollectionEquality().equals(other.deletes, deletes) && - const DeepCollectionEquality() - .equals(other.listDownloads, listDownloads) && - const DeepCollectionEquality() - .equals(other.listCancels, listCancels) && - (identical(other.saveDir, saveDir) || other.saveDir == saveDir)); - } - - @override - int get hashCode => Object.hash( - runtimeType, - const DeepCollectionEquality().hash(downloads), - const DeepCollectionEquality().hash(deletes), - const DeepCollectionEquality().hash(listDownloads), - const DeepCollectionEquality().hash(listCancels), - saveDir); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_DownloadStateCopyWith<_$_DownloadState> get copyWith => - __$$_DownloadStateCopyWithImpl<_$_DownloadState>(this, _$identity); -} - -abstract class _DownloadState implements DownloadState { - const factory _DownloadState( - {final IList downloads, - final IList deletes, - final IList listDownloads, - final IList listCancels, - required final String saveDir}) = _$_DownloadState; - - @override - IList get downloads; - @override - IList get deletes; - @override - IList get listDownloads; - @override - IList get listCancels; - @override - String get saveDir; - @override - @JsonKey(ignore: true) - _$$_DownloadStateCopyWith<_$_DownloadState> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$Download { - String get taskId => throw _privateConstructorUsedError; - DownloadTaskStatus get status => throw _privateConstructorUsedError; - int get progress => throw _privateConstructorUsedError; - String get url => throw _privateConstructorUsedError; - String? get filename => throw _privateConstructorUsedError; - String get savedDir => throw _privateConstructorUsedError; - int get timeCreated => throw _privateConstructorUsedError; - bool get allowCellular => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $DownloadCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $DownloadCopyWith<$Res> { - factory $DownloadCopyWith(Download value, $Res Function(Download) then) = - _$DownloadCopyWithImpl<$Res, Download>; - @useResult - $Res call( - {String taskId, - DownloadTaskStatus status, - int progress, - String url, - String? filename, - String savedDir, - int timeCreated, - bool allowCellular}); -} - -/// @nodoc -class _$DownloadCopyWithImpl<$Res, $Val extends Download> - implements $DownloadCopyWith<$Res> { - _$DownloadCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? taskId = null, - Object? status = null, - Object? progress = null, - Object? url = null, - Object? filename = freezed, - Object? savedDir = null, - Object? timeCreated = null, - Object? allowCellular = null, - }) { - return _then(_value.copyWith( - taskId: null == taskId - ? _value.taskId - : taskId // ignore: cast_nullable_to_non_nullable - as String, - status: null == status - ? _value.status - : status // ignore: cast_nullable_to_non_nullable - as DownloadTaskStatus, - progress: null == progress - ? _value.progress - : progress // ignore: cast_nullable_to_non_nullable - as int, - url: null == url - ? _value.url - : url // ignore: cast_nullable_to_non_nullable - as String, - filename: freezed == filename - ? _value.filename - : filename // ignore: cast_nullable_to_non_nullable - as String?, - savedDir: null == savedDir - ? _value.savedDir - : savedDir // ignore: cast_nullable_to_non_nullable - as String, - timeCreated: null == timeCreated - ? _value.timeCreated - : timeCreated // ignore: cast_nullable_to_non_nullable - as int, - allowCellular: null == allowCellular - ? _value.allowCellular - : allowCellular // ignore: cast_nullable_to_non_nullable - as bool, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$_DownloadCopyWith<$Res> implements $DownloadCopyWith<$Res> { - factory _$$_DownloadCopyWith( - _$_Download value, $Res Function(_$_Download) then) = - __$$_DownloadCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {String taskId, - DownloadTaskStatus status, - int progress, - String url, - String? filename, - String savedDir, - int timeCreated, - bool allowCellular}); -} - -/// @nodoc -class __$$_DownloadCopyWithImpl<$Res> - extends _$DownloadCopyWithImpl<$Res, _$_Download> - implements _$$_DownloadCopyWith<$Res> { - __$$_DownloadCopyWithImpl( - _$_Download _value, $Res Function(_$_Download) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? taskId = null, - Object? status = null, - Object? progress = null, - Object? url = null, - Object? filename = freezed, - Object? savedDir = null, - Object? timeCreated = null, - Object? allowCellular = null, - }) { - return _then(_$_Download( - taskId: null == taskId - ? _value.taskId - : taskId // ignore: cast_nullable_to_non_nullable - as String, - status: null == status - ? _value.status - : status // ignore: cast_nullable_to_non_nullable - as DownloadTaskStatus, - progress: null == progress - ? _value.progress - : progress // ignore: cast_nullable_to_non_nullable - as int, - url: null == url - ? _value.url - : url // ignore: cast_nullable_to_non_nullable - as String, - filename: freezed == filename - ? _value.filename - : filename // ignore: cast_nullable_to_non_nullable - as String?, - savedDir: null == savedDir - ? _value.savedDir - : savedDir // ignore: cast_nullable_to_non_nullable - as String, - timeCreated: null == timeCreated - ? _value.timeCreated - : timeCreated // ignore: cast_nullable_to_non_nullable - as int, - allowCellular: null == allowCellular - ? _value.allowCellular - : allowCellular // ignore: cast_nullable_to_non_nullable - as bool, - )); - } -} - -/// @nodoc - -class _$_Download extends _Download { - const _$_Download( - {required this.taskId, - required this.status, - required this.progress, - required this.url, - required this.filename, - required this.savedDir, - required this.timeCreated, - required this.allowCellular}) - : super._(); - - @override - final String taskId; - @override - final DownloadTaskStatus status; - @override - final int progress; - @override - final String url; - @override - final String? filename; - @override - final String savedDir; - @override - final int timeCreated; - @override - final bool allowCellular; - - @override - String toString() { - return 'Download(taskId: $taskId, status: $status, progress: $progress, url: $url, filename: $filename, savedDir: $savedDir, timeCreated: $timeCreated, allowCellular: $allowCellular)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$_Download && - (identical(other.taskId, taskId) || other.taskId == taskId) && - (identical(other.status, status) || other.status == status) && - (identical(other.progress, progress) || - other.progress == progress) && - (identical(other.url, url) || other.url == url) && - (identical(other.filename, filename) || - other.filename == filename) && - (identical(other.savedDir, savedDir) || - other.savedDir == savedDir) && - (identical(other.timeCreated, timeCreated) || - other.timeCreated == timeCreated) && - (identical(other.allowCellular, allowCellular) || - other.allowCellular == allowCellular)); - } - - @override - int get hashCode => Object.hash(runtimeType, taskId, status, progress, url, - filename, savedDir, timeCreated, allowCellular); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$_DownloadCopyWith<_$_Download> get copyWith => - __$$_DownloadCopyWithImpl<_$_Download>(this, _$identity); -} - -abstract class _Download extends Download { - const factory _Download( - {required final String taskId, - required final DownloadTaskStatus status, - required final int progress, - required final String url, - required final String? filename, - required final String savedDir, - required final int timeCreated, - required final bool allowCellular}) = _$_Download; - const _Download._() : super._(); - - @override - String get taskId; - @override - DownloadTaskStatus get status; - @override - int get progress; - @override - String get url; - @override - String? get filename; - @override - String get savedDir; - @override - int get timeCreated; - @override - bool get allowCellular; - @override - @JsonKey(ignore: true) - _$$_DownloadCopyWith<_$_Download> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/lib/services/download_service.g.dart b/lib/services/download_service.g.dart deleted file mode 100644 index 6a2026e2..00000000 --- a/lib/services/download_service.g.dart +++ /dev/null @@ -1,25 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'download_service.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$downloadServiceHash() => r'c72c49f980e307f3013467e76b6564d14a34a736'; - -/// See also [DownloadService]. -@ProviderFor(DownloadService) -final downloadServiceProvider = - NotifierProvider.internal( - DownloadService.new, - name: r'downloadServiceProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$downloadServiceHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$DownloadService = Notifier; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart deleted file mode 100644 index 6a8df1d3..00000000 --- a/lib/services/settings_service.dart +++ /dev/null @@ -1,129 +0,0 @@ -import 'package:collection/collection.dart'; -import 'package:drift/drift.dart'; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../database/database.dart'; -import '../http/client.dart'; -import '../models/settings.dart'; -import '../sources/subsonic/client.dart'; -import '../state/init.dart'; -import 'download_service.dart'; - -part 'settings_service.g.dart'; - -@Riverpod(keepAlive: true) -class SettingsService extends _$SettingsService { - SubtracksDatabase get _db => ref.read(databaseProvider); - - @override - Settings build() { - return const Settings(); - } - - Future init() async { - final sources = await _db.allSubsonicSources().get(); - final settings = await _db.getAppSettings().getSingleOrNull(); - - state = Settings( - sources: sources - .sorted((a, b) => a.createdAt.compareTo(b.createdAt)) - .toIList(), - activeSource: sources.singleWhereOrNull((e) => e.isActive == true), - app: settings ?? const AppSettings(), - ); - } - - Future createSource( - SourcesCompanion source, - SubsonicSourcesCompanion subsonic, - ) async { - final client = SubsonicClient( - SubsonicSettings( - id: 1, - name: source.name.value, - address: source.address.value, - features: IList(), - username: subsonic.username.value, - password: subsonic.password.value, - useTokenAuth: subsonic.useTokenAuth.value, - isActive: true, - createdAt: DateTime.now(), - ), - ref.read(httpClientProvider), - ); - - await client.test(); - - final features = IList([ - if (await client.testFeature(SubsonicFeature.emptyQuerySearch)) - SubsonicFeature.emptyQuerySearch, - ]); - - await _db.createSource( - source, - subsonic.copyWith(features: Value(features)), - ); - await init(); - } - - Future updateSource(SubsonicSettings source) async { - final client = SubsonicClient(source, ref.read(httpClientProvider)); - - await client.test(); - - await _db.updateSource(source); - await init(); - } - - Future deleteSource(int sourceId) async { - await ref.read(downloadServiceProvider.notifier).deleteAll(sourceId); - await _db.deleteSource(sourceId); - await init(); - } - - Future setActiveSource(int id) async { - await _db.setActiveSource(id); - await init(); - } - - Future addTestSource(String prefix) async { - final env = ref.read(envProvider).requireValue; - - await createSource( - SourcesCompanion.insert( - name: env['${prefix}_SERVER_NAME']!, - address: Uri.parse(env['${prefix}_SERVER_URL']!), - ), - SubsonicSourcesCompanion.insert( - features: IList(), - username: env['${prefix}_SERVER_USERNAME']!, - password: env['${prefix}_SERVER_PASSWORD']!, - useTokenAuth: const Value(true), - ), - ); - - await init(); - } - - Future setMaxBitrateWifi(int bitrate) async { - await _db.updateSettings( - state.app.copyWith(maxBitrateWifi: bitrate).toCompanion(), - ); - await init(); - } - - Future setMaxBitrateMobile(int bitrate) async { - await _db.updateSettings( - state.app.copyWith(maxBitrateMobile: bitrate).toCompanion(), - ); - await init(); - } - - Future setStreamFormat(String? streamFormat) async { - await _db.updateSettings( - state.app.copyWith(streamFormat: streamFormat).toCompanion(), - ); - await init(); - } -} diff --git a/lib/services/settings_service.g.dart b/lib/services/settings_service.g.dart deleted file mode 100644 index 3e236150..00000000 --- a/lib/services/settings_service.g.dart +++ /dev/null @@ -1,25 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'settings_service.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$settingsServiceHash() => r'85f2bd5eedc3f791fe03a6707748bc95277c6aaf'; - -/// See also [SettingsService]. -@ProviderFor(SettingsService) -final settingsServiceProvider = - NotifierProvider.internal( - SettingsService.new, - name: r'settingsServiceProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$settingsServiceHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$SettingsService = Notifier; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/services/sync_service.dart b/lib/services/sync_service.dart deleted file mode 100644 index 7a051334..00000000 --- a/lib/services/sync_service.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../database/database.dart'; -import '../state/settings.dart'; - -part 'sync_service.g.dart'; - -@Riverpod(keepAlive: true) -class SyncService extends _$SyncService { - @override - DateTime build() { - return DateTime.now(); - } - - Future syncAll() async { - final db = ref.read(databaseProvider); - - await db.transaction(() async { - await Future.wait([ - db.transaction(_syncAllArtists), - db.transaction(_syncAllAlbums), - db.transaction(_syncAllPlaylists), - db.transaction(_syncAllSongs), - ]); - }); - - state = DateTime.now(); - } - - Future _syncAllArtists() async { - final source = ref.read(musicSourceProvider); - final db = ref.read(databaseProvider); - - final ids = {}; - await for (var artists in source.allArtists()) { - ids.addAll(artists.map((e) => e.id.value)); - await db.saveArtists(artists); - } - - await db.deleteArtistsNotIn(source.id, ids); - } - - Future _syncAllAlbums() async { - final source = ref.read(musicSourceProvider); - final db = ref.read(databaseProvider); - - final ids = {}; - await for (var albums in source.allAlbums()) { - ids.addAll(albums.map((e) => e.id.value)); - await db.saveAlbums(albums); - } - - await db.deleteAlbumsNotIn(source.id, ids); - } - - Future _syncAllPlaylists() async { - final source = ref.read(musicSourceProvider); - final db = ref.read(databaseProvider); - - final ids = {}; - await for (var playlists in source.allPlaylists()) { - ids.addAll(playlists.map((e) => e.playist.id.value)); - await db.savePlaylists(playlists); - } - - await db.deletePlaylistsNotIn(source.id, ids); - } - - Future _syncAllSongs() async { - final source = ref.read(musicSourceProvider); - final db = ref.read(databaseProvider); - - final ids = {}; - await for (var songs in source.allSongs()) { - ids.addAll(songs.map((e) => e.id.value)); - await db.saveSongs(songs); - } - - await db.deleteSongsNotIn(source.id, ids); - } - - // Future syncArtist(String id) async { - // final source = ref.read(musicSourceProvider); - // final db = ref.read(databaseProvider); - - // final artist = await source.artist(id); - // await saveArtist(db, artist); - // } - - // Future syncAlbum(String id) async { - // final source = ref.read(musicSourceProvider); - // final db = ref.read(databaseProvider); - - // final album = await source.album(id); - // await saveAlbum(db, album); - // } - - // Future syncPlaylist(String id) async { - // final source = ref.read(musicSourceProvider); - // final db = ref.read(databaseProvider); - - // final playlist = await source.playlist(id); - // await savePlaylist(db, playlist); - // } -} diff --git a/lib/services/sync_service.g.dart b/lib/services/sync_service.g.dart deleted file mode 100644 index 8288d774..00000000 --- a/lib/services/sync_service.g.dart +++ /dev/null @@ -1,23 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'sync_service.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$syncServiceHash() => r'58ebee4e6f055b64ee6789ae43d63c0e15c679e0'; - -/// See also [SyncService]. -@ProviderFor(SyncService) -final syncServiceProvider = NotifierProvider.internal( - SyncService.new, - name: r'syncServiceProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$syncServiceHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$SyncService = Notifier; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/sources/music_source.dart b/lib/sources/music_source.dart deleted file mode 100644 index bb4af449..00000000 --- a/lib/sources/music_source.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:rxdart/rxdart.dart'; - -import '../database/database.dart'; -import '../log.dart'; -import '../state/settings.dart'; - -abstract class BaseMusicSource { - int get id; - - Future ping(); - - Stream> allAlbums(); - Stream> allArtists(); - Stream> allPlaylists(); - Stream> allSongs(); - - Uri streamUri(String songId); - Uri downloadUri(String songId); - - Uri coverArtUri(String coverArtId, {bool thumbnail = true}); - Future artistArtUri(String artistId, {bool thumbnail = true}); -} - -class OfflineException implements Exception { - @override - String toString() => 'OfflineException'; -} - -class MusicSource implements BaseMusicSource { - final BaseMusicSource _source; - final Ref _ref; - - const MusicSource(this._source, this._ref); - - void _testOnline() { - if (_ref.read(offlineModeProvider)) { - throw OfflineException(); - } - } - - @override - Stream> allAlbums() { - _testOnline(); - return _source - .allAlbums() - .doOnError((e, st) => log.severe('allAlbums', e, st)); - } - - @override - Stream> allArtists() { - _testOnline(); - return _source - .allArtists() - .doOnError((e, st) => log.severe('allArtists', e, st)); - } - - @override - Stream> allPlaylists() { - _testOnline(); - return _source - .allPlaylists() - .doOnError((e, st) => log.severe('allPlaylists', e, st)); - } - - @override - Stream> allSongs() { - _testOnline(); - return _source - .allSongs() - .doOnError((e, st) => log.severe('allSongs', e, st)); - } - - @override - Future artistArtUri(String artistId, {bool thumbnail = true}) { - _testOnline(); - return _source.artistArtUri(artistId, thumbnail: thumbnail); - } - - @override - Uri coverArtUri(String coverArtId, {bool thumbnail = true}) => - _source.coverArtUri(coverArtId, thumbnail: thumbnail); - - @override - Uri downloadUri(String songId) => _source.downloadUri(songId); - - @override - int get id => _source.id; - - @override - Future ping() => _source.ping(); - - @override - Uri streamUri(String songId) => _source.streamUri(songId); -} diff --git a/lib/sources/subsonic/client.dart b/lib/sources/subsonic/client.dart deleted file mode 100644 index 0e1128a0..00000000 --- a/lib/sources/subsonic/client.dart +++ /dev/null @@ -1,140 +0,0 @@ -import 'dart:convert'; -import 'dart:math'; - -import 'package:collection/collection.dart'; -import 'package:crypto/crypto.dart'; -import 'package:http/http.dart'; -import 'package:xml/xml.dart'; - -import '../../log.dart'; -import '../../models/settings.dart'; -import 'xml.dart'; - -class SubsonicException implements Exception { - final XmlElement xml; - - late int code; - late String message; - - SubsonicException(this.xml) { - try { - final error = xml.getElement('error')!; - code = int.parse(error.getAttribute('code')!); - message = error.getAttribute('message')!; - } catch (err) { - code = -1; - message = 'Unknown error.'; - } - } - - @override - String toString() => 'SubsonicException [$code]: $message'; -} - -class SubsonicClient { - final SubsonicSettings opt; - final BaseClient http; - - SubsonicClient(this.opt, this.http); - - String _salt() { - final r = Random(); - return String.fromCharCodes( - List.generate(4, (index) => r.nextInt(92) + 33), - ); - } - - Map _params() { - final Map p = {}; - p['v'] = '1.13.0'; - p['c'] = 'subtracks'; - p['u'] = opt.username; - - if (opt.useTokenAuth) { - p['s'] = _salt(); - p['t'] = md5.convert(utf8.encode(opt.password + p['s']!)).toString(); - } else { - p['p'] = opt.password; - } - - return p; - } - - Uri uri( - String method, [ - Map? extraParams, - ]) { - final pathSegments = [...opt.address.pathSegments, 'rest', '$method.view']; - - _removeIdPrefix(extraParams); - extraParams?.removeWhere((key, value) => value == null); - final queryParameters = { - ..._params(), - ...(extraParams ?? {}), - }; - - return Uri( - scheme: opt.address.scheme, - host: opt.address.host, - port: opt.address.hasPort ? opt.address.port : null, - pathSegments: pathSegments, - queryParameters: queryParameters, - ); - } - - Future get( - String method, [ - Map? extraParams, - ]) async { - final res = await http.get(uri(method, extraParams)); - final subsonicResponse = - SubsonicResponse(XmlDocument.parse(utf8.decode(res.bodyBytes))); - if (subsonicResponse.status == Status.failed) { - final error = SubsonicException(subsonicResponse.xml); - log.severe('Subsonic error', error); - throw error; - } - - return subsonicResponse; - } - - Future test() => get('ping'); - - Future testFeature(SubsonicFeature feature) async { - switch (feature) { - case SubsonicFeature.emptyQuerySearch: - final res = await get( - 'search3', - {'query': '""', 'songCount': '1'}, - ); - return res.xml.findAllElements('song').isNotEmpty; - default: - return false; - } - } - - static const _idsWithPrefix = { - 'id', - 'playlistId', - 'songIdToAdd', - 'albumId', - 'artistId', - }; - - static const _idPrefixMatch = - r'(artist\.|album\.|playlist\.|song\.|coverArt\.)'; - - void _removeIdPrefix(Map? params) { - if (params == null) return; - - for (var key in params.keys) { - if (!_idsWithPrefix.contains(key)) continue; - if (params[key] == null) continue; - - final hasPrefix = params[key]!.startsWith(RegExp(_idPrefixMatch)); - if (!hasPrefix) continue; - - params[key] = params[key]?.split('.').slice(1).join(''); - } - } -} diff --git a/lib/sources/subsonic/source.dart b/lib/sources/subsonic/source.dart deleted file mode 100644 index 15207edd..00000000 --- a/lib/sources/subsonic/source.dart +++ /dev/null @@ -1,285 +0,0 @@ -import 'package:collection/collection.dart'; -import 'package:drift/drift.dart' show Value; -import 'package:http/http.dart'; -import 'package:pool/pool.dart'; -import 'package:xml/xml.dart'; -import 'package:xml/xml_events.dart'; - -import '../../database/database.dart'; -import '../../database/util.dart'; -import '../../models/settings.dart'; -import '../music_source.dart'; -import 'client.dart'; - -class SubsonicSource implements MusicSource { - final SubsonicSettings opt; - final BaseClient http; - final int maxBitrate; - final String? streamFormat; - - late final SubsonicClient client; - - final _pool = Pool(10, timeout: const Duration(seconds: 60)); - - SubsonicSource({ - required this.opt, - required this.http, - required this.maxBitrate, - this.streamFormat, - }) { - client = SubsonicClient(opt, http); - } - - @override - int get id => opt.id; - - @override - Future ping() async { - await client.get('ping'); - } - - @override - Stream> allArtists() async* { - final res = await client.get('getArtists'); - for (var artists in res.xml.findAllElements('artist').slices(200)) { - yield artists.map(_mapArtist); - } - } - - @override - Stream> allAlbums() async* { - final extras = await Future.wait([ - _albumList('frequent') - .flatten() - .map((element) => element.getAttribute('id')!) - .toList(), - _albumList('recent') - .flatten() - .map((element) => element.getAttribute('id')!) - .toList(), - ]); - - final frequentlyPlayed = { - for (var i = 0; i < extras[0].length; i++) extras[0][i]: i - }; - final recentlyPlayed = { - for (var i = 0; i < extras[1].length; i++) extras[1][i]: i - }; - - await for (var albums in _albumList('newest')) { - yield albums.map( - (e) => _mapAlbum( - e, - frequentRank: Value(frequentlyPlayed[e.getAttribute('id')!]), - recentRank: Value(recentlyPlayed[e.getAttribute('id')!]), - ), - ); - } - } - - @override - Stream> allPlaylists() async* { - final allPlaylists = await client.get('getPlaylists'); - - yield* _pool.forEach(allPlaylists.xml.findAllElements('playlist'), - (playlist) async { - final res = await client.get( - 'getPlaylist', - {'id': playlist.getAttribute('id')}, - ); - return [ - PlaylistWithSongsCompanion( - _mapPlaylist(res.xml.getElement('playlist')!), - res.xml.findAllElements('entry').mapIndexed(_mapPlaylistSong), - ) - ]; - }); - } - - @override - Stream> allSongs() async* { - if (opt.features.contains(SubsonicFeature.emptyQuerySearch)) { - await for (var songs in _songSearch()) { - yield songs.map(_mapSong); - } - } else { - await for (var albumsList in _albumList('alphabeticalByName')) { - yield* _pool.forEach(albumsList, (album) async { - final albums = await client.get('getAlbum', { - 'id': album.getAttribute('id')!, - }); - return albums.xml.findAllElements('song').map(_mapSong); - }); - } - } - } - - @override - Uri streamUri(String songId) { - return client.uri('stream', { - 'id': songId, - 'estimateContentLength': true.toString(), - 'maxBitRate': maxBitrate.toString(), - 'format': streamFormat?.toString(), - }); - } - - @override - Uri downloadUri(String songId) { - return client.uri('download', {'id': songId}); - } - - @override - Uri coverArtUri(String id, {bool thumbnail = true}) { - final opts = {'id': id}; - if (thumbnail) { - opts['size'] = 256.toString(); - } - return client.uri('getCoverArt', opts); - } - - @override - Future artistArtUri(String artistId, {bool thumbnail = true}) async { - final res = await client.get('getArtistInfo2', {'id': artistId}); - return Uri.tryParse(res.xml - .getElement('artistInfo2') - ?.getElement(thumbnail ? 'smallImageUrl' : 'largeImageUrl') - ?.text ?? - ''); - } - - Stream> _albumList(String type) async* { - const size = 500; - var offset = 0; - - while (true) { - final res = await client.get('getAlbumList2', { - 'type': type, - 'size': size.toString(), - 'offset': offset.toString(), - }); - - final albums = res.xml.findAllElements('album'); - offset += albums.length; - - yield albums; - - if (albums.length < size) { - break; - } - } - } - - Stream> _songSearch() async* { - const size = 500; - var offset = 0; - - while (true) { - final res = await client.get('search3', { - 'query': '""', - 'songCount': size.toString(), - 'songOffset': offset.toString(), - 'artistCount': '0', - 'albumCount': '0', - }); - - final songs = res.xml.findAllElements('song'); - offset += songs.length; - - yield songs; - - if (songs.length < size) { - break; - } - } - } - - ArtistsCompanion _mapArtist(XmlElement e) { - return ArtistsCompanion.insert( - sourceId: id, - id: 'artist.${e.getAttribute('id')!}', - name: e.getAttribute('name') ?? 'Artist ${e.getAttribute('id')}', - albumCount: int.parse(e.getAttribute('albumCount')!), - starred: Value(DateTimeExt.tryParseUtc(e.getAttribute('starred'))), - ); - } - - AlbumsCompanion _mapAlbum( - XmlElement e, { - Value frequentRank = const Value.absent(), - Value recentRank = const Value.absent(), - }) { - return AlbumsCompanion.insert( - sourceId: id, - id: 'album.${e.getAttribute('id')!}', - artistId: Value(e.getAttribute('artistId') != null - ? 'artist.${e.getAttribute('artistId')}' - : null), - name: e.getAttribute('name') ?? 'Album ${e.getAttribute('id')}', - albumArtist: Value(e.getAttribute('artist')), - created: DateTimeExt.parseUtc(e.getAttribute('created')!), - coverArt: Value(e.getAttribute('coverArt') != null - ? 'coverArt.${e.getAttribute('coverArt')}' - : null), - year: e.getAttribute('year') != null - ? Value(int.parse(e.getAttribute('year')!)) - : const Value(null), - starred: Value(DateTimeExt.tryParseUtc(e.getAttribute('starred'))), - genre: Value(e.getAttribute('genre')), - songCount: int.parse(e.getAttribute('songCount')!), - frequentRank: frequentRank, - recentRank: recentRank, - ); - } - - PlaylistsCompanion _mapPlaylist(XmlElement e) { - return PlaylistsCompanion.insert( - sourceId: id, - id: 'playlist.${e.getAttribute('id')!}', - name: e.getAttribute('name') ?? 'Playlist ${e.getAttribute('id')}', - comment: Value(e.getAttribute('comment')), - coverArt: Value(e.getAttribute('coverArt') != null - ? 'coverArt.${e.getAttribute('coverArt')}' - : null), - songCount: int.parse(e.getAttribute('songCount')!), - created: DateTimeExt.parseUtc(e.getAttribute('created')!), - ); - } - - SongsCompanion _mapSong(XmlElement e) { - return SongsCompanion.insert( - sourceId: id, - id: 'song.${e.getAttribute('id')!}', - albumId: Value(e.getAttribute('albumId') != null - ? 'album.${e.getAttribute('albumId')}' - : null), - artistId: Value(e.getAttribute('artistId') != null - ? 'artist.${e.getAttribute('artistId')}' - : null), - title: e.getAttribute('title') ?? 'Song ${e.getAttribute('id')}', - album: Value(e.getAttribute('album')), - artist: Value(e.getAttribute('artist')), - duration: e.getAttribute('duration') != null - ? Value(Duration( - seconds: int.parse(e.getAttribute('duration').toString()))) - : const Value(null), - track: e.getAttribute('track') != null - ? Value(int.parse(e.getAttribute('track')!)) - : const Value(null), - disc: e.getAttribute('discNumber') != null - ? Value(int.parse(e.getAttribute('discNumber')!)) - : const Value(null), - starred: Value(DateTimeExt.tryParseUtc(e.getAttribute('starred'))), - genre: Value(e.getAttribute('genre')), - ); - } - - PlaylistSongsCompanion _mapPlaylistSong(int index, XmlElement e) { - return PlaylistSongsCompanion.insert( - sourceId: id, - playlistId: 'playlist.${e.parentElement!.getAttribute('id')!}', - songId: 'song.${e.getAttribute('id')!}', - position: index, - ); - } -} diff --git a/lib/sources/subsonic/xml.dart b/lib/sources/subsonic/xml.dart deleted file mode 100644 index 3d8ad61a..00000000 --- a/lib/sources/subsonic/xml.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:xml/xml.dart'; - -enum Status { - ok('ok'), - failed('failed'); - - const Status(this.value); - final String value; -} - -class SubsonicResponse { - late Status status; - late XmlElement xml; - - SubsonicResponse(XmlDocument xml) { - this.xml = xml.getElement('subsonic-response')!; - status = Status.values.byName(this.xml.getAttribute('status')!); - } -} diff --git a/lib/state/audio.dart b/lib/state/audio.dart deleted file mode 100644 index 8ba3e39f..00000000 --- a/lib/state/audio.dart +++ /dev/null @@ -1,143 +0,0 @@ -import 'package:audio_service/audio_service.dart'; -import 'package:drift/drift.dart' show Value; -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../database/database.dart'; -import '../models/music.dart'; -import '../models/support.dart'; -import '../services/audio_service.dart'; -import 'settings.dart'; - -part 'audio.g.dart'; - -@Riverpod(keepAlive: true) -Stream mediaItem(MediaItemRef ref) async* { - final audio = ref.watch(audioControlProvider); - await for (var item in audio.mediaItem) { - yield item; - } -} - -@Riverpod(keepAlive: true) -MediaItemData? mediaItemData(MediaItemDataRef ref) { - return ref.watch(mediaItemProvider.select( - (value) => value.valueOrNull?.data, - )); -} - -@Riverpod(keepAlive: true) -Stream mediaItemSong(MediaItemSongRef ref) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - final id = ref.watch(mediaItemProvider.select( - (value) => value.valueOrNull?.id, - )); - - return db.songById(sourceId, id ?? '').watchSingleOrNull(); -} - -@Riverpod(keepAlive: true) -Stream playbackState(PlaybackStateRef ref) async* { - final audio = ref.watch(audioControlProvider); - await for (var state in audio.playbackState) { - yield state; - } -} - -@Riverpod(keepAlive: true) -Stream queueMode(QueueModeRef ref) async* { - final audio = ref.watch(audioControlProvider); - await for (var state in audio.queueMode) { - yield state; - } -} - -@Riverpod(keepAlive: true) -Stream> queue(QueueRef ref) async* { - final audio = ref.watch(audioControlProvider); - await for (var queue in audio.queue) { - yield queue; - } -} - -@Riverpod(keepAlive: true) -Stream?> shuffleIndicies(ShuffleIndiciesRef ref) async* { - final audio = ref.watch(audioControlProvider); - await for (var indicies in audio.shuffleIndicies) { - yield indicies; - } -} - -@riverpod -Stream positionStream(PositionStreamRef ref) async* { - final audio = ref.watch(audioControlProvider); - await for (var state in audio.position) { - yield state; - } -} - -@riverpod -bool playing(PlayingRef ref) { - return ref.watch(playbackStateProvider.select( - (value) => value.valueOrNull?.playing ?? false, - )); -} - -@riverpod -AudioProcessingState? processingState(ProcessingStateRef ref) { - return ref.watch(playbackStateProvider.select( - (value) => value.valueOrNull?.processingState, - )); -} - -@riverpod -int position(PositionRef ref) { - return ref.watch(positionStreamProvider.select( - (value) => value.valueOrNull?.inSeconds ?? 0, - )); -} - -@riverpod -int duration(DurationRef ref) { - return ref.watch(mediaItemProvider.select( - (value) => value.valueOrNull?.duration?.inSeconds ?? 0, - )); -} - -@Riverpod(keepAlive: true) -AudioServiceShuffleMode? shuffleMode(ShuffleModeRef ref) { - return ref.watch(playbackStateProvider.select( - (value) => value.valueOrNull?.shuffleMode, - )); -} - -@Riverpod(keepAlive: true) -AudioServiceRepeatMode repeatMode(RepeatModeRef ref) { - return ref.watch(playbackStateProvider.select( - (value) => value.valueOrNull?.repeatMode ?? AudioServiceRepeatMode.none, - )); -} - -@Riverpod(keepAlive: true) -class LastAudioStateService extends _$LastAudioStateService { - @override - Future build() async { - final db = ref.watch(databaseProvider); - final queueMode = ref.watch(queueModeProvider).valueOrNull; - final shuffleIndicies = ref.watch(shuffleIndiciesProvider).valueOrNull; - final repeat = ref.watch(repeatModeProvider); - - await db.saveLastAudioState(LastAudioStateCompanion.insert( - id: const Value(1), - queueMode: queueMode ?? QueueMode.user, - shuffleIndicies: Value(shuffleIndicies?.lock), - repeat: { - AudioServiceRepeatMode.none: RepeatMode.none, - AudioServiceRepeatMode.all: RepeatMode.all, - AudioServiceRepeatMode.group: RepeatMode.all, - AudioServiceRepeatMode.one: RepeatMode.one, - }[repeat]!, - )); - } -} diff --git a/lib/state/audio.g.dart b/lib/state/audio.g.dart deleted file mode 100644 index 0c9b0fcc..00000000 --- a/lib/state/audio.g.dart +++ /dev/null @@ -1,229 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'audio.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$mediaItemHash() => r'ca8b6768872f17355f756c95cf85278127b59444'; - -/// See also [mediaItem]. -@ProviderFor(mediaItem) -final mediaItemProvider = StreamProvider.internal( - mediaItem, - name: r'mediaItemProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$mediaItemHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef MediaItemRef = StreamProviderRef; -String _$mediaItemDataHash() => r'8539c02682f0d33b584ea0437dd3774d9f321a2e'; - -/// See also [mediaItemData]. -@ProviderFor(mediaItemData) -final mediaItemDataProvider = Provider.internal( - mediaItemData, - name: r'mediaItemDataProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$mediaItemDataHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef MediaItemDataRef = ProviderRef; -String _$mediaItemSongHash() => r'274f43470cd993f0a2bed3d3da22d7bd41b562f1'; - -/// See also [mediaItemSong]. -@ProviderFor(mediaItemSong) -final mediaItemSongProvider = StreamProvider.internal( - mediaItemSong, - name: r'mediaItemSongProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$mediaItemSongHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef MediaItemSongRef = StreamProviderRef; -String _$playbackStateHash() => r'b4a9eb7f802fc8c92666c1318f789865140d6025'; - -/// See also [playbackState]. -@ProviderFor(playbackState) -final playbackStateProvider = StreamProvider.internal( - playbackState, - name: r'playbackStateProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$playbackStateHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef PlaybackStateRef = StreamProviderRef; -String _$queueModeHash() => r'be0b1ff436c367e9be54c6d15fd8bac4f904fdec'; - -/// See also [queueMode]. -@ProviderFor(queueMode) -final queueModeProvider = StreamProvider.internal( - queueMode, - name: r'queueModeProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$queueModeHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef QueueModeRef = StreamProviderRef; -String _$queueHash() => r'94d86c99382f56193a11baf3f13354eab6a39fa8'; - -/// See also [queue]. -@ProviderFor(queue) -final queueProvider = StreamProvider>.internal( - queue, - name: r'queueProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$queueHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef QueueRef = StreamProviderRef>; -String _$shuffleIndiciesHash() => r'e5dc6879b2a7b7a501b58aace717ff36eff59995'; - -/// See also [shuffleIndicies]. -@ProviderFor(shuffleIndicies) -final shuffleIndiciesProvider = StreamProvider?>.internal( - shuffleIndicies, - name: r'shuffleIndiciesProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$shuffleIndiciesHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef ShuffleIndiciesRef = StreamProviderRef?>; -String _$positionStreamHash() => r'5f1dc9d11e1bcce649ddb764525cc0dc79bfb6d8'; - -/// See also [positionStream]. -@ProviderFor(positionStream) -final positionStreamProvider = AutoDisposeStreamProvider.internal( - positionStream, - name: r'positionStreamProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$positionStreamHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef PositionStreamRef = AutoDisposeStreamProviderRef; -String _$playingHash() => r'2a40fa275358918b243c8734bbe49bc9d7373f10'; - -/// See also [playing]. -@ProviderFor(playing) -final playingProvider = AutoDisposeProvider.internal( - playing, - name: r'playingProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$playingHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef PlayingRef = AutoDisposeProviderRef; -String _$processingStateHash() => r'b9e59927b905384a0f1221b2adb9b681091c27d1'; - -/// See also [processingState]. -@ProviderFor(processingState) -final processingStateProvider = - AutoDisposeProvider.internal( - processingState, - name: r'processingStateProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$processingStateHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef ProcessingStateRef = AutoDisposeProviderRef; -String _$positionHash() => r'bfc853fe9e46bf79522fa41374763a7e1c12e739'; - -/// See also [position]. -@ProviderFor(position) -final positionProvider = AutoDisposeProvider.internal( - position, - name: r'positionProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$positionHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef PositionRef = AutoDisposeProviderRef; -String _$durationHash() => r'bf9eb316b8401401e5862384deb1a4c1134e6dd2'; - -/// See also [duration]. -@ProviderFor(duration) -final durationProvider = AutoDisposeProvider.internal( - duration, - name: r'durationProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$durationHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef DurationRef = AutoDisposeProviderRef; -String _$shuffleModeHash() => r'fd26d81cb9bd5e0e1a7e9ccf1589c104d9a4eb3a'; - -/// See also [shuffleMode]. -@ProviderFor(shuffleMode) -final shuffleModeProvider = Provider.internal( - shuffleMode, - name: r'shuffleModeProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$shuffleModeHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef ShuffleModeRef = ProviderRef; -String _$repeatModeHash() => r'346248bf08df65f1f69e4cb4b6ef192190d2910c'; - -/// See also [repeatMode]. -@ProviderFor(repeatMode) -final repeatModeProvider = Provider.internal( - repeatMode, - name: r'repeatModeProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$repeatModeHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef RepeatModeRef = ProviderRef; -String _$lastAudioStateServiceHash() => - r'4291b8d4a399f1b192277a3e8a93fbe7096fea32'; - -/// See also [LastAudioStateService]. -@ProviderFor(LastAudioStateService) -final lastAudioStateServiceProvider = - AsyncNotifierProvider.internal( - LastAudioStateService.new, - name: r'lastAudioStateServiceProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$lastAudioStateServiceHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$LastAudioStateService = AsyncNotifier; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/state/init.dart b/lib/state/init.dart deleted file mode 100644 index eec2188a..00000000 --- a/lib/state/init.dart +++ /dev/null @@ -1,82 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/services.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; -import 'package:package_info_plus/package_info_plus.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../app/app.dart'; -import '../app/app_router.dart'; -import '../app/pages/bottom_nav_page.dart'; -import '../app/pages/library_page.dart'; -import '../services/audio_service.dart'; -import '../services/download_service.dart'; -import '../services/settings_service.dart'; -import 'audio.dart'; -import 'settings.dart'; - -part 'init.g.dart'; - -@Riverpod(keepAlive: true) -FutureOr> env(EnvRef ref) async { - await dotenv.load(); - return dotenv.env; -} - -@Riverpod(keepAlive: true) -AppRouter router(RouterRef ref) { - return AppRouter(); -} - -@Riverpod(keepAlive: true) -FutureOr placeholderImageUri(PlaceholderImageUriRef ref) async { - final byteData = await rootBundle.load('assets/placeholder.png'); - final docsDir = await getApplicationDocumentsDirectory(); - - return (await File('${docsDir.path}/placeholder.png').writeAsBytes(byteData - .buffer - .asUint8List(byteData.offsetInBytes, byteData.lengthInBytes))) - .uri; -} - -@Riverpod(keepAlive: true) -FutureOr placeholderThumbImageUri(PlaceholderThumbImageUriRef ref) async { - final byteData = await rootBundle.load('assets/placeholder_thumb.png'); - final docsDir = await getApplicationDocumentsDirectory(); - - return (await File('${docsDir.path}/placeholder_thumb.png').writeAsBytes( - byteData.buffer - .asUint8List(byteData.offsetInBytes, byteData.lengthInBytes))) - .uri; -} - -@Riverpod(keepAlive: true) -FutureOr packageInfo(PackageInfoRef ref) async { - return await PackageInfo.fromPlatform(); -} - -@Riverpod(keepAlive: true) -FutureOr init(InitRef ref) async { - ref.watch(routerProvider); - await ref.watch(envProvider.future); - await ref.read(packageInfoProvider.future); - await ref.watch(placeholderImageUriProvider.future); - await ref.watch(placeholderThumbImageUriProvider.future); - - await ref.read(networkModeProvider.future); - await ref.read(maxBitrateProvider.future); - await ref.watch(settingsServiceProvider.notifier).init(); - - final audio = await ref.watch(audioControlInitProvider.future); - await audio.init(); - ref.watch(lastAudioStateServiceProvider.notifier); - - await ref.watch(downloadServiceProvider.notifier).init(); - - await ref.watch(lastPathProvider.notifier).init(); - ref.watch(lastBottomNavStateServiceProvider.notifier); - ref.watch(lastLibraryStateServiceProvider.notifier); - - await ref.watch(libraryListsProvider.notifier).init(); -} diff --git a/lib/state/init.g.dart b/lib/state/init.g.dart deleted file mode 100644 index 74468895..00000000 --- a/lib/state/init.g.dart +++ /dev/null @@ -1,97 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'init.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$envHash() => r'183e2c6c10c5a9d3dfcaffca0f1723cd85d67a5c'; - -/// See also [env]. -@ProviderFor(env) -final envProvider = FutureProvider>.internal( - env, - name: r'envProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$envHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef EnvRef = FutureProviderRef>; -String _$routerHash() => r'3f52af31948ac5942fe4167f84785572458eeacc'; - -/// See also [router]. -@ProviderFor(router) -final routerProvider = Provider.internal( - router, - name: r'routerProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$routerHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef RouterRef = ProviderRef; -String _$placeholderImageUriHash() => - r'129f37af640421ec12038d161a8b15a67536e570'; - -/// See also [placeholderImageUri]. -@ProviderFor(placeholderImageUri) -final placeholderImageUriProvider = FutureProvider.internal( - placeholderImageUri, - name: r'placeholderImageUriProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$placeholderImageUriHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef PlaceholderImageUriRef = FutureProviderRef; -String _$placeholderThumbImageUriHash() => - r'8136dd4bbb3dc57fb1e6aa8db556e58620c61c85'; - -/// See also [placeholderThumbImageUri]. -@ProviderFor(placeholderThumbImageUri) -final placeholderThumbImageUriProvider = FutureProvider.internal( - placeholderThumbImageUri, - name: r'placeholderThumbImageUriProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$placeholderThumbImageUriHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef PlaceholderThumbImageUriRef = FutureProviderRef; -String _$packageInfoHash() => r'9a2956f08c2e98b92dd8cce49cb331a127c78670'; - -/// See also [packageInfo]. -@ProviderFor(packageInfo) -final packageInfoProvider = FutureProvider.internal( - packageInfo, - name: r'packageInfoProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$packageInfoHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef PackageInfoRef = FutureProviderRef; -String _$initHash() => r'10e2945eb65f51e6a904a3811fa88e63771e5b19'; - -/// See also [init]. -@ProviderFor(init) -final initProvider = FutureProvider.internal( - init, - name: r'initProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$initHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef InitRef = FutureProviderRef; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/state/music.dart b/lib/state/music.dart deleted file mode 100644 index 57a4e861..00000000 --- a/lib/state/music.dart +++ /dev/null @@ -1,152 +0,0 @@ -import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../database/database.dart'; -import '../models/music.dart'; -import '../models/query.dart'; -import '../models/support.dart'; -import 'settings.dart'; - -part 'music.g.dart'; - -@riverpod -Stream artist(ArtistRef ref, String id) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.artistById(sourceId, id).watchSingle(); -} - -@riverpod -Stream album(AlbumRef ref, String id) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.albumById(sourceId, id).watchSingle(); -} - -@riverpod -Stream albumDownloadStatus( - AlbumDownloadStatusRef ref, - String id, -) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.albumDownloadStatus(sourceId, id).watchSingle(); -} - -@riverpod -Stream playlistDownloadStatus( - PlaylistDownloadStatusRef ref, - String id, -) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.playlistDownloadStatus(sourceId, id).watchSingle(); -} - -@riverpod -Stream song(SongRef ref, String id) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.songById(sourceId, id).watchSingle(); -} - -@riverpod -Future> albumSongsList( - AlbumSongsListRef ref, - String id, - ListQuery opt, -) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.albumSongsList(SourceId(sourceId: sourceId, id: id), opt).get(); -} - -@riverpod -Future> songsByAlbumList( - SongsByAlbumListRef ref, - ListQuery opt, -) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.songsByAlbumList(sourceId, opt).get(); -} - -@riverpod -Stream playlist(PlaylistRef ref, String id) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.playlistById(sourceId, id).watchSingle(); -} - -@riverpod -Future> playlistSongsList( - PlaylistSongsListRef ref, - String id, - ListQuery opt, -) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.playlistSongsList(SourceId(sourceId: sourceId, id: id), opt).get(); -} - -@riverpod -Future> albumsInIds(AlbumsInIdsRef ref, IList ids) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.albumsInIds(sourceId, ids.toList()).get(); -} - -@riverpod -Stream> albumsByArtistId(AlbumsByArtistIdRef ref, String id) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db - .albumsByArtistId(sourceId, id) - .watch() - .map((event) => event.toIList()); -} - -@riverpod -Stream> albumGenres(AlbumGenresRef ref, Pagination page) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db - .albumGenres(sourceId, page.limit, page.offset) - .watch() - .map((event) => event.withNullsRemoved().toIList()); -} - -@riverpod -Stream> albumsByGenre( - AlbumsByGenreRef ref, - String genre, - Pagination page, -) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db - .albumsByGenre(sourceId, genre, page.limit, page.offset) - .watch() - .map((event) => event.toIList()); -} - -@riverpod -Stream songsByGenreCount(SongsByGenreCountRef ref, String genre) { - final db = ref.watch(databaseProvider); - final sourceId = ref.watch(sourceIdProvider); - - return db.songsByGenreCount(sourceId, genre).watchSingle(); -} diff --git a/lib/state/music.g.dart b/lib/state/music.g.dart deleted file mode 100644 index 454eb5cc..00000000 --- a/lib/state/music.g.dart +++ /dev/null @@ -1,1206 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'music.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$artistHash() => r'2e2f1e28d5133b3ad10254a3c646de7d8a150c8e'; - -/// Copied from Dart SDK -class _SystemHash { - _SystemHash._(); - - static int combine(int hash, int value) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + value); - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - return hash ^ (hash >> 6); - } - - static int finish(int hash) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - // ignore: parameter_assignments - hash = hash ^ (hash >> 11); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } -} - -typedef ArtistRef = AutoDisposeStreamProviderRef; - -/// See also [artist]. -@ProviderFor(artist) -const artistProvider = ArtistFamily(); - -/// See also [artist]. -class ArtistFamily extends Family> { - /// See also [artist]. - const ArtistFamily(); - - /// See also [artist]. - ArtistProvider call( - String id, - ) { - return ArtistProvider( - id, - ); - } - - @override - ArtistProvider getProviderOverride( - covariant ArtistProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'artistProvider'; -} - -/// See also [artist]. -class ArtistProvider extends AutoDisposeStreamProvider { - /// See also [artist]. - ArtistProvider( - this.id, - ) : super.internal( - (ref) => artist( - ref, - id, - ), - from: artistProvider, - name: r'artistProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$artistHash, - dependencies: ArtistFamily._dependencies, - allTransitiveDependencies: ArtistFamily._allTransitiveDependencies, - ); - - final String id; - - @override - bool operator ==(Object other) { - return other is ArtistProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$albumHash() => r'914f37fe8bc2d883de2548ce9411aa10e8a9868a'; -typedef AlbumRef = AutoDisposeStreamProviderRef; - -/// See also [album]. -@ProviderFor(album) -const albumProvider = AlbumFamily(); - -/// See also [album]. -class AlbumFamily extends Family> { - /// See also [album]. - const AlbumFamily(); - - /// See also [album]. - AlbumProvider call( - String id, - ) { - return AlbumProvider( - id, - ); - } - - @override - AlbumProvider getProviderOverride( - covariant AlbumProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'albumProvider'; -} - -/// See also [album]. -class AlbumProvider extends AutoDisposeStreamProvider { - /// See also [album]. - AlbumProvider( - this.id, - ) : super.internal( - (ref) => album( - ref, - id, - ), - from: albumProvider, - name: r'albumProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$albumHash, - dependencies: AlbumFamily._dependencies, - allTransitiveDependencies: AlbumFamily._allTransitiveDependencies, - ); - - final String id; - - @override - bool operator ==(Object other) { - return other is AlbumProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$albumDownloadStatusHash() => - r'0b6c5f09f8327a624172d7ef33e1911c87b2cb60'; -typedef AlbumDownloadStatusRef - = AutoDisposeStreamProviderRef; - -/// See also [albumDownloadStatus]. -@ProviderFor(albumDownloadStatus) -const albumDownloadStatusProvider = AlbumDownloadStatusFamily(); - -/// See also [albumDownloadStatus]. -class AlbumDownloadStatusFamily extends Family> { - /// See also [albumDownloadStatus]. - const AlbumDownloadStatusFamily(); - - /// See also [albumDownloadStatus]. - AlbumDownloadStatusProvider call( - String id, - ) { - return AlbumDownloadStatusProvider( - id, - ); - } - - @override - AlbumDownloadStatusProvider getProviderOverride( - covariant AlbumDownloadStatusProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'albumDownloadStatusProvider'; -} - -/// See also [albumDownloadStatus]. -class AlbumDownloadStatusProvider - extends AutoDisposeStreamProvider { - /// See also [albumDownloadStatus]. - AlbumDownloadStatusProvider( - this.id, - ) : super.internal( - (ref) => albumDownloadStatus( - ref, - id, - ), - from: albumDownloadStatusProvider, - name: r'albumDownloadStatusProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$albumDownloadStatusHash, - dependencies: AlbumDownloadStatusFamily._dependencies, - allTransitiveDependencies: - AlbumDownloadStatusFamily._allTransitiveDependencies, - ); - - final String id; - - @override - bool operator ==(Object other) { - return other is AlbumDownloadStatusProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$playlistDownloadStatusHash() => - r'd563e8746265b2022c59e70869d136cdf6c03ab9'; -typedef PlaylistDownloadStatusRef - = AutoDisposeStreamProviderRef; - -/// See also [playlistDownloadStatus]. -@ProviderFor(playlistDownloadStatus) -const playlistDownloadStatusProvider = PlaylistDownloadStatusFamily(); - -/// See also [playlistDownloadStatus]. -class PlaylistDownloadStatusFamily - extends Family> { - /// See also [playlistDownloadStatus]. - const PlaylistDownloadStatusFamily(); - - /// See also [playlistDownloadStatus]. - PlaylistDownloadStatusProvider call( - String id, - ) { - return PlaylistDownloadStatusProvider( - id, - ); - } - - @override - PlaylistDownloadStatusProvider getProviderOverride( - covariant PlaylistDownloadStatusProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'playlistDownloadStatusProvider'; -} - -/// See also [playlistDownloadStatus]. -class PlaylistDownloadStatusProvider - extends AutoDisposeStreamProvider { - /// See also [playlistDownloadStatus]. - PlaylistDownloadStatusProvider( - this.id, - ) : super.internal( - (ref) => playlistDownloadStatus( - ref, - id, - ), - from: playlistDownloadStatusProvider, - name: r'playlistDownloadStatusProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$playlistDownloadStatusHash, - dependencies: PlaylistDownloadStatusFamily._dependencies, - allTransitiveDependencies: - PlaylistDownloadStatusFamily._allTransitiveDependencies, - ); - - final String id; - - @override - bool operator ==(Object other) { - return other is PlaylistDownloadStatusProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$songHash() => r'bd8ac3b046180c9fa7676e437542d5afe4dcdb7d'; -typedef SongRef = AutoDisposeStreamProviderRef; - -/// See also [song]. -@ProviderFor(song) -const songProvider = SongFamily(); - -/// See also [song]. -class SongFamily extends Family> { - /// See also [song]. - const SongFamily(); - - /// See also [song]. - SongProvider call( - String id, - ) { - return SongProvider( - id, - ); - } - - @override - SongProvider getProviderOverride( - covariant SongProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'songProvider'; -} - -/// See also [song]. -class SongProvider extends AutoDisposeStreamProvider { - /// See also [song]. - SongProvider( - this.id, - ) : super.internal( - (ref) => song( - ref, - id, - ), - from: songProvider, - name: r'songProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$songHash, - dependencies: SongFamily._dependencies, - allTransitiveDependencies: SongFamily._allTransitiveDependencies, - ); - - final String id; - - @override - bool operator ==(Object other) { - return other is SongProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$albumSongsListHash() => r'dfc357b4c2b6a7dcc5e4701dc395c49ec8c8b88a'; -typedef AlbumSongsListRef = AutoDisposeFutureProviderRef>; - -/// See also [albumSongsList]. -@ProviderFor(albumSongsList) -const albumSongsListProvider = AlbumSongsListFamily(); - -/// See also [albumSongsList]. -class AlbumSongsListFamily extends Family>> { - /// See also [albumSongsList]. - const AlbumSongsListFamily(); - - /// See also [albumSongsList]. - AlbumSongsListProvider call( - String id, - ListQuery opt, - ) { - return AlbumSongsListProvider( - id, - opt, - ); - } - - @override - AlbumSongsListProvider getProviderOverride( - covariant AlbumSongsListProvider provider, - ) { - return call( - provider.id, - provider.opt, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'albumSongsListProvider'; -} - -/// See also [albumSongsList]. -class AlbumSongsListProvider extends AutoDisposeFutureProvider> { - /// See also [albumSongsList]. - AlbumSongsListProvider( - this.id, - this.opt, - ) : super.internal( - (ref) => albumSongsList( - ref, - id, - opt, - ), - from: albumSongsListProvider, - name: r'albumSongsListProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$albumSongsListHash, - dependencies: AlbumSongsListFamily._dependencies, - allTransitiveDependencies: - AlbumSongsListFamily._allTransitiveDependencies, - ); - - final String id; - final ListQuery opt; - - @override - bool operator ==(Object other) { - return other is AlbumSongsListProvider && - other.id == id && - other.opt == opt; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - hash = _SystemHash.combine(hash, opt.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$songsByAlbumListHash() => r'd6ed7fd9d8ceb3c5743b8c5538c7ffd50d2a8284'; -typedef SongsByAlbumListRef = AutoDisposeFutureProviderRef>; - -/// See also [songsByAlbumList]. -@ProviderFor(songsByAlbumList) -const songsByAlbumListProvider = SongsByAlbumListFamily(); - -/// See also [songsByAlbumList]. -class SongsByAlbumListFamily extends Family>> { - /// See also [songsByAlbumList]. - const SongsByAlbumListFamily(); - - /// See also [songsByAlbumList]. - SongsByAlbumListProvider call( - ListQuery opt, - ) { - return SongsByAlbumListProvider( - opt, - ); - } - - @override - SongsByAlbumListProvider getProviderOverride( - covariant SongsByAlbumListProvider provider, - ) { - return call( - provider.opt, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'songsByAlbumListProvider'; -} - -/// See also [songsByAlbumList]. -class SongsByAlbumListProvider extends AutoDisposeFutureProvider> { - /// See also [songsByAlbumList]. - SongsByAlbumListProvider( - this.opt, - ) : super.internal( - (ref) => songsByAlbumList( - ref, - opt, - ), - from: songsByAlbumListProvider, - name: r'songsByAlbumListProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$songsByAlbumListHash, - dependencies: SongsByAlbumListFamily._dependencies, - allTransitiveDependencies: - SongsByAlbumListFamily._allTransitiveDependencies, - ); - - final ListQuery opt; - - @override - bool operator ==(Object other) { - return other is SongsByAlbumListProvider && other.opt == opt; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, opt.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$playlistHash() => r'df0c8441c67c487155574caeeb11f4cdfe25ed31'; -typedef PlaylistRef = AutoDisposeStreamProviderRef; - -/// See also [playlist]. -@ProviderFor(playlist) -const playlistProvider = PlaylistFamily(); - -/// See also [playlist]. -class PlaylistFamily extends Family> { - /// See also [playlist]. - const PlaylistFamily(); - - /// See also [playlist]. - PlaylistProvider call( - String id, - ) { - return PlaylistProvider( - id, - ); - } - - @override - PlaylistProvider getProviderOverride( - covariant PlaylistProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'playlistProvider'; -} - -/// See also [playlist]. -class PlaylistProvider extends AutoDisposeStreamProvider { - /// See also [playlist]. - PlaylistProvider( - this.id, - ) : super.internal( - (ref) => playlist( - ref, - id, - ), - from: playlistProvider, - name: r'playlistProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$playlistHash, - dependencies: PlaylistFamily._dependencies, - allTransitiveDependencies: PlaylistFamily._allTransitiveDependencies, - ); - - final String id; - - @override - bool operator ==(Object other) { - return other is PlaylistProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$playlistSongsListHash() => r'c3593829c6c91dc6958df6dc4cb6e89e3e7647a5'; -typedef PlaylistSongsListRef = AutoDisposeFutureProviderRef>; - -/// See also [playlistSongsList]. -@ProviderFor(playlistSongsList) -const playlistSongsListProvider = PlaylistSongsListFamily(); - -/// See also [playlistSongsList]. -class PlaylistSongsListFamily extends Family>> { - /// See also [playlistSongsList]. - const PlaylistSongsListFamily(); - - /// See also [playlistSongsList]. - PlaylistSongsListProvider call( - String id, - ListQuery opt, - ) { - return PlaylistSongsListProvider( - id, - opt, - ); - } - - @override - PlaylistSongsListProvider getProviderOverride( - covariant PlaylistSongsListProvider provider, - ) { - return call( - provider.id, - provider.opt, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'playlistSongsListProvider'; -} - -/// See also [playlistSongsList]. -class PlaylistSongsListProvider extends AutoDisposeFutureProvider> { - /// See also [playlistSongsList]. - PlaylistSongsListProvider( - this.id, - this.opt, - ) : super.internal( - (ref) => playlistSongsList( - ref, - id, - opt, - ), - from: playlistSongsListProvider, - name: r'playlistSongsListProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$playlistSongsListHash, - dependencies: PlaylistSongsListFamily._dependencies, - allTransitiveDependencies: - PlaylistSongsListFamily._allTransitiveDependencies, - ); - - final String id; - final ListQuery opt; - - @override - bool operator ==(Object other) { - return other is PlaylistSongsListProvider && - other.id == id && - other.opt == opt; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - hash = _SystemHash.combine(hash, opt.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$albumsInIdsHash() => r'089ceafa122e1b3ce87c216bf3650cae5f656bdc'; -typedef AlbumsInIdsRef = AutoDisposeFutureProviderRef>; - -/// See also [albumsInIds]. -@ProviderFor(albumsInIds) -const albumsInIdsProvider = AlbumsInIdsFamily(); - -/// See also [albumsInIds]. -class AlbumsInIdsFamily extends Family>> { - /// See also [albumsInIds]. - const AlbumsInIdsFamily(); - - /// See also [albumsInIds]. - AlbumsInIdsProvider call( - IList ids, - ) { - return AlbumsInIdsProvider( - ids, - ); - } - - @override - AlbumsInIdsProvider getProviderOverride( - covariant AlbumsInIdsProvider provider, - ) { - return call( - provider.ids, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'albumsInIdsProvider'; -} - -/// See also [albumsInIds]. -class AlbumsInIdsProvider extends AutoDisposeFutureProvider> { - /// See also [albumsInIds]. - AlbumsInIdsProvider( - this.ids, - ) : super.internal( - (ref) => albumsInIds( - ref, - ids, - ), - from: albumsInIdsProvider, - name: r'albumsInIdsProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$albumsInIdsHash, - dependencies: AlbumsInIdsFamily._dependencies, - allTransitiveDependencies: - AlbumsInIdsFamily._allTransitiveDependencies, - ); - - final IList ids; - - @override - bool operator ==(Object other) { - return other is AlbumsInIdsProvider && other.ids == ids; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, ids.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$albumsByArtistIdHash() => r'e9a5c9255b6c7b6cfb22f4a4bacc4e518787465d'; -typedef AlbumsByArtistIdRef = AutoDisposeStreamProviderRef>; - -/// See also [albumsByArtistId]. -@ProviderFor(albumsByArtistId) -const albumsByArtistIdProvider = AlbumsByArtistIdFamily(); - -/// See also [albumsByArtistId]. -class AlbumsByArtistIdFamily extends Family>> { - /// See also [albumsByArtistId]. - const AlbumsByArtistIdFamily(); - - /// See also [albumsByArtistId]. - AlbumsByArtistIdProvider call( - String id, - ) { - return AlbumsByArtistIdProvider( - id, - ); - } - - @override - AlbumsByArtistIdProvider getProviderOverride( - covariant AlbumsByArtistIdProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'albumsByArtistIdProvider'; -} - -/// See also [albumsByArtistId]. -class AlbumsByArtistIdProvider extends AutoDisposeStreamProvider> { - /// See also [albumsByArtistId]. - AlbumsByArtistIdProvider( - this.id, - ) : super.internal( - (ref) => albumsByArtistId( - ref, - id, - ), - from: albumsByArtistIdProvider, - name: r'albumsByArtistIdProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$albumsByArtistIdHash, - dependencies: AlbumsByArtistIdFamily._dependencies, - allTransitiveDependencies: - AlbumsByArtistIdFamily._allTransitiveDependencies, - ); - - final String id; - - @override - bool operator ==(Object other) { - return other is AlbumsByArtistIdProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$albumGenresHash() => r'17ba64391a678a4eb88017d782a843eeb92b2049'; -typedef AlbumGenresRef = AutoDisposeStreamProviderRef>; - -/// See also [albumGenres]. -@ProviderFor(albumGenres) -const albumGenresProvider = AlbumGenresFamily(); - -/// See also [albumGenres]. -class AlbumGenresFamily extends Family>> { - /// See also [albumGenres]. - const AlbumGenresFamily(); - - /// See also [albumGenres]. - AlbumGenresProvider call( - Pagination page, - ) { - return AlbumGenresProvider( - page, - ); - } - - @override - AlbumGenresProvider getProviderOverride( - covariant AlbumGenresProvider provider, - ) { - return call( - provider.page, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'albumGenresProvider'; -} - -/// See also [albumGenres]. -class AlbumGenresProvider extends AutoDisposeStreamProvider> { - /// See also [albumGenres]. - AlbumGenresProvider( - this.page, - ) : super.internal( - (ref) => albumGenres( - ref, - page, - ), - from: albumGenresProvider, - name: r'albumGenresProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$albumGenresHash, - dependencies: AlbumGenresFamily._dependencies, - allTransitiveDependencies: - AlbumGenresFamily._allTransitiveDependencies, - ); - - final Pagination page; - - @override - bool operator ==(Object other) { - return other is AlbumGenresProvider && other.page == page; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, page.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$albumsByGenreHash() => r'd35cb85a50df93b7f50c28c934ea182b69534b8b'; -typedef AlbumsByGenreRef = AutoDisposeStreamProviderRef>; - -/// See also [albumsByGenre]. -@ProviderFor(albumsByGenre) -const albumsByGenreProvider = AlbumsByGenreFamily(); - -/// See also [albumsByGenre]. -class AlbumsByGenreFamily extends Family>> { - /// See also [albumsByGenre]. - const AlbumsByGenreFamily(); - - /// See also [albumsByGenre]. - AlbumsByGenreProvider call( - String genre, - Pagination page, - ) { - return AlbumsByGenreProvider( - genre, - page, - ); - } - - @override - AlbumsByGenreProvider getProviderOverride( - covariant AlbumsByGenreProvider provider, - ) { - return call( - provider.genre, - provider.page, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'albumsByGenreProvider'; -} - -/// See also [albumsByGenre]. -class AlbumsByGenreProvider extends AutoDisposeStreamProvider> { - /// See also [albumsByGenre]. - AlbumsByGenreProvider( - this.genre, - this.page, - ) : super.internal( - (ref) => albumsByGenre( - ref, - genre, - page, - ), - from: albumsByGenreProvider, - name: r'albumsByGenreProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$albumsByGenreHash, - dependencies: AlbumsByGenreFamily._dependencies, - allTransitiveDependencies: - AlbumsByGenreFamily._allTransitiveDependencies, - ); - - final String genre; - final Pagination page; - - @override - bool operator ==(Object other) { - return other is AlbumsByGenreProvider && - other.genre == genre && - other.page == page; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, genre.hashCode); - hash = _SystemHash.combine(hash, page.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$songsByGenreCountHash() => r'408bc1d82a6dae29e7b9a85fbf6988ba854551f7'; -typedef SongsByGenreCountRef = AutoDisposeStreamProviderRef; - -/// See also [songsByGenreCount]. -@ProviderFor(songsByGenreCount) -const songsByGenreCountProvider = SongsByGenreCountFamily(); - -/// See also [songsByGenreCount]. -class SongsByGenreCountFamily extends Family> { - /// See also [songsByGenreCount]. - const SongsByGenreCountFamily(); - - /// See also [songsByGenreCount]. - SongsByGenreCountProvider call( - String genre, - ) { - return SongsByGenreCountProvider( - genre, - ); - } - - @override - SongsByGenreCountProvider getProviderOverride( - covariant SongsByGenreCountProvider provider, - ) { - return call( - provider.genre, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'songsByGenreCountProvider'; -} - -/// See also [songsByGenreCount]. -class SongsByGenreCountProvider extends AutoDisposeStreamProvider { - /// See also [songsByGenreCount]. - SongsByGenreCountProvider( - this.genre, - ) : super.internal( - (ref) => songsByGenreCount( - ref, - genre, - ), - from: songsByGenreCountProvider, - name: r'songsByGenreCountProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$songsByGenreCountHash, - dependencies: SongsByGenreCountFamily._dependencies, - allTransitiveDependencies: - SongsByGenreCountFamily._allTransitiveDependencies, - ); - - final String genre; - - @override - bool operator ==(Object other) { - return other is SongsByGenreCountProvider && other.genre == genre; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, genre.hashCode); - - return _SystemHash.finish(hash); - } -} -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/state/settings.dart b/lib/state/settings.dart deleted file mode 100644 index 170de4fa..00000000 --- a/lib/state/settings.dart +++ /dev/null @@ -1,88 +0,0 @@ -import 'package:connectivity_plus/connectivity_plus.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import '../http/client.dart'; -import '../models/settings.dart'; -import '../services/settings_service.dart'; -import '../sources/music_source.dart'; -import '../sources/subsonic/source.dart'; - -part 'settings.g.dart'; - -@Riverpod(keepAlive: true) -MusicSource musicSource(MusicSourceRef ref) { - final settings = ref.watch(settingsServiceProvider.select( - (value) => value.activeSource, - )) as SubsonicSettings; - final streamFormat = ref.watch(settingsServiceProvider.select( - (value) => value.app.streamFormat, - )); - final maxBitrate = ref.watch(maxBitrateProvider).requireValue; - final http = ref.watch(httpClientProvider); - - return MusicSource( - SubsonicSource( - opt: settings, - http: http, - maxBitrate: maxBitrate, - streamFormat: streamFormat, - ), - ref, - ); -} - -@Riverpod(keepAlive: true) -Stream networkMode(NetworkModeRef ref) async* { - await for (var state in Connectivity().onConnectivityChanged) { - switch (state) { - case ConnectivityResult.wifi: - case ConnectivityResult.ethernet: - yield NetworkMode.wifi; - break; - default: - yield NetworkMode.mobile; - break; - } - } -} - -@Riverpod(keepAlive: true) -Future maxBitrate(MaxBitrateRef ref) async { - final settings = ref.watch(settingsServiceProvider.select( - (value) => value.app, - )); - final networkMode = ref.watch(networkModeProvider).requireValue; - - return networkMode == NetworkMode.wifi - ? settings.maxBitrateWifi - : settings.maxBitrateMobile; -} - -@Riverpod(keepAlive: true) -int sourceId(SourceIdRef ref) { - return ref.watch(musicSourceProvider.select((value) => value.id)); -} - -@Riverpod(keepAlive: true) -class OfflineMode extends _$OfflineMode { - @override - bool build() { - return false; - } - - Future setMode(bool value) async { - final hasSource = ref.read(settingsServiceProvider.select( - (value) => value.activeSource != null, - )); - if (!hasSource) return; - - if (value == false && state == true) { - try { - await ref.read(musicSourceProvider).ping(); - } catch (err) { - return; - } - } - state = value; - } -} diff --git a/lib/state/settings.g.dart b/lib/state/settings.g.dart deleted file mode 100644 index a8681d81..00000000 --- a/lib/state/settings.g.dart +++ /dev/null @@ -1,79 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'settings.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$musicSourceHash() => r'466e2654eab8518c9e40c8c2c08a2ecb331b0a7f'; - -/// See also [musicSource]. -@ProviderFor(musicSource) -final musicSourceProvider = Provider.internal( - musicSource, - name: r'musicSourceProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$musicSourceHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef MusicSourceRef = ProviderRef; -String _$networkModeHash() => r'813a60a454c6acaefbe3b56bf0152497ab18dcce'; - -/// See also [networkMode]. -@ProviderFor(networkMode) -final networkModeProvider = StreamProvider.internal( - networkMode, - name: r'networkModeProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$networkModeHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef NetworkModeRef = StreamProviderRef; -String _$maxBitrateHash() => r'ec02d3ccbc9f3429acfc1b3f191cab791b1191e0'; - -/// See also [maxBitrate]. -@ProviderFor(maxBitrate) -final maxBitrateProvider = FutureProvider.internal( - maxBitrate, - name: r'maxBitrateProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$maxBitrateHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef MaxBitrateRef = FutureProviderRef; -String _$sourceIdHash() => r'66ed4717b4a07548f5e25a42aeac2027aeab9b9c'; - -/// See also [sourceId]. -@ProviderFor(sourceId) -final sourceIdProvider = Provider.internal( - sourceId, - name: r'sourceIdProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$sourceIdHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef SourceIdRef = ProviderRef; -String _$offlineModeHash() => r'b84cdece48d97c69e995fbaea97febb128cfc20a'; - -/// See also [OfflineMode]. -@ProviderFor(OfflineMode) -final offlineModeProvider = NotifierProvider.internal( - OfflineMode.new, - name: r'offlineModeProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$offlineModeHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$OfflineMode = Notifier; -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/lib/state/theme.dart b/lib/state/theme.dart deleted file mode 100644 index da78ae8b..00000000 --- a/lib/state/theme.dart +++ /dev/null @@ -1,258 +0,0 @@ -import 'dart:async'; -import 'dart:typed_data'; -import 'dart:ui' as ui; - -import 'package:flutter/material.dart'; -import 'package:palette_generator/palette_generator.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; -import 'package:worker_manager/worker_manager.dart'; - -import '../cache/image_cache.dart'; -import '../models/support.dart'; -import '../services/cache_service.dart'; -import 'audio.dart'; -import 'music.dart'; - -part 'theme.g.dart'; - -const kDarkBackgroundValue = 0.28; -const kDarkerBackgroundLightness = 0.13; -const kOnDarkerBackgroundLightness = 0.6; - -PaletteColor? _rankedByLuminance( - List colors, [ - double minLuminance = 0.0, - double maxLuminance = 1.0, -]) { - for (var color in colors) { - if (color == null) { - continue; - } - - final luminance = color.color.computeLuminance(); - if (luminance >= minLuminance && luminance <= maxLuminance) { - return color; - } - } - - return null; -} - -PaletteColor? _rankedWithValue(double value, List colors) { - for (var color in colors) { - if (color == null) { - continue; - } - - final hsv = HSVColor.fromColor(color.color); - if (hsv.value > value) { - return PaletteColor(hsv.withValue(value).toColor(), 0); - } - } - - return null; -} - -@riverpod -ColorTheme _colorTheme(_ColorThemeRef ref, Palette palette) { - final base = ref.watch(baseThemeProvider); - - final primary = _rankedByLuminance([ - palette.dominantColor, - palette.vibrantColor, - palette.mutedColor, - palette.darkVibrantColor, - ], 0.2); - final vibrant = _rankedByLuminance([ - palette.vibrantColor, - palette.darkVibrantColor, - palette.dominantColor, - ], 0.05); - final secondary = _rankedByLuminance([ - palette.lightMutedColor, - palette.mutedColor, - palette.darkMutedColor, - ]); - - final background = _rankedWithValue(0.5, [ - palette.vibrantColor, - palette.darkVibrantColor, - palette.darkMutedColor, - palette.dominantColor, - palette.mutedColor, - palette.lightVibrantColor, - palette.lightMutedColor, - ]); - - final colorScheme = ColorScheme.fromSeed( - brightness: Brightness.dark, - seedColor: background?.color ?? Colors.purple[800]!, - background: background?.color, - primaryContainer: primary?.color, - onPrimaryContainer: primary?.bodyTextColor, - secondaryContainer: secondary?.color, - onSecondaryContainer: secondary?.bodyTextColor, - surface: background?.color, - surfaceTint: vibrant?.color, - ); - - final hsv = HSVColor.fromColor(colorScheme.background); - final hsl = HSLColor.fromColor(colorScheme.background); - - return base.copyWith( - theme: ThemeData( - colorScheme: colorScheme, - useMaterial3: base.theme.useMaterial3, - brightness: base.theme.brightness, - cardTheme: base.theme.cardTheme, - ), - gradientHigh: colorScheme.background, - darkBackground: hsv.withValue(kDarkBackgroundValue).toColor(), - darkerBackground: hsl.withLightness(kDarkerBackgroundLightness).toColor(), - onDarkerBackground: - hsl.withLightness(kOnDarkerBackgroundLightness).toColor(), - ); -} - -@riverpod -ColorTheme baseTheme(BaseThemeRef ref) { - final theme = ThemeData( - useMaterial3: true, - colorSchemeSeed: Colors.purple[800], - brightness: Brightness.dark, - cardTheme: CardTheme( - clipBehavior: Clip.antiAlias, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(2), - ), - ), - ); - - final hsv = HSVColor.fromColor(theme.colorScheme.background); - final hsl = HSLColor.fromColor(theme.colorScheme.background); - - return ColorTheme( - theme: theme, - gradientHigh: theme.colorScheme.background, - gradientLow: HSLColor.fromColor(theme.colorScheme.background) - .withLightness(0.06) - .toColor(), - darkBackground: hsv.withValue(kDarkBackgroundValue).toColor(), - darkerBackground: hsl.withLightness(kDarkerBackgroundLightness).toColor(), - onDarkerBackground: - hsl.withLightness(kOnDarkerBackgroundLightness).toColor(), - ); -} - -@riverpod -FutureOr albumArtPalette( - AlbumArtPaletteRef ref, - String id, -) async { - final album = await ref.watch(albumProvider(id).future); - final cache = ref.watch(cacheServiceProvider); - final info = cache.albumArt(album, thumbnail: true); - - return Palette.fromPaletteGenerator(await _generateFromCache(info)); -} - -Future _generateFromCache( - UriCacheInfo cacheInfo, -) async { - var file = await cacheInfo.cacheManager.getSingleFile( - cacheInfo.uri.toString(), - key: cacheInfo.cacheKey, - ); - - final memoryImage = ResizeImage( - MemoryImage(await file.readAsBytes()), - height: 32, - width: 32, - ); - final stream = memoryImage.resolve(const ImageConfiguration( - devicePixelRatio: 1.0, - )); - - Completer imageCompleter = Completer(); - late ImageStreamListener listener; - listener = ImageStreamListener((ImageInfo info, bool synchronousCall) { - stream.removeListener(listener); - imageCompleter.complete(info.image); - }); - - stream.addListener(listener); - final image = await imageCompleter.future; - final byteData = (await image.toByteData())!; - final height = image.height; - final width = image.width; - - return await Executor().execute( - arg1: byteData, - arg2: height, - arg3: width, - fun3: _computePalette, - ); -} - -Future _computePalette( - ByteData byteData, - int height, - int width, - TypeSendPort port, -) async { - return await PaletteGenerator.fromByteData( - EncodedImage(byteData, height: height, width: width), - ); -} - -@riverpod -FutureOr playlistArtPalette( - PlaylistArtPaletteRef ref, - String id, -) async { - final playlist = await ref.watch(playlistProvider(id).future); - final cache = ref.watch(cacheServiceProvider); - final info = cache.playlistArt(playlist, thumbnail: true); - - return Palette.fromPaletteGenerator(await _generateFromCache(info)); -} - -@riverpod -FutureOr mediaItemPalette(MediaItemPaletteRef ref) async { - final item = ref.watch(mediaItemProvider).valueOrNull; - final itemData = ref.watch(mediaItemDataProvider); - final imageCache = ref.watch(imageCacheProvider); - - if (item == null || item.artUri == null || itemData == null) { - return const Palette(); - } - - return Palette.fromPaletteGenerator(await _generateFromCache( - UriCacheInfo( - uri: item.artUri!, - cacheKey: itemData.artCache!.thumbnailArtCacheKey, - cacheManager: imageCache, - ), - )); -} - -@riverpod -FutureOr mediaItemTheme(MediaItemThemeRef ref) async { - final palette = await ref.watch(mediaItemPaletteProvider.future); - return ref.watch(_colorThemeProvider(palette)); -} - -@riverpod -FutureOr albumArtTheme(AlbumArtThemeRef ref, String id) async { - final palette = await ref.watch(albumArtPaletteProvider(id).future); - return ref.watch(_colorThemeProvider(palette)); -} - -@riverpod -FutureOr playlistArtTheme( - PlaylistArtThemeRef ref, - String id, -) async { - final palette = await ref.watch(playlistArtPaletteProvider(id).future); - return ref.watch(_colorThemeProvider(palette)); -} diff --git a/lib/state/theme.g.dart b/lib/state/theme.g.dart deleted file mode 100644 index 1fdb0bf3..00000000 --- a/lib/state/theme.g.dart +++ /dev/null @@ -1,485 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'theme.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$colorThemeHash() => r'f5cc23cb5e2af379c02ae4b9756df72f9f6da5e6'; - -/// Copied from Dart SDK -class _SystemHash { - _SystemHash._(); - - static int combine(int hash, int value) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + value); - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - return hash ^ (hash >> 6); - } - - static int finish(int hash) { - // ignore: parameter_assignments - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - // ignore: parameter_assignments - hash = hash ^ (hash >> 11); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } -} - -typedef _ColorThemeRef = AutoDisposeProviderRef; - -/// See also [_colorTheme]. -@ProviderFor(_colorTheme) -const _colorThemeProvider = _ColorThemeFamily(); - -/// See also [_colorTheme]. -class _ColorThemeFamily extends Family { - /// See also [_colorTheme]. - const _ColorThemeFamily(); - - /// See also [_colorTheme]. - _ColorThemeProvider call( - Palette palette, - ) { - return _ColorThemeProvider( - palette, - ); - } - - @override - _ColorThemeProvider getProviderOverride( - covariant _ColorThemeProvider provider, - ) { - return call( - provider.palette, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'_colorThemeProvider'; -} - -/// See also [_colorTheme]. -class _ColorThemeProvider extends AutoDisposeProvider { - /// See also [_colorTheme]. - _ColorThemeProvider( - this.palette, - ) : super.internal( - (ref) => _colorTheme( - ref, - palette, - ), - from: _colorThemeProvider, - name: r'_colorThemeProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$colorThemeHash, - dependencies: _ColorThemeFamily._dependencies, - allTransitiveDependencies: - _ColorThemeFamily._allTransitiveDependencies, - ); - - final Palette palette; - - @override - bool operator ==(Object other) { - return other is _ColorThemeProvider && other.palette == palette; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, palette.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$baseThemeHash() => r'317a5ef77def208357a54b7938ef3d91666fce70'; - -/// See also [baseTheme]. -@ProviderFor(baseTheme) -final baseThemeProvider = AutoDisposeProvider.internal( - baseTheme, - name: r'baseThemeProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$baseThemeHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef BaseThemeRef = AutoDisposeProviderRef; -String _$albumArtPaletteHash() => r'8130b954ee3c67f53207593d4ed3dfbffb00c95d'; -typedef AlbumArtPaletteRef = AutoDisposeFutureProviderRef; - -/// See also [albumArtPalette]. -@ProviderFor(albumArtPalette) -const albumArtPaletteProvider = AlbumArtPaletteFamily(); - -/// See also [albumArtPalette]. -class AlbumArtPaletteFamily extends Family> { - /// See also [albumArtPalette]. - const AlbumArtPaletteFamily(); - - /// See also [albumArtPalette]. - AlbumArtPaletteProvider call( - String id, - ) { - return AlbumArtPaletteProvider( - id, - ); - } - - @override - AlbumArtPaletteProvider getProviderOverride( - covariant AlbumArtPaletteProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'albumArtPaletteProvider'; -} - -/// See also [albumArtPalette]. -class AlbumArtPaletteProvider extends AutoDisposeFutureProvider { - /// See also [albumArtPalette]. - AlbumArtPaletteProvider( - this.id, - ) : super.internal( - (ref) => albumArtPalette( - ref, - id, - ), - from: albumArtPaletteProvider, - name: r'albumArtPaletteProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$albumArtPaletteHash, - dependencies: AlbumArtPaletteFamily._dependencies, - allTransitiveDependencies: - AlbumArtPaletteFamily._allTransitiveDependencies, - ); - - final String id; - - @override - bool operator ==(Object other) { - return other is AlbumArtPaletteProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$playlistArtPaletteHash() => - r'6bc015688f354ea8d91dde86e2a7191ef1ef6496'; -typedef PlaylistArtPaletteRef = AutoDisposeFutureProviderRef; - -/// See also [playlistArtPalette]. -@ProviderFor(playlistArtPalette) -const playlistArtPaletteProvider = PlaylistArtPaletteFamily(); - -/// See also [playlistArtPalette]. -class PlaylistArtPaletteFamily extends Family> { - /// See also [playlistArtPalette]. - const PlaylistArtPaletteFamily(); - - /// See also [playlistArtPalette]. - PlaylistArtPaletteProvider call( - String id, - ) { - return PlaylistArtPaletteProvider( - id, - ); - } - - @override - PlaylistArtPaletteProvider getProviderOverride( - covariant PlaylistArtPaletteProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'playlistArtPaletteProvider'; -} - -/// See also [playlistArtPalette]. -class PlaylistArtPaletteProvider extends AutoDisposeFutureProvider { - /// See also [playlistArtPalette]. - PlaylistArtPaletteProvider( - this.id, - ) : super.internal( - (ref) => playlistArtPalette( - ref, - id, - ), - from: playlistArtPaletteProvider, - name: r'playlistArtPaletteProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$playlistArtPaletteHash, - dependencies: PlaylistArtPaletteFamily._dependencies, - allTransitiveDependencies: - PlaylistArtPaletteFamily._allTransitiveDependencies, - ); - - final String id; - - @override - bool operator ==(Object other) { - return other is PlaylistArtPaletteProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$mediaItemPaletteHash() => r'2f2744aa735c6056919197c283a367714d7e04e4'; - -/// See also [mediaItemPalette]. -@ProviderFor(mediaItemPalette) -final mediaItemPaletteProvider = AutoDisposeFutureProvider.internal( - mediaItemPalette, - name: r'mediaItemPaletteProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$mediaItemPaletteHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef MediaItemPaletteRef = AutoDisposeFutureProviderRef; -String _$mediaItemThemeHash() => r'f43e6f86eeed7aef33fa8bd2695454a760f41afa'; - -/// See also [mediaItemTheme]. -@ProviderFor(mediaItemTheme) -final mediaItemThemeProvider = AutoDisposeFutureProvider.internal( - mediaItemTheme, - name: r'mediaItemThemeProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$mediaItemThemeHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef MediaItemThemeRef = AutoDisposeFutureProviderRef; -String _$albumArtThemeHash() => r'd3ee71b2df856f1763ec925e158ae2e0f613b9e0'; -typedef AlbumArtThemeRef = AutoDisposeFutureProviderRef; - -/// See also [albumArtTheme]. -@ProviderFor(albumArtTheme) -const albumArtThemeProvider = AlbumArtThemeFamily(); - -/// See also [albumArtTheme]. -class AlbumArtThemeFamily extends Family> { - /// See also [albumArtTheme]. - const AlbumArtThemeFamily(); - - /// See also [albumArtTheme]. - AlbumArtThemeProvider call( - String id, - ) { - return AlbumArtThemeProvider( - id, - ); - } - - @override - AlbumArtThemeProvider getProviderOverride( - covariant AlbumArtThemeProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'albumArtThemeProvider'; -} - -/// See also [albumArtTheme]. -class AlbumArtThemeProvider extends AutoDisposeFutureProvider { - /// See also [albumArtTheme]. - AlbumArtThemeProvider( - this.id, - ) : super.internal( - (ref) => albumArtTheme( - ref, - id, - ), - from: albumArtThemeProvider, - name: r'albumArtThemeProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$albumArtThemeHash, - dependencies: AlbumArtThemeFamily._dependencies, - allTransitiveDependencies: - AlbumArtThemeFamily._allTransitiveDependencies, - ); - - final String id; - - @override - bool operator ==(Object other) { - return other is AlbumArtThemeProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} - -String _$playlistArtThemeHash() => r'1629552e1f3aa2a1e7d223ac1e078893042e5e3b'; -typedef PlaylistArtThemeRef = AutoDisposeFutureProviderRef; - -/// See also [playlistArtTheme]. -@ProviderFor(playlistArtTheme) -const playlistArtThemeProvider = PlaylistArtThemeFamily(); - -/// See also [playlistArtTheme]. -class PlaylistArtThemeFamily extends Family> { - /// See also [playlistArtTheme]. - const PlaylistArtThemeFamily(); - - /// See also [playlistArtTheme]. - PlaylistArtThemeProvider call( - String id, - ) { - return PlaylistArtThemeProvider( - id, - ); - } - - @override - PlaylistArtThemeProvider getProviderOverride( - covariant PlaylistArtThemeProvider provider, - ) { - return call( - provider.id, - ); - } - - static const Iterable? _dependencies = null; - - @override - Iterable? get dependencies => _dependencies; - - static const Iterable? _allTransitiveDependencies = null; - - @override - Iterable? get allTransitiveDependencies => - _allTransitiveDependencies; - - @override - String? get name => r'playlistArtThemeProvider'; -} - -/// See also [playlistArtTheme]. -class PlaylistArtThemeProvider extends AutoDisposeFutureProvider { - /// See also [playlistArtTheme]. - PlaylistArtThemeProvider( - this.id, - ) : super.internal( - (ref) => playlistArtTheme( - ref, - id, - ), - from: playlistArtThemeProvider, - name: r'playlistArtThemeProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') - ? null - : _$playlistArtThemeHash, - dependencies: PlaylistArtThemeFamily._dependencies, - allTransitiveDependencies: - PlaylistArtThemeFamily._allTransitiveDependencies, - ); - - final String id; - - @override - bool operator ==(Object other) { - return other is PlaylistArtThemeProvider && other.id == id; - } - - @override - int get hashCode { - var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, id.hashCode); - - return _SystemHash.finish(hash); - } -} -// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index 1d12ea25..00000000 --- a/pubspec.lock +++ /dev/null @@ -1,1384 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - sha256: a36ec4843dc30ea6bf652bf25e3448db6c5e8bcf4aa55f063a5d1dad216d8214 - url: "https://pub.dev" - source: hosted - version: "58.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - sha256: cc4242565347e98424ce9945c819c192ec0838cb9d1f6aa4a97cc96becbc5b27 - url: "https://pub.dev" - source: hosted - version: "5.10.0" - analyzer_plugin: - dependency: transitive - description: - name: analyzer_plugin - sha256: c1d5f167683de03d5ab6c3b53fc9aeefc5d59476e7810ba7bbddff50c6f4392d - url: "https://pub.dev" - source: hosted - version: "0.11.2" - args: - dependency: transitive - description: - name: args - sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440" - url: "https://pub.dev" - source: hosted - version: "2.4.0" - async: - dependency: transitive - description: - name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 - url: "https://pub.dev" - source: hosted - version: "2.10.0" - audio_service: - dependency: "direct main" - description: - path: audio_service - ref: "features/cache-key-resolver" - resolved-ref: "6d5299d699ef40ea28742879b03e33c028eb2e84" - url: "https://github.com/austinried/audio_service" - source: git - version: "0.18.10" - audio_service_platform_interface: - dependency: transitive - description: - name: audio_service_platform_interface - sha256: "2c3a1d52803931e836b9693547a71c0c3585ad54219d2214219ed5cfcc3c1af4" - url: "https://pub.dev" - source: hosted - version: "0.1.0" - audio_service_web: - dependency: transitive - description: - name: audio_service_web - sha256: "523e64ddc914c714d53eec2da85bba1074f08cf26c786d4efb322de510815ea7" - url: "https://pub.dev" - source: hosted - version: "0.1.1" - audio_session: - dependency: transitive - description: - name: audio_session - sha256: e4acc4e9eaa32436dfc5d7aed7f0a370f2d7bb27ee27de30d6c4f220c2a05c73 - url: "https://pub.dev" - source: hosted - version: "0.1.13" - auto_route: - dependency: "direct main" - description: - name: auto_route - sha256: "12047baeca0e01df93165ef33275b32119d72699ab9a49dc64c20e78f586f96d" - url: "https://pub.dev" - source: hosted - version: "5.0.4" - auto_route_generator: - dependency: "direct dev" - description: - name: auto_route_generator - sha256: de5bfbc02ae4eebb339dd90d325749ae7536e903f6513ef72b88954072d72b0e - url: "https://pub.dev" - source: hosted - version: "5.0.3" - auto_size_text: - dependency: "direct main" - description: - name: auto_size_text - sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599" - url: "https://pub.dev" - source: hosted - version: "3.0.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - build: - dependency: transitive - description: - name: build - sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" - url: "https://pub.dev" - source: hosted - version: "2.3.1" - build_config: - dependency: transitive - description: - name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 - url: "https://pub.dev" - source: hosted - version: "1.1.1" - build_daemon: - dependency: transitive - description: - name: build_daemon - sha256: "757153e5d9cd88253cb13f28c2fb55a537dc31fefd98137549895b5beb7c6169" - url: "https://pub.dev" - source: hosted - version: "3.1.1" - build_resolvers: - dependency: transitive - description: - name: build_resolvers - sha256: db49b8609ef8c81cca2b310618c3017c00f03a92af44c04d310b907b2d692d95 - url: "https://pub.dev" - source: hosted - version: "2.2.0" - build_runner: - dependency: "direct dev" - description: - name: build_runner - sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727 - url: "https://pub.dev" - source: hosted - version: "2.3.3" - build_runner_core: - dependency: transitive - description: - name: build_runner_core - sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292" - url: "https://pub.dev" - source: hosted - version: "7.2.7" - built_collection: - dependency: transitive - description: - name: built_collection - sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" - url: "https://pub.dev" - source: hosted - version: "5.1.1" - built_value: - dependency: transitive - description: - name: built_value - sha256: "31b7c748fd4b9adf8d25d72a4c4a59ef119f12876cf414f94f8af5131d5fa2b0" - url: "https://pub.dev" - source: hosted - version: "8.4.4" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15 - url: "https://pub.dev" - source: hosted - version: "3.2.3" - cached_network_image_platform_interface: - dependency: transitive - description: - name: cached_network_image_platform_interface - sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7 - url: "https://pub.dev" - source: hosted - version: "2.0.0" - cached_network_image_web: - dependency: transitive - description: - name: cached_network_image_web - sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0 - url: "https://pub.dev" - source: hosted - version: "1.0.2" - characters: - dependency: transitive - description: - name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c - url: "https://pub.dev" - source: hosted - version: "1.2.1" - charcode: - dependency: transitive - description: - name: charcode - sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 - url: "https://pub.dev" - source: hosted - version: "1.3.1" - checked_yaml: - dependency: transitive - description: - name: checked_yaml - sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - ci: - dependency: transitive - description: - name: ci - sha256: "145d095ce05cddac4d797a158bc4cf3b6016d1fe63d8c3d2fbd7212590adca13" - url: "https://pub.dev" - source: hosted - version: "0.1.0" - cli_util: - dependency: transitive - description: - name: cli_util - sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 - url: "https://pub.dev" - source: hosted - version: "0.4.0" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - code_builder: - dependency: transitive - description: - name: code_builder - sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe" - url: "https://pub.dev" - source: hosted - version: "4.4.0" - collection: - dependency: "direct main" - description: - name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 - url: "https://pub.dev" - source: hosted - version: "1.17.0" - connectivity_plus: - dependency: "direct main" - description: - name: connectivity_plus - sha256: d73575bb66216738db892f72ba67dc478bd3b5490fbbcf43644b57645eabc822 - url: "https://pub.dev" - source: hosted - version: "3.0.4" - connectivity_plus_platform_interface: - dependency: transitive - description: - name: connectivity_plus_platform_interface - sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a - url: "https://pub.dev" - source: hosted - version: "1.2.4" - convert: - dependency: transitive - description: - name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" - url: "https://pub.dev" - source: hosted - version: "3.1.1" - coverage: - dependency: transitive - description: - name: coverage - sha256: "2fb815080e44a09b85e0f2ca8a820b15053982b2e714b59267719e8a9ff17097" - url: "https://pub.dev" - source: hosted - version: "1.6.3" - cross_file: - dependency: transitive - description: - name: cross_file - sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" - url: "https://pub.dev" - source: hosted - version: "0.3.3+4" - crypto: - dependency: "direct main" - description: - name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 - url: "https://pub.dev" - source: hosted - version: "3.0.2" - custom_lint: - dependency: transitive - description: - name: custom_lint - sha256: "80ccf10b30d4f1d0b40bd6d276a86d72266569c0a7542f1b839daf2fd05c16a5" - url: "https://pub.dev" - source: hosted - version: "0.3.3" - custom_lint_core: - dependency: transitive - description: - name: custom_lint_core - sha256: "83bf91d1e4ef2a893bd9a7cefaede25a4e93b47779f71a2fed33d9122e3f02c9" - url: "https://pub.dev" - source: hosted - version: "0.3.3" - dart_style: - dependency: transitive - description: - name: dart_style - sha256: "6d691edde054969f0e0f26abb1b30834b5138b963793e56f69d3a9a4435e6352" - url: "https://pub.dev" - source: hosted - version: "2.3.0" - dbus: - dependency: transitive - description: - name: dbus - sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" - url: "https://pub.dev" - source: hosted - version: "0.7.8" - drift: - dependency: "direct main" - description: - name: drift - sha256: "1eaef0a152f1b3dc2e3ad3b04f900794bbe5a2833c26a85794ed1f7e5b7320ce" - url: "https://pub.dev" - source: hosted - version: "2.7.0" - drift_dev: - dependency: "direct dev" - description: - name: drift_dev - sha256: b6c2b1bcf637d34142bf9a0c21d1d290ade2254538be00559360db165b524381 - url: "https://pub.dev" - source: hosted - version: "2.7.0" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - fast_immutable_collections: - dependency: "direct main" - description: - name: fast_immutable_collections - sha256: "60d68b272a33f919da05cd5f6dddcc69f62ace6a81b29f87a23b54a9126c971e" - url: "https://pub.dev" - source: hosted - version: "9.0.0" - ffi: - dependency: transitive - description: - name: ffi - sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 - url: "https://pub.dev" - source: hosted - version: "2.0.1" - file: - dependency: transitive - description: - name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" - url: "https://pub.dev" - source: hosted - version: "6.1.4" - fixnum: - dependency: transitive - description: - name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_blurhash: - dependency: transitive - description: - name: flutter_blurhash - sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6" - url: "https://pub.dev" - source: hosted - version: "0.7.0" - flutter_cache_manager: - dependency: "direct main" - description: - name: flutter_cache_manager - sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3" - url: "https://pub.dev" - source: hosted - version: "3.3.0" - flutter_dotenv: - dependency: "direct main" - description: - name: flutter_dotenv - sha256: d9283d92059a22e9834bc0a31336658ffba77089fb6f3cc36751f1fc7c6661a3 - url: "https://pub.dev" - source: hosted - version: "5.0.2" - flutter_downloader: - dependency: "direct main" - description: - name: flutter_downloader - sha256: "6f2836668f33d0cd3ed275c3198d30967c42af53fa9b18c6b0edbf5fc12b599a" - url: "https://pub.dev" - source: hosted - version: "1.10.2" - flutter_hooks: - dependency: "direct main" - description: - name: flutter_hooks - sha256: "6a126f703b89499818d73305e4ce1e3de33b4ae1c5512e3b8eab4b986f46774c" - url: "https://pub.dev" - source: hosted - version: "0.18.6" - flutter_keyboard_visibility: - dependency: "direct main" - description: - name: flutter_keyboard_visibility - sha256: "86b71bbaffa38e885f5c21b1182408b9be6951fd125432cf6652c636254cef2d" - url: "https://pub.dev" - source: hosted - version: "5.4.0" - flutter_keyboard_visibility_linux: - dependency: transitive - description: - name: flutter_keyboard_visibility_linux - sha256: "6fba7cd9bb033b6ddd8c2beb4c99ad02d728f1e6e6d9b9446667398b2ac39f08" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - flutter_keyboard_visibility_macos: - dependency: transitive - description: - name: flutter_keyboard_visibility_macos - sha256: c5c49b16fff453dfdafdc16f26bdd8fb8d55812a1d50b0ce25fc8d9f2e53d086 - url: "https://pub.dev" - source: hosted - version: "1.0.0" - flutter_keyboard_visibility_platform_interface: - dependency: transitive - description: - name: flutter_keyboard_visibility_platform_interface - sha256: e43a89845873f7be10cb3884345ceb9aebf00a659f479d1c8f4293fcb37022a4 - url: "https://pub.dev" - source: hosted - version: "2.0.0" - flutter_keyboard_visibility_web: - dependency: transitive - description: - name: flutter_keyboard_visibility_web - sha256: d3771a2e752880c79203f8d80658401d0c998e4183edca05a149f5098ce6e3d1 - url: "https://pub.dev" - source: hosted - version: "2.0.0" - flutter_keyboard_visibility_windows: - dependency: transitive - description: - name: flutter_keyboard_visibility_windows - sha256: fc4b0f0b6be9b93ae527f3d527fb56ee2d918cd88bbca438c478af7bcfd0ef73 - url: "https://pub.dev" - source: hosted - version: "1.0.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c - url: "https://pub.dev" - source: hosted - version: "2.0.1" - flutter_localizations: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_riverpod: - dependency: transitive - description: - name: flutter_riverpod - sha256: "812dfbb87af51e73e68ea038bcfd1c732078d6838d3388d03283db7dec0d1e5f" - url: "https://pub.dev" - source: hosted - version: "2.3.4" - flutter_staggered_grid_view: - dependency: "direct main" - description: - name: flutter_staggered_grid_view - sha256: "1312314293acceb65b92754298754801b0e1f26a1845833b740b30415bbbcf07" - url: "https://pub.dev" - source: hosted - version: "0.6.2" - flutter_svg: - dependency: "direct main" - description: - name: flutter_svg - sha256: f991fdb1533c3caeee0cdc14b04f50f0c3916f0dbcbc05237ccbe4e3c6b93f3f - url: "https://pub.dev" - source: hosted - version: "2.0.5" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - freezed: - dependency: "direct dev" - description: - name: freezed - sha256: e819441678f1679b719008ff2ff0ef045d66eed9f9ec81166ca0d9b02a187454 - url: "https://pub.dev" - source: hosted - version: "2.3.2" - freezed_annotation: - dependency: "direct main" - description: - name: freezed_annotation - sha256: aeac15850ef1b38ee368d4c53ba9a847e900bb2c53a4db3f6881cbb3cb684338 - url: "https://pub.dev" - source: hosted - version: "2.2.0" - frontend_server_client: - dependency: transitive - description: - name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" - url: "https://pub.dev" - source: hosted - version: "3.2.0" - glob: - dependency: transitive - description: - name: glob - sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - graphs: - dependency: transitive - description: - name: graphs - sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2 - url: "https://pub.dev" - source: hosted - version: "2.2.0" - hooks_riverpod: - dependency: "direct main" - description: - name: hooks_riverpod - sha256: eceb62b7e3a18e6c2831498c3f2ea5b42c0a938c95d0c1eb1b8a7ccdd022accc - url: "https://pub.dev" - source: hosted - version: "2.3.4" - http: - dependency: "direct main" - description: - name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" - url: "https://pub.dev" - source: hosted - version: "0.13.5" - http_multi_server: - dependency: transitive - description: - name: http_multi_server - sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - infinite_scroll_pagination: - dependency: "direct main" - description: - name: infinite_scroll_pagination - sha256: "9517328f4e373f08f57dbb11c5aac5b05554142024d6b60c903f3b73476d52db" - url: "https://pub.dev" - source: hosted - version: "3.2.0" - intl: - dependency: "direct main" - description: - name: intl - sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 - url: "https://pub.dev" - source: hosted - version: "0.18.0" - io: - dependency: transitive - description: - name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" - url: "https://pub.dev" - source: hosted - version: "1.0.4" - js: - dependency: transitive - description: - name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" - url: "https://pub.dev" - source: hosted - version: "0.6.5" - json_annotation: - dependency: "direct main" - description: - name: json_annotation - sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317 - url: "https://pub.dev" - source: hosted - version: "4.8.0" - json_serializable: - dependency: "direct dev" - description: - name: json_serializable - sha256: dadc08bd61f72559f938dd08ec20dbfec6c709bba83515085ea943d2078d187a - url: "https://pub.dev" - source: hosted - version: "6.6.1" - just_audio: - dependency: "direct main" - description: - name: just_audio - sha256: "7e6d31508dacd01a066e3889caf6282e5f1eb60707c230203b21a83af5c55586" - url: "https://pub.dev" - source: hosted - version: "0.9.32" - just_audio_platform_interface: - dependency: transitive - description: - name: just_audio_platform_interface - sha256: eff112d5138bea3ba544b6338b1e0537a32b5e1425e4d0dc38f732771cda7c84 - url: "https://pub.dev" - source: hosted - version: "4.2.0" - just_audio_web: - dependency: transitive - description: - name: just_audio_web - sha256: "89d8db6f19f3821bb6bf908c4bfb846079afb2ab575b783d781a6bf119e3abaf" - url: "https://pub.dev" - source: hosted - version: "0.4.7" - lints: - dependency: transitive - description: - name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - logging: - dependency: "direct main" - description: - name: logging - sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - matcher: - dependency: transitive - description: - name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" - url: "https://pub.dev" - source: hosted - version: "0.12.13" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 - url: "https://pub.dev" - source: hosted - version: "0.2.0" - meta: - dependency: transitive - description: - name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" - url: "https://pub.dev" - source: hosted - version: "1.8.0" - mime: - dependency: "direct main" - description: - name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e - url: "https://pub.dev" - source: hosted - version: "1.0.4" - nm: - dependency: transitive - description: - name: nm - sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" - url: "https://pub.dev" - source: hosted - version: "0.5.0" - node_preamble: - dependency: transitive - description: - name: node_preamble - sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - octo_image: - dependency: transitive - description: - name: octo_image - sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - package_config: - dependency: transitive - description: - name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - package_info_plus: - dependency: "direct main" - description: - name: package_info_plus - sha256: de41e74b0ea9a3e524c68f35099af1fdeb4885625aeb277d2e01a42d6bd7b293 - url: "https://pub.dev" - source: hosted - version: "3.1.1" - package_info_plus_platform_interface: - dependency: transitive - description: - name: package_info_plus_platform_interface - sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - palette_generator: - dependency: "direct main" - description: - name: palette_generator - sha256: "0e3cd6974e10b1434dcf4cf779efddb80e2696585e273a2dbede6af52f94568d" - url: "https://pub.dev" - source: hosted - version: "0.3.3+2" - path: - dependency: "direct main" - description: - name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b - url: "https://pub.dev" - source: hosted - version: "1.8.2" - path_parsing: - dependency: transitive - description: - name: path_parsing - sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf - url: "https://pub.dev" - source: hosted - version: "1.0.1" - path_provider: - dependency: "direct main" - description: - name: path_provider - sha256: c7edf82217d4b2952b2129a61d3ad60f1075b9299e629e149a8d2e39c2e6aad4 - url: "https://pub.dev" - source: hosted - version: "2.0.14" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - sha256: "019f18c9c10ae370b08dce1f3e3b73bc9f58e7f087bb5e921f06529438ac0ae7" - url: "https://pub.dev" - source: hosted - version: "2.0.24" - path_provider_foundation: - dependency: transitive - description: - name: path_provider_foundation - sha256: "818b2dc38b0f178e0ea3f7cf3b28146faab11375985d815942a68eee11c2d0f7" - url: "https://pub.dev" - source: hosted - version: "2.2.1" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1" - url: "https://pub.dev" - source: hosted - version: "2.1.10" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" - url: "https://pub.dev" - source: hosted - version: "2.0.6" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6 - url: "https://pub.dev" - source: hosted - version: "2.1.6" - pedantic: - dependency: transitive - description: - name: pedantic - sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" - url: "https://pub.dev" - source: hosted - version: "1.11.1" - petitparser: - dependency: transitive - description: - name: petitparser - sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" - url: "https://pub.dev" - source: hosted - version: "5.1.0" - platform: - dependency: transitive - description: - name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - pool: - dependency: "direct main" - description: - name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" - url: "https://pub.dev" - source: hosted - version: "1.5.1" - process: - dependency: transitive - description: - name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" - url: "https://pub.dev" - source: hosted - version: "4.2.4" - pub_semver: - dependency: transitive - description: - name: pub_semver - sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" - url: "https://pub.dev" - source: hosted - version: "2.1.3" - pubspec_parse: - dependency: transitive - description: - name: pubspec_parse - sha256: ec85d7d55339d85f44ec2b682a82fea340071e8978257e5a43e69f79e98ef50c - url: "https://pub.dev" - source: hosted - version: "1.2.2" - recase: - dependency: transitive - description: - name: recase - sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 - url: "https://pub.dev" - source: hosted - version: "4.1.0" - riverpod: - dependency: transitive - description: - name: riverpod - sha256: "77ab3bcd084bb19fa8717a526217787c725d7f5be938404c7839cd760fdf6ae5" - url: "https://pub.dev" - source: hosted - version: "2.3.4" - riverpod_analyzer_utils: - dependency: transitive - description: - name: riverpod_analyzer_utils - sha256: "34270111fa5843517e9ee63b1f906c756d99380f2aecbce52151aadb6d1c05a6" - url: "https://pub.dev" - source: hosted - version: "0.2.1" - riverpod_annotation: - dependency: "direct main" - description: - name: riverpod_annotation - sha256: afc01d5ba57e7993342c8d5120925826949455607ae29c8d98608ee840ee1cd6 - url: "https://pub.dev" - source: hosted - version: "2.0.4" - riverpod_generator: - dependency: "direct dev" - description: - name: riverpod_generator - sha256: decd5427a51603fc2add9b01f04874ac0bc6b5b6547343b8a5ccb0ba1a069943 - url: "https://pub.dev" - source: hosted - version: "2.1.6" - rxdart: - dependency: "direct main" - description: - name: rxdart - sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" - url: "https://pub.dev" - source: hosted - version: "0.27.7" - share_plus: - dependency: "direct main" - description: - name: share_plus - sha256: "322a1ec9d9fe07e2e2252c098ce93d12dbd06133cc4c00ffe6a4ef505c295c17" - url: "https://pub.dev" - source: hosted - version: "7.0.0" - share_plus_platform_interface: - dependency: transitive - description: - name: share_plus_platform_interface - sha256: "0c6e61471bd71b04a138b8b588fa388e66d8b005e6f2deda63371c5c505a0981" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - shelf: - dependency: transitive - description: - name: shelf - sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c - url: "https://pub.dev" - source: hosted - version: "1.4.0" - shelf_packages_handler: - dependency: transitive - description: - name: shelf_packages_handler - sha256: aef74dc9195746a384843102142ab65b6a4735bb3beea791e63527b88cc83306 - url: "https://pub.dev" - source: hosted - version: "3.0.1" - shelf_static: - dependency: transitive - description: - name: shelf_static - sha256: e792b76b96a36d4a41b819da593aff4bdd413576b3ba6150df5d8d9996d2e74c - url: "https://pub.dev" - source: hosted - version: "1.1.1" - shelf_web_socket: - dependency: transitive - description: - name: shelf_web_socket - sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 - url: "https://pub.dev" - source: hosted - version: "1.0.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - sliver_tools: - dependency: "direct main" - description: - name: sliver_tools - sha256: ccdc502098a8bfa07b3ec582c282620031481300035584e1bb3aca296a505e8c - url: "https://pub.dev" - source: hosted - version: "0.2.10" - source_gen: - dependency: transitive - description: - name: source_gen - sha256: c2bea18c95cfa0276a366270afaa2850b09b4a76db95d546f3d003dcc7011298 - url: "https://pub.dev" - source: hosted - version: "1.2.7" - source_helper: - dependency: transitive - description: - name: source_helper - sha256: "3b67aade1d52416149c633ba1bb36df44d97c6b51830c2198e934e3fca87ca1f" - url: "https://pub.dev" - source: hosted - version: "1.3.3" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - source_maps: - dependency: transitive - description: - name: source_maps - sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" - url: "https://pub.dev" - source: hosted - version: "0.10.12" - source_span: - dependency: transitive - description: - name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 - url: "https://pub.dev" - source: hosted - version: "1.9.1" - sqflite: - dependency: transitive - description: - name: sqflite - sha256: "500d6fec583d2c021f2d25a056d96654f910662c64f836cd2063167b8f1fa758" - url: "https://pub.dev" - source: hosted - version: "2.2.6" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - sha256: "963dad8c4aa2f814ce7d2d5b1da2f36f31bd1a439d8f27e3dc189bb9d26bc684" - url: "https://pub.dev" - source: hosted - version: "2.4.3" - sqlite3: - dependency: transitive - description: - name: sqlite3 - sha256: a3ba4b66a7ab170ce7aa3f5ac43c19ee8d6637afbe7b7c95c94112b4f4d91566 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - sqlite3_flutter_libs: - dependency: "direct main" - description: - name: sqlite3_flutter_libs - sha256: "02f80aea54a19a36b347dedf6d4181ecd9107f5831ea6139cfd0376a3de197ba" - url: "https://pub.dev" - source: hosted - version: "0.5.13" - sqlparser: - dependency: transitive - description: - name: sqlparser - sha256: "11ebfd764085a96261f44f90cbf475927c508e654d4be30ee4832d564d06d86b" - url: "https://pub.dev" - source: hosted - version: "0.28.1" - stack_trace: - dependency: "direct main" - description: - name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - state_notifier: - dependency: transitive - description: - name: state_notifier - sha256: "8fe42610f179b843b12371e40db58c9444f8757f8b69d181c97e50787caed289" - url: "https://pub.dev" - source: hosted - version: "0.7.2+1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - stream_transform: - dependency: transitive - description: - name: stream_transform - sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - synchronized: - dependency: "direct main" - description: - name: synchronized - sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test: - dependency: "direct dev" - description: - name: test - sha256: a5fcd2d25eeadbb6589e80198a47d6a464ba3e2049da473943b8af9797900c2d - url: "https://pub.dev" - source: hosted - version: "1.22.0" - test_api: - dependency: transitive - description: - name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 - url: "https://pub.dev" - source: hosted - version: "0.4.16" - test_core: - dependency: transitive - description: - name: test_core - sha256: "0ef9755ec6d746951ba0aabe62f874b707690b5ede0fecc818b138fcc9b14888" - url: "https://pub.dev" - source: hosted - version: "0.4.20" - text_scroll: - dependency: "direct main" - description: - name: text_scroll - sha256: "7869d86a6fdd725dee56bdd150216a99f0372b82fbfcac319214dbd5f36e1908" - url: "https://pub.dev" - source: hosted - version: "0.2.0" - timing: - dependency: transitive - description: - name: timing - sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" - url: "https://pub.dev" - source: hosted - version: "1.0.1" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - url_launcher: - dependency: "direct main" - description: - name: url_launcher - sha256: "75f2846facd11168d007529d6cd8fcb2b750186bea046af9711f10b907e1587e" - url: "https://pub.dev" - source: hosted - version: "6.1.10" - url_launcher_android: - dependency: transitive - description: - name: url_launcher_android - sha256: "40612cd31902fe46b5158693faa65781b1ca7adfb883d77fa6f0d6dcf0317d85" - url: "https://pub.dev" - source: hosted - version: "6.0.30" - url_launcher_ios: - dependency: transitive - description: - name: url_launcher_ios - sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2" - url: "https://pub.dev" - source: hosted - version: "6.1.4" - url_launcher_linux: - dependency: transitive - description: - name: url_launcher_linux - sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5" - url: "https://pub.dev" - source: hosted - version: "3.0.5" - url_launcher_macos: - dependency: transitive - description: - name: url_launcher_macos - sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e" - url: "https://pub.dev" - source: hosted - version: "3.0.5" - url_launcher_platform_interface: - dependency: transitive - description: - name: url_launcher_platform_interface - sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - url_launcher_web: - dependency: transitive - description: - name: url_launcher_web - sha256: "81fe91b6c4f84f222d186a9d23c73157dc4c8e1c71489c4d08be1ad3b228f1aa" - url: "https://pub.dev" - source: hosted - version: "2.0.16" - url_launcher_windows: - dependency: transitive - description: - name: url_launcher_windows - sha256: "254708f17f7c20a9c8c471f67d86d76d4a3f9c1591aad1e15292008aceb82771" - url: "https://pub.dev" - source: hosted - version: "3.0.6" - uuid: - dependency: transitive - description: - name: uuid - sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" - url: "https://pub.dev" - source: hosted - version: "3.0.7" - vector_graphics: - dependency: transitive - description: - name: vector_graphics - sha256: "4cf8e60dbe4d3a693d37dff11255a172594c0793da542183cbfe7fe978ae4aaa" - url: "https://pub.dev" - source: hosted - version: "1.1.4" - vector_graphics_codec: - dependency: transitive - description: - name: vector_graphics_codec - sha256: "278ad5f816f58b1967396d1f78ced470e3e58c9fe4b27010102c0a595c764468" - url: "https://pub.dev" - source: hosted - version: "1.1.4" - vector_graphics_compiler: - dependency: transitive - description: - name: vector_graphics_compiler - sha256: "0bf61ad56e6fd6688a2865d3ceaea396bc6a0a90ea0d7ad5049b1b76c09d6163" - url: "https://pub.dev" - source: hosted - version: "1.1.4" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: e7fb6c2282f7631712b69c19d1bff82f3767eea33a2321c14fa59ad67ea391c7 - url: "https://pub.dev" - source: hosted - version: "9.4.0" - watcher: - dependency: transitive - description: - name: watcher - sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b - url: "https://pub.dev" - source: hosted - version: "2.3.0" - webkit_inspection_protocol: - dependency: transitive - description: - name: webkit_inspection_protocol - sha256: "67d3a8b6c79e1987d19d848b0892e582dbb0c66c57cc1fef58a177dd2aa2823d" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - win32: - dependency: transitive - description: - name: win32 - sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" - url: "https://pub.dev" - source: hosted - version: "4.1.4" - worker_manager: - dependency: "direct main" - description: - name: worker_manager - sha256: "42501e49ee0acad9eeda562984e3dcfe6fe3d26f2d8dc410bd76308a86447eb5" - url: "https://pub.dev" - source: hosted - version: "5.0.3" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 - url: "https://pub.dev" - source: hosted - version: "1.0.0" - xml: - dependency: "direct main" - description: - name: xml - sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5" - url: "https://pub.dev" - source: hosted - version: "6.2.2" - yaml: - dependency: transitive - description: - name: yaml - sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" - url: "https://pub.dev" - source: hosted - version: "3.1.1" -sdks: - dart: ">=2.19.2 <3.0.0" - flutter: ">=3.7.0-0" diff --git a/pubspec.yaml b/pubspec.yaml deleted file mode 100644 index 2b56e57d..00000000 --- a/pubspec.yaml +++ /dev/null @@ -1,85 +0,0 @@ -name: subtracks -description: A media player for Android. -homepage: https://github.com/austinried/subtracks -repository: https://github.com/austinried/subtracks -issue_tracker: https://github.com/austinried/subtracks/issues -publish_to: 'none' -version: 2.0.0-alpha.3+12 - -environment: - sdk: '>=2.19.2 <3.0.0' - -dependencies: - flutter: - sdk: flutter - flutter_localizations: - sdk: flutter - xml: ^6.2.2 - http: ^0.13.5 - crypto: ^3.0.2 - freezed_annotation: ^2.2.0 - fast_immutable_collections: ^9.0.0 - path: ^1.8.2 - path_provider: ^2.0.12 - flutter_dotenv: ^5.0.2 # TODO: remove before release - collection: ^1.17.0 - intl: any - flutter_hooks: ^0.18.5+1 - hooks_riverpod: ^2.3.2 - riverpod_annotation: ^2.0.2 - cached_network_image: ^3.2.3 - flutter_staggered_grid_view: ^0.6.2 - flutter_cache_manager: ^3.3.0 - auto_route: ^5.0.0 - flutter_svg: ^2.0.2 - audio_service: - git: - url: https://github.com/austinried/audio_service - path: audio_service - ref: features/cache-key-resolver - just_audio: ^0.9.31 - sqlite3_flutter_libs: ^0.5.12 - drift: ^2.6.0 - sliver_tools: ^0.2.9 - palette_generator: ^0.3.3+2 - json_annotation: ^4.8.0 - text_scroll: ^0.2.0 - auto_size_text: ^3.0.0 - stack_trace: ^1.11.0 - infinite_scroll_pagination: ^3.2.0 - flutter_downloader: ^1.10.2 - mime: ^1.0.4 - rxdart: ^0.27.7 - worker_manager: ^5.0.3 - pool: ^1.5.1 - synchronized: ^3.1.0 - flutter_keyboard_visibility: ^5.4.0 - connectivity_plus: ^3.0.4 - package_info_plus: ^3.1.1 - url_launcher: ^6.1.10 - logging: ^1.1.1 - share_plus: ^7.0.0 - -# https://github.com/dart-lang/intl/issues/522#issuecomment-1469961807 -dependency_overrides: - intl: ^0.18.0 - -dev_dependencies: - flutter_test: - sdk: flutter - flutter_lints: ^2.0.0 - test: ^1.22.0 - build_runner: - riverpod_generator: ^2.1.4 - freezed: ^2.3.2 - auto_route_generator: ^5.0.0 - drift_dev: ^2.5.2 - json_serializable: ^6.6.1 - -flutter: - uses-material-design: true - generate: true - - assets: - - .env - - assets/ diff --git a/scripts/arb-delete-key.js b/scripts/arb-delete-key.js deleted file mode 100644 index 34c5a8fd..00000000 --- a/scripts/arb-delete-key.js +++ /dev/null @@ -1,17 +0,0 @@ -const path = require('path') -const fs = require('fs') -const process = require('process') - -const key = process.argv[2] - -const arbDir = path.join(__dirname, '../lib/l10n') - -const arbFiles = fs.readdirSync(arbDir) -for (const file of arbFiles) { - const json = JSON.parse(fs.readFileSync(path.join(arbDir, file), { encoding: 'utf8' })) - - delete json[key] - delete json[`@${key}`] - - fs.writeFileSync(path.join(arbDir, file), JSON.stringify(json, null, 4)) -} diff --git a/scripts/arb-rename-key.js b/scripts/arb-rename-key.js deleted file mode 100644 index 00529efc..00000000 --- a/scripts/arb-rename-key.js +++ /dev/null @@ -1,37 +0,0 @@ -const path = require('path') -const fs = require('fs') -const process = require('process') - -const from = process.argv[2] -const to = process.argv[3] - -const arbDir = path.join(__dirname, '../lib/l10n') - -const arbFiles = fs.readdirSync(arbDir) -for (const file of arbFiles) { - const json = JSON.parse(fs.readFileSync(path.join(arbDir, file), { encoding: 'utf8' })) - - json[to] = json[from] - json[`@${to}`] = json[`@${from}`] - - delete json[from] - delete json[`@${from}`] - - fs.writeFileSync(path.join(arbDir, file), JSON.stringify(sortObj(json), null, 4)) -} - -function sortObj(obj) { - return Object.keys(obj) - .sort((a, b) => moveSymbol(a).localeCompare(moveSymbol(b))) - .reduce(function (result, key) { - result[key] = obj[key] - return result - }, {}) -} - -function moveSymbol(str) { - if (str.startsWith('@')) { - return `${str.substring(1)}@` - } - return str -} diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000..bf6e9ac1 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,24 @@ +pluginManagement { + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "subtracks" +include(":app") diff --git a/tools/preview_server.py b/tools/preview_server.py new file mode 100644 index 00000000..b6594e71 --- /dev/null +++ b/tools/preview_server.py @@ -0,0 +1,66 @@ +"""Serve the Roborazzi report for local review: thumbnails scaled by CSS and +full images opened in a new tab. Expects a .preview/ directory mirroring the +app module layout (build/reports/roborazzi and src/test/screenshots).""" + +import http.server +import os +import sys + +ROOT = os.path.normpath( + os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", ".preview") +) + +INJECT = """ + + +""" + + +class Handler(http.server.SimpleHTTPRequestHandler): + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=ROOT, **kwargs) + + def do_GET(self): + path = self.translate_path(self.path) + if os.path.isdir(path): + path = os.path.join(path, "index.html") + if os.path.isfile(path) and path.endswith(".html"): + with open(path, "r", encoding="utf-8") as f: + html = f.read() + html = html.replace("", INJECT + "") + body = html.encode("utf-8") + self.send_response(200) + self.send_header("Content-Type", "text/html; charset=utf-8") + self.send_header("Content-Length", str(len(body))) + self.end_headers() + self.wfile.write(body) + return + super().do_GET() + + +if __name__ == "__main__": + port = int(sys.argv[1]) if len(sys.argv) > 1 else 8099 + server = http.server.ThreadingHTTPServer(("127.0.0.1", port), Handler) + server.serve_forever()