Compare commits

...

52 Commits

Author SHA1 Message Date
Kuldeep Singh
1d2a7ac830
Merge 7b85ab1617 into 826c8e4dd6 2025-11-14 17:07:33 +05:45
Kingkor Roy Tirtho
826c8e4dd6
Merge pull request #2846 from KRTirtho/dev
Release 5.1.0
2025-11-14 16:23:10 +06:00
Kingkor Roy Tirtho
4838656dcc chore: fix alternative sources not persisting 2025-11-14 16:17:37 +06:00
Kingkor Roy Tirtho
7ad2066684 website: add AppImage link 2025-11-14 15:07:51 +06:00
Kingkor Roy Tirtho
77c32a27cf chor: idkl 2025-11-14 14:26:46 +06:00
Kingkor Roy Tirtho
89c67e4f89 docs: update readme credits 2025-11-14 14:19:12 +06:00
Kingkor Roy Tirtho
b142928412 chore: remove buffer size limit 2025-11-14 13:38:47 +06:00
Kingkor Roy Tirtho
bf2eb0ffac chore: bump version and generate CHANGELOG 2025-11-14 13:36:20 +06:00
Kingkor Roy Tirtho
3f5291ec92 chore: upgrade hetu_std 2025-11-14 13:09:46 +06:00
Kingkor Roy Tirtho
5ea4df932f cd: add back rpm for x86_64 2025-11-13 16:03:08 +06:00
Kingkor Roy Tirtho
3462e32a6c chore: add arch for install deps 2025-11-13 15:39:58 +06:00
Kingkor Roy Tirtho
a452122302 cd: add appimage support and use fastforge 2025-11-13 15:15:13 +06:00
Kingkor Roy Tirtho
11866d532b chore: remove useless dependencies 2025-11-13 14:57:08 +06:00
Kingkor Roy Tirtho
d843ce9ede chore: upgrade yt plugin 2025-11-12 15:55:07 +06:00
Kingkor Roy Tirtho
6884a131c9 fix(playback): use stream instead of chunked serving of audio bytes 2025-11-12 14:35:06 +06:00
Kingkor Roy Tirtho
bb6f4bd57b feat(android): add 16KB page size support 2025-11-12 11:17:34 +06:00
Kingkor Roy Tirtho
cab09e00ce chore: ignore DB queries in migrations 2025-11-12 10:02:37 +06:00
Kingkor Roy Tirtho
4fae9013a7 fix: download not working in different devices and slow 2025-11-11 10:39:13 +06:00
Kingkor Roy Tirtho
834445eda3 chore: remove jsf as arm doesn't build 2025-11-10 13:07:58 +06:00
Rahul Sahani
f10a3d4976
feat(queue): add multi-select and bulk actions to queue (#2839)
* feat(queue): add multi-select and bulk actions to queue

- Add selection mode to PlayerQueue with long-press to select
- Disable inner navigation (title/artist) when selecting via TrackTile
- Show checkboxes only in selection mode
- Add selection AppBar behavior and bottom-sheet menu with: Select all, Add to playlist, Remove selected, Cancel
- Reuse existing PlaylistAddTrackDialog for bulk add
- Hide drag handle while in selection mode

Closes: # (implement multi-select queue feature)

* chore: update .gitignore to include .vscode and modify signing configurations back to default in build.gradle

* chore: add VS Code configuration files

* chore: update dependencies in pubspec.lock

* chore: update pubspec.lock to reflect dependency changes and version updates

* chore: fix replace material widgets with shadcn widgets

---------

Co-authored-by: Kingkor Roy Tirtho <krtirtho@gmail.com>
2025-11-10 10:36:10 +06:00
Kingkor Roy Tirtho
3209c75144 fix: downloaded tracks are not tagged with metadata 2025-11-08 15:49:37 +06:00
Kingkor Roy Tirtho
700a69fcd1
Merge pull request #2840 from KRTirtho/audio-source-extension
feat: add audio source plugin support
2025-11-08 14:14:06 +06:00
Kingkor Roy Tirtho
d2dd60aa5c chore: update YoutubeExplode to v3 2025-11-08 13:48:50 +06:00
Kingkor Roy Tirtho
fda2257119 feat: add default plugin loading capability 2025-11-07 22:51:48 +06:00
Kingkor Roy Tirtho
7c632c8f06 cd: remove unnecessary stuff for android build 2025-11-07 21:56:03 +06:00
Kingkor Roy Tirtho
a012a8f3af chore: fix unique index on source_match_table causing failure on insert 2025-11-07 20:28:09 +06:00
Kingkor Roy Tirtho
64f937bd14 chore: remove useless appbundle build 2025-11-07 18:59:55 +06:00
Kingkor Roy Tirtho
d1b73dbb1c feat: add NewPipe support for desktop platforms 2025-11-07 18:48:18 +06:00
Kingkor Roy Tirtho
e1fa9efa14 fix: selection preset quality returning null 2025-11-04 13:45:23 +06:00
Kingkor Roy Tirtho
6272f376ea fix: quality preset initialization fails and audio source auth 2025-11-04 12:02:10 +06:00
Kingkor Roy Tirtho
4b5108e54e fix: streaming not working 2025-11-03 21:27:06 +06:00
Kingkor Roy Tirtho
6311831902 feat: move away from track source query and preferences audio quality and codec 2025-11-03 19:33:47 +06:00
Kingkor Roy Tirtho
99a84aa6dc chore: create sourced track from active audio source plugin 2025-11-03 13:32:48 +06:00
Kingkor Roy Tirtho
3bc296cf22 feat: add setting default audio source support 2025-10-25 23:23:27 +06:00
Kingkor Roy Tirtho
f6d9d64b7d feat(plugins): filter plugins by abilities in plugins page and show abilities as badge 2025-10-23 08:57:45 +06:00
Kingkor Roy Tirtho
439de5d7f7 feat: add plugin audio source models and api service 2025-10-19 13:48:53 +06:00
Kingkor Roy Tirtho
88699e9a3b fix: jiosaavn not working due to json signature change 2025-10-17 11:26:58 +06:00
Kingkor Roy Tirtho
348c2e931b fix: upgrade NewPipeExtractor to avoid unplayable streams 2025-10-17 10:27:00 +06:00
Kingkor Roy Tirtho
973ca20c8e fix(playback): play next not working 2025-09-20 20:25:51 +06:00
Kingkor Roy Tirtho
7d849b1430 fix: change plugin download directory to application support 2025-09-20 18:01:42 +06:00
Kingkor Roy Tirtho
e5150515f3 chore: cache dab music match source 2025-09-20 17:54:08 +06:00
Kingkor Roy Tirtho
66848c78c7 chore: add dab music option on getting started page and audio source quality label 2025-09-19 23:55:38 +06:00
Kingkor Roy Tirtho
3e34bc4be6 chore: streaming issue for mp3 2025-09-19 21:40:26 +06:00
Kingkor Roy Tirtho
cecb687592 feat(playback): add uncompressed flac playback support 2025-09-19 11:53:36 +06:00
Kingkor Roy Tirtho
e8a54d3209 feat(playback): add dab music source 2025-09-19 10:31:49 +06:00
Kingkor Roy Tirtho
ca6924f5a9 feat: show plugin source and set the only plugin as default if no plugin is there 2025-09-18 23:28:56 +06:00
Kingkor Roy Tirtho
0e48b7a337 website: update logo 2025-09-12 00:38:35 +06:00
Kingkor Roy Tirtho
60fbf66639 website: use locked version of astro-pagefine 2025-09-12 00:26:56 +06:00
Kingkor Roy Tirtho
97370712bc website: add back download buttons 2025-09-12 00:19:00 +06:00
Kingkor Roy Tirtho
c36e819ba3 Merge branch 'dev' into website 2025-09-12 00:11:03 +06:00
Kingkor Roy Tirtho
61d34963fa website: ads not showing up 2025-08-15 21:39:05 +06:00
Kuldeep Singh
7b85ab1617
Create app_pa.arb
Punjabi (pa) translation
2025-01-02 17:46:20 +05:30
236 changed files with 15909 additions and 7927 deletions

25
.github/Dockerfile vendored
View File

@ -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" ]

View File

@ -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 }}

View File

@ -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'}}

1
.gitignore vendored
View File

@ -9,6 +9,7 @@
.history
.svn/
# IntelliJ related
*.iml
*.ipr

View File

@ -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

View File

@ -2,7 +2,7 @@
<img width="600" src="assets/branding/spotube_banner.png" alt="Spotube Logo">
A cross-platform extensible open-source music streaming platform.<br>
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.
</details>
<div align="center"><h4>© Copyright Spotube 2025</h4></div>

1
android/.gitignore vendored
View File

@ -11,3 +11,4 @@ GeneratedPluginRegistrant.java
key.properties
**/*.keystore
**/*.jks
.kotlin

View File

@ -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

View File

@ -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'

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -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");
}
}

View File

@ -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
""",
);
}

View File

@ -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");
}
}

View File

@ -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
""",
);

View File

@ -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(

View File

@ -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;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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<AssetGenImage> 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<AssetGenImage> get values => [invidious, jiosaavn, songlinkTransparent];
List<String> 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<String> 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<String> 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<String> 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;
}

View File

@ -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._();

View File

