diff --git a/.github/Dockerfile b/.github/Dockerfile
deleted file mode 100644
index f6a9f538..00000000
--- a/.github/Dockerfile
+++ /dev/null
@@ -1,25 +0,0 @@
-ARG FLUTTER_VERSION
-
-FROM --platform=linux/arm64 krtirtho/flutter_distributor:${FLUTTER_VERSION}
-
-ARG BUILD_VERSION
-
-WORKDIR /app
-
-COPY . .
-
-RUN chown -R $(whoami) /app
-
-RUN rustup target add aarch64-unknown-linux-gnu
-
-RUN flutter pub get
-
-RUN alias dpkg-deb="dpkg-deb --Zxz" &&\
- flutter_distributor package --platform=linux --targets=deb --skip-clean
-
-RUN make tar VERSION=${BUILD_VERSION} ARCH=arm64 PKG_ARCH=aarch64
-
-RUN mv build/spotube-linux-*-aarch64.tar.xz dist/ &&\
- mv dist/**/spotube-*-linux.deb dist/Spotube-linux-aarch64.deb
-
-CMD [ "sleep", "5000000" ]
\ No newline at end of file
diff --git a/.github/workflows/spotube-publish-binary.yml b/.github/workflows/spotube-publish-binary.yml
index f88e618c..e682dbdd 100644
--- a/.github/workflows/spotube-publish-binary.yml
+++ b/.github/workflows/spotube-publish-binary.yml
@@ -12,10 +12,10 @@ on:
type: boolean
default: true
jobs:
- description: Jobs to run (flathub,aur,winget,chocolatey,playstore)
+ description: Jobs to run (flathub,aur,winget,chocolatey)
required: true
type: string
- default: "flathub,aur,winget,chocolatey,playstore"
+ default: "flathub,aur,winget,chocolatey"
jobs:
flathub:
@@ -112,26 +112,26 @@ jobs:
- name: Tagname (workflow dispatch)
run: echo 'TAG_NAME=${{inputs.version}}' >> $GITHUB_ENV
- - uses: robinraju/release-downloader@main
- with:
- repository: KRTirtho/spotube
- tag: v${{ env.TAG_NAME }}
- tarBall: false
- zipBall: false
- out-file-path: dist
- fileName: "Spotube-playstore-all-arch.aab"
+ # - uses: robinraju/release-downloader@main
+ # with:
+ # repository: KRTirtho/spotube
+ # tag: v${{ env.TAG_NAME }}
+ # tarBall: false
+ # zipBall: false
+ # out-file-path: dist
+ # fileName: "Spotube-playstore-all-arch.aab"
- - name: Create service-account.json
- run: |
- echo "${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_BASE64 }}" | base64 -d > service-account.json
+ # - name: Create service-account.json
+ # run: |
+ # echo "${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_BASE64 }}" | base64 -d > service-account.json
- - name: Upload Android Release to Play Store
- if: ${{!inputs.dry_run}}
- uses: r0adkll/upload-google-play@v1
- with:
- serviceAccountJson: ./service-account.json
- releaseFiles: ./dist/Spotube-playstore-all-arch.aab
- packageName: oss.krtirtho.spotube
- track: production
- status: draft
- releaseName: ${{ env.TAG_NAME }}
+ # - name: Upload Android Release to Play Store
+ # if: ${{!inputs.dry_run}}
+ # uses: r0adkll/upload-google-play@v1
+ # with:
+ # serviceAccountJson: ./service-account.json
+ # releaseFiles: ./dist/Spotube-playstore-all-arch.aab
+ # packageName: oss.krtirtho.spotube
+ # track: production
+ # status: draft
+ # releaseName: ${{ env.TAG_NAME }}
diff --git a/.github/workflows/spotube-release-binary.yml b/.github/workflows/spotube-release-binary.yml
index 4f2cff34..dfec7d44 100644
--- a/.github/workflows/spotube-release-binary.yml
+++ b/.github/workflows/spotube-release-binary.yml
@@ -37,19 +37,20 @@ jobs:
files: |
dist/Spotube-linux-x86_64.deb
dist/Spotube-linux-x86_64.rpm
+ dist/Spotube-linux-x86_64.AppImage
dist/spotube-linux-*-x86_64.tar.xz
- os: ubuntu-22.04-arm
platform: linux
arch: arm64
files: |
dist/Spotube-linux-aarch64.deb
+ dist/Spotube-linux-aarch64.AppImage
dist/spotube-linux-*-aarch64.tar.xz
- os: ubuntu-22.04
platform: android
arch: all
files: |
build/Spotube-android-all-arch.apk
- build/Spotube-playstore-all-arch.aab
- os: windows-latest
platform: windows
arch: x86
@@ -77,6 +78,14 @@ jobs:
cache: true
git-source: https://github.com/flutter/flutter.git
+ - name: free disk space
+ if: ${{ matrix.platform == 'android' }}
+ run: |
+ sudo swapoff -a
+ sudo rm -f /swapfile
+ sudo apt clean
+ docker rmi $(docker image ls -aq)
+ df -h
- name: Setup Java
if: ${{matrix.platform == 'android'}}
uses: actions/setup-java@v4
@@ -100,7 +109,7 @@ jobs:
- name: Install ${{matrix.platform}} dependencies
run: |
flutter pub get
- dart cli/cli.dart install-dependencies --platform=${{matrix.platform}}
+ dart cli/cli.dart install-dependencies --platform=${{matrix.platform}} --arch=${{matrix.arch}}
- name: Sign Apk
if: ${{matrix.platform == 'android'}}
diff --git a/.gitignore b/.gitignore
index 119e42e5..544dbba8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@
.history
.svn/
+
# IntelliJ related
*.iml
*.ipr
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 21ae3f15..b8a5b0e1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,29 @@
# Changelog
+## [5.1.0](https://github.com/KRTirtho/spotube/compare/v5.0.0...v5.1.0) (2025-11-14)
+
+### Features
+
+- Show plugin source and set the only plugin as default if no plugin is there
+- **playback**: Add dab music source
+- **playback**: Add uncompressed flac playback support
+- Add plugin audio source models and api service
+- **plugins**: Filter plugins by abilities in plugins page and show abilities as badge
+- Add setting default audio source support
+- Move away from track source query and preferences audio quality and codec
+- Add NewPipe support for desktop platforms
+- Add default plugin loading capability
+- **queue**: Add multi-select and bulk actions to queue ([#2839](https://github.com/KRTirtho/spotube/issues/2839))
+- **android**: Add 16KB page size support
+
+### Bug Fixes
+
+- Change plugin download directory to application support
+- **playback**: Play next not working
+- Downloaded tracks are not tagged with metadata
+- Download not working in different devices and slow
+- **playback**: Use stream instead of chunked serving of audio bytes
+
## [5.0.0](https://github.com/KRTirtho/spotube/compare/v4.0.2...v5.0.0) (2025-09-08)
### Features
diff --git a/README.md b/README.md
index 4c5c1f1c..1043fabc 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
A cross-platform extensible open-source music streaming platform.
-Bring your own music metadata/playlist with plugins created by community or by yourself. A small step towards the decentralized music streaming era!
+Bring your own music metadata/playlist/audio-source with plugins created by community or by yourself. A small step towards the decentralized music streaming era!
Btw it's not just another Electron app 😉
@@ -202,7 +202,7 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [Invidious](https://invidious.io/) - Invidious is an open source alternative front-end to YouTube.
1. [yt-dlp](https://github.com/yt-dlp/yt-dlp) - A feature-rich command-line audio/video downloader.
1. [NewPipeExtractor](https://github.com/TeamNewPipe/NewPipeExtractor) - NewPipe's core library for extracting data from streaming sites.
-1. [SongLink](https://song.link) - SongLink is a free smart link service that helps you share music with your audience. It's a one-stop-shop for creating smart links for music, podcasts, and other audio content
+1. [YouTubeExplodeDart](https://github.com/Hexer10/youtube_explode_dart) - A port in dart of the youtube explode library. Supports several API functions without the need of Youtube API Key.
1. [LRCLib](https://lrclib.net/) - A public synced lyric API.
1. [Linux](https://www.linux.org) - Linux is a family of open-source Unix-like operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991, by Linus Torvalds. Linux is typically packaged in a Linux distribution
1. [AUR](https://aur.archlinux.org) - AUR stands for Arch User Repository. It is a community-driven repository for Arch-based Linux distributions users
@@ -216,7 +216,6 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [app_links](https://github.com/llfbandit/app_links) - Android App Links, Deep Links, iOs Universal Links and Custom URL schemes handler for Flutter (desktop included).
1. [args](https://pub.dev/packages/args) - Library for defining parsers for parsing raw command-line arguments into a set of options and values using GNU and POSIX style options.
-1. [async](https://pub.dev/packages/async) - Utility functions and classes related to the 'dart:async' library.
1. [audio_service](https://pub.dev/packages/audio_service) - Flutter plugin to play audio in the background while the screen is off.
1. [audio_service_mpris](https://github.com/bdrazhzhov/audio-service-mpris) - audio_service platform interface supporting Media Player Remote Interfacing Specification.
1. [audio_session](https://github.com/ryanheise/audio_session) - Sets the iOS audio session category and Android audio attributes for your app, and manages your app's audio focus, mixing and ducking behaviour.
@@ -243,15 +242,11 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [flutter_inappwebview](https://inappwebview.dev/) - A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window.
1. [flutter_native_splash](https://pub.dev/packages/flutter_native_splash) - Customize Flutter's default white native splash screen with background color and splash image. Supports dark mode, full screen, and more.
1. [flutter_riverpod](https://riverpod.dev) - A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze.
-1. [flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage) - Flutter Secure Storage provides API to store data in secure storage. Keychain is used in iOS, KeyStore based solution is used in Android.
1. [flutter_sharing_intent](https://github.com/bhagat-techind/flutter_sharing_intent.git) - A flutter plugin that allow flutter apps to receive photos, videos, text, urls or any other file types from another app.
1. [flutter_undraw](https://github.com/KRTirtho/flutter_undraw) - Undraw.co Illustrations for Flutter with customization options
1. [form_builder_validators](https://github.com/flutter-form-builder-ecosystem) - Form Builder Validators set of validators for FlutterFormBuilder. Provides common validators and a way to make your own.
-1. [form_validator](https://github.com/TheMisir/form-validator) - Simplest form validation library for flutter's form field widgets
1. [freezed_annotation](https://pub.dev/packages/freezed_annotation) - Annotations for the freezed code-generator. This package does nothing without freezed too.
1. [fuzzywuzzy](https://github.com/sphericalkat/dart-fuzzywuzzy) - An implementation of the popular fuzzywuzzy package in Dart, to suit all your fuzzy string matching/searching needs!
-1. [gap](https://github.com/letsar/gap) - Flutter widgets for easily adding gaps inside Flex widgets such as Columns and Rows or scrolling views.
-1. [google_fonts](https://pub.dev/packages/google_fonts) - A Flutter package to use fonts from fonts.google.com. Supports HTTP fetching, caching, and asset bundling.
1. [home_widget](https://pub.dev/packages/home_widget) - A plugin to provide a common interface for creating HomeScreen Widgets for Android and iOS.
1. [hooks_riverpod](https://riverpod.dev) - A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze.
1. [html](https://pub.dev/packages/html) - APIs for parsing and manipulating HTML content outside the browser.
@@ -259,15 +254,10 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [http](https://pub.dev/packages/http) - A composable, multi-platform, Future-based API for HTTP requests.
1. [image_picker](https://pub.dev/packages/image_picker) - Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera.
1. [intl](https://pub.dev/packages/intl) - Contains code to deal with internationalized/localized messages, date and number formatting and parsing, bi-directional text, and other internationalization issues.
-1. [invidious](https://pub.dev/packages/invidious) - Invidious API client for Dart and Flutter.
-1. [jiosaavn](https://github.com/KRTirtho/jiosaavn) - Unofficial API client for jiosaavn.com
-1. [json_annotation](https://pub.dev/packages/json_annotation) - Classes and helper functions that support JSON code generation via the `json_serializable` package.
1. [local_notifier](https://github.com/leanflutter/local_notifier) - This plugin allows Flutter desktop apps to displaying local notifications.
1. [logger](https://pub.dev/packages/logger) - Small, easy to use and extensible logger which prints beautiful logs.
1. [logging](https://pub.dev/packages/logging) - Provides APIs for debugging and error logging, similar to loggers in other languages, such as the Closure JS Logger and java.util.logging.Logger.
1. [lrc](https://pub.dev/packages/lrc) - A Dart-only package that creates, parses, and handles LRC, which is a format that stores song lyrics.
-1. [media_kit](https://github.com/media-kit/media-kit) - A cross-platform video player & audio player for Flutter & Dart. Performant, stable, feature-proof & modular.
-1. [media_kit_libs_audio](https://github.com/media-kit/media-kit.git) - package:media_kit audio (only) playback native libraries for all platforms.
1. [metadata_god](https://pub.dev/packages/metadata_god) - Plugin for retrieving and writing audio tags/metadata from audio files
1. [mime](https://pub.dev/packages/mime) - Utilities for handling media (MIME) types, including determining a type from a file extension and file contents.
1. [open_file](https://pub.dev/packages/open_file) - A plug-in that can call native APP to open files with string result in flutter, support iOS(UTI) / android(intent) / PC(ffi) / web(dart:html)
@@ -276,7 +266,6 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [path](https://pub.dev/packages/path) - A string-based path manipulation library. All of the path operations you know and love, with solid support for Windows, POSIX (Linux and Mac OS X), and the web.
1. [path_provider](https://pub.dev/packages/path_provider) - Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories.
1. [permission_handler](https://pub.dev/packages/permission_handler) - Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
-1. [piped_client](https://github.com/KRTirtho/piped_client) - API Client for piped.video
1. [riverpod](https://riverpod.dev) - A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze.
1. [scroll_to_index](https://github.com/quire-io/scroll-to-index) - Scroll to a specific child of any scrollable widget in Flutter
1. [shadcn_flutter](https://github.com/sunarya-thito/shadcn_flutter) - Beautifully designed components from Shadcn/UI is now available for Flutter
@@ -291,9 +280,6 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [smtc_windows](https://pub.dev/packages/smtc_windows) - Windows `SystemMediaTransportControls` implementation for Flutter giving access to Windows OS Media Control applet.
1. [sqlite3](https://github.com/simolus3/sqlite3.dart/tree/main/sqlite3) - Provides lightweight yet convenient bindings to SQLite by using dart:ffi
1. [sqlite3_flutter_libs](https://github.com/simolus3/sqlite3.dart/tree/main/sqlite3_flutter_libs) - Flutter plugin to include native sqlite3 libraries with your app
-1. [stroke_text](https://github.com/MohamedAbd0/stroke_text) - A Simple Flutter plugin for applying stroke (border) style to a text widget
-1. [system_theme](https://github.com/bdlukaa/system_theme/tree/master/system_theme) - A plugin to get the current system theme info. Supports Android, Web, Windows, Linux and macOS
-1. [test](https://pub.dev/packages/test) - A full featured library for writing and running Dart tests across platforms.
1. [timezone](https://pub.dev/packages/timezone) - Time zone database and time zone aware DateTime.
1. [titlebar_buttons](https://github.com/gtk-flutter/titlebar_buttons) - A package which provides most of the titlebar buttons from windows, linux and macos.
1. [tray_manager](https://github.com/leanflutter/tray_manager) - This plugin allows Flutter desktop apps to defines system tray.
@@ -305,12 +291,17 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [web_socket_channel](https://pub.dev/packages/web_socket_channel) - StreamChannel wrappers for WebSockets. Provides a cross-platform WebSocketChannel API, a cross-platform implementation of that API that communicates over an underlying StreamChannel.
1. [wikipedia_api](https://github.com/KRTirtho/wikipedia_api) - Wikipedia API for dart and flutter
1. [win32_registry](https://pub.dev/packages/win32_registry) - A package that provides a friendly Dart API for accessing the Windows Registry.
-1. [window_manager](https://github.com/leanflutter/window_manager) - This plugin allows Flutter desktop apps to resizing and repositioning the window.
+1. [window_manager](https://leanflutter.dev) - This plugin allows Flutter desktop apps to resizing and repositioning the window.
1. [youtube_explode_dart](https://github.com/Hexer10/youtube_explode_dart) - A port in dart of the youtube explode library. Supports several API functions without the need of Youtube API Key.
1. [http_parser](https://pub.dev/packages/http_parser) - A platform-independent package for parsing and serializing HTTP formats.
1. [collection](https://pub.dev/packages/collection) - Collections and utilities functions and classes related to collections.
-1. [otp_util](https://github.com/dushiling) - otp_util is a dart package to generate and verify one-time passwords,it It provides two methods TOPT and HOTP.They are Time-based OTPs and Counter-based OTPs.
-1. [dio_http2_adapter](https://github.com/cfug/dio) - An adapter that combines HTTP/2 and dio. Supports reusing connections, header compression, etc.
+1. [archive](https://pub.dev/packages/archive) - Provides encoders and decoders for various archive and compression formats such as zip, tar, bzip2, gzip, and zlib.
+1. [hetu_script](https://github.com/hetu-script/hetu-script) - Hetu is a lightweight scripting language for embedding in Flutter apps.
+1. [get_it](https://github.com/flutter-it/get_it) - Simple direct Service Locator that allows to decouple the interface from a concrete implementation and to access the concrete implementation from everywhere in your App"
+1. [flutter_markdown_plus](https://pub.dev/packages/flutter_markdown_plus) - A Markdown renderer for Flutter. Create rich text output, including text styles, tables, links, and more, from plain text data formatted with simple Markdown tags.
+1. [pub_semver](https://pub.dev/packages/pub_semver) - Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases.
+1. [change_case](https://github.com/mrgnhnt96/change_case) - An extension on String for the missing methods for camelCase, PascalCase, Capital Case, snake_case, param-case, CONSTANT_CASE and others.
+1. [flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage) - Flutter Secure Storage provides API to store data in secure storage. Keychain is used in iOS, KeyStore based solution is used in Android.
1. [build_runner](https://pub.dev/packages/build_runner) - A build system for Dart code generation and modular compilation.
1. [envied_generator](https://github.com/petercinibulk/envied) - Generator for the Envied package. See https://pub.dev/packages/envied.
1. [flutter_gen_runner](https://github.com/FlutterGen/flutter_gen) - The Flutter code generator for your assets, fonts, colors, … — Get rid of all String-based APIs.
@@ -321,17 +312,23 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [process_run](https://github.com/tekartik/process_run.dart/blob/master/packages/process_run) - Process run helpers for Linux/Win/Mac and which like feature for finding executables.
1. [pubspec_parse](https://pub.dev/packages/pubspec_parse) - Simple package for parsing pubspec.yaml files with a type-safe API and rich error reporting.
1. [pub_api_client](https://github.com/leoafarias/pub_api_client) - An API Client for Pub to interact with public package information.
-1. [xml](https://github.com/renggli/dart-xml) - A lightweight library for parsing, traversing, querying, transforming and building XML documents.
1. [io](https://pub.dev/packages/io) - Utilities for the Dart VM Runtime including support for ANSI colors, file copying, and standard exit code values.
1. [drift_dev](https://drift.simonbinder.eu/) - Dev-dependency for users of drift. Contains the generator and development tools.
+1. [test](https://pub.dev/packages/test) - A full featured library for writing and running Dart tests across platforms.
1. [auto_route_generator](https://github.com/Milad-Akarie/auto_route_library) - AutoRoute is a declarative routing solution, where everything needed for navigation is automatically generated for you.
1. [desktop_webview_window](https://github.com/MixinNetwork/flutter-plugins/tree/main/packages/desktop_webview_window) - Show a webview window on your flutter desktop application.
1. [disable_battery_optimization](https://github.com/pvsvamsi/Disable-Battery-Optimizations) - Flutter plugin to check and disable battery optimizations. Also shows custom steps to disable the optimizations in devices like mi, xiaomi, samsung, oppo, huawei, oneplus etc
1. [draggable_scrollbar](https://github.com/fluttercommunity/flutter-draggable-scrollbar) - A scrollbar that can be dragged for quickly navigation through a vertical list. Additional option is showing label next to scrollthumb with information about current item.
1. [flutter_broadcasts](https://github.com/KRTirtho/flutter_broadcasts.git) - A plugin for sending and receiving broadcasts with Android intents and iOS notifications.
1. [scrobblenaut](https://github.com/Nebulino/Scrobblenaut) - A deadly simple LastFM API Wrapper for Dart. So deadly simple that it's gonna hit the mark.
-1. [yt_dlp_dart](https://github.com/KRTirtho/yt_dlp_dart.git) - yt-dlp binding in Dart
+1. [yt_dlp_dart](https://github.com/KRTirtho/yt_dlp_dart.git) - A starting point for Dart libraries or applications.
1. [flutter_new_pipe_extractor](https://github.com/KRTirtho/flutter_new_pipe_extractor) - NewPipeExtractor binding for Flutter (Android only)
+1. [hetu_std](https://github.com/hetu-community/hetu_std.git) - A sample command-line application.
+1. [hetu_otp_util](https://github.com/hetu-community/hetu_otp_util.git) - A sample command-line application.
+1. [hetu_spotube_plugin](https://github.com/KRTirtho/hetu_spotube_plugin) - A new Flutter package project.
+1. [media_kit](https://github.com/media-kit/media-kit) - A cross-platform video player & audio player for Flutter & Dart. Performant, stable, feature-proof & modular.
+1. [media_kit_libs_audio](https://github.com/media-kit/media-kit.git) - package:media_kit audio (only) playback native libraries for all platforms.
+
© Copyright Spotube 2025
diff --git a/android/.gitignore b/android/.gitignore
index 6f568019..2391a77e 100644
--- a/android/.gitignore
+++ b/android/.gitignore
@@ -11,3 +11,4 @@ GeneratedPluginRegistrant.java
key.properties
**/*.keystore
**/*.jks
+.kotlin
\ No newline at end of file
diff --git a/android/app/build.gradle b/android/app/build.gradle
index ee481eca..7319c6a8 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -2,6 +2,7 @@ plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
+ id "org.jetbrains.kotlin.plugin.compose"
}
def localProperties = new Properties()
@@ -35,7 +36,7 @@ android {
compileSdkVersion 36
- ndkVersion = "27.0.12077973"
+ ndkVersion = "29.0.14206865"
compileOptions {
coreLibraryDesugaringEnabled true
diff --git a/android/settings.gradle b/android/settings.gradle
index 1e8ffbe3..53d34a77 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -19,7 +19,8 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.7.0' apply false
- id "org.jetbrains.kotlin.android" version "1.8.22" apply false
+ id "org.jetbrains.kotlin.android" version "2.1.0" apply false
+ id "org.jetbrains.kotlin.plugin.compose" version "2.1.0" apply false
}
include ':app'
\ No newline at end of file
diff --git a/assets/images/logos/dab-music.png b/assets/images/logos/dab-music.png
new file mode 100644
index 00000000..e09d3410
Binary files /dev/null and b/assets/images/logos/dab-music.png differ
diff --git a/assets/images/logos/songlink-transparent.png b/assets/images/logos/songlink-transparent.png
deleted file mode 100644
index fc4ae541..00000000
Binary files a/assets/images/logos/songlink-transparent.png and /dev/null differ
diff --git a/assets/plugins/spotube-plugin-musicbrainz-listenbrainz/plugin.smplug b/assets/plugins/spotube-plugin-musicbrainz-listenbrainz/plugin.smplug
new file mode 100644
index 00000000..41be05a4
Binary files /dev/null and b/assets/plugins/spotube-plugin-musicbrainz-listenbrainz/plugin.smplug differ
diff --git a/assets/plugins/spotube-plugin-youtube-audio/plugin.smplug b/assets/plugins/spotube-plugin-youtube-audio/plugin.smplug
new file mode 100644
index 00000000..55aa2895
Binary files /dev/null and b/assets/plugins/spotube-plugin-youtube-audio/plugin.smplug differ
diff --git a/cli/commands/build/android.dart b/cli/commands/build/android.dart
index 4216553a..b9edeb84 100644
--- a/cli/commands/build/android.dart
+++ b/cli/commands/build/android.dart
@@ -2,9 +2,7 @@ import 'dart:async';
import 'dart:io';
import 'package:args/command_runner.dart';
-import 'package:collection/collection.dart';
import 'package:path/path.dart';
-import 'package:xml/xml.dart';
import '../../core/env.dart';
import 'common.dart';
@@ -24,39 +22,6 @@ class AndroidBuildCommand extends Command with BuildCommandCommonSteps {
"flutter build apk --flavor ${CliEnv.channel.name}",
);
- await dotEnvFile.writeAsString(
- "\nENABLE_UPDATE_CHECK=0"
- "\nHIDE_DONATIONS=1",
- mode: FileMode.append,
- );
-
- final androidManifestFile = File(
- join(cwd.path, "android", "app", "src", "main", "AndroidManifest.xml"));
-
- final androidManifestXml =
- XmlDocument.parse(await androidManifestFile.readAsString());
-
- final deletingElement =
- androidManifestXml.findAllElements("meta-data").firstWhereOrNull(
- (el) =>
- el.getAttribute("android:name") ==
- "com.google.android.gms.car.application",
- );
-
- deletingElement?.parent?.children.remove(deletingElement);
-
- await androidManifestFile.writeAsString(
- androidManifestXml.toXmlString(pretty: true),
- );
-
- await shell.run(
- """
- dart run build_runner clean
- dart run build_runner build --delete-conflicting-outputs
- flutter build appbundle --flavor ${CliEnv.channel.name}
- """,
- );
-
final ogApkFile = File(
join(
"build",
@@ -71,22 +36,6 @@ class AndroidBuildCommand extends Command with BuildCommandCommonSteps {
join(cwd.path, "build", "Spotube-android-all-arch.apk"),
);
- final ogAppbundleFile = File(
- join(
- cwd.path,
- "build",
- "app",
- "outputs",
- "bundle",
- "${CliEnv.channel.name}Release",
- "app-${CliEnv.channel.name}-release.aab",
- ),
- );
-
- await ogAppbundleFile.copy(
- join(cwd.path, "build", "Spotube-playstore-all-arch.aab"),
- );
-
stdout.writeln("✅ Built Android Apk and Appbundle");
}
}
diff --git a/cli/commands/build/common.dart b/cli/commands/build/common.dart
index 30906b3c..c30197f5 100644
--- a/cli/commands/build/common.dart
+++ b/cli/commands/build/common.dart
@@ -59,7 +59,7 @@ mixin BuildCommandCommonSteps on Command {
"""
flutter pub get
dart run build_runner build --delete-conflicting-outputs
- dart pub global activate flutter_distributor
+ dart pub global activate fastforge
""",
);
}
diff --git a/cli/commands/build/linux.dart b/cli/commands/build/linux.dart
index 378f5a72..3ca792ea 100644
--- a/cli/commands/build/linux.dart
+++ b/cli/commands/build/linux.dart
@@ -37,12 +37,11 @@ class LinuxBuildCommand extends Command with BuildCommandCommonSteps {
await bootstrap();
await shell.run(
- "flutter_distributor package --platform=linux --targets=deb",
+ "fastforge package --platform=linux --targets=deb,appimage",
);
-
if (architecture == "x86") {
await shell.run(
- "flutter_distributor package --platform=linux --targets=rpm",
+ "fastforge package --platform=linux --targets=rpm",
);
}
@@ -116,6 +115,23 @@ class LinuxBuildCommand extends Command with BuildCommandCommonSteps {
await ogRpm.delete();
}
+ final ogAppImage = File(
+ join(
+ cwd.path,
+ "dist",
+ pubspec.version.toString(),
+ "spotube-${pubspec.version}-linux.AppImage",
+ ),
+ );
+ await ogAppImage.copy(
+ join(
+ cwd.path,
+ "dist",
+ "Spotube-linux-$bundleArchName.AppImage",
+ ),
+ );
+ await ogAppImage.delete();
+
stdout.writeln("✅ Linux building done");
}
}
diff --git a/cli/commands/build/macos.dart b/cli/commands/build/macos.dart
index e8f34b77..936f1fc8 100644
--- a/cli/commands/build/macos.dart
+++ b/cli/commands/build/macos.dart
@@ -21,7 +21,7 @@ class MacosBuildCommand extends Command with BuildCommandCommonSteps {
"""
flutter build macos
appdmg appdmg.json ${join(cwd.path, "build", "Spotube-macos-universal.dmg")}
- flutter_distributor package --platform=macos --targets pkg --skip-clean
+ fastforge package --platform=macos --targets pkg --skip-clean
""",
);
diff --git a/cli/commands/build/windows.dart b/cli/commands/build/windows.dart
index c44ed52f..1045c11c 100644
--- a/cli/commands/build/windows.dart
+++ b/cli/commands/build/windows.dart
@@ -61,7 +61,7 @@ class WindowsBuildCommand extends Command with BuildCommandCommonSteps {
);
await shell.run(
- "flutter_distributor package --platform=windows --targets=exe --skip-clean",
+ "fastforge package --platform=windows --targets=exe --skip-clean",
);
final ogExe = File(
diff --git a/cli/commands/install-dependencies.dart b/cli/commands/install-dependencies.dart
index e26b8078..56f679f1 100644
--- a/cli/commands/install-dependencies.dart
+++ b/cli/commands/install-dependencies.dart
@@ -37,14 +37,24 @@ class InstallDependenciesCommand extends Command {
FutureOr? run() async {
final shell = Shell();
+ final arch = argResults?.option("arch") == "x86" ? "x86_64" : "aarch64";
+
switch (argResults!.option("platform")) {
case "windows":
+ await shell.run(
+ """
+ choco install innosetup -y
+ """,
+ );
break;
case "linux":
await shell.run(
"""
sudo apt-get update -y
- sudo apt-get install -y tar clang cmake ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse libunwind-dev locate patchelf gir1.2-appindicator3-0.1 libappindicator3-1 libappindicator3-dev libsecret-1-0 libjsoncpp25 libsecret-1-dev libjsoncpp-dev libnotify-bin libnotify-dev mpv libmpv-dev libwebkit2gtk-4.1-0 libwebkit2gtk-4.1-dev libsoup-3.0-0 libsoup-3.0-dev
+ sudo apt-get install -y wget tar clang cmake ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse libunwind-dev locate patchelf gir1.2-appindicator3-0.1 libappindicator3-1 libappindicator3-dev libsecret-1-0 libjsoncpp25 libsecret-1-dev libjsoncpp-dev libnotify-bin libnotify-dev mpv libmpv-dev libwebkit2gtk-4.1-0 libwebkit2gtk-4.1-dev libsoup-3.0-0 libsoup-3.0-dev
+ wget -O appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$arch.AppImage"
+ chmod +x appimagetool
+ sudo mv appimagetool /usr/local/bin/
""",
);
break;
diff --git a/drift_schemas/app_db/drift_schema_v10.json b/drift_schemas/app_db/drift_schema_v10.json
new file mode 100644
index 00000000..5fb86d25
--- /dev/null
+++ b/drift_schemas/app_db/drift_schema_v10.json
@@ -0,0 +1 @@
+{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.2.0"},"options":{"store_date_time_values_as_text":false},"entities":[{"id":0,"references":[],"type":"table","data":{"name":"authentication_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"cookie","getter_name":"cookie","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"EncryptedTextConverter()","dart_type_name":"DecryptedText"}},{"name":"access_token","getter_name":"accessToken","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"EncryptedTextConverter()","dart_type_name":"DecryptedText"}},{"name":"expiration","getter_name":"expiration","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":1,"references":[],"type":"table","data":{"name":"blacklist_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"element_type","getter_name":"elementType","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(BlacklistedType.values)","dart_type_name":"BlacklistedType"}},{"name":"element_id","getter_name":"elementId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":2,"references":[],"type":"table","data":{"name":"preferences_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"album_color_sync","getter_name":"albumColorSync","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"album_color_sync\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"album_color_sync\" IN (0, 1))"},"default_dart":"const Constant(true)","default_client_dart":null,"dsl_features":[]},{"name":"amoled_dark_theme","getter_name":"amoledDarkTheme","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"amoled_dark_theme\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"amoled_dark_theme\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"check_update","getter_name":"checkUpdate","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"check_update\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"check_update\" IN (0, 1))"},"default_dart":"const Constant(true)","default_client_dart":null,"dsl_features":[]},{"name":"normalize_audio","getter_name":"normalizeAudio","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"normalize_audio\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"normalize_audio\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"show_system_tray_icon","getter_name":"showSystemTrayIcon","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"show_system_tray_icon\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"show_system_tray_icon\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"system_title_bar","getter_name":"systemTitleBar","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"system_title_bar\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"system_title_bar\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"skip_non_music","getter_name":"skipNonMusic","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"skip_non_music\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"skip_non_music\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"close_behavior","getter_name":"closeBehavior","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(CloseBehavior.close.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(CloseBehavior.values)","dart_type_name":"CloseBehavior"}},{"name":"accent_color_scheme","getter_name":"accentColorScheme","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant(\"Slate:0xff64748b\")","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const SpotubeColorConverter()","dart_type_name":"SpotubeColor"}},{"name":"layout_mode","getter_name":"layoutMode","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(LayoutMode.adaptive.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(LayoutMode.values)","dart_type_name":"LayoutMode"}},{"name":"locale","getter_name":"locale","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant('{\"languageCode\":\"system\",\"countryCode\":\"system\"}')","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const LocaleConverter()","dart_type_name":"Locale"}},{"name":"market","getter_name":"market","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(Market.US.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(Market.values)","dart_type_name":"Market"}},{"name":"search_mode","getter_name":"searchMode","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(SearchMode.youtube.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(SearchMode.values)","dart_type_name":"SearchMode"}},{"name":"download_location","getter_name":"downloadLocation","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant(\"\")","default_client_dart":null,"dsl_features":[]},{"name":"local_library_location","getter_name":"localLibraryLocation","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant(\"\")","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const StringListConverter()","dart_type_name":"List"}},{"name":"theme_mode","getter_name":"themeMode","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(ThemeMode.system.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(ThemeMode.values)","dart_type_name":"ThemeMode"}},{"name":"audio_source_id","getter_name":"audioSourceId","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"youtube_client_engine","getter_name":"youtubeClientEngine","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(YoutubeClientEngine.youtubeExplode.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(YoutubeClientEngine.values)","dart_type_name":"YoutubeClientEngine"}},{"name":"discord_presence","getter_name":"discordPresence","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"discord_presence\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"discord_presence\" IN (0, 1))"},"default_dart":"const Constant(true)","default_client_dart":null,"dsl_features":[]},{"name":"endless_playback","getter_name":"endlessPlayback","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"endless_playback\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"endless_playback\" IN (0, 1))"},"default_dart":"const Constant(true)","default_client_dart":null,"dsl_features":[]},{"name":"enable_connect","getter_name":"enableConnect","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"enable_connect\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"enable_connect\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"connect_port","getter_name":"connectPort","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const Constant(-1)","default_client_dart":null,"dsl_features":[]},{"name":"cache_music","getter_name":"cacheMusic","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"cache_music\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"cache_music\" IN (0, 1))"},"default_dart":"const Constant(true)","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":3,"references":[],"type":"table","data":{"name":"scrobbler_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"currentDateAndTime","default_client_dart":null,"dsl_features":[]},{"name":"username","getter_name":"username","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"password_hash","getter_name":"passwordHash","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"EncryptedTextConverter()","dart_type_name":"DecryptedText"}}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":4,"references":[],"type":"table","data":{"name":"skip_segment_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"start","getter_name":"start","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"end","getter_name":"end","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"track_id","getter_name":"trackId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"currentDateAndTime","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":5,"references":[],"type":"table","data":{"name":"source_match_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"track_id","getter_name":"trackId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"source_info","getter_name":"sourceInfo","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant(\"{}\")","default_client_dart":null,"dsl_features":[]},{"name":"source_type","getter_name":"sourceType","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"currentDateAndTime","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":6,"references":[],"type":"table","data":{"name":"audio_player_state_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"playing","getter_name":"playing","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"playing\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"playing\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"loop_mode","getter_name":"loopMode","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(PlaylistMode.values)","dart_type_name":"PlaylistMode"}},{"name":"shuffled","getter_name":"shuffled","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"shuffled\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"shuffled\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"collections","getter_name":"collections","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const StringListConverter()","dart_type_name":"List"}},{"name":"tracks","getter_name":"tracks","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant(\"[]\")","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const SpotubeTrackObjectListConverter()","dart_type_name":"List"}},{"name":"current_index","getter_name":"currentIndex","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const Constant(0)","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":7,"references":[],"type":"table","data":{"name":"history_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"currentDateAndTime","default_client_dart":null,"dsl_features":[]},{"name":"type","getter_name":"type","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(HistoryEntryType.values)","dart_type_name":"HistoryEntryType"}},{"name":"item_id","getter_name":"itemId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"data","getter_name":"data","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const MapTypeConverter()","dart_type_name":"Map"}}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":8,"references":[],"type":"table","data":{"name":"lyrics_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"track_id","getter_name":"trackId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"data","getter_name":"data","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"SubtitleTypeConverter()","dart_type_name":"SubtitleSimple"}}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":9,"references":[],"type":"table","data":{"name":"plugins_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[{"allowed-lengths":{"min":1,"max":50}}]},{"name":"description","getter_name":"description","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"version","getter_name":"version","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"author","getter_name":"author","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"entry_point","getter_name":"entryPoint","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"apis","getter_name":"apis","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const StringListConverter()","dart_type_name":"List"}},{"name":"abilities","getter_name":"abilities","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const StringListConverter()","dart_type_name":"List"}},{"name":"selected_for_metadata","getter_name":"selectedForMetadata","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"selected_for_metadata\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"selected_for_metadata\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"selected_for_audio_source","getter_name":"selectedForAudioSource","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"selected_for_audio_source\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"selected_for_audio_source\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"repository","getter_name":"repository","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"plugin_api_version","getter_name":"pluginApiVersion","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant('2.0.0')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":10,"references":[1],"type":"index","data":{"on":1,"name":"unique_blacklist","sql":null,"unique":true,"columns":["element_type","element_id"]}},{"id":11,"references":[5],"type":"index","data":{"on":5,"name":"uniq_track_match","sql":null,"unique":true,"columns":["track_id","source_info","source_type"]}}]}
\ No newline at end of file
diff --git a/drift_schemas/app_db/drift_schema_v9.json b/drift_schemas/app_db/drift_schema_v9.json
new file mode 100644
index 00000000..73af2588
--- /dev/null
+++ b/drift_schemas/app_db/drift_schema_v9.json
@@ -0,0 +1 @@
+{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.2.0"},"options":{"store_date_time_values_as_text":false},"entities":[{"id":0,"references":[],"type":"table","data":{"name":"authentication_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"cookie","getter_name":"cookie","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"EncryptedTextConverter()","dart_type_name":"DecryptedText"}},{"name":"access_token","getter_name":"accessToken","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"EncryptedTextConverter()","dart_type_name":"DecryptedText"}},{"name":"expiration","getter_name":"expiration","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":1,"references":[],"type":"table","data":{"name":"blacklist_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"element_type","getter_name":"elementType","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(BlacklistedType.values)","dart_type_name":"BlacklistedType"}},{"name":"element_id","getter_name":"elementId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":2,"references":[],"type":"table","data":{"name":"preferences_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"audio_quality","getter_name":"audioQuality","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(SourceQualities.high.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(SourceQualities.values)","dart_type_name":"SourceQualities"}},{"name":"album_color_sync","getter_name":"albumColorSync","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"album_color_sync\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"album_color_sync\" IN (0, 1))"},"default_dart":"const Constant(true)","default_client_dart":null,"dsl_features":[]},{"name":"amoled_dark_theme","getter_name":"amoledDarkTheme","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"amoled_dark_theme\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"amoled_dark_theme\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"check_update","getter_name":"checkUpdate","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"check_update\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"check_update\" IN (0, 1))"},"default_dart":"const Constant(true)","default_client_dart":null,"dsl_features":[]},{"name":"normalize_audio","getter_name":"normalizeAudio","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"normalize_audio\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"normalize_audio\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"show_system_tray_icon","getter_name":"showSystemTrayIcon","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"show_system_tray_icon\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"show_system_tray_icon\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"system_title_bar","getter_name":"systemTitleBar","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"system_title_bar\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"system_title_bar\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"skip_non_music","getter_name":"skipNonMusic","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"skip_non_music\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"skip_non_music\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"close_behavior","getter_name":"closeBehavior","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(CloseBehavior.close.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(CloseBehavior.values)","dart_type_name":"CloseBehavior"}},{"name":"accent_color_scheme","getter_name":"accentColorScheme","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant(\"Slate:0xff64748b\")","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const SpotubeColorConverter()","dart_type_name":"SpotubeColor"}},{"name":"layout_mode","getter_name":"layoutMode","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(LayoutMode.adaptive.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(LayoutMode.values)","dart_type_name":"LayoutMode"}},{"name":"locale","getter_name":"locale","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant('{\"languageCode\":\"system\",\"countryCode\":\"system\"}')","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const LocaleConverter()","dart_type_name":"Locale"}},{"name":"market","getter_name":"market","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(Market.US.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(Market.values)","dart_type_name":"Market"}},{"name":"search_mode","getter_name":"searchMode","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(SearchMode.youtube.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(SearchMode.values)","dart_type_name":"SearchMode"}},{"name":"download_location","getter_name":"downloadLocation","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant(\"\")","default_client_dart":null,"dsl_features":[]},{"name":"local_library_location","getter_name":"localLibraryLocation","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant(\"\")","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const StringListConverter()","dart_type_name":"List"}},{"name":"piped_instance","getter_name":"pipedInstance","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant(\"https://pipedapi.kavin.rocks\")","default_client_dart":null,"dsl_features":[]},{"name":"invidious_instance","getter_name":"invidiousInstance","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant(\"https://inv.nadeko.net\")","default_client_dart":null,"dsl_features":[]},{"name":"theme_mode","getter_name":"themeMode","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(ThemeMode.system.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(ThemeMode.values)","dart_type_name":"ThemeMode"}},{"name":"audio_source","getter_name":"audioSource","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(AudioSource.youtube.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(AudioSource.values)","dart_type_name":"AudioSource"}},{"name":"youtube_client_engine","getter_name":"youtubeClientEngine","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(YoutubeClientEngine.youtubeExplode.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(YoutubeClientEngine.values)","dart_type_name":"YoutubeClientEngine"}},{"name":"stream_music_codec","getter_name":"streamMusicCodec","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(SourceCodecs.weba.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(SourceCodecs.values)","dart_type_name":"SourceCodecs"}},{"name":"download_music_codec","getter_name":"downloadMusicCodec","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(SourceCodecs.m4a.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(SourceCodecs.values)","dart_type_name":"SourceCodecs"}},{"name":"discord_presence","getter_name":"discordPresence","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"discord_presence\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"discord_presence\" IN (0, 1))"},"default_dart":"const Constant(true)","default_client_dart":null,"dsl_features":[]},{"name":"endless_playback","getter_name":"endlessPlayback","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"endless_playback\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"endless_playback\" IN (0, 1))"},"default_dart":"const Constant(true)","default_client_dart":null,"dsl_features":[]},{"name":"enable_connect","getter_name":"enableConnect","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"enable_connect\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"enable_connect\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"connect_port","getter_name":"connectPort","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const Constant(-1)","default_client_dart":null,"dsl_features":[]},{"name":"cache_music","getter_name":"cacheMusic","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"cache_music\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"cache_music\" IN (0, 1))"},"default_dart":"const Constant(true)","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":3,"references":[],"type":"table","data":{"name":"scrobbler_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"currentDateAndTime","default_client_dart":null,"dsl_features":[]},{"name":"username","getter_name":"username","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"password_hash","getter_name":"passwordHash","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"EncryptedTextConverter()","dart_type_name":"DecryptedText"}}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":4,"references":[],"type":"table","data":{"name":"skip_segment_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"start","getter_name":"start","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"end","getter_name":"end","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"track_id","getter_name":"trackId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"currentDateAndTime","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":5,"references":[],"type":"table","data":{"name":"source_match_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"track_id","getter_name":"trackId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"source_id","getter_name":"sourceId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"source_type","getter_name":"sourceType","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"Constant(SourceType.youtube.name)","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(SourceType.values)","dart_type_name":"SourceType"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"currentDateAndTime","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":6,"references":[],"type":"table","data":{"name":"audio_player_state_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"playing","getter_name":"playing","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"playing\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"playing\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"loop_mode","getter_name":"loopMode","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(PlaylistMode.values)","dart_type_name":"PlaylistMode"}},{"name":"shuffled","getter_name":"shuffled","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"shuffled\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"shuffled\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"collections","getter_name":"collections","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const StringListConverter()","dart_type_name":"List"}},{"name":"tracks","getter_name":"tracks","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant(\"[]\")","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const SpotubeTrackObjectListConverter()","dart_type_name":"List"}},{"name":"current_index","getter_name":"currentIndex","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const Constant(0)","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":7,"references":[],"type":"table","data":{"name":"history_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"currentDateAndTime","default_client_dart":null,"dsl_features":[]},{"name":"type","getter_name":"type","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumNameConverter(HistoryEntryType.values)","dart_type_name":"HistoryEntryType"}},{"name":"item_id","getter_name":"itemId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"data","getter_name":"data","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const MapTypeConverter()","dart_type_name":"Map"}}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":8,"references":[],"type":"table","data":{"name":"lyrics_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"track_id","getter_name":"trackId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"data","getter_name":"data","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"SubtitleTypeConverter()","dart_type_name":"SubtitleSimple"}}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":9,"references":[],"type":"table","data":{"name":"plugins_table","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[{"allowed-lengths":{"min":1,"max":50}}]},{"name":"description","getter_name":"description","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"version","getter_name":"version","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"author","getter_name":"author","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"entry_point","getter_name":"entryPoint","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"apis","getter_name":"apis","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const StringListConverter()","dart_type_name":"List"}},{"name":"abilities","getter_name":"abilities","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const StringListConverter()","dart_type_name":"List"}},{"name":"selected_for_metadata","getter_name":"selectedForMetadata","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"selected_for_metadata\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"selected_for_metadata\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"selected_for_audio_source","getter_name":"selectedForAudioSource","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"selected_for_audio_source\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"selected_for_audio_source\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"repository","getter_name":"repository","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"plugin_api_version","getter_name":"pluginApiVersion","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant('2.0.0')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":10,"references":[1],"type":"index","data":{"on":1,"name":"unique_blacklist","sql":null,"unique":true,"columns":["element_type","element_id"]}},{"id":11,"references":[5],"type":"index","data":{"on":5,"name":"uniq_track_match","sql":null,"unique":true,"columns":["track_id","source_id","source_type"]}}]}
\ No newline at end of file
diff --git a/lib/collections/assets.gen.dart b/lib/collections/assets.gen.dart
index 31fb54b8..7ab0ad03 100644
--- a/lib/collections/assets.gen.dart
+++ b/lib/collections/assets.gen.dart
@@ -1,3 +1,5 @@
+// dart format width=80
+
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
/// FlutterGen
@@ -5,7 +7,7 @@
// coverage:ignore-file
// ignore_for_file: type=lint
-// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use
+// ignore_for_file: deprecated_member_use,directives_ordering,implicit_dynamic_list_literal,unnecessary_import
import 'package:flutter/widgets.dart';
@@ -64,9 +66,26 @@ class $AssetsImagesGen {
];
}
+class $AssetsPluginsGen {
+ const $AssetsPluginsGen();
+
+ /// Directory path: assets/plugins/spotube-plugin-musicbrainz-listenbrainz
+ $AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen
+ get spotubePluginMusicbrainzListenbrainz =>
+ const $AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen();
+
+ /// Directory path: assets/plugins/spotube-plugin-youtube-audio
+ $AssetsPluginsSpotubePluginYoutubeAudioGen get spotubePluginYoutubeAudio =>
+ const $AssetsPluginsSpotubePluginYoutubeAudioGen();
+}
+
class $AssetsImagesLogosGen {
const $AssetsImagesLogosGen();
+ /// File path: assets/images/logos/dab-music.png
+ AssetGenImage get dabMusic =>
+ const AssetGenImage('assets/images/logos/dab-music.png');
+
/// File path: assets/images/logos/invidious.jpg
AssetGenImage get invidious =>
const AssetGenImage('assets/images/logos/invidious.jpg');
@@ -75,20 +94,39 @@ class $AssetsImagesLogosGen {
AssetGenImage get jiosaavn =>
const AssetGenImage('assets/images/logos/jiosaavn.png');
- /// File path: assets/images/logos/songlink-transparent.png
- AssetGenImage get songlinkTransparent =>
- const AssetGenImage('assets/images/logos/songlink-transparent.png');
+ /// List of all assets
+ List get values => [dabMusic, invidious, jiosaavn];
+}
+
+class $AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen {
+ const $AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen();
+
+ /// File path: assets/plugins/spotube-plugin-musicbrainz-listenbrainz/plugin.smplug
+ String get plugin =>
+ 'assets/plugins/spotube-plugin-musicbrainz-listenbrainz/plugin.smplug';
/// List of all assets
- List get values => [invidious, jiosaavn, songlinkTransparent];
+ List get values => [plugin];
+}
+
+class $AssetsPluginsSpotubePluginYoutubeAudioGen {
+ const $AssetsPluginsSpotubePluginYoutubeAudioGen();
+
+ /// File path: assets/plugins/spotube-plugin-youtube-audio/plugin.smplug
+ String get plugin =>
+ 'assets/plugins/spotube-plugin-youtube-audio/plugin.smplug';
+
+ /// List of all assets
+ List get values => [plugin];
}
class Assets {
- Assets._();
+ const Assets._();
static const String license = 'LICENSE';
static const $AssetsBrandingGen branding = $AssetsBrandingGen();
static const $AssetsImagesGen images = $AssetsImagesGen();
+ static const $AssetsPluginsGen plugins = $AssetsPluginsGen();
/// List of all assets
static List get values => [license];
@@ -99,12 +137,14 @@ class AssetGenImage {
this._assetName, {
this.size,
this.flavors = const {},
+ this.animation,
});
final String _assetName;
final Size? size;
final Set flavors;
+ final AssetGenImageAnimation? animation;
Image image({
Key? key,
@@ -127,7 +167,7 @@ class AssetGenImage {
bool gaplessPlayback = true,
bool isAntiAlias = false,
String? package,
- FilterQuality filterQuality = FilterQuality.low,
+ FilterQuality filterQuality = FilterQuality.medium,
int? cacheWidth,
int? cacheHeight,
}) {
@@ -174,3 +214,15 @@ class AssetGenImage {
String get keyName => _assetName;
}
+
+class AssetGenImageAnimation {
+ const AssetGenImageAnimation({
+ required this.isAnimation,
+ required this.duration,
+ required this.frames,
+ });
+
+ final bool isAnimation;
+ final Duration duration;
+ final int frames;
+}
diff --git a/lib/collections/fonts.gen.dart b/lib/collections/fonts.gen.dart
index 16cc6e82..d2c68231 100644
--- a/lib/collections/fonts.gen.dart
+++ b/lib/collections/fonts.gen.dart
@@ -1,3 +1,4 @@
+// dart format width=80
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
/// FlutterGen
@@ -5,7 +6,7 @@
// coverage:ignore-file
// ignore_for_file: type=lint
-// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use
+// ignore_for_file: deprecated_member_use,directives_ordering,implicit_dynamic_list_literal,unnecessary_import
class FontFamily {
FontFamily._();
diff --git a/lib/collections/routes.gr.dart b/lib/collections/routes.gr.dart
index e039abb9..f5ff24bf 100644
--- a/lib/collections/routes.gr.dart
+++ b/lib/collections/routes.gr.dart
@@ -1,3 +1,4 @@
+// dart format width=80
// GENERATED CODE - DO NOT MODIFY BY HAND
// **************************************************************************
@@ -59,10 +60,7 @@ import 'package:spotube/pages/track/track.dart' as _i35;
/// [_i1.AboutSpotubePage]
class AboutSpotubeRoute extends _i41.PageRouteInfo {
const AboutSpotubeRoute({List<_i41.PageRouteInfo>? children})
- : super(
- AboutSpotubeRoute.name,
- initialChildren: children,
- );
+ : super(AboutSpotubeRoute.name, initialChildren: children);
static const String name = 'AboutSpotubeRoute';
@@ -83,15 +81,11 @@ class AlbumRoute extends _i41.PageRouteInfo {
required _i43.SpotubeSimpleAlbumObject album,
List<_i41.PageRouteInfo>? children,
}) : super(
- AlbumRoute.name,
- args: AlbumRouteArgs(
- key: key,
- id: id,
- album: album,
- ),
- rawPathParams: {'id': id},
- initialChildren: children,
- );
+ AlbumRoute.name,
+ args: AlbumRouteArgs(key: key, id: id, album: album),
+ rawPathParams: {'id': id},
+ initialChildren: children,
+ );
static const String name = 'AlbumRoute';
@@ -99,21 +93,13 @@ class AlbumRoute extends _i41.PageRouteInfo {
name,
builder: (data) {
final args = data.argsAs();
- return _i2.AlbumPage(
- key: args.key,
- id: args.id,
- album: args.album,
- );
+ return _i2.AlbumPage(key: args.key, id: args.id, album: args.album);
},
);
}
class AlbumRouteArgs {
- const AlbumRouteArgs({
- this.key,
- required this.id,
- required this.album,
- });
+ const AlbumRouteArgs({this.key, required this.id, required this.album});
final _i42.Key? key;
@@ -135,14 +121,11 @@ class ArtistRoute extends _i41.PageRouteInfo {
_i42.Key? key,
List<_i41.PageRouteInfo>? children,
}) : super(
- ArtistRoute.name,
- args: ArtistRouteArgs(
- artistId: artistId,
- key: key,
- ),
- rawPathParams: {'id': artistId},
- initialChildren: children,
- );
+ ArtistRoute.name,
+ args: ArtistRouteArgs(artistId: artistId, key: key),
+ rawPathParams: {'id': artistId},
+ initialChildren: children,
+ );
static const String name = 'ArtistRoute';
@@ -151,20 +134,15 @@ class ArtistRoute extends _i41.PageRouteInfo {
builder: (data) {
final pathParams = data.inheritedPathParams;
final args = data.argsAs(
- orElse: () => ArtistRouteArgs(artistId: pathParams.getString('id')));
- return _i3.ArtistPage(
- args.artistId,
- key: args.key,
+ orElse: () => ArtistRouteArgs(artistId: pathParams.getString('id')),
);
+ return _i3.ArtistPage(args.artistId, key: args.key);
},
);
}
class ArtistRouteArgs {
- const ArtistRouteArgs({
- required this.artistId,
- this.key,
- });
+ const ArtistRouteArgs({required this.artistId, this.key});
final String artistId;
@@ -180,10 +158,7 @@ class ArtistRouteArgs {
/// [_i4.BlackListPage]
class BlackListRoute extends _i41.PageRouteInfo {
const BlackListRoute({List<_i41.PageRouteInfo>? children})
- : super(
- BlackListRoute.name,
- initialChildren: children,
- );
+ : super(BlackListRoute.name, initialChildren: children);
static const String name = 'BlackListRoute';
@@ -199,10 +174,7 @@ class BlackListRoute extends _i41.PageRouteInfo {
/// [_i5.ConnectControlPage]
class ConnectControlRoute extends _i41.PageRouteInfo {
const ConnectControlRoute({List<_i41.PageRouteInfo>? children})
- : super(
- ConnectControlRoute.name,
- initialChildren: children,
- );
+ : super(ConnectControlRoute.name, initialChildren: children);
static const String name = 'ConnectControlRoute';
@@ -218,10 +190,7 @@ class ConnectControlRoute extends _i41.PageRouteInfo {
/// [_i6.ConnectPage]
class ConnectRoute extends _i41.PageRouteInfo {
const ConnectRoute({List<_i41.PageRouteInfo>? children})
- : super(
- ConnectRoute.name,
- initialChildren: children,
- );
+ : super(ConnectRoute.name, initialChildren: children);
static const String name = 'ConnectRoute';
@@ -237,10 +206,7 @@ class ConnectRoute extends _i41.PageRouteInfo {
/// [_i7.GettingStartedPage]
class GettingStartedRoute extends _i41.PageRouteInfo {
const GettingStartedRoute({List<_i41.PageRouteInfo>? children})
- : super(
- GettingStartedRoute.name,
- initialChildren: children,
- );
+ : super(GettingStartedRoute.name, initialChildren: children);
static const String name = 'GettingStartedRoute';
@@ -262,15 +228,15 @@ class HomeBrowseSectionItemsRoute
required _i43.SpotubeBrowseSectionObject section,
List<_i41.PageRouteInfo>? children,
}) : super(
- HomeBrowseSectionItemsRoute.name,
- args: HomeBrowseSectionItemsRouteArgs(
- key: key,
- sectionId: sectionId,
- section: section,
- ),
- rawPathParams: {'sectionId': sectionId},
- initialChildren: children,
- );
+ HomeBrowseSectionItemsRoute.name,
+ args: HomeBrowseSectionItemsRouteArgs(
+ key: key,
+ sectionId: sectionId,
+ section: section,
+ ),
+ rawPathParams: {'sectionId': sectionId},
+ initialChildren: children,
+ );
static const String name = 'HomeBrowseSectionItemsRoute';
@@ -310,10 +276,7 @@ class HomeBrowseSectionItemsRouteArgs {
/// [_i9.HomePage]
class HomeRoute extends _i41.PageRouteInfo {
const HomeRoute({List<_i41.PageRouteInfo>? children})
- : super(
- HomeRoute.name,
- initialChildren: children,
- );
+ : super(HomeRoute.name, initialChildren: children);
static const String name = 'HomeRoute';
@@ -329,10 +292,7 @@ class HomeRoute extends _i41.PageRouteInfo {
/// [_i10.LastFMLoginPage]
class LastFMLoginRoute extends _i41.PageRouteInfo {
const LastFMLoginRoute({List<_i41.PageRouteInfo>? children})
- : super(
- LastFMLoginRoute.name,
- initialChildren: children,
- );
+ : super(LastFMLoginRoute.name, initialChildren: children);
static const String name = 'LastFMLoginRoute';
@@ -348,10 +308,7 @@ class LastFMLoginRoute extends _i41.PageRouteInfo {
/// [_i11.LibraryPage]
class LibraryRoute extends _i41.PageRouteInfo {
const LibraryRoute({List<_i41.PageRouteInfo>? children})
- : super(
- LibraryRoute.name,
- initialChildren: children,
- );
+ : super(LibraryRoute.name, initialChildren: children);
static const String name = 'LibraryRoute';
@@ -371,13 +328,10 @@ class LikedPlaylistRoute extends _i41.PageRouteInfo {
required _i43.SpotubeSimplePlaylistObject playlist,
List<_i41.PageRouteInfo>? children,
}) : super(
- LikedPlaylistRoute.name,
- args: LikedPlaylistRouteArgs(
- key: key,
- playlist: playlist,
- ),
- initialChildren: children,
- );
+ LikedPlaylistRoute.name,
+ args: LikedPlaylistRouteArgs(key: key, playlist: playlist),
+ initialChildren: children,
+ );
static const String name = 'LikedPlaylistRoute';
@@ -385,19 +339,13 @@ class LikedPlaylistRoute extends _i41.PageRouteInfo {
name,
builder: (data) {
final args = data.argsAs();
- return _i12.LikedPlaylistPage(
- key: args.key,
- playlist: args.playlist,
- );
+ return _i12.LikedPlaylistPage(key: args.key, playlist: args.playlist);
},
);
}
class LikedPlaylistRouteArgs {
- const LikedPlaylistRouteArgs({
- this.key,
- required this.playlist,
- });
+ const LikedPlaylistRouteArgs({this.key, required this.playlist});
final _i42.Key? key;
@@ -419,15 +367,15 @@ class LocalLibraryRoute extends _i41.PageRouteInfo {
bool isCache = false,
List<_i41.PageRouteInfo>? children,
}) : super(
- LocalLibraryRoute.name,
- args: LocalLibraryRouteArgs(
- location: location,
- key: key,
- isDownloads: isDownloads,
- isCache: isCache,
- ),
- initialChildren: children,
- );
+ LocalLibraryRoute.name,
+ args: LocalLibraryRouteArgs(
+ location: location,
+ key: key,
+ isDownloads: isDownloads,
+ isCache: isCache,
+ ),
+ initialChildren: children,
+ );
static const String name = 'LocalLibraryRoute';
@@ -471,10 +419,7 @@ class LocalLibraryRouteArgs {
/// [_i14.LogsPage]
class LogsRoute extends _i41.PageRouteInfo {
const LogsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- LogsRoute.name,
- initialChildren: children,
- );
+ : super(LogsRoute.name, initialChildren: children);
static const String name = 'LogsRoute';
@@ -490,10 +435,7 @@ class LogsRoute extends _i41.PageRouteInfo {
/// [_i15.LyricsPage]
class LyricsRoute extends _i41.PageRouteInfo {
const LyricsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- LyricsRoute.name,
- initialChildren: children,
- );
+ : super(LyricsRoute.name, initialChildren: children);
static const String name = 'LyricsRoute';
@@ -513,13 +455,10 @@ class MiniLyricsRoute extends _i41.PageRouteInfo {
required _i44.Size prevSize,
List<_i41.PageRouteInfo>? children,
}) : super(
- MiniLyricsRoute.name,
- args: MiniLyricsRouteArgs(
- key: key,
- prevSize: prevSize,
- ),
- initialChildren: children,
- );
+ MiniLyricsRoute.name,
+ args: MiniLyricsRouteArgs(key: key, prevSize: prevSize),
+ initialChildren: children,
+ );
static const String name = 'MiniLyricsRoute';
@@ -527,19 +466,13 @@ class MiniLyricsRoute extends _i41.PageRouteInfo {
name,
builder: (data) {
final args = data.argsAs();
- return _i16.MiniLyricsPage(
- key: args.key,
- prevSize: args.prevSize,
- );
+ return _i16.MiniLyricsPage(key: args.key, prevSize: args.prevSize);
},
);
}
class MiniLyricsRouteArgs {
- const MiniLyricsRouteArgs({
- this.key,
- required this.prevSize,
- });
+ const MiniLyricsRouteArgs({this.key, required this.prevSize});
final _i44.Key? key;
@@ -555,10 +488,7 @@ class MiniLyricsRouteArgs {
/// [_i17.PlayerLyricsPage]
class PlayerLyricsRoute extends _i41.PageRouteInfo {
const PlayerLyricsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- PlayerLyricsRoute.name,
- initialChildren: children,
- );
+ : super(PlayerLyricsRoute.name, initialChildren: children);
static const String name = 'PlayerLyricsRoute';
@@ -574,10 +504,7 @@ class PlayerLyricsRoute extends _i41.PageRouteInfo {
/// [_i18.PlayerQueuePage]
class PlayerQueueRoute extends _i41.PageRouteInfo {
const PlayerQueueRoute({List<_i41.PageRouteInfo>? children})
- : super(
- PlayerQueueRoute.name,
- initialChildren: children,
- );
+ : super(PlayerQueueRoute.name, initialChildren: children);
static const String name = 'PlayerQueueRoute';
@@ -593,10 +520,7 @@ class PlayerQueueRoute extends _i41.PageRouteInfo {
/// [_i19.PlayerTrackSourcesPage]
class PlayerTrackSourcesRoute extends _i41.PageRouteInfo {
const PlayerTrackSourcesRoute({List<_i41.PageRouteInfo>? children})
- : super(
- PlayerTrackSourcesRoute.name,
- initialChildren: children,
- );
+ : super(PlayerTrackSourcesRoute.name, initialChildren: children);
static const String name = 'PlayerTrackSourcesRoute';
@@ -617,15 +541,11 @@ class PlaylistRoute extends _i41.PageRouteInfo {
required _i43.SpotubeSimplePlaylistObject playlist,
List<_i41.PageRouteInfo>? children,
}) : super(
- PlaylistRoute.name,
- args: PlaylistRouteArgs(
- key: key,
- id: id,
- playlist: playlist,
- ),
- rawPathParams: {'id': id},
- initialChildren: children,
- );
+ PlaylistRoute.name,
+ args: PlaylistRouteArgs(key: key, id: id, playlist: playlist),
+ rawPathParams: {'id': id},
+ initialChildren: children,
+ );
static const String name = 'PlaylistRoute';
@@ -643,11 +563,7 @@ class PlaylistRoute extends _i41.PageRouteInfo {
}
class PlaylistRouteArgs {
- const PlaylistRouteArgs({
- this.key,
- required this.id,
- required this.playlist,
- });
+ const PlaylistRouteArgs({this.key, required this.id, required this.playlist});
final _i42.Key? key;
@@ -665,10 +581,7 @@ class PlaylistRouteArgs {
/// [_i21.ProfilePage]
class ProfileRoute extends _i41.PageRouteInfo {
const ProfileRoute({List<_i41.PageRouteInfo>? children})
- : super(
- ProfileRoute.name,
- initialChildren: children,
- );
+ : super(ProfileRoute.name, initialChildren: children);
static const String name = 'ProfileRoute';
@@ -684,10 +597,7 @@ class ProfileRoute extends _i41.PageRouteInfo {
/// [_i22.RootAppPage]
class RootAppRoute extends _i41.PageRouteInfo {
const RootAppRoute({List<_i41.PageRouteInfo>? children})
- : super(
- RootAppRoute.name,
- initialChildren: children,
- );
+ : super(RootAppRoute.name, initialChildren: children);
static const String name = 'RootAppRoute';
@@ -703,10 +613,7 @@ class RootAppRoute extends _i41.PageRouteInfo {
/// [_i23.SearchPage]
class SearchRoute extends _i41.PageRouteInfo {
const SearchRoute({List<_i41.PageRouteInfo>? children})
- : super(
- SearchRoute.name,
- initialChildren: children,
- );
+ : super(SearchRoute.name, initialChildren: children);
static const String name = 'SearchRoute';
@@ -728,14 +635,14 @@ class SettingsMetadataProviderFormRoute
required List<_i43.MetadataFormFieldObject> fields,
List<_i41.PageRouteInfo>? children,
}) : super(
- SettingsMetadataProviderFormRoute.name,
- args: SettingsMetadataProviderFormRouteArgs(
- key: key,
- title: title,
- fields: fields,
- ),
- initialChildren: children,
- );
+ SettingsMetadataProviderFormRoute.name,
+ args: SettingsMetadataProviderFormRouteArgs(
+ key: key,
+ title: title,
+ fields: fields,
+ ),
+ initialChildren: children,
+ );
static const String name = 'SettingsMetadataProviderFormRoute';
@@ -775,10 +682,7 @@ class SettingsMetadataProviderFormRouteArgs {
/// [_i25.SettingsMetadataProviderPage]
class SettingsMetadataProviderRoute extends _i41.PageRouteInfo {
const SettingsMetadataProviderRoute({List<_i41.PageRouteInfo>? children})
- : super(
- SettingsMetadataProviderRoute.name,
- initialChildren: children,
- );
+ : super(SettingsMetadataProviderRoute.name, initialChildren: children);
static const String name = 'SettingsMetadataProviderRoute';
@@ -794,10 +698,7 @@ class SettingsMetadataProviderRoute extends _i41.PageRouteInfo {
/// [_i26.SettingsPage]
class SettingsRoute extends _i41.PageRouteInfo {
const SettingsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- SettingsRoute.name,
- initialChildren: children,
- );
+ : super(SettingsRoute.name, initialChildren: children);
static const String name = 'SettingsRoute';
@@ -813,10 +714,7 @@ class SettingsRoute extends _i41.PageRouteInfo {
/// [_i27.SettingsScrobblingPage]
class SettingsScrobblingRoute extends _i41.PageRouteInfo {
const SettingsScrobblingRoute({List<_i41.PageRouteInfo>? children})
- : super(
- SettingsScrobblingRoute.name,
- initialChildren: children,
- );
+ : super(SettingsScrobblingRoute.name, initialChildren: children);
static const String name = 'SettingsScrobblingRoute';
@@ -832,10 +730,7 @@ class SettingsScrobblingRoute extends _i41.PageRouteInfo {
/// [_i28.StatsAlbumsPage]
class StatsAlbumsRoute extends _i41.PageRouteInfo {
const StatsAlbumsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- StatsAlbumsRoute.name,
- initialChildren: children,
- );
+ : super(StatsAlbumsRoute.name, initialChildren: children);
static const String name = 'StatsAlbumsRoute';
@@ -851,10 +746,7 @@ class StatsAlbumsRoute extends _i41.PageRouteInfo {
/// [_i29.StatsArtistsPage]
class StatsArtistsRoute extends _i41.PageRouteInfo {
const StatsArtistsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- StatsArtistsRoute.name,
- initialChildren: children,
- );
+ : super(StatsArtistsRoute.name, initialChildren: children);
static const String name = 'StatsArtistsRoute';
@@ -870,10 +762,7 @@ class StatsArtistsRoute extends _i41.PageRouteInfo {
/// [_i30.StatsMinutesPage]
class StatsMinutesRoute extends _i41.PageRouteInfo {
const StatsMinutesRoute({List<_i41.PageRouteInfo>? children})
- : super(
- StatsMinutesRoute.name,
- initialChildren: children,
- );
+ : super(StatsMinutesRoute.name, initialChildren: children);
static const String name = 'StatsMinutesRoute';
@@ -889,10 +778,7 @@ class StatsMinutesRoute extends _i41.PageRouteInfo {
/// [_i31.StatsPage]
class StatsRoute extends _i41.PageRouteInfo {
const StatsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- StatsRoute.name,
- initialChildren: children,
- );
+ : super(StatsRoute.name, initialChildren: children);
static const String name = 'StatsRoute';
@@ -908,10 +794,7 @@ class StatsRoute extends _i41.PageRouteInfo {
/// [_i32.StatsPlaylistsPage]
class StatsPlaylistsRoute extends _i41.PageRouteInfo {
const StatsPlaylistsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- StatsPlaylistsRoute.name,
- initialChildren: children,
- );
+ : super(StatsPlaylistsRoute.name, initialChildren: children);
static const String name = 'StatsPlaylistsRoute';
@@ -927,10 +810,7 @@ class StatsPlaylistsRoute extends _i41.PageRouteInfo {
/// [_i33.StatsStreamFeesPage]
class StatsStreamFeesRoute extends _i41.PageRouteInfo {
const StatsStreamFeesRoute({List<_i41.PageRouteInfo>? children})
- : super(
- StatsStreamFeesRoute.name,
- initialChildren: children,
- );
+ : super(StatsStreamFeesRoute.name, initialChildren: children);
static const String name = 'StatsStreamFeesRoute';
@@ -946,10 +826,7 @@ class StatsStreamFeesRoute extends _i41.PageRouteInfo {
/// [_i34.StatsStreamsPage]
class StatsStreamsRoute extends _i41.PageRouteInfo {
const StatsStreamsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- StatsStreamsRoute.name,
- initialChildren: children,
- );
+ : super(StatsStreamsRoute.name, initialChildren: children);
static const String name = 'StatsStreamsRoute';
@@ -969,14 +846,11 @@ class TrackRoute extends _i41.PageRouteInfo {
required String trackId,
List<_i41.PageRouteInfo>? children,
}) : super(
- TrackRoute.name,
- args: TrackRouteArgs(
- key: key,
- trackId: trackId,
- ),
- rawPathParams: {'id': trackId},
- initialChildren: children,
- );
+ TrackRoute.name,
+ args: TrackRouteArgs(key: key, trackId: trackId),
+ rawPathParams: {'id': trackId},
+ initialChildren: children,
+ );
static const String name = 'TrackRoute';
@@ -985,20 +859,15 @@ class TrackRoute extends _i41.PageRouteInfo {
builder: (data) {
final pathParams = data.inheritedPathParams;
final args = data.argsAs(
- orElse: () => TrackRouteArgs(trackId: pathParams.getString('id')));
- return _i35.TrackPage(
- key: args.key,
- trackId: args.trackId,
+ orElse: () => TrackRouteArgs(trackId: pathParams.getString('id')),
);
+ return _i35.TrackPage(key: args.key, trackId: args.trackId);
},
);
}
class TrackRouteArgs {
- const TrackRouteArgs({
- this.key,
- required this.trackId,
- });
+ const TrackRouteArgs({this.key, required this.trackId});
final _i44.Key? key;
@@ -1014,10 +883,7 @@ class TrackRouteArgs {
/// [_i36.UserAlbumsPage]
class UserAlbumsRoute extends _i41.PageRouteInfo {
const UserAlbumsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- UserAlbumsRoute.name,
- initialChildren: children,
- );
+ : super(UserAlbumsRoute.name, initialChildren: children);
static const String name = 'UserAlbumsRoute';
@@ -1033,10 +899,7 @@ class UserAlbumsRoute extends _i41.PageRouteInfo {
/// [_i37.UserArtistsPage]
class UserArtistsRoute extends _i41.PageRouteInfo {
const UserArtistsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- UserArtistsRoute.name,
- initialChildren: children,
- );
+ : super(UserArtistsRoute.name, initialChildren: children);
static const String name = 'UserArtistsRoute';
@@ -1052,10 +915,7 @@ class UserArtistsRoute extends _i41.PageRouteInfo {
/// [_i38.UserDownloadsPage]
class UserDownloadsRoute extends _i41.PageRouteInfo {
const UserDownloadsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- UserDownloadsRoute.name,
- initialChildren: children,
- );
+ : super(UserDownloadsRoute.name, initialChildren: children);
static const String name = 'UserDownloadsRoute';
@@ -1071,10 +931,7 @@ class UserDownloadsRoute extends _i41.PageRouteInfo {
/// [_i39.UserLocalLibraryPage]
class UserLocalLibraryRoute extends _i41.PageRouteInfo {
const UserLocalLibraryRoute({List<_i41.PageRouteInfo>? children})
- : super(
- UserLocalLibraryRoute.name,
- initialChildren: children,
- );
+ : super(UserLocalLibraryRoute.name, initialChildren: children);
static const String name = 'UserLocalLibraryRoute';
@@ -1090,10 +947,7 @@ class UserLocalLibraryRoute extends _i41.PageRouteInfo {
/// [_i40.UserPlaylistsPage]
class UserPlaylistsRoute extends _i41.PageRouteInfo {
const UserPlaylistsRoute({List<_i41.PageRouteInfo>? children})
- : super(
- UserPlaylistsRoute.name,
- initialChildren: children,
- );
+ : super(UserPlaylistsRoute.name, initialChildren: children);
static const String name = 'UserPlaylistsRoute';
diff --git a/lib/collections/spotube_icons.dart b/lib/collections/spotube_icons.dart
index b10ef7e3..99d9ff74 100644
--- a/lib/collections/spotube_icons.dart
+++ b/lib/collections/spotube_icons.dart
@@ -80,6 +80,7 @@ abstract class SpotubeIcons {
static const hoverOff = Icons.back_hand_outlined;
static const dragHandle = Icons.drag_indicator;
static const lightning = Icons.flash_on_rounded;
+ static const lightningOutlined = FeatherIcons.zap;
static const colorSync = FeatherIcons.activity;
static const language = FeatherIcons.globe;
static const error = FeatherIcons.alertTriangle;
@@ -134,7 +135,7 @@ abstract class SpotubeIcons {
static const list = FeatherIcons.list;
static const device = FeatherIcons.smartphone;
static const engine = FeatherIcons.server;
- static const extensions = FeatherIcons.package;
+ static const extensions = Icons.extension_rounded;
static const message = FeatherIcons.send;
static const upload = FeatherIcons.uploadCloud;
static const plugin = Icons.extension_outlined;
diff --git a/lib/components/dialogs/link_open_permission_dialog.dart b/lib/components/dialogs/link_open_permission_dialog.dart
new file mode 100644
index 00000000..a7212d0a
--- /dev/null
+++ b/lib/components/dialogs/link_open_permission_dialog.dart
@@ -0,0 +1,69 @@
+import 'package:flutter/services.dart';
+import 'package:shadcn_flutter/shadcn_flutter.dart';
+import 'package:spotube/collections/spotube_icons.dart';
+import 'package:spotube/extensions/context.dart';
+import 'package:url_launcher/url_launcher_string.dart';
+
+class LinkOpenPermissionDialog extends StatelessWidget {
+ final String? href;
+ const LinkOpenPermissionDialog({super.key, this.href});
+
+ @override
+ Widget build(BuildContext context) {
+ return ConstrainedBox(
+ constraints: const BoxConstraints(maxWidth: 450),
+ child: AlertDialog(
+ title: Row(
+ spacing: 8,
+ children: [
+ const Icon(SpotubeIcons.warning),
+ Text(context.l10n.open_link_in_browser),
+ ],
+ ),
+ content: Text.rich(
+ TextSpan(
+ children: [
+ TextSpan(
+ text:
+ "${context.l10n.do_you_want_to_open_the_following_link}:\n",
+ ),
+ if (href != null)
+ TextSpan(
+ text: "$href\n\n",
+ style: const TextStyle(color: Colors.blue),
+ ),
+ TextSpan(text: context.l10n.unsafe_url_warning),
+ ],
+ ),
+ ),
+ actions: [
+ Button.ghost(
+ onPressed: () => Navigator.of(context).pop(false),
+ child: Text(context.l10n.cancel),
+ ),
+ Button.ghost(
+ onPressed: () {
+ if (href != null) {
+ Clipboard.setData(ClipboardData(text: href!));
+ }
+ Navigator.of(context).pop(false);
+ },
+ child: Text(context.l10n.copy_link),
+ ),
+ Button.destructive(
+ onPressed: () {
+ if (href != null) {
+ launchUrlString(
+ href!,
+ mode: LaunchMode.externalApplication,
+ );
+ }
+ Navigator.of(context).pop(true);
+ },
+ child: Text(context.l10n.open),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/components/dialogs/replace_downloaded_dialog.dart b/lib/components/dialogs/replace_downloaded_dialog.dart
index 6634a039..5b5b194e 100644
--- a/lib/components/dialogs/replace_downloaded_dialog.dart
+++ b/lib/components/dialogs/replace_downloaded_dialog.dart
@@ -12,13 +12,12 @@ class ReplaceDownloadedDialog extends ConsumerWidget {
@override
Widget build(BuildContext context, ref) {
- final groupValue = ref.watch(replaceDownloadedFileState);
final replaceAll = ref.watch(replaceDownloadedFileState);
return AlertDialog(
title: Text(context.l10n.track_exists(track.name)),
content: RadioGroup(
- value: groupValue,
+ value: replaceAll,
onChanged: (value) {
ref.read(replaceDownloadedFileState.notifier).state = value;
},
diff --git a/lib/components/dialogs/track_details_dialog.dart b/lib/components/dialogs/track_details_dialog.dart
index 3d3fd7e9..9d35a6fb 100644
--- a/lib/components/dialogs/track_details_dialog.dart
+++ b/lib/components/dialogs/track_details_dialog.dart
@@ -7,8 +7,7 @@ import 'package:spotube/extensions/constrains.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/extensions/duration.dart';
import 'package:spotube/models/metadata/metadata.dart';
-import 'package:spotube/models/playback/track_sources.dart';
-import 'package:spotube/provider/server/track_sources.dart';
+import 'package:spotube/provider/server/sourced_track_provider.dart';
class TrackDetailsDialog extends HookConsumerWidget {
final SpotubeFullTrackObject track;
@@ -21,8 +20,7 @@ class TrackDetailsDialog extends HookConsumerWidget {
Widget build(BuildContext context, ref) {
final theme = Theme.of(context);
final mediaQuery = MediaQuery.of(context);
- final sourcedTrack =
- ref.read(trackSourcesProvider(TrackSourceQuery.fromTrack(track)));
+ final sourcedTrack = ref.read(sourcedTrackProvider(track));
final detailsMap = {
context.l10n.title: track.name,
@@ -39,8 +37,7 @@ class TrackDetailsDialog extends HookConsumerWidget {
// style: const TextStyle(color: Colors.blue),
// ),
context.l10n.duration: sourcedTrack.asData != null
- ? Duration(milliseconds: sourcedTrack.asData!.value.info.durationMs)
- .toHumanReadableString()
+ ? sourcedTrack.asData!.value.info.duration.toHumanReadableString()
: Duration(milliseconds: track.durationMs).toHumanReadableString(),
if (track.album.releaseDate != null)
context.l10n.released: track.album.releaseDate,
@@ -57,7 +54,7 @@ class TrackDetailsDialog extends HookConsumerWidget {
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
- context.l10n.channel: Text(sourceInfo.artists),
+ context.l10n.channel: Text(sourceInfo.artists.join(", ")),
if (sourcedTrack.asData?.value.url != null)
context.l10n.streamUrl: Hyperlink(
sourcedTrack.asData!.value.url ?? "",
diff --git a/lib/components/markdown/markdown.dart b/lib/components/markdown/markdown.dart
index 9ea2e77c..1fd4ac5b 100644
--- a/lib/components/markdown/markdown.dart
+++ b/lib/components/markdown/markdown.dart
@@ -1,9 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart';
-import 'package:flutter/services.dart';
import 'package:flutter_markdown_plus/flutter_markdown_plus.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
-import 'package:spotube/collections/spotube_icons.dart';
-import 'package:spotube/extensions/context.dart';
+import 'package:spotube/components/dialogs/link_open_permission_dialog.dart';
import 'package:url_launcher/url_launcher_string.dart';
class AppMarkdown extends StatelessWidget {
@@ -28,61 +26,7 @@ class AppMarkdown extends StatelessWidget {
final allowOpeningLink = await showDialog(
context: context,
builder: (context) {
- return ConstrainedBox(
- constraints: const BoxConstraints(maxWidth: 450),
- child: AlertDialog(
- title: Row(
- spacing: 8,
- children: [
- const Icon(SpotubeIcons.warning),
- Text(context.l10n.open_link_in_browser),
- ],
- ),
- content: Text.rich(
- TextSpan(
- children: [
- TextSpan(
- text:
- "${context.l10n.do_you_want_to_open_the_following_link}:\n",
- ),
- if (href != null)
- TextSpan(
- text: "$href\n\n",
- style: const TextStyle(color: Colors.blue),
- ),
- TextSpan(text: context.l10n.unsafe_url_warning),
- ],
- ),
- ),
- actions: [
- Button.ghost(
- onPressed: () => Navigator.of(context).pop(false),
- child: Text(context.l10n.cancel),
- ),
- Button.ghost(
- onPressed: () {
- if (href != null) {
- Clipboard.setData(ClipboardData(text: href));
- }
- Navigator.of(context).pop(false);
- },
- child: Text(context.l10n.copy_link),
- ),
- Button.destructive(
- onPressed: () {
- if (href != null) {
- launchUrlString(
- href,
- mode: LaunchMode.externalApplication,
- );
- }
- Navigator.of(context).pop(true);
- },
- child: Text(context.l10n.open),
- ),
- ],
- ),
- );
+ return LinkOpenPermissionDialog(href: href);
},
);
diff --git a/lib/components/track_presentation/presentation_actions.dart b/lib/components/track_presentation/presentation_actions.dart
index 735a4514..61202a48 100644
--- a/lib/components/track_presentation/presentation_actions.dart
+++ b/lib/components/track_presentation/presentation_actions.dart
@@ -8,12 +8,10 @@ import 'package:spotube/components/dialogs/playlist_add_track_dialog.dart';
import 'package:spotube/components/track_presentation/presentation_props.dart';
import 'package:spotube/components/track_presentation/presentation_state.dart';
import 'package:spotube/extensions/context.dart';
-import 'package:spotube/models/database/database.dart';
import 'package:spotube/models/metadata/metadata.dart';
import 'package:spotube/provider/download_manager_provider.dart';
import 'package:spotube/provider/history/history.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
-import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
ToastOverlay showToastForAction(
BuildContext context,
@@ -70,8 +68,6 @@ class TrackPresentationActionsSection extends HookConsumerWidget {
final downloader = ref.watch(downloadManagerProvider.notifier);
final playlistNotifier = ref.watch(audioPlayerProvider.notifier);
final historyNotifier = ref.watch(playbackHistoryActionsProvider);
- final audioSource =
- ref.watch(userPreferencesProvider.select((s) => s.audioSource));
final state = ref.watch(presentationStateProvider(options.collection));
final notifier =
@@ -85,16 +81,15 @@ class TrackPresentationActionsSection extends HookConsumerWidget {
}) async {
final fullTrackObjects =
tracks.whereType().toList();
- final confirmed = audioSource == AudioSource.piped ||
- (await showDialog(
- context: context,
- builder: (context) {
- return const ConfirmDownloadDialog();
- },
- ) ??
- false);
+ final confirmed = await showDialog(
+ context: context,
+ builder: (context) {
+ return const ConfirmDownloadDialog();
+ },
+ ) ??
+ false;
if (confirmed != true) return;
- downloader.batchAddToQueue(fullTrackObjects);
+ downloader.addAllToQueue(fullTrackObjects);
notifier.deselectAllTracks();
if (!context.mounted) return;
showToastForAction(context, action, fullTrackObjects.length);
diff --git a/lib/components/track_tile/track_options.dart b/lib/components/track_tile/track_options.dart
index 7943fe3d..7d14493e 100644
--- a/lib/components/track_tile/track_options.dart
+++ b/lib/components/track_tile/track_options.dart
@@ -1,10 +1,8 @@
-import 'package:flutter_hooks/flutter_hooks.dart';
-
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:shadcn_flutter/shadcn_flutter_extension.dart';
-import 'package:spotube/collections/assets.gen.dart';
+import 'package:spotube/collections/routes.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/ui/button_tile.dart';
import 'package:spotube/extensions/constrains.dart';
@@ -35,7 +33,6 @@ class TrackOptions extends HookConsumerWidget {
@override
Widget build(BuildContext context, ref) {
final mediaQuery = MediaQuery.of(context);
- final ThemeData(:colorScheme) = Theme.of(context);
final trackOptionActions = ref.watch(trackOptionActionsProvider(track));
final (
@@ -45,7 +42,7 @@ class TrackOptions extends HookConsumerWidget {
:isActiveTrack,
:isAuthenticated,
:isLiked,
- :progressNotifier
+ :downloadTask
) = ref.watch(trackOptionsStateProvider(track));
final isLocalTrack = track is SpotubeLocalTrackObject;
@@ -59,7 +56,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.delete,
playlistId,
);
@@ -73,7 +70,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.album,
playlistId,
);
@@ -97,7 +94,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.addToQueue,
playlistId,
);
@@ -110,7 +107,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.playNext,
playlistId,
);
@@ -124,7 +121,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.removeFromQueue,
playlistId,
);
@@ -139,7 +136,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.favorite,
playlistId,
);
@@ -162,7 +159,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.startRadio,
playlistId,
);
@@ -175,7 +172,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.addToPlaylist,
playlistId,
);
@@ -190,7 +187,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.removeFromPlaylist,
playlistId,
);
@@ -204,7 +201,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.download,
playlistId,
);
@@ -212,12 +209,19 @@ class TrackOptions extends HookConsumerWidget {
},
enabled: !isInDownloadQueue,
leading: isInDownloadQueue
- ? HookBuilder(builder: (context) {
- final progress = useListenable(progressNotifier);
- return CircularProgressIndicator(
- value: progress?.value,
- );
- })
+ ? StreamBuilder(
+ stream: downloadTask?.downloadedBytesStream,
+ builder: (context, snapshot) {
+ final progress = downloadTask?.totalSizeBytes == null ||
+ downloadTask?.totalSizeBytes == 0
+ ? 0
+ : (snapshot.data ?? 0) /
+ downloadTask!.totalSizeBytes!;
+ return CircularProgressIndicator(
+ value: progress.toDouble(),
+ );
+ },
+ )
: const Icon(SpotubeIcons.download),
title: Text(context.l10n.download_track),
),
@@ -226,7 +230,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.blacklist,
playlistId,
);
@@ -250,7 +254,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.share,
playlistId,
);
@@ -264,25 +268,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
- context,
- TrackOptionValue.songlink,
- playlistId,
- );
- onTapItem?.call();
- },
- leading: Assets.images.logos.songlinkTransparent.image(
- width: 22,
- height: 22,
- color: colorScheme.foreground.withValues(alpha: 0.5),
- ),
- title: Text(context.l10n.song_link),
- ),
- if (!isLocalTrack)
- ButtonTile(
- style: ButtonVariance.menu,
- onPressed: () async {
- await trackOptionActions.action(
- context,
+ rootNavigatorKey.currentContext!,
TrackOptionValue.details,
playlistId,
);
diff --git a/lib/components/track_tile/track_tile.dart b/lib/components/track_tile/track_tile.dart
index 955ac90d..ec3f50f3 100644
--- a/lib/components/track_tile/track_tile.dart
+++ b/lib/components/track_tile/track_tile.dart
@@ -39,6 +39,7 @@ class TrackTile extends HookConsumerWidget {
final int? index;
final SpotubeTrackObject track;
final bool selected;
+ final bool selectionMode;
final ValueChanged? onChanged;
final Future Function()? onTap;
final VoidCallback? onLongPress;
@@ -53,6 +54,7 @@ class TrackTile extends HookConsumerWidget {
this.index,
required this.track,
this.selected = false,
+ this.selectionMode = false,
required this.playlist,
this.onTap,
this.onLongPress,
@@ -81,6 +83,12 @@ class TrackTile extends HookConsumerWidget {
[track.album.images],
);
+ // Treat either explicit selectionMode or presence of onChanged as selection
+ // context. Some lists enable selection by providing `onChanged` without
+ // toggling a dedicated `selectionMode` flag (e.g. playlists), so we must
+ // disable inner navigation in both cases.
+ final effectiveSelection = selectionMode || onChanged != null;
+
return LayoutBuilder(builder: (context, constrains) {
return Listener(
onPointerDown: (event) {
@@ -222,7 +230,9 @@ class TrackTile extends HookConsumerWidget {
children: [
Expanded(
flex: 6,
- child: switch (track) {
+ child: AbsorbPointer(
+ absorbing: selectionMode,
+ child: switch (track) {
SpotubeLocalTrackObject() => Text(
track.name,
maxLines: 1,
@@ -232,15 +242,17 @@ class TrackTile extends HookConsumerWidget {
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
- child: Button(
- style: ButtonVariance.link.copyWith(
- padding: (context, states, value) =>
- EdgeInsets.zero,
- ),
- onPressed: () {
- context
- .navigateTo(TrackRoute(trackId: track.id));
- },
+ child: Button(
+ style: ButtonVariance.link.copyWith(
+ padding: (context, states, value) =>
+ EdgeInsets.zero,
+ ),
+ onPressed: effectiveSelection
+ ? null
+ : () {
+ context
+ .navigateTo(TrackRoute(trackId: track.id));
+ },
child: Text(
track.name,
maxLines: 1,
@@ -251,6 +263,7 @@ class TrackTile extends HookConsumerWidget {
],
),
},
+ ),
),
if (constrains.mdAndUp) ...[
const SizedBox(width: 8),
@@ -281,20 +294,25 @@ class TrackTile extends HookConsumerWidget {
),
subtitle: Align(
alignment: Alignment.centerLeft,
- child: track is SpotubeLocalTrackObject
+ child: track is SpotubeLocalTrackObject
? Text(
track.artists.asString(),
)
: ClipRect(
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 40),
- child: ArtistLink(
- artists: track.artists,
- onOverflowArtistClick: () {
- context.navigateTo(
- TrackRoute(trackId: track.id),
- );
- },
+ child: AbsorbPointer(
+ absorbing: effectiveSelection,
+ child: ArtistLink(
+ artists: track.artists,
+ onOverflowArtistClick: effectiveSelection
+ ? () {}
+ : () {
+ context.navigateTo(
+ TrackRoute(trackId: track.id),
+ );
+ },
+ ),
),
),
),
diff --git a/lib/extensions/dio.dart b/lib/extensions/dio.dart
new file mode 100644
index 00000000..81bb1e70
--- /dev/null
+++ b/lib/extensions/dio.dart
@@ -0,0 +1,168 @@
+import 'dart:io';
+import 'package:dio/dio.dart';
+import 'package:path/path.dart';
+import 'package:path_provider/path_provider.dart';
+
+extension ChunkDownloaderDioExtension on Dio {
+ Future chunkDownload(
+ String urlPath,
+ dynamic savePath, {
+ ProgressCallback? onReceiveProgress,
+ Map? queryParameters,
+ CancelToken? cancelToken,
+ bool deleteOnError = true,
+ FileAccessMode fileAccessMode = FileAccessMode.write,
+ String lengthHeader = Headers.contentLengthHeader,
+ Object? data,
+ Options? options,
+ int connections = 4,
+ }) async {
+ final targetFile = File(savePath.toString());
+ final tempRootDir = await getTemporaryDirectory();
+ final tempSaveDir = Directory(
+ join(
+ tempRootDir.path,
+ 'Spotube',
+ '.chunk_dl_${targetFile.uri.pathSegments.last}',
+ ),
+ );
+ if (await tempSaveDir.exists()) await tempSaveDir.delete(recursive: true);
+ await tempSaveDir.create(recursive: true);
+
+ try {
+ int? totalLength;
+ bool supportsRange = false;
+
+ Response? headResp;
+ try {
+ headResp = await head(
+ urlPath,
+ queryParameters: queryParameters,
+ options: Options(
+ headers: {'Range': 'bytes=0-0'},
+ followRedirects: true,
+ ),
+ );
+ } catch (_) {
+ // Some servers reject HEAD -> ignore
+ }
+
+ final lengthStr = headResp?.headers[lengthHeader]?.first;
+ if (lengthStr != null) {
+ final parsed = int.tryParse(lengthStr);
+ if (parsed != null && parsed > 1) {
+ totalLength = parsed;
+ }
+ }
+
+ supportsRange = headResp?.statusCode == 206 ||
+ headResp?.headers.value(HttpHeaders.acceptRangesHeader) == 'bytes';
+
+ if (totalLength == null || totalLength <= 1) {
+ final resp = await get(
+ urlPath,
+ options: Options(
+ responseType: ResponseType.stream,
+ ),
+ queryParameters: queryParameters,
+ cancelToken: cancelToken,
+ );
+
+ final len = int.tryParse(resp.headers[lengthHeader]?.first ?? '');
+ if (len == null || len <= 1) {
+ // can’t safely chunk — fallback
+ return download(
+ urlPath,
+ savePath,
+ onReceiveProgress: onReceiveProgress,
+ queryParameters: queryParameters,
+ cancelToken: cancelToken,
+ deleteOnError: deleteOnError,
+ options: options,
+ data: data,
+ );
+ }
+
+ totalLength = len;
+ supportsRange =
+ resp.headers.value(HttpHeaders.acceptRangesHeader)?.toLowerCase() ==
+ 'bytes';
+ }
+
+ if (!supportsRange || connections <= 1) {
+ return download(
+ urlPath,
+ savePath,
+ onReceiveProgress: onReceiveProgress,
+ queryParameters: queryParameters,
+ cancelToken: cancelToken,
+ deleteOnError: deleteOnError,
+ options: options,
+ data: data,
+ );
+ }
+
+ final chunkSize = (totalLength / connections).ceil();
+ int downloaded = 0;
+
+ final partFiles = List.generate(
+ connections,
+ (i) => File(join(tempSaveDir.path, 'part_$i')),
+ );
+
+ final futures = List.generate(connections, (i) async {
+ final start = i * chunkSize;
+ final end = (i + 1) * chunkSize - 1;
+ if (start >= totalLength!) return;
+
+ final resp = await get(
+ urlPath,
+ options: Options(
+ responseType: ResponseType.stream,
+ headers: {'Range': 'bytes=$start-$end'},
+ ),
+ queryParameters: queryParameters,
+ cancelToken: cancelToken,
+ );
+
+ final file = partFiles[i];
+ if (await file.exists()) await file.delete();
+ await file.create(recursive: true);
+ final sink = file.openWrite();
+
+ await for (final chunk in resp.data!.stream) {
+ sink.add(chunk);
+ downloaded += chunk.length;
+ onReceiveProgress?.call(downloaded, totalLength);
+ }
+
+ await sink.close();
+ });
+
+ await Future.wait(futures);
+
+ final targetSink = targetFile.openWrite();
+ for (final f in partFiles) {
+ await targetSink.addStream(f.openRead());
+ }
+ await targetSink.close();
+
+ await tempSaveDir.delete(recursive: true);
+
+ return Response(
+ requestOptions: RequestOptions(path: urlPath),
+ data: targetFile,
+ statusCode: 200,
+ statusMessage: 'Chunked download completed ($connections connections)',
+ );
+ } catch (e) {
+ if (deleteOnError) {
+ if (await targetFile.exists()) await targetFile.delete();
+ if (await tempSaveDir.exists()) {
+ await tempSaveDir.delete(recursive: true);
+ }
+ }
+ rethrow;
+ }
+ }
+}
diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb
index 99af2097..f1997517 100644
--- a/lib/l10n/app_ar.arb
+++ b/lib/l10n/app_ar.arb
@@ -477,5 +477,18 @@
"available_plugins": "الإضافات المتوفّرة",
"configure_your_own_metadata_plugin": "تهيئة مزوّد بيانات للقائمة/الألبوم/الفنان/المصدر خاص بك",
"audio_scrobblers": "أجهزة تتبع الصوت",
- "scrobbling": "التتبع"
+ "scrobbling": "التتبع",
+ "download_music_format": "تنسيق تنزيل الموسيقى",
+ "streaming_music_format": "تنسيق بث الموسيقى",
+ "download_music_quality": "جودة تنزيل الموسيقى",
+ "streaming_music_quality": "جودة بث الموسيقى",
+ "default_metadata_source": "مصدر البيانات الوصفية الافتراضي",
+ "set_default_metadata_source": "تعيين مصدر البيانات الوصفية الافتراضي",
+ "default_audio_source": "مصدر الصوت الافتراضي",
+ "set_default_audio_source": "تعيين مصدر الصوت الافتراضي",
+ "plugins": "الإضافات",
+ "configure_plugins": "قم بتكوين مزود البيانات الوصفية ومكونات مصدر الصوت الخاصة بك",
+ "source": "المصدر: ",
+ "uncompressed": "غير مضغوط",
+ "dab_music_source_description": "لمحبي الصوتيات. يوفر تدفقات صوتية عالية الجودة/بدون فقدان. مطابقة دقيقة للمسارات بناءً على ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_bn.arb b/lib/l10n/app_bn.arb
index 222e28b4..4d001da1 100644
--- a/lib/l10n/app_bn.arb
+++ b/lib/l10n/app_bn.arb
@@ -477,5 +477,18 @@
"available_plugins": "উপলব্ধ প্লাগইনগুলো",
"configure_your_own_metadata_plugin": "নিজস্ব প্লেলিস্ট/অ্যালবাম/শিল্পী/ফিড মেটাডেটা প্রদানকারী কনফিগার করুন",
"audio_scrobblers": "অডিও স্ক্রোব্বলার্স",
- "scrobbling": "স্ক্রোব্বলিং"
+ "scrobbling": "স্ক্রোব্বলিং",
+ "download_music_format": "গান ডাউনলোডের বিন্যাস",
+ "streaming_music_format": "গান স্ট্রিমিং এর বিন্যাস",
+ "download_music_quality": "গান ডাউনলোডের মান",
+ "streaming_music_quality": "গান স্ট্রিমিং এর মান",
+ "default_metadata_source": "ডিফল্ট মেটাডেটা উৎস",
+ "set_default_metadata_source": "ডিফল্ট মেটাডেটা উৎস সেট করুন",
+ "default_audio_source": "ডিফল্ট অডিও উৎস",
+ "set_default_audio_source": "ডিফল্ট অডিও উৎস সেট করুন",
+ "plugins": "প্লাগইন",
+ "configure_plugins": "আপনার নিজের মেটাডেটা প্রদানকারী এবং অডিও উৎস প্লাগইন কনফিগার করুন",
+ "source": "উৎস: ",
+ "uncompressed": "অ-সংকুচিত",
+ "dab_music_source_description": "অডিওফাইলদের জন্য। উচ্চ-মানের/লসলেস অডিও স্ট্রিম প্রদান করে। সঠিক ISRC ভিত্তিক ট্র্যাক ম্যাচিং।"
}
\ No newline at end of file
diff --git a/lib/l10n/app_ca.arb b/lib/l10n/app_ca.arb
index 0482468b..06ed7ec6 100644
--- a/lib/l10n/app_ca.arb
+++ b/lib/l10n/app_ca.arb
@@ -477,5 +477,18 @@
"available_plugins": "Complements disponibles",
"configure_your_own_metadata_plugin": "Configura el teu propi proveïdor de metadades per llistes/reproduccions àlbum/artista/flux",
"audio_scrobblers": "Scrobblers d’àudio",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Format de descàrrega de música",
+ "streaming_music_format": "Format de reproducció de música en temps real",
+ "download_music_quality": "Qualitat de descàrrega de música",
+ "streaming_music_quality": "Qualitat de reproducció de música en temps real",
+ "default_metadata_source": "Font de metadades per defecte",
+ "set_default_metadata_source": "Estableix la font de metadades per defecte",
+ "default_audio_source": "Font d'àudio per defecte",
+ "set_default_audio_source": "Estableix la font d'àudio per defecte",
+ "plugins": "Connectors",
+ "configure_plugins": "Configura els teus propis connectors de proveïdor de metadades i de font d'àudio",
+ "source": "Font: ",
+ "uncompressed": "Sense comprimir",
+ "dab_music_source_description": "Per als audiòfils. Ofereix fluxos d'àudio d'alta qualitat/sense pèrdua. Coincidència precisa de pistes basada en ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_cs.arb b/lib/l10n/app_cs.arb
index d5d0f7af..59938004 100644
--- a/lib/l10n/app_cs.arb
+++ b/lib/l10n/app_cs.arb
@@ -477,5 +477,18 @@
"available_plugins": "Dostupné pluginy",
"configure_your_own_metadata_plugin": "Nakonfigurujte si vlastního poskytovatele metadat pro playlist/album/umělec/fid",
"audio_scrobblers": "Audio scrobblers",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Formát stahování hudby",
+ "streaming_music_format": "Formát streamování hudby",
+ "download_music_quality": "Kvalita stahování hudby",
+ "streaming_music_quality": "Kvalita streamování hudby",
+ "default_metadata_source": "Výchozí zdroj metadat",
+ "set_default_metadata_source": "Nastavit výchozí zdroj metadat",
+ "default_audio_source": "Výchozí zdroj zvuku",
+ "set_default_audio_source": "Nastavit výchozí zdroj zvuku",
+ "plugins": "Pluginy",
+ "configure_plugins": "Konfigurujte své vlastní pluginy poskytovatele metadat a zdroje zvuku",
+ "source": "Zdroj: ",
+ "uncompressed": "Nekomprimováno",
+ "dab_music_source_description": "Pro audiofily. Poskytuje vysoce kvalitní/bezztrátové zvukové toky. Přesná shoda skladeb na základě ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb
index 8ef22fac..458e7c07 100644
--- a/lib/l10n/app_de.arb
+++ b/lib/l10n/app_de.arb
@@ -477,5 +477,18 @@
"available_plugins": "Verfügbare Plugins",
"configure_your_own_metadata_plugin": "Eigenen Anbieter für Playlist-/Album-/Künstler-/Feed-Metadaten konfigurieren",
"audio_scrobblers": "Audio-Scrobbler",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Musik-Downloadformat",
+ "streaming_music_format": "Musik-Streamingformat",
+ "download_music_quality": "Musik-Downloadqualität",
+ "streaming_music_quality": "Musik-Streamingqualität",
+ "default_metadata_source": "Standard-Metadatenquelle",
+ "set_default_metadata_source": "Standard-Metadatenquelle festlegen",
+ "default_audio_source": "Standard-Audioquelle",
+ "set_default_audio_source": "Standard-Audioquelle festlegen",
+ "plugins": "Plugins",
+ "configure_plugins": "Richte deine eigenen Metadatenanbieter- und Audioquellen-Plugins ein",
+ "source": "Quelle: ",
+ "uncompressed": "Unkomprimiert",
+ "dab_music_source_description": "Für Audiophile. Bietet hochwertige/verlustfreie Audiostreams. Präzises ISRC-basiertes Track-Matching."
}
\ No newline at end of file
diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb
index 34b56489..111d76a8 100644
--- a/lib/l10n/app_en.arb
+++ b/lib/l10n/app_en.arb
@@ -264,8 +264,10 @@
"change_cover": "Change cover",
"add_cover": "Add cover",
"restore_defaults": "Restore defaults",
- "download_music_codec": "Download music codec",
- "streaming_music_codec": "Streaming music codec",
+ "download_music_format": "Download music format",
+ "streaming_music_format": "Streaming music format",
+ "download_music_quality": "Download music quality",
+ "streaming_music_quality": "Streaming music quality",
"login_with_lastfm": "Login with Last.fm",
"connect": "Connect",
"disconnect_lastfm": "Disconnect Last.fm",
@@ -434,7 +436,10 @@
"update_available": "Update available",
"supports_scrobbling": "Supports scrobbling",
"plugin_scrobbling_info": "This plugin scrobbles your music to generate your listening history.",
- "default_plugin": "Default",
+ "default_metadata_source": "Default metadata source",
+ "set_default_metadata_source": "Set default metadata source",
+ "default_audio_source": "Default audio source",
+ "set_default_audio_source": "Set default audio source",
"set_default": "Set default",
"support": "Support",
"support_plugin_development": "Support plugin development",
@@ -452,14 +457,17 @@
"disclaimer": "Disclaimer",
"third_party_plugin_dmca_notice": "The Spotube team does not hold any responsibility (including legal) for any \"Third-party\" plugins.\nPlease use them at your own risk. For any bugs/issues, please report them to the plugin repository.\n\nIf any \"Third-party\" plugin is breaking ToS/DMCA of any service/legal entity, please ask the \"Third-party\" plugin author or the hosting platform .e.g GitHub/Codeberg to take action. Above listed (\"Third-party\" labelled) are all public/community maintained plugins. We're not curating them, so we cannot take any action on them.\n\n",
"input_does_not_match_format": "Input doesn't match the required format",
- "metadata_provider_plugins": "Metadata Provider Plugins",
+ "plugins": "Plugins",
"paste_plugin_download_url": "Paste download url or GitHub/Codeberg repo url or direct link to .smplug file",
"download_and_install_plugin_from_url": "Download and install plugin from url",
"failed_to_add_plugin_error": "Failed to add plugin: {error}",
"upload_plugin_from_file": "Upload plugin from file",
"installed": "Installed",
"available_plugins": "Available plugins",
- "configure_your_own_metadata_plugin": "Configure your own playlist/album/artist/feed metadata provider",
+ "configure_plugins": "Configure your own metadata provider and audio source plugins",
"audio_scrobblers": "Audio Scrobblers",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "source": "Source: ",
+ "uncompressed": "Uncompressed",
+ "dab_music_source_description": "For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching."
}
diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb
index 8321f2f5..32822763 100644
--- a/lib/l10n/app_es.arb
+++ b/lib/l10n/app_es.arb
@@ -477,5 +477,18 @@
"available_plugins": "Complementos disponibles",
"configure_your_own_metadata_plugin": "Configura tu propio proveedor de metadatos para listas/álbum/artista/feeds",
"audio_scrobblers": "Scrobblers de audio",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Formato de descarga de música",
+ "streaming_music_format": "Formato de transmisión de música",
+ "download_music_quality": "Calidad de descarga de música",
+ "streaming_music_quality": "Calidad de transmisión de música",
+ "default_metadata_source": "Fuente de metadatos predeterminada",
+ "set_default_metadata_source": "Establecer fuente de metadatos predeterminada",
+ "default_audio_source": "Fuente de audio predeterminada",
+ "set_default_audio_source": "Establecer fuente de audio predeterminada",
+ "plugins": "Plugins",
+ "configure_plugins": "Configura tus propios plugins de proveedor de metadatos y fuente de audio",
+ "source": "Fuente: ",
+ "uncompressed": "Sin comprimir",
+ "dab_music_source_description": "Para audiófilos. Proporciona transmisiones de audio de alta calidad/sin pérdida. Coincidencia precisa de pistas basada en ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_eu.arb b/lib/l10n/app_eu.arb
index 0b49bea1..8c87fd2c 100644
--- a/lib/l10n/app_eu.arb
+++ b/lib/l10n/app_eu.arb
@@ -477,5 +477,18 @@
"available_plugins": "Eskaintzen diren pluginak",
"configure_your_own_metadata_plugin": "Konfiguratu zureko playlists-/album-/artista-/feed-metadaten hornitzailea",
"audio_scrobblers": "Audio scrobbler-ak",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Musika deskargatzeko formatua",
+ "streaming_music_format": "Musika streaming bidezko formatua",
+ "download_music_quality": "Musika deskargaren kalitatea",
+ "streaming_music_quality": "Streaming bidezko musika kalitatea",
+ "default_metadata_source": "Metadatu-iturburu lehenetsia",
+ "set_default_metadata_source": "Ezarri metadatu-iturburu lehenetsia",
+ "default_audio_source": "Audio-iturburu lehenetsia",
+ "set_default_audio_source": "Ezarri audio-iturburu lehenetsia",
+ "plugins": "Pluginak",
+ "configure_plugins": "Konfiguratu zure metadatu-hornitzaile eta audio-iturburu pluginak",
+ "source": "Iturburua: ",
+ "uncompressed": "Konprimitu gabea",
+ "dab_music_source_description": "Audiozaleentzat. Kalitate handiko/galerarik gabeko audio-streamak eskaintzen ditu. ISRC oinarritutako pistaren parekatze zehatza."
}
\ No newline at end of file
diff --git a/lib/l10n/app_fa.arb b/lib/l10n/app_fa.arb
index 73bb4d48..72f775fc 100644
--- a/lib/l10n/app_fa.arb
+++ b/lib/l10n/app_fa.arb
@@ -477,5 +477,18 @@
"available_plugins": "افزونههای موجود",
"configure_your_own_metadata_plugin": "پیکربندی ارائهدهندهٔ متادیتا برای پلیلیست/آلبوم/هنرمند/فید بهصورت سفارشی",
"audio_scrobblers": "اسکراببلرهای صوتی",
- "scrobbling": "اسکراببلینگ"
+ "scrobbling": "اسکراببلینگ",
+ "download_music_format": "فرمت دانلود موسیقی",
+ "streaming_music_format": "فرمت پخش آنلاین موسیقی",
+ "download_music_quality": "کیفیت دانلود موسیقی",
+ "streaming_music_quality": "کیفیت پخش آنلاین موسیقی",
+ "default_metadata_source": "منبع پیشفرض فراداده",
+ "set_default_metadata_source": "تنظیم منبع پیشفرض فراداده",
+ "default_audio_source": "منبع پیشفرض صوت",
+ "set_default_audio_source": "تنظیم منبع پیشفرض صوت",
+ "plugins": "افزونهها",
+ "configure_plugins": "افزونههای منبع صوت و ارائهدهنده فراداده خود را پیکربندی کنید",
+ "source": "منبع: ",
+ "uncompressed": "بدون فشردهسازی",
+ "dab_music_source_description": "مخصوص علاقهمندان صدا. ارائهدهنده استریمهای باکیفیت/بدون افت. تطبیق دقیق آهنگ بر اساس ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_fi.arb b/lib/l10n/app_fi.arb
index 93c6c577..d92e5acf 100644
--- a/lib/l10n/app_fi.arb
+++ b/lib/l10n/app_fi.arb
@@ -477,5 +477,18 @@
"available_plugins": "Saatavilla olevat lisäosat",
"configure_your_own_metadata_plugin": "Määritä oma soittolistan/albumin/artistin/syötteen metatietojen tarjoaja",
"audio_scrobblers": "Äänen scrobblerit",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Musiikin latausmuoto",
+ "streaming_music_format": "Musiikin suoratoistomuoto",
+ "download_music_quality": "Musiikin latauslaatu",
+ "streaming_music_quality": "Musiikin suoratoistolaadun",
+ "default_metadata_source": "Oletusarvoinen metatietolähde",
+ "set_default_metadata_source": "Aseta oletusmetatietolähde",
+ "default_audio_source": "Oletusarvoinen äänilähde",
+ "set_default_audio_source": "Aseta oletusäänilähde",
+ "plugins": "Laajennukset",
+ "configure_plugins": "Määritä omat metatietojen tarjoaja- ja äänilähdelaajennukset",
+ "source": "Lähde: ",
+ "uncompressed": "Pakkaamaton",
+ "dab_music_source_description": "Audiofiileille. Tarjoaa korkealaatuisia/häviöttömiä äänivirtoja. Tarkka ISRC-pohjainen kappaleiden tunnistus."
}
\ No newline at end of file
diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb
index 1851dbe1..e73c2eb2 100644
--- a/lib/l10n/app_fr.arb
+++ b/lib/l10n/app_fr.arb
@@ -478,5 +478,18 @@
"available_plugins": "Plugins disponibles",
"configure_your_own_metadata_plugin": "Configurer votre propre fournisseur de métadonnées de playlist/album/artiste/flux",
"audio_scrobblers": "Scrobblers audio",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Format de téléchargement de musique",
+ "streaming_music_format": "Format de streaming de musique",
+ "download_music_quality": "Qualité de téléchargement de musique",
+ "streaming_music_quality": "Qualité de streaming de musique",
+ "default_metadata_source": "Source de métadonnées par défaut",
+ "set_default_metadata_source": "Définir la source de métadonnées par défaut",
+ "default_audio_source": "Source audio par défaut",
+ "set_default_audio_source": "Définir la source audio par défaut",
+ "plugins": "Plugins",
+ "configure_plugins": "Configurez vos propres plugins de fournisseur de métadonnées et de source audio",
+ "source": "Source : ",
+ "uncompressed": "Non compressé",
+ "dab_music_source_description": "Pour les audiophiles. Fournit des flux audio de haute qualité/sans perte. Correspondance précise des pistes basée sur ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_hi.arb b/lib/l10n/app_hi.arb
index d0c6ba36..8e8087bb 100644
--- a/lib/l10n/app_hi.arb
+++ b/lib/l10n/app_hi.arb
@@ -477,5 +477,18 @@
"available_plugins": "उपलब्ध प्लगइन",
"configure_your_own_metadata_plugin": "अपनी खुद की प्लेलिस्ट/एल्बम/कलाकार/फ़ीड मेटाडेटा प्रदाता कॉन्फ़िगर करें",
"audio_scrobblers": "ऑडियो स्क्रॉबलर्स",
- "scrobbling": "स्क्रॉबलिंग"
+ "scrobbling": "स्क्रॉबलिंग",
+ "download_music_format": "संगीत डाउनलोड प्रारूप",
+ "streaming_music_format": "संगीत स्ट्रीमिंग प्रारूप",
+ "download_music_quality": "संगीत डाउनलोड गुणवत्ता",
+ "streaming_music_quality": "संगीत स्ट्रीमिंग गुणवत्ता",
+ "default_metadata_source": "डिफ़ॉल्ट मेटाडेटा स्रोत",
+ "set_default_metadata_source": "डिफ़ॉल्ट मेटाडेटा स्रोत सेट करें",
+ "default_audio_source": "डिफ़ॉल्ट ऑडियो स्रोत",
+ "set_default_audio_source": "डिफ़ॉल्ट ऑडियो स्रोत सेट करें",
+ "plugins": "प्लगइन्स",
+ "configure_plugins": "अपने स्वयं के मेटाडेटा प्रदाता और ऑडियो स्रोत प्लगइन्स कॉन्फ़िगर करें",
+ "source": "स्रोत: ",
+ "uncompressed": "असंपीड़ित",
+ "dab_music_source_description": "ऑडियोफाइलों के लिए। उच्च-गुणवत्ता/बिना हानि वाले ऑडियो स्ट्रीम प्रदान करता है। सटीक ISRC आधारित ट्रैक मिलान।"
}
\ No newline at end of file
diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb
index 8ab234a7..3405fd2f 100644
--- a/lib/l10n/app_id.arb
+++ b/lib/l10n/app_id.arb
@@ -477,5 +477,18 @@
"available_plugins": "Plugin yang tersedia",
"configure_your_own_metadata_plugin": "Konfigurasi penyedia metadata playlist/album/artis/feed Anda sendiri",
"audio_scrobblers": "Scrobblers Audio",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Format unduh musik",
+ "streaming_music_format": "Format streaming musik",
+ "download_music_quality": "Kualitas unduh musik",
+ "streaming_music_quality": "Kualitas streaming musik",
+ "default_metadata_source": "Sumber metadata default",
+ "set_default_metadata_source": "Atur sumber metadata default",
+ "default_audio_source": "Sumber audio default",
+ "set_default_audio_source": "Atur sumber audio default",
+ "plugins": "Plugin",
+ "configure_plugins": "Konfigurasi plugin penyedia metadata dan sumber audio Anda sendiri",
+ "source": "Sumber: ",
+ "uncompressed": "Tidak terkompresi",
+ "dab_music_source_description": "Untuk audiophile. Menyediakan aliran audio berkualitas tinggi/tanpa kehilangan. Pencocokkan trek yang akurat berdasarkan ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb
index f489db5d..c544dbf3 100644
--- a/lib/l10n/app_it.arb
+++ b/lib/l10n/app_it.arb
@@ -478,5 +478,18 @@
"available_plugins": "Plugin disponibili",
"configure_your_own_metadata_plugin": "Configura il tuo provider di metadati per playlist/album/artista/feed",
"audio_scrobblers": "Scrobbler audio",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Formato download musica",
+ "streaming_music_format": "Formato streaming musica",
+ "download_music_quality": "Qualità download musica",
+ "streaming_music_quality": "Qualità streaming musica",
+ "default_metadata_source": "Fonte metadati predefinita",
+ "set_default_metadata_source": "Imposta fonte metadati predefinita",
+ "default_audio_source": "Fonte audio predefinita",
+ "set_default_audio_source": "Imposta fonte audio predefinita",
+ "plugins": "Plugin",
+ "configure_plugins": "Configura i tuoi plugin per fornitore metadati e fonte audio",
+ "source": "Fonte: ",
+ "uncompressed": "Non compresso",
+ "dab_music_source_description": "Per audiophile. Fornisce flussi audio di alta qualità/senza perdita. Abbinamento traccia accurato basato su ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb
index 88fc51c3..991f56be 100644
--- a/lib/l10n/app_ja.arb
+++ b/lib/l10n/app_ja.arb
@@ -476,5 +476,18 @@
"available_plugins": "利用可能なプラグイン",
"configure_your_own_metadata_plugin": "独自のプレイリスト/アルバム/アーティスト/フィードのメタデータプロバイダーを構成",
"audio_scrobblers": "オーディオスクロッブラー",
- "scrobbling": "Scrobbling"
-}
+ "scrobbling": "Scrobbling",
+ "download_music_format": "音楽ダウンロード形式",
+ "streaming_music_format": "音楽ストリーミング形式",
+ "download_music_quality": "音楽ダウンロード品質",
+ "streaming_music_quality": "音楽ストリーミング品質",
+ "default_metadata_source": "デフォルトメタデータソース",
+ "set_default_metadata_source": "デフォルトメタデータソースを設定",
+ "default_audio_source": "デフォルトオーディオソース",
+ "set_default_audio_source": "デフォルトオーディオソースを設定",
+ "plugins": "プラグイン",
+ "configure_plugins": "独自のメタデータプロバイダーとオーディオソースプラグインを設定",
+ "source": "ソース: ",
+ "uncompressed": "非圧縮",
+ "dab_music_source_description": "オーディオファイル向け。高品質/ロスレスオーディオストリームを提供。正確なISRCベースのトラックマッチング。"
+}
\ No newline at end of file
diff --git a/lib/l10n/app_ka.arb b/lib/l10n/app_ka.arb
index 7aaa5cfb..6a0cb06c 100644
--- a/lib/l10n/app_ka.arb
+++ b/lib/l10n/app_ka.arb
@@ -477,5 +477,18 @@
"available_plugins": "ხელმისაწვდომი პლაგინები",
"configure_your_own_metadata_plugin": "დააყენეთ თქვენი საკუთარი პლეილისტის/ალბომის/არტისტის/ფიდის მეტამონაცემების პროვაიდერი",
"audio_scrobblers": "აუდიო სქრობლერები",
- "scrobbling": "სქრობლინგი"
+ "scrobbling": "სქრობლინგი",
+ "download_music_format": "მუსიკის ჩამოტვირთვის ფორმატი",
+ "streaming_music_format": "სტრიმინგის მუსიკის ფორმატი",
+ "download_music_quality": "ჩამოტვირთვის ხარისხი",
+ "streaming_music_quality": "სტრიმინგის ხარისხი",
+ "default_metadata_source": "ნაგულისხმევი მეტამონაცემების წყარო",
+ "set_default_metadata_source": "ნაგულისხმევი მეტამონაცემების წყაროს დაყენება",
+ "default_audio_source": "ნაგულისხმევი აუდიო წყარო",
+ "set_default_audio_source": "ნაგულისხმევი აუდიო წყაროს დაყენება",
+ "plugins": "პლაგინები",
+ "configure_plugins": "თქვენი საკუთარი მეტამონაცემებისა და აუდიო წყაროს პლაგინების კონფიგურაცია",
+ "source": "წყარო: ",
+ "uncompressed": "შეუკუმშავი",
+ "dab_music_source_description": "აუდიოფილებისთვის. უზრუნველყოფს მაღალი ხარისხის/უკომპრესო აუდიო სტრიმებს. ზუსტი შესაბამისობა ISRC-ის მიხედვით."
}
\ No newline at end of file
diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb
index b38e35c5..70a68f8b 100644
--- a/lib/l10n/app_ko.arb
+++ b/lib/l10n/app_ko.arb
@@ -478,5 +478,18 @@
"available_plugins": "사용 가능한 플러그인",
"configure_your_own_metadata_plugin": "자신만의 플레이리스트/앨범/아티스트/피드 메타데이터 제공자 구성",
"audio_scrobblers": "오디오 스크로블러",
- "scrobbling": "스크로블링"
+ "scrobbling": "스크로블링",
+ "download_music_format": "다운로드 음악 포맷",
+ "streaming_music_format": "스트리밍 음악 포맷",
+ "download_music_quality": "다운로드 음질",
+ "streaming_music_quality": "스트리밍 음질",
+ "default_metadata_source": "기본 메타데이터 소스",
+ "set_default_metadata_source": "기본 메타데이터 소스 설정",
+ "default_audio_source": "기본 오디오 소스",
+ "set_default_audio_source": "기본 오디오 소스 설정",
+ "plugins": "플러그인",
+ "configure_plugins": "직접 메타데이터 제공자와 오디오 소스 플러그인을 구성하세요",
+ "source": "출처: ",
+ "uncompressed": "비압축",
+ "dab_music_source_description": "오디오파일을 위한 소스입니다. 고음질/무손실 오디오 스트림을 제공하며 ISRC 기반으로 정확한 트랙 매칭을 지원합니다."
}
\ No newline at end of file
diff --git a/lib/l10n/app_ne.arb b/lib/l10n/app_ne.arb
index 1da053c4..874c28a5 100644
--- a/lib/l10n/app_ne.arb
+++ b/lib/l10n/app_ne.arb
@@ -477,5 +477,18 @@
"available_plugins": "उपलब्ध प्लगइनहरू",
"configure_your_own_metadata_plugin": "तपाईंको आफ्नै प्लेलिस्ट/एल्बम/कलाकार/फिड मेटाडेटा प्रदायक कन्फिगर गर्नुहोस्",
"audio_scrobblers": "अडियो स्क्रब्बलरहरू",
- "scrobbling": "स्क्रब्बलिंग"
+ "scrobbling": "स्क्रब्बलिंग",
+ "download_music_format": "सङ्गीत डाउनलोड ढाँचा",
+ "streaming_music_format": "स्ट्रिमिङ सङ्गीत ढाँचा",
+ "download_music_quality": "डाउनलोड गुणस्तर",
+ "streaming_music_quality": "स्ट्रिमिङ गुणस्तर",
+ "default_metadata_source": "पूर्वनिर्धारित मेटाडाटा स्रोत",
+ "set_default_metadata_source": "पूर्वनिर्धारित मेटाडाटा स्रोत सेट गर्नुहोस्",
+ "default_audio_source": "पूर्वनिर्धारित अडियो स्रोत",
+ "set_default_audio_source": "पूर्वनिर्धारित अडियो स्रोत सेट गर्नुहोस्",
+ "plugins": "प्लगइनहरू",
+ "configure_plugins": "आफ्नै मेटाडाटा प्रदायक र अडियो स्रोत प्लगइनहरू कन्फिगर गर्नुहोस्",
+ "source": "स्रोत: ",
+ "uncompressed": "असंक्षिप्त",
+ "dab_music_source_description": "अडियोप्रेमीहरूका लागि। उच्च गुणस्तर/लसलेस अडियो स्ट्रिमहरू उपलब्ध गराउँछ। ISRC-मा आधारित सटीक ट्र्याक मिलान।"
}
\ No newline at end of file
diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb
index 9395ec35..4d8deac1 100644
--- a/lib/l10n/app_nl.arb
+++ b/lib/l10n/app_nl.arb
@@ -477,5 +477,19 @@
"available_plugins": "Beschikbare plugins",
"configure_your_own_metadata_plugin": "Configureer uw eigen metadata-aanbieder voor afspeellijst/album/artiest/feed",
"audio_scrobblers": "Audioscrobblers",
- "scrobbling": "Scrobbling"
-}
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Download muziekformaat",
+ "streaming_music_format": "Streaming muziekformaat",
+ "download_music_quality": "Downloadkwaliteit",
+ "streaming_music_quality": "Streamingkwaliteit",
+ "default_metadata_source": "Standaard metadata-bron",
+ "set_default_metadata_source": "Standaard metadata-bron instellen",
+ "default_audio_source": "Standaard audiobron",
+ "set_default_audio_source": "Standaard audiobron instellen",
+ "plugins": "Plug-ins",
+ "configure_plugins": "Configureer je eigen metadata- en audiobron-plug-ins",
+ "source": "Bron: ",
+ "uncompressed": "Ongecomprimeerd",
+ "dab_music_source_description": "Voor audiofielen. Biedt hoge kwaliteit/lossless audiostreams. Nauwkeurige trackmatching op basis van ISRC.",
+ "audio_source": "Audiobron"
+}
\ No newline at end of file
diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb
index fac9070a..80da1e89 100644
--- a/lib/l10n/app_pl.arb
+++ b/lib/l10n/app_pl.arb
@@ -477,5 +477,18 @@
"available_plugins": "Dostępne wtyczki",
"configure_your_own_metadata_plugin": "Skonfiguruj własnego dostawcę metadanych dla playlisty/albumu/artysty/kanału",
"audio_scrobblers": "Scrobblery audio",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Format pobierania muzyki",
+ "streaming_music_format": "Format strumieniowania muzyki",
+ "download_music_quality": "Jakość pobierania",
+ "streaming_music_quality": "Jakość strumieniowania",
+ "default_metadata_source": "Domyślne źródło metadanych",
+ "set_default_metadata_source": "Ustaw domyślne źródło metadanych",
+ "default_audio_source": "Domyślne źródło audio",
+ "set_default_audio_source": "Ustaw domyślne źródło audio",
+ "plugins": "Wtyczki",
+ "configure_plugins": "Skonfiguruj własne wtyczki dostawców metadanych i źródeł audio",
+ "source": "Źródło: ",
+ "uncompressed": "Nieskompresowany",
+ "dab_music_source_description": "Dla audiofilów. Oferuje strumienie audio wysokiej jakości/lossless. Precyzyjne dopasowanie utworów na podstawie ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb
index 71e5ab55..fa7845c3 100644
--- a/lib/l10n/app_pt.arb
+++ b/lib/l10n/app_pt.arb
@@ -477,5 +477,18 @@
"available_plugins": "Plugins disponíveis",
"configure_your_own_metadata_plugin": "Configure seu próprio provedor de metadados de playlist/álbum/artista/feed",
"audio_scrobblers": "Scrobblers de áudio",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Formato de download de música",
+ "streaming_music_format": "Formato de streaming de música",
+ "download_music_quality": "Qualidade de download",
+ "streaming_music_quality": "Qualidade de streaming",
+ "default_metadata_source": "Fonte padrão de metadados",
+ "set_default_metadata_source": "Definir fonte padrão de metadados",
+ "default_audio_source": "Fonte de áudio padrão",
+ "set_default_audio_source": "Definir fonte de áudio padrão",
+ "plugins": "Plugins",
+ "configure_plugins": "Configure seus próprios plugins de provedores de metadados e fontes de áudio",
+ "source": "Fonte: ",
+ "uncompressed": "Não comprimido",
+ "dab_music_source_description": "Para audiófilos. Fornece streams de áudio de alta qualidade/sem perdas. Correspondência precisa de faixas baseada em ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb
index bc7586ed..2e864268 100644
--- a/lib/l10n/app_ru.arb
+++ b/lib/l10n/app_ru.arb
@@ -477,5 +477,18 @@
"available_plugins": "Доступные плагины",
"configure_your_own_metadata_plugin": "Настройте свой собственный поставщик метаданных для плейлиста/альбома/артиста/ленты",
"audio_scrobblers": "Аудио скробблеры",
- "scrobbling": "Скробблинг"
+ "scrobbling": "Скробблинг",
+ "download_music_format": "Формат загрузки музыки",
+ "streaming_music_format": "Формат потоковой музыки",
+ "download_music_quality": "Качество загрузки",
+ "streaming_music_quality": "Качество стриминга",
+ "default_metadata_source": "Источник метаданных по умолчанию",
+ "set_default_metadata_source": "Задать источник метаданных по умолчанию",
+ "default_audio_source": "Источник аудио по умолчанию",
+ "set_default_audio_source": "Задать источник аудио по умолчанию",
+ "plugins": "Плагины",
+ "configure_plugins": "Настройте собственные плагины провайдеров метаданных и источников аудио",
+ "source": "Источник: ",
+ "uncompressed": "Несжатый",
+ "dab_music_source_description": "Для аудиофилов. Предоставляет высококачественные/lossless аудиопотоки. Точное совпадение треков по ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_ta.arb b/lib/l10n/app_ta.arb
index 01991a39..6cea7b1a 100644
--- a/lib/l10n/app_ta.arb
+++ b/lib/l10n/app_ta.arb
@@ -475,5 +475,18 @@
"available_plugins": "கிடைக்கக்கூடிய பிளகின்கள்",
"configure_your_own_metadata_plugin": "உங்கள் சொந்த பிளேலிஸ்ட்/ஆல்பம்/கலைஞர்/ஊட்ட மெட்டாடேட்டா வழங்குநரை உள்ளமைக்கவும்",
"audio_scrobblers": "ஆடியோ ஸ்க்ரோப்ளர்கள்",
- "scrobbling": "ஸ்க்ரோப்ளிங்"
+ "scrobbling": "ஸ்க்ரோப்ளிங்",
+ "download_music_format": "இசை பதிவிறக்க வடிவம்",
+ "streaming_music_format": "இசை ஸ்ட்ரீமிங் வடிவம்",
+ "download_music_quality": "பதிவிறக்க தரம்",
+ "streaming_music_quality": "ஸ்ட்ரீமிங் தரம்",
+ "default_metadata_source": "இயல்புநிலை மெட்டாடேட்டா மூலம்",
+ "set_default_metadata_source": "இயல்புநிலை மெட்டாடேட்டா மூலத்தை அமை",
+ "default_audio_source": "இயல்புநிலை ஆடியோ மூலம்",
+ "set_default_audio_source": "இயல்புநிலை ஆடியோ மூலத்தை அமை",
+ "plugins": "செருகுநிரல்கள்",
+ "configure_plugins": "உங்கள் சொந்த மெட்டாடேட்டா வழங்குநர் மற்றும் ஆடியோ மூல செருகுநிரல்களை அமைக்கவும்",
+ "source": "மூலம்: ",
+ "uncompressed": "அழுத்தப்படாத",
+ "dab_music_source_description": "ஆடியோஃபைல்களுக்காக. உயர்தர/லாஸ்லெஸ் ஆடியோ ஸ்ட்ரீம்களை வழங்குகிறது. ISRC அடிப்படையில் துல்லியமான பாடல் பொருத்தம்."
}
\ No newline at end of file
diff --git a/lib/l10n/app_th.arb b/lib/l10n/app_th.arb
index 4b999fe0..4f2efc0e 100644
--- a/lib/l10n/app_th.arb
+++ b/lib/l10n/app_th.arb
@@ -478,5 +478,18 @@
"available_plugins": "ปลั๊กอินที่มีอยู่",
"configure_your_own_metadata_plugin": "กำหนดค่าผู้ให้บริการเมตาดาต้าเพลย์ลิสต์/อัลบั้ม/ศิลปิน/ฟีดของคุณเอง",
"audio_scrobblers": "เครื่อง scrobbler เสียง",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "รูปแบบการดาวน์โหลดเพลง",
+ "streaming_music_format": "รูปแบบการสตรีมเพลง",
+ "download_music_quality": "คุณภาพการดาวน์โหลด",
+ "streaming_music_quality": "คุณภาพการสตรีม",
+ "default_metadata_source": "แหล่งเมตาดาต้าพื้นฐาน",
+ "set_default_metadata_source": "ตั้งค่าแหล่งเมตาดาต้าพื้นฐาน",
+ "default_audio_source": "แหล่งเสียงพื้นฐาน",
+ "set_default_audio_source": "ตั้งค่าแหล่งเสียงพื้นฐาน",
+ "plugins": "ปลั๊กอิน",
+ "configure_plugins": "กำหนดค่าปลั๊กอินผู้ให้บริการเมตาดาต้าและแหล่งเสียงของคุณเอง",
+ "source": "แหล่งที่มา: ",
+ "uncompressed": "ไม่บีบอัด",
+ "dab_music_source_description": "สำหรับคนรักเสียงเพลง ให้สตรีมเสียงคุณภาพสูง/ไร้การสูญเสียการบีบอัด การจับคู่แทร็กแม่นยำตาม ISRC"
}
\ No newline at end of file
diff --git a/lib/l10n/app_tl.arb b/lib/l10n/app_tl.arb
index 45e0b070..bf1f174c 100644
--- a/lib/l10n/app_tl.arb
+++ b/lib/l10n/app_tl.arb
@@ -475,5 +475,18 @@
"available_plugins": "Mga available na plugin",
"configure_your_own_metadata_plugin": "I-configure ang iyong sariling playlist/album/artist/feed metadata provider",
"audio_scrobblers": "Mga Audio Scrobbler",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "I-download na format ng musika",
+ "streaming_music_format": "Format ng streaming ng musika",
+ "download_music_quality": "Kalidad ng i-download na musika",
+ "streaming_music_quality": "Kalidad ng streaming ng musika",
+ "default_metadata_source": "Default na pinagmulan ng metadata",
+ "set_default_metadata_source": "Itakda ang default na pinagmulan ng metadata",
+ "default_audio_source": "Default na pinagmulan ng audio",
+ "set_default_audio_source": "Itakda ang default na pinagmulan ng audio",
+ "plugins": "Mga plugin",
+ "configure_plugins": "I-configure ang sarili mong metadata provider at mga audio source plugin",
+ "source": "Pinagmulan: ",
+ "uncompressed": "Hindi naka-compress",
+ "dab_music_source_description": "Para sa mga audiophile. Nagbibigay ng de-kalidad/walang loss na audio streams. Tumpak na pagtutugma ng track batay sa ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_tr.arb b/lib/l10n/app_tr.arb
index ff5785dd..72734d3b 100644
--- a/lib/l10n/app_tr.arb
+++ b/lib/l10n/app_tr.arb
@@ -477,5 +477,18 @@
"available_plugins": "Mevcut eklentiler",
"configure_your_own_metadata_plugin": "Kendi çalma listenizi/albümünüzü/sanatçınızı/akış meta veri sağlayıcınızı yapılandırın",
"audio_scrobblers": "Ses Scrobbler'lar",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Müzik indirme formatı",
+ "streaming_music_format": "Müzik akış formatı",
+ "download_music_quality": "İndirilen müzik kalitesi",
+ "streaming_music_quality": "Yayınlanan müzik kalitesi",
+ "default_metadata_source": "Varsayılan meta veri kaynağı",
+ "set_default_metadata_source": "Varsayılan meta veri kaynağını ayarla",
+ "default_audio_source": "Varsayılan ses kaynağı",
+ "set_default_audio_source": "Varsayılan ses kaynağını ayarla",
+ "plugins": "Eklentiler",
+ "configure_plugins": "Kendi meta veri sağlayıcı ve ses kaynağı eklentilerinizi yapılandırın",
+ "source": "Kaynak: ",
+ "uncompressed": "Sıkıştırılmamış",
+ "dab_music_source_description": "Audiophile'ler için. Yüksek kaliteli/kayıpsız ses akışları sağlar. Doğru ISRC tabanlı parça eşleştirme."
}
\ No newline at end of file
diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb
index 8eb5a8e9..bdb723ad 100644
--- a/lib/l10n/app_uk.arb
+++ b/lib/l10n/app_uk.arb
@@ -477,5 +477,18 @@
"available_plugins": "Доступні плагіни",
"configure_your_own_metadata_plugin": "Налаштуйте свій власний провайдер метаданих для плейлиста/альбому/виконавця/стрічки",
"audio_scrobblers": "Аудіо скробблери",
- "scrobbling": "Скроблінг"
+ "scrobbling": "Скроблінг",
+ "download_music_format": "Формат завантаження музики",
+ "streaming_music_format": "Формат потокової музики",
+ "download_music_quality": "Якість завантаженої музики",
+ "streaming_music_quality": "Якість потокової музики",
+ "default_metadata_source": "Джерело метаданих за замовчуванням",
+ "set_default_metadata_source": "Встановити джерело метаданих за замовчуванням",
+ "default_audio_source": "Джерело аудіо за замовчуванням",
+ "set_default_audio_source": "Встановити джерело аудіо за замовчуванням",
+ "plugins": "Плагіни",
+ "configure_plugins": "Налаштуйте власні плагіни метаданих і аудіоджерела",
+ "source": "Джерело: ",
+ "uncompressed": "Без стиснення",
+ "dab_music_source_description": "Для аудіофілів. Забезпечує високоякісні/без втрат аудіопотоки. Точна відповідність треків на основі ISRC."
}
\ No newline at end of file
diff --git a/lib/l10n/app_vi.arb b/lib/l10n/app_vi.arb
index 453e12e9..5733963e 100644
--- a/lib/l10n/app_vi.arb
+++ b/lib/l10n/app_vi.arb
@@ -477,5 +477,18 @@
"available_plugins": "Các plugin có sẵn",
"configure_your_own_metadata_plugin": "Cấu hình nhà cung cấp siêu dữ liệu danh sách phát/album/nghệ sĩ/nguồn cấp dữ liệu của riêng bạn",
"audio_scrobblers": "Bộ scrobbler âm thanh",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "Định dạng nhạc tải về",
+ "streaming_music_format": "Định dạng nhạc phát trực tuyến",
+ "download_music_quality": "Chất lượng nhạc tải về",
+ "streaming_music_quality": "Chất lượng nhạc phát trực tuyến",
+ "default_metadata_source": "Nguồn siêu dữ liệu mặc định",
+ "set_default_metadata_source": "Đặt nguồn siêu dữ liệu mặc định",
+ "default_audio_source": "Nguồn âm thanh mặc định",
+ "set_default_audio_source": "Đặt nguồn âm thanh mặc định",
+ "plugins": "Tiện ích bổ sung",
+ "configure_plugins": "Cấu hình nhà cung cấp siêu dữ liệu và tiện ích nguồn âm thanh riêng",
+ "source": "Nguồn: ",
+ "uncompressed": "Không nén",
+ "dab_music_source_description": "Dành cho người yêu âm nhạc chất lượng cao. Cung cấp luồng âm thanh chất lượng cao/không nén. Phù hợp bài hát dựa trên ISRC chính xác."
}
\ No newline at end of file
diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb
index cccb3214..44f7d38c 100644
--- a/lib/l10n/app_zh.arb
+++ b/lib/l10n/app_zh.arb
@@ -477,5 +477,18 @@
"available_plugins": "可用插件",
"configure_your_own_metadata_plugin": "配置您自己的播放列表/专辑/艺人/订阅元数据提供者",
"audio_scrobblers": "音频 Scrobblers",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "下载音乐格式",
+ "streaming_music_format": "流媒体音乐格式",
+ "download_music_quality": "下载音乐质量",
+ "streaming_music_quality": "流媒体音乐质量",
+ "default_metadata_source": "默认元数据源",
+ "set_default_metadata_source": "设置默认元数据源",
+ "default_audio_source": "默认音频源",
+ "set_default_audio_source": "设置默认音频源",
+ "plugins": "插件",
+ "configure_plugins": "配置您自己的元数据提供者和音频源插件",
+ "source": "来源:",
+ "uncompressed": "无损",
+ "dab_music_source_description": "适合发烧友。提供高质量/无损音频流。基于 ISRC 的精确曲目匹配。"
}
\ No newline at end of file
diff --git a/lib/l10n/app_zh_TW.arb b/lib/l10n/app_zh_TW.arb
index fa4c3e67..934006d5 100644
--- a/lib/l10n/app_zh_TW.arb
+++ b/lib/l10n/app_zh_TW.arb
@@ -477,5 +477,18 @@
"available_plugins": "可用的外掛程式",
"configure_your_own_metadata_plugin": "設定您自己的播放清單/專輯/藝人/動態中繼資料供應商",
"audio_scrobblers": "音訊 Scrobblers",
- "scrobbling": "Scrobbling"
+ "scrobbling": "Scrobbling",
+ "download_music_format": "下載音樂格式",
+ "streaming_music_format": "串流音樂格式",
+ "download_music_quality": "下載音樂品質",
+ "streaming_music_quality": "串流音樂品質",
+ "default_metadata_source": "預設中繼資料來源",
+ "set_default_metadata_source": "設定預設中繼資料來源",
+ "default_audio_source": "預設音訊來源",
+ "set_default_audio_source": "設定預設音訊來源",
+ "plugins": "外掛程式",
+ "configure_plugins": "配置您自己的中繼資料提供者和音訊來源外掛程式",
+ "source": "來源:",
+ "uncompressed": "未壓縮",
+ "dab_music_source_description": "適合音響發燒友。提供高品質/無損音訊串流。精確的 ISRC 曲目比對。"
}
\ No newline at end of file
diff --git a/lib/l10n/generated/app_localizations.dart b/lib/l10n/generated/app_localizations.dart
index bf6f5211..e9d7913d 100644
--- a/lib/l10n/generated/app_localizations.dart
+++ b/lib/l10n/generated/app_localizations.dart
@@ -1743,17 +1743,29 @@ abstract class AppLocalizations {
/// **'Restore defaults'**
String get restore_defaults;
- /// No description provided for @download_music_codec.
+ /// No description provided for @download_music_format.
///
/// In en, this message translates to:
- /// **'Download music codec'**
- String get download_music_codec;
+ /// **'Download music format'**
+ String get download_music_format;
- /// No description provided for @streaming_music_codec.
+ /// No description provided for @streaming_music_format.
///
/// In en, this message translates to:
- /// **'Streaming music codec'**
- String get streaming_music_codec;
+ /// **'Streaming music format'**
+ String get streaming_music_format;
+
+ /// No description provided for @download_music_quality.
+ ///
+ /// In en, this message translates to:
+ /// **'Download music quality'**
+ String get download_music_quality;
+
+ /// No description provided for @streaming_music_quality.
+ ///
+ /// In en, this message translates to:
+ /// **'Streaming music quality'**
+ String get streaming_music_quality;
/// No description provided for @login_with_lastfm.
///
@@ -2763,11 +2775,29 @@ abstract class AppLocalizations {
/// **'This plugin scrobbles your music to generate your listening history.'**
String get plugin_scrobbling_info;
- /// No description provided for @default_plugin.
+ /// No description provided for @default_metadata_source.
///
/// In en, this message translates to:
- /// **'Default'**
- String get default_plugin;
+ /// **'Default metadata source'**
+ String get default_metadata_source;
+
+ /// No description provided for @set_default_metadata_source.
+ ///
+ /// In en, this message translates to:
+ /// **'Set default metadata source'**
+ String get set_default_metadata_source;
+
+ /// No description provided for @default_audio_source.
+ ///
+ /// In en, this message translates to:
+ /// **'Default audio source'**
+ String get default_audio_source;
+
+ /// No description provided for @set_default_audio_source.
+ ///
+ /// In en, this message translates to:
+ /// **'Set default audio source'**
+ String get set_default_audio_source;
/// No description provided for @set_default.
///
@@ -2871,11 +2901,11 @@ abstract class AppLocalizations {
/// **'Input doesn\'t match the required format'**
String get input_does_not_match_format;
- /// No description provided for @metadata_provider_plugins.
+ /// No description provided for @plugins.
///
/// In en, this message translates to:
- /// **'Metadata Provider Plugins'**
- String get metadata_provider_plugins;
+ /// **'Plugins'**
+ String get plugins;
/// No description provided for @paste_plugin_download_url.
///
@@ -2913,11 +2943,11 @@ abstract class AppLocalizations {
/// **'Available plugins'**
String get available_plugins;
- /// No description provided for @configure_your_own_metadata_plugin.
+ /// No description provided for @configure_plugins.
///
/// In en, this message translates to:
- /// **'Configure your own playlist/album/artist/feed metadata provider'**
- String get configure_your_own_metadata_plugin;
+ /// **'Configure your own metadata provider and audio source plugins'**
+ String get configure_plugins;
/// No description provided for @audio_scrobblers.
///
@@ -2930,6 +2960,24 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Scrobbling'**
String get scrobbling;
+
+ /// No description provided for @source.
+ ///
+ /// In en, this message translates to:
+ /// **'Source: '**
+ String get source;
+
+ /// No description provided for @uncompressed.
+ ///
+ /// In en, this message translates to:
+ /// **'Uncompressed'**
+ String get uncompressed;
+
+ /// No description provided for @dab_music_source_description.
+ ///
+ /// In en, this message translates to:
+ /// **'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.'**
+ String get dab_music_source_description;
}
class _AppLocalizationsDelegate
diff --git a/lib/l10n/generated/app_localizations_ar.dart b/lib/l10n/generated/app_localizations_ar.dart
index b5734db6..8fd50ffa 100644
--- a/lib/l10n/generated/app_localizations_ar.dart
+++ b/lib/l10n/generated/app_localizations_ar.dart
@@ -874,10 +874,16 @@ class AppLocalizationsAr extends AppLocalizations {
String get restore_defaults => 'استعادة الإعدادات الافتراضية';
@override
- String get download_music_codec => 'تنزيل ترميز الموسيقى';
+ String get download_music_format => 'تنسيق تنزيل الموسيقى';
@override
- String get streaming_music_codec => 'ترميز الموسيقى بالتدفق';
+ String get streaming_music_format => 'تنسيق بث الموسيقى';
+
+ @override
+ String get download_music_quality => 'جودة تنزيل الموسيقى';
+
+ @override
+ String get streaming_music_quality => 'جودة بث الموسيقى';
@override
String get login_with_lastfm => 'تسجيل الدخول باستخدام Last.fm';
@@ -1443,7 +1449,17 @@ class AppLocalizationsAr extends AppLocalizations {
'تقوم هذه الإضافة بتتبع مقاطعك الموسيقية لإنشاء سجل الاستماع الخاص بك.';
@override
- String get default_plugin => 'الافتراضي';
+ String get default_metadata_source => 'مصدر البيانات الوصفية الافتراضي';
+
+ @override
+ String get set_default_metadata_source =>
+ 'تعيين مصدر البيانات الوصفية الافتراضي';
+
+ @override
+ String get default_audio_source => 'مصدر الصوت الافتراضي';
+
+ @override
+ String get set_default_audio_source => 'تعيين مصدر الصوت الافتراضي';
@override
String get set_default => 'تعيين كافتراضي';
@@ -1504,7 +1520,7 @@ class AppLocalizationsAr extends AppLocalizations {
'المدخل لا يتوافق مع التنسيق المطلوب';
@override
- String get metadata_provider_plugins => 'إضافات مزود البيانات';
+ String get plugins => 'الإضافات';
@override
String get paste_plugin_download_url =>
@@ -1529,12 +1545,22 @@ class AppLocalizationsAr extends AppLocalizations {
String get available_plugins => 'الإضافات المتوفّرة';
@override
- String get configure_your_own_metadata_plugin =>
- 'تهيئة مزوّد بيانات للقائمة/الألبوم/الفنان/المصدر خاص بك';
+ String get configure_plugins =>
+ 'قم بتكوين مزود البيانات الوصفية ومكونات مصدر الصوت الخاصة بك';
@override
String get audio_scrobblers => 'أجهزة تتبع الصوت';
@override
String get scrobbling => 'التتبع';
+
+ @override
+ String get source => 'المصدر: ';
+
+ @override
+ String get uncompressed => 'غير مضغوط';
+
+ @override
+ String get dab_music_source_description =>
+ 'لمحبي الصوتيات. يوفر تدفقات صوتية عالية الجودة/بدون فقدان. مطابقة دقيقة للمسارات بناءً على ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_bn.dart b/lib/l10n/generated/app_localizations_bn.dart
index 4503564e..7dc1e07f 100644
--- a/lib/l10n/generated/app_localizations_bn.dart
+++ b/lib/l10n/generated/app_localizations_bn.dart
@@ -873,10 +873,16 @@ class AppLocalizationsBn extends AppLocalizations {
String get restore_defaults => 'ডিফল্ট সেটিংস পুনরুদ্ধার করুন';
@override
- String get download_music_codec => 'সঙ্গীত কোডেক ডাউনলোড করুন';
+ String get download_music_format => 'গান ডাউনলোডের বিন্যাস';
@override
- String get streaming_music_codec => 'স্ট্রিমিং সঙ্গীত কোডেক';
+ String get streaming_music_format => 'গান স্ট্রিমিং এর বিন্যাস';
+
+ @override
+ String get download_music_quality => 'গান ডাউনলোডের মান';
+
+ @override
+ String get streaming_music_quality => 'গান স্ট্রিমিং এর মান';
@override
String get login_with_lastfm => 'Last.fm দিয়ে লগইন করুন';
@@ -1443,7 +1449,16 @@ class AppLocalizationsBn extends AppLocalizations {
'এই প্লাগইনটি আপনার সঙ্গীত স্ক্রোব্বল করে আপনার শোনা ইতিহাস তৈরি করে।';
@override
- String get default_plugin => 'ডিফল্ট';
+ String get default_metadata_source => 'ডিফল্ট মেটাডেটা উৎস';
+
+ @override
+ String get set_default_metadata_source => 'ডিফল্ট মেটাডেটা উৎস সেট করুন';
+
+ @override
+ String get default_audio_source => 'ডিফল্ট অডিও উৎস';
+
+ @override
+ String get set_default_audio_source => 'ডিফল্ট অডিও উৎস সেট করুন';
@override
String get set_default => 'ডিফল্ট হিসাবে নির্ধারণ করুন';
@@ -1505,7 +1520,7 @@ class AppLocalizationsBn extends AppLocalizations {
'ইনপুট প্রয়োজনীয় ফরম্যাটের সাথে মেলে না';
@override
- String get metadata_provider_plugins => 'মেটাডেটা প্রদানকারী প্লাগইনসমূহ';
+ String get plugins => 'প্লাগইন';
@override
String get paste_plugin_download_url =>
@@ -1530,12 +1545,22 @@ class AppLocalizationsBn extends AppLocalizations {
String get available_plugins => 'উপলব্ধ প্লাগইনগুলো';
@override
- String get configure_your_own_metadata_plugin =>
- 'নিজস্ব প্লেলিস্ট/অ্যালবাম/শিল্পী/ফিড মেটাডেটা প্রদানকারী কনফিগার করুন';
+ String get configure_plugins =>
+ 'আপনার নিজের মেটাডেটা প্রদানকারী এবং অডিও উৎস প্লাগইন কনফিগার করুন';
@override
String get audio_scrobblers => 'অডিও স্ক্রোব্বলার্স';
@override
String get scrobbling => 'স্ক্রোব্বলিং';
+
+ @override
+ String get source => 'উৎস: ';
+
+ @override
+ String get uncompressed => 'অ-সংকুচিত';
+
+ @override
+ String get dab_music_source_description =>
+ 'অডিওফাইলদের জন্য। উচ্চ-মানের/লসলেস অডিও স্ট্রিম প্রদান করে। সঠিক ISRC ভিত্তিক ট্র্যাক ম্যাচিং।';
}
diff --git a/lib/l10n/generated/app_localizations_ca.dart b/lib/l10n/generated/app_localizations_ca.dart
index 70899f04..a4f587c9 100644
--- a/lib/l10n/generated/app_localizations_ca.dart
+++ b/lib/l10n/generated/app_localizations_ca.dart
@@ -876,10 +876,18 @@ class AppLocalizationsCa extends AppLocalizations {
String get restore_defaults => 'Restaura els valors per defecte';
@override
- String get download_music_codec => 'Descarrega el codec de música';
+ String get download_music_format => 'Format de descàrrega de música';
@override
- String get streaming_music_codec => 'Codec de música en streaming';
+ String get streaming_music_format =>
+ 'Format de reproducció de música en temps real';
+
+ @override
+ String get download_music_quality => 'Qualitat de descàrrega de música';
+
+ @override
+ String get streaming_music_quality =>
+ 'Qualitat de reproducció de música en temps real';
@override
String get login_with_lastfm => 'Inicia la sessió amb Last.fm';
@@ -1450,7 +1458,18 @@ class AppLocalizationsCa extends AppLocalizations {
'Aquest complement fa scrobbling de la teva música per generar l’historial d’escoltes.';
@override
- String get default_plugin => 'Predeterminat';
+ String get default_metadata_source => 'Font de metadades per defecte';
+
+ @override
+ String get set_default_metadata_source =>
+ 'Estableix la font de metadades per defecte';
+
+ @override
+ String get default_audio_source => 'Font d\'àudio per defecte';
+
+ @override
+ String get set_default_audio_source =>
+ 'Estableix la font d\'àudio per defecte';
@override
String get set_default => 'Establir com a predeterminat';
@@ -1514,8 +1533,7 @@ class AppLocalizationsCa extends AppLocalizations {
'L’entrada no coincideix amb el format requerit';
@override
- String get metadata_provider_plugins =>
- 'Complements de proveïdor de metadades';
+ String get plugins => 'Connectors';
@override
String get paste_plugin_download_url =>
@@ -1540,12 +1558,22 @@ class AppLocalizationsCa extends AppLocalizations {
String get available_plugins => 'Complements disponibles';
@override
- String get configure_your_own_metadata_plugin =>
- 'Configura el teu propi proveïdor de metadades per llistes/reproduccions àlbum/artista/flux';
+ String get configure_plugins =>
+ 'Configura els teus propis connectors de proveïdor de metadades i de font d\'àudio';
@override
String get audio_scrobblers => 'Scrobblers d’àudio';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Font: ';
+
+ @override
+ String get uncompressed => 'Sense comprimir';
+
+ @override
+ String get dab_music_source_description =>
+ 'Per als audiòfils. Ofereix fluxos d\'àudio d\'alta qualitat/sense pèrdua. Coincidència precisa de pistes basada en ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_cs.dart b/lib/l10n/generated/app_localizations_cs.dart
index 3cb620e0..24d5b34b 100644
--- a/lib/l10n/generated/app_localizations_cs.dart
+++ b/lib/l10n/generated/app_localizations_cs.dart
@@ -869,10 +869,16 @@ class AppLocalizationsCs extends AppLocalizations {
String get restore_defaults => 'Obnovit výchozí';
@override
- String get download_music_codec => 'Kodek pro stahování';
+ String get download_music_format => 'Formát stahování hudby';
@override
- String get streaming_music_codec => 'Kodek pro streamování';
+ String get streaming_music_format => 'Formát streamování hudby';
+
+ @override
+ String get download_music_quality => 'Kvalita stahování hudby';
+
+ @override
+ String get streaming_music_quality => 'Kvalita streamování hudby';
@override
String get login_with_lastfm => 'Přihlásit se pomocí Last.fm';
@@ -1442,7 +1448,16 @@ class AppLocalizationsCs extends AppLocalizations {
'Tento plugin scrobbles vaši hudbu pro vytvoření historie poslechů.';
@override
- String get default_plugin => 'Výchozí';
+ String get default_metadata_source => 'Výchozí zdroj metadat';
+
+ @override
+ String get set_default_metadata_source => 'Nastavit výchozí zdroj metadat';
+
+ @override
+ String get default_audio_source => 'Výchozí zdroj zvuku';
+
+ @override
+ String get set_default_audio_source => 'Nastavit výchozí zdroj zvuku';
@override
String get set_default => 'Nastavit jako výchozí';
@@ -1505,7 +1520,7 @@ class AppLocalizationsCs extends AppLocalizations {
'Vstup neodpovídá požadovanému formátu';
@override
- String get metadata_provider_plugins => 'Pluginy poskytovatelů metadat';
+ String get plugins => 'Pluginy';
@override
String get paste_plugin_download_url =>
@@ -1530,12 +1545,22 @@ class AppLocalizationsCs extends AppLocalizations {
String get available_plugins => 'Dostupné pluginy';
@override
- String get configure_your_own_metadata_plugin =>
- 'Nakonfigurujte si vlastního poskytovatele metadat pro playlist/album/umělec/fid';
+ String get configure_plugins =>
+ 'Konfigurujte své vlastní pluginy poskytovatele metadat a zdroje zvuku';
@override
String get audio_scrobblers => 'Audio scrobblers';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Zdroj: ';
+
+ @override
+ String get uncompressed => 'Nekomprimováno';
+
+ @override
+ String get dab_music_source_description =>
+ 'Pro audiofily. Poskytuje vysoce kvalitní/bezztrátové zvukové toky. Přesná shoda skladeb na základě ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_de.dart b/lib/l10n/generated/app_localizations_de.dart
index 75c858f5..4ab10266 100644
--- a/lib/l10n/generated/app_localizations_de.dart
+++ b/lib/l10n/generated/app_localizations_de.dart
@@ -879,10 +879,16 @@ class AppLocalizationsDe extends AppLocalizations {
String get restore_defaults => 'Standardeinstellungen wiederherstellen';
@override
- String get download_music_codec => 'Musik-Codec herunterladen';
+ String get download_music_format => 'Musik-Downloadformat';
@override
- String get streaming_music_codec => 'Streaming-Musik-Codec';
+ String get streaming_music_format => 'Musik-Streamingformat';
+
+ @override
+ String get download_music_quality => 'Musik-Downloadqualität';
+
+ @override
+ String get streaming_music_quality => 'Musik-Streamingqualität';
@override
String get login_with_lastfm => 'Mit Last.fm anmelden';
@@ -1455,7 +1461,17 @@ class AppLocalizationsDe extends AppLocalizations {
'Dieses Plugin scrobbelt Ihre Musik, um Ihre Hörhistorie zu erstellen.';
@override
- String get default_plugin => 'Standard';
+ String get default_metadata_source => 'Standard-Metadatenquelle';
+
+ @override
+ String get set_default_metadata_source =>
+ 'Standard-Metadatenquelle festlegen';
+
+ @override
+ String get default_audio_source => 'Standard-Audioquelle';
+
+ @override
+ String get set_default_audio_source => 'Standard-Audioquelle festlegen';
@override
String get set_default => 'Als Standard festlegen';
@@ -1517,7 +1533,7 @@ class AppLocalizationsDe extends AppLocalizations {
'Eingabe entspricht nicht dem geforderten Format';
@override
- String get metadata_provider_plugins => 'Plugins für Metadatenanbieter';
+ String get plugins => 'Plugins';
@override
String get paste_plugin_download_url =>
@@ -1542,12 +1558,22 @@ class AppLocalizationsDe extends AppLocalizations {
String get available_plugins => 'Verfügbare Plugins';
@override
- String get configure_your_own_metadata_plugin =>
- 'Eigenen Anbieter für Playlist-/Album-/Künstler-/Feed-Metadaten konfigurieren';
+ String get configure_plugins =>
+ 'Richte deine eigenen Metadatenanbieter- und Audioquellen-Plugins ein';
@override
String get audio_scrobblers => 'Audio-Scrobbler';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Quelle: ';
+
+ @override
+ String get uncompressed => 'Unkomprimiert';
+
+ @override
+ String get dab_music_source_description =>
+ 'Für Audiophile. Bietet hochwertige/verlustfreie Audiostreams. Präzises ISRC-basiertes Track-Matching.';
}
diff --git a/lib/l10n/generated/app_localizations_en.dart b/lib/l10n/generated/app_localizations_en.dart
index e6d4db1e..83a2c24c 100644
--- a/lib/l10n/generated/app_localizations_en.dart
+++ b/lib/l10n/generated/app_localizations_en.dart
@@ -871,10 +871,16 @@ class AppLocalizationsEn extends AppLocalizations {
String get restore_defaults => 'Restore defaults';
@override
- String get download_music_codec => 'Download music codec';
+ String get download_music_format => 'Download music format';
@override
- String get streaming_music_codec => 'Streaming music codec';
+ String get streaming_music_format => 'Streaming music format';
+
+ @override
+ String get download_music_quality => 'Download music quality';
+
+ @override
+ String get streaming_music_quality => 'Streaming music quality';
@override
String get login_with_lastfm => 'Login with Last.fm';
@@ -1442,7 +1448,16 @@ class AppLocalizationsEn extends AppLocalizations {
'This plugin scrobbles your music to generate your listening history.';
@override
- String get default_plugin => 'Default';
+ String get default_metadata_source => 'Default metadata source';
+
+ @override
+ String get set_default_metadata_source => 'Set default metadata source';
+
+ @override
+ String get default_audio_source => 'Default audio source';
+
+ @override
+ String get set_default_audio_source => 'Set default audio source';
@override
String get set_default => 'Set default';
@@ -1503,7 +1518,7 @@ class AppLocalizationsEn extends AppLocalizations {
'Input doesn\'t match the required format';
@override
- String get metadata_provider_plugins => 'Metadata Provider Plugins';
+ String get plugins => 'Plugins';
@override
String get paste_plugin_download_url =>
@@ -1528,12 +1543,22 @@ class AppLocalizationsEn extends AppLocalizations {
String get available_plugins => 'Available plugins';
@override
- String get configure_your_own_metadata_plugin =>
- 'Configure your own playlist/album/artist/feed metadata provider';
+ String get configure_plugins =>
+ 'Configure your own metadata provider and audio source plugins';
@override
String get audio_scrobblers => 'Audio Scrobblers';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Source: ';
+
+ @override
+ String get uncompressed => 'Uncompressed';
+
+ @override
+ String get dab_music_source_description =>
+ 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
}
diff --git a/lib/l10n/generated/app_localizations_es.dart b/lib/l10n/generated/app_localizations_es.dart
index f51f829c..0fcd6739 100644
--- a/lib/l10n/generated/app_localizations_es.dart
+++ b/lib/l10n/generated/app_localizations_es.dart
@@ -876,10 +876,16 @@ class AppLocalizationsEs extends AppLocalizations {
String get restore_defaults => 'Restaurar valores predeterminados';
@override
- String get download_music_codec => 'Descargar códec de música';
+ String get download_music_format => 'Formato de descarga de música';
@override
- String get streaming_music_codec => 'Códec de música en streaming';
+ String get streaming_music_format => 'Formato de transmisión de música';
+
+ @override
+ String get download_music_quality => 'Calidad de descarga de música';
+
+ @override
+ String get streaming_music_quality => 'Calidad de transmisión de música';
@override
String get login_with_lastfm => 'Iniciar sesión con Last.fm';
@@ -1452,7 +1458,18 @@ class AppLocalizationsEs extends AppLocalizations {
'Este complemento scrobblea tu música para generar tu historial de reproducción.';
@override
- String get default_plugin => 'Predeterminado';
+ String get default_metadata_source => 'Fuente de metadatos predeterminada';
+
+ @override
+ String get set_default_metadata_source =>
+ 'Establecer fuente de metadatos predeterminada';
+
+ @override
+ String get default_audio_source => 'Fuente de audio predeterminada';
+
+ @override
+ String get set_default_audio_source =>
+ 'Establecer fuente de audio predeterminada';
@override
String get set_default => 'Establecer como predeterminado';
@@ -1517,8 +1534,7 @@ class AppLocalizationsEs extends AppLocalizations {
'La entrada no coincide con el formato requerido';
@override
- String get metadata_provider_plugins =>
- 'Complementos de proveedor de metadatos';
+ String get plugins => 'Plugins';
@override
String get paste_plugin_download_url =>
@@ -1543,12 +1559,22 @@ class AppLocalizationsEs extends AppLocalizations {
String get available_plugins => 'Complementos disponibles';
@override
- String get configure_your_own_metadata_plugin =>
- 'Configura tu propio proveedor de metadatos para listas/álbum/artista/feeds';
+ String get configure_plugins =>
+ 'Configura tus propios plugins de proveedor de metadatos y fuente de audio';
@override
String get audio_scrobblers => 'Scrobblers de audio';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Fuente: ';
+
+ @override
+ String get uncompressed => 'Sin comprimir';
+
+ @override
+ String get dab_music_source_description =>
+ 'Para audiófilos. Proporciona transmisiones de audio de alta calidad/sin pérdida. Coincidencia precisa de pistas basada en ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_eu.dart b/lib/l10n/generated/app_localizations_eu.dart
index 523f110f..5f80397e 100644
--- a/lib/l10n/generated/app_localizations_eu.dart
+++ b/lib/l10n/generated/app_localizations_eu.dart
@@ -876,10 +876,16 @@ class AppLocalizationsEu extends AppLocalizations {
String get restore_defaults => 'Berrezarri berezko balioak';
@override
- String get download_music_codec => 'Deskargatutako musikaren codec-a';
+ String get download_music_format => 'Musika deskargatzeko formatua';
@override
- String get streaming_music_codec => 'Streaming musikaren codec-a';
+ String get streaming_music_format => 'Musika streaming bidezko formatua';
+
+ @override
+ String get download_music_quality => 'Musika deskargaren kalitatea';
+
+ @override
+ String get streaming_music_quality => 'Streaming bidezko musika kalitatea';
@override
String get login_with_lastfm => 'Hasi saioa Last.fm-n';
@@ -1451,7 +1457,17 @@ class AppLocalizationsEu extends AppLocalizations {
'Plugin honek zure musika scrobbled egiten du zure entzuteen historia sortzeko.';
@override
- String get default_plugin => 'Lehenetsia';
+ String get default_metadata_source => 'Metadatu-iturburu lehenetsia';
+
+ @override
+ String get set_default_metadata_source =>
+ 'Ezarri metadatu-iturburu lehenetsia';
+
+ @override
+ String get default_audio_source => 'Audio-iturburu lehenetsia';
+
+ @override
+ String get set_default_audio_source => 'Ezarri audio-iturburu lehenetsia';
@override
String get set_default => 'Lehenetsi gisa ezarri';
@@ -1515,7 +1531,7 @@ class AppLocalizationsEu extends AppLocalizations {
'Sarrera ezin da beharrezko formatutik desberdina izan';
@override
- String get metadata_provider_plugins => 'Metadaten hornitzailearen pluginak';
+ String get plugins => 'Pluginak';
@override
String get paste_plugin_download_url =>
@@ -1540,12 +1556,22 @@ class AppLocalizationsEu extends AppLocalizations {
String get available_plugins => 'Eskaintzen diren pluginak';
@override
- String get configure_your_own_metadata_plugin =>
- 'Konfiguratu zureko playlists-/album-/artista-/feed-metadaten hornitzailea';
+ String get configure_plugins =>
+ 'Konfiguratu zure metadatu-hornitzaile eta audio-iturburu pluginak';
@override
String get audio_scrobblers => 'Audio scrobbler-ak';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Iturburua: ';
+
+ @override
+ String get uncompressed => 'Konprimitu gabea';
+
+ @override
+ String get dab_music_source_description =>
+ 'Audiozaleentzat. Kalitate handiko/galerarik gabeko audio-streamak eskaintzen ditu. ISRC oinarritutako pistaren parekatze zehatza.';
}
diff --git a/lib/l10n/generated/app_localizations_fa.dart b/lib/l10n/generated/app_localizations_fa.dart
index c63e723a..5c0b7c2b 100644
--- a/lib/l10n/generated/app_localizations_fa.dart
+++ b/lib/l10n/generated/app_localizations_fa.dart
@@ -870,10 +870,16 @@ class AppLocalizationsFa extends AppLocalizations {
String get restore_defaults => 'بازیابی پیش فرض ها';
@override
- String get download_music_codec => 'دانلود کدک موسیقی';
+ String get download_music_format => 'فرمت دانلود موسیقی';
@override
- String get streaming_music_codec => 'کدک موسیقی استریمینگ';
+ String get streaming_music_format => 'فرمت پخش آنلاین موسیقی';
+
+ @override
+ String get download_music_quality => 'کیفیت دانلود موسیقی';
+
+ @override
+ String get streaming_music_quality => 'کیفیت پخش آنلاین موسیقی';
@override
String get login_with_lastfm => 'ورود با Last.fm';
@@ -1441,7 +1447,16 @@ class AppLocalizationsFa extends AppLocalizations {
'این افزونه موسیقی شما را اسکراب میکند تا تاریخچهٔ شنیداریتان را تولید کند.';
@override
- String get default_plugin => 'پیشفرض';
+ String get default_metadata_source => 'منبع پیشفرض فراداده';
+
+ @override
+ String get set_default_metadata_source => 'تنظیم منبع پیشفرض فراداده';
+
+ @override
+ String get default_audio_source => 'منبع پیشفرض صوت';
+
+ @override
+ String get set_default_audio_source => 'تنظیم منبع پیشفرض صوت';
@override
String get set_default => 'تنظیم به عنوان پیشفرض';
@@ -1503,7 +1518,7 @@ class AppLocalizationsFa extends AppLocalizations {
'ورودی با قالب مورد نیاز تطابق ندارد';
@override
- String get metadata_provider_plugins => 'افزونههای ارائهدهندهٔ متادیتا';
+ String get plugins => 'افزونهها';
@override
String get paste_plugin_download_url =>
@@ -1528,12 +1543,22 @@ class AppLocalizationsFa extends AppLocalizations {
String get available_plugins => 'افزونههای موجود';
@override
- String get configure_your_own_metadata_plugin =>
- 'پیکربندی ارائهدهندهٔ متادیتا برای پلیلیست/آلبوم/هنرمند/فید بهصورت سفارشی';
+ String get configure_plugins =>
+ 'افزونههای منبع صوت و ارائهدهنده فراداده خود را پیکربندی کنید';
@override
String get audio_scrobblers => 'اسکراببلرهای صوتی';
@override
String get scrobbling => 'اسکراببلینگ';
+
+ @override
+ String get source => 'منبع: ';
+
+ @override
+ String get uncompressed => 'بدون فشردهسازی';
+
+ @override
+ String get dab_music_source_description =>
+ 'مخصوص علاقهمندان صدا. ارائهدهنده استریمهای باکیفیت/بدون افت. تطبیق دقیق آهنگ بر اساس ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_fi.dart b/lib/l10n/generated/app_localizations_fi.dart
index e1ba7f5a..3f616849 100644
--- a/lib/l10n/generated/app_localizations_fi.dart
+++ b/lib/l10n/generated/app_localizations_fi.dart
@@ -872,10 +872,16 @@ class AppLocalizationsFi extends AppLocalizations {
String get restore_defaults => 'Palauta oletukset';
@override
- String get download_music_codec => 'Ladatun musiikin codefc';
+ String get download_music_format => 'Musiikin latausmuoto';
@override
- String get streaming_music_codec => 'Suoratoistetun musiikin codec';
+ String get streaming_music_format => 'Musiikin suoratoistomuoto';
+
+ @override
+ String get download_music_quality => 'Musiikin latauslaatu';
+
+ @override
+ String get streaming_music_quality => 'Musiikin suoratoistolaadun';
@override
String get login_with_lastfm => 'Kirjaudu sisään Last.fm:llä';
@@ -1443,7 +1449,16 @@ class AppLocalizationsFi extends AppLocalizations {
'Tämä lisäosa scrobblaa musiikkisi luodakseen kuunteluhistoriasi.';
@override
- String get default_plugin => 'Oletus';
+ String get default_metadata_source => 'Oletusarvoinen metatietolähde';
+
+ @override
+ String get set_default_metadata_source => 'Aseta oletusmetatietolähde';
+
+ @override
+ String get default_audio_source => 'Oletusarvoinen äänilähde';
+
+ @override
+ String get set_default_audio_source => 'Aseta oletusäänilähde';
@override
String get set_default => 'Aseta oletukseksi';
@@ -1503,7 +1518,7 @@ class AppLocalizationsFi extends AppLocalizations {
String get input_does_not_match_format => 'Syöte ei vastaa vaadittua muotoa';
@override
- String get metadata_provider_plugins => 'Metatietojen tarjoajan lisäosat';
+ String get plugins => 'Laajennukset';
@override
String get paste_plugin_download_url =>
@@ -1528,12 +1543,22 @@ class AppLocalizationsFi extends AppLocalizations {
String get available_plugins => 'Saatavilla olevat lisäosat';
@override
- String get configure_your_own_metadata_plugin =>
- 'Määritä oma soittolistan/albumin/artistin/syötteen metatietojen tarjoaja';
+ String get configure_plugins =>
+ 'Määritä omat metatietojen tarjoaja- ja äänilähdelaajennukset';
@override
String get audio_scrobblers => 'Äänen scrobblerit';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Lähde: ';
+
+ @override
+ String get uncompressed => 'Pakkaamaton';
+
+ @override
+ String get dab_music_source_description =>
+ 'Audiofiileille. Tarjoaa korkealaatuisia/häviöttömiä äänivirtoja. Tarkka ISRC-pohjainen kappaleiden tunnistus.';
}
diff --git a/lib/l10n/generated/app_localizations_fr.dart b/lib/l10n/generated/app_localizations_fr.dart
index 88350997..3637391b 100644
--- a/lib/l10n/generated/app_localizations_fr.dart
+++ b/lib/l10n/generated/app_localizations_fr.dart
@@ -880,10 +880,16 @@ class AppLocalizationsFr extends AppLocalizations {
String get restore_defaults => 'Restaurer les valeurs par défaut';
@override
- String get download_music_codec => 'Télécharger le codec musical';
+ String get download_music_format => 'Format de téléchargement de musique';
@override
- String get streaming_music_codec => 'Codec de musique en streaming';
+ String get streaming_music_format => 'Format de streaming de musique';
+
+ @override
+ String get download_music_quality => 'Qualité de téléchargement de musique';
+
+ @override
+ String get streaming_music_quality => 'Qualité de streaming de musique';
@override
String get login_with_lastfm => 'Se connecter avec Last.fm';
@@ -1457,7 +1463,17 @@ class AppLocalizationsFr extends AppLocalizations {
'Ce plugin scrobble votre musique pour générer votre historique d\'écoute.';
@override
- String get default_plugin => 'Par défaut';
+ String get default_metadata_source => 'Source de métadonnées par défaut';
+
+ @override
+ String get set_default_metadata_source =>
+ 'Définir la source de métadonnées par défaut';
+
+ @override
+ String get default_audio_source => 'Source audio par défaut';
+
+ @override
+ String get set_default_audio_source => 'Définir la source audio par défaut';
@override
String get set_default => 'Définir par défaut';
@@ -1521,8 +1537,7 @@ class AppLocalizationsFr extends AppLocalizations {
'L\'entrée ne correspond pas au format requis';
@override
- String get metadata_provider_plugins =>
- 'Plugins de fournisseur de métadonnées';
+ String get plugins => 'Plugins';
@override
String get paste_plugin_download_url =>
@@ -1548,12 +1563,22 @@ class AppLocalizationsFr extends AppLocalizations {
String get available_plugins => 'Plugins disponibles';
@override
- String get configure_your_own_metadata_plugin =>
- 'Configurer votre propre fournisseur de métadonnées de playlist/album/artiste/flux';
+ String get configure_plugins =>
+ 'Configurez vos propres plugins de fournisseur de métadonnées et de source audio';
@override
String get audio_scrobblers => 'Scrobblers audio';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Source : ';
+
+ @override
+ String get uncompressed => 'Non compressé';
+
+ @override
+ String get dab_music_source_description =>
+ 'Pour les audiophiles. Fournit des flux audio de haute qualité/sans perte. Correspondance précise des pistes basée sur ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_hi.dart b/lib/l10n/generated/app_localizations_hi.dart
index f3ba4802..0434e8db 100644
--- a/lib/l10n/generated/app_localizations_hi.dart
+++ b/lib/l10n/generated/app_localizations_hi.dart
@@ -872,10 +872,16 @@ class AppLocalizationsHi extends AppLocalizations {
String get restore_defaults => 'डिफ़ॉल्ट सेटिंग्स को बहाल करें';
@override
- String get download_music_codec => 'संगीत कोडेक डाउनलोड करें';
+ String get download_music_format => 'संगीत डाउनलोड प्रारूप';
@override
- String get streaming_music_codec => 'स्ट्रीमिंग संगीत कोडेक';
+ String get streaming_music_format => 'संगीत स्ट्रीमिंग प्रारूप';
+
+ @override
+ String get download_music_quality => 'संगीत डाउनलोड गुणवत्ता';
+
+ @override
+ String get streaming_music_quality => 'संगीत स्ट्रीमिंग गुणवत्ता';
@override
String get login_with_lastfm => 'Last.fm से लॉगिन करें';
@@ -1448,7 +1454,16 @@ class AppLocalizationsHi extends AppLocalizations {
'यह प्लगइन आपके सुनने के इतिहास को उत्पन्न करने के लिए आपके संगीत को स्क्रॉबल करता है।';
@override
- String get default_plugin => 'डिफ़ॉल्ट';
+ String get default_metadata_source => 'डिफ़ॉल्ट मेटाडेटा स्रोत';
+
+ @override
+ String get set_default_metadata_source => 'डिफ़ॉल्ट मेटाडेटा स्रोत सेट करें';
+
+ @override
+ String get default_audio_source => 'डिफ़ॉल्ट ऑडियो स्रोत';
+
+ @override
+ String get set_default_audio_source => 'डिफ़ॉल्ट ऑडियो स्रोत सेट करें';
@override
String get set_default => 'डिफ़ॉल्ट सेट करें';
@@ -1509,7 +1524,7 @@ class AppLocalizationsHi extends AppLocalizations {
'इनपुट आवश्यक प्रारूप से मेल नहीं खाता है';
@override
- String get metadata_provider_plugins => 'मेटाडेटा प्रदाता प्लगइन';
+ String get plugins => 'प्लगइन्स';
@override
String get paste_plugin_download_url =>
@@ -1534,12 +1549,22 @@ class AppLocalizationsHi extends AppLocalizations {
String get available_plugins => 'उपलब्ध प्लगइन';
@override
- String get configure_your_own_metadata_plugin =>
- 'अपनी खुद की प्लेलिस्ट/एल्बम/कलाकार/फ़ीड मेटाडेटा प्रदाता कॉन्फ़िगर करें';
+ String get configure_plugins =>
+ 'अपने स्वयं के मेटाडेटा प्रदाता और ऑडियो स्रोत प्लगइन्स कॉन्फ़िगर करें';
@override
String get audio_scrobblers => 'ऑडियो स्क्रॉबलर्स';
@override
String get scrobbling => 'स्क्रॉबलिंग';
+
+ @override
+ String get source => 'स्रोत: ';
+
+ @override
+ String get uncompressed => 'असंपीड़ित';
+
+ @override
+ String get dab_music_source_description =>
+ 'ऑडियोफाइलों के लिए। उच्च-गुणवत्ता/बिना हानि वाले ऑडियो स्ट्रीम प्रदान करता है। सटीक ISRC आधारित ट्रैक मिलान।';
}
diff --git a/lib/l10n/generated/app_localizations_id.dart b/lib/l10n/generated/app_localizations_id.dart
index c56f1ece..ce250425 100644
--- a/lib/l10n/generated/app_localizations_id.dart
+++ b/lib/l10n/generated/app_localizations_id.dart
@@ -874,10 +874,16 @@ class AppLocalizationsId extends AppLocalizations {
String get restore_defaults => 'Kembalikan semula';
@override
- String get download_music_codec => 'Unduh codec musik';
+ String get download_music_format => 'Format unduh musik';
@override
- String get streaming_music_codec => 'Streaming codec musik';
+ String get streaming_music_format => 'Format streaming musik';
+
+ @override
+ String get download_music_quality => 'Kualitas unduh musik';
+
+ @override
+ String get streaming_music_quality => 'Kualitas streaming musik';
@override
String get login_with_lastfm => 'Masuk dengan Last.fm';
@@ -1449,7 +1455,16 @@ class AppLocalizationsId extends AppLocalizations {
'Plugin ini scrobble musik Anda untuk menghasilkan riwayat mendengarkan Anda.';
@override
- String get default_plugin => 'Bawaan';
+ String get default_metadata_source => 'Sumber metadata default';
+
+ @override
+ String get set_default_metadata_source => 'Atur sumber metadata default';
+
+ @override
+ String get default_audio_source => 'Sumber audio default';
+
+ @override
+ String get set_default_audio_source => 'Atur sumber audio default';
@override
String get set_default => 'Atur sebagai bawaan';
@@ -1511,7 +1526,7 @@ class AppLocalizationsId extends AppLocalizations {
'Masukan tidak cocok dengan format yang diperlukan';
@override
- String get metadata_provider_plugins => 'Plugin Penyedia Metadata';
+ String get plugins => 'Plugin';
@override
String get paste_plugin_download_url =>
@@ -1536,12 +1551,22 @@ class AppLocalizationsId extends AppLocalizations {
String get available_plugins => 'Plugin yang tersedia';
@override
- String get configure_your_own_metadata_plugin =>
- 'Konfigurasi penyedia metadata playlist/album/artis/feed Anda sendiri';
+ String get configure_plugins =>
+ 'Konfigurasi plugin penyedia metadata dan sumber audio Anda sendiri';
@override
String get audio_scrobblers => 'Scrobblers Audio';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Sumber: ';
+
+ @override
+ String get uncompressed => 'Tidak terkompresi';
+
+ @override
+ String get dab_music_source_description =>
+ 'Untuk audiophile. Menyediakan aliran audio berkualitas tinggi/tanpa kehilangan. Pencocokkan trek yang akurat berdasarkan ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_it.dart b/lib/l10n/generated/app_localizations_it.dart
index dc8ed9cd..f2dfa5ed 100644
--- a/lib/l10n/generated/app_localizations_it.dart
+++ b/lib/l10n/generated/app_localizations_it.dart
@@ -874,10 +874,16 @@ class AppLocalizationsIt extends AppLocalizations {
String get restore_defaults => 'Ripristina default';
@override
- String get download_music_codec => 'Codec musicale scaricamento';
+ String get download_music_format => 'Formato download musica';
@override
- String get streaming_music_codec => 'Codec musicale streaming';
+ String get streaming_music_format => 'Formato streaming musica';
+
+ @override
+ String get download_music_quality => 'Qualità download musica';
+
+ @override
+ String get streaming_music_quality => 'Qualità streaming musica';
@override
String get login_with_lastfm => 'Accesso a Last.fm';
@@ -1448,7 +1454,17 @@ class AppLocalizationsIt extends AppLocalizations {
'Questo plugin scrobbla la tua musica per generare la tua cronologia di ascolti.';
@override
- String get default_plugin => 'Predefinito';
+ String get default_metadata_source => 'Fonte metadati predefinita';
+
+ @override
+ String get set_default_metadata_source =>
+ 'Imposta fonte metadati predefinita';
+
+ @override
+ String get default_audio_source => 'Fonte audio predefinita';
+
+ @override
+ String get set_default_audio_source => 'Imposta fonte audio predefinita';
@override
String get set_default => 'Imposta come predefinito';
@@ -1510,7 +1526,7 @@ class AppLocalizationsIt extends AppLocalizations {
'L\'input non corrisponde al formato richiesto';
@override
- String get metadata_provider_plugins => 'Plugin del provider di metadati';
+ String get plugins => 'Plugin';
@override
String get paste_plugin_download_url =>
@@ -1535,12 +1551,22 @@ class AppLocalizationsIt extends AppLocalizations {
String get available_plugins => 'Plugin disponibili';
@override
- String get configure_your_own_metadata_plugin =>
- 'Configura il tuo provider di metadati per playlist/album/artista/feed';
+ String get configure_plugins =>
+ 'Configura i tuoi plugin per fornitore metadati e fonte audio';
@override
String get audio_scrobblers => 'Scrobbler audio';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Fonte: ';
+
+ @override
+ String get uncompressed => 'Non compresso';
+
+ @override
+ String get dab_music_source_description =>
+ 'Per audiophile. Fornisce flussi audio di alta qualità/senza perdita. Abbinamento traccia accurato basato su ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_ja.dart b/lib/l10n/generated/app_localizations_ja.dart
index 7ce62161..2505f68a 100644
--- a/lib/l10n/generated/app_localizations_ja.dart
+++ b/lib/l10n/generated/app_localizations_ja.dart
@@ -861,10 +861,16 @@ class AppLocalizationsJa extends AppLocalizations {
String get restore_defaults => '設定を初期化';
@override
- String get download_music_codec => 'ダウンロード用の音声コーデック';
+ String get download_music_format => '音楽ダウンロード形式';
@override
- String get streaming_music_codec => 'ストリーミング用の音声コーデック';
+ String get streaming_music_format => '音楽ストリーミング形式';
+
+ @override
+ String get download_music_quality => '音楽ダウンロード品質';
+
+ @override
+ String get streaming_music_quality => '音楽ストリーミング品質';
@override
String get login_with_lastfm => 'Last.fmでログイン';
@@ -1416,7 +1422,16 @@ class AppLocalizationsJa extends AppLocalizations {
String get plugin_scrobbling_info => 'このプラグインは、あなたの音楽をscrobbleして視聴履歴を生成します。';
@override
- String get default_plugin => 'デフォルト';
+ String get default_metadata_source => 'デフォルトメタデータソース';
+
+ @override
+ String get set_default_metadata_source => 'デフォルトメタデータソースを設定';
+
+ @override
+ String get default_audio_source => 'デフォルトオーディオソース';
+
+ @override
+ String get set_default_audio_source => 'デフォルトオーディオソースを設定';
@override
String get set_default => 'デフォルトに設定';
@@ -1474,7 +1489,7 @@ class AppLocalizationsJa extends AppLocalizations {
String get input_does_not_match_format => '入力が必須フォーマットと一致しません';
@override
- String get metadata_provider_plugins => 'メタデータプロバイダープラグイン';
+ String get plugins => 'プラグイン';
@override
String get paste_plugin_download_url =>
@@ -1499,12 +1514,21 @@ class AppLocalizationsJa extends AppLocalizations {
String get available_plugins => '利用可能なプラグイン';
@override
- String get configure_your_own_metadata_plugin =>
- '独自のプレイリスト/アルバム/アーティスト/フィードのメタデータプロバイダーを構成';
+ String get configure_plugins => '独自のメタデータプロバイダーとオーディオソースプラグインを設定';
@override
String get audio_scrobblers => 'オーディオスクロッブラー';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'ソース: ';
+
+ @override
+ String get uncompressed => '非圧縮';
+
+ @override
+ String get dab_music_source_description =>
+ 'オーディオファイル向け。高品質/ロスレスオーディオストリームを提供。正確なISRCベースのトラックマッチング。';
}
diff --git a/lib/l10n/generated/app_localizations_ka.dart b/lib/l10n/generated/app_localizations_ka.dart
index a28bd02d..c8557037 100644
--- a/lib/l10n/generated/app_localizations_ka.dart
+++ b/lib/l10n/generated/app_localizations_ka.dart
@@ -872,10 +872,16 @@ class AppLocalizationsKa extends AppLocalizations {
String get restore_defaults => 'ნაგულისხმევი პარამეტრების აღდგენა';
@override
- String get download_music_codec => 'მუსიკის კოდეკის გადმოწერა';
+ String get download_music_format => 'მუსიკის ჩამოტვირთვის ფორმატი';
@override
- String get streaming_music_codec => 'სტრიმინგ მუსიკის კოდეკი';
+ String get streaming_music_format => 'სტრიმინგის მუსიკის ფორმატი';
+
+ @override
+ String get download_music_quality => 'ჩამოტვირთვის ხარისხი';
+
+ @override
+ String get streaming_music_quality => 'სტრიმინგის ხარისხი';
@override
String get login_with_lastfm => 'Last.fm-ით შესვლა';
@@ -1448,7 +1454,17 @@ class AppLocalizationsKa extends AppLocalizations {
'ეს პლაგინი აწარმოებს თქვენი მუსიკის სქრობლინგს, რათა შექმნას თქვენი მოსმენის ისტორია.';
@override
- String get default_plugin => 'ნაგულისხმევი';
+ String get default_metadata_source => 'ნაგულისხმევი მეტამონაცემების წყარო';
+
+ @override
+ String get set_default_metadata_source =>
+ 'ნაგულისხმევი მეტამონაცემების წყაროს დაყენება';
+
+ @override
+ String get default_audio_source => 'ნაგულისხმევი აუდიო წყარო';
+
+ @override
+ String get set_default_audio_source => 'ნაგულისხმევი აუდიო წყაროს დაყენება';
@override
String get set_default => 'ნაგულისხმევად დაყენება';
@@ -1511,8 +1527,7 @@ class AppLocalizationsKa extends AppLocalizations {
'შეყვანა არ ემთხვევა საჭირო ფორმატს';
@override
- String get metadata_provider_plugins =>
- 'მეტამონაცემების პროვაიდერების პლაგინები';
+ String get plugins => 'პლაგინები';
@override
String get paste_plugin_download_url =>
@@ -1537,12 +1552,22 @@ class AppLocalizationsKa extends AppLocalizations {
String get available_plugins => 'ხელმისაწვდომი პლაგინები';
@override
- String get configure_your_own_metadata_plugin =>
- 'დააყენეთ თქვენი საკუთარი პლეილისტის/ალბომის/არტისტის/ფიდის მეტამონაცემების პროვაიდერი';
+ String get configure_plugins =>
+ 'თქვენი საკუთარი მეტამონაცემებისა და აუდიო წყაროს პლაგინების კონფიგურაცია';
@override
String get audio_scrobblers => 'აუდიო სქრობლერები';
@override
String get scrobbling => 'სქრობლინგი';
+
+ @override
+ String get source => 'წყარო: ';
+
+ @override
+ String get uncompressed => 'შეუკუმშავი';
+
+ @override
+ String get dab_music_source_description =>
+ 'აუდიოფილებისთვის. უზრუნველყოფს მაღალი ხარისხის/უკომპრესო აუდიო სტრიმებს. ზუსტი შესაბამისობა ISRC-ის მიხედვით.';
}
diff --git a/lib/l10n/generated/app_localizations_ko.dart b/lib/l10n/generated/app_localizations_ko.dart
index 40104b52..42ea337a 100644
--- a/lib/l10n/generated/app_localizations_ko.dart
+++ b/lib/l10n/generated/app_localizations_ko.dart
@@ -862,10 +862,16 @@ class AppLocalizationsKo extends AppLocalizations {
String get restore_defaults => '기본값으로 복원';
@override
- String get download_music_codec => '다운로드 음악 코덱';
+ String get download_music_format => '다운로드 음악 포맷';
@override
- String get streaming_music_codec => '스트리밍 음악 코덱';
+ String get streaming_music_format => '스트리밍 음악 포맷';
+
+ @override
+ String get download_music_quality => '다운로드 음질';
+
+ @override
+ String get streaming_music_quality => '스트리밍 음질';
@override
String get login_with_lastfm => 'Last.fm에 로그인';
@@ -1421,7 +1427,16 @@ class AppLocalizationsKo extends AppLocalizations {
String get plugin_scrobbling_info => '이 플러그인은 음악을 스크로블하여 청취 기록을 생성합니다.';
@override
- String get default_plugin => '기본';
+ String get default_metadata_source => '기본 메타데이터 소스';
+
+ @override
+ String get set_default_metadata_source => '기본 메타데이터 소스 설정';
+
+ @override
+ String get default_audio_source => '기본 오디오 소스';
+
+ @override
+ String get set_default_audio_source => '기본 오디오 소스 설정';
@override
String get set_default => '기본값으로 설정';
@@ -1479,7 +1494,7 @@ class AppLocalizationsKo extends AppLocalizations {
String get input_does_not_match_format => '입력이 필요한 형식과 일치하지 않습니다';
@override
- String get metadata_provider_plugins => '메타데이터 제공자 플러그인';
+ String get plugins => '플러그인';
@override
String get paste_plugin_download_url =>
@@ -1503,12 +1518,21 @@ class AppLocalizationsKo extends AppLocalizations {
String get available_plugins => '사용 가능한 플러그인';
@override
- String get configure_your_own_metadata_plugin =>
- '자신만의 플레이리스트/앨범/아티스트/피드 메타데이터 제공자 구성';
+ String get configure_plugins => '직접 메타데이터 제공자와 오디오 소스 플러그인을 구성하세요';
@override
String get audio_scrobblers => '오디오 스크로블러';
@override
String get scrobbling => '스크로블링';
+
+ @override
+ String get source => '출처: ';
+
+ @override
+ String get uncompressed => '비압축';
+
+ @override
+ String get dab_music_source_description =>
+ '오디오파일을 위한 소스입니다. 고음질/무손실 오디오 스트림을 제공하며 ISRC 기반으로 정확한 트랙 매칭을 지원합니다.';
}
diff --git a/lib/l10n/generated/app_localizations_ne.dart b/lib/l10n/generated/app_localizations_ne.dart
index 18d155fe..8f881b51 100644
--- a/lib/l10n/generated/app_localizations_ne.dart
+++ b/lib/l10n/generated/app_localizations_ne.dart
@@ -880,10 +880,16 @@ class AppLocalizationsNe extends AppLocalizations {
String get restore_defaults => 'पूर्वनिर्धारितहरू पुनः स्थापित गर्नुहोस्';
@override
- String get download_music_codec => 'साङ्गीत कोडेक डाउनलोड गर्नुहोस्';
+ String get download_music_format => 'सङ्गीत डाउनलोड ढाँचा';
@override
- String get streaming_music_codec => 'स्ट्रिमिङ साङ्गीत कोडेक';
+ String get streaming_music_format => 'स्ट्रिमिङ सङ्गीत ढाँचा';
+
+ @override
+ String get download_music_quality => 'डाउनलोड गुणस्तर';
+
+ @override
+ String get streaming_music_quality => 'स्ट्रिमिङ गुणस्तर';
@override
String get login_with_lastfm => 'लास्ट.एफ.एम सँग लगइन गर्नुहोस्';
@@ -1454,7 +1460,18 @@ class AppLocalizationsNe extends AppLocalizations {
'यो प्लगइनले तपाईंको सुन्ने इतिहास उत्पन्न गर्न तपाईंको संगीतलाई स्क्रब्बल गर्दछ।';
@override
- String get default_plugin => 'पूर्वनिर्धारित';
+ String get default_metadata_source => 'पूर्वनिर्धारित मेटाडाटा स्रोत';
+
+ @override
+ String get set_default_metadata_source =>
+ 'पूर्वनिर्धारित मेटाडाटा स्रोत सेट गर्नुहोस्';
+
+ @override
+ String get default_audio_source => 'पूर्वनिर्धारित अडियो स्रोत';
+
+ @override
+ String get set_default_audio_source =>
+ 'पूर्वनिर्धारित अडियो स्रोत सेट गर्नुहोस्';
@override
String get set_default => 'पूर्वनिर्धारित सेट गर्नुहोस्';
@@ -1515,7 +1532,7 @@ class AppLocalizationsNe extends AppLocalizations {
String get input_does_not_match_format => 'इनपुट आवश्यक ढाँचासँग मेल खाँदैन';
@override
- String get metadata_provider_plugins => 'मेटाडेटा प्रदायक प्लगइनहरू';
+ String get plugins => 'प्लगइनहरू';
@override
String get paste_plugin_download_url =>
@@ -1540,12 +1557,22 @@ class AppLocalizationsNe extends AppLocalizations {
String get available_plugins => 'उपलब्ध प्लगइनहरू';
@override
- String get configure_your_own_metadata_plugin =>
- 'तपाईंको आफ्नै प्लेलिस्ट/एल्बम/कलाकार/फिड मेटाडेटा प्रदायक कन्फिगर गर्नुहोस्';
+ String get configure_plugins =>
+ 'आफ्नै मेटाडाटा प्रदायक र अडियो स्रोत प्लगइनहरू कन्फिगर गर्नुहोस्';
@override
String get audio_scrobblers => 'अडियो स्क्रब्बलरहरू';
@override
String get scrobbling => 'स्क्रब्बलिंग';
+
+ @override
+ String get source => 'स्रोत: ';
+
+ @override
+ String get uncompressed => 'असंक्षिप्त';
+
+ @override
+ String get dab_music_source_description =>
+ 'अडियोप्रेमीहरूका लागि। उच्च गुणस्तर/लसलेस अडियो स्ट्रिमहरू उपलब्ध गराउँछ। ISRC-मा आधारित सटीक ट्र्याक मिलान।';
}
diff --git a/lib/l10n/generated/app_localizations_nl.dart b/lib/l10n/generated/app_localizations_nl.dart
index 3074e958..0a73c640 100644
--- a/lib/l10n/generated/app_localizations_nl.dart
+++ b/lib/l10n/generated/app_localizations_nl.dart
@@ -815,7 +815,7 @@ class AppLocalizationsNl extends AppLocalizations {
String get search_mode => 'Zoekmodus';
@override
- String get audio_source => 'Audio Source';
+ String get audio_source => 'Audiobron';
@override
String get ok => 'Oké';
@@ -872,10 +872,16 @@ class AppLocalizationsNl extends AppLocalizations {
String get restore_defaults => 'Standaardwaarden herstellen';
@override
- String get download_music_codec => 'Download-codec';
+ String get download_music_format => 'Download muziekformaat';
@override
- String get streaming_music_codec => 'Streaming-codec';
+ String get streaming_music_format => 'Streaming muziekformaat';
+
+ @override
+ String get download_music_quality => 'Downloadkwaliteit';
+
+ @override
+ String get streaming_music_quality => 'Streamingkwaliteit';
@override
String get login_with_lastfm => 'Inloggen met Last.fm';
@@ -1446,7 +1452,16 @@ class AppLocalizationsNl extends AppLocalizations {
'Deze plugin scrobblet uw muziek om uw luistergeschiedenis te genereren.';
@override
- String get default_plugin => 'Standaard';
+ String get default_metadata_source => 'Standaard metadata-bron';
+
+ @override
+ String get set_default_metadata_source => 'Standaard metadata-bron instellen';
+
+ @override
+ String get default_audio_source => 'Standaard audiobron';
+
+ @override
+ String get set_default_audio_source => 'Standaard audiobron instellen';
@override
String get set_default => 'Instellen als standaard';
@@ -1509,7 +1524,7 @@ class AppLocalizationsNl extends AppLocalizations {
'Invoer komt niet overeen met het vereiste formaat';
@override
- String get metadata_provider_plugins => 'Metadata-aanbieder Plugins';
+ String get plugins => 'Plug-ins';
@override
String get paste_plugin_download_url =>
@@ -1534,12 +1549,22 @@ class AppLocalizationsNl extends AppLocalizations {
String get available_plugins => 'Beschikbare plugins';
@override
- String get configure_your_own_metadata_plugin =>
- 'Configureer uw eigen metadata-aanbieder voor afspeellijst/album/artiest/feed';
+ String get configure_plugins =>
+ 'Configureer je eigen metadata- en audiobron-plug-ins';
@override
String get audio_scrobblers => 'Audioscrobblers';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Bron: ';
+
+ @override
+ String get uncompressed => 'Ongecomprimeerd';
+
+ @override
+ String get dab_music_source_description =>
+ 'Voor audiofielen. Biedt hoge kwaliteit/lossless audiostreams. Nauwkeurige trackmatching op basis van ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_pl.dart b/lib/l10n/generated/app_localizations_pl.dart
index 969204da..5e185035 100644
--- a/lib/l10n/generated/app_localizations_pl.dart
+++ b/lib/l10n/generated/app_localizations_pl.dart
@@ -873,10 +873,16 @@ class AppLocalizationsPl extends AppLocalizations {
String get restore_defaults => 'Przywróć domyślne';
@override
- String get download_music_codec => 'Pobierz kodek muzyczny';
+ String get download_music_format => 'Format pobierania muzyki';
@override
- String get streaming_music_codec => 'Kodek strumieniowy muzyki';
+ String get streaming_music_format => 'Format strumieniowania muzyki';
+
+ @override
+ String get download_music_quality => 'Jakość pobierania';
+
+ @override
+ String get streaming_music_quality => 'Jakość strumieniowania';
@override
String get login_with_lastfm => 'Zaloguj się z Last.fm';
@@ -1449,7 +1455,16 @@ class AppLocalizationsPl extends AppLocalizations {
'Ta wtyczka scrobbluje Twoją muzykę, aby wygenerować historię odsłuchań.';
@override
- String get default_plugin => 'Domyślna';
+ String get default_metadata_source => 'Domyślne źródło metadanych';
+
+ @override
+ String get set_default_metadata_source => 'Ustaw domyślne źródło metadanych';
+
+ @override
+ String get default_audio_source => 'Domyślne źródło audio';
+
+ @override
+ String get set_default_audio_source => 'Ustaw domyślne źródło audio';
@override
String get set_default => 'Ustaw jako domyślną';
@@ -1511,7 +1526,7 @@ class AppLocalizationsPl extends AppLocalizations {
'Wprowadzony tekst nie pasuje do wymaganego formatu';
@override
- String get metadata_provider_plugins => 'Wtyczki dostawców metadanych';
+ String get plugins => 'Wtyczki';
@override
String get paste_plugin_download_url =>
@@ -1536,12 +1551,22 @@ class AppLocalizationsPl extends AppLocalizations {
String get available_plugins => 'Dostępne wtyczki';
@override
- String get configure_your_own_metadata_plugin =>
- 'Skonfiguruj własnego dostawcę metadanych dla playlisty/albumu/artysty/kanału';
+ String get configure_plugins =>
+ 'Skonfiguruj własne wtyczki dostawców metadanych i źródeł audio';
@override
String get audio_scrobblers => 'Scrobblery audio';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Źródło: ';
+
+ @override
+ String get uncompressed => 'Nieskompresowany';
+
+ @override
+ String get dab_music_source_description =>
+ 'Dla audiofilów. Oferuje strumienie audio wysokiej jakości/lossless. Precyzyjne dopasowanie utworów na podstawie ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_pt.dart b/lib/l10n/generated/app_localizations_pt.dart
index 35d9881d..8d2eabe7 100644
--- a/lib/l10n/generated/app_localizations_pt.dart
+++ b/lib/l10n/generated/app_localizations_pt.dart
@@ -873,10 +873,16 @@ class AppLocalizationsPt extends AppLocalizations {
String get restore_defaults => 'Restaurar padrões';
@override
- String get download_music_codec => 'Descarregar codec de música';
+ String get download_music_format => 'Formato de download de música';
@override
- String get streaming_music_codec => 'Codec de streaming de música';
+ String get streaming_music_format => 'Formato de streaming de música';
+
+ @override
+ String get download_music_quality => 'Qualidade de download';
+
+ @override
+ String get streaming_music_quality => 'Qualidade de streaming';
@override
String get login_with_lastfm => 'Iniciar sessão com o Last.fm';
@@ -1446,7 +1452,16 @@ class AppLocalizationsPt extends AppLocalizations {
'Este plugin faz o scrobbling de sua música para gerar seu histórico de audição.';
@override
- String get default_plugin => 'Padrão';
+ String get default_metadata_source => 'Fonte padrão de metadados';
+
+ @override
+ String get set_default_metadata_source => 'Definir fonte padrão de metadados';
+
+ @override
+ String get default_audio_source => 'Fonte de áudio padrão';
+
+ @override
+ String get set_default_audio_source => 'Definir fonte de áudio padrão';
@override
String get set_default => 'Definir como padrão';
@@ -1508,7 +1523,7 @@ class AppLocalizationsPt extends AppLocalizations {
'A entrada não corresponde ao formato exigido';
@override
- String get metadata_provider_plugins => 'Plugins do provedor de metadados';
+ String get plugins => 'Plugins';
@override
String get paste_plugin_download_url =>
@@ -1533,12 +1548,22 @@ class AppLocalizationsPt extends AppLocalizations {
String get available_plugins => 'Plugins disponíveis';
@override
- String get configure_your_own_metadata_plugin =>
- 'Configure seu próprio provedor de metadados de playlist/álbum/artista/feed';
+ String get configure_plugins =>
+ 'Configure seus próprios plugins de provedores de metadados e fontes de áudio';
@override
String get audio_scrobblers => 'Scrobblers de áudio';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Fonte: ';
+
+ @override
+ String get uncompressed => 'Não comprimido';
+
+ @override
+ String get dab_music_source_description =>
+ 'Para audiófilos. Fornece streams de áudio de alta qualidade/sem perdas. Correspondência precisa de faixas baseada em ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_ru.dart b/lib/l10n/generated/app_localizations_ru.dart
index e4cd090b..31be6a7b 100644
--- a/lib/l10n/generated/app_localizations_ru.dart
+++ b/lib/l10n/generated/app_localizations_ru.dart
@@ -874,10 +874,16 @@ class AppLocalizationsRu extends AppLocalizations {
String get restore_defaults => 'Восстановить настройки по умолчанию';
@override
- String get download_music_codec => 'Загрузить кодек для музыки';
+ String get download_music_format => 'Формат загрузки музыки';
@override
- String get streaming_music_codec => 'Кодек потоковой передачи музыки';
+ String get streaming_music_format => 'Формат потоковой музыки';
+
+ @override
+ String get download_music_quality => 'Качество загрузки';
+
+ @override
+ String get streaming_music_quality => 'Качество стриминга';
@override
String get login_with_lastfm => 'Войти с помощью Last.fm';
@@ -1448,7 +1454,17 @@ class AppLocalizationsRu extends AppLocalizations {
'Этот плагин скробблит вашу музыку для создания вашей истории прослушиваний.';
@override
- String get default_plugin => 'По умолчанию';
+ String get default_metadata_source => 'Источник метаданных по умолчанию';
+
+ @override
+ String get set_default_metadata_source =>
+ 'Задать источник метаданных по умолчанию';
+
+ @override
+ String get default_audio_source => 'Источник аудио по умолчанию';
+
+ @override
+ String get set_default_audio_source => 'Задать источник аудио по умолчанию';
@override
String get set_default => 'Установить по умолчанию';
@@ -1511,7 +1527,7 @@ class AppLocalizationsRu extends AppLocalizations {
'Введенные данные не соответствуют требуемому формату';
@override
- String get metadata_provider_plugins => 'Плагины поставщика метаданных';
+ String get plugins => 'Плагины';
@override
String get paste_plugin_download_url =>
@@ -1536,12 +1552,22 @@ class AppLocalizationsRu extends AppLocalizations {
String get available_plugins => 'Доступные плагины';
@override
- String get configure_your_own_metadata_plugin =>
- 'Настройте свой собственный поставщик метаданных для плейлиста/альбома/артиста/ленты';
+ String get configure_plugins =>
+ 'Настройте собственные плагины провайдеров метаданных и источников аудио';
@override
String get audio_scrobblers => 'Аудио скробблеры';
@override
String get scrobbling => 'Скробблинг';
+
+ @override
+ String get source => 'Источник: ';
+
+ @override
+ String get uncompressed => 'Несжатый';
+
+ @override
+ String get dab_music_source_description =>
+ 'Для аудиофилов. Предоставляет высококачественные/lossless аудиопотоки. Точное совпадение треков по ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_ta.dart b/lib/l10n/generated/app_localizations_ta.dart
index 0a131edd..062a99dc 100644
--- a/lib/l10n/generated/app_localizations_ta.dart
+++ b/lib/l10n/generated/app_localizations_ta.dart
@@ -879,10 +879,16 @@ class AppLocalizationsTa extends AppLocalizations {
String get restore_defaults => 'இயல்புநிலைகளை மீட்டமை';
@override
- String get download_music_codec => 'இசை கோடெக்கை பதிவிறக்கு';
+ String get download_music_format => 'இசை பதிவிறக்க வடிவம்';
@override
- String get streaming_music_codec => 'இசை கோடெக்கை ஸ்ட்ரீம் செய்';
+ String get streaming_music_format => 'இசை ஸ்ட்ரீமிங் வடிவம்';
+
+ @override
+ String get download_music_quality => 'பதிவிறக்க தரம்';
+
+ @override
+ String get streaming_music_quality => 'ஸ்ட்ரீமிங் தரம்';
@override
String get login_with_lastfm => 'Last.fm உடன் உள்நுழைக';
@@ -1455,7 +1461,17 @@ class AppLocalizationsTa extends AppLocalizations {
'இந்த பிளகின் உங்கள் கேட்பதின் வரலாற்றை உருவாக்க உங்கள் இசையை ஸ்க்ரோப்ள் செய்கிறது.';
@override
- String get default_plugin => 'இயல்புநிலை';
+ String get default_metadata_source => 'இயல்புநிலை மெட்டாடேட்டா மூலம்';
+
+ @override
+ String get set_default_metadata_source =>
+ 'இயல்புநிலை மெட்டாடேட்டா மூலத்தை அமை';
+
+ @override
+ String get default_audio_source => 'இயல்புநிலை ஆடியோ மூலம்';
+
+ @override
+ String get set_default_audio_source => 'இயல்புநிலை ஆடியோ மூலத்தை அமை';
@override
String get set_default => 'இயல்புநிலையாக அமைக்கவும்';
@@ -1517,7 +1533,7 @@ class AppLocalizationsTa extends AppLocalizations {
'உள்ளீடு தேவையான வடிவத்துடன் பொருந்தவில்லை';
@override
- String get metadata_provider_plugins => 'மெட்டாடேட்டா வழங்குநர் பிளகின்கள்';
+ String get plugins => 'செருகுநிரல்கள்';
@override
String get paste_plugin_download_url =>
@@ -1542,12 +1558,22 @@ class AppLocalizationsTa extends AppLocalizations {
String get available_plugins => 'கிடைக்கக்கூடிய பிளகின்கள்';
@override
- String get configure_your_own_metadata_plugin =>
- 'உங்கள் சொந்த பிளேலிஸ்ட்/ஆல்பம்/கலைஞர்/ஊட்ட மெட்டாடேட்டா வழங்குநரை உள்ளமைக்கவும்';
+ String get configure_plugins =>
+ 'உங்கள் சொந்த மெட்டாடேட்டா வழங்குநர் மற்றும் ஆடியோ மூல செருகுநிரல்களை அமைக்கவும்';
@override
String get audio_scrobblers => 'ஆடியோ ஸ்க்ரோப்ளர்கள்';
@override
String get scrobbling => 'ஸ்க்ரோப்ளிங்';
+
+ @override
+ String get source => 'மூலம்: ';
+
+ @override
+ String get uncompressed => 'அழுத்தப்படாத';
+
+ @override
+ String get dab_music_source_description =>
+ 'ஆடியோஃபைல்களுக்காக. உயர்தர/லாஸ்லெஸ் ஆடியோ ஸ்ட்ரீம்களை வழங்குகிறது. ISRC அடிப்படையில் துல்லியமான பாடல் பொருத்தம்.';
}
diff --git a/lib/l10n/generated/app_localizations_th.dart b/lib/l10n/generated/app_localizations_th.dart
index 85230bfd..16584ab8 100644
--- a/lib/l10n/generated/app_localizations_th.dart
+++ b/lib/l10n/generated/app_localizations_th.dart
@@ -872,10 +872,16 @@ class AppLocalizationsTh extends AppLocalizations {
String get restore_defaults => 'คืนค่าเริ่มต้น';
@override
- String get download_music_codec => 'ดาวน์โหลดโคเดคเพลง';
+ String get download_music_format => 'รูปแบบการดาวน์โหลดเพลง';
@override
- String get streaming_music_codec => 'สตรีมมิ่งโคเดคเพลง';
+ String get streaming_music_format => 'รูปแบบการสตรีมเพลง';
+
+ @override
+ String get download_music_quality => 'คุณภาพการดาวน์โหลด';
+
+ @override
+ String get streaming_music_quality => 'คุณภาพการสตรีม';
@override
String get login_with_lastfm => 'เข้าสู่ระบบด้วย Last.fm';
@@ -1440,7 +1446,16 @@ class AppLocalizationsTh extends AppLocalizations {
'ปลั๊กอินนี้จะ scrobble เพลงของคุณเพื่อสร้างประวัติการฟังของคุณ';
@override
- String get default_plugin => 'ค่าเริ่มต้น';
+ String get default_metadata_source => 'แหล่งเมตาดาต้าพื้นฐาน';
+
+ @override
+ String get set_default_metadata_source => 'ตั้งค่าแหล่งเมตาดาต้าพื้นฐาน';
+
+ @override
+ String get default_audio_source => 'แหล่งเสียงพื้นฐาน';
+
+ @override
+ String get set_default_audio_source => 'ตั้งค่าแหล่งเสียงพื้นฐาน';
@override
String get set_default => 'ตั้งค่าเริ่มต้น';
@@ -1500,7 +1515,7 @@ class AppLocalizationsTh extends AppLocalizations {
String get input_does_not_match_format => 'อินพุตไม่ตรงกับรูปแบบที่ต้องการ';
@override
- String get metadata_provider_plugins => 'ปลั๊กอินผู้ให้บริการเมตาดาต้า';
+ String get plugins => 'ปลั๊กอิน';
@override
String get paste_plugin_download_url =>
@@ -1525,12 +1540,22 @@ class AppLocalizationsTh extends AppLocalizations {
String get available_plugins => 'ปลั๊กอินที่มีอยู่';
@override
- String get configure_your_own_metadata_plugin =>
- 'กำหนดค่าผู้ให้บริการเมตาดาต้าเพลย์ลิสต์/อัลบั้ม/ศิลปิน/ฟีดของคุณเอง';
+ String get configure_plugins =>
+ 'กำหนดค่าปลั๊กอินผู้ให้บริการเมตาดาต้าและแหล่งเสียงของคุณเอง';
@override
String get audio_scrobblers => 'เครื่อง scrobbler เสียง';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'แหล่งที่มา: ';
+
+ @override
+ String get uncompressed => 'ไม่บีบอัด';
+
+ @override
+ String get dab_music_source_description =>
+ 'สำหรับคนรักเสียงเพลง ให้สตรีมเสียงคุณภาพสูง/ไร้การสูญเสียการบีบอัด การจับคู่แทร็กแม่นยำตาม ISRC';
}
diff --git a/lib/l10n/generated/app_localizations_tl.dart b/lib/l10n/generated/app_localizations_tl.dart
index 361a7bf0..5febc92d 100644
--- a/lib/l10n/generated/app_localizations_tl.dart
+++ b/lib/l10n/generated/app_localizations_tl.dart
@@ -878,10 +878,16 @@ class AppLocalizationsTl extends AppLocalizations {
String get restore_defaults => 'Ibalik ang mga default';
@override
- String get download_music_codec => 'Codec para sa pag-download ng musika';
+ String get download_music_format => 'I-download na format ng musika';
@override
- String get streaming_music_codec => 'Codec para sa pag-stream ng musika';
+ String get streaming_music_format => 'Format ng streaming ng musika';
+
+ @override
+ String get download_music_quality => 'Kalidad ng i-download na musika';
+
+ @override
+ String get streaming_music_quality => 'Kalidad ng streaming ng musika';
@override
String get login_with_lastfm => 'Mag-login gamit ang Last.fm';
@@ -1456,7 +1462,18 @@ class AppLocalizationsTl extends AppLocalizations {
'Sinis-scrobble ng plugin na ito ang iyong musika upang mabuo ang iyong kasaysayan ng pakikinig.';
@override
- String get default_plugin => 'Default';
+ String get default_metadata_source => 'Default na pinagmulan ng metadata';
+
+ @override
+ String get set_default_metadata_source =>
+ 'Itakda ang default na pinagmulan ng metadata';
+
+ @override
+ String get default_audio_source => 'Default na pinagmulan ng audio';
+
+ @override
+ String get set_default_audio_source =>
+ 'Itakda ang default na pinagmulan ng audio';
@override
String get set_default => 'Itakda bilang default';
@@ -1518,7 +1535,7 @@ class AppLocalizationsTl extends AppLocalizations {
'Ang input ay hindi tumutugma sa kinakailangang format';
@override
- String get metadata_provider_plugins => 'Mga Plugin ng Metadata Provider';
+ String get plugins => 'Mga plugin';
@override
String get paste_plugin_download_url =>
@@ -1543,12 +1560,22 @@ class AppLocalizationsTl extends AppLocalizations {
String get available_plugins => 'Mga available na plugin';
@override
- String get configure_your_own_metadata_plugin =>
- 'I-configure ang iyong sariling playlist/album/artist/feed metadata provider';
+ String get configure_plugins =>
+ 'I-configure ang sarili mong metadata provider at mga audio source plugin';
@override
String get audio_scrobblers => 'Mga Audio Scrobbler';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Pinagmulan: ';
+
+ @override
+ String get uncompressed => 'Hindi naka-compress';
+
+ @override
+ String get dab_music_source_description =>
+ 'Para sa mga audiophile. Nagbibigay ng de-kalidad/walang loss na audio streams. Tumpak na pagtutugma ng track batay sa ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_tr.dart b/lib/l10n/generated/app_localizations_tr.dart
index 4dc65bbc..c2280f47 100644
--- a/lib/l10n/generated/app_localizations_tr.dart
+++ b/lib/l10n/generated/app_localizations_tr.dart
@@ -875,10 +875,16 @@ class AppLocalizationsTr extends AppLocalizations {
String get restore_defaults => 'Varsayılanları geri yükle';
@override
- String get download_music_codec => 'Müzik codec bileşenini indir';
+ String get download_music_format => 'Müzik indirme formatı';
@override
- String get streaming_music_codec => 'Müzik codec\'i akışı';
+ String get streaming_music_format => 'Müzik akış formatı';
+
+ @override
+ String get download_music_quality => 'İndirilen müzik kalitesi';
+
+ @override
+ String get streaming_music_quality => 'Yayınlanan müzik kalitesi';
@override
String get login_with_lastfm => 'Last.fm ile giriş yap';
@@ -1450,7 +1456,17 @@ class AppLocalizationsTr extends AppLocalizations {
'Bu eklenti, dinleme geçmişinizi oluşturmak için müziğinizi scrobble eder.';
@override
- String get default_plugin => 'Varsayılan';
+ String get default_metadata_source => 'Varsayılan meta veri kaynağı';
+
+ @override
+ String get set_default_metadata_source =>
+ 'Varsayılan meta veri kaynağını ayarla';
+
+ @override
+ String get default_audio_source => 'Varsayılan ses kaynağı';
+
+ @override
+ String get set_default_audio_source => 'Varsayılan ses kaynağını ayarla';
@override
String get set_default => 'Varsayılan olarak ayarla';
@@ -1511,7 +1527,7 @@ class AppLocalizationsTr extends AppLocalizations {
String get input_does_not_match_format => 'Girdi, gerekli biçimle eşleşmiyor';
@override
- String get metadata_provider_plugins => 'Meta Veri Sağlayıcısı Eklentileri';
+ String get plugins => 'Eklentiler';
@override
String get paste_plugin_download_url =>
@@ -1536,12 +1552,22 @@ class AppLocalizationsTr extends AppLocalizations {
String get available_plugins => 'Mevcut eklentiler';
@override
- String get configure_your_own_metadata_plugin =>
- 'Kendi çalma listenizi/albümünüzü/sanatçınızı/akış meta veri sağlayıcınızı yapılandırın';
+ String get configure_plugins =>
+ 'Kendi meta veri sağlayıcı ve ses kaynağı eklentilerinizi yapılandırın';
@override
String get audio_scrobblers => 'Ses Scrobbler\'lar';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Kaynak: ';
+
+ @override
+ String get uncompressed => 'Sıkıştırılmamış';
+
+ @override
+ String get dab_music_source_description =>
+ 'Audiophile\'ler için. Yüksek kaliteli/kayıpsız ses akışları sağlar. Doğru ISRC tabanlı parça eşleştirme.';
}
diff --git a/lib/l10n/generated/app_localizations_uk.dart b/lib/l10n/generated/app_localizations_uk.dart
index 35a18d55..c2bed426 100644
--- a/lib/l10n/generated/app_localizations_uk.dart
+++ b/lib/l10n/generated/app_localizations_uk.dart
@@ -875,10 +875,16 @@ class AppLocalizationsUk extends AppLocalizations {
String get restore_defaults => 'Відновити налаштування за замовчуванням';
@override
- String get download_music_codec => 'Завантажити кодек для музики';
+ String get download_music_format => 'Формат завантаження музики';
@override
- String get streaming_music_codec => 'Кодек потокової передачі музики';
+ String get streaming_music_format => 'Формат потокової музики';
+
+ @override
+ String get download_music_quality => 'Якість завантаженої музики';
+
+ @override
+ String get streaming_music_quality => 'Якість потокової музики';
@override
String get login_with_lastfm => 'Увійти з Last.fm';
@@ -1446,7 +1452,18 @@ class AppLocalizationsUk extends AppLocalizations {
'Цей плагін скроббить вашу музику, щоб створити вашу історію прослуховувань.';
@override
- String get default_plugin => 'За замовчуванням';
+ String get default_metadata_source => 'Джерело метаданих за замовчуванням';
+
+ @override
+ String get set_default_metadata_source =>
+ 'Встановити джерело метаданих за замовчуванням';
+
+ @override
+ String get default_audio_source => 'Джерело аудіо за замовчуванням';
+
+ @override
+ String get set_default_audio_source =>
+ 'Встановити джерело аудіо за замовчуванням';
@override
String get set_default => 'Встановити за замовчуванням';
@@ -1507,7 +1524,7 @@ class AppLocalizationsUk extends AppLocalizations {
'Введені дані не відповідають необхідному формату';
@override
- String get metadata_provider_plugins => 'Плагіни провайдера метаданих';
+ String get plugins => 'Плагіни';
@override
String get paste_plugin_download_url =>
@@ -1532,12 +1549,22 @@ class AppLocalizationsUk extends AppLocalizations {
String get available_plugins => 'Доступні плагіни';
@override
- String get configure_your_own_metadata_plugin =>
- 'Налаштуйте свій власний провайдер метаданих для плейлиста/альбому/виконавця/стрічки';
+ String get configure_plugins =>
+ 'Налаштуйте власні плагіни метаданих і аудіоджерела';
@override
String get audio_scrobblers => 'Аудіо скробблери';
@override
String get scrobbling => 'Скроблінг';
+
+ @override
+ String get source => 'Джерело: ';
+
+ @override
+ String get uncompressed => 'Без стиснення';
+
+ @override
+ String get dab_music_source_description =>
+ 'Для аудіофілів. Забезпечує високоякісні/без втрат аудіопотоки. Точна відповідність треків на основі ISRC.';
}
diff --git a/lib/l10n/generated/app_localizations_vi.dart b/lib/l10n/generated/app_localizations_vi.dart
index 6015931e..4d7a8945 100644
--- a/lib/l10n/generated/app_localizations_vi.dart
+++ b/lib/l10n/generated/app_localizations_vi.dart
@@ -875,10 +875,16 @@ class AppLocalizationsVi extends AppLocalizations {
String get restore_defaults => 'Khôi phục mặc định';
@override
- String get download_music_codec => 'Định dạng tải xuống';
+ String get download_music_format => 'Định dạng nhạc tải về';
@override
- String get streaming_music_codec => 'Định dạng nghe';
+ String get streaming_music_format => 'Định dạng nhạc phát trực tuyến';
+
+ @override
+ String get download_music_quality => 'Chất lượng nhạc tải về';
+
+ @override
+ String get streaming_music_quality => 'Chất lượng nhạc phát trực tuyến';
@override
String get login_with_lastfm => 'Đăng nhập bằng tài khoản Last.fm';
@@ -1450,7 +1456,16 @@ class AppLocalizationsVi extends AppLocalizations {
'Plugin này scrobble nhạc của bạn để tạo lịch sử nghe của bạn.';
@override
- String get default_plugin => 'Mặc định';
+ String get default_metadata_source => 'Nguồn siêu dữ liệu mặc định';
+
+ @override
+ String get set_default_metadata_source => 'Đặt nguồn siêu dữ liệu mặc định';
+
+ @override
+ String get default_audio_source => 'Nguồn âm thanh mặc định';
+
+ @override
+ String get set_default_audio_source => 'Đặt nguồn âm thanh mặc định';
@override
String get set_default => 'Đặt làm mặc định';
@@ -1513,7 +1528,7 @@ class AppLocalizationsVi extends AppLocalizations {
'Đầu vào không khớp với định dạng yêu cầu';
@override
- String get metadata_provider_plugins => 'Plugin Nhà cung cấp siêu dữ liệu';
+ String get plugins => 'Tiện ích bổ sung';
@override
String get paste_plugin_download_url =>
@@ -1538,12 +1553,22 @@ class AppLocalizationsVi extends AppLocalizations {
String get available_plugins => 'Các plugin có sẵn';
@override
- String get configure_your_own_metadata_plugin =>
- 'Cấu hình nhà cung cấp siêu dữ liệu danh sách phát/album/nghệ sĩ/nguồn cấp dữ liệu của riêng bạn';
+ String get configure_plugins =>
+ 'Cấu hình nhà cung cấp siêu dữ liệu và tiện ích nguồn âm thanh riêng';
@override
String get audio_scrobblers => 'Bộ scrobbler âm thanh';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => 'Nguồn: ';
+
+ @override
+ String get uncompressed => 'Không nén';
+
+ @override
+ String get dab_music_source_description =>
+ 'Dành cho người yêu âm nhạc chất lượng cao. Cung cấp luồng âm thanh chất lượng cao/không nén. Phù hợp bài hát dựa trên ISRC chính xác.';
}
diff --git a/lib/l10n/generated/app_localizations_zh.dart b/lib/l10n/generated/app_localizations_zh.dart
index e42b6994..ac7d4890 100644
--- a/lib/l10n/generated/app_localizations_zh.dart
+++ b/lib/l10n/generated/app_localizations_zh.dart
@@ -859,10 +859,16 @@ class AppLocalizationsZh extends AppLocalizations {
String get restore_defaults => '恢复默认值';
@override
- String get download_music_codec => '下载音乐编解码器';
+ String get download_music_format => '下载音乐格式';
@override
- String get streaming_music_codec => '流媒体音乐编解码器';
+ String get streaming_music_format => '流媒体音乐格式';
+
+ @override
+ String get download_music_quality => '下载音乐质量';
+
+ @override
+ String get streaming_music_quality => '流媒体音乐质量';
@override
String get login_with_lastfm => '使用 Last.fm 登录';
@@ -1412,7 +1418,16 @@ class AppLocalizationsZh extends AppLocalizations {
String get plugin_scrobbling_info => '此插件会 scrobble 您的音乐以生成您的收听历史记录。';
@override
- String get default_plugin => '默认';
+ String get default_metadata_source => '默认元数据源';
+
+ @override
+ String get set_default_metadata_source => '设置默认元数据源';
+
+ @override
+ String get default_audio_source => '默认音频源';
+
+ @override
+ String get set_default_audio_source => '设置默认音频源';
@override
String get set_default => '设为默认';
@@ -1469,7 +1484,7 @@ class AppLocalizationsZh extends AppLocalizations {
String get input_does_not_match_format => '输入与所需格式不匹配';
@override
- String get metadata_provider_plugins => '元数据提供者插件';
+ String get plugins => '插件';
@override
String get paste_plugin_download_url =>
@@ -1493,13 +1508,23 @@ class AppLocalizationsZh extends AppLocalizations {
String get available_plugins => '可用插件';
@override
- String get configure_your_own_metadata_plugin => '配置您自己的播放列表/专辑/艺人/订阅元数据提供者';
+ String get configure_plugins => '配置您自己的元数据提供者和音频源插件';
@override
String get audio_scrobblers => '音频 Scrobblers';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => '来源:';
+
+ @override
+ String get uncompressed => '无损';
+
+ @override
+ String get dab_music_source_description =>
+ '适合发烧友。提供高质量/无损音频流。基于 ISRC 的精确曲目匹配。';
}
/// The translations for Chinese, as used in Taiwan (`zh_TW`).
@@ -2357,10 +2382,16 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
String get restore_defaults => '恢復預設值';
@override
- String get download_music_codec => '下載音樂編解碼器';
+ String get download_music_format => '下載音樂格式';
@override
- String get streaming_music_codec => '串流音樂編解碼器';
+ String get streaming_music_format => '串流音樂格式';
+
+ @override
+ String get download_music_quality => '下載音樂品質';
+
+ @override
+ String get streaming_music_quality => '串流音樂品質';
@override
String get login_with_lastfm => '使用 Last.fm 登入';
@@ -2910,7 +2941,16 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
String get plugin_scrobbling_info => '此外掛程式會 Scrobble 您的音樂以產生您的收聽記錄。';
@override
- String get default_plugin => '預設';
+ String get default_metadata_source => '預設中繼資料來源';
+
+ @override
+ String get set_default_metadata_source => '設定預設中繼資料來源';
+
+ @override
+ String get default_audio_source => '預設音訊來源';
+
+ @override
+ String get set_default_audio_source => '設定預設音訊來源';
@override
String get set_default => '設為預設';
@@ -2967,7 +3007,7 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
String get input_does_not_match_format => '輸入不符合所需格式';
@override
- String get metadata_provider_plugins => '中繼資料供應商外掛程式';
+ String get plugins => '外掛程式';
@override
String get paste_plugin_download_url =>
@@ -2991,11 +3031,21 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
String get available_plugins => '可用的外掛程式';
@override
- String get configure_your_own_metadata_plugin => '設定您自己的播放清單/專輯/藝人/動態中繼資料供應商';
+ String get configure_plugins => '配置您自己的中繼資料提供者和音訊來源外掛程式';
@override
String get audio_scrobblers => '音訊 Scrobblers';
@override
String get scrobbling => 'Scrobbling';
+
+ @override
+ String get source => '來源:';
+
+ @override
+ String get uncompressed => '未壓縮';
+
+ @override
+ String get dab_music_source_description =>
+ '適合音響發燒友。提供高品質/無損音訊串流。精確的 ISRC 曲目比對。';
}
diff --git a/lib/main.dart b/lib/main.dart
index b5789d6f..ecf7148d 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -83,6 +83,8 @@ Future main(List rawArgs) async {
// force High Refresh Rate on some Android devices (like One Plus)
if (kIsAndroid) {
await FlutterDisplayMode.setHighRefreshRate();
+ }
+ if (kIsAndroid || kIsDesktop) {
await NewPipeExtractor.init();
}
@@ -150,11 +152,13 @@ class Spotube extends HookConsumerWidget {
ref.listen(audioPlayerStreamListenersProvider, (_, __) {});
ref.listen(bonsoirProvider, (_, __) {});
ref.listen(connectClientsProvider, (_, __) {});
- ref.listen(metadataPluginsProvider, (_, __) {});
- ref.listen(metadataPluginProvider, (_, __) {});
ref.listen(serverProvider, (_, __) {});
ref.listen(trayManagerProvider, (_, __) {});
+ ref.listen(metadataPluginsProvider, (_, __) {});
+ ref.listen(metadataPluginProvider, (_, __) {});
+ ref.listen(audioSourcePluginProvider, (_, __) {});
ref.listen(metadataPluginUpdateCheckerProvider, (_, __) {});
+ ref.listen(audioSourcePluginUpdateCheckerProvider, (_, __) {});
useFixWindowStretching();
useDisableBatteryOptimizations();
diff --git a/lib/models/connect/connect.freezed.dart b/lib/models/connect/connect.freezed.dart
index 9f9b558b..157d0911 100644
--- a/lib/models/connect/connect.freezed.dart
+++ b/lib/models/connect/connect.freezed.dart
@@ -112,8 +112,13 @@ mixin _$WebSocketLoadEventData {
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
+
+ /// Serializes this WebSocketLoadEventData to a JSON map.
Map toJson() => throw _privateConstructorUsedError;
- @JsonKey(ignore: true)
+
+ /// Create a copy of WebSocketLoadEventData
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
$WebSocketLoadEventDataCopyWith get copyWith =>
throw _privateConstructorUsedError;
}
@@ -142,6 +147,8 @@ class _$WebSocketLoadEventDataCopyWithImpl<$Res,
// ignore: unused_field
final $Res Function($Val) _then;
+ /// Create a copy of WebSocketLoadEventData
+ /// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
@@ -190,6 +197,8 @@ class __$$WebSocketLoadEventDataPlaylistImplCopyWithImpl<$Res>
$Res Function(_$WebSocketLoadEventDataPlaylistImpl) _then)
: super(_value, _then);
+ /// Create a copy of WebSocketLoadEventData
+ /// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
@@ -213,6 +222,8 @@ class __$$WebSocketLoadEventDataPlaylistImplCopyWithImpl<$Res>
));
}
+ /// Create a copy of WebSocketLoadEventData
+ /// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SpotubeSimplePlaylistObjectCopyWith<$Res>? get collection {
@@ -281,12 +292,14 @@ class _$WebSocketLoadEventDataPlaylistImpl
other.initialIndex == initialIndex));
}
- @JsonKey(ignore: true)
+ @JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,
const DeepCollectionEquality().hash(_tracks), collection, initialIndex);
- @JsonKey(ignore: true)
+ /// Create a copy of WebSocketLoadEventData
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$WebSocketLoadEventDataPlaylistImplCopyWith<
@@ -420,8 +433,11 @@ abstract class WebSocketLoadEventDataPlaylist extends WebSocketLoadEventData {
SpotubeSimplePlaylistObject? get collection;
@override
int? get initialIndex;
+
+ /// Create a copy of WebSocketLoadEventData
+ /// with the given fields replaced by the non-null parameter values.
@override
- @JsonKey(ignore: true)
+ @JsonKey(includeFromJson: false, includeToJson: false)
_$$WebSocketLoadEventDataPlaylistImplCopyWith<
_$WebSocketLoadEventDataPlaylistImpl>
get copyWith => throw _privateConstructorUsedError;
@@ -456,6 +472,8 @@ class __$$WebSocketLoadEventDataAlbumImplCopyWithImpl<$Res>
$Res Function(_$WebSocketLoadEventDataAlbumImpl) _then)
: super(_value, _then);
+ /// Create a copy of WebSocketLoadEventData
+ /// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
@@ -479,6 +497,8 @@ class __$$WebSocketLoadEventDataAlbumImplCopyWithImpl<$Res>
));
}
+ /// Create a copy of WebSocketLoadEventData
+ /// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SpotubeSimpleAlbumObjectCopyWith<$Res>? get collection {
@@ -545,12 +565,14 @@ class _$WebSocketLoadEventDataAlbumImpl extends WebSocketLoadEventDataAlbum {
other.initialIndex == initialIndex));
}
- @JsonKey(ignore: true)
+ @JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,
const DeepCollectionEquality().hash(_tracks), collection, initialIndex);
- @JsonKey(ignore: true)
+ /// Create a copy of WebSocketLoadEventData
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$WebSocketLoadEventDataAlbumImplCopyWith<_$WebSocketLoadEventDataAlbumImpl>
@@ -683,8 +705,11 @@ abstract class WebSocketLoadEventDataAlbum extends WebSocketLoadEventData {
SpotubeSimpleAlbumObject? get collection;
@override
int? get initialIndex;
+
+ /// Create a copy of WebSocketLoadEventData
+ /// with the given fields replaced by the non-null parameter values.
@override
- @JsonKey(ignore: true)
+ @JsonKey(includeFromJson: false, includeToJson: false)
_$$WebSocketLoadEventDataAlbumImplCopyWith<_$WebSocketLoadEventDataAlbumImpl>
get copyWith => throw _privateConstructorUsedError;
}
diff --git a/lib/models/database/database.dart b/lib/models/database/database.dart
index bc30627d..f1c66c1a 100644
--- a/lib/models/database/database.dart
+++ b/lib/models/database/database.dart
@@ -16,13 +16,14 @@ import 'package:spotube/models/metadata/market.dart';
import 'package:spotube/models/metadata/metadata.dart';
import 'package:spotube/services/kv_store/encrypted_kv_store.dart';
import 'package:spotube/services/kv_store/kv_store.dart';
-import 'package:spotube/services/sourced_track/enums.dart';
import 'package:flutter/widgets.dart' hide Table, Key, View;
import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart';
import 'package:drift/native.dart';
+import 'package:spotube/services/logger/logger.dart';
import 'package:spotube/services/youtube_engine/newpipe_engine.dart';
import 'package:spotube/services/youtube_engine/youtube_explode_engine.dart';
import 'package:spotube/services/youtube_engine/yt_dlp_engine.dart';
+import 'package:spotube/utils/platform.dart';
import 'package:sqlite3/sqlite3.dart';
import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart';
@@ -58,14 +59,14 @@ part 'typeconverters/subtitle.dart';
AudioPlayerStateTable,
HistoryTable,
LyricsTable,
- MetadataPluginsTable,
+ PluginsTable,
],
)
class AppDatabase extends _$AppDatabase {
AppDatabase() : super(_openConnection());
@override
- int get schemaVersion => 8;
+ int get schemaVersion => 10;
@override
MigrationStrategy get migration {
@@ -199,6 +200,43 @@ class AppDatabase extends _$AppDatabase {
}
});
},
+ from8To9: (m, schema) async {
+ await m
+ .renameTable(schema.pluginsTable, "metadata_plugins_table")
+ .catchError((e, stack) => AppLogger.reportError(e, stack));
+ await m
+ .renameColumn(
+ schema.pluginsTable,
+ "selected",
+ pluginsTable.selectedForMetadata,
+ )
+ .catchError((e, stack) => AppLogger.reportError(e, stack));
+ await m
+ .addColumn(
+ schema.pluginsTable,
+ pluginsTable.selectedForAudioSource,
+ )
+ .catchError((e, stack) => AppLogger.reportError(e, stack));
+ },
+ from9To10: (m, schema) async {
+ await m
+ .dropColumn(schema.preferencesTable, "piped_instance")
+ .catchError((e, stack) => AppLogger.reportError(e, stack));
+ await m
+ .dropColumn(schema.preferencesTable, "invidious_instance")
+ .catchError((e, stack) => AppLogger.reportError(e, stack));
+ await m
+ .addColumn(
+ schema.sourceMatchTable,
+ sourceMatchTable.sourceInfo,
+ )
+ .catchError((e, stack) => AppLogger.reportError(e, stack));
+ await customStatement("DROP INDEX IF EXISTS uniq_track_match;")
+ .catchError((e, stack) => AppLogger.reportError(e, stack));
+ await m
+ .dropColumn(schema.sourceMatchTable, "source_id")
+ .catchError((e, stack) => AppLogger.reportError(e, stack));
+ },
),
);
}
diff --git a/lib/models/database/database.g.dart b/lib/models/database/database.g.dart
index ba24c037..8aa14899 100644
--- a/lib/models/database/database.g.dart
+++ b/lib/models/database/database.g.dart
@@ -18,15 +18,12 @@ class $AuthenticationTableTable extends AuthenticationTable
requiredDuringInsert: false,
defaultConstraints:
GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
- static const VerificationMeta _cookieMeta = const VerificationMeta('cookie');
@override
late final GeneratedColumnWithTypeConverter cookie =
GeneratedColumn('cookie', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true)
.withConverter(
$AuthenticationTableTable.$convertercookie);
- static const VerificationMeta _accessTokenMeta =
- const VerificationMeta('accessToken');
@override
late final GeneratedColumnWithTypeConverter
accessToken = GeneratedColumn('access_token', aliasedName, false,
@@ -55,8 +52,6 @@ class $AuthenticationTableTable extends AuthenticationTable
if (data.containsKey('id')) {
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
}
- context.handle(_cookieMeta, const VerificationResult.success());
- context.handle(_accessTokenMeta, const VerificationResult.success());
if (data.containsKey('expiration')) {
context.handle(
_expirationMeta,
@@ -301,8 +296,6 @@ class $BlacklistTableTable extends BlacklistTable
late final GeneratedColumn name = GeneratedColumn(
'name', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true);
- static const VerificationMeta _elementTypeMeta =
- const VerificationMeta('elementType');
@override
late final GeneratedColumnWithTypeConverter
elementType = GeneratedColumn('element_type', aliasedName, false,
@@ -336,7 +329,6 @@ class $BlacklistTableTable extends BlacklistTable
} else if (isInserting) {
context.missing(_nameMeta);
}
- context.handle(_elementTypeMeta, const VerificationResult.success());
if (data.containsKey('element_id')) {
context.handle(_elementIdMeta,
elementId.isAcceptableOrUnknown(data['element_id']!, _elementIdMeta));
@@ -566,17 +558,6 @@ class $PreferencesTableTable extends PreferencesTable
requiredDuringInsert: false,
defaultConstraints:
GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
- static const VerificationMeta _audioQualityMeta =
- const VerificationMeta('audioQuality');
- @override
- late final GeneratedColumnWithTypeConverter
- audioQuality = GeneratedColumn(
- 'audio_quality', aliasedName, false,
- type: DriftSqlType.string,
- requiredDuringInsert: false,
- defaultValue: Constant(SourceQualities.high.name))
- .withConverter(
- $PreferencesTableTable.$converteraudioQuality);
static const VerificationMeta _albumColorSyncMeta =
const VerificationMeta('albumColorSync');
@override
@@ -647,8 +628,6 @@ class $PreferencesTableTable extends PreferencesTable
defaultConstraints: GeneratedColumn.constraintIsAlways(
'CHECK ("skip_non_music" IN (0, 1))'),
defaultValue: const Constant(false));
- static const VerificationMeta _closeBehaviorMeta =
- const VerificationMeta('closeBehavior');
@override
late final GeneratedColumnWithTypeConverter
closeBehavior = GeneratedColumn(
@@ -658,8 +637,6 @@ class $PreferencesTableTable extends PreferencesTable
defaultValue: Constant(CloseBehavior.close.name))
.withConverter(
$PreferencesTableTable.$convertercloseBehavior);
- static const VerificationMeta _accentColorSchemeMeta =
- const VerificationMeta('accentColorScheme');
@override
late final GeneratedColumnWithTypeConverter
accentColorScheme = GeneratedColumn(
@@ -669,8 +646,6 @@ class $PreferencesTableTable extends PreferencesTable
defaultValue: const Constant("Slate:0xff64748b"))
.withConverter(
$PreferencesTableTable.$converteraccentColorScheme);
- static const VerificationMeta _layoutModeMeta =
- const VerificationMeta('layoutMode');
@override
late final GeneratedColumnWithTypeConverter layoutMode =
GeneratedColumn('layout_mode', aliasedName, false,
@@ -679,7 +654,6 @@ class $PreferencesTableTable extends PreferencesTable
defaultValue: Constant(LayoutMode.adaptive.name))
.withConverter(
$PreferencesTableTable.$converterlayoutMode);
- static const VerificationMeta _localeMeta = const VerificationMeta('locale');
@override
late final GeneratedColumnWithTypeConverter locale =
GeneratedColumn('locale', aliasedName, false,
@@ -688,7 +662,6 @@ class $PreferencesTableTable extends PreferencesTable
defaultValue: const Constant(
'{"languageCode":"system","countryCode":"system"}'))
.withConverter($PreferencesTableTable.$converterlocale);
- static const VerificationMeta _marketMeta = const VerificationMeta('market');
@override
late final GeneratedColumnWithTypeConverter market =
GeneratedColumn('market', aliasedName, false,
@@ -696,8 +669,6 @@ class $PreferencesTableTable extends PreferencesTable
requiredDuringInsert: false,
defaultValue: Constant(Market.US.name))
.withConverter($PreferencesTableTable.$convertermarket);
- static const VerificationMeta _searchModeMeta =
- const VerificationMeta('searchMode');
@override
late final GeneratedColumnWithTypeConverter searchMode =
GeneratedColumn('search_mode', aliasedName, false,
@@ -714,8 +685,6 @@ class $PreferencesTableTable extends PreferencesTable
type: DriftSqlType.string,
requiredDuringInsert: false,
defaultValue: const Constant(""));
- static const VerificationMeta _localLibraryLocationMeta =
- const VerificationMeta('localLibraryLocation');
@override
late final GeneratedColumnWithTypeConverter, String>
localLibraryLocation = GeneratedColumn(
@@ -725,24 +694,6 @@ class $PreferencesTableTable extends PreferencesTable
defaultValue: const Constant(""))
.withConverter>(
$PreferencesTableTable.$converterlocalLibraryLocation);
- static const VerificationMeta _pipedInstanceMeta =
- const VerificationMeta('pipedInstance');
- @override
- late final GeneratedColumn pipedInstance = GeneratedColumn(
- 'piped_instance', aliasedName, false,
- type: DriftSqlType.string,
- requiredDuringInsert: false,
- defaultValue: const Constant("https://pipedapi.kavin.rocks"));
- static const VerificationMeta _invidiousInstanceMeta =
- const VerificationMeta('invidiousInstance');
- @override
- late final GeneratedColumn invidiousInstance =
- GeneratedColumn('invidious_instance', aliasedName, false,
- type: DriftSqlType.string,
- requiredDuringInsert: false,
- defaultValue: const Constant("https://inv.nadeko.net"));
- static const VerificationMeta _themeModeMeta =
- const VerificationMeta('themeMode');
@override
late final GeneratedColumnWithTypeConverter themeMode =
GeneratedColumn('theme_mode', aliasedName, false,
@@ -750,18 +701,12 @@ class $PreferencesTableTable extends PreferencesTable
requiredDuringInsert: false,
defaultValue: Constant(ThemeMode.system.name))
.withConverter($PreferencesTableTable.$converterthemeMode);
- static const VerificationMeta _audioSourceMeta =
- const VerificationMeta('audioSource');
+ static const VerificationMeta _audioSourceIdMeta =
+ const VerificationMeta('audioSourceId');
@override
- late final GeneratedColumnWithTypeConverter audioSource =
- GeneratedColumn('audio_source', aliasedName, false,
- type: DriftSqlType.string,
- requiredDuringInsert: false,
- defaultValue: Constant(AudioSource.youtube.name))
- .withConverter(
- $PreferencesTableTable.$converteraudioSource);
- static const VerificationMeta _youtubeClientEngineMeta =
- const VerificationMeta('youtubeClientEngine');
+ late final GeneratedColumn audioSourceId = GeneratedColumn(
+ 'audio_source_id', aliasedName, true,
+ type: DriftSqlType.string, requiredDuringInsert: false);
@override
late final GeneratedColumnWithTypeConverter
youtubeClientEngine = GeneratedColumn(
@@ -771,28 +716,6 @@ class $PreferencesTableTable extends PreferencesTable
defaultValue: Constant(YoutubeClientEngine.youtubeExplode.name))
.withConverter(
$PreferencesTableTable.$converteryoutubeClientEngine);
- static const VerificationMeta _streamMusicCodecMeta =
- const VerificationMeta('streamMusicCodec');
- @override
- late final GeneratedColumnWithTypeConverter
- streamMusicCodec = GeneratedColumn(
- 'stream_music_codec', aliasedName, false,
- type: DriftSqlType.string,
- requiredDuringInsert: false,
- defaultValue: Constant(SourceCodecs.weba.name))
- .withConverter(
- $PreferencesTableTable.$converterstreamMusicCodec);
- static const VerificationMeta _downloadMusicCodecMeta =
- const VerificationMeta('downloadMusicCodec');
- @override
- late final GeneratedColumnWithTypeConverter
- downloadMusicCodec = GeneratedColumn(
- 'download_music_codec', aliasedName, false,
- type: DriftSqlType.string,
- requiredDuringInsert: false,
- defaultValue: Constant(SourceCodecs.m4a.name))
- .withConverter(
- $PreferencesTableTable.$converterdownloadMusicCodec);
static const VerificationMeta _discordPresenceMeta =
const VerificationMeta('discordPresence');
@override
@@ -844,7 +767,6 @@ class $PreferencesTableTable extends PreferencesTable
@override
List get $columns => [
id,
- audioQuality,
albumColorSync,
amoledDarkTheme,
checkUpdate,
@@ -860,13 +782,9 @@ class $PreferencesTableTable extends PreferencesTable
searchMode,
downloadLocation,
localLibraryLocation,
- pipedInstance,
- invidiousInstance,
themeMode,
- audioSource,
+ audioSourceId,
youtubeClientEngine,
- streamMusicCodec,
- downloadMusicCodec,
discordPresence,
endlessPlayback,
enableConnect,
@@ -887,7 +805,6 @@ class $PreferencesTableTable extends PreferencesTable
if (data.containsKey('id')) {
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
}
- context.handle(_audioQualityMeta, const VerificationResult.success());
if (data.containsKey('album_color_sync')) {
context.handle(
_albumColorSyncMeta,
@@ -930,38 +847,18 @@ class $PreferencesTableTable extends PreferencesTable
skipNonMusic.isAcceptableOrUnknown(
data['skip_non_music']!, _skipNonMusicMeta));
}
- context.handle(_closeBehaviorMeta, const VerificationResult.success());
- context.handle(_accentColorSchemeMeta, const VerificationResult.success());
- context.handle(_layoutModeMeta, const VerificationResult.success());
- context.handle(_localeMeta, const VerificationResult.success());
- context.handle(_marketMeta, const VerificationResult.success());
- context.handle(_searchModeMeta, const VerificationResult.success());
if (data.containsKey('download_location')) {
context.handle(
_downloadLocationMeta,
downloadLocation.isAcceptableOrUnknown(
data['download_location']!, _downloadLocationMeta));
}
- context.handle(
- _localLibraryLocationMeta, const VerificationResult.success());
- if (data.containsKey('piped_instance')) {
+ if (data.containsKey('audio_source_id')) {
context.handle(
- _pipedInstanceMeta,
- pipedInstance.isAcceptableOrUnknown(
- data['piped_instance']!, _pipedInstanceMeta));
+ _audioSourceIdMeta,
+ audioSourceId.isAcceptableOrUnknown(
+ data['audio_source_id']!, _audioSourceIdMeta));
}
- if (data.containsKey('invidious_instance')) {
- context.handle(
- _invidiousInstanceMeta,
- invidiousInstance.isAcceptableOrUnknown(
- data['invidious_instance']!, _invidiousInstanceMeta));
- }
- context.handle(_themeModeMeta, const VerificationResult.success());
- context.handle(_audioSourceMeta, const VerificationResult.success());
- context.handle(
- _youtubeClientEngineMeta, const VerificationResult.success());
- context.handle(_streamMusicCodecMeta, const VerificationResult.success());
- context.handle(_downloadMusicCodecMeta, const VerificationResult.success());
if (data.containsKey('discord_presence')) {
context.handle(
_discordPresenceMeta,
@@ -1003,9 +900,6 @@ class $PreferencesTableTable extends PreferencesTable
return PreferencesTableData(
id: attachedDatabase.typeMapping
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
- audioQuality: $PreferencesTableTable.$converteraudioQuality.fromSql(
- attachedDatabase.typeMapping.read(
- DriftSqlType.string, data['${effectivePrefix}audio_quality'])!),
albumColorSync: attachedDatabase.typeMapping
.read(DriftSqlType.bool, data['${effectivePrefix}album_color_sync'])!,
amoledDarkTheme: attachedDatabase.typeMapping.read(
@@ -1044,25 +938,14 @@ class $PreferencesTableTable extends PreferencesTable
.$converterlocalLibraryLocation
.fromSql(attachedDatabase.typeMapping.read(DriftSqlType.string,
data['${effectivePrefix}local_library_location'])!),
- pipedInstance: attachedDatabase.typeMapping
- .read(DriftSqlType.string, data['${effectivePrefix}piped_instance'])!,
- invidiousInstance: attachedDatabase.typeMapping.read(
- DriftSqlType.string, data['${effectivePrefix}invidious_instance'])!,
themeMode: $PreferencesTableTable.$converterthemeMode.fromSql(
attachedDatabase.typeMapping.read(
DriftSqlType.string, data['${effectivePrefix}theme_mode'])!),
- audioSource: $PreferencesTableTable.$converteraudioSource.fromSql(
- attachedDatabase.typeMapping.read(
- DriftSqlType.string, data['${effectivePrefix}audio_source'])!),
+ audioSourceId: attachedDatabase.typeMapping
+ .read(DriftSqlType.string, data['${effectivePrefix}audio_source_id']),
youtubeClientEngine: $PreferencesTableTable.$converteryoutubeClientEngine
.fromSql(attachedDatabase.typeMapping.read(DriftSqlType.string,
data['${effectivePrefix}youtube_client_engine'])!),
- streamMusicCodec: $PreferencesTableTable.$converterstreamMusicCodec
- .fromSql(attachedDatabase.typeMapping.read(DriftSqlType.string,
- data['${effectivePrefix}stream_music_codec'])!),
- downloadMusicCodec: $PreferencesTableTable.$converterdownloadMusicCodec
- .fromSql(attachedDatabase.typeMapping.read(DriftSqlType.string,
- data['${effectivePrefix}download_music_codec'])!),
discordPresence: attachedDatabase.typeMapping
.read(DriftSqlType.bool, data['${effectivePrefix}discord_presence'])!,
endlessPlayback: attachedDatabase.typeMapping
@@ -1081,9 +964,6 @@ class $PreferencesTableTable extends PreferencesTable
return $PreferencesTableTable(attachedDatabase, alias);
}
- static JsonTypeConverter2
- $converteraudioQuality =
- const EnumNameConverter(SourceQualities.values);
static JsonTypeConverter2
$convertercloseBehavior =
const EnumNameConverter(CloseBehavior.values);
@@ -1101,23 +981,14 @@ class $PreferencesTableTable extends PreferencesTable
const StringListConverter();
static JsonTypeConverter2 $converterthemeMode =
const EnumNameConverter(ThemeMode.values);
- static JsonTypeConverter2 $converteraudioSource =
- const EnumNameConverter(AudioSource.values);
static JsonTypeConverter2
$converteryoutubeClientEngine =
const EnumNameConverter(YoutubeClientEngine.values);
- static JsonTypeConverter2
- $converterstreamMusicCodec =
- const EnumNameConverter(SourceCodecs.values);
- static JsonTypeConverter2
- $converterdownloadMusicCodec =
- const EnumNameConverter(SourceCodecs.values);
}
class PreferencesTableData extends DataClass
implements Insertable {
final int id;
- final SourceQualities audioQuality;
final bool albumColorSync;
final bool amoledDarkTheme;
final bool checkUpdate;
@@ -1133,13 +1004,9 @@ class PreferencesTableData extends DataClass
final SearchMode searchMode;
final String downloadLocation;
final List localLibraryLocation;
- final String pipedInstance;
- final String invidiousInstance;
final ThemeMode themeMode;
- final AudioSource audioSource;
+ final String? audioSourceId;
final YoutubeClientEngine youtubeClientEngine;
- final SourceCodecs streamMusicCodec;
- final SourceCodecs downloadMusicCodec;
final bool discordPresence;
final bool endlessPlayback;
final bool enableConnect;
@@ -1147,7 +1014,6 @@ class PreferencesTableData extends DataClass
final bool cacheMusic;
const PreferencesTableData(
{required this.id,
- required this.audioQuality,
required this.albumColorSync,
required this.amoledDarkTheme,
required this.checkUpdate,
@@ -1163,13 +1029,9 @@ class PreferencesTableData extends DataClass
required this.searchMode,
required this.downloadLocation,
required this.localLibraryLocation,
- required this.pipedInstance,
- required this.invidiousInstance,
required this.themeMode,
- required this.audioSource,
+ this.audioSourceId,
required this.youtubeClientEngine,
- required this.streamMusicCodec,
- required this.downloadMusicCodec,
required this.discordPresence,
required this.endlessPlayback,
required this.enableConnect,
@@ -1179,10 +1041,6 @@ class PreferencesTableData extends DataClass
Map toColumns(bool nullToAbsent) {
final map = {};
map['id'] = Variable(id);
- {
- map['audio_quality'] = Variable(
- $PreferencesTableTable.$converteraudioQuality.toSql(audioQuality));
- }
map['album_color_sync'] = Variable(albumColorSync);
map['amoled_dark_theme'] = Variable(amoledDarkTheme);
map['check_update'] = Variable(checkUpdate);
@@ -1221,31 +1079,18 @@ class PreferencesTableData extends DataClass
.$converterlocalLibraryLocation
.toSql(localLibraryLocation));
}
- map['piped_instance'] = Variable(pipedInstance);
- map['invidious_instance'] = Variable(invidiousInstance);
{
map['theme_mode'] = Variable(
$PreferencesTableTable.$converterthemeMode.toSql(themeMode));
}
- {
- map['audio_source'] = Variable(
- $PreferencesTableTable.$converteraudioSource.toSql(audioSource));
+ if (!nullToAbsent || audioSourceId != null) {
+ map['audio_source_id'] = Variable(audioSourceId);
}
{
map['youtube_client_engine'] = Variable($PreferencesTableTable
.$converteryoutubeClientEngine
.toSql(youtubeClientEngine));
}
- {
- map['stream_music_codec'] = Variable($PreferencesTableTable
- .$converterstreamMusicCodec
- .toSql(streamMusicCodec));
- }
- {
- map['download_music_codec'] = Variable($PreferencesTableTable
- .$converterdownloadMusicCodec
- .toSql(downloadMusicCodec));
- }
map['discord_presence'] = Variable(discordPresence);
map['endless_playback'] = Variable(endlessPlayback);
map['enable_connect'] = Variable(enableConnect);
@@ -1257,7 +1102,6 @@ class PreferencesTableData extends DataClass
PreferencesTableCompanion toCompanion(bool nullToAbsent) {
return PreferencesTableCompanion(
id: Value(id),
- audioQuality: Value(audioQuality),
albumColorSync: Value(albumColorSync),
amoledDarkTheme: Value(amoledDarkTheme),
checkUpdate: Value(checkUpdate),
@@ -1273,13 +1117,11 @@ class PreferencesTableData extends DataClass
searchMode: Value(searchMode),
downloadLocation: Value(downloadLocation),
localLibraryLocation: Value(localLibraryLocation),
- pipedInstance: Value(pipedInstance),
- invidiousInstance: Value(invidiousInstance),
themeMode: Value(themeMode),
- audioSource: Value(audioSource),
+ audioSourceId: audioSourceId == null && nullToAbsent
+ ? const Value.absent()
+ : Value(audioSourceId),
youtubeClientEngine: Value(youtubeClientEngine),
- streamMusicCodec: Value(streamMusicCodec),
- downloadMusicCodec: Value(downloadMusicCodec),
discordPresence: Value(discordPresence),
endlessPlayback: Value(endlessPlayback),
enableConnect: Value(enableConnect),
@@ -1293,8 +1135,6 @@ class PreferencesTableData extends DataClass
serializer ??= driftRuntimeOptions.defaultSerializer;
return PreferencesTableData(
id: serializer.fromJson(json['id']),
- audioQuality: $PreferencesTableTable.$converteraudioQuality
- .fromJson(serializer.fromJson(json['audioQuality'])),
albumColorSync: serializer.fromJson(json['albumColorSync']),
amoledDarkTheme: serializer.fromJson(json['amoledDarkTheme']),
checkUpdate: serializer.fromJson(json['checkUpdate']),
@@ -1316,18 +1156,11 @@ class PreferencesTableData extends DataClass
downloadLocation: serializer.fromJson(json['downloadLocation']),
localLibraryLocation:
serializer.fromJson>(json['localLibraryLocation']),
- pipedInstance: serializer.fromJson(json['pipedInstance']),
- invidiousInstance: serializer.fromJson(json['invidiousInstance']),
themeMode: $PreferencesTableTable.$converterthemeMode
.fromJson(serializer.fromJson(json['themeMode'])),
- audioSource: $PreferencesTableTable.$converteraudioSource
- .fromJson(serializer.fromJson(json['audioSource'])),
+ audioSourceId: serializer.fromJson(json['audioSourceId']),
youtubeClientEngine: $PreferencesTableTable.$converteryoutubeClientEngine
.fromJson(serializer.fromJson(json['youtubeClientEngine'])),
- streamMusicCodec: $PreferencesTableTable.$converterstreamMusicCodec
- .fromJson(serializer.fromJson(json['streamMusicCodec'])),
- downloadMusicCodec: $PreferencesTableTable.$converterdownloadMusicCodec
- .fromJson(serializer.fromJson(json['downloadMusicCodec'])),
discordPresence: serializer.fromJson(json['discordPresence']),
endlessPlayback: serializer.fromJson(json['endlessPlayback']),
enableConnect: serializer.fromJson(json['enableConnect']),
@@ -1340,8 +1173,6 @@ class PreferencesTableData extends DataClass
serializer ??= driftRuntimeOptions.defaultSerializer;
return {
'id': serializer.toJson(id),
- 'audioQuality': serializer.toJson(
- $PreferencesTableTable.$converteraudioQuality.toJson(audioQuality)),
'albumColorSync': serializer.toJson(albumColorSync),
'amoledDarkTheme': serializer.toJson(amoledDarkTheme),
'checkUpdate': serializer.toJson(checkUpdate),
@@ -1362,21 +1193,12 @@ class PreferencesTableData extends DataClass
'downloadLocation': serializer.toJson(downloadLocation),
'localLibraryLocation':
serializer.toJson>(localLibraryLocation),
- 'pipedInstance': serializer.toJson(pipedInstance),
- 'invidiousInstance': serializer.toJson(invidiousInstance),
'themeMode': serializer.toJson(
$PreferencesTableTable.$converterthemeMode.toJson(themeMode)),
- 'audioSource': serializer.toJson(
- $PreferencesTableTable.$converteraudioSource.toJson(audioSource)),
+ 'audioSourceId': serializer.toJson(audioSourceId),
'youtubeClientEngine': serializer.toJson($PreferencesTableTable
.$converteryoutubeClientEngine
.toJson(youtubeClientEngine)),
- 'streamMusicCodec': serializer.toJson($PreferencesTableTable
- .$converterstreamMusicCodec
- .toJson(streamMusicCodec)),
- 'downloadMusicCodec': serializer.toJson($PreferencesTableTable
- .$converterdownloadMusicCodec
- .toJson(downloadMusicCodec)),
'discordPresence': serializer.toJson(discordPresence),
'endlessPlayback': serializer.toJson