@ -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<void> {
const AboutSpotubeRoute({List<_i41.PageRouteInfo>? children})
: super(
AboutSpotubeRoute.name,
initialChildren: children,
);
: super(AboutSpotubeRoute.name, initialChildren: children);
static const String name = 'AboutSpotubeRoute';
@ -84,11 +82,7 @@ class AlbumRoute extends _i41.PageRouteInfo<AlbumRouteArgs> {
List<_i41.PageRouteInfo>? children,
}) : super(
AlbumRoute.name,
args: AlbumRouteArgs(
key: key,
id: id,
album: album,
),
args: AlbumRouteArgs(key: key, id: id, album: album),
rawPathParams: {'id': id},
initialChildren: children,
);
@ -99,21 +93,13 @@ class AlbumRoute extends _i41.PageRouteInfo<AlbumRouteArgs> {
name,
builder: (data) {
final args = data.argsAs<AlbumRouteArgs>();
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;
@ -136,10 +122,7 @@ class ArtistRoute extends _i41.PageRouteInfo<ArtistRouteArgs> {
List<_i41.PageRouteInfo>? children,
}) : super(
ArtistRoute.name,
args: ArtistRouteArgs(
artistId: artistId,
key: key,
),
args: ArtistRouteArgs(artistId: artistId, key: key),
rawPathParams: {'id': artistId},
initialChildren: children,
);
@ -151,20 +134,15 @@ class ArtistRoute extends _i41.PageRouteInfo<ArtistRouteArgs> {
builder: (data) {
final pathParams = data.inheritedPathParams;
final args = data.argsAs<ArtistRouteArgs>(
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<void> {
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<void> {
/// [_i5.ConnectControlPage]
class ConnectControlRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i6.ConnectPage]
class ConnectRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i7.GettingStartedPage]
class GettingStartedRoute extends _i41.PageRouteInfo<void> {
const GettingStartedRoute({List<_i41.PageRouteInfo>? children})
: super(
GettingStartedRoute.name,
initialChildren: children,
);
: super(GettingStartedRoute.name, initialChildren: children);
static const String name = 'GettingStartedRoute';
@ -310,10 +276,7 @@ class HomeBrowseSectionItemsRouteArgs {
/// [_i9.HomePage]
class HomeRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i10.LastFMLoginPage]
class LastFMLoginRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i11.LibraryPage]
class LibraryRoute extends _i41.PageRouteInfo<void> {
const LibraryRoute({List<_i41.PageRouteInfo>? children})
: super(
LibraryRoute.name,
initialChildren: children,
);
: super(LibraryRoute.name, initialChildren: children);
static const String name = 'LibraryRoute';
@ -372,10 +329,7 @@ class LikedPlaylistRoute extends _i41.PageRouteInfo<LikedPlaylistRouteArgs> {
List<_i41.PageRouteInfo>? children,
}) : super(
LikedPlaylistRoute.name,
args: LikedPlaylistRouteArgs(
key: key,
playlist: playlist,
),
args: LikedPlaylistRouteArgs(key: key, playlist: playlist),
initialChildren: children,
);
@ -385,19 +339,13 @@ class LikedPlaylistRoute extends _i41.PageRouteInfo<LikedPlaylistRouteArgs> {
name,
builder: (data) {
final args = data.argsAs<LikedPlaylistRouteArgs>();
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;
@ -471,10 +419,7 @@ class LocalLibraryRouteArgs {
/// [_i14.LogsPage]
class LogsRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i15.LyricsPage]
class LyricsRoute extends _i41.PageRouteInfo<void> {
const LyricsRoute({List<_i41.PageRouteInfo>? children})
: super(
LyricsRoute.name,
initialChildren: children,
);
: super(LyricsRoute.name, initialChildren: children);
static const String name = 'LyricsRoute';
@ -514,10 +456,7 @@ class MiniLyricsRoute extends _i41.PageRouteInfo<MiniLyricsRouteArgs> {
List<_i41.PageRouteInfo>? children,
}) : super(
MiniLyricsRoute.name,
args: MiniLyricsRouteArgs(
key: key,
prevSize: prevSize,
),
args: MiniLyricsRouteArgs(key: key, prevSize: prevSize),
initialChildren: children,
);
@ -527,19 +466,13 @@ class MiniLyricsRoute extends _i41.PageRouteInfo<MiniLyricsRouteArgs> {
name,
builder: (data) {
final args = data.argsAs<MiniLyricsRouteArgs>();
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<void> {
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<void> {
/// [_i18.PlayerQueuePage]
class PlayerQueueRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i19.PlayerTrackSourcesPage]
class PlayerTrackSourcesRoute extends _i41.PageRouteInfo<void> {
const PlayerTrackSourcesRoute({List<_i41.PageRouteInfo>? children})
: super(
PlayerTrackSourcesRoute.name,
initialChildren: children,
);
: super(PlayerTrackSourcesRoute.name, initialChildren: children);
static const String name = 'PlayerTrackSourcesRoute';
@ -618,11 +542,7 @@ class PlaylistRoute extends _i41.PageRouteInfo<PlaylistRouteArgs> {
List<_i41.PageRouteInfo>? children,
}) : super(
PlaylistRoute.name,
args: PlaylistRouteArgs(
key: key,
id: id,
playlist: playlist,
),
args: PlaylistRouteArgs(key: key, id: id, playlist: playlist),
rawPathParams: {'id': id},
initialChildren: children,
);
@ -643,11 +563,7 @@ class PlaylistRoute extends _i41.PageRouteInfo<PlaylistRouteArgs> {
}
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<void> {
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<void> {
/// [_i22.RootAppPage]
class RootAppRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i23.SearchPage]
class SearchRoute extends _i41.PageRouteInfo<void> {
const SearchRoute({List<_i41.PageRouteInfo>? children})
: super(
SearchRoute.name,
initialChildren: children,
);
: super(SearchRoute.name, initialChildren: children);
static const String name = 'SearchRoute';
@ -775,10 +682,7 @@ class SettingsMetadataProviderFormRouteArgs {
/// [_i25.SettingsMetadataProviderPage]
class SettingsMetadataProviderRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i26.SettingsPage]
class SettingsRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i27.SettingsScrobblingPage]
class SettingsScrobblingRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i28.StatsAlbumsPage]
class StatsAlbumsRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i29.StatsArtistsPage]
class StatsArtistsRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i30.StatsMinutesPage]
class StatsMinutesRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i31.StatsPage]
class StatsRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i32.StatsPlaylistsPage]
class StatsPlaylistsRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i33.StatsStreamFeesPage]
class StatsStreamFeesRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i34.StatsStreamsPage]
class StatsStreamsRoute extends _i41.PageRouteInfo<void> {
const StatsStreamsRoute({List<_i41.PageRouteInfo>? children})
: super(
StatsStreamsRoute.name,
initialChildren: children,
);
: super(StatsStreamsRoute.name, initialChildren: children);
static const String name = 'StatsStreamsRoute';
@ -970,10 +847,7 @@ class TrackRoute extends _i41.PageRouteInfo<TrackRouteArgs> {
List<_i41.PageRouteInfo>? children,
}) : super(
TrackRoute.name,
args: TrackRouteArgs(
key: key,
trackId: trackId,
),
args: TrackRouteArgs(key: key, trackId: trackId),
rawPathParams: {'id': trackId},
initialChildren: children,
);
@ -985,20 +859,15 @@ class TrackRoute extends _i41.PageRouteInfo<TrackRouteArgs> {
builder: (data) {
final pathParams = data.inheritedPathParams;
final args = data.argsAs<TrackRouteArgs>(
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<void> {
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<void> {
/// [_i37.UserArtistsPage]
class UserArtistsRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i38.UserDownloadsPage]
class UserDownloadsRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i39.UserLocalLibraryPage]
class UserLocalLibraryRoute extends _i41.PageRouteInfo<void> {
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<void> {
/// [_i40.UserPlaylistsPage]
class UserPlaylistsRoute extends _i41.PageRouteInfo<void> {
const UserPlaylistsRoute({List<_i41.PageRouteInfo>? children})
: super(
UserPlaylistsRoute.name,
initialChildren: children,
);
: super(UserPlaylistsRoute.name, initialChildren: children);
static const String name = 'UserPlaylistsRoute';

View File

@ -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;

View File

@ -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),
),
],
),
);
}
}

View File

@ -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;
},

View File

@ -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 ?? "",

View File

@ -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<bool>(
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);
},
);

View File

@ -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<SpotubeFullTrackObject>().toList();
final confirmed = audioSource == AudioSource.piped ||
(await showDialog<bool>(
final confirmed = await showDialog<bool>(
context: context,
builder: (context) {
return const ConfirmDownloadDialog();
},
) ??
false);
false;
if (confirmed != true) return;
downloader.batchAddToQueue(fullTrackObjects);
downloader.addAllToQueue(fullTrackObjects);
notifier.deselectAllTracks();
if (!context.mounted) return;
showToastForAction(context, action, fullTrackObjects.length);

View File

@ -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);
? 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?.value,
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,
);

View File

@ -39,6 +39,7 @@ class TrackTile extends HookConsumerWidget {
final int? index;
final SpotubeTrackObject track;
final bool selected;
final bool selectionMode;
final ValueChanged<bool?>? onChanged;
final Future<void> 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,6 +230,8 @@ class TrackTile extends HookConsumerWidget {
children: [
Expanded(
flex: 6,
child: AbsorbPointer(
absorbing: selectionMode,
child: switch (track) {
SpotubeLocalTrackObject() => Text(
track.name,
@ -237,7 +247,9 @@ class TrackTile extends HookConsumerWidget {
padding: (context, states, value) =>
EdgeInsets.zero,
),
onPressed: () {
onPressed: effectiveSelection
? null
: () {
context
.navigateTo(TrackRoute(trackId: track.id));
},
@ -252,6 +264,7 @@ class TrackTile extends HookConsumerWidget {
),
},
),
),
if (constrains.mdAndUp) ...[
const SizedBox(width: 8),
Expanded(
@ -288,9 +301,13 @@ class TrackTile extends HookConsumerWidget {
: ClipRect(
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 40),
child: AbsorbPointer(
absorbing: effectiveSelection,
child: ArtistLink(
artists: track.artists,
onOverflowArtistClick: () {
onOverflowArtistClick: effectiveSelection
? () {}
: () {
context.navigateTo(
TrackRoute(trackId: track.id),
);
@ -299,6 +316,7 @@ class TrackTile extends HookConsumerWidget {
),
),
),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [

168
lib/extensions/dio.dart Normal file
View File

@ -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<Response> chunkDownload(
String urlPath,
dynamic savePath, {
ProgressCallback? onReceiveProgress,
Map<String, dynamic>? 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<ResponseBody>(
urlPath,
options: Options(
responseType: ResponseType.stream,
),
queryParameters: queryParameters,
cancelToken: cancelToken,
);
final len = int.tryParse(resp.headers[lengthHeader]?.first ?? '');
if (len == null || len <= 1) {
// cant 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<ResponseBody>(
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;
}
}
}

View File

@ -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."
}

View File

@ -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 ভিত্তিক ট্র্যাক ম্যাচিং।"
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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 आधारित ट्रैक मिलान।"
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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ベースのトラックマッチング。"
}

View File

@ -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-ის მიხედვით."
}

View File

@ -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 기반으로 정확한 트랙 매칭을 지원합니다."
}

View File

@ -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-मा आधारित सटीक ट्र्याक मिलान।"
}

View File

@ -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"
}

405
lib/l10n/app_pa.arb Normal file
View File

@ -0,0 +1,405 @@
{
"guest": "ਮਹਿਮਾਨ",
"browse": "ਬ੍ਰਾਊਜ਼ ਕਰੋ",
"search": "ਖੋਜੋ",
"library": "ਲਾਇਬ੍ਰੇਰੀ",
"lyrics": "ਗੀਤਾਂ ਦੇ ਬੋਲ",
"settings": "ਸੈਟਿੰਗਾਂ",
"genre_categories_filter": "ਸ਼੍ਰੇਣੀਆਂ ਜਾਂ ਸ਼ੈਲੀਆਂ ਨੂੰ ਛਾਣੋ...",
"genre": "ਸ਼ੈਲੀ",
"personalized": "ਵਿਅਕਤੀਗਤ",
"featured": "ਵਿਸ਼ੇਸ਼ ਰੂਪ ਨਾਲ ਪ੍ਰਦਰਸ਼ਿਤ",
"new_releases": "ਨਵੀਂ ਰਿਲੀਜ਼",
"songs": "ਗੀਤ",
"playing_track": "{track} ਚੱਲ ਰਿਹਾ ਹੈ",
"queue_clear_alert": "ਇਹ ਮੌਜੂਦਾ ਕਤਾਰ ਨੂੰ ਸਾਫ਼ ਕਰ ਦੇਵੇਗਾ। {track_length} ਟ੍ਰੈਕ ਹਟਾ ਦਿੱਤੇ ਜਾਣਗੇ\nਕੀ ਤੁਸੀਂ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?",
"load_more": "ਹੋਰ ਲੋਡ ਕਰੋ",
"playlists": "ਪਲੇਸੂਚੀ",
"artists": "ਕਲਾਕਾਰ",
"albums": "ਐਲਬਮ",
"tracks": "ਟ੍ਰੈਕ",
"downloads": "ਡਾਊਨਲੋਡ",
"filter_playlists": "ਆਪਣੀਆਂ ਪਲੇਸੂਚੀਆਂ ਨੂੰ ਛਾਣੋ...",
"liked_tracks": "ਪਸੰਦੀਦਾ ਟ੍ਰੈਕ",
"liked_tracks_description": "ਤੁਹਾਡੇ ਸਾਰੇ ਪਸੰਦੀਦਾ ਟ੍ਰੈਕ",
"create_playlist": "ਪਲੇਸੂਚੀ ਬਣਾਉ",
"create_a_playlist": "ਇੱਕ ਪਲੇਸੂਚੀ ਬਣਾਉ",
"create": "ਬਣਾਉ",
"cancel": "ਰੱਦ ਕਰੋ",
"playlist_name": "ਪਲੇਸੂਚੀ ਦਾ ਨਾਮ",
"name_of_playlist": "ਪਲੇਸੂਚੀ ਦਾ ਨਾਮ",
"description": "ਵੇਰਵਾ",
"public": "ਜਨਤਕ",
"collaborative": "ਸਹਿਯੋਗੀ",
"search_local_tracks": "ਸਥਾਨਕ ਟ੍ਰੈਕ ਖੋਜੋ...",
"play": "ਚਲਾਉ",
"delete": "ਹਟਾਉ",
"none": "ਕੋਈ ਨਹੀਂ",
"sort_a_z": "A-Z ਦਿਖਾਉ",
"sort_z_a": "Z-A ਦਿਖਾਉ",
"sort_artist": "ਕਲਾਕਾਰ ਅਨੁਸਾਰ ਦਿਖਾਉ",
"sort_album": "ਐਲਬਮ ਅਨੁਸਾਰ ਦਿਖਾਉ",
"sort_tracks": "ਟ੍ਰੈਕ ਅਨੁਸਾਰ ਦਿਖਾਉ",
"currently_downloading": "ਹੁਣ ਡਾਊਨਲੋਡ ਹੋ ਰਿਹਾ ਹੈ ({tracks_length})",
"cancel_all": "ਸਾਰਿਆਂ ਨੂੰ ਰੱਦ ਕਰੋ",
"filter_artist": "ਕਲਾਕਾਰ ਨੂੰ ਛਾਣੋ...",
"followers": "{followers} ਫ਼ਾਲੋਅਰ",
"add_artist_to_blacklist": "ਕਲਾਕਾਰ ਨੂੰ ਕਾਲੀਸੂਚੀ ਵਿੱਚ ਜੋੜੋ",
"top_tracks": "ਚੋਟੀ ਦਾ ਟ੍ਰੈਕ",
"fans_also_like": "ਫੈਨਸ ਨੂੰ ਇਹ ਵੀ ਪਸੰਦ ਹੈ",
"loading": "ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ...",
"artist": "ਕਲਾਕਾਰ",
"blacklisted": "ਕਾਲੀਸੂਚੀ ਵਿੱਚ ਹੈ",
"following": "ਫ਼ਾਲੋ ਕਰ ਰਿਹਾ ਹੈ",
"follow": "ਫ਼ਾਲੋ ਕਰੋ",
"artist_url_copied": "ਕਲਾਕਾਰ ਯੂਆਰਐਲ ਕਲਿੱਪਬੋਰਡ ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ",
"added_to_queue": "{tracks} ਟ੍ਰੈਕ ਕਤਾਰ ਵਿੱਚ ਜੋੜੇ ਗਏ",
"filter_albums": "ਐਲਬਮਾਂ ਨੂੰ ਛਾਣੋ...",
"synced": "ਸਿੰਕ ਕੀਤਾ ਗਿਆ",
"plain": "ਸਾਦਾ",
"shuffle": "ਸ਼ਫਲ",
"search_tracks": "ਟ੍ਰੈਕ ਖੋਜੋ...",
"released": "ਜਾਰੀ ਹੋਇਆ",
"error": "ਤਰੁੱਟੀ {error}",
"title": "ਸਿਰਲੇਖ",
"time": "ਸਮਾਂ",
"more_actions": "ਹੋਰ ਕਾਰਵਾਈ",
"download_count": "ਡਾਊਨਲੋਡ ({count})",
"add_count_to_playlist": "({count}) ਨੂੰ ਪਲੇਸੂਚੀ ਵਿੱਚ ਜੋੜੋ",
"add_count_to_queue": "({count}) ਨੂੰ ਕਤਾਰ ਵਿੱਚ ਜੋੜੋ",
"play_count_next": "({count}) ਅਗਲਾ ਚਲਾਉ",
"album": "ਐਲਬਮ",
"copied_to_clipboard": "{data} ਕਲਿੱਪਬੋਰਡ ਉੱਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ",
"add_to_following_playlists": "{track} ਨੂੰ ਹੇਠ ਲਿਖੀ ਪਲੇਸੂਚੀ ਵਿੱਚ ਜੋੜੋ",
"add": "ਜੋੜੋ",
"added_track_to_queue": "{track} ਨੂੰ ਕਤਾਰ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ",
"add_to_queue": "ਕਤਾਰ ਵਿੱਚ ਜੋੜੋ",
"track_will_play_next": "{track} ਅਗਲਾ ਚਲਾਉ",
"play_next": "ਅਗਲਾ ਚਲਾਉ",
"removed_track_from_queue": "{track} ਨੂੰ ਕਤਾਰ ਵਿੱਚੋਂ ਹਟਾਇਆ ਗਿਆ",
"remove_from_queue": "ਕਤਾਰ ਵਿੱਚ ਹਟਾਉ",
"remove_from_favorites": "ਪਸੰਦੀਦਾ ਵਿੱਚੋਂ ਹਟਾਉ",
"save_as_favorite": "ਪਸੰਦੀਦਾ ਵਜੋਂ ਸੰਭਾਲੋ",
"add_to_playlist": "ਪਲੇਸੂਚੀ ਵਿੱਚ ਜੋੜੋ",
"remove_from_playlist": "ਪਲੇਸੂਚੀ ਵਿੱਚੋਂ ਹਟਾਉ",
"add_to_blacklist": "ਕਾਲੀਸੂਚੀ ਵਿੱਚ ਜੋੜੋ",
"remove_from_blacklist": "ਕਾਲੀਸੂਚੀ ਵਿੱਚੋਂ ਹਟਾਉ",
"share": "ਸਾਂਝਾ ਕਰੋ",
"mini_player": "ਮਿੰਨੀ ਪਲੇਅਰ",
"slide_to_seek": "ਅੱਗੇ ਜਾਂ ਪਿੱਛੇ ਖੋਜਣ ਲਈ ਸਲਾਈਡ ਕਰੋ",
"shuffle_playlist": "ਪਲੇਸੂਚੀ ਸ਼ਫਲ ਕਰੋ",
"unshuffle_playlist": "ਪਲੇਸੂਚੀ ਅਣਸ਼ਫਲ ਕਰੋ",
"previous_track": "ਪਿਛਲਾ ਟ੍ਰੈਕ",
"next_track": "ਅਗਲਾ ਟ੍ਰੈਕ",
"pause_playback": "ਪਲੇਬੈਕ ਰੋਕੋ",
"resume_playback": "ਪਲੇਬੈਕ ਚਲਾਉ",
"loop_track": "ਲੂਪ ਟ੍ਰੈਕ",
"repeat_playlist": "ਪਲੇਸੂਚੀ ਦੁਹਰਾਉ",
"queue": "ਕਤਾਰ",
"alternative_track_sources": "ਵਿਕਲਪਕ ਟ੍ਰੈਕ ਸਰੋਤ",
"download_track": "ਟ੍ਰੈਕ ਡਾਊਨਲੋਡ ਕਰੋ",
"tracks_in_queue": "{tracks} ਟ੍ਰੈਕ ਕਤਾਰ ਵਿੱਚ ਹਨ",
"clear_all": "ਸਾਰੇ ਹਟਾਉ",
"show_hide_ui_on_hover": "ਹਵਰ ਉੱਤੇ ਯੂਆਈ ਦਿਖਾਉ/ਛਿਪਾਉ",
"always_on_top": "ਹਮੇਸ਼ਾ ਉੱਤੇ ਹੋਵੇ",
"exit_mini_player": "ਮਿੰਨੀ ਪਲੇਅਰ ਤੋਂ ਬਾਹਰ ਨਿਕਲੋ",
"download_location": "ਡਾਊਨਲੋਡ ਸਥਾਨ",
"account": "ਖ਼ਾਤਾ",
"login_with_spotify": "ਆਪਣੇ ਸਪੋਟਫਾਈ ਖ਼ਾਤੇ ਨਾਲ ਦਾਖ਼ਲ ਹੋਵੋ",
"connect_with_spotify": "ਸਪੋਟਫਾਈ ਨਾਲ ਕਨੈਕਟ ਕਰੋ",
"logout": "ਵਿਦਾਈ ਲਵੋ",
"logout_of_this_account": "ਇਸ ਖ਼ਾਤੇ ਤੋਂ ਵਿਦਾਈ ਲਵੋ",
"language_region": "ਭਾਸ਼ਾ ਅਤੇ ਖੇਤਰ",
"language": "ਭਾਸ਼ਾ",
"system_default": "ਸਿਸਟਮ ਡਿਫਾਲਟ",
"market_place_region": "ਮਾਰਕਿਟਪਲੇਸ ਖੇਤਰ",
"recommendation_country": "ਸੁਝਾਇਆ ਗਿਆ ਦੇਸ਼",
"appearance": "ਦਿੱਖ",
"layout_mode": "ਲੇਆਊਟ ਮੋਡ",
"override_layout_settings": "ਓਵਰਰਾਈਡ ਰਿਸਪਾਂਸਿਵ ਲੇਆਊਟ ਮੋਡ ਸੈਟਿੰਗ",
"adaptive": "ਅਨੁਕੂਲ",
"compact": "ਕੰਪੈਕਟ",
"extended": "ਵਿਸਤ੍ਰਿਤ",
"theme": "ਥੀਮ",
"dark": "ਗੂੜ੍ਹਾ",
"light": "ਚਾਨਣ",
"system": "ਸਿਸਟਮ",
"accent_color": "ਅੱਖਰਸ਼ੈਲੀ ਦਾ ਰੰਗ",
"sync_album_color": "ਐਲਬਮ ਦਾ ਰੰਗ ਸਿੰਕ ਕਰੋ",
"sync_album_color_description": "ਐਲਬਮ ਕਲਾ ਦਾ ਪ੍ਰਾਇਮਰੀ ਰੰਗ ਇੱਕ ਲਹਿਜ਼ੇ ਦੇ ਰੰਗ ਵਜੋਂ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ",
"playback": "ਪਲੇਬੈਕ",
"audio_quality": "ਆਡੀਉ ਗੁਣਵੱਤਾ",
"high": "ਉੱਚ",
"low": "ਨਿਮਨ",
"pre_download_play": "ਪਹਿਲਾਂ ਡਾਊਨਲੋਡ ਕਰੋ ਅਤੇ ਚਲਾਉ",
"pre_download_play_description": "ਸਟ੍ਰੀਮਿੰਗ ਆਡੀਓ ਦੀ ਬਜਾਏ ਬਾਈਟ ਡਾਊਨਲੋਡ ਕਰੋ ਅਤੇ ਚਲਾਓ (ਉੱਚ ਬੈਂਡਵਿਡਥ ਉਪਭੋਗਤਾਵਾਂ ਲਈ ਸਿਫ਼ਾਰਿਸ਼ ਕੀਤੀ ਗਈ ਹੈ)",
"skip_non_music": "ਗੀਤ ਦੇ ਇਲਾਵਾ ਸੈਗਮੈਂਟਾਂ ਨੂੰ ਛੱਡੋ (ਸਪਾਂਸਰਬਲਾਕ)",
"blacklist_description": "ਕਾਲੀਸੂਚੀ ਵਿੱਚ ਸ਼ਾਮਲ ਟ੍ਰੈਕ ਅਤੇ ਕਲਾਕਾਰ",
"wait_for_download_to_finish": "ਵਰਤਮਾਨ ਡਾਊਨਲੋਡ ਸਮਾਪਤ ਹੋਣ ਤੱਕ ਇੰਤਜ਼ਾਰ ਕਰੋ",
"desktop": "ਡੈਸਕਟਾਪ",
"close_behavior": "ਬੰਦ ਕਰਨ ਦਾ ਵਿਵਹਾਰ",
"close": "ਬੰਦ ਕਰੋ",
"minimize_to_tray": "ਟ੍ਰੇ ਵਿੱਚ ਘੱਟ ਕਰੋ",
"show_tray_icon": "ਸਿਸਟਮ ਟ੍ਰੇ ਆਈਕਨ ਦਿਖਾਉ",
"about": "ਬਾਬਤ",
"u_love_spotube": "ਅਸੀਂ ਜਾਣਦੇ ਹਾਂ ਕਿ ਤੁਸੀਂ Spotube ਨੂੰ ਪਿਆਰ ਕਰਦੇ ਹੋ",
"check_for_updates": "ਅੱਪਡੇਟ ਲਈ ਜਾਂਚ ਕਰੋ",
"about_spotube": "Spotube ਦੇ ਬਾਰੇ",
"blacklist": "ਕਾਲੀਸੂਚੀ",
"please_sponsor": "ਕਿਰਪਾ ਕਰਕੇ ਸਪਾਂਸਰ / ਦਾਨ ਕਰੋ",
"spotube_description": "Spotube, ਇੱਕ ਹਲਕਾ, ਸਾਰੇ ਪਲੇਟਫਾਰਮਾਂ ਤੇ ਚੱਲਣ ਵਾਲਾ, ਮੁਫ਼ਤ ਸਪੋਟੀਫਾਈ ਕਲਾਇੰਟ",
"version": "ਸੰਸਕਰਨ",
"build_number": "ਬਿਲਡ ਨੰਬਰ",
"founder": "ਸੰਸਥਾਪਕ",
"repository": "ਭੰਡਾਰ",
"bug_issues": "ਦਿੱਕਤਾਂ+ਮੁੱਦੇ",
"made_with": "ਬੰਗਲਾਦੇਸ਼🇧🇩 ਵਿੱਚ ਦਿਲ ਨਾਲ ਬਣਾਇਆ ਗਿਆ",
"kingkor_roy_tirtho": "ਕਿੰਗਕੋਰ ਰੌਏ ਤਿਰਥੋ",
"copyright": "© 2021-{current_year} ਕਿੰਗਕੋਰ ਰੌਏ ਤਿਰਥੋ",
"license": "ਲਸੰਸ",
"add_spotify_credentials": "ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਸਪੋਟੀਫਾਈ ਕਰੇਡੈਂਸ਼ੀਅਲ ਜੋੜੋ",
"credentials_will_not_be_shared_disclaimer": "ਚਿੰਤਾ ਨਾ ਕਰੋ, ਤੁਹਾਡੇ ਕਰੇਡੈਂਸ਼ੀਅਲ ਕਿਸੇ ਵੀ ਤਰ੍ਹਾਂ ਨਾਲ ਇਕੱਠੇ ਜਾਂ ਸਾਂਝੇ ਨਹੀਂ ਕੀਤੇ ਜਾਣਗੇ",
"know_how_to_login": "ਇਸਨੂੰ ਕਿਵੇਂ ਕਰਨਾ ਹੈ, ਨਹੀਂ ਪਤਾ?",
"follow_step_by_step_guide": "ਕਦਮ ਨਾਲ ਕਦਮ ਗਾਈਡ ਦੇ ਨਾਲ ਚੱਲੋ",
"spotify_cookie": "ਸਪੋਟੀਫਾਈ {name} ਕੁਕੀ",
"cookie_name_cookie": "{name} ਕੁਕੀ",
"fill_in_all_fields": "ਕ੍ਰਿਪਾ ਸਾਰੇ ਫੀਲਡ ਭਰੋ",
"submit": "ਸਪੁਰਦ",
"exit": "ਬਾਹਰ ਨਿਕਲੋ",
"previous": "ਪਿਛਲਾ",
"next": "ਅਗਲਾ",
"done": "ਹੋ ਗਿਆ",
"step_1": "ਚਰਣ 1",
"first_go_to": "ਪਹਿਲਾਂ, ਜਾਉ",
"login_if_not_logged_in": "ਅਤੇ ਜੇਕਰ ਤੁਸੀਂ ਦਾਖ਼ਲ ਨਹੀਂ ਹੋਏ ਹੋ ਤਾਂ ਦਾਖ਼ਲ ਹੋਵੋ / ਸਾਈਨਅੱਪ ਕਰੋ",
"step_2": "ਚਰਣ 2",
"step_2_steps": "1. ਇੱਕ ਵਾਰ ਜਦੋਂ ਤੁਸੀਂ ਦਾਖ਼ਲ ਹੋ ਜਾਂਦੇ ਹੋ, ਤਾਂ F12 ਦਬਾਓ ਜਾਂ ਮਾਊਸ ਸੱਜਾ ਕਲਿੱਕ ਕਰੋ > ਜਾਂਚ ਕਰੋ ਤਾਂ ਕਿ ਬ੍ਰਾਊਜ਼ਰ DevTools ਖੁੱਲ੍ਹ ਜਾਵੇ।\n2. ਫਿਰ ਬ੍ਰਾਊਜ਼ਰ ਦੇ \"ਐਪਲੀਕੇਸ਼ਨ\" ਟੈਬ (Chrome, Edge, Brave ਆਦਿ) ਜਾਂ \"ਸਟੋਰੇਜ\" ਟੈਬ (Firefox, Palemoon ਆਦਿ) ਵਿੱਚ ਜਾਉ\n3. \"ਕੁਕੀਜ\" ਅਨੁਭਾਗ ਵਿੱਚ ਜਾਉ ਫਿਰ \"https: //accounts.spotify.com\" ਉਪ-ਅਨੁਭਾਗ ਵਿੱਚ ਜਾਉ",
"step_3": "ਚਰਣ 3",
"success_emoji": "ਸਫ਼ਲ🥳",
"success_message": "ਤੁਸੀਂ ਹੁਣ ਆਪਣੇ Spotify ਖ਼ਾਤੇ ਨਾਲ ਸਫ਼ਲਤਾਪੂਰਵਕ ਦਾਖ਼ਲ ਹੋ ਗਏ ਹੋ। ਤੁਸੀਂ ਵਧੀਆ ਕੰਮ ਕੀਤਾ!",
"step_4": "ਚਰਣ 4",
"something_went_wrong": "ਕੁੱਝ ਗਲਤ ਹੋ ਗਿਆ ਹੈ",
"piped_instance": "ਪਾਈਪਡ ਸਰਵਰ",
"piped_description": "ਪਾਈਪ ਕੀਤੇ ਗਏ ਸਰਵਰ",
"piped_warning": "ਗਾਣਿਆਂ ਨਾਲ ਮੇਲ ਕਰਨ ਲਈ ਵਰਤੇ ਜਾਂਦੇ ਹਨ, ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਉਹਨਾਂ ਵਿੱਚੋਂ ਕੁਝ ਦੇ ਨਾਲ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ ਇਸਲਈ ਆਪਣੇ ਜੋਖਮ 'ਤੇ ਵਰਤੋਂ",
"generate_playlist": "ਪਲੇਸੂਚੀ ਬਣਾਉ",
"track_exists": "ਟ੍ਰੈਕ {track} ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ",
"replace_downloaded_tracks": "ਸਾਰੇ ਡਾਊਨਲੋਡ ਕੀਤੇ ਗਏ ਟ੍ਰੈਕ ਬਦਲੋ",
"skip_download_tracks": "ਸਾਰੇ ਡਾਊਨਲੋਡ ਕੀਤੇ ਗਏ ਟ੍ਰੈਕ ਛੱਡੋ",
"do_you_want_to_replace": "ਕੀ ਤੁਸੀਂ ਮੌਜੂਦਾ ਟ੍ਰੈਕ ਬਦਲਣਾ ਚਾਹੁੰਦੇ ਹੋ?",
"replace": "ਬਦਲੋ",
"skip": "ਛੱਡੋ",
"select_up_to_count_type": "{count} {type} ਤੱਕ ਚੁਣੋ",
"select_genres": "ਸ਼ੈਲੀਆਂ ਚੁਣੋ",
"add_genres": "ਸ਼ੈਲੀਆਂ ਜੋੜੋ",
"country": "ਦੇਸ਼",
"number_of_tracks_generate": "ਉਤਪੰਨ ਕਰਨ ਲਈ ਟ੍ਰੈਕਾਂ ਦੀ ਸੰਖਿਆ",
"acousticness": "ਧੁਨਿਕਤਾ",
"danceability": "ਨੱਚਣ ਵਾਲੇ",
"energy": "ਊਰਜਾ",
"instrumentalness": "ਅਲਾਪਿਕਤਾ",
"liveness": "ਜੀਵੰਤਤਾ",
"loudness": "ਸ਼ੋਰ",
"speechiness": "ਬੋਲਚਾਲਤਾ",
"valence": "ਮਨੋਦਯਤਾ",
"popularity": "ਲੋਕਪ੍ਰਿਯਤਾ",
"key": "ਕੁੰਜੀ",
"duration": "ਅਵਧੀ (ਸੈਕਿੰਡ)",
"tempo": "ਗਤੀ (BPM)",
"mode": "ਮੋਡ",
"time_signature": "ਸਮਾਂ ਛਾਪ",
"short": "ਸੰਖੇਪ",
"medium": "ਮੱਧਮ",
"long": "ਲੰਬਾ",
"min": "ਨਿਊਨਤਮ",
"max": "ਅਧਿਕਤਮ",
"target": "ਟੀਚਾ",
"moderate": "ਮੱਧਮ",
"deselect_all": "ਸਭ ਨੂੰ ਅਣਚੁਣਿਆ ਕਰੋ",
"select_all": "ਸਭ ਨੂੰ ਚੁਣੋ",
"are_you_sure": "ਕੁ ਤੁਹਾਨੂੰ ਯਕੀਨ ਹੈ?",
"generating_playlist": "ਤੁਹਾਡੀ ਆਪਣੀ ਪਲੇਸੂਚੀ ਬਣਾਈ ਜਾ ਰਹੀ ਹੈ...",
"selected_count_tracks": "{count} ਟ੍ਰੈਕ ਚੁਣੇ ਗਏ",
"download_warning": "ਜੇਕਰ ਤੁਸੀਂ ਸਾਰੇ ਟਰੈਕਾਂ ਨੂੰ ਬਲਕ ਵਿੱਚ ਡਾਊਨਲੋਡ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਸੀਂ ਸਪਸ਼ਟ ਤੌਰ 'ਤੇ ਸੰਗੀਤ ਦੀ ਗੈਰ-ਕਾਨੂੰਨੀ ਨਕਲ ਕਰ ਰਹੇ ਹੋ ਅਤੇ ਸੰਗੀਤ ਦੇ ਰਚਨਾਤਮਕ ਸਮਾਜ ਨੂੰ ਨੁਕਸਾਨ ਪਹੁੰਚਾ ਰਹੇ ਹੋ। ਮੈਨੂੰ ਉਮੀਦ ਹੈ ਕਿ ਤੁਸੀਂ ਇਸ ਬਾਰੇ ਜਾਣਦੇ ਹੋ। ਹਮੇਸ਼ਾ ਕਲਾਕਾਰ ਦੀ ਮਿਹਨਤ ਦਾ ਸਤਿਕਾਰ ਅਤੇ ਸਮਰਥਨ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।",
"download_ip_ban_warning": "ਬਾਹਰੀ ਡਾਉਨਲੋਡ ਬੇਨਤੀਆਂ ਕਾਰਨ ਤੁਹਾਡਾ IP YouTube 'ਤੇ ਵੱਧ ਤੋਂ ਵੱਧ ਬਲੌਕ ਹੋ ਸਕਦਾ ਹੈ। IP ਬਲਾਕ ਦਾ ਮਤਲਬ ਹੈ ਕਿ ਤੁਸੀਂ ਘੱਟੋ-ਘੱਟ 2-3 ਮਹੀਨਿਆਂ ਲਈ ਉਸੇ IP ਡਿਵਾਈਸ ਤੋਂ YouTube ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕਰ ਸਕੋਗੇ (ਭਾਵੇਂ ਤੁਸੀਂ ਲੌਗਇਨ ਕੀਤਾ ਹੋਵੇ)। ਅਤੇ ਜੇਕਰ ਅਜਿਹਾ ਹੁੰਦਾ ਹੈ ਤਾਂ Spottube ਕੋਈ ਜ਼ਿੰਮੇਵਾਰੀ ਨਹੀਂ ਲੈਂਦਾ।",
"by_clicking_accept_terms": "'ਸਵੀਕਾਰ' ਕਲਿੱਕ ਕਰਕੇ ਤੁਸੀਂ ਹੇਠਾਂ ਦਿੱਤੀਆਂ ਸ਼ਰਤਾਂ ਨਾਲ ਸਹਿਮਤ ਹੁੰਦੇ ਹੋ:",
"download_agreement_1": "ਮੈਨੂੰ ਪਤਾ ਹੈ ਕਿ ਮੈਂ ਗ਼ੈਰ-ਕਾਨੂੰਨੀ ਸੰਗੀਤ ਨੂੰ ਨਕਲੀ ਬਣਾ ਰਿਹਾ ਹਾਂ। ਮੈਂ ਬੁਰਾ ਹਾਂ",
"download_agreement_2": "ਮੈਂ ਜਿੱਥੇ ਵੀ ਹੋ ਸਕੇ ਕਲਾਕਾਰਾਂ ਦਾ ਸਮਰਥਨ ਕਰਾਂਗਾ ਅਤੇ ਮੈਂ ਅਜਿਹਾ ਇਸ ਲਈ ਕਰ ਰਿਹਾ ਹਾਂ ਕਿਉਂਕਿ ਮੇਰੇ ਕੋਲ ਉਨ੍ਹਾਂ ਦੀ ਕਲਾ ਖਰੀਦਣ ਲਈ ਪੈਸੇ ਨਹੀਂ ਹਨ।",
"download_agreement_3": "ਮੈਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਪਤਾ ਹੈ ਕਿ ਮੇਰਾ ਆਈਪੀ ਯੂਟਿਊਬ 'ਤੇ ਬਲੌਕ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ ਅਤੇ ਮੈਂ ਕਿਸੇ ਵੀ ਦੁਰਘਟਨਾ ਲਈ ਸਪੋਟੀਫਾਈ ਜਾਂ ਇਸਦੇ ਮਾਲਕਾਂ/ਸਬੰਧੀਆਂ ਨੂੰ ਜ਼ਿੰਮੇਵਾਰ ਨਹੀਂ ਠਹਿਰਾਉਂਦਾ ਹਾਂ।",
"decline": "ਇਨਕਾਰ ਕਰੋ",
"accept": "ਸਵੀਕਾਰ ਕਰੋ",
"details": "ਵਿਵਰਣ",
"youtube": "ਯੂਟਿਊਬ",
"channel": "ਚੈਨਲ",
"likes": "ਪਸੰਦ",
"dislikes": "ਨਾਪਸੰਦ",
"views": "ਵਿਯੂ",
"streamUrl": "ਸਟ੍ਰੀਮ ਯੂਆਰਐਲ",
"stop": "ਰੋਕੋ",
"sort_newest": "ਨਵੇਂ ਜੋੜੇ ਗਏ ਅਨੁਸਾਰ ਕ੍ਰਮਬੱਧ ਕਰੋ",
"sort_oldest": "ਸਭਤੋਂ ਪੁਰਾਣੇ ਅਨੁਸਾਰ ਕ੍ਰਮਬੱਧ ਕਰੋ",
"sleep_timer": "ਸਲੀਪ ਟਾਈਮਰ",
"mins": "{minutes} ਮਿੰਟ",
"hours": "{hours} ਘੰਟੇ",
"hour": "{hours} ਘੰਟਾ",
"custom_hours": "ਕਸਟਮ ਘੰਟੇ",
"logs": "ਚਿੱਠੇ",
"developers": "ਡਿਵੈਲਪਰ",
"not_logged_in": "ਤੁਸੀਂ ਦਾਖ਼ਲ ਨਹੀਂ ਹੋ",
"search_mode": "ਖੋਜ ਮੋਡ",
"audio_source": "ਆਡੀਓ ਸਰੋਤ",
"ok": "ਠੀਕ ਹੈ",
"failed_to_encrypt": "ਇਨਕ੍ਰਿਪਟ ਕਰਨ ਵਿੱਚ ਅਸਫਲ",
"encryption_failed_warning": "Spottube ਤੁਹਾਡੇ ਡੇਟਾ ਨੂੰ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਸਟੋਰ ਕਰਨ ਲਈ ਐਨਕ੍ਰਿਪਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ। ਪਰ ਇਹ ਅਸਫਲ ਰਿਹਾ. ਇਸ ਲਈ, ਇਹ ਅਸੁਰੱਖਿਅਤ ਸਟੋਰੇਜ 'ਤੇ ਵਾਪਸ ਆ ਜਾਵੇਗਾ\nਜੇਕਰ ਤੁਸੀਂ ਲੀਨਕਸ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੇ ਹੋ, ਤਾਂ ਕਿਰਪਾ ਕਰਕੇ ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਤੁਹਾਡੇ ਕੋਲ ਕੋਈ ਗੁਪਤ-ਸੇਵਾਵਾਂ ਜਿਵੇਂ ਕਿ gnome-keyring, kde-wallet, Keepassxc ਆਦਿ ਇੰਸਟਾਲ ਹਨ।",
"querying_info": "ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰ ਰਿਹਾ ਹੈ",
"piped_api_down": "ਪਾਈਪਡ ਏਪੀਆਈ ਡਾਊਨ ਹੈ",
"piped_down_error_instructions": "ਪਾਈਪਡ ਇੰਸਟੈਂਸ {pipedInstance} ਵਰਤਮਾਨ ਵਿੱਚ ਡਾਊਨ ਹੈ\n\nਇੰਸਟੈਂਸ ਬਦਲੋ ਜਾਂ 'ਏਪੀਆਈ ਪ੍ਰਕਾਰ' ਨੂੰ ਅਧਿਕਾਰਤ YouTube API ਵਿੱਚ ਬਦਲੋ\n\nਤਬਦੀਲੀਆਂ ਤੋਂ ਬਾਅਦ ਐਪ ਨੂੰ ਦੁਬਾਰਾ ਚਲਾਉਣਾ ਯਕੀਨੀ ਬਣਾਓ",
"you_are_offline": "ਤੁਸੀਂ ਵਰਤਮਾਨ ਵਿੱਚ ਆਫ਼ਲਾਈਨ ਹੋ",
"connection_restored": "ਤੁਹਾਡਾ ਇੰਟਰਨੈੱਟ ਕੁਨੈਕਸ਼ਨ ਬਹਾਲ ਹੋ ਗਿਆ ਹੈ",
"use_system_title_bar": "ਸਿਸਟਮ ਸਿਰਲੇਖ ਪੱਟੀ ਵਰਤੋ",
"update_playlist": "ਪਲੇਸੂਚੀ ਅੱਪਡੇਟ ਕਰੋ",
"update": "ਅੱਪਡੇਟ ਕਰੋ",
"crunching_results": "ਨਤੀਜਿਆਂ 'ਤੇ ਕਾਰਵਾਈ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ...",
"search_to_get_results": "ਨਤੀਜੇ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਖੋਜੋ",
"use_amoled_mode": "AMOLED ਮੋਡ ਵਰਤੋ",
"pitch_dark_theme": "ਪਿੱਚ ਬਲੈਕ ਗੂੜ੍ਹੀ ਥੀਮ",
"normalize_audio": "ਆਡੀਓ ਨੂੰ ਸਧਾਰਨ ਕਰੋ",
"change_cover": "ਕਵਰ ਬਦਲੋ",
"add_cover": "ਕਵਰ ਜੋੜੋ",
"restore_defaults": "ਡਿਫਾਲਟ ਸੈਟਿੰਗਾਂ ਬਹਾਲ ਕਰੋ",
"download_music_codec": "ਸੰਗੀਤ ਕੋਡੈਕ ਡਾਊਨਲੋਡ ਕਰੋ",
"streaming_music_codec": "ਸਟ੍ਰੀਮਿੰਗ ਸੰਗੀਤ ਕੋਡੈਕ",
"login_with_lastfm": "Last.fm ਨਾਲ ਦਾਖ਼ਲ ਹੋਵੋ",
"connect": "ਕਨੈਕਟ ਕਰੋ",
"disconnect_lastfm": "Last.fm ਤੋਂ ਡਿਸਕਨੈਕਟ ਕਰੋ",
"disconnect": "ਡਿਸਕਨੈਕਟ ਕਰੋ",
"username": "ਉਪਯੋਗਕਰਤਾ ਨਾਮ",
"password": "ਪਾਸਵਰਡ",
"login": "ਦਾਖ਼ਲ ਹੋਵੋ",
"login_with_your_lastfm": "ਆਪਣੇ Last.fm ਖ਼ਾਤੇ ਨਾਲ਼ ਦਾਖ਼ਲ ਹੋਵੋ",
"scrobble_to_lastfm": "Last.fm ਉੱਤੇ ਸਕਰੌਬਲ ਕਰੋ",
"go_to_album": "ਐਲਬਮ ਤੇ ਜਾਓ",
"discord_rich_presence": "ਡਿਸਕਾਰਡ ਰਿਚ ਪ੍ਰੈਜੈਂਸ",
"browse_all": "ਸਾਰਿਆਂ ਨੂੰ ਬ੍ਰਾਊਜ਼ ਕਰੋ",
"genres": "ਸ਼ੈਲੀਆਂ",
"explore_genres": "ਸ਼ੈਲੀਆਂ ਫਰੋਲੋ",
"step_3_steps": "\"sp_dc\" ਕੁਕੀ ਦਾ ਮੁੱਲ ਕਾਪੀ ਕਰੋ",
"step_4_steps": "ਕਾਪੀ ਕੀਤੇ ਗਏ \"sp_dc\" ਮੁੱਲ ਨੂੰ ਪੈਸਟ ਕਰੋ",
"friends": "ਦੋਸਤ",
"no_lyrics_available": "ਮਾਫ਼ ਕਰਨਾ, ਇਸ ਟ੍ਰੈਕ ਦੇ ਬੋਲ ਨਹੀਂ ਮਿਲ ਸਕੋ",
"sort_duration": "ਅਵਧੀ ਅਨੁਸਾਰ ਕ੍ਰਮਬੱਧ ਕਰੋ",
"start_a_radio": "ਰੇਡੀਉ ਸ਼ੁਰੂ ਕਰੋ",
"how_to_start_radio": "ਰੇਡੀਉ ਕਿਵੇਂ ਸ਼ੁਰੂ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?",
"replace_queue_question": "ਕੀ ਤੁਸੀਂ ਮੌਜੂਦਾ ਕਤਾਰ ਨੂੰ ਬਦਲਣਾ ਚਾਹੁੰਦੇ ਹੋ ਜਾਂ ਜੋੜਨਾ ਚਾਹੁੰਦੇ ਹੋ?",
"endless_playback": "ਬੇਅੰਤ ਪਲੇਬੈਕ",
"delete_playlist": "ਪਲੇਸੂਚੀ ਹਟਾਉ",
"delete_playlist_confirmation": "ਕੀ ਤੁਸੀਂ ਸੱਚਮੁੱਚ ਇਸ ਪਲੇਸੂਚੀ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?",
"local_tracks": "ਸਥਾਨਕ ਟ੍ਰੈਕ",
"song_link": "ਗੀਤ ਦਾ ਲਿੰਕ",
"skip_this_nonsense": "ਇਸਨੂੰ ਛੱਡੋ",
"freedom_of_music": "“ਸੰਗੀਤ ਦੀ ਅਜ਼ਾਦੀ”",
"freedom_of_music_palm": "“ਹੱਥ ਵਿੱਚ ਸੰਗੀਤ ਦੀ ਅਜ਼ਾਦੀ”",
"get_started": "ਆਉ ਸ਼ੁਰੂ ਕਰੋ",
"youtube_source_description": "ਸਿਫ਼ਾਰਸ਼ ਕੀਤਾ ਗਿਆ ਅਤੇ ਸਭਤੋਂ ਵਧੀਆ ਕੰਮ ਕਰਦਾ ਹੈ।",
"piped_source_description": "ਮੁਫ਼ਤ ਮਹਿਸੂਸ ਕਰ ਰਹੇ ਹੋ? YouTube ਦੇ ਸਮਾਨ ਪਰ ਕਾਫੀ ਮੁਫ਼ਤ।",
"jiosaavn_source_description": "ਦੱਖਣੀ ਏਸ਼ੀਆਈ ਖੇਤਰ ਲਈ ਸਭ ਤੋਂ ਵਧੀਆ।",
"highest_quality": "ਸਭਤੋਂ ਵਧੀਆ ਗੁਣਵੱਤਾ: {quality}",
"select_audio_source": "ਆਡੀਉ ਸਰੋਤ ਚੁਣੋ",
"endless_playback_description": "ਕ੍ਰਮਬੱਧ ਕਤਾਰ ਦੇ ਅੰਤ ਵਿੱਚ ਆਪਣੇ ਆਪ ਨਵੇਂ ਗੀਤ ਸ਼ਾਮਲ ਕਰੋ",
"choose_your_region": "ਆਪਣਾ ਖੇਤਰ ਚੁਣੋ",
"choose_your_region_description": "ਇਹ Spotube ਨੂੰ ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਲਈ ਸਹੀ ਸਮੱਗਰੀ ਦਿਖਾਉਣ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਕਰੇਗਾ।",
"choose_your_language": "ਆਪਣੀ ਭਾਸ਼ਾ ਚੁਣੋ",
"help_project_grow": "ਇਸ ਪਰਿਯੋਜਨਾ ਨੂੰ ਵਧਾਉਣ ਵਿੱਚ ਮਦਦ ਕਰੋ",
"help_project_grow_description": "Spotube ਇੱਕ ਓਪਨ ਸੋਰਸ ਪ੍ਰੋਜੈਕਟ ਹੈ। ਤੁਸੀਂ ਯੋਗਦਾਨ ਦੇ ਕੇ, ਬੱਗਾਂ ਦੀ ਰਿਪੋਰਟ ਕਰਕੇ, ਜਾਂ ਨਵੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦਾ ਸੁਝਾਅ ਦੇ ਕੇ ਇਸ ਪ੍ਰੋਜੈਕਟ ਨੂੰ ਵਧਾ ਸਕਦੇ ਹੋ।",
"contribute_on_github": "GitHub ਉੱਤੇ ਯੋਗਦਾਨ ਦਿਉ",
"donate_on_open_collective": "ਓਪਨ ਕਲੈਕਟਿਵ ਉੱਤੇ ਯੋਗਦਾਨ ਦਿਉ",
"browse_anonymously": "ਬਿਨ੍ਹਾ ਨਾਮ ਦੇ ਬ੍ਰਾਊਜ਼ ਕਰੋ",
"enable_connect": "ਕਨੈਕਟ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ",
"enable_connect_description": "ਹੋਰ ਡਿਵਾਈਸਾਂ ਤੋਂ Spottube ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ",
"devices": "ਉਪਕਰਣ",
"select": "ਚੁਣੋ",
"connect_client_alert": "ਤੁਹਾਨੂੰ {client} ਦੁਆਰਾ ਕੰਟਰੋਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ",
"this_device": "ਇਹ ਉਪਕਰਣ",
"remote": "ਰਿਮੋਟ",
"local_library": "ਸਥਾਨਕ ਲਾਇਬ੍ਰੇਰੀ",
"add_library_location": "ਲਾਇਬ੍ਰੇਰੀ ਵਿੱਚ ਜੋੜੋ",
"remove_library_location": "ਲਾਇਬ੍ਰੇਰੀ ਵਿੱਚੋਂ ਹਟਾਉ",
"local_tab": "ਸਥਾਨਕ",
"stats": "ਅੰਕੜੇ",
"and_n_more": "और {count} और",
"recently_played": "ਹਾਲ ਹੀ ਵਿੱਚ ਚਲਾਏ ਗਏ",
"browse_more": "ਹੋਰ ਬ੍ਰਾਉਜ਼ ਕਰੋ",
"no_title": "ਕੋਈ ਸਿਰਲੇਖ ਨਹੀਂ",
"not_playing": "ਚੱਲ ਨਹੀਂ ਰਿਹਾ",
"epic_failure": "ਮਹਾਨ ਅਸਫ਼ਲਤਾ!",
"added_num_tracks_to_queue": "{tracks_length} ਟ੍ਰੈਕ ਕਤਾਰ ਵਿੱਚ ਜੋੜੇ ਗਏ",
"spotube_has_an_update": "Spotube ਲਈ ਇੱਕ ਅੱਪਡੇਟ ਹੈ",
"download_now": "ਹੁਣੇ ਡਾਊਨਲੋਡ ਕਰੋ",
"nightly_version": "Spotube Nightly {nightlyBuildNum} ਜਾਰੀ ਕੀਤਾ ਗਿਆ ਹੈ",
"release_version": "Spotube v{version} ਜਾਰੀ ਕੀਤਾ ਗਿਆ ਹੈ",
"read_the_latest": "ਨਵੀਨਤਮ ਪੜ੍ਹੋ",
"release_notes": "ਰਿਲੀਜ਼ ਨੋਟਸ",
"pick_color_scheme": "ਰੰਗ ਯੋਜਨਾ ਚੁਣੋ",
"save": "ਸੰਭਾਲੋ",
"choose_the_device": "ਉਪਕਰਣ ਚੁਣੋ:",
"multiple_device_connected": "ਕਈ ਉਪਕਰਣ ਜੋੜੇ ਗਏ ਹਨ।\nਉਸ ਉਪਕਰਣ ਨੂੰ ਚੁਣੋ ਜਿਸ ਤੇ ਤੁਸੀਂ ਕਿਰਿਆ ਕਰਨੀ ਚਾਹੁੰਦੇ ਹੋ",
"nothing_found": "ਕੁੱਝ ਨਹੀਂ ਮਿਲਿਆ",
"the_box_is_empty": "ਡੱਬਾ ਖਾਲੀ ਹੈ",
"top_artists": "ਚੋਟੀ ਦਾ ਕਲਾਕਾਰ",
"top_albums": "ਚੋਟੀ ਦੀ ਐਲਬਮ",
"this_week": "ਇਸ ਹਫ਼ਤੇ",
"this_month": "ਇਸ ਮਹੀਨੇ",
"last_6_months": "ਪਿਛਲੇ 6 ਮਹੀਨੇ",
"this_year": "ਇਸ ਸਾਲ",
"last_2_years": "ਪਿਛਲੇ 2 साल",
"all_time": "ਪੂਰਾ ਸਮਾਂ",
"powered_by_provider": "{providerName} ਦੁਆਰਾ ਸੰਚਾਲਿਤ",
"email": "ਈਮੇਲ",
"profile_followers": "ਫ਼ਾਲੋਅਰ",
"birthday": "ਜਨਮਦਿਨ",
"subscription": "ਗਾਹਕੀਆਂ",
"not_born": "ਹਲੇ ਪੈਦਾ ਨਹੀਂ ਹੋਇਆ",
"hacker": "ਹੈਕਰ",
"profile": "ਪ੍ਰੋਫ਼ਾਈਲ",
"no_name": "ਕੋਈ ਨਾਮ ਨਹੀਂ",
"edit": "ਸੋਧੋ",
"user_profile": "ਵਰਤੋਂਕਾਰ ਪ੍ਰੋਫ਼ਾਈਲ",
"count_plays": "{count} ਪਲੇ",
"streaming_fees_hypothetical": "ਸਟ੍ਰੀਮਿੰਗ ਫੀਸ (ਕਾਲਪਨਿਕ)",
"count_mins": "{minutes} ਮਿੰਟ",
"summary_minutes": "ਮਿੰਟ",
"summary_listened_to_music": "ਸੁਣਿਆ ਗਿਆ ਸੰਗੀਤ",
"summary_songs": "ਗੀਤ",
"summary_streamed_overall": "ਕੁੱਲ ਸਟ੍ਰੀਮ",
"summary_owed_to_artists": "ਕਲਾਕਾਰਾਂ ਨੂੰ ਦੇਣਦਾਰ\nਇਸ ਮਹੀਨੇ",
"summary_artists": "ਕਲਾਕਾਰ",
"summary_music_reached_you": "ਸੰਗੀਤ ਤੁਹਾਡੇ ਤੱਕ ਪਹੁੰਚ ਗਿਆ",
"summary_full_albums": "ਪੂਰਾ ਐਲਬਮ",
"summary_got_your_love": "ਤੁਹਾਡਾ ਪਿਆਰ ਮਿਲਿਆ",
"summary_playlists": "ਪਲੇਸੂਚੀਆਂ",
"summary_were_on_repeat": "ਦੁਹਰਾਇਆ ਗਿਆ",
"total_money": "ਕੁੱਲ {money}",
"minutes_listened": "ਮਿੰਟ ਸੁਣਿਆ",
"streamed_songs": "ਗੀਤ ਸਟ੍ਰੀਮ ਕੀਤੇ",
"count_streams": "{count} ਸਟ੍ਰੀਮ",
"owned_by_you": "ਤੁਹਾਡੀ ਮਲਕੀਅਤ",
"copied_shareurl_to_clipboard": "{shareUrl} ਕਲਿੱਪਬੋਰਡ ਉੱਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ",
"spotify_hipotetical_calculation": "*ਇਸਦੀ ਗਣਨਾ Spotify ਪ੍ਰਤੀ ਸਟ੍ਰੀਮ\n$0.003 ਤੋਂ $0.005 ਦੇ ਭੁਗਤਾਨ ਦੇ ਆਧਾਰ 'ਤੇ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਇਹ ਇੱਕ ਕਾਲਪਨਿਕ\nਗਣਨਾ ਹੈ ਜੋ ਉਪਭੋਗਤਾ ਨੂੰ ਇਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਦਿੰਦਾ ਹੈ ਕਿ \nਜੇਕਰ ਉਹਨਾਂ ਨੇ Spotify 'ਤੇ ਗੀਤ ਸੁਣਿਆ ਤਾਂ ਉਹਨਾਂ ਨੇ ਕਿੰਨਾ ਭੁਗਤਾਨ ਕੀਤਾ ਹੋਵੇਗਾ।",
"webview_not_found": "ਵੈੱਬਵਿਯੂ ਨਹੀਂ ਮਿਲਿਆ",
"webview_not_found_description": "ਤੁਹਾਡੇ ਡਿਵਾਈਸ ਉੱਤੇ ਕੋਈ ਵੈੱਬਵਿਯੂ ਰਨਟਾਈਮ ਇੰਸਟਾਲ ਨਹੀਂ ਹੈ।\nਜੈਕਰ ਇਹ ਇੰਸਟਾਲ ਹੈ ਤਾਂ ਪੱਕਾ ਕਰੋ ਕਿ ਇਹ ਵਾਤਾਵਰਨ ਰਸਤੇ ਵਿੱਚ ਹੈ\n\nਇੰਸਟਾਲ ਕਰਨ ਤੋਂ ਬਾਅਦ, ਐਪ ਦੁਬਾਰਾ ਚਲਾਉ",
"unsupported_platform": "ਅਸਮਰਥਿਤ ਪਲੇਟਫਾਰਮ",
"invidious_instance": "ਇਨਡਿਵੀਡਿਊਸ ਸਰਵਰ ਇੰਸਟੈਂਸ",
"invidious_description": "ਟ੍ਰੈਕ ਮਿਲਾਨ ਲਈ ਇਨਡਿਵੀਡਿਊਸ ਸਰਵਰ ਇੰਸਟੈਂਸ",
"invidious_warning": "ਕੁੱਝ ਇੰਸਟੈਂਸ ਸਹੀ ਕੰਮ ਨਹੀਂ ਕਰ ਰਹੇ ਹਨ। ਆਪਣੇ ਜੋਖਮ ਤੇ ਵਰਤੋ",
"invidious_source_description": "ਪਾਈਪਡ ਦੇ ਸਮਾਨ, ਪਰ ਵੱਧ ਉਪਲਬਧਤਾ ਨਾਲ",
"cache_music": "ਸੰਗੀਤ ਨੂੰ ਕੈਸ਼ ਕਰੋ",
"open": "ਖੋਲ੍ਹੋ",
"cache_folder": "ਕੈਸ਼ ਫੋਲਡਰ",
"export": "ਨਿਰਯਾਤ ਕਰੋ",
"clear_cache": "ਕੈਸ਼ ਸਾਫ਼ ਕਰੋ",
"clear_cache_confirmation": "ਕੀ ਤੁਸੀਂ ਕੈਸ਼ ਸਾਫ਼ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?",
"export_cache_files": "ਕੈਸ਼ ਫ਼ਾਈਲਾਂ ਨਿਰਯਾਤ ਕਰੋ",
"found_n_files": "{count} ਫ਼ਾਈਲਾਂ ਮਿਲੀਆਂ",
"export_cache_confirmation": "ਕੀ ਤੁਸੀਂ ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਨਿਰਯਾਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ",
"exported_n_out_of_m_files": "{files} ਵਿੱਚੋਂ {filesExported} ਫ਼ਾਈਲਾਂ ਨਿਰਯਾਤ ਕੀਤੀਆਂ ਗਈਆਂ"
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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 அடிப்படையில் துல்லியமான பாடல் பொருத்தம்."
}

View File

@ -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"
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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."
}

View File

@ -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 的精确曲目匹配。"
}

View File

@ -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 曲目比對。"
}

View File

@ -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

View File

@ -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.';
}

View File

@ -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 ভিত্তিক ট্র্যাক ম্যাচিং।';
}

View File

@ -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 lhistorial descoltes.';
@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 {
'Lentrada 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.';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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 आधारित ट्रैक मिलान।';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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ベースのトラックマッチング。';
}

View File

@ -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-ის მიხედვით.';
}

View File

@ -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 기반으로 정확한 트랙 매칭을 지원합니다.';
}

View File

@ -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-मा आधारित सटीक ट्र्याक मिलान।';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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 அடிப்படையில் துல்லியமான பாடல் பொருத்தம்.';
}

View File

@ -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';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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.';
}

View File

@ -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 曲目比對。';
}

View File

@ -83,6 +83,8 @@ Future<void> main(List<String> 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();

View File

@ -112,8 +112,13 @@ mixin _$WebSocketLoadEventData {
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
/// Serializes this WebSocketLoadEventData to a JSON map.
Map<String, dynamic> 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<WebSocketLoadEventData> 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;
}

View File

@ -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));
},
),
);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
// dart format width=80
import 'package:drift/internal/versioned_schema.dart' as i0;
import 'package:drift/drift.dart' as i1;
import 'package:drift/drift.dart'; // ignore_for_file: type=lint,unused_import
import 'package:flutter/material.dart';
import 'package:spotube/models/database/database.dart';
import 'package:spotube/models/metadata/market.dart';
import 'package:spotube/services/sourced_track/enums.dart';
// GENERATED BY drift_dev, DO NOT MODIFY.
final class Schema2 extends i0.VersionedSchema {
@ -329,8 +329,7 @@ class Shape2 extends i0.VersionedTable {
i1.GeneratedColumn<String> _column_7(String aliasedName) =>
i1.GeneratedColumn<String>('audio_quality', aliasedName, false,
type: i1.DriftSqlType.string,
defaultValue: Constant(SourceQualities.high.name));
type: i1.DriftSqlType.string, defaultValue: Constant("high"));
i1.GeneratedColumn<bool> _column_8(String aliasedName) =>
i1.GeneratedColumn<bool>('album_color_sync', aliasedName, false,
type: i1.DriftSqlType.bool,
@ -417,16 +416,13 @@ i1.GeneratedColumn<String> _column_25(String aliasedName) =>
defaultValue: Constant(ThemeMode.system.name));
i1.GeneratedColumn<String> _column_26(String aliasedName) =>
i1.GeneratedColumn<String>('audio_source', aliasedName, false,
type: i1.DriftSqlType.string,
defaultValue: Constant(AudioSource.youtube.name));
type: i1.DriftSqlType.string, defaultValue: Constant("youtube"));
i1.GeneratedColumn<String> _column_27(String aliasedName) =>
i1.GeneratedColumn<String>('stream_music_codec', aliasedName, false,
type: i1.DriftSqlType.string,
defaultValue: Constant(SourceCodecs.weba.name));
type: i1.DriftSqlType.string, defaultValue: Constant("weba"));
i1.GeneratedColumn<String> _column_28(String aliasedName) =>
i1.GeneratedColumn<String>('download_music_codec', aliasedName, false,
type: i1.DriftSqlType.string,
defaultValue: Constant(SourceCodecs.m4a.name));
type: i1.DriftSqlType.string, defaultValue: Constant("m4a"));
i1.GeneratedColumn<bool> _column_29(String aliasedName) =>
i1.GeneratedColumn<bool>('discord_presence', aliasedName, false,
type: i1.DriftSqlType.bool,
@ -511,8 +507,7 @@ i1.GeneratedColumn<String> _column_38(String aliasedName) =>
type: i1.DriftSqlType.string);
i1.GeneratedColumn<String> _column_39(String aliasedName) =>
i1.GeneratedColumn<String>('source_type', aliasedName, false,
type: i1.DriftSqlType.string,
defaultValue: Constant(SourceType.youtube.name));
type: i1.DriftSqlType.string, defaultValue: Constant("youtube"));
class Shape6 extends i0.VersionedTable {
Shape6({required super.source, required super.alias}) : super.aliased();
@ -1407,7 +1402,7 @@ final class Schema5 extends i0.VersionedSchema {
i1.GeneratedColumn<String> _column_55(String aliasedName) =>
i1.GeneratedColumn<String>('accent_color_scheme', aliasedName, false,
type: i1.DriftSqlType.string,
defaultValue: const Constant("Slate:0xff64748b"));
defaultValue: const Constant("Orange:0xFFf97315"));
final class Schema6 extends i0.VersionedSchema {
Schema6({required super.database}) : super(version: 6);
@ -2053,7 +2048,7 @@ final class Schema8 extends i0.VersionedSchema {
_column_13,
_column_14,
_column_15,
_column_55,
_column_69,
_column_17,
_column_18,
_column_19,
@ -2188,7 +2183,7 @@ final class Schema8 extends i0.VersionedSchema {
_column_65,
_column_66,
_column_67,
_column_69,
_column_70,
],
attachedDatabase: database,
),
@ -2200,8 +2195,550 @@ final class Schema8 extends i0.VersionedSchema {
}
i1.GeneratedColumn<String> _column_69(String aliasedName) =>
i1.GeneratedColumn<String>('accent_color_scheme', aliasedName, false,
type: i1.DriftSqlType.string,
defaultValue: const Constant("Slate:0xff64748b"));
i1.GeneratedColumn<String> _column_70(String aliasedName) =>
i1.GeneratedColumn<String>('plugin_api_version', aliasedName, false,
type: i1.DriftSqlType.string, defaultValue: const Constant('1.0.0'));
final class Schema9 extends i0.VersionedSchema {
Schema9({required super.database}) : super(version: 9);
@override
late final List<i1.DatabaseSchemaEntity> entities = [
authenticationTable,
blacklistTable,
preferencesTable,
scrobblerTable,
skipSegmentTable,
sourceMatchTable,
audioPlayerStateTable,
historyTable,
lyricsTable,
pluginsTable,
uniqueBlacklist,
uniqTrackMatch,
];
late final Shape0 authenticationTable = Shape0(
source: i0.VersionedTable(
entityName: 'authentication_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_1,
_column_2,
_column_3,
],
attachedDatabase: database,
),
alias: null);
late final Shape1 blacklistTable = Shape1(
source: i0.VersionedTable(
entityName: 'blacklist_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_4,
_column_5,
_column_6,
],
attachedDatabase: database,
),
alias: null);
late final Shape13 preferencesTable = Shape13(
source: i0.VersionedTable(
entityName: 'preferences_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_7,
_column_8,
_column_9,
_column_10,
_column_11,
_column_12,
_column_13,
_column_14,
_column_15,
_column_69,
_column_17,
_column_18,
_column_19,
_column_20,
_column_21,
_column_22,
_column_23,
_column_24,
_column_25,
_column_26,
_column_54,
_column_27,
_column_28,
_column_29,
_column_30,
_column_31,
_column_56,
_column_53,
],
attachedDatabase: database,
),
alias: null);
late final Shape3 scrobblerTable = Shape3(
source: i0.VersionedTable(
entityName: 'scrobbler_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_32,
_column_33,
_column_34,
],
attachedDatabase: database,
),
alias: null);
late final Shape4 skipSegmentTable = Shape4(
source: i0.VersionedTable(
entityName: 'skip_segment_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_35,
_column_36,
_column_37,
_column_32,
],
attachedDatabase: database,
),
alias: null);
late final Shape5 sourceMatchTable = Shape5(
source: i0.VersionedTable(
entityName: 'source_match_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_37,
_column_38,
_column_39,
_column_32,
],
attachedDatabase: database,
),
alias: null);
late final Shape14 audioPlayerStateTable = Shape14(
source: i0.VersionedTable(
entityName: 'audio_player_state_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_40,
_column_41,
_column_42,
_column_43,
_column_57,
_column_58,
],
attachedDatabase: database,
),
alias: null);
late final Shape9 historyTable = Shape9(
source: i0.VersionedTable(
entityName: 'history_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_32,
_column_50,
_column_51,
_column_52,
],
attachedDatabase: database,
),
alias: null);
late final Shape10 lyricsTable = Shape10(
source: i0.VersionedTable(
entityName: 'lyrics_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_37,
_column_52,
],
attachedDatabase: database,
),
alias: null);
late final Shape16 pluginsTable = Shape16(
source: i0.VersionedTable(
entityName: 'plugins_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_59,
_column_60,
_column_61,
_column_62,
_column_63,
_column_64,
_column_65,
_column_71,
_column_72,
_column_67,
_column_73,
],
attachedDatabase: database,
),
alias: null);
final i1.Index uniqueBlacklist = i1.Index('unique_blacklist',
'CREATE UNIQUE INDEX unique_blacklist ON blacklist_table (element_type, element_id)');
final i1.Index uniqTrackMatch = i1.Index('uniq_track_match',
'CREATE UNIQUE INDEX uniq_track_match ON source_match_table (track_id, source_id, source_type)');
}
class Shape16 extends i0.VersionedTable {
Shape16({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get name =>
columnsByName['name']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get description =>
columnsByName['description']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get version =>
columnsByName['version']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get author =>
columnsByName['author']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get entryPoint =>
columnsByName['entry_point']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get apis =>
columnsByName['apis']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get abilities =>
columnsByName['abilities']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<bool> get selectedForMetadata =>
columnsByName['selected_for_metadata']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get selectedForAudioSource =>
columnsByName['selected_for_audio_source']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<String> get repository =>
columnsByName['repository']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get pluginApiVersion =>
columnsByName['plugin_api_version']! as i1.GeneratedColumn<String>;
}
i1.GeneratedColumn<bool> _column_71(String aliasedName) =>
i1.GeneratedColumn<bool>('selected_for_metadata', aliasedName, false,
type: i1.DriftSqlType.bool,
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
'CHECK ("selected_for_metadata" IN (0, 1))'),
defaultValue: const Constant(false));
i1.GeneratedColumn<bool> _column_72(String aliasedName) =>
i1.GeneratedColumn<bool>('selected_for_audio_source', aliasedName, false,
type: i1.DriftSqlType.bool,
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
'CHECK ("selected_for_audio_source" IN (0, 1))'),
defaultValue: const Constant(false));
i1.GeneratedColumn<String> _column_73(String aliasedName) =>
i1.GeneratedColumn<String>('plugin_api_version', aliasedName, false,
type: i1.DriftSqlType.string, defaultValue: const Constant('2.0.0'));
final class Schema10 extends i0.VersionedSchema {
Schema10({required super.database}) : super(version: 10);
@override
late final List<i1.DatabaseSchemaEntity> entities = [
authenticationTable,
blacklistTable,
preferencesTable,
scrobblerTable,
skipSegmentTable,
sourceMatchTable,
audioPlayerStateTable,
historyTable,
lyricsTable,
pluginsTable,
uniqueBlacklist,
uniqTrackMatch,
];
late final Shape0 authenticationTable = Shape0(
source: i0.VersionedTable(
entityName: 'authentication_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_1,
_column_2,
_column_3,
],
attachedDatabase: database,
),
alias: null);
late final Shape1 blacklistTable = Shape1(
source: i0.VersionedTable(
entityName: 'blacklist_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_4,
_column_5,
_column_6,
],
attachedDatabase: database,
),
alias: null);
late final Shape17 preferencesTable = Shape17(
source: i0.VersionedTable(
entityName: 'preferences_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_8,
_column_9,
_column_10,
_column_11,
_column_12,
_column_13,
_column_14,
_column_15,
_column_69,
_column_17,
_column_18,
_column_19,
_column_20,
_column_21,
_column_22,
_column_25,
_column_74,
_column_54,
_column_29,
_column_30,
_column_31,
_column_56,
_column_53,
],
attachedDatabase: database,
),
alias: null);
late final Shape3 scrobblerTable = Shape3(
source: i0.VersionedTable(
entityName: 'scrobbler_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_32,
_column_33,
_column_34,
],
attachedDatabase: database,
),
alias: null);
late final Shape4 skipSegmentTable = Shape4(
source: i0.VersionedTable(
entityName: 'skip_segment_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_35,
_column_36,
_column_37,
_column_32,
],
attachedDatabase: database,
),
alias: null);
late final Shape18 sourceMatchTable = Shape18(
source: i0.VersionedTable(
entityName: 'source_match_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_37,
_column_75,
_column_76,
_column_32,
],
attachedDatabase: database,
),
alias: null);
late final Shape14 audioPlayerStateTable = Shape14(
source: i0.VersionedTable(
entityName: 'audio_player_state_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_40,
_column_41,
_column_42,
_column_43,
_column_57,
_column_58,
],
attachedDatabase: database,
),
alias: null);
late final Shape9 historyTable = Shape9(
source: i0.VersionedTable(
entityName: 'history_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_32,
_column_50,
_column_51,
_column_52,
],
attachedDatabase: database,
),
alias: null);
late final Shape10 lyricsTable = Shape10(
source: i0.VersionedTable(
entityName: 'lyrics_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_37,
_column_52,
],
attachedDatabase: database,
),
alias: null);
late final Shape16 pluginsTable = Shape16(
source: i0.VersionedTable(
entityName: 'plugins_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_59,
_column_60,
_column_61,
_column_62,
_column_63,
_column_64,
_column_65,
_column_71,
_column_72,
_column_67,
_column_73,
],
attachedDatabase: database,
),
alias: null);
final i1.Index uniqueBlacklist = i1.Index('unique_blacklist',
'CREATE UNIQUE INDEX unique_blacklist ON blacklist_table (element_type, element_id)');
final i1.Index uniqTrackMatch = i1.Index('uniq_track_match',
'CREATE UNIQUE INDEX uniq_track_match ON source_match_table (track_id, source_info, source_type)');
}
class Shape17 extends i0.VersionedTable {
Shape17({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<bool> get albumColorSync =>
columnsByName['album_color_sync']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get amoledDarkTheme =>
columnsByName['amoled_dark_theme']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get checkUpdate =>
columnsByName['check_update']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get normalizeAudio =>
columnsByName['normalize_audio']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get showSystemTrayIcon =>
columnsByName['show_system_tray_icon']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get systemTitleBar =>
columnsByName['system_title_bar']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get skipNonMusic =>
columnsByName['skip_non_music']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<String> get closeBehavior =>
columnsByName['close_behavior']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get accentColorScheme =>
columnsByName['accent_color_scheme']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get layoutMode =>
columnsByName['layout_mode']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get locale =>
columnsByName['locale']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get market =>
columnsByName['market']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get searchMode =>
columnsByName['search_mode']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get downloadLocation =>
columnsByName['download_location']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get localLibraryLocation =>
columnsByName['local_library_location']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get themeMode =>
columnsByName['theme_mode']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get audioSourceId =>
columnsByName['audio_source_id']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get youtubeClientEngine =>
columnsByName['youtube_client_engine']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<bool> get discordPresence =>
columnsByName['discord_presence']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get endlessPlayback =>
columnsByName['endless_playback']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get enableConnect =>
columnsByName['enable_connect']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<int> get connectPort =>
columnsByName['connect_port']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<bool> get cacheMusic =>
columnsByName['cache_music']! as i1.GeneratedColumn<bool>;
}
i1.GeneratedColumn<String> _column_74(String aliasedName) =>
i1.GeneratedColumn<String>('audio_source_id', aliasedName, true,
type: i1.DriftSqlType.string);
class Shape18 extends i0.VersionedTable {
Shape18({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get trackId =>
columnsByName['track_id']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get sourceInfo =>
columnsByName['source_info']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get sourceType =>
columnsByName['source_type']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<DateTime> get createdAt =>
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
}
i1.GeneratedColumn<String> _column_75(String aliasedName) =>
i1.GeneratedColumn<String>('source_info', aliasedName, false,
type: i1.DriftSqlType.string, defaultValue: const Constant("{}"));
i1.GeneratedColumn<String> _column_76(String aliasedName) =>
i1.GeneratedColumn<String>('source_type', aliasedName, false,
type: i1.DriftSqlType.string);
i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
@ -2210,6 +2747,8 @@ i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, Schema6 schema) from5To6,
required Future<void> Function(i1.Migrator m, Schema7 schema) from6To7,
required Future<void> Function(i1.Migrator m, Schema8 schema) from7To8,
required Future<void> Function(i1.Migrator m, Schema9 schema) from8To9,
required Future<void> Function(i1.Migrator m, Schema10 schema) from9To10,
}) {
return (currentVersion, database) async {
switch (currentVersion) {
@ -2248,6 +2787,16 @@ i0.MigrationStepWithVersion migrationSteps({
final migrator = i1.Migrator(database, schema);
await from7To8(migrator, schema);
return 8;
case 8:
final schema = Schema9(database: database);
final migrator = i1.Migrator(database, schema);
await from8To9(migrator, schema);
return 9;
case 9:
final schema = Schema10(database: database);
final migrator = i1.Migrator(database, schema);
await from9To10(migrator, schema);
return 10;
default:
throw ArgumentError.value('Unknown migration from $currentVersion');
}
@ -2262,6 +2811,8 @@ i1.OnUpgrade stepByStep({
required Future<void> Function(i1.Migrator m, Schema6 schema) from5To6,
required Future<void> Function(i1.Migrator m, Schema7 schema) from6To7,
required Future<void> Function(i1.Migrator m, Schema8 schema) from7To8,
required Future<void> Function(i1.Migrator m, Schema9 schema) from8To9,
required Future<void> Function(i1.Migrator m, Schema10 schema) from9To10,
}) =>
i0.VersionedSchema.stepByStepHelper(
step: migrationSteps(
@ -2272,4 +2823,6 @@ i1.OnUpgrade stepByStep({
from5To6: from5To6,
from6To7: from6To7,
from7To8: from7To8,
from8To9: from8To9,
from9To10: from9To10,
));

View File

@ -1,6 +1,6 @@
part of '../database.dart';
class MetadataPluginsTable extends Table {
class PluginsTable extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text().withLength(min: 1, max: 50)();
TextColumn get description => text()();
@ -9,8 +9,11 @@ class MetadataPluginsTable extends Table {
TextColumn get entryPoint => text()();
TextColumn get apis => text().map(const StringListConverter())();
TextColumn get abilities => text().map(const StringListConverter())();
BoolColumn get selected => boolean().withDefault(const Constant(false))();
BoolColumn get selectedForMetadata =>
boolean().withDefault(const Constant(false))();
BoolColumn get selectedForAudioSource =>
boolean().withDefault(const Constant(false))();
TextColumn get repository => text().nullable()();
TextColumn get pluginApiVersion =>
text().withDefault(const Constant('1.0.0'))();
text().withDefault(const Constant('2.0.0'))();
}

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