23 Commits

Author SHA1 Message Date
Bart Ribbers
dae166ecb9 Merge eaffffac4d into b0bb26f84b 2024-12-10 22:47:14 +01:00
Bart Ribbers
eaffffac4d fix: move all .of(context) out of the widget tree and into a variable
At some places <something>.of(context) was used multiple times in the
same widget. This, although small, can have an impact on performance
that's just plain unnecessary. It's better to just get things you need
out of the context first before you do anything else.
2024-12-10 22:47:06 +01:00
Bart Ribbers
e11250182d chore: upgrade to Flutter 3.24.5
At the time of writing the latest Flutter version.
2024-12-10 22:45:36 +01:00
Bart Ribbers
fc0daacfc0 chore: ignore VSCode's settings.json in git
Seettings in there can be different per user and should be, it should
not be committed
2024-12-10 20:42:50 +01:00
Bart Ribbers
7e5885e5c8 chore: cleanup fvm configuration
I guess fvm changed the way it does it's configuration at some point,
but rather than having .fvm/fmv_config.json checked in .fvmrc should be
checked in. The .fvm directory is used to store files and symlinks
related to the installed Flutter version and as such should not be
commited at all.
2024-12-10 20:42:49 +01:00
austinried
b0bb26f84b Fix initial server ping/feature tests always using token auth 2023-05-18 06:42:29 +09:00
austinried
e94fcf3128 bump version 2023-05-16 18:59:16 +09:00
josé m
bd6e818f36 Translated using Weblate (Galician)
Currently translated at 100.0% (94 of 94 strings)

Co-authored-by: josé m <correoxm@disroot.org>
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/gl/
Translation: Subtracks/subtracks
2023-05-16 18:57:04 +09:00
Max Smith
96d0c35c31 Translated using Weblate (Russian)
Currently translated at 100.0% (94 of 94 strings)

Co-authored-by: Max Smith <sevinfolds@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/ru/
Translation: Subtracks/subtracks
2023-05-16 18:57:04 +09:00
Tim Schneeberger
4ef3281a0b Translated using Weblate (German)
Currently translated at 100.0% (92 of 92 strings)

Co-authored-by: Tim Schneeberger <thebone.main@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/de/
Translation: Subtracks/subtracks
2023-05-16 18:57:04 +09:00
austinried
c56e3dba0f remove todo 2023-05-16 09:34:39 +09:00
austinried
53d284ace4 redact error too
create log file if it doesn't exist first
2023-05-16 09:34:39 +09:00
austinried
c2733482e5 show snackbar error for sync
log http errors
log sync errors
2023-05-16 09:34:39 +09:00
austinried
67f0c926c4 add snackbar method for errors
test (ping) server before saving source
display error message when saving source
2023-05-16 09:34:39 +09:00
Joel Calado
889be2ff2c return null 2023-05-15 07:11:58 +09:00
Joel Calado
52b51954aa improve url validation in settings 2023-05-15 07:11:58 +09:00
austinried
1c76293559 default force plaintext password off 2023-05-14 14:35:19 +09:00
austinried
250d6793a2 wording 2023-05-14 14:29:04 +09:00
austinried
121af2bca3 audio playback error logging
subsonic error logging
source save error logging
2023-05-14 14:29:04 +09:00
austinried
e410dcb2eb log sql exceptions 2023-05-14 14:29:04 +09:00
austinried
63ff9772e5 initial console/file logging framework 2023-05-14 14:29:04 +09:00
Vojtěch Fošnár
1ae29c5ade Translated using Weblate (Czech)
Currently translated at 85.8% (79 of 92 strings)

Co-authored-by: Vojtěch Fošnár <vfosnar@fosny.eu>
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/cs/
Translation: Subtracks/subtracks
2023-05-11 10:07:23 +09:00
Joel Calado
fedd6a71bb Translated using Weblate (Portuguese)
Currently translated at 88.0% (81 of 92 strings)

Co-authored-by: Joel Calado <joelcalado@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/pt/
Translation: Subtracks/subtracks
2023-05-11 10:07:23 +09:00
75 changed files with 3937 additions and 2107 deletions

View File

@@ -1,4 +0,0 @@
{
"flutterSdkVersion": "3.7.11",
"flavors": {}
}

4
.fvmrc Normal file
View File

@@ -0,0 +1,4 @@
{
"flutter": "3.24.5",
"flavors": {}
}

8
.gitignore vendored
View File

@@ -16,10 +16,8 @@ migrate_working_dir/
*.iws *.iws
.idea/ .idea/
# The .vscode folder contains launch configuration and tasks you configure in # VSCode related
# VS Code which you may wish to be included in version control, so this line .vscode/settings.json
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related # Flutter/Dart/Pub related
**/doc/api/ **/doc/api/
@@ -45,5 +43,5 @@ app.*.map.json
/.env /.env
*.sqlite* *.sqlite*
/.fvm/flutter_sdk .fvm/
*.keystore *.keystore

View File

@@ -22,6 +22,8 @@
"resourcesSortByTitle", "resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn",
@@ -53,6 +55,8 @@
"resourcesSortByTitle", "resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn",
@@ -62,32 +66,12 @@
], ],
"cs": [ "cs": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"resourcesAlbumCount", "resourcesAlbumCount",
"resourcesArtistCount", "resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount", "resourcesPlaylistCount",
"resourcesSongCount", "resourcesSongCount",
"resourcesSongListDeleteAllContent", "settingsAboutShareLogs",
"resourcesSongListDeleteAllTitle", "settingsAboutChooseLog",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsLicenses",
"settingsAboutActionsProjectHomepage",
"settingsAboutActionsSupport",
"settingsAboutName",
"settingsAboutVersion",
"settingsMusicName", "settingsMusicName",
"settingsMusicOptionsScrobbleDescriptionOff", "settingsMusicOptionsScrobbleDescriptionOff",
"settingsMusicOptionsScrobbleDescriptionOn", "settingsMusicOptionsScrobbleDescriptionOn",
@@ -96,12 +80,7 @@
"settingsNetworkOptionsMinBufferTitle", "settingsNetworkOptionsMinBufferTitle",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn"
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsResetActionsClearImageCache",
"settingsResetName",
"settingsServersFieldsName"
], ],
"da": [ "da": [
@@ -133,6 +112,8 @@
"resourcesSortByTitle", "resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsMusicOptionsScrobbleDescriptionOff", "settingsMusicOptionsScrobbleDescriptionOff",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
@@ -146,29 +127,8 @@
], ],
"de": [ "de": [
"actionsDownloadDelete", "settingsAboutShareLogs",
"actionsOk", "settingsAboutChooseLog"
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
], ],
"es": [ "es": [
@@ -187,6 +147,8 @@
"resourcesSortByTitle", "resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn",
@@ -218,6 +180,8 @@
"resourcesSortByTitle", "resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn",
@@ -249,6 +213,8 @@
"resourcesSortByTitle", "resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn",
@@ -300,6 +266,8 @@
"settingsAboutActionsLicenses", "settingsAboutActionsLicenses",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutName", "settingsAboutName",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsAboutVersion", "settingsAboutVersion",
"settingsMusicOptionsScrobbleDescriptionOff", "settingsMusicOptionsScrobbleDescriptionOff",
"settingsMusicOptionsScrobbleDescriptionOn", "settingsMusicOptionsScrobbleDescriptionOn",
@@ -356,6 +324,8 @@
"resourcesSortByTitle", "resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn",
@@ -387,6 +357,8 @@
"resourcesSortByTitle", "resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn",
@@ -418,6 +390,8 @@
"resourcesSortByTitle", "resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn",
@@ -427,63 +401,17 @@
], ],
"pt": [ "pt": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"resourcesAlbumCount", "resourcesAlbumCount",
"resourcesArtistCount", "resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner", "resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount", "resourcesPlaylistCount",
"resourcesSongCount", "resourcesSongCount",
"resourcesSongListDeleteAllContent", "resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle", "resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount", "resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutShareLogs",
"settingsNetworkOptionsOfflineMode", "settingsAboutChooseLog",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName"
],
"ru": [
"actionsCancel",
"actionsDelete",
"actionsDownload",
"actionsDownloadCancel",
"actionsDownloadDelete",
"actionsOk",
"controlsShuffle",
"resourcesAlbumCount",
"resourcesArtistCount",
"resourcesFilterAlbum",
"resourcesFilterArtist",
"resourcesFilterOwner",
"resourcesFilterYear",
"resourcesPlaylistCount",
"resourcesSongCount",
"resourcesSongListDeleteAllContent",
"resourcesSongListDeleteAllTitle",
"resourcesSortByAlbum",
"resourcesSortByAlbumCount",
"resourcesSortByTitle",
"resourcesSortByUpdated",
"settingsAboutActionsSupport",
"settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn",
"settingsNetworkOptionsStreamFormat",
"settingsNetworkOptionsStreamFormatServerDefault", "settingsNetworkOptionsStreamFormatServerDefault",
"settingsServersFieldsName" "settingsServersFieldsName"
], ],
@@ -511,6 +439,8 @@
"resourcesSortByTitle", "resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn",
@@ -542,6 +472,8 @@
"resourcesSortByTitle", "resourcesSortByTitle",
"resourcesSortByUpdated", "resourcesSortByUpdated",
"settingsAboutActionsSupport", "settingsAboutActionsSupport",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn",
@@ -556,6 +488,8 @@
"resourcesArtistCount", "resourcesArtistCount",
"resourcesPlaylistCount", "resourcesPlaylistCount",
"resourcesSongCount", "resourcesSongCount",
"settingsAboutShareLogs",
"settingsAboutChooseLog",
"settingsNetworkOptionsOfflineMode", "settingsNetworkOptionsOfflineMode",
"settingsNetworkOptionsOfflineModeOff", "settingsNetworkOptionsOfflineModeOff",
"settingsNetworkOptionsOfflineModeOn", "settingsNetworkOptionsOfflineModeOn",

View File

@@ -1,3 +1,9 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties() def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties') def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) { if (localPropertiesFile.exists()) {
@@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
} }
} }
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode') def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) { if (flutterVersionCode == null) {
flutterVersionCode = '1' flutterVersionCode = '1'
@@ -21,10 +22,6 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0' flutterVersionName = '1.0'
} }
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
def keystoreProperties = new Properties() def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties') def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) { if (keystorePropertiesFile.exists()) {
@@ -53,7 +50,7 @@ android {
applicationId "com.subtracks2" applicationId "com.subtracks2"
// You can update the following values to match your application needs. // You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 19 minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
@@ -81,8 +78,4 @@ android {
flutter { flutter {
source '../..' source '../..'
} }
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

View File

@@ -5,4 +5,9 @@
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<!-- audio_service -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
</manifest> </manifest>

View File

@@ -69,4 +69,5 @@
<!-- audio_service --> <!-- audio_service -->
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
</manifest> </manifest>

View File

@@ -1,25 +0,0 @@
// Generated file.
//
// If you wish to remove Flutter's multidex support, delete this entire file.
//
// Modifications to this file should be done in a copy under a different name
// as this file may be regenerated.
package io.flutter.app;
import android.app.Application;
import android.content.Context;
import androidx.annotation.CallSuper;
import androidx.multidex.MultiDex;
/**
* Extension of {@link android.app.Application}, adding multidex support.
*/
public class FlutterMultiDexApplication extends Application {
@Override
@CallSuper
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}

View File

@@ -5,4 +5,9 @@
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<!-- audio_service -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
</manifest> </manifest>

View File

@@ -1,16 +1,3 @@
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects { allprojects {
repositories { repositories {
google() google()
@@ -26,6 +13,6 @@ subprojects {
project.evaluationDependsOn(':app') project.evaluationDependsOn(':app')
} }
task clean(type: Delete) { tasks.register("clean", Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }

View File

@@ -1,11 +1,25 @@
include ':app' pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()
def localPropertiesFile = new File(rootProject.projectDir, "local.properties") includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
def properties = new Properties()
assert localPropertiesFile.exists() repositories {
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } google()
mavenCentral()
gradlePluginPortal()
}
}
def flutterSdkPath = properties.getProperty("flutter.sdk") plugins {
assert flutterSdkPath != null, "flutter.sdk not set in local.properties" id "dev.flutter.flutter-plugin-loader" version "1.0.0"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" id "com.android.application" version "7.2.0" apply false
id "org.jetbrains.kotlin.android" version "2.0.21" apply false
}
include ":app"

View File

@@ -20,4 +20,5 @@ final lastPathProvider = NotifierProvider<LastPath, String>.internal(
); );
typedef _$LastPath = Notifier<String>; typedef _$LastPath = Notifier<String>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -32,6 +32,8 @@ class RadioPlayFab extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context);
return FloatingActionButton( return FloatingActionButton(
heroTag: null, heroTag: null,
onPressed: onPressed, onPressed: onPressed,
@@ -44,7 +46,7 @@ class RadioPlayFab extends StatelessWidget {
right: -10, right: -10,
child: Icon( child: Icon(
Icons.play_arrow_rounded, Icons.play_arrow_rounded,
color: Theme.of(context).colorScheme.primaryContainer, color: theme.colorScheme.primaryContainer,
size: 26, size: 26,
), ),
), ),

View File

@@ -25,7 +25,7 @@ Future<T?> showContextMenu<T>({
required WidgetBuilder builder, required WidgetBuilder builder,
}) { }) {
return showModalBottomSheet<T>( return showModalBottomSheet<T>(
backgroundColor: ref.read(baseThemeProvider).theme.colorScheme.background, backgroundColor: ref.read(baseThemeProvider).theme.colorScheme.surface,
useRootNavigator: true, useRootNavigator: true,
isScrollControlled: true, isScrollControlled: true,
context: context, context: context,
@@ -327,8 +327,9 @@ class _DownloadAction extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final l = AppLocalizations.of(context);
return _MenuItem( return _MenuItem(
title: _actionText(AppLocalizations.of(context)), title: _actionText(l),
icon: downloadAction.iconBuilder(context), icon: downloadAction.iconBuilder(context),
onTap: downloadAction.action, onTap: downloadAction.action,
); );

View File

@@ -54,11 +54,12 @@ class BackgroundGradient extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final mediaQuery = MediaQuery.of(context);
final base = ref.watch(baseThemeProvider); final base = ref.watch(baseThemeProvider);
return SizedBox( return SizedBox(
width: double.infinity, width: double.infinity,
height: MediaQuery.of(context).size.height, height: mediaQuery.size.height,
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(

View File

@@ -112,9 +112,9 @@ List<DownloadAction> useListDownloadActions({
DownloadAction cancel() { DownloadAction cancel() {
return DownloadAction( return DownloadAction(
type: DownloadActionType.cancel, type: DownloadActionType.cancel,
iconBuilder: (context) => Stack( iconBuilder: (context) => const Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: const [ children: [
Icon(Icons.cancel_rounded), Icon(Icons.cancel_rounded),
SizedBox( SizedBox(
height: 32, height: 32,

View File

@@ -103,6 +103,8 @@ class ArtistArtImage extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
final cache = ref.watch(_artistArtUriCacheInfoProvider( final cache = ref.watch(_artistArtUriCacheInfoProvider(
artistId: artistId, artistId: artistId,
thumbnail: thumbnail, thumbnail: thumbnail,
@@ -123,7 +125,7 @@ class ArtistArtImage extends HookConsumerWidget {
width: width, width: width,
), ),
loading: () => Container( loading: () => Container(
color: Theme.of(context).colorScheme.secondaryContainer, color: theme.colorScheme.secondaryContainer,
height: height, height: height,
width: width, width: width,
), ),
@@ -211,9 +213,11 @@ class CardClip extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final cardShape = Theme.of(context).cardTheme.shape; final cardShape = Theme.of(context).cardTheme.shape;
return ClipRRect( return ClipRRect(
borderRadius: borderRadius: cardShape is RoundedRectangleBorder
cardShape is RoundedRectangleBorder ? cardShape.borderRadius : null, ? cardShape.borderRadius
: BorderRadius.zero,
child: !square child: !square
? child ? child
: AspectRatio( : AspectRatio(
@@ -247,6 +251,8 @@ class UriCacheInfoImage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context);
return CachedNetworkImage( return CachedNetworkImage(
imageUrl: cache.uri.toString(), imageUrl: cache.uri.toString(),
cacheKey: cache.cacheKey, cacheKey: cache.cacheKey,
@@ -260,7 +266,7 @@ class UriCacheInfoImage extends StatelessWidget {
placeholderStyle == PlaceholderStyle.spinner placeholderStyle == PlaceholderStyle.spinner
? Container() ? Container()
: Container( : Container(
color: Theme.of(context).colorScheme.secondaryContainer, color: theme.colorScheme.secondaryContainer,
), ),
errorWidget: (context, url, error) => PlaceholderImage( errorWidget: (context, url, error) => PlaceholderImage(
fit: fit, fit: fit,

View File

@@ -30,8 +30,6 @@ class _SystemHash {
} }
} }
typedef _ArtistArtCacheInfoRef = AutoDisposeProviderRef<CacheInfo>;
/// See also [_artistArtCacheInfo]. /// See also [_artistArtCacheInfo].
@ProviderFor(_artistArtCacheInfo) @ProviderFor(_artistArtCacheInfo)
const _artistArtCacheInfoProvider = _ArtistArtCacheInfoFamily(); const _artistArtCacheInfoProvider = _ArtistArtCacheInfoFamily();
@@ -81,11 +79,11 @@ class _ArtistArtCacheInfoFamily extends Family<CacheInfo> {
class _ArtistArtCacheInfoProvider extends AutoDisposeProvider<CacheInfo> { class _ArtistArtCacheInfoProvider extends AutoDisposeProvider<CacheInfo> {
/// See also [_artistArtCacheInfo]. /// See also [_artistArtCacheInfo].
_ArtistArtCacheInfoProvider({ _ArtistArtCacheInfoProvider({
required this.artistId, required String artistId,
this.thumbnail = true, bool thumbnail = true,
}) : super.internal( }) : this._internal(
(ref) => _artistArtCacheInfo( (ref) => _artistArtCacheInfo(
ref, ref as _ArtistArtCacheInfoRef,
artistId: artistId, artistId: artistId,
thumbnail: thumbnail, thumbnail: thumbnail,
), ),
@@ -98,11 +96,48 @@ class _ArtistArtCacheInfoProvider extends AutoDisposeProvider<CacheInfo> {
dependencies: _ArtistArtCacheInfoFamily._dependencies, dependencies: _ArtistArtCacheInfoFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
_ArtistArtCacheInfoFamily._allTransitiveDependencies, _ArtistArtCacheInfoFamily._allTransitiveDependencies,
artistId: artistId,
thumbnail: thumbnail,
); );
_ArtistArtCacheInfoProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.artistId,
required this.thumbnail,
}) : super.internal();
final String artistId; final String artistId;
final bool thumbnail; final bool thumbnail;
@override
Override overrideWith(
CacheInfo Function(_ArtistArtCacheInfoRef provider) create,
) {
return ProviderOverride(
origin: this,
override: _ArtistArtCacheInfoProvider._internal(
(ref) => create(ref as _ArtistArtCacheInfoRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
artistId: artistId,
thumbnail: thumbnail,
),
);
}
@override
AutoDisposeProviderElement<CacheInfo> createElement() {
return _ArtistArtCacheInfoProviderElement(this);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is _ArtistArtCacheInfoProvider && return other is _ArtistArtCacheInfoProvider &&
@@ -120,9 +155,26 @@ class _ArtistArtCacheInfoProvider extends AutoDisposeProvider<CacheInfo> {
} }
} }
mixin _ArtistArtCacheInfoRef on AutoDisposeProviderRef<CacheInfo> {
/// The parameter `artistId` of this provider.
String get artistId;
/// The parameter `thumbnail` of this provider.
bool get thumbnail;
}
class _ArtistArtCacheInfoProviderElement
extends AutoDisposeProviderElement<CacheInfo> with _ArtistArtCacheInfoRef {
_ArtistArtCacheInfoProviderElement(super.provider);
@override
String get artistId => (origin as _ArtistArtCacheInfoProvider).artistId;
@override
bool get thumbnail => (origin as _ArtistArtCacheInfoProvider).thumbnail;
}
String _$artistArtCachedUrlHash() => String _$artistArtCachedUrlHash() =>
r'2a5e0fea614ff12a1d562faccec6cfe98394af42'; r'2a5e0fea614ff12a1d562faccec6cfe98394af42';
typedef _ArtistArtCachedUrlRef = AutoDisposeFutureProviderRef<String?>;
/// See also [_artistArtCachedUrl]. /// See also [_artistArtCachedUrl].
@ProviderFor(_artistArtCachedUrl) @ProviderFor(_artistArtCachedUrl)
@@ -173,11 +225,11 @@ class _ArtistArtCachedUrlFamily extends Family<AsyncValue<String?>> {
class _ArtistArtCachedUrlProvider extends AutoDisposeFutureProvider<String?> { class _ArtistArtCachedUrlProvider extends AutoDisposeFutureProvider<String?> {
/// See also [_artistArtCachedUrl]. /// See also [_artistArtCachedUrl].
_ArtistArtCachedUrlProvider({ _ArtistArtCachedUrlProvider({
required this.artistId, required String artistId,
this.thumbnail = true, bool thumbnail = true,
}) : super.internal( }) : this._internal(
(ref) => _artistArtCachedUrl( (ref) => _artistArtCachedUrl(
ref, ref as _ArtistArtCachedUrlRef,
artistId: artistId, artistId: artistId,
thumbnail: thumbnail, thumbnail: thumbnail,
), ),
@@ -190,11 +242,48 @@ class _ArtistArtCachedUrlProvider extends AutoDisposeFutureProvider<String?> {
dependencies: _ArtistArtCachedUrlFamily._dependencies, dependencies: _ArtistArtCachedUrlFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
_ArtistArtCachedUrlFamily._allTransitiveDependencies, _ArtistArtCachedUrlFamily._allTransitiveDependencies,
artistId: artistId,
thumbnail: thumbnail,
); );
_ArtistArtCachedUrlProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.artistId,
required this.thumbnail,
}) : super.internal();
final String artistId; final String artistId;
final bool thumbnail; final bool thumbnail;
@override
Override overrideWith(
FutureOr<String?> Function(_ArtistArtCachedUrlRef provider) create,
) {
return ProviderOverride(
origin: this,
override: _ArtistArtCachedUrlProvider._internal(
(ref) => create(ref as _ArtistArtCachedUrlRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
artistId: artistId,
thumbnail: thumbnail,
),
);
}
@override
AutoDisposeFutureProviderElement<String?> createElement() {
return _ArtistArtCachedUrlProviderElement(this);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is _ArtistArtCachedUrlProvider && return other is _ArtistArtCachedUrlProvider &&
@@ -212,9 +301,27 @@ class _ArtistArtCachedUrlProvider extends AutoDisposeFutureProvider<String?> {
} }
} }
mixin _ArtistArtCachedUrlRef on AutoDisposeFutureProviderRef<String?> {
/// The parameter `artistId` of this provider.
String get artistId;
/// The parameter `thumbnail` of this provider.
bool get thumbnail;
}
class _ArtistArtCachedUrlProviderElement
extends AutoDisposeFutureProviderElement<String?>
with _ArtistArtCachedUrlRef {
_ArtistArtCachedUrlProviderElement(super.provider);
@override
String get artistId => (origin as _ArtistArtCachedUrlProvider).artistId;
@override
bool get thumbnail => (origin as _ArtistArtCachedUrlProvider).thumbnail;
}
String _$artistArtUriCacheInfoHash() => String _$artistArtUriCacheInfoHash() =>
r'9bdc0f5654882265236ef746ea697a6d107a4b6f'; r'9bdc0f5654882265236ef746ea697a6d107a4b6f';
typedef _ArtistArtUriCacheInfoRef = AutoDisposeFutureProviderRef<UriCacheInfo>;
/// See also [_artistArtUriCacheInfo]. /// See also [_artistArtUriCacheInfo].
@ProviderFor(_artistArtUriCacheInfo) @ProviderFor(_artistArtUriCacheInfo)
@@ -266,11 +373,11 @@ class _ArtistArtUriCacheInfoProvider
extends AutoDisposeFutureProvider<UriCacheInfo> { extends AutoDisposeFutureProvider<UriCacheInfo> {
/// See also [_artistArtUriCacheInfo]. /// See also [_artistArtUriCacheInfo].
_ArtistArtUriCacheInfoProvider({ _ArtistArtUriCacheInfoProvider({
required this.artistId, required String artistId,
this.thumbnail = true, bool thumbnail = true,
}) : super.internal( }) : this._internal(
(ref) => _artistArtUriCacheInfo( (ref) => _artistArtUriCacheInfo(
ref, ref as _ArtistArtUriCacheInfoRef,
artistId: artistId, artistId: artistId,
thumbnail: thumbnail, thumbnail: thumbnail,
), ),
@@ -283,11 +390,48 @@ class _ArtistArtUriCacheInfoProvider
dependencies: _ArtistArtUriCacheInfoFamily._dependencies, dependencies: _ArtistArtUriCacheInfoFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
_ArtistArtUriCacheInfoFamily._allTransitiveDependencies, _ArtistArtUriCacheInfoFamily._allTransitiveDependencies,
artistId: artistId,
thumbnail: thumbnail,
); );
_ArtistArtUriCacheInfoProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.artistId,
required this.thumbnail,
}) : super.internal();
final String artistId; final String artistId;
final bool thumbnail; final bool thumbnail;
@override
Override overrideWith(
FutureOr<UriCacheInfo> Function(_ArtistArtUriCacheInfoRef provider) create,
) {
return ProviderOverride(
origin: this,
override: _ArtistArtUriCacheInfoProvider._internal(
(ref) => create(ref as _ArtistArtUriCacheInfoRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
artistId: artistId,
thumbnail: thumbnail,
),
);
}
@override
AutoDisposeFutureProviderElement<UriCacheInfo> createElement() {
return _ArtistArtUriCacheInfoProviderElement(this);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is _ArtistArtUriCacheInfoProvider && return other is _ArtistArtUriCacheInfoProvider &&
@@ -304,4 +448,24 @@ class _ArtistArtUriCacheInfoProvider
return _SystemHash.finish(hash); return _SystemHash.finish(hash);
} }
} }
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
mixin _ArtistArtUriCacheInfoRef on AutoDisposeFutureProviderRef<UriCacheInfo> {
/// The parameter `artistId` of this provider.
String get artistId;
/// The parameter `thumbnail` of this provider.
bool get thumbnail;
}
class _ArtistArtUriCacheInfoProviderElement
extends AutoDisposeFutureProviderElement<UriCacheInfo>
with _ArtistArtUriCacheInfoRef {
_ArtistArtUriCacheInfoProviderElement(super.provider);
@override
String get artistId => (origin as _ArtistArtUriCacheInfoProvider).artistId;
@override
bool get thumbnail => (origin as _ArtistArtUriCacheInfoProvider).thumbnail;
}
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -204,12 +204,14 @@ class ArtistListTile extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final l = AppLocalizations.of(context);
return ListTile( return ListTile(
leading: CircleClip( leading: CircleClip(
child: ArtistArtImage(artistId: artist.id), child: ArtistArtImage(artistId: artist.id),
), ),
title: Text(artist.name), title: Text(artist.name),
subtitle: Text(AppLocalizations.of(context).resourcesAlbumCount( subtitle: Text(l.resourcesAlbumCount(
artist.albumCount, artist.albumCount,
)), )),
onTap: onTap, onTap: onTap,
@@ -239,6 +241,8 @@ class PlaylistListTile extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final l = AppLocalizations.of(context);
// generate the palette used in other views ahead of time // generate the palette used in other views ahead of time
ref.watch(playlistArtPaletteProvider(playlist.id)); ref.watch(playlistArtPaletteProvider(playlist.id));
final cache = ref.watch(cacheServiceProvider).playlistArt(playlist); final cache = ref.watch(cacheServiceProvider).playlistArt(playlist);
@@ -248,7 +252,7 @@ class PlaylistListTile extends HookConsumerWidget {
child: UriCacheInfoImage(cache: cache), child: UriCacheInfoImage(cache: cache),
), ),
title: Text(playlist.name), title: Text(playlist.name),
subtitle: Text(AppLocalizations.of(context).resourcesSongCount( subtitle: Text(l.resourcesSongCount(
playlist.songCount, playlist.songCount,
)), )),
onTap: onTap, onTap: onTap,

View File

@@ -4,6 +4,7 @@ import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import '../services/sync_service.dart'; import '../services/sync_service.dart';
import 'items.dart'; import 'items.dart';
import 'snackbars.dart';
class PagedListQueryView<T> extends HookConsumerWidget { class PagedListQueryView<T> extends HookConsumerWidget {
final PagingController<int, T> pagingController; final PagingController<int, T> pagingController;
@@ -71,6 +72,8 @@ class PagedGridQueryView<T> extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final mediaQuery = MediaQuery.of(context);
SliverGridDelegate gridDelegate; SliverGridDelegate gridDelegate;
double spacing; double spacing;
@@ -91,7 +94,7 @@ class PagedGridQueryView<T> extends HookConsumerWidget {
} }
final listView = PagedGridView<int, T>( final listView = PagedGridView<int, T>(
padding: MediaQuery.of(context).padding + EdgeInsets.all(spacing), padding: mediaQuery.padding + EdgeInsets.all(spacing),
pagingController: pagingController, pagingController: pagingController,
builderDelegate: PagedChildBuilderDelegate( builderDelegate: PagedChildBuilderDelegate(
itemBuilder: (context, item, index) => itemBuilder: (context, item, index) =>
@@ -122,7 +125,14 @@ class SyncAllRefresh extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
return RefreshIndicator( return RefreshIndicator(
onRefresh: () => ref.read(syncServiceProvider.notifier).syncAll(), onRefresh: () async {
try {
await ref.read(syncServiceProvider.notifier).syncAll();
} catch (e) {
if (!context.mounted) return;
showErrorSnackbar(context, e.toString());
}
},
child: child, child: child,
); );
} }

View File

@@ -30,13 +30,13 @@ class NowPlayingBar extends HookConsumerWidget {
elevation: 3, elevation: 3,
color: colors?.darkBackground, color: colors?.darkBackground,
// surfaceTintColor: theme?.colorScheme.background, // surfaceTintColor: theme?.colorScheme.background,
child: Column( child: const Column(
children: [ children: [
SizedBox( SizedBox(
height: 70, height: 70,
child: Row( child: Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: const [ children: [
Padding( Padding(
padding: EdgeInsets.all(10), padding: EdgeInsets.all(10),
child: _ArtImage(), child: _ArtImage(),
@@ -54,7 +54,7 @@ class NowPlayingBar extends HookConsumerWidget {
], ],
), ),
), ),
const _ProgressBar(), _ProgressBar(),
], ],
), ),
), ),
@@ -112,6 +112,8 @@ class _TrackInfo extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
final item = ref.watch(mediaItemProvider); final item = ref.watch(mediaItemProvider);
return Column( return Column(
@@ -125,11 +127,11 @@ class _TrackInfo extends HookConsumerWidget {
// maxLines: 1, // maxLines: 1,
// softWrap: false, // softWrap: false,
// overflow: TextOverflow.fade, // overflow: TextOverflow.fade,
// style: Theme.of(context).textTheme.labelLarge, // style: theme.textTheme.labelLarge,
// ), // ),
ScrollableText( ScrollableText(
data?.title ?? 'Nothing!!!', data?.title ?? 'Nothing!!!',
style: Theme.of(context).textTheme.labelLarge, style: theme.textTheme.labelLarge,
), ),
const SizedBox(height: 2), const SizedBox(height: 2),
Text( Text(
@@ -137,7 +139,7 @@ class _TrackInfo extends HookConsumerWidget {
maxLines: 1, maxLines: 1,
softWrap: false, softWrap: false,
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
style: Theme.of(context).textTheme.labelMedium, style: theme.textTheme.labelMedium,
), ),
], ],
error: (_, __) => const [Text('Error!')], error: (_, __) => const [Text('Error!')],
@@ -158,6 +160,8 @@ class PlayPauseButton extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
final playing = ref.watch(playingProvider); final playing = ref.watch(playingProvider);
final state = ref.watch(processingStateProvider); final state = ref.watch(processingStateProvider);
@@ -173,7 +177,7 @@ class PlayPauseButton extends HookConsumerWidget {
width: size / 3, width: size / 3,
child: CircularProgressIndicator( child: CircularProgressIndicator(
strokeWidth: size / 16, strokeWidth: size / 16,
color: Theme.of(context).colorScheme.background, color: theme.colorScheme.surface,
), ),
), ),
], ],
@@ -195,7 +199,7 @@ class PlayPauseButton extends HookConsumerWidget {
} }
}, },
icon: icon, icon: icon,
color: Theme.of(context).colorScheme.onBackground, color: theme.colorScheme.surface,
); );
} }
} }

View File

@@ -118,10 +118,11 @@ class _Title extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context);
return Text( return Text(
text, text,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.displayMedium!.copyWith( style: theme.textTheme.displayMedium!.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.white, color: Colors.white,
shadows: [ shadows: [

View File

@@ -46,6 +46,8 @@ class BottomNavTabsPage extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
final observer = ref.watch(bottomTabObserverProvider); final observer = ref.watch(bottomTabObserverProvider);
const navElevation = 3.0; const navElevation = 3.0;
@@ -63,8 +65,8 @@ class BottomNavTabsPage extends HookConsumerWidget {
return AnnotatedRegion<SystemUiOverlayStyle>( return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light.copyWith( value: SystemUiOverlayStyle.light.copyWith(
systemNavigationBarColor: ElevationOverlay.applySurfaceTint( systemNavigationBarColor: ElevationOverlay.applySurfaceTint(
Theme.of(context).colorScheme.surface, theme.colorScheme.surface,
Theme.of(context).colorScheme.surfaceTint, theme.colorScheme.surfaceTint,
navElevation, navElevation,
), ),
statusBarColor: Colors.transparent, statusBarColor: Colors.transparent,
@@ -111,13 +113,13 @@ class OfflineIndicator extends HookConsumerWidget {
), ),
child: FilledButton.tonal( child: FilledButton.tonal(
style: const ButtonStyle( style: const ButtonStyle(
padding: MaterialStatePropertyAll<EdgeInsetsGeometry>( padding: WidgetStatePropertyAll<EdgeInsetsGeometry>(
EdgeInsets.zero, EdgeInsets.zero,
), ),
fixedSize: MaterialStatePropertyAll<Size>( fixedSize: WidgetStatePropertyAll<Size>(
Size(42, 42), Size(42, 42),
), ),
minimumSize: MaterialStatePropertyAll<Size>( minimumSize: WidgetStatePropertyAll<Size>(
Size(42, 42), Size(42, 42),
), ),
), ),
@@ -136,7 +138,6 @@ class OfflineIndicator extends HookConsumerWidget {
padding: EdgeInsets.only(left: 2, bottom: 2), padding: EdgeInsets.only(left: 2, bottom: 2),
child: Icon( child: Icon(
Icons.cloud_off_rounded, Icons.cloud_off_rounded,
// color: Theme.of(context).colorScheme.secondary,
size: 20, size: 20,
), ),
), ),
@@ -154,6 +155,7 @@ class _BottomNavBar extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final iconTheme = IconTheme.of(context);
final tabsRouter = AutoTabsRouter.of(context); final tabsRouter = AutoTabsRouter.of(context);
useListenableSelector(tabsRouter, () => tabsRouter.activeIndex); useListenableSelector(tabsRouter, () => tabsRouter.activeIndex);
@@ -190,9 +192,7 @@ class _BottomNavBar extends HookConsumerWidget {
return SvgPicture.asset( return SvgPicture.asset(
'assets/tag_FILL0_wght400_GRAD0_opsz24.svg', 'assets/tag_FILL0_wght400_GRAD0_opsz24.svg',
colorFilter: ColorFilter.mode( colorFilter: ColorFilter.mode(
IconTheme.of(context).color!.withOpacity( iconTheme.color!.withOpacity(iconTheme.opacity ?? 1),
IconTheme.of(context).opacity ?? 1,
),
BlendMode.srcIn, BlendMode.srcIn,
), ),
height: 28, height: 28,

View File

@@ -53,4 +53,5 @@ final lastBottomNavStateServiceProvider =
); );
typedef _$LastBottomNavStateService = AsyncNotifier<void>; typedef _$LastBottomNavStateService = AsyncNotifier<void>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -249,6 +249,8 @@ class _Category extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
return MultiSliver( return MultiSliver(
children: [ children: [
SliverToBoxAdapter( SliverToBoxAdapter(
@@ -256,7 +258,7 @@ class _Category extends HookConsumerWidget {
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Text( child: Text(
title, title,
style: Theme.of(context).textTheme.headlineMedium, style: theme.textTheme.headlineMedium,
), ),
), ),
), ),

View File

@@ -30,8 +30,6 @@ class _SystemHash {
} }
} }
typedef AlbumsCategoryListRef = AutoDisposeStreamProviderRef<List<Album>>;
/// See also [albumsCategoryList]. /// See also [albumsCategoryList].
@ProviderFor(albumsCategoryList) @ProviderFor(albumsCategoryList)
const albumsCategoryListProvider = AlbumsCategoryListFamily(); const albumsCategoryListProvider = AlbumsCategoryListFamily();
@@ -79,10 +77,10 @@ class AlbumsCategoryListProvider
extends AutoDisposeStreamProvider<List<Album>> { extends AutoDisposeStreamProvider<List<Album>> {
/// See also [albumsCategoryList]. /// See also [albumsCategoryList].
AlbumsCategoryListProvider( AlbumsCategoryListProvider(
this.opt, ListQuery opt,
) : super.internal( ) : this._internal(
(ref) => albumsCategoryList( (ref) => albumsCategoryList(
ref, ref as AlbumsCategoryListRef,
opt, opt,
), ),
from: albumsCategoryListProvider, from: albumsCategoryListProvider,
@@ -94,10 +92,44 @@ class AlbumsCategoryListProvider
dependencies: AlbumsCategoryListFamily._dependencies, dependencies: AlbumsCategoryListFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
AlbumsCategoryListFamily._allTransitiveDependencies, AlbumsCategoryListFamily._allTransitiveDependencies,
opt: opt,
); );
AlbumsCategoryListProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.opt,
}) : super.internal();
final ListQuery opt; final ListQuery opt;
@override
Override overrideWith(
Stream<List<Album>> Function(AlbumsCategoryListRef provider) create,
) {
return ProviderOverride(
origin: this,
override: AlbumsCategoryListProvider._internal(
(ref) => create(ref as AlbumsCategoryListRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
opt: opt,
),
);
}
@override
AutoDisposeStreamProviderElement<List<Album>> createElement() {
return _AlbumsCategoryListProviderElement(this);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is AlbumsCategoryListProvider && other.opt == opt; return other is AlbumsCategoryListProvider && other.opt == opt;
@@ -111,4 +143,19 @@ class AlbumsCategoryListProvider
return _SystemHash.finish(hash); return _SystemHash.finish(hash);
} }
} }
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
mixin AlbumsCategoryListRef on AutoDisposeStreamProviderRef<List<Album>> {
/// The parameter `opt` of this provider.
ListQuery get opt;
}
class _AlbumsCategoryListProviderElement
extends AutoDisposeStreamProviderElement<List<Album>>
with AlbumsCategoryListRef {
_AlbumsCategoryListProviderElement(super.provider);
@override
ListQuery get opt => (origin as AlbumsCategoryListProvider).opt;
}
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -228,6 +228,8 @@ class _LibraryFilterFab extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
final tabsRouter = AutoTabsRouter.of(context); final tabsRouter = AutoTabsRouter.of(context);
final activeIndex = final activeIndex =
useListenableSelector(tabsRouter, () => tabsRouter.activeIndex); useListenableSelector(tabsRouter, () => tabsRouter.activeIndex);
@@ -242,7 +244,7 @@ class _LibraryFilterFab extends HookConsumerWidget {
end: 0, end: 0,
child: Icon( child: Icon(
Icons.circle, Icons.circle,
color: Theme.of(context).colorScheme.primaryContainer, color: theme.colorScheme.primaryContainer,
size: 11, size: 11,
), ),
), ),
@@ -449,6 +451,8 @@ class ListSortFilterOptions extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
final list = ref.watch(libraryListQueryProvider(index)); final list = ref.watch(libraryListQueryProvider(index));
return SliverList( return SliverList(
@@ -457,7 +461,7 @@ class ListSortFilterOptions extends HookConsumerWidget {
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text( child: Text(
'Sort by', 'Sort by',
style: Theme.of(context).textTheme.titleLarge, style: theme.textTheme.titleLarge,
), ),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
@@ -480,7 +484,7 @@ class ListSortFilterOptions extends HookConsumerWidget {
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text( child: Text(
'Filter', 'Filter',
style: Theme.of(context).textTheme.titleLarge, style: theme.textTheme.titleLarge,
), ),
), ),
for (var column in list.options.filterColumns) for (var column in list.options.filterColumns)

View File

@@ -60,8 +60,6 @@ class _SystemHash {
} }
} }
typedef LibraryListQueryRef = ProviderRef<LibraryListQuery>;
/// See also [libraryListQuery]. /// See also [libraryListQuery].
@ProviderFor(libraryListQuery) @ProviderFor(libraryListQuery)
const libraryListQueryProvider = LibraryListQueryFamily(); const libraryListQueryProvider = LibraryListQueryFamily();
@@ -108,10 +106,10 @@ class LibraryListQueryFamily extends Family<LibraryListQuery> {
class LibraryListQueryProvider extends Provider<LibraryListQuery> { class LibraryListQueryProvider extends Provider<LibraryListQuery> {
/// See also [libraryListQuery]. /// See also [libraryListQuery].
LibraryListQueryProvider( LibraryListQueryProvider(
this.index, int index,
) : super.internal( ) : this._internal(
(ref) => libraryListQuery( (ref) => libraryListQuery(
ref, ref as LibraryListQueryRef,
index, index,
), ),
from: libraryListQueryProvider, from: libraryListQueryProvider,
@@ -123,10 +121,44 @@ class LibraryListQueryProvider extends Provider<LibraryListQuery> {
dependencies: LibraryListQueryFamily._dependencies, dependencies: LibraryListQueryFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
LibraryListQueryFamily._allTransitiveDependencies, LibraryListQueryFamily._allTransitiveDependencies,
index: index,
); );
LibraryListQueryProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.index,
}) : super.internal();
final int index; final int index;
@override
Override overrideWith(
LibraryListQuery Function(LibraryListQueryRef provider) create,
) {
return ProviderOverride(
origin: this,
override: LibraryListQueryProvider._internal(
(ref) => create(ref as LibraryListQueryRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
index: index,
),
);
}
@override
ProviderElement<LibraryListQuery> createElement() {
return _LibraryListQueryProviderElement(this);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is LibraryListQueryProvider && other.index == index; return other is LibraryListQueryProvider && other.index == index;
@@ -141,6 +173,19 @@ class LibraryListQueryProvider extends Provider<LibraryListQuery> {
} }
} }
mixin LibraryListQueryRef on ProviderRef<LibraryListQuery> {
/// The parameter `index` of this provider.
int get index;
}
class _LibraryListQueryProviderElement extends ProviderElement<LibraryListQuery>
with LibraryListQueryRef {
_LibraryListQueryProviderElement(super.provider);
@override
int get index => (origin as LibraryListQueryProvider).index;
}
String _$lastLibraryStateServiceHash() => String _$lastLibraryStateServiceHash() =>
r'a49e26b5dc0fcb0f697ec2def08e7336f64c4cb3'; r'a49e26b5dc0fcb0f697ec2def08e7336f64c4cb3';
@@ -173,4 +218,5 @@ final libraryListsProvider =
); );
typedef _$LibraryLists = Notifier<IList<LibraryListQuery>>; typedef _$LibraryLists = Notifier<IList<LibraryListQuery>>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -29,8 +29,6 @@ class _SystemHash {
} }
} }
typedef SongsListRef = AutoDisposeFutureProviderRef<List<Song>>;
/// See also [songsList]. /// See also [songsList].
@ProviderFor(songsList) @ProviderFor(songsList)
const songsListProvider = SongsListFamily(); const songsListProvider = SongsListFamily();
@@ -77,10 +75,10 @@ class SongsListFamily extends Family<AsyncValue<List<Song>>> {
class SongsListProvider extends AutoDisposeFutureProvider<List<Song>> { class SongsListProvider extends AutoDisposeFutureProvider<List<Song>> {
/// See also [songsList]. /// See also [songsList].
SongsListProvider( SongsListProvider(
this.opt, ListQuery opt,
) : super.internal( ) : this._internal(
(ref) => songsList( (ref) => songsList(
ref, ref as SongsListRef,
opt, opt,
), ),
from: songsListProvider, from: songsListProvider,
@@ -91,10 +89,44 @@ class SongsListProvider extends AutoDisposeFutureProvider<List<Song>> {
: _$songsListHash, : _$songsListHash,
dependencies: SongsListFamily._dependencies, dependencies: SongsListFamily._dependencies,
allTransitiveDependencies: SongsListFamily._allTransitiveDependencies, allTransitiveDependencies: SongsListFamily._allTransitiveDependencies,
opt: opt,
); );
SongsListProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.opt,
}) : super.internal();
final ListQuery opt; final ListQuery opt;
@override
Override overrideWith(
FutureOr<List<Song>> Function(SongsListRef provider) create,
) {
return ProviderOverride(
origin: this,
override: SongsListProvider._internal(
(ref) => create(ref as SongsListRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
opt: opt,
),
);
}
@override
AutoDisposeFutureProviderElement<List<Song>> createElement() {
return _SongsListProviderElement(this);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is SongsListProvider && other.opt == opt; return other is SongsListProvider && other.opt == opt;
@@ -108,4 +140,18 @@ class SongsListProvider extends AutoDisposeFutureProvider<List<Song>> {
return _SystemHash.finish(hash); return _SystemHash.finish(hash);
} }
} }
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
mixin SongsListRef on AutoDisposeFutureProviderRef<List<Song>> {
/// The parameter `opt` of this provider.
ListQuery get opt;
}
class _SongsListProviderElement
extends AutoDisposeFutureProviderElement<List<Song>> with SongsListRef {
_SongsListProviderElement(super.provider);
@override
ListQuery get opt => (origin as SongsListProvider).opt;
}
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -55,13 +55,13 @@ class NowPlayingPage extends HookConsumerWidget {
], ],
), ),
), ),
body: Stack( body: const Stack(
children: [ children: [
const MediaItemGradient(), MediaItemGradient(),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8), padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: Column( child: Column(
children: const [ children: [
Expanded( Expanded(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16), padding: EdgeInsets.symmetric(horizontal: 16),
@@ -215,6 +215,8 @@ class _Progress extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
final colors = ref.watch(mediaItemThemeProvider).valueOrNull; final colors = ref.watch(mediaItemThemeProvider).valueOrNull;
final position = ref.watch(positionProvider); final position = ref.watch(positionProvider);
final duration = ref.watch(durationProvider); final duration = ref.watch(durationProvider);
@@ -229,8 +231,8 @@ class _Progress extends HookConsumerWidget {
value: changing.value ? changeValue.value : position.toDouble(), value: changing.value ? changeValue.value : position.toDouble(),
min: 0, min: 0,
max: max(duration.toDouble(), position.toDouble()), max: max(duration.toDouble(), position.toDouble()),
thumbColor: colors?.theme.colorScheme.onBackground, thumbColor: colors?.theme.colorScheme.surface,
activeColor: colors?.theme.colorScheme.onBackground, activeColor: colors?.theme.colorScheme.surface,
inactiveColor: colors?.theme.colorScheme.surface, inactiveColor: colors?.theme.colorScheme.surface,
onChanged: (value) { onChanged: (value) {
changeValue.value = value; changeValue.value = value;
@@ -246,7 +248,7 @@ class _Progress extends HookConsumerWidget {
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 24), padding: const EdgeInsets.symmetric(horizontal: 24),
child: DefaultTextStyle( child: DefaultTextStyle(
style: Theme.of(context).textTheme.titleMedium!, style: theme.textTheme.titleMedium!,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@@ -354,7 +356,7 @@ class _Controls extends HookConsumerWidget {
final audio = ref.watch(audioControlProvider); final audio = ref.watch(audioControlProvider);
return IconTheme( return IconTheme(
data: IconThemeData(color: base.theme.colorScheme.onBackground), data: IconThemeData(color: base.theme.colorScheme.surface),
child: Column( child: Column(
children: [ children: [
SizedBox( SizedBox(

View File

@@ -131,11 +131,11 @@ class _SectionHeader extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context).textTheme; final theme = Theme.of(context);
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text(title, style: theme.headlineMedium), child: Text(title, style: theme.textTheme.headlineMedium),
); );
} }
} }

View File

@@ -35,4 +35,5 @@ final searchQueryProvider =
); );
typedef _$SearchQuery = AutoDisposeNotifier<String?>; typedef _$SearchQuery = AutoDisposeNotifier<String?>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -1,11 +1,16 @@
import 'dart:math';
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart'; import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:path/path.dart' as p;
import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../log.dart';
import '../../models/support.dart'; import '../../models/support.dart';
import '../../services/settings_service.dart'; import '../../services/settings_service.dart';
import '../../state/init.dart'; import '../../state/init.dart';
@@ -162,6 +167,54 @@ class _About extends HookConsumerWidget {
mode: LaunchMode.externalApplication, mode: LaunchMode.externalApplication,
), ),
), ),
const SizedBox(height: 12),
const _ShareLogsButton(),
],
);
}
}
class _ShareLogsButton extends StatelessWidget {
const _ShareLogsButton();
@override
Widget build(BuildContext context) {
final l = AppLocalizations.of(context);
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton.icon(
icon: const Icon(Icons.share),
label: Text(l.settingsAboutShareLogs),
onPressed: () async {
final files = await logFiles();
if (files.isEmpty) return;
if (!context.mounted) return;
final value = await showDialog<String>(
context: context,
builder: (context) => MultipleChoiceDialog<String>(
title: l.settingsAboutChooseLog,
current: files.first.path,
options: files
.map((e) => MultiChoiceOption.string(
title: p.basename(e.path),
option: e.path,
))
.toIList(),
),
);
if (value == null) return;
Share.shareXFiles(
[XFile(value, mimeType: 'text/plain')],
subject: 'Logs from subtracks: ${String.fromCharCodes(
List.generate(8, (_) => Random().nextInt(26) + 65),
)}',
);
},
),
], ],
); );
} }

View File

@@ -8,9 +8,11 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../database/database.dart'; import '../../database/database.dart';
import '../../log.dart';
import '../../models/settings.dart'; import '../../models/settings.dart';
import '../../services/settings_service.dart'; import '../../services/settings_service.dart';
import '../items.dart'; import '../items.dart';
import '../snackbars.dart';
class SourcePage extends HookConsumerWidget { class SourcePage extends HookConsumerWidget {
final int? id; final int? id;
@@ -44,7 +46,7 @@ class SourcePage extends HookConsumerWidget {
autofillHints: const [AutofillHints.url], autofillHints: const [AutofillHints.url],
required: true, required: true,
validator: (value, label) { validator: (value, label) {
if (Uri.tryParse(value!) == null) { if (!value!.contains(RegExp(r'https?:\/\/'))) {
return '$label must be a valid URL'; return '$label must be a valid URL';
} }
return null; return null;
@@ -64,7 +66,7 @@ class SourcePage extends HookConsumerWidget {
required: true, required: true,
); );
final forcePlaintextPassword = useState(!(source?.useTokenAuth ?? false)); final forcePlaintextPassword = useState(!(source?.useTokenAuth ?? true));
final forcePlaintextSwitch = SwitchListTile( final forcePlaintextSwitch = SwitchListTile(
value: forcePlaintextPassword.value, value: forcePlaintextPassword.value,
title: Text(l.settingsServersOptionsForcePlaintextPasswordTitle), title: Text(l.settingsServersOptionsForcePlaintextPasswordTitle),
@@ -74,8 +76,8 @@ class SourcePage extends HookConsumerWidget {
onChanged: (value) => forcePlaintextPassword.value = value, onChanged: (value) => forcePlaintextPassword.value = value,
); );
return WillPopScope( return PopScope(
onWillPop: () async => !isSaving.value && !isDeleting.value, canPop: !isSaving.value && !isDeleting.value,
child: Scaffold( child: Scaffold(
appBar: AppBar(), appBar: AppBar(),
floatingActionButton: Row( floatingActionButton: Row(
@@ -161,8 +163,10 @@ class SourcePage extends HookConsumerWidget {
), ),
); );
} }
} catch (err) { } catch (e, st) {
// TOOD: toast the error or whatever if (!context.mounted) return;
showErrorSnackbar(context, e.toString());
log.severe('Saving source', e, st);
error = true; error = true;
} finally { } finally {
isSaving.value = false; isSaving.value = false;

14
lib/app/snackbars.dart Normal file
View File

@@ -0,0 +1,14 @@
import 'package:flutter/material.dart';
void showErrorSnackbar(BuildContext context, String message) {
final colors = Theme.of(context).colorScheme;
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(message, style: TextStyle(color: colors.onErrorContainer)),
backgroundColor: colors.errorContainer,
showCloseIcon: true,
closeIconColor: colors.onErrorContainer,
behavior: SnackBarBehavior.floating,
duration: const Duration(seconds: 10),
));
}

View File

@@ -20,4 +20,5 @@ final imageCacheProvider = Provider<CacheManager>.internal(
); );
typedef ImageCacheRef = ProviderRef<CacheManager>; typedef ImageCacheRef = ProviderRef<CacheManager>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -9,11 +9,13 @@ import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../log.dart';
import '../models/music.dart'; import '../models/music.dart';
import '../models/query.dart'; import '../models/query.dart';
import '../models/settings.dart'; import '../models/settings.dart';
import '../models/support.dart'; import '../models/support.dart';
import 'converters.dart'; import 'converters.dart';
import 'error_logging_database.dart';
part 'database.g.dart'; part 'database.g.dart';
@@ -435,7 +437,11 @@ LazyDatabase _openConnection() {
final dbFolder = await getApplicationDocumentsDirectory(); final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'subtracks.sqlite')); final file = File(p.join(dbFolder.path, 'subtracks.sqlite'));
// return NativeDatabase.createInBackground(file, logStatements: true); // return NativeDatabase.createInBackground(file, logStatements: true);
return NativeDatabase.createInBackground(file);
return ErrorLoggingDatabase(
NativeDatabase.createInBackground(file),
(e, s) => log.severe('SQL error', e, s),
);
}); });
} }

View File

@@ -53,9 +53,10 @@ class Queue extends Table with TableInfo<Queue, QueueData> {
List<GeneratedColumn> get $columns => List<GeneratedColumn> get $columns =>
[index, sourceId, id, context, contextId, currentTrack]; [index, sourceId, id, context, contextId, currentTrack];
@override @override
String get aliasedName => _alias ?? 'queue'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'queue'; String get actualTableName => $name;
static const String $name = 'queue';
@override @override
VerificationContext validateIntegrity(Insertable<QueueData> instance, VerificationContext validateIntegrity(Insertable<QueueData> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -144,8 +145,7 @@ class QueueData extends DataClass implements Insertable<QueueData> {
map['source_id'] = Variable<int>(sourceId); map['source_id'] = Variable<int>(sourceId);
map['id'] = Variable<String>(id); map['id'] = Variable<String>(id);
{ {
final converter = Queue.$convertercontext; map['context'] = Variable<String>(Queue.$convertercontext.toSql(context));
map['context'] = Variable<String>(converter.toSql(context));
} }
if (!nullToAbsent || contextId != null) { if (!nullToAbsent || contextId != null) {
map['context_id'] = Variable<String>(contextId); map['context_id'] = Variable<String>(contextId);
@@ -315,8 +315,8 @@ class QueueCompanion extends UpdateCompanion<QueueData> {
map['id'] = Variable<String>(id.value); map['id'] = Variable<String>(id.value);
} }
if (context.present) { if (context.present) {
final converter = Queue.$convertercontext; map['context'] =
map['context'] = Variable<String>(converter.toSql(context.value)); Variable<String>(Queue.$convertercontext.toSql(context.value));
} }
if (contextId.present) { if (contextId.present) {
map['context_id'] = Variable<String>(contextId.value); map['context_id'] = Variable<String>(contextId.value);
@@ -382,9 +382,10 @@ class LastAudioState extends Table
List<GeneratedColumn> get $columns => List<GeneratedColumn> get $columns =>
[id, queueMode, shuffleIndicies, repeat]; [id, queueMode, shuffleIndicies, repeat];
@override @override
String get aliasedName => _alias ?? 'last_audio_state'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'last_audio_state'; String get actualTableName => $name;
static const String $name = 'last_audio_state';
@override @override
VerificationContext validateIntegrity(Insertable<LastAudioStateData> instance, VerificationContext validateIntegrity(Insertable<LastAudioStateData> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -452,17 +453,16 @@ class LastAudioStateData extends DataClass
final map = <String, Expression>{}; final map = <String, Expression>{};
map['id'] = Variable<int>(id); map['id'] = Variable<int>(id);
{ {
final converter = LastAudioState.$converterqueueMode; map['queue_mode'] =
map['queue_mode'] = Variable<int>(converter.toSql(queueMode)); Variable<int>(LastAudioState.$converterqueueMode.toSql(queueMode));
} }
if (!nullToAbsent || shuffleIndicies != null) { if (!nullToAbsent || shuffleIndicies != null) {
final converter = LastAudioState.$convertershuffleIndiciesn; map['shuffle_indicies'] = Variable<String>(
map['shuffle_indicies'] = LastAudioState.$convertershuffleIndiciesn.toSql(shuffleIndicies));
Variable<String>(converter.toSql(shuffleIndicies));
} }
{ {
final converter = LastAudioState.$converterrepeat; map['repeat'] =
map['repeat'] = Variable<int>(converter.toSql(repeat)); Variable<int>(LastAudioState.$converterrepeat.toSql(repeat));
} }
return map; return map;
} }
@@ -592,17 +592,17 @@ class LastAudioStateCompanion extends UpdateCompanion<LastAudioStateData> {
map['id'] = Variable<int>(id.value); map['id'] = Variable<int>(id.value);
} }
if (queueMode.present) { if (queueMode.present) {
final converter = LastAudioState.$converterqueueMode; map['queue_mode'] = Variable<int>(
map['queue_mode'] = Variable<int>(converter.toSql(queueMode.value)); LastAudioState.$converterqueueMode.toSql(queueMode.value));
} }
if (shuffleIndicies.present) { if (shuffleIndicies.present) {
final converter = LastAudioState.$convertershuffleIndiciesn; map['shuffle_indicies'] = Variable<String>(LastAudioState
map['shuffle_indicies'] = .$convertershuffleIndiciesn
Variable<String>(converter.toSql(shuffleIndicies.value)); .toSql(shuffleIndicies.value));
} }
if (repeat.present) { if (repeat.present) {
final converter = LastAudioState.$converterrepeat; map['repeat'] =
map['repeat'] = Variable<int>(converter.toSql(repeat.value)); Variable<int>(LastAudioState.$converterrepeat.toSql(repeat.value));
} }
return map; return map;
} }
@@ -640,9 +640,10 @@ class LastBottomNavState extends Table
@override @override
List<GeneratedColumn> get $columns => [id, tab]; List<GeneratedColumn> get $columns => [id, tab];
@override @override
String get aliasedName => _alias ?? 'last_bottom_nav_state'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'last_bottom_nav_state'; String get actualTableName => $name;
static const String $name = 'last_bottom_nav_state';
@override @override
VerificationContext validateIntegrity( VerificationContext validateIntegrity(
Insertable<LastBottomNavStateData> instance, Insertable<LastBottomNavStateData> instance,
@@ -849,9 +850,10 @@ class LastLibraryState extends Table
List<GeneratedColumn> get $columns => List<GeneratedColumn> get $columns =>
[id, tab, albumsList, artistsList, playlistsList, songsList]; [id, tab, albumsList, artistsList, playlistsList, songsList];
@override @override
String get aliasedName => _alias ?? 'last_library_state'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'last_library_state'; String get actualTableName => $name;
static const String $name = 'last_library_state';
@override @override
VerificationContext validateIntegrity( VerificationContext validateIntegrity(
Insertable<LastLibraryStateData> instance, Insertable<LastLibraryStateData> instance,
@@ -937,20 +939,20 @@ class LastLibraryStateData extends DataClass
map['id'] = Variable<int>(id); map['id'] = Variable<int>(id);
map['tab'] = Variable<String>(tab); map['tab'] = Variable<String>(tab);
{ {
final converter = LastLibraryState.$converteralbumsList; map['albums_list'] = Variable<String>(
map['albums_list'] = Variable<String>(converter.toSql(albumsList)); LastLibraryState.$converteralbumsList.toSql(albumsList));
} }
{ {
final converter = LastLibraryState.$converterartistsList; map['artists_list'] = Variable<String>(
map['artists_list'] = Variable<String>(converter.toSql(artistsList)); LastLibraryState.$converterartistsList.toSql(artistsList));
} }
{ {
final converter = LastLibraryState.$converterplaylistsList; map['playlists_list'] = Variable<String>(
map['playlists_list'] = Variable<String>(converter.toSql(playlistsList)); LastLibraryState.$converterplaylistsList.toSql(playlistsList));
} }
{ {
final converter = LastLibraryState.$convertersongsList; map['songs_list'] = Variable<String>(
map['songs_list'] = Variable<String>(converter.toSql(songsList)); LastLibraryState.$convertersongsList.toSql(songsList));
} }
return map; return map;
} }
@@ -1106,22 +1108,20 @@ class LastLibraryStateCompanion extends UpdateCompanion<LastLibraryStateData> {
map['tab'] = Variable<String>(tab.value); map['tab'] = Variable<String>(tab.value);
} }
if (albumsList.present) { if (albumsList.present) {
final converter = LastLibraryState.$converteralbumsList; map['albums_list'] = Variable<String>(
map['albums_list'] = Variable<String>(converter.toSql(albumsList.value)); LastLibraryState.$converteralbumsList.toSql(albumsList.value));
} }
if (artistsList.present) { if (artistsList.present) {
final converter = LastLibraryState.$converterartistsList; map['artists_list'] = Variable<String>(
map['artists_list'] = LastLibraryState.$converterartistsList.toSql(artistsList.value));
Variable<String>(converter.toSql(artistsList.value));
} }
if (playlistsList.present) { if (playlistsList.present) {
final converter = LastLibraryState.$converterplaylistsList; map['playlists_list'] = Variable<String>(
map['playlists_list'] = LastLibraryState.$converterplaylistsList.toSql(playlistsList.value));
Variable<String>(converter.toSql(playlistsList.value));
} }
if (songsList.present) { if (songsList.present) {
final converter = LastLibraryState.$convertersongsList; map['songs_list'] = Variable<String>(
map['songs_list'] = Variable<String>(converter.toSql(songsList.value)); LastLibraryState.$convertersongsList.toSql(songsList.value));
} }
return map; return map;
} }
@@ -1177,9 +1177,10 @@ class AppSettingsTable extends Table
List<GeneratedColumn> get $columns => List<GeneratedColumn> get $columns =>
[id, maxBitrateWifi, maxBitrateMobile, streamFormat]; [id, maxBitrateWifi, maxBitrateMobile, streamFormat];
@override @override
String get aliasedName => _alias ?? 'app_settings'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'app_settings'; String get actualTableName => $name;
static const String $name = 'app_settings';
@override @override
VerificationContext validateIntegrity(Insertable<AppSettings> instance, VerificationContext validateIntegrity(Insertable<AppSettings> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -1359,9 +1360,10 @@ class Sources extends Table with TableInfo<Sources, Source> {
List<GeneratedColumn> get $columns => List<GeneratedColumn> get $columns =>
[id, name, address, isActive, createdAt]; [id, name, address, isActive, createdAt];
@override @override
String get aliasedName => _alias ?? 'sources'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'sources'; String get actualTableName => $name;
static const String $name = 'sources';
@override @override
VerificationContext validateIntegrity(Insertable<Source> instance, VerificationContext validateIntegrity(Insertable<Source> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -1435,8 +1437,8 @@ class Source extends DataClass implements Insertable<Source> {
map['id'] = Variable<int>(id); map['id'] = Variable<int>(id);
map['name'] = Variable<String>(name); map['name'] = Variable<String>(name);
{ {
final converter = Sources.$converteraddress; map['address'] =
map['address'] = Variable<String>(converter.toSql(address)); Variable<String>(Sources.$converteraddress.toSql(address));
} }
if (!nullToAbsent || isActive != null) { if (!nullToAbsent || isActive != null) {
map['is_active'] = Variable<bool>(isActive); map['is_active'] = Variable<bool>(isActive);
@@ -1580,8 +1582,8 @@ class SourcesCompanion extends UpdateCompanion<Source> {
map['name'] = Variable<String>(name.value); map['name'] = Variable<String>(name.value);
} }
if (address.present) { if (address.present) {
final converter = Sources.$converteraddress; map['address'] =
map['address'] = Variable<String>(converter.toSql(address.value)); Variable<String>(Sources.$converteraddress.toSql(address.value));
} }
if (isActive.present) { if (isActive.present) {
map['is_active'] = Variable<bool>(isActive.value); map['is_active'] = Variable<bool>(isActive.value);
@@ -1653,9 +1655,10 @@ class SubsonicSources extends Table
List<GeneratedColumn> get $columns => List<GeneratedColumn> get $columns =>
[sourceId, features, username, password, useTokenAuth]; [sourceId, features, username, password, useTokenAuth];
@override @override
String get aliasedName => _alias ?? 'subsonic_sources'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'subsonic_sources'; String get actualTableName => $name;
static const String $name = 'subsonic_sources';
@override @override
VerificationContext validateIntegrity(Insertable<SubsonicSource> instance, VerificationContext validateIntegrity(Insertable<SubsonicSource> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -1738,8 +1741,8 @@ class SubsonicSource extends DataClass implements Insertable<SubsonicSource> {
final map = <String, Expression>{}; final map = <String, Expression>{};
map['source_id'] = Variable<int>(sourceId); map['source_id'] = Variable<int>(sourceId);
{ {
final converter = SubsonicSources.$converterfeatures; map['features'] =
map['features'] = Variable<String>(converter.toSql(features)); Variable<String>(SubsonicSources.$converterfeatures.toSql(features));
} }
map['username'] = Variable<String>(username); map['username'] = Variable<String>(username);
map['password'] = Variable<String>(password); map['password'] = Variable<String>(password);
@@ -1879,8 +1882,8 @@ class SubsonicSourcesCompanion extends UpdateCompanion<SubsonicSource> {
map['source_id'] = Variable<int>(sourceId.value); map['source_id'] = Variable<int>(sourceId.value);
} }
if (features.present) { if (features.present) {
final converter = SubsonicSources.$converterfeatures; map['features'] = Variable<String>(
map['features'] = Variable<String>(converter.toSql(features.value)); SubsonicSources.$converterfeatures.toSql(features.value));
} }
if (username.present) { if (username.present) {
map['username'] = Variable<String>(username.value); map['username'] = Variable<String>(username.value);
@@ -1959,9 +1962,10 @@ class Artists extends Table with TableInfo<Artists, Artist> {
List<GeneratedColumn> get $columns => List<GeneratedColumn> get $columns =>
[sourceId, id, name, albumCount, starred, updated]; [sourceId, id, name, albumCount, starred, updated];
@override @override
String get aliasedName => _alias ?? 'artists'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'artists'; String get actualTableName => $name;
static const String $name = 'artists';
@override @override
VerificationContext validateIntegrity(Insertable<Artist> instance, VerificationContext validateIntegrity(Insertable<Artist> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -2170,9 +2174,10 @@ class ArtistsFts extends Table
@override @override
List<GeneratedColumn> get $columns => [sourceId, name]; List<GeneratedColumn> get $columns => [sourceId, name];
@override @override
String get aliasedName => _alias ?? 'artists_fts'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'artists_fts'; String get actualTableName => $name;
static const String $name = 'artists_fts';
@override @override
VerificationContext validateIntegrity(Insertable<ArtistsFt> instance, VerificationContext validateIntegrity(Insertable<ArtistsFt> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -2468,9 +2473,10 @@ class Albums extends Table with TableInfo<Albums, Album> {
updated updated
]; ];
@override @override
String get aliasedName => _alias ?? 'albums'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'albums'; String get actualTableName => $name;
static const String $name = 'albums';
@override @override
VerificationContext validateIntegrity(Insertable<Album> instance, VerificationContext validateIntegrity(Insertable<Album> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -2837,9 +2843,10 @@ class AlbumsFts extends Table
@override @override
List<GeneratedColumn> get $columns => [sourceId, name]; List<GeneratedColumn> get $columns => [sourceId, name];
@override @override
String get aliasedName => _alias ?? 'albums_fts'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'albums_fts'; String get actualTableName => $name;
static const String $name = 'albums_fts';
@override @override
VerificationContext validateIntegrity(Insertable<AlbumsFt> instance, VerificationContext validateIntegrity(Insertable<AlbumsFt> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -3072,9 +3079,10 @@ class Playlists extends Table with TableInfo<Playlists, Playlist> {
List<GeneratedColumn> get $columns => List<GeneratedColumn> get $columns =>
[sourceId, id, name, comment, coverArt, songCount, created, updated]; [sourceId, id, name, comment, coverArt, songCount, created, updated];
@override @override
String get aliasedName => _alias ?? 'playlists'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'playlists'; String get actualTableName => $name;
static const String $name = 'playlists';
@override @override
VerificationContext validateIntegrity(Insertable<Playlist> instance, VerificationContext validateIntegrity(Insertable<Playlist> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -3340,9 +3348,10 @@ class PlaylistSongs extends Table with TableInfo<PlaylistSongs, PlaylistSong> {
List<GeneratedColumn> get $columns => List<GeneratedColumn> get $columns =>
[sourceId, playlistId, songId, position, updated]; [sourceId, playlistId, songId, position, updated];
@override @override
String get aliasedName => _alias ?? 'playlist_songs'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'playlist_songs'; String get actualTableName => $name;
static const String $name = 'playlist_songs';
@override @override
VerificationContext validateIntegrity(Insertable<PlaylistSong> instance, VerificationContext validateIntegrity(Insertable<PlaylistSong> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -3632,9 +3641,10 @@ class PlaylistsFts extends Table
@override @override
List<GeneratedColumn> get $columns => [sourceId, name]; List<GeneratedColumn> get $columns => [sourceId, name];
@override @override
String get aliasedName => _alias ?? 'playlists_fts'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'playlists_fts'; String get actualTableName => $name;
static const String $name = 'playlists_fts';
@override @override
VerificationContext validateIntegrity(Insertable<PlaylistsFt> instance, VerificationContext validateIntegrity(Insertable<PlaylistsFt> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -3936,9 +3946,10 @@ class Songs extends Table with TableInfo<Songs, Song> {
updated updated
]; ];
@override @override
String get aliasedName => _alias ?? 'songs'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'songs'; String get actualTableName => $name;
static const String $name = 'songs';
@override @override
VerificationContext validateIntegrity(Insertable<Song> instance, VerificationContext validateIntegrity(Insertable<Song> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -4236,8 +4247,8 @@ class SongsCompanion extends UpdateCompanion<Song> {
map['artist'] = Variable<String>(artist.value); map['artist'] = Variable<String>(artist.value);
} }
if (duration.present) { if (duration.present) {
final converter = Songs.$converterdurationn; map['duration'] =
map['duration'] = Variable<int>(converter.toSql(duration.value)); Variable<int>(Songs.$converterdurationn.toSql(duration.value));
} }
if (track.present) { if (track.present) {
map['track'] = Variable<int>(track.value); map['track'] = Variable<int>(track.value);
@@ -4316,9 +4327,10 @@ class SongsFts extends Table
@override @override
List<GeneratedColumn> get $columns => [sourceId, title]; List<GeneratedColumn> get $columns => [sourceId, title];
@override @override
String get aliasedName => _alias ?? 'songs_fts'; String get aliasedName => _alias ?? actualTableName;
@override @override
String get actualTableName => 'songs_fts'; String get actualTableName => $name;
static const String $name = 'songs_fts';
@override @override
VerificationContext validateIntegrity(Insertable<SongsFt> instance, VerificationContext validateIntegrity(Insertable<SongsFt> instance,
{bool isInserting = false}) { {bool isInserting = false}) {
@@ -5570,4 +5582,5 @@ final databaseProvider = Provider<SubtracksDatabase>.internal(
); );
typedef DatabaseRef = ProviderRef<SubtracksDatabase>; typedef DatabaseRef = ProviderRef<SubtracksDatabase>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -0,0 +1,94 @@
import 'dart:async';
import 'package:drift/drift.dart';
import 'package:drift/isolate.dart';
/// https://github.com/simolus3/drift/issues/2326#issuecomment-1445138730
class ErrorLoggingDatabase implements QueryExecutor {
final QueryExecutor inner;
final void Function(Object, StackTrace) onError;
ErrorLoggingDatabase(this.inner, this.onError);
Future<T> _handleErrors<T>(Future<T> Function() body) {
return Future.sync(body)
.onError<DriftWrappedException>((error, stackTrace) {
onError(error, error.trace ?? stackTrace);
throw error;
}).onError<DriftRemoteException>((error, stackTrace) {
onError(error, error.remoteStackTrace ?? stackTrace);
throw error;
});
}
@override
TransactionExecutor beginTransaction() {
return _ErrorLoggingTransactionExecutor(inner.beginTransaction(), onError);
}
@override
Future<void> close() {
return _handleErrors(inner.close);
}
@override
SqlDialect get dialect => inner.dialect;
@override
Future<bool> ensureOpen(QueryExecutorUser user) {
return _handleErrors(() => inner.ensureOpen(user));
}
@override
Future<void> runBatched(BatchedStatements statements) {
return _handleErrors(() => inner.runBatched(statements));
}
@override
Future<void> runCustom(String statement, [List<Object?>? args]) {
return _handleErrors(() => inner.runCustom(statement, args));
}
@override
Future<int> runDelete(String statement, List<Object?> args) {
return _handleErrors(() => inner.runDelete(statement, args));
}
@override
Future<int> runInsert(String statement, List<Object?> args) {
return _handleErrors(() => inner.runInsert(statement, args));
}
@override
Future<List<Map<String, Object?>>> runSelect(
String statement, List<Object?> args) {
return _handleErrors(() => inner.runSelect(statement, args));
}
@override
Future<int> runUpdate(String statement, List<Object?> args) {
return _handleErrors(() => inner.runUpdate(statement, args));
}
}
class _ErrorLoggingTransactionExecutor extends ErrorLoggingDatabase
implements TransactionExecutor {
final TransactionExecutor transaction;
_ErrorLoggingTransactionExecutor(
this.transaction, void Function(Object, StackTrace) onError)
: super(transaction, onError);
@override
Future<void> rollback() {
return _handleErrors(transaction.rollback);
}
@override
Future<void> send() {
return _handleErrors(transaction.send);
}
@override
bool get supportsNestedTransactions => transaction.supportsNestedTransactions;
}

View File

@@ -1,7 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../log.dart';
part 'client.g.dart'; part 'client.g.dart';
const Map<String, String> subtracksHeaders = { const Map<String, String> subtracksHeaders = {
@@ -14,8 +15,14 @@ class SubtracksHttpClient extends BaseClient {
@override @override
Future<StreamedResponse> send(BaseRequest request) { Future<StreamedResponse> send(BaseRequest request) {
request.headers.addAll(subtracksHeaders); request.headers.addAll(subtracksHeaders);
if (kDebugMode) print('${request.method} ${request.url}'); log.info('${request.method} ${request.url}');
return request.send();
try {
return request.send();
} catch (e, st) {
log.severe('HTTP client: ${request.method} ${request.url}', e, st);
rethrow;
}
} }
} }

View File

@@ -20,4 +20,5 @@ final httpClientProvider = Provider<BaseClient>.internal(
); );
typedef HttpClientRef = ProviderRef<BaseClient>; typedef HttpClientRef = ProviderRef<BaseClient>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -1,166 +1,226 @@
{ {
"actionsStar": "Ohodnotit", "actionsStar": "Ohodnotit",
"@actionsStar": {}, "@actionsStar": {},
"actionsUnstar": "Zrušit hodnocení", "actionsUnstar": "Zrušit hodnocení",
"@actionsUnstar": {}, "@actionsUnstar": {},
"messagesNothingHere": "Zde nic není…", "messagesNothingHere": "Zde nic není…",
"@messagesNothingHere": {}, "@messagesNothingHere": {},
"navigationTabsHome": "Domů", "navigationTabsHome": "Domů",
"@navigationTabsHome": {}, "@navigationTabsHome": {},
"navigationTabsLibrary": "Knihovna", "navigationTabsLibrary": "Knihovna",
"@navigationTabsLibrary": {}, "@navigationTabsLibrary": {},
"navigationTabsSearch": "Hledat", "navigationTabsSearch": "Hledat",
"@navigationTabsSearch": {}, "@navigationTabsSearch": {},
"navigationTabsSettings": "Nastavení", "navigationTabsSettings": "Nastavení",
"@navigationTabsSettings": {}, "@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Přehrát album", "resourcesAlbumActionsPlay": "Přehrát album",
"@resourcesAlbumActionsPlay": {}, "@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Zobrazit album", "resourcesAlbumActionsView": "Zobrazit album",
"@resourcesAlbumActionsView": {}, "@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Seřadit alba", "resourcesAlbumListsSort": "Seřadit alba",
"@resourcesAlbumListsSort": {}, "@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Album} few{Alba} many{Alba} other{Alba}}", "resourcesAlbumName": "{count,plural, =1{Album} few{Alba} many{Alba} other{Alba}}",
"@resourcesAlbumName": { "@resourcesAlbumName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesArtistActionsView": "Zobrazit umělce", "resourcesArtistActionsView": "Zobrazit umělce",
"@resourcesArtistActionsView": {}, "@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Seřadit umělce", "resourcesArtistListsSort": "Seřadit umělce",
"@resourcesArtistListsSort": {}, "@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Umělec} few{Umělci} many{Umělci} other{Umělci}}", "resourcesArtistName": "{count,plural, =1{Umělec} few{Umělci} many{Umělci} other{Umělci}}",
"@resourcesArtistName": { "@resourcesArtistName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesFilterGenre": "Podle žánru", "resourcesFilterGenre": "Podle žánru",
"@resourcesFilterGenre": {}, "@resourcesFilterGenre": {},
"resourcesFilterStarred": "Ohodnocené", "resourcesFilterStarred": "Ohodnocené",
"@resourcesFilterStarred": {}, "@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Přehrát seznam skladeb", "resourcesPlaylistActionsPlay": "Přehrát seznam skladeb",
"@resourcesPlaylistActionsPlay": {}, "@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Seznam skladeb} few{Seznamy skladeb} many{Seznamy skladeb} other{Seznamy skladeb}}", "resourcesPlaylistName": "{count,plural, =1{Seznam skladeb} few{Seznamy skladeb} many{Seznamy skladeb} other{Seznamy skladeb}}",
"@resourcesPlaylistName": { "@resourcesPlaylistName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesQueueName": "{count,plural, =1{Fronta} few{Fronty} many{Fronty} other{Fronty}}", "resourcesQueueName": "{count,plural, =1{Fronta} few{Fronty} many{Fronty} other{Fronty}}",
"@resourcesQueueName": { "@resourcesQueueName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesSongListsArtistTopSongs": "Top skladby", "resourcesSongListsArtistTopSongs": "Top skladby",
"@resourcesSongListsArtistTopSongs": {}, "@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Skladba} few{Skladby} many{Skladby} other{Skladby}}", "resourcesSongName": "{count,plural, =1{Skladba} few{Skladby} many{Skladby} other{Skladby}}",
"@resourcesSongName": { "@resourcesSongName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesSortByAdded": "Nedávno přidané", "resourcesSortByAdded": "Nedávno přidané",
"@resourcesSortByAdded": {}, "@resourcesSortByAdded": {},
"resourcesSortByArtist": "Podle umělce", "resourcesSortByArtist": "Umělce",
"@resourcesSortByArtist": {}, "@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Často přehrávané", "resourcesSortByFrequentlyPlayed": "Často přehrávané",
"@resourcesSortByFrequentlyPlayed": {}, "@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Podle názvu", "resourcesSortByName": "Názvu",
"@resourcesSortByName": {}, "@resourcesSortByName": {},
"resourcesSortByRandom": "Náhodně", "resourcesSortByRandom": "Náhodně",
"@resourcesSortByRandom": {}, "@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Často přehrávané", "resourcesSortByRecentlyPlayed": "Často přehrávané",
"@resourcesSortByRecentlyPlayed": {}, "@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Podle roku", "resourcesSortByYear": "Roku",
"@resourcesSortByYear": {}, "@resourcesSortByYear": {},
"searchHeaderTitle": "Hledat: {query}", "searchHeaderTitle": "Hledat: {query}",
"@searchHeaderTitle": { "@searchHeaderTitle": {
"placeholders": { "placeholders": {
"query": { "query": {
"type": "String" "type": "String"
} }
} }
}, },
"searchInputPlaceholder": "Hledat", "searchInputPlaceholder": "Hledat",
"@searchInputPlaceholder": {}, "@searchInputPlaceholder": {},
"searchMoreResults": "Více…", "searchMoreResults": "Více…",
"@searchMoreResults": {}, "@searchMoreResults": {},
"searchNowPlayingContext": "Výsledky hledání", "searchNowPlayingContext": "Výsledky hledání",
"@searchNowPlayingContext": {}, "@searchNowPlayingContext": {},
"settingsNetworkName": "Síť", "settingsNetworkName": "Síť",
"@settingsNetworkName": {}, "@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Maximální datový tok (mobil)", "settingsNetworkOptionsMaxBitrateMobileTitle": "Maximální datový tok (mobil)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {}, "@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Maximální datový tok (Wi-Fi)", "settingsNetworkOptionsMaxBitrateWifiTitle": "Maximální datový tok (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {}, "@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkValuesKbps": "{value}kbps", "settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": { "@settingsNetworkValuesKbps": {
"placeholders": { "placeholders": {
"value": { "value": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsNetworkValuesSeconds": "{value} sekund", "settingsNetworkValuesSeconds": "{value} sekund",
"@settingsNetworkValuesSeconds": { "@settingsNetworkValuesSeconds": {
"placeholders": { "placeholders": {
"value": { "value": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsNetworkValuesUnlimitedKbps": "Neomezeno", "settingsNetworkValuesUnlimitedKbps": "Neomezeno",
"@settingsNetworkValuesUnlimitedKbps": {}, "@settingsNetworkValuesUnlimitedKbps": {},
"settingsServersActionsAdd": "Přidat server", "settingsServersActionsAdd": "Přidat server",
"@settingsServersActionsAdd": {}, "@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Odstranit", "settingsServersActionsDelete": "Odstranit",
"@settingsServersActionsDelete": {}, "@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Upravit server", "settingsServersActionsEdit": "Upravit server",
"@settingsServersActionsEdit": {}, "@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Uložit", "settingsServersActionsSave": "Uložit",
"@settingsServersActionsSave": {}, "@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Otestovat spojení", "settingsServersActionsTestConnection": "Otestovat spojení",
"@settingsServersActionsTestConnection": {}, "@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Adresa", "settingsServersFieldsAddress": "Adresa",
"@settingsServersFieldsAddress": {}, "@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Heslo", "settingsServersFieldsPassword": "Heslo",
"@settingsServersFieldsPassword": {}, "@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Uživ. jméno", "settingsServersFieldsUsername": "Uživ. jméno",
"@settingsServersFieldsUsername": {}, "@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Připojení k {address} selhalo, zkontrolujte nastavení nebo server", "settingsServersMessagesConnectionFailed": "Připojení k {address} selhalo, zkontrolujte nastavení nebo server",
"@settingsServersMessagesConnectionFailed": { "@settingsServersMessagesConnectionFailed": {
"placeholders": { "placeholders": {
"address": { "address": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsServersMessagesConnectionOk": "Připojení k {address} je OK!", "settingsServersMessagesConnectionOk": "Připojení k {address} je OK!",
"@settingsServersMessagesConnectionOk": { "@settingsServersMessagesConnectionOk": {
"placeholders": { "placeholders": {
"address": { "address": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsServersName": "Servery", "settingsServersName": "Servery",
"@settingsServersName": {}, "@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Posílat heslo jako token + salt", "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Posílat heslo jako token + salt",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Posílat heslo v prostém textu (zastaralé, ujistěte se, že je vaše připojení zabezpečené!)", "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Posílat heslo v prostém textu (zastaralé, ujistěte se, že je vaše připojení zabezpečené!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Vynutit heslo ve formátu prostého textu", "settingsServersOptionsForcePlaintextPasswordTitle": "Vynutit heslo ve formátu prostého textu",
"@settingsServersOptionsForcePlaintextPasswordTitle": {} "@settingsServersOptionsForcePlaintextPasswordTitle": {},
} "actionsDownloadDelete": "Smazat stažené",
"@actionsDownloadDelete": {},
"actionsOk": "OK",
"@actionsOk": {},
"actionsCancel": "Zrušit",
"@actionsCancel": {},
"actionsDownload": "Stáhnout",
"@actionsDownload": {},
"controlsShuffle": "Náhodně",
"@controlsShuffle": {},
"resourcesFilterAlbum": "Album",
"@resourcesFilterAlbum": {},
"resourcesFilterArtist": "Umělec",
"@resourcesFilterArtist": {},
"resourcesFilterYear": "Rok",
"@resourcesFilterYear": {},
"resourcesFilterOwner": "Majitele",
"@resourcesFilterOwner": {},
"resourcesSongListDeleteAllTitle": "Smazat stažené?",
"@resourcesSongListDeleteAllTitle": {},
"resourcesSongListDeleteAllContent": "Toto odstraní všechny stažené soubory s hudbou.",
"@resourcesSongListDeleteAllContent": {},
"resourcesSortByUpdated": "Naposledy upravené",
"@resourcesSortByUpdated": {},
"resourcesSortByAlbum": "Alba",
"@resourcesSortByAlbum": {},
"resourcesSortByAlbumCount": "Počtu alb",
"@resourcesSortByAlbumCount": {},
"resourcesSortByTitle": "Názvu",
"@resourcesSortByTitle": {},
"settingsAboutActionsLicenses": "Licence",
"@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Stránka projektu",
"@settingsAboutActionsProjectHomepage": {},
"settingsAboutActionsSupport": "Podpořit vývojáře 💜",
"@settingsAboutActionsSupport": {},
"settingsAboutVersion": "verze {version}",
"@settingsAboutVersion": {
"placeholders": {
"version": {
"type": "String"
}
}
},
"settingsNetworkOptionsStreamFormat": "Preferovaný formát pro streamování",
"@settingsNetworkOptionsStreamFormat": {},
"settingsNetworkOptionsStreamFormatServerDefault": "Použít nastavení serveru",
"@settingsNetworkOptionsStreamFormatServerDefault": {},
"settingsResetActionsClearImageCache": "Smazat mezipaměť obrázků",
"@settingsResetActionsClearImageCache": {},
"settingsResetName": "Resetovat",
"@settingsResetName": {},
"settingsServersFieldsName": "Jméno",
"@settingsServersFieldsName": {},
"settingsAboutName": "O aplikaci",
"@settingsAboutName": {},
"actionsDownloadCancel": "Zrušit stahování",
"@actionsDownloadCancel": {},
"actionsDelete": "Smazat",
"@actionsDelete": {}
}

View File

@@ -202,5 +202,75 @@
"controlsShuffle": "Zufall", "controlsShuffle": "Zufall",
"@controlsShuffle": {}, "@controlsShuffle": {},
"actionsCancel": "Abbrechen", "actionsCancel": "Abbrechen",
"@actionsCancel": {} "@actionsCancel": {},
"actionsDownloadDelete": "Heruntergeladene Inhalte löschen",
"@actionsDownloadDelete": {},
"actionsOk": "OK",
"@actionsOk": {},
"resourcesAlbumCount": "{count,plural, =1{{count} Album} other{{count} Alben}}",
"@resourcesAlbumCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterAlbum": "Album",
"@resourcesFilterAlbum": {},
"resourcesArtistCount": "{count,plural, =1{{count} Künstler} other{{count} Künstler}}",
"@resourcesArtistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesFilterArtist": "Künstler",
"@resourcesFilterArtist": {},
"resourcesFilterOwner": "Besitzer",
"@resourcesFilterOwner": {},
"resourcesFilterYear": "Jahr",
"@resourcesFilterYear": {},
"resourcesPlaylistCount": "{count,plural, =1{{count} Playlist} other{{count} Playlists}}",
"@resourcesPlaylistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongCount": "{count,plural, =1{{count} Song} other{{count} Songs}}",
"@resourcesSongCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSongListDeleteAllContent": "Hierdurch werden alle heruntergeladenen Inhalte entfernt.",
"@resourcesSongListDeleteAllContent": {},
"resourcesSortByAlbum": "Album",
"@resourcesSortByAlbum": {},
"resourcesSortByAlbumCount": "Albenanzahl",
"@resourcesSortByAlbumCount": {},
"resourcesSortByTitle": "Titel",
"@resourcesSortByTitle": {},
"resourcesSortByUpdated": "Kürzlich hinzugefügt",
"@resourcesSortByUpdated": {},
"settingsAboutActionsSupport": "Den Entwickler unterstützen",
"@settingsAboutActionsSupport": {},
"settingsNetworkOptionsOfflineMode": "Offline Modus",
"@settingsNetworkOptionsOfflineMode": {},
"settingsNetworkOptionsOfflineModeOff": "Nutze das Internet um Musik zu synchronisieren.",
"@settingsNetworkOptionsOfflineModeOff": {},
"settingsNetworkOptionsOfflineModeOn": "Nutze nicht das Internet um Musik zu synchronisieren.",
"@settingsNetworkOptionsOfflineModeOn": {},
"settingsNetworkOptionsStreamFormat": "Bevorzugtes Streaming-Format",
"@settingsNetworkOptionsStreamFormat": {},
"settingsServersFieldsName": "Name",
"@settingsServersFieldsName": {},
"resourcesSongListDeleteAllTitle": "Downloads löschen?",
"@resourcesSongListDeleteAllTitle": {},
"settingsNetworkOptionsStreamFormatServerDefault": "Server-Standard verwenden",
"@settingsNetworkOptionsStreamFormatServerDefault": {}
} }

View File

@@ -173,6 +173,10 @@
"@settingsAboutActionsSupport": {}, "@settingsAboutActionsSupport": {},
"settingsAboutName": "About", "settingsAboutName": "About",
"@settingsAboutName": {}, "@settingsAboutName": {},
"settingsAboutShareLogs": "Share logs",
"@settingsAboutShareLogs": {},
"settingsAboutChooseLog": "Choose a log file",
"@settingsAboutChooseLog": {},
"settingsAboutVersion": "version {version}", "settingsAboutVersion": "version {version}",
"@settingsAboutVersion": { "@settingsAboutVersion": {
"placeholders": { "placeholders": {

View File

@@ -272,5 +272,9 @@
"resourcesSortByTitle": "Título", "resourcesSortByTitle": "Título",
"@resourcesSortByTitle": {}, "@resourcesSortByTitle": {},
"resourcesSortByUpdated": "Actualizado recentemente", "resourcesSortByUpdated": "Actualizado recentemente",
"@resourcesSortByUpdated": {} "@resourcesSortByUpdated": {},
"settingsAboutShareLogs": "Compartir rexistros",
"@settingsAboutShareLogs": {},
"settingsAboutChooseLog": "Escolle un ficheiro de rexistro",
"@settingsAboutChooseLog": {}
} }

View File

@@ -1,196 +1,230 @@
{ {
"actionsStar": "Favorito", "actionsStar": "Favorito",
"@actionsStar": {}, "@actionsStar": {},
"actionsUnstar": "Remover favorito", "actionsUnstar": "Remover favorito",
"@actionsUnstar": {}, "@actionsUnstar": {},
"messagesNothingHere": "Não existe nada…", "messagesNothingHere": "Não existe nada…",
"@messagesNothingHere": {}, "@messagesNothingHere": {},
"navigationTabsHome": "Início", "navigationTabsHome": "Início",
"@navigationTabsHome": {}, "@navigationTabsHome": {},
"navigationTabsLibrary": "Biblioteca", "navigationTabsLibrary": "Biblioteca",
"@navigationTabsLibrary": {}, "@navigationTabsLibrary": {},
"navigationTabsSearch": "Procurar", "navigationTabsSearch": "Procurar",
"@navigationTabsSearch": {}, "@navigationTabsSearch": {},
"navigationTabsSettings": "Definições", "navigationTabsSettings": "Definições",
"@navigationTabsSettings": {}, "@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Tocar Álbum", "resourcesAlbumActionsPlay": "Tocar Álbum",
"@resourcesAlbumActionsPlay": {}, "@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Ver Álbum", "resourcesAlbumActionsView": "Ver Álbum",
"@resourcesAlbumActionsView": {}, "@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Ordenar Álbuns", "resourcesAlbumListsSort": "Ordenar Álbuns",
"@resourcesAlbumListsSort": {}, "@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Álbum} other{Álbuns}}", "resourcesAlbumName": "{count,plural, =1{Álbum} other{Álbuns}}",
"@resourcesAlbumName": { "@resourcesAlbumName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesArtistActionsView": "Ver Artista", "resourcesArtistActionsView": "Ver Artista",
"@resourcesArtistActionsView": {}, "@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Ordenar Artistas", "resourcesArtistListsSort": "Ordenar Artistas",
"@resourcesArtistListsSort": {}, "@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Artista} other{Artistas}}", "resourcesArtistName": "{count,plural, =1{Artista} other{Artistas}}",
"@resourcesArtistName": { "@resourcesArtistName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesFilterGenre": "Por Género", "resourcesFilterGenre": "Por Género",
"@resourcesFilterGenre": {}, "@resourcesFilterGenre": {},
"resourcesFilterStarred": "Favoritos", "resourcesFilterStarred": "Favoritos",
"@resourcesFilterStarred": {}, "@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Tocar Playlist", "resourcesPlaylistActionsPlay": "Tocar Playlist",
"@resourcesPlaylistActionsPlay": {}, "@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Lista} other{Listas}}", "resourcesPlaylistName": "{count,plural, =1{Lista} other{Listas}}",
"@resourcesPlaylistName": { "@resourcesPlaylistName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesQueueName": "{count,plural, =1{Fila} other{Filas}}", "resourcesQueueName": "{count,plural, =1{Fila} other{Filas}}",
"@resourcesQueueName": { "@resourcesQueueName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesSongListsArtistTopSongs": "Top Músicas", "resourcesSongListsArtistTopSongs": "Top Músicas",
"@resourcesSongListsArtistTopSongs": {}, "@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Música} other{Músicas}}", "resourcesSongName": "{count,plural, =1{Música} other{Músicas}}",
"@resourcesSongName": { "@resourcesSongName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesSortByAdded": "Adicionado recentemente", "resourcesSortByAdded": "Adicionado recentemente",
"@resourcesSortByAdded": {}, "@resourcesSortByAdded": {},
"resourcesSortByArtist": "Por Artista", "resourcesSortByArtist": "Por Artista",
"@resourcesSortByArtist": {}, "@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Mais Tocado", "resourcesSortByFrequentlyPlayed": "Mais Tocado",
"@resourcesSortByFrequentlyPlayed": {}, "@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "Por Nome", "resourcesSortByName": "Por Nome",
"@resourcesSortByName": {}, "@resourcesSortByName": {},
"resourcesSortByRandom": "Aleatório", "resourcesSortByRandom": "Aleatório",
"@resourcesSortByRandom": {}, "@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Ouviu recentemente", "resourcesSortByRecentlyPlayed": "Ouviu recentemente",
"@resourcesSortByRecentlyPlayed": {}, "@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "Por Ano", "resourcesSortByYear": "Por Ano",
"@resourcesSortByYear": {}, "@resourcesSortByYear": {},
"searchHeaderTitle": "Procurar: {query}", "searchHeaderTitle": "Procurar: {query}",
"@searchHeaderTitle": { "@searchHeaderTitle": {
"placeholders": { "placeholders": {
"query": { "query": {
"type": "String" "type": "String"
} }
} }
}, },
"searchInputPlaceholder": "Procurar", "searchInputPlaceholder": "Procurar",
"@searchInputPlaceholder": {}, "@searchInputPlaceholder": {},
"searchMoreResults": "Mais…", "searchMoreResults": "Mais…",
"@searchMoreResults": {}, "@searchMoreResults": {},
"searchNowPlayingContext": "Resultados da Pesquisa", "searchNowPlayingContext": "Resultados da Pesquisa",
"@searchNowPlayingContext": {}, "@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Licenças", "settingsAboutActionsLicenses": "Licenças",
"@settingsAboutActionsLicenses": {}, "@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Página do Projeto", "settingsAboutActionsProjectHomepage": "Página do Projeto",
"@settingsAboutActionsProjectHomepage": {}, "@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "Acerca", "settingsAboutName": "Acerca",
"@settingsAboutName": {}, "@settingsAboutName": {},
"settingsAboutVersion": "versão {version}", "settingsAboutVersion": "versão {version}",
"@settingsAboutVersion": { "@settingsAboutVersion": {
"placeholders": { "placeholders": {
"version": { "version": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsMusicName": "Música", "settingsMusicName": "Música",
"@settingsMusicName": {}, "@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Não enviar histórico de reproduções por scrobble", "settingsMusicOptionsScrobbleDescriptionOff": "Não enviar histórico de reproduções por scrobble",
"@settingsMusicOptionsScrobbleDescriptionOff": {}, "@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Enviar histórico de reproduções por scrobble", "settingsMusicOptionsScrobbleDescriptionOn": "Enviar histórico de reproduções por scrobble",
"@settingsMusicOptionsScrobbleDescriptionOn": {}, "@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Enviar reproduções por scrobble", "settingsMusicOptionsScrobbleTitle": "Enviar reproduções por scrobble",
"@settingsMusicOptionsScrobbleTitle": {}, "@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Rede", "settingsNetworkName": "Rede",
"@settingsNetworkName": {}, "@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Bitrate Máximo (móvel)", "settingsNetworkOptionsMaxBitrateMobileTitle": "Bitrate Máximo (móvel)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {}, "@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Bitrate Máximo (Wi-Fi)", "settingsNetworkOptionsMaxBitrateWifiTitle": "Bitrate Máximo (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {}, "@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Tempo de buffer máximo", "settingsNetworkOptionsMaxBufferTitle": "Tempo de buffer máximo",
"@settingsNetworkOptionsMaxBufferTitle": {}, "@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Tempo de buffer mínimo", "settingsNetworkOptionsMinBufferTitle": "Tempo de buffer mínimo",
"@settingsNetworkOptionsMinBufferTitle": {}, "@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value}kbps", "settingsNetworkValuesKbps": "{value}kbps",
"@settingsNetworkValuesKbps": { "@settingsNetworkValuesKbps": {
"placeholders": { "placeholders": {
"value": { "value": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsNetworkValuesSeconds": "{value} segundos", "settingsNetworkValuesSeconds": "{value} segundos",
"@settingsNetworkValuesSeconds": { "@settingsNetworkValuesSeconds": {
"placeholders": { "placeholders": {
"value": { "value": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsNetworkValuesUnlimitedKbps": "Ilimitado", "settingsNetworkValuesUnlimitedKbps": "Ilimitado",
"@settingsNetworkValuesUnlimitedKbps": {}, "@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Limpar cache de Imagens", "settingsResetActionsClearImageCache": "Limpar cache de Imagens",
"@settingsResetActionsClearImageCache": {}, "@settingsResetActionsClearImageCache": {},
"settingsResetName": "Redefinir", "settingsResetName": "Redefinir",
"@settingsResetName": {}, "@settingsResetName": {},
"settingsServersActionsAdd": "Adicionar Servidor", "settingsServersActionsAdd": "Adicionar Servidor",
"@settingsServersActionsAdd": {}, "@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Apagar", "settingsServersActionsDelete": "Apagar",
"@settingsServersActionsDelete": {}, "@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Editar Servidor", "settingsServersActionsEdit": "Editar Servidor",
"@settingsServersActionsEdit": {}, "@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Guardar", "settingsServersActionsSave": "Guardar",
"@settingsServersActionsSave": {}, "@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Testar Ligação", "settingsServersActionsTestConnection": "Testar Ligação",
"@settingsServersActionsTestConnection": {}, "@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Endereço", "settingsServersFieldsAddress": "Endereço",
"@settingsServersFieldsAddress": {}, "@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Senha", "settingsServersFieldsPassword": "Senha",
"@settingsServersFieldsPassword": {}, "@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Nome de utilizador", "settingsServersFieldsUsername": "Nome de utilizador",
"@settingsServersFieldsUsername": {}, "@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Ligação a {address} falhou, verifique definições ou servidor", "settingsServersMessagesConnectionFailed": "Ligação a {address} falhou, verifique definições ou servidor",
"@settingsServersMessagesConnectionFailed": { "@settingsServersMessagesConnectionFailed": {
"placeholders": { "placeholders": {
"address": { "address": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsServersMessagesConnectionOk": "Ligação a {address} OK!", "settingsServersMessagesConnectionOk": "Ligação a {address} OK!",
"@settingsServersMessagesConnectionOk": { "@settingsServersMessagesConnectionOk": {
"placeholders": { "placeholders": {
"address": { "address": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsServersName": "Servidores", "settingsServersName": "Servidores",
"@settingsServersName": {}, "@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Enviar senha como token + sal", "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Enviar senha como token + sal",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Enviar senha em texto simples (antigo, certifique-se que a sua ligação é segura!)", "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Enviar senha em texto simples (antigo, certifique-se que a sua ligação é segura!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Forçar password em texto simples", "settingsServersOptionsForcePlaintextPasswordTitle": "Forçar password em texto simples",
"@settingsServersOptionsForcePlaintextPasswordTitle": {} "@settingsServersOptionsForcePlaintextPasswordTitle": {},
} "actionsCancel": "Cancelar",
"@actionsCancel": {},
"actionsDelete": "Apagar",
"@actionsDelete": {},
"actionsDownload": "Descarregar",
"@actionsDownload": {},
"actionsDownloadCancel": "Cancelar descarga",
"@actionsDownloadCancel": {},
"actionsDownloadDelete": "Apagar descarga",
"@actionsDownloadDelete": {},
"resourcesFilterAlbum": "Álbum",
"@resourcesFilterAlbum": {},
"resourcesFilterArtist": "Artista",
"@resourcesFilterArtist": {},
"resourcesFilterYear": "Ano",
"@resourcesFilterYear": {},
"resourcesSortByAlbum": "Álbum",
"@resourcesSortByAlbum": {},
"settingsAboutActionsSupport": "Apoie o programador 💜",
"@settingsAboutActionsSupport": {},
"settingsNetworkOptionsOfflineMode": "Modo offline",
"@settingsNetworkOptionsOfflineMode": {},
"settingsNetworkOptionsOfflineModeOff": "Usar a internet para sincronizar música.",
"@settingsNetworkOptionsOfflineModeOff": {},
"settingsNetworkOptionsOfflineModeOn": "Não usar a internet para sincronizar ou tocar música.",
"@settingsNetworkOptionsOfflineModeOn": {},
"settingsNetworkOptionsStreamFormat": "Formato preferido de streaming",
"@settingsNetworkOptionsStreamFormat": {},
"resourcesSortByTitle": "Título",
"@resourcesSortByTitle": {},
"actionsOk": "OK",
"@actionsOk": {},
"controlsShuffle": "Aleatório",
"@controlsShuffle": {}
}

View File

@@ -1,196 +1,280 @@
{ {
"actionsStar": "Избранное", "actionsStar": "Избранное",
"@actionsStar": {}, "@actionsStar": {},
"actionsUnstar": "Убрать из избранного", "actionsUnstar": "Убрать из избранного",
"@actionsUnstar": {}, "@actionsUnstar": {},
"messagesNothingHere": "Здесь ничего нет…", "messagesNothingHere": "Здесь ничего нет…",
"@messagesNothingHere": {}, "@messagesNothingHere": {},
"navigationTabsHome": "Главная", "navigationTabsHome": "Главная",
"@navigationTabsHome": {}, "@navigationTabsHome": {},
"navigationTabsLibrary": "Библиотека", "navigationTabsLibrary": "Библиотека",
"@navigationTabsLibrary": {}, "@navigationTabsLibrary": {},
"navigationTabsSearch": "Поиск", "navigationTabsSearch": "Поиск",
"@navigationTabsSearch": {}, "@navigationTabsSearch": {},
"navigationTabsSettings": "Настройки", "navigationTabsSettings": "Настройки",
"@navigationTabsSettings": {}, "@navigationTabsSettings": {},
"resourcesAlbumActionsPlay": "Воспроизвести альбом", "resourcesAlbumActionsPlay": "Воспроизвести альбом",
"@resourcesAlbumActionsPlay": {}, "@resourcesAlbumActionsPlay": {},
"resourcesAlbumActionsView": "Посмотреть альбом", "resourcesAlbumActionsView": "Посмотреть альбом",
"@resourcesAlbumActionsView": {}, "@resourcesAlbumActionsView": {},
"resourcesAlbumListsSort": "Сортировка альбомов", "resourcesAlbumListsSort": "Сортировка альбомов",
"@resourcesAlbumListsSort": {}, "@resourcesAlbumListsSort": {},
"resourcesAlbumName": "{count,plural, =1{Альбом} few{Альбомы} many{Альбомов} other{Альбомов}}", "resourcesAlbumName": "{count,plural, =1{Альбом} few{Альбомы} many{Альбомов} other{Альбомов}}",
"@resourcesAlbumName": { "@resourcesAlbumName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesArtistActionsView": "Посмотреть исполнителя", "resourcesArtistActionsView": "Посмотреть исполнителя",
"@resourcesArtistActionsView": {}, "@resourcesArtistActionsView": {},
"resourcesArtistListsSort": "Сортировать исполнителей", "resourcesArtistListsSort": "Сортировать исполнителей",
"@resourcesArtistListsSort": {}, "@resourcesArtistListsSort": {},
"resourcesArtistName": "{count,plural, =1{Исполнитель} few{Исполнители} many{Исполнителей} other{Исполнителей}}", "resourcesArtistName": "{count,plural, =1{Исполнитель} few{Исполнители} many{Исполнителей} other{Исполнителей}}",
"@resourcesArtistName": { "@resourcesArtistName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesFilterGenre": "По жанру", "resourcesFilterGenre": "По жанру",
"@resourcesFilterGenre": {}, "@resourcesFilterGenre": {},
"resourcesFilterStarred": "Избранные", "resourcesFilterStarred": "Избранные",
"@resourcesFilterStarred": {}, "@resourcesFilterStarred": {},
"resourcesPlaylistActionsPlay": "Воспроизвести плейлист", "resourcesPlaylistActionsPlay": "Воспроизвести плейлист",
"@resourcesPlaylistActionsPlay": {}, "@resourcesPlaylistActionsPlay": {},
"resourcesPlaylistName": "{count,plural, =1{Плейлист} few{Плейлисты} many{Плейлистов} other{Плейлистов}}", "resourcesPlaylistName": "{count,plural, =1{Плейлист} few{Плейлисты} many{Плейлистов} other{Плейлистов}}",
"@resourcesPlaylistName": { "@resourcesPlaylistName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesQueueName": "{count,plural, =1{Очередь} few{Очереди} many{Очередей} other{Очередей}}", "resourcesQueueName": "{count,plural, =1{Очередь} few{Очереди} many{Очередей} other{Очередей}}",
"@resourcesQueueName": { "@resourcesQueueName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesSongListsArtistTopSongs": "Лучшие треки", "resourcesSongListsArtistTopSongs": "Лучшие треки",
"@resourcesSongListsArtistTopSongs": {}, "@resourcesSongListsArtistTopSongs": {},
"resourcesSongName": "{count,plural, =1{Трек} few{Трека} many{Треков} other{Треков}}", "resourcesSongName": "{count,plural, =1{Трек} few{Трека} many{Треков} other{Треков}}",
"@resourcesSongName": { "@resourcesSongName": {
"placeholders": { "placeholders": {
"count": { "count": {
"type": "int" "type": "int"
} }
} }
}, },
"resourcesSortByAdded": "Недавно добавленные", "resourcesSortByAdded": "Недавно добавленные",
"@resourcesSortByAdded": {}, "@resourcesSortByAdded": {},
"resourcesSortByArtist": "По исполнителю", "resourcesSortByArtist": "По исполнителям",
"@resourcesSortByArtist": {}, "@resourcesSortByArtist": {},
"resourcesSortByFrequentlyPlayed": "Часто проигрываемые", "resourcesSortByFrequentlyPlayed": "Часто проигрываемые",
"@resourcesSortByFrequentlyPlayed": {}, "@resourcesSortByFrequentlyPlayed": {},
"resourcesSortByName": "По имени", "resourcesSortByName": "По имени",
"@resourcesSortByName": {}, "@resourcesSortByName": {},
"resourcesSortByRandom": "Случайно", "resourcesSortByRandom": "Случайно",
"@resourcesSortByRandom": {}, "@resourcesSortByRandom": {},
"resourcesSortByRecentlyPlayed": "Недавно проигранные", "resourcesSortByRecentlyPlayed": "Недавно проигранные",
"@resourcesSortByRecentlyPlayed": {}, "@resourcesSortByRecentlyPlayed": {},
"resourcesSortByYear": "По году", "resourcesSortByYear": "По году",
"@resourcesSortByYear": {}, "@resourcesSortByYear": {},
"searchHeaderTitle": "Поиск: {query}", "searchHeaderTitle": "Поиск: {query}",
"@searchHeaderTitle": { "@searchHeaderTitle": {
"placeholders": { "placeholders": {
"query": { "query": {
"type": "String" "type": "String"
} }
} }
}, },
"searchInputPlaceholder": "Поиск", "searchInputPlaceholder": "Поиск",
"@searchInputPlaceholder": {}, "@searchInputPlaceholder": {},
"searchMoreResults": "Больше…", "searchMoreResults": "Больше…",
"@searchMoreResults": {}, "@searchMoreResults": {},
"searchNowPlayingContext": "Результаты поиска", "searchNowPlayingContext": "Результаты поиска",
"@searchNowPlayingContext": {}, "@searchNowPlayingContext": {},
"settingsAboutActionsLicenses": "Лицензии", "settingsAboutActionsLicenses": "Лицензии",
"@settingsAboutActionsLicenses": {}, "@settingsAboutActionsLicenses": {},
"settingsAboutActionsProjectHomepage": "Сайт проекта", "settingsAboutActionsProjectHomepage": "Сайт проекта",
"@settingsAboutActionsProjectHomepage": {}, "@settingsAboutActionsProjectHomepage": {},
"settingsAboutName": "О Subtracks", "settingsAboutName": "О Subtracks",
"@settingsAboutName": {}, "@settingsAboutName": {},
"settingsAboutVersion": "версия {version}", "settingsAboutVersion": "версия {version}",
"@settingsAboutVersion": { "@settingsAboutVersion": {
"placeholders": { "placeholders": {
"version": { "version": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsMusicName": "Музыка", "settingsMusicName": "Музыка",
"@settingsMusicName": {}, "@settingsMusicName": {},
"settingsMusicOptionsScrobbleDescriptionOff": "Не отправлять историю воспроизведений", "settingsMusicOptionsScrobbleDescriptionOff": "Не отправлять историю воспроизведений",
"@settingsMusicOptionsScrobbleDescriptionOff": {}, "@settingsMusicOptionsScrobbleDescriptionOff": {},
"settingsMusicOptionsScrobbleDescriptionOn": "Скробблинг истории воспроизведения", "settingsMusicOptionsScrobbleDescriptionOn": "Скробблинг истории воспроизведения",
"@settingsMusicOptionsScrobbleDescriptionOn": {}, "@settingsMusicOptionsScrobbleDescriptionOn": {},
"settingsMusicOptionsScrobbleTitle": "Скробблинг", "settingsMusicOptionsScrobbleTitle": "Скробблинг",
"@settingsMusicOptionsScrobbleTitle": {}, "@settingsMusicOptionsScrobbleTitle": {},
"settingsNetworkName": "Сеть", "settingsNetworkName": "Сеть",
"@settingsNetworkName": {}, "@settingsNetworkName": {},
"settingsNetworkOptionsMaxBitrateMobileTitle": "Максимальный битрейт (мобильный интернет)", "settingsNetworkOptionsMaxBitrateMobileTitle": "Максимальный битрейт (мобильный интернет)",
"@settingsNetworkOptionsMaxBitrateMobileTitle": {}, "@settingsNetworkOptionsMaxBitrateMobileTitle": {},
"settingsNetworkOptionsMaxBitrateWifiTitle": "Максимальный битрейт (Wi-Fi)", "settingsNetworkOptionsMaxBitrateWifiTitle": "Максимальный битрейт (Wi-Fi)",
"@settingsNetworkOptionsMaxBitrateWifiTitle": {}, "@settingsNetworkOptionsMaxBitrateWifiTitle": {},
"settingsNetworkOptionsMaxBufferTitle": "Максимальное время буферизации", "settingsNetworkOptionsMaxBufferTitle": "Максимальное время буферизации",
"@settingsNetworkOptionsMaxBufferTitle": {}, "@settingsNetworkOptionsMaxBufferTitle": {},
"settingsNetworkOptionsMinBufferTitle": "Минимальное время буферизации", "settingsNetworkOptionsMinBufferTitle": "Минимальное время буферизации",
"@settingsNetworkOptionsMinBufferTitle": {}, "@settingsNetworkOptionsMinBufferTitle": {},
"settingsNetworkValuesKbps": "{value} кбит/с", "settingsNetworkValuesKbps": "{value} кбит/с",
"@settingsNetworkValuesKbps": { "@settingsNetworkValuesKbps": {
"placeholders": { "placeholders": {
"value": { "value": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsNetworkValuesSeconds": "{value} секунд", "settingsNetworkValuesSeconds": "{value} секунд",
"@settingsNetworkValuesSeconds": { "@settingsNetworkValuesSeconds": {
"placeholders": { "placeholders": {
"value": { "value": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsNetworkValuesUnlimitedKbps": "Без ограничений", "settingsNetworkValuesUnlimitedKbps": "Без ограничений",
"@settingsNetworkValuesUnlimitedKbps": {}, "@settingsNetworkValuesUnlimitedKbps": {},
"settingsResetActionsClearImageCache": "Очистить кэш изображения", "settingsResetActionsClearImageCache": "Очистить кэш изображения",
"@settingsResetActionsClearImageCache": {}, "@settingsResetActionsClearImageCache": {},
"settingsResetName": "Сброс", "settingsResetName": "Сброс",
"@settingsResetName": {}, "@settingsResetName": {},
"settingsServersActionsAdd": "Добавить сервер", "settingsServersActionsAdd": "Добавить сервер",
"@settingsServersActionsAdd": {}, "@settingsServersActionsAdd": {},
"settingsServersActionsDelete": "Удалить", "settingsServersActionsDelete": "Удалить",
"@settingsServersActionsDelete": {}, "@settingsServersActionsDelete": {},
"settingsServersActionsEdit": "Редактировать сервер", "settingsServersActionsEdit": "Редактировать сервер",
"@settingsServersActionsEdit": {}, "@settingsServersActionsEdit": {},
"settingsServersActionsSave": "Сохранить", "settingsServersActionsSave": "Сохранить",
"@settingsServersActionsSave": {}, "@settingsServersActionsSave": {},
"settingsServersActionsTestConnection": "Проверить подключение", "settingsServersActionsTestConnection": "Проверить подключение",
"@settingsServersActionsTestConnection": {}, "@settingsServersActionsTestConnection": {},
"settingsServersFieldsAddress": "Адрес", "settingsServersFieldsAddress": "Адрес",
"@settingsServersFieldsAddress": {}, "@settingsServersFieldsAddress": {},
"settingsServersFieldsPassword": "Пароль", "settingsServersFieldsPassword": "Пароль",
"@settingsServersFieldsPassword": {}, "@settingsServersFieldsPassword": {},
"settingsServersFieldsUsername": "Имя пользователя", "settingsServersFieldsUsername": "Имя пользователя",
"@settingsServersFieldsUsername": {}, "@settingsServersFieldsUsername": {},
"settingsServersMessagesConnectionFailed": "Не удалось подключиться к {address}, проверьте настройки или сервер", "settingsServersMessagesConnectionFailed": "Не удалось подключиться к {address}, проверьте настройки или сервер",
"@settingsServersMessagesConnectionFailed": { "@settingsServersMessagesConnectionFailed": {
"placeholders": { "placeholders": {
"address": { "address": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsServersMessagesConnectionOk": "Подключение к {address} установлено!", "settingsServersMessagesConnectionOk": "Подключение к {address} установлено!",
"@settingsServersMessagesConnectionOk": { "@settingsServersMessagesConnectionOk": {
"placeholders": { "placeholders": {
"address": { "address": {
"type": "String" "type": "String"
} }
} }
}, },
"settingsServersName": "Серверы", "settingsServersName": "Серверы",
"@settingsServersName": {}, "@settingsServersName": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Отправить пароль в виде токена", "settingsServersOptionsForcePlaintextPasswordDescriptionOff": "Отправить пароль в виде токена",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {}, "@settingsServersOptionsForcePlaintextPasswordDescriptionOff": {},
"settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Отправить пароль в виде текста (устарело, убедитесь, что ваше соединение безопасно!)", "settingsServersOptionsForcePlaintextPasswordDescriptionOn": "Отправить пароль в виде текста (устарело, убедитесь, что ваше соединение безопасно!)",
"@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {}, "@settingsServersOptionsForcePlaintextPasswordDescriptionOn": {},
"settingsServersOptionsForcePlaintextPasswordTitle": "Принудительно использовать текстовой пароль", "settingsServersOptionsForcePlaintextPasswordTitle": "Принудительно использовать текстовой пароль",
"@settingsServersOptionsForcePlaintextPasswordTitle": {} "@settingsServersOptionsForcePlaintextPasswordTitle": {},
} "settingsAboutShareLogs": "Поделиться журналами",
"@settingsAboutShareLogs": {},
"settingsAboutChooseLog": "Выбрать файл журнала",
"@settingsAboutChooseLog": {},
"settingsNetworkOptionsStreamFormatServerDefault": "Использовать сервер по умолчанию",
"@settingsNetworkOptionsStreamFormatServerDefault": {},
"actionsDownload": "Скачать",
"@actionsDownload": {},
"actionsDownloadCancel": "Отменить загрузку",
"@actionsDownloadCancel": {},
"actionsCancel": "Отменить",
"@actionsCancel": {},
"resourcesSongCount": "{count,plural, =1{{count} трек} other{{count} треки}}",
"@resourcesSongCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesSortByAlbum": "По альбомам",
"@resourcesSortByAlbum": {},
"resourcesSortByTitle": "По заголовку",
"@resourcesSortByTitle": {},
"resourcesSortByUpdated": "По недавно обновленному",
"@resourcesSortByUpdated": {},
"resourcesSortByAlbumCount": "По количеству альбомов",
"@resourcesSortByAlbumCount": {},
"settingsNetworkOptionsOfflineMode": "Автономный режим",
"@settingsNetworkOptionsOfflineMode": {},
"settingsNetworkOptionsOfflineModeOff": "Использовать интернет для синхронизации музыки.",
"@settingsNetworkOptionsOfflineModeOff": {},
"settingsServersFieldsName": "Имя",
"@settingsServersFieldsName": {},
"actionsDelete": "Удалить",
"@actionsDelete": {},
"actionsDownloadDelete": "Удалить загруженное",
"@actionsDownloadDelete": {},
"actionsOk": "ОК",
"@actionsOk": {},
"controlsShuffle": "Перемешать",
"@controlsShuffle": {},
"resourcesFilterArtist": "По исполнителю",
"@resourcesFilterArtist": {},
"resourcesFilterAlbum": "По альбомам",
"@resourcesFilterAlbum": {},
"resourcesFilterYear": "По годам",
"@resourcesFilterYear": {},
"resourcesFilterOwner": "По владельцу",
"@resourcesFilterOwner": {},
"resourcesSongListDeleteAllContent": "Это удалит все загруженные файлы песен.",
"@resourcesSongListDeleteAllContent": {},
"settingsNetworkOptionsStreamFormat": "Предпочтительный формат потока",
"@settingsNetworkOptionsStreamFormat": {},
"resourcesSongListDeleteAllTitle": "Удалить загрузки?",
"@resourcesSongListDeleteAllTitle": {},
"settingsNetworkOptionsOfflineModeOn": "Не использовать интернет для синхронизации или воспроизведения музыки.",
"@settingsNetworkOptionsOfflineModeOn": {},
"settingsAboutActionsSupport": "Поддержать разработчика",
"@settingsAboutActionsSupport": {},
"resourcesArtistCount": "{count,plural, =1{{count} исполнитель} other{{count} исполнители}}",
"@resourcesArtistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesPlaylistCount": "{count,plural, =1{{count} плейлист} other{{count} плейлисты}}",
"@resourcesPlaylistCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"resourcesAlbumCount": "{count,plural, =1{{count} альбом} other{{count} альбомы}}",
"@resourcesAlbumCount": {
"placeholders": {
"count": {
"type": "int"
}
}
}
}

209
lib/log.dart Normal file
View File

@@ -0,0 +1,209 @@
// import 'dart:convert';
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
class AnsiColor {
/// ANSI Control Sequence Introducer, signals the terminal for new settings.
static const ansiEsc = '\x1B[';
/// Reset all colors and options for current SGRs to terminal defaults.
static const ansiDefault = '${ansiEsc}0m';
final int? fg;
final int? bg;
final bool color;
AnsiColor.none()
: fg = null,
bg = null,
color = false;
AnsiColor.fg(this.fg)
: bg = null,
color = true;
AnsiColor.bg(this.bg)
: fg = null,
color = true;
@override
String toString() {
if (fg != null) {
return '${ansiEsc}38;5;${fg}m';
} else if (bg != null) {
return '${ansiEsc}48;5;${bg}m';
} else {
return '';
}
}
String call(String msg) {
if (color) {
// ignore: unnecessary_brace_in_string_interps
return '${this}$msg$ansiDefault';
} else {
return msg;
}
}
AnsiColor toFg() => AnsiColor.fg(bg);
AnsiColor toBg() => AnsiColor.bg(fg);
/// Defaults the terminal's foreground color without altering the background.
String get resetForeground => color ? '${ansiEsc}39m' : '';
/// Defaults the terminal's background color without altering the foreground.
String get resetBackground => color ? '${ansiEsc}49m' : '';
static int grey(double level) => 232 + (level.clamp(0.0, 1.0) * 23).round();
}
final levelColors = {
Level.FINEST: AnsiColor.fg(AnsiColor.grey(0.5)),
Level.FINER: AnsiColor.fg(AnsiColor.grey(0.5)),
Level.FINE: AnsiColor.fg(AnsiColor.grey(0.5)),
Level.CONFIG: AnsiColor.fg(81),
Level.INFO: AnsiColor.fg(12),
Level.WARNING: AnsiColor.fg(208),
Level.SEVERE: AnsiColor.fg(196),
Level.SHOUT: AnsiColor.fg(199),
};
class LogData {
final String? message;
final Object? data;
const LogData(this.message, this.data);
}
String _format(
LogRecord event, {
bool color = false,
bool time = true,
bool level = true,
bool redact = true,
}) {
var message = '';
if (time) message += '${event.time.toIso8601String()} ';
if (level) message += '${event.level.name} ';
final object = event.object;
if (object is LogData) {
message += '${object.message}';
message += '\n${object.data}';
} else if (object != null) {
message += 'Object';
message += '\n$object';
} else {
message += event.message;
}
if (event.error != null) {
message += '\n${event.error}';
}
if (redact) {
message = _redactUrl(message);
}
if (event.stackTrace != null) {
message += '\n${event.stackTrace}';
}
return color
? message.split('\n').map((e) => levelColors[event.level]!(e)).join('\n')
: message;
}
String _redactUrl(String message) {
if (!_queryReplace('u').hasMatch(message)) {
return message;
}
message = _redactParam(message, 'u');
message = _redactParam(message, 'p');
message = _redactParam(message, 's');
message = _redactParam(message, 't');
return message;
}
RegExp _queryReplace(String key) => RegExp('$key=([^&|\\n|\\t\\s]+)');
String _redactParam(String url, String key) =>
url.replaceAll(_queryReplace(key), '$key=REDACTED');
Future<Directory> logDirectory() async {
return Directory(
p.join((await getApplicationDocumentsDirectory()).path, 'logs'),
);
}
Future<List<File>> logFiles() async {
final dir = await logDirectory();
return dir.listSync().whereType<File>().toList()
..sort(
(a, b) => b.statSync().modified.compareTo(a.statSync().modified),
);
}
File _currentLogFile(String logDir) {
final now = DateTime.now();
return File(p.join(logDir, '${now.year}-${now.month}-${now.day}.txt'));
}
Future<void> _printFile(String event, String logDir) async {
final file = _currentLogFile(logDir);
if (!event.endsWith('\n')) {
event += '\n';
}
await file.writeAsString(event, mode: FileMode.writeOnlyAppend, flush: true);
}
void _printDebug(LogRecord event) {
// ignore: avoid_print
print(_format(event, color: true, time: false, level: false, redact: false));
}
Future<void> _printRelease(LogRecord event, String logDir) async {
await _printFile(
_format(event, color: false, time: true, level: true, redact: true),
logDir,
);
}
final log = Logger('default');
Future<void> initLogging() async {
final dir = (await logDirectory())..create();
final file = _currentLogFile(dir.path);
if (!(await file.exists())) {
await file.create();
}
final files = await logFiles();
if (files.length > 7) {
for (var file in files.slice(7)) {
await file.delete();
}
}
Logger.root.level = kDebugMode ? Level.ALL : Level.INFO;
Logger.root.onRecord.asyncMap((event) async {
if (kDebugMode) {
_printDebug(event);
} else {
await _printRelease(event, dir.path);
}
}).listen((_) {}, cancelOnError: false);
}

View File

@@ -4,6 +4,7 @@ import 'package:stack_trace/stack_trace.dart' as stack_trace;
import 'package:worker_manager/worker_manager.dart'; import 'package:worker_manager/worker_manager.dart';
import 'app/app.dart'; import 'app/app.dart';
import 'log.dart';
void main() async { void main() async {
// TOOD: probably remove before live // TOOD: probably remove before live
@@ -18,5 +19,8 @@ void main() async {
await Executor().warmUp(); await Executor().warmUp();
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await initLogging();
runApp(const ProviderScope(child: MyApp())); runApp(const ProviderScope(child: MyApp()));
} }

View File

@@ -12,7 +12,7 @@ part of 'music.dart';
T _$identity<T>(T value) => value; T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError( final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
/// @nodoc /// @nodoc
mixin _$SourceId { mixin _$SourceId {
@@ -62,21 +62,22 @@ class _$SourceIdCopyWithImpl<$Res, $Val extends SourceId>
} }
/// @nodoc /// @nodoc
abstract class _$$_SourceIdCopyWith<$Res> implements $SourceIdCopyWith<$Res> { abstract class _$$SourceIdImplCopyWith<$Res>
factory _$$_SourceIdCopyWith( implements $SourceIdCopyWith<$Res> {
_$_SourceId value, $Res Function(_$_SourceId) then) = factory _$$SourceIdImplCopyWith(
__$$_SourceIdCopyWithImpl<$Res>; _$SourceIdImpl value, $Res Function(_$SourceIdImpl) then) =
__$$SourceIdImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call({int sourceId, String id}); $Res call({int sourceId, String id});
} }
/// @nodoc /// @nodoc
class __$$_SourceIdCopyWithImpl<$Res> class __$$SourceIdImplCopyWithImpl<$Res>
extends _$SourceIdCopyWithImpl<$Res, _$_SourceId> extends _$SourceIdCopyWithImpl<$Res, _$SourceIdImpl>
implements _$$_SourceIdCopyWith<$Res> { implements _$$SourceIdImplCopyWith<$Res> {
__$$_SourceIdCopyWithImpl( __$$SourceIdImplCopyWithImpl(
_$_SourceId _value, $Res Function(_$_SourceId) _then) _$SourceIdImpl _value, $Res Function(_$SourceIdImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -85,7 +86,7 @@ class __$$_SourceIdCopyWithImpl<$Res>
Object? sourceId = null, Object? sourceId = null,
Object? id = null, Object? id = null,
}) { }) {
return _then(_$_SourceId( return _then(_$SourceIdImpl(
sourceId: null == sourceId sourceId: null == sourceId
? _value.sourceId ? _value.sourceId
: sourceId // ignore: cast_nullable_to_non_nullable : sourceId // ignore: cast_nullable_to_non_nullable
@@ -100,8 +101,8 @@ class __$$_SourceIdCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$_SourceId with DiagnosticableTreeMixin implements _SourceId { class _$SourceIdImpl with DiagnosticableTreeMixin implements _SourceId {
const _$_SourceId({required this.sourceId, required this.id}); const _$SourceIdImpl({required this.sourceId, required this.id});
@override @override
final int sourceId; final int sourceId;
@@ -123,10 +124,10 @@ class _$_SourceId with DiagnosticableTreeMixin implements _SourceId {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_SourceId && other is _$SourceIdImpl &&
(identical(other.sourceId, sourceId) || (identical(other.sourceId, sourceId) ||
other.sourceId == sourceId) && other.sourceId == sourceId) &&
(identical(other.id, id) || other.id == id)); (identical(other.id, id) || other.id == id));
@@ -138,13 +139,13 @@ class _$_SourceId with DiagnosticableTreeMixin implements _SourceId {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_SourceIdCopyWith<_$_SourceId> get copyWith => _$$SourceIdImplCopyWith<_$SourceIdImpl> get copyWith =>
__$$_SourceIdCopyWithImpl<_$_SourceId>(this, _$identity); __$$SourceIdImplCopyWithImpl<_$SourceIdImpl>(this, _$identity);
} }
abstract class _SourceId implements SourceId { abstract class _SourceId implements SourceId {
const factory _SourceId( const factory _SourceId(
{required final int sourceId, required final String id}) = _$_SourceId; {required final int sourceId, required final String id}) = _$SourceIdImpl;
@override @override
int get sourceId; int get sourceId;
@@ -152,7 +153,7 @@ abstract class _SourceId implements SourceId {
String get id; String get id;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_SourceIdCopyWith<_$_SourceId> get copyWith => _$$SourceIdImplCopyWith<_$SourceIdImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
@@ -205,22 +206,22 @@ class _$SourceIdSetCopyWithImpl<$Res, $Val extends SourceIdSet>
} }
/// @nodoc /// @nodoc
abstract class _$$_SourceIdSetCopyWith<$Res> abstract class _$$SourceIdSetImplCopyWith<$Res>
implements $SourceIdSetCopyWith<$Res> { implements $SourceIdSetCopyWith<$Res> {
factory _$$_SourceIdSetCopyWith( factory _$$SourceIdSetImplCopyWith(
_$_SourceIdSet value, $Res Function(_$_SourceIdSet) then) = _$SourceIdSetImpl value, $Res Function(_$SourceIdSetImpl) then) =
__$$_SourceIdSetCopyWithImpl<$Res>; __$$SourceIdSetImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call({int sourceId, ISet<String> ids}); $Res call({int sourceId, ISet<String> ids});
} }
/// @nodoc /// @nodoc
class __$$_SourceIdSetCopyWithImpl<$Res> class __$$SourceIdSetImplCopyWithImpl<$Res>
extends _$SourceIdSetCopyWithImpl<$Res, _$_SourceIdSet> extends _$SourceIdSetCopyWithImpl<$Res, _$SourceIdSetImpl>
implements _$$_SourceIdSetCopyWith<$Res> { implements _$$SourceIdSetImplCopyWith<$Res> {
__$$_SourceIdSetCopyWithImpl( __$$SourceIdSetImplCopyWithImpl(
_$_SourceIdSet _value, $Res Function(_$_SourceIdSet) _then) _$SourceIdSetImpl _value, $Res Function(_$SourceIdSetImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -229,7 +230,7 @@ class __$$_SourceIdSetCopyWithImpl<$Res>
Object? sourceId = null, Object? sourceId = null,
Object? ids = null, Object? ids = null,
}) { }) {
return _then(_$_SourceIdSet( return _then(_$SourceIdSetImpl(
sourceId: null == sourceId sourceId: null == sourceId
? _value.sourceId ? _value.sourceId
: sourceId // ignore: cast_nullable_to_non_nullable : sourceId // ignore: cast_nullable_to_non_nullable
@@ -244,8 +245,8 @@ class __$$_SourceIdSetCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$_SourceIdSet with DiagnosticableTreeMixin implements _SourceIdSet { class _$SourceIdSetImpl with DiagnosticableTreeMixin implements _SourceIdSet {
const _$_SourceIdSet({required this.sourceId, required this.ids}); const _$SourceIdSetImpl({required this.sourceId, required this.ids});
@override @override
final int sourceId; final int sourceId;
@@ -267,10 +268,10 @@ class _$_SourceIdSet with DiagnosticableTreeMixin implements _SourceIdSet {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_SourceIdSet && other is _$SourceIdSetImpl &&
(identical(other.sourceId, sourceId) || (identical(other.sourceId, sourceId) ||
other.sourceId == sourceId) && other.sourceId == sourceId) &&
const DeepCollectionEquality().equals(other.ids, ids)); const DeepCollectionEquality().equals(other.ids, ids));
@@ -283,14 +284,14 @@ class _$_SourceIdSet with DiagnosticableTreeMixin implements _SourceIdSet {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_SourceIdSetCopyWith<_$_SourceIdSet> get copyWith => _$$SourceIdSetImplCopyWith<_$SourceIdSetImpl> get copyWith =>
__$$_SourceIdSetCopyWithImpl<_$_SourceIdSet>(this, _$identity); __$$SourceIdSetImplCopyWithImpl<_$SourceIdSetImpl>(this, _$identity);
} }
abstract class _SourceIdSet implements SourceIdSet { abstract class _SourceIdSet implements SourceIdSet {
const factory _SourceIdSet( const factory _SourceIdSet(
{required final int sourceId, {required final int sourceId,
required final ISet<String> ids}) = _$_SourceIdSet; required final ISet<String> ids}) = _$SourceIdSetImpl;
@override @override
int get sourceId; int get sourceId;
@@ -298,7 +299,7 @@ abstract class _SourceIdSet implements SourceIdSet {
ISet<String> get ids; ISet<String> get ids;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_SourceIdSetCopyWith<_$_SourceIdSet> get copyWith => _$$SourceIdSetImplCopyWith<_$SourceIdSetImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
@@ -372,9 +373,10 @@ class _$ArtistCopyWithImpl<$Res, $Val extends Artist>
} }
/// @nodoc /// @nodoc
abstract class _$$_ArtistCopyWith<$Res> implements $ArtistCopyWith<$Res> { abstract class _$$ArtistImplCopyWith<$Res> implements $ArtistCopyWith<$Res> {
factory _$$_ArtistCopyWith(_$_Artist value, $Res Function(_$_Artist) then) = factory _$$ArtistImplCopyWith(
__$$_ArtistCopyWithImpl<$Res>; _$ArtistImpl value, $Res Function(_$ArtistImpl) then) =
__$$ArtistImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call( $Res call(
@@ -386,10 +388,11 @@ abstract class _$$_ArtistCopyWith<$Res> implements $ArtistCopyWith<$Res> {
} }
/// @nodoc /// @nodoc
class __$$_ArtistCopyWithImpl<$Res> class __$$ArtistImplCopyWithImpl<$Res>
extends _$ArtistCopyWithImpl<$Res, _$_Artist> extends _$ArtistCopyWithImpl<$Res, _$ArtistImpl>
implements _$$_ArtistCopyWith<$Res> { implements _$$ArtistImplCopyWith<$Res> {
__$$_ArtistCopyWithImpl(_$_Artist _value, $Res Function(_$_Artist) _then) __$$ArtistImplCopyWithImpl(
_$ArtistImpl _value, $Res Function(_$ArtistImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -401,7 +404,7 @@ class __$$_ArtistCopyWithImpl<$Res>
Object? albumCount = null, Object? albumCount = null,
Object? starred = freezed, Object? starred = freezed,
}) { }) {
return _then(_$_Artist( return _then(_$ArtistImpl(
sourceId: null == sourceId sourceId: null == sourceId
? _value.sourceId ? _value.sourceId
: sourceId // ignore: cast_nullable_to_non_nullable : sourceId // ignore: cast_nullable_to_non_nullable
@@ -428,8 +431,8 @@ class __$$_ArtistCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$_Artist with DiagnosticableTreeMixin implements _Artist { class _$ArtistImpl with DiagnosticableTreeMixin implements _Artist {
const _$_Artist( const _$ArtistImpl(
{required this.sourceId, {required this.sourceId,
required this.id, required this.id,
required this.name, required this.name,
@@ -465,10 +468,10 @@ class _$_Artist with DiagnosticableTreeMixin implements _Artist {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_Artist && other is _$ArtistImpl &&
(identical(other.sourceId, sourceId) || (identical(other.sourceId, sourceId) ||
other.sourceId == sourceId) && other.sourceId == sourceId) &&
(identical(other.id, id) || other.id == id) && (identical(other.id, id) || other.id == id) &&
@@ -485,8 +488,8 @@ class _$_Artist with DiagnosticableTreeMixin implements _Artist {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_ArtistCopyWith<_$_Artist> get copyWith => _$$ArtistImplCopyWith<_$ArtistImpl> get copyWith =>
__$$_ArtistCopyWithImpl<_$_Artist>(this, _$identity); __$$ArtistImplCopyWithImpl<_$ArtistImpl>(this, _$identity);
} }
abstract class _Artist implements Artist { abstract class _Artist implements Artist {
@@ -495,7 +498,7 @@ abstract class _Artist implements Artist {
required final String id, required final String id,
required final String name, required final String name,
required final int albumCount, required final int albumCount,
final DateTime? starred}) = _$_Artist; final DateTime? starred}) = _$ArtistImpl;
@override @override
int get sourceId; int get sourceId;
@@ -509,7 +512,7 @@ abstract class _Artist implements Artist {
DateTime? get starred; DateTime? get starred;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_ArtistCopyWith<_$_Artist> get copyWith => _$$ArtistImplCopyWith<_$ArtistImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
@@ -648,9 +651,10 @@ class _$AlbumCopyWithImpl<$Res, $Val extends Album>
} }
/// @nodoc /// @nodoc
abstract class _$$_AlbumCopyWith<$Res> implements $AlbumCopyWith<$Res> { abstract class _$$AlbumImplCopyWith<$Res> implements $AlbumCopyWith<$Res> {
factory _$$_AlbumCopyWith(_$_Album value, $Res Function(_$_Album) then) = factory _$$AlbumImplCopyWith(
__$$_AlbumCopyWithImpl<$Res>; _$AlbumImpl value, $Res Function(_$AlbumImpl) then) =
__$$AlbumImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call( $Res call(
@@ -671,9 +675,11 @@ abstract class _$$_AlbumCopyWith<$Res> implements $AlbumCopyWith<$Res> {
} }
/// @nodoc /// @nodoc
class __$$_AlbumCopyWithImpl<$Res> extends _$AlbumCopyWithImpl<$Res, _$_Album> class __$$AlbumImplCopyWithImpl<$Res>
implements _$$_AlbumCopyWith<$Res> { extends _$AlbumCopyWithImpl<$Res, _$AlbumImpl>
__$$_AlbumCopyWithImpl(_$_Album _value, $Res Function(_$_Album) _then) implements _$$AlbumImplCopyWith<$Res> {
__$$AlbumImplCopyWithImpl(
_$AlbumImpl _value, $Res Function(_$AlbumImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -694,7 +700,7 @@ class __$$_AlbumCopyWithImpl<$Res> extends _$AlbumCopyWithImpl<$Res, _$_Album>
Object? frequentRank = freezed, Object? frequentRank = freezed,
Object? recentRank = freezed, Object? recentRank = freezed,
}) { }) {
return _then(_$_Album( return _then(_$AlbumImpl(
sourceId: null == sourceId sourceId: null == sourceId
? _value.sourceId ? _value.sourceId
: sourceId // ignore: cast_nullable_to_non_nullable : sourceId // ignore: cast_nullable_to_non_nullable
@@ -757,8 +763,8 @@ class __$$_AlbumCopyWithImpl<$Res> extends _$AlbumCopyWithImpl<$Res, _$_Album>
/// @nodoc /// @nodoc
class _$_Album with DiagnosticableTreeMixin implements _Album { class _$AlbumImpl with DiagnosticableTreeMixin implements _Album {
const _$_Album( const _$AlbumImpl(
{required this.sourceId, {required this.sourceId,
required this.id, required this.id,
required this.name, required this.name,
@@ -833,10 +839,10 @@ class _$_Album with DiagnosticableTreeMixin implements _Album {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_Album && other is _$AlbumImpl &&
(identical(other.sourceId, sourceId) || (identical(other.sourceId, sourceId) ||
other.sourceId == sourceId) && other.sourceId == sourceId) &&
(identical(other.id, id) || other.id == id) && (identical(other.id, id) || other.id == id) &&
@@ -882,8 +888,8 @@ class _$_Album with DiagnosticableTreeMixin implements _Album {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_AlbumCopyWith<_$_Album> get copyWith => _$$AlbumImplCopyWith<_$AlbumImpl> get copyWith =>
__$$_AlbumCopyWithImpl<_$_Album>(this, _$identity); __$$AlbumImplCopyWithImpl<_$AlbumImpl>(this, _$identity);
} }
abstract class _Album implements Album { abstract class _Album implements Album {
@@ -901,7 +907,7 @@ abstract class _Album implements Album {
required final int songCount, required final int songCount,
final bool isDeleted, final bool isDeleted,
final int? frequentRank, final int? frequentRank,
final int? recentRank}) = _$_Album; final int? recentRank}) = _$AlbumImpl;
@override @override
int get sourceId; int get sourceId;
@@ -933,7 +939,7 @@ abstract class _Album implements Album {
int? get recentRank; int? get recentRank;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_AlbumCopyWith<_$_Album> get copyWith => _$$AlbumImplCopyWith<_$AlbumImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
@@ -1022,10 +1028,11 @@ class _$PlaylistCopyWithImpl<$Res, $Val extends Playlist>
} }
/// @nodoc /// @nodoc
abstract class _$$_PlaylistCopyWith<$Res> implements $PlaylistCopyWith<$Res> { abstract class _$$PlaylistImplCopyWith<$Res>
factory _$$_PlaylistCopyWith( implements $PlaylistCopyWith<$Res> {
_$_Playlist value, $Res Function(_$_Playlist) then) = factory _$$PlaylistImplCopyWith(
__$$_PlaylistCopyWithImpl<$Res>; _$PlaylistImpl value, $Res Function(_$PlaylistImpl) then) =
__$$PlaylistImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call( $Res call(
@@ -1039,11 +1046,11 @@ abstract class _$$_PlaylistCopyWith<$Res> implements $PlaylistCopyWith<$Res> {
} }
/// @nodoc /// @nodoc
class __$$_PlaylistCopyWithImpl<$Res> class __$$PlaylistImplCopyWithImpl<$Res>
extends _$PlaylistCopyWithImpl<$Res, _$_Playlist> extends _$PlaylistCopyWithImpl<$Res, _$PlaylistImpl>
implements _$$_PlaylistCopyWith<$Res> { implements _$$PlaylistImplCopyWith<$Res> {
__$$_PlaylistCopyWithImpl( __$$PlaylistImplCopyWithImpl(
_$_Playlist _value, $Res Function(_$_Playlist) _then) _$PlaylistImpl _value, $Res Function(_$PlaylistImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -1057,7 +1064,7 @@ class __$$_PlaylistCopyWithImpl<$Res>
Object? songCount = null, Object? songCount = null,
Object? created = null, Object? created = null,
}) { }) {
return _then(_$_Playlist( return _then(_$PlaylistImpl(
sourceId: null == sourceId sourceId: null == sourceId
? _value.sourceId ? _value.sourceId
: sourceId // ignore: cast_nullable_to_non_nullable : sourceId // ignore: cast_nullable_to_non_nullable
@@ -1092,8 +1099,8 @@ class __$$_PlaylistCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$_Playlist with DiagnosticableTreeMixin implements _Playlist { class _$PlaylistImpl with DiagnosticableTreeMixin implements _Playlist {
const _$_Playlist( const _$PlaylistImpl(
{required this.sourceId, {required this.sourceId,
required this.id, required this.id,
required this.name, required this.name,
@@ -1137,10 +1144,10 @@ class _$_Playlist with DiagnosticableTreeMixin implements _Playlist {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_Playlist && other is _$PlaylistImpl &&
(identical(other.sourceId, sourceId) || (identical(other.sourceId, sourceId) ||
other.sourceId == sourceId) && other.sourceId == sourceId) &&
(identical(other.id, id) || other.id == id) && (identical(other.id, id) || other.id == id) &&
@@ -1160,8 +1167,8 @@ class _$_Playlist with DiagnosticableTreeMixin implements _Playlist {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_PlaylistCopyWith<_$_Playlist> get copyWith => _$$PlaylistImplCopyWith<_$PlaylistImpl> get copyWith =>
__$$_PlaylistCopyWithImpl<_$_Playlist>(this, _$identity); __$$PlaylistImplCopyWithImpl<_$PlaylistImpl>(this, _$identity);
} }
abstract class _Playlist implements Playlist { abstract class _Playlist implements Playlist {
@@ -1172,7 +1179,7 @@ abstract class _Playlist implements Playlist {
final String? comment, final String? comment,
final String? coverArt, final String? coverArt,
required final int songCount, required final int songCount,
required final DateTime created}) = _$_Playlist; required final DateTime created}) = _$PlaylistImpl;
@override @override
int get sourceId; int get sourceId;
@@ -1190,7 +1197,7 @@ abstract class _Playlist implements Playlist {
DateTime get created; DateTime get created;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_PlaylistCopyWith<_$_Playlist> get copyWith => _$$PlaylistImplCopyWith<_$PlaylistImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
@@ -1334,9 +1341,10 @@ class _$SongCopyWithImpl<$Res, $Val extends Song>
} }
/// @nodoc /// @nodoc
abstract class _$$_SongCopyWith<$Res> implements $SongCopyWith<$Res> { abstract class _$$SongImplCopyWith<$Res> implements $SongCopyWith<$Res> {
factory _$$_SongCopyWith(_$_Song value, $Res Function(_$_Song) then) = factory _$$SongImplCopyWith(
__$$_SongCopyWithImpl<$Res>; _$SongImpl value, $Res Function(_$SongImpl) then) =
__$$SongImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call( $Res call(
@@ -1358,9 +1366,10 @@ abstract class _$$_SongCopyWith<$Res> implements $SongCopyWith<$Res> {
} }
/// @nodoc /// @nodoc
class __$$_SongCopyWithImpl<$Res> extends _$SongCopyWithImpl<$Res, _$_Song> class __$$SongImplCopyWithImpl<$Res>
implements _$$_SongCopyWith<$Res> { extends _$SongCopyWithImpl<$Res, _$SongImpl>
__$$_SongCopyWithImpl(_$_Song _value, $Res Function(_$_Song) _then) implements _$$SongImplCopyWith<$Res> {
__$$SongImplCopyWithImpl(_$SongImpl _value, $Res Function(_$SongImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -1382,7 +1391,7 @@ class __$$_SongCopyWithImpl<$Res> extends _$SongCopyWithImpl<$Res, _$_Song>
Object? downloadFilePath = freezed, Object? downloadFilePath = freezed,
Object? isDeleted = null, Object? isDeleted = null,
}) { }) {
return _then(_$_Song( return _then(_$SongImpl(
sourceId: null == sourceId sourceId: null == sourceId
? _value.sourceId ? _value.sourceId
: sourceId // ignore: cast_nullable_to_non_nullable : sourceId // ignore: cast_nullable_to_non_nullable
@@ -1449,8 +1458,8 @@ class __$$_SongCopyWithImpl<$Res> extends _$SongCopyWithImpl<$Res, _$_Song>
/// @nodoc /// @nodoc
class _$_Song with DiagnosticableTreeMixin implements _Song { class _$SongImpl with DiagnosticableTreeMixin implements _Song {
const _$_Song( const _$SongImpl(
{required this.sourceId, {required this.sourceId,
required this.id, required this.id,
this.albumId, this.albumId,
@@ -1527,10 +1536,10 @@ class _$_Song with DiagnosticableTreeMixin implements _Song {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_Song && other is _$SongImpl &&
(identical(other.sourceId, sourceId) || (identical(other.sourceId, sourceId) ||
other.sourceId == sourceId) && other.sourceId == sourceId) &&
(identical(other.id, id) || other.id == id) && (identical(other.id, id) || other.id == id) &&
@@ -1576,8 +1585,8 @@ class _$_Song with DiagnosticableTreeMixin implements _Song {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_SongCopyWith<_$_Song> get copyWith => _$$SongImplCopyWith<_$SongImpl> get copyWith =>
__$$_SongCopyWithImpl<_$_Song>(this, _$identity); __$$SongImplCopyWithImpl<_$SongImpl>(this, _$identity);
} }
abstract class _Song implements Song { abstract class _Song implements Song {
@@ -1596,7 +1605,7 @@ abstract class _Song implements Song {
final String? genre, final String? genre,
final String? downloadTaskId, final String? downloadTaskId,
final String? downloadFilePath, final String? downloadFilePath,
final bool isDeleted}) = _$_Song; final bool isDeleted}) = _$SongImpl;
@override @override
int get sourceId; int get sourceId;
@@ -1630,7 +1639,8 @@ abstract class _Song implements Song {
bool get isDeleted; bool get isDeleted;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_SongCopyWith<_$_Song> get copyWith => throw _privateConstructorUsedError; _$$SongImplCopyWith<_$SongImpl> get copyWith =>
throw _privateConstructorUsedError;
} }
/// @nodoc /// @nodoc
@@ -1698,11 +1708,11 @@ class _$SearchResultsCopyWithImpl<$Res, $Val extends SearchResults>
} }
/// @nodoc /// @nodoc
abstract class _$$_SearchResultsCopyWith<$Res> abstract class _$$SearchResultsImplCopyWith<$Res>
implements $SearchResultsCopyWith<$Res> { implements $SearchResultsCopyWith<$Res> {
factory _$$_SearchResultsCopyWith( factory _$$SearchResultsImplCopyWith(
_$_SearchResults value, $Res Function(_$_SearchResults) then) = _$SearchResultsImpl value, $Res Function(_$SearchResultsImpl) then) =
__$$_SearchResultsCopyWithImpl<$Res>; __$$SearchResultsImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call( $Res call(
@@ -1713,11 +1723,11 @@ abstract class _$$_SearchResultsCopyWith<$Res>
} }
/// @nodoc /// @nodoc
class __$$_SearchResultsCopyWithImpl<$Res> class __$$SearchResultsImplCopyWithImpl<$Res>
extends _$SearchResultsCopyWithImpl<$Res, _$_SearchResults> extends _$SearchResultsCopyWithImpl<$Res, _$SearchResultsImpl>
implements _$$_SearchResultsCopyWith<$Res> { implements _$$SearchResultsImplCopyWith<$Res> {
__$$_SearchResultsCopyWithImpl( __$$SearchResultsImplCopyWithImpl(
_$_SearchResults _value, $Res Function(_$_SearchResults) _then) _$SearchResultsImpl _value, $Res Function(_$SearchResultsImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -1728,7 +1738,7 @@ class __$$_SearchResultsCopyWithImpl<$Res>
Object? albums = null, Object? albums = null,
Object? artists = null, Object? artists = null,
}) { }) {
return _then(_$_SearchResults( return _then(_$SearchResultsImpl(
query: freezed == query query: freezed == query
? _value.query ? _value.query
: query // ignore: cast_nullable_to_non_nullable : query // ignore: cast_nullable_to_non_nullable
@@ -1751,8 +1761,10 @@ class __$$_SearchResultsCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$_SearchResults with DiagnosticableTreeMixin implements _SearchResults { class _$SearchResultsImpl
const _$_SearchResults( with DiagnosticableTreeMixin
implements _SearchResults {
const _$SearchResultsImpl(
{this.query, {this.query,
this.songs = const IListConst([]), this.songs = const IListConst([]),
this.albums = const IListConst([]), this.albums = const IListConst([]),
@@ -1787,10 +1799,10 @@ class _$_SearchResults with DiagnosticableTreeMixin implements _SearchResults {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_SearchResults && other is _$SearchResultsImpl &&
(identical(other.query, query) || other.query == query) && (identical(other.query, query) || other.query == query) &&
const DeepCollectionEquality().equals(other.songs, songs) && const DeepCollectionEquality().equals(other.songs, songs) &&
const DeepCollectionEquality().equals(other.albums, albums) && const DeepCollectionEquality().equals(other.albums, albums) &&
@@ -1808,8 +1820,8 @@ class _$_SearchResults with DiagnosticableTreeMixin implements _SearchResults {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_SearchResultsCopyWith<_$_SearchResults> get copyWith => _$$SearchResultsImplCopyWith<_$SearchResultsImpl> get copyWith =>
__$$_SearchResultsCopyWithImpl<_$_SearchResults>(this, _$identity); __$$SearchResultsImplCopyWithImpl<_$SearchResultsImpl>(this, _$identity);
} }
abstract class _SearchResults implements SearchResults { abstract class _SearchResults implements SearchResults {
@@ -1817,7 +1829,7 @@ abstract class _SearchResults implements SearchResults {
{final String? query, {final String? query,
final IList<Song> songs, final IList<Song> songs,
final IList<Album> albums, final IList<Album> albums,
final IList<Artist> artists}) = _$_SearchResults; final IList<Artist> artists}) = _$SearchResultsImpl;
@override @override
String? get query; String? get query;
@@ -1829,6 +1841,6 @@ abstract class _SearchResults implements SearchResults {
IList<Artist> get artists; IList<Artist> get artists;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_SearchResultsCopyWith<_$_SearchResults> get copyWith => _$$SearchResultsImplCopyWith<_$SearchResultsImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -6,25 +6,26 @@ part of 'query.dart';
// JsonSerializableGenerator // JsonSerializableGenerator
// ************************************************************************** // **************************************************************************
_$_Pagination _$$_PaginationFromJson(Map<String, dynamic> json) => _$PaginationImpl _$$PaginationImplFromJson(Map<String, dynamic> json) =>
_$_Pagination( _$PaginationImpl(
limit: json['limit'] as int, limit: (json['limit'] as num).toInt(),
offset: json['offset'] as int? ?? 0, offset: (json['offset'] as num?)?.toInt() ?? 0,
); );
Map<String, dynamic> _$$_PaginationToJson(_$_Pagination instance) => Map<String, dynamic> _$$PaginationImplToJson(_$PaginationImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'limit': instance.limit, 'limit': instance.limit,
'offset': instance.offset, 'offset': instance.offset,
}; };
_$_SortBy _$$_SortByFromJson(Map<String, dynamic> json) => _$_SortBy( _$SortByImpl _$$SortByImplFromJson(Map<String, dynamic> json) => _$SortByImpl(
column: json['column'] as String, column: json['column'] as String,
dir: $enumDecodeNullable(_$SortDirectionEnumMap, json['dir']) ?? dir: $enumDecodeNullable(_$SortDirectionEnumMap, json['dir']) ??
SortDirection.asc, SortDirection.asc,
); );
Map<String, dynamic> _$$_SortByToJson(_$_SortBy instance) => <String, dynamic>{ Map<String, dynamic> _$$SortByImplToJson(_$SortByImpl instance) =>
<String, dynamic>{
'column': instance.column, 'column': instance.column,
'dir': _$SortDirectionEnumMap[instance.dir]!, 'dir': _$SortDirectionEnumMap[instance.dir]!,
}; };
@@ -34,15 +35,17 @@ const _$SortDirectionEnumMap = {
SortDirection.desc: 'desc', SortDirection.desc: 'desc',
}; };
_$_FilterWithEquals _$$_FilterWithEqualsFromJson(Map<String, dynamic> json) => _$FilterWithEqualsImpl _$$FilterWithEqualsImplFromJson(
_$_FilterWithEquals( Map<String, dynamic> json) =>
_$FilterWithEqualsImpl(
column: json['column'] as String, column: json['column'] as String,
value: json['value'] as String, value: json['value'] as String,
invert: json['invert'] as bool? ?? false, invert: json['invert'] as bool? ?? false,
$type: json['runtimeType'] as String?, $type: json['runtimeType'] as String?,
); );
Map<String, dynamic> _$$_FilterWithEqualsToJson(_$_FilterWithEquals instance) => Map<String, dynamic> _$$FilterWithEqualsImplToJson(
_$FilterWithEqualsImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'column': instance.column, 'column': instance.column,
'value': instance.value, 'value': instance.value,
@@ -50,17 +53,17 @@ Map<String, dynamic> _$$_FilterWithEqualsToJson(_$_FilterWithEquals instance) =>
'runtimeType': instance.$type, 'runtimeType': instance.$type,
}; };
_$_FilterWithGreaterThan _$$_FilterWithGreaterThanFromJson( _$FilterWithGreaterThanImpl _$$FilterWithGreaterThanImplFromJson(
Map<String, dynamic> json) => Map<String, dynamic> json) =>
_$_FilterWithGreaterThan( _$FilterWithGreaterThanImpl(
column: json['column'] as String, column: json['column'] as String,
value: json['value'] as String, value: json['value'] as String,
orEquals: json['orEquals'] as bool? ?? false, orEquals: json['orEquals'] as bool? ?? false,
$type: json['runtimeType'] as String?, $type: json['runtimeType'] as String?,
); );
Map<String, dynamic> _$$_FilterWithGreaterThanToJson( Map<String, dynamic> _$$FilterWithGreaterThanImplToJson(
_$_FilterWithGreaterThan instance) => _$FilterWithGreaterThanImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'column': instance.column, 'column': instance.column,
'value': instance.value, 'value': instance.value,
@@ -68,31 +71,33 @@ Map<String, dynamic> _$$_FilterWithGreaterThanToJson(
'runtimeType': instance.$type, 'runtimeType': instance.$type,
}; };
_$_FilterWithIsNull _$$_FilterWithIsNullFromJson(Map<String, dynamic> json) => _$FilterWithIsNullImpl _$$FilterWithIsNullImplFromJson(
_$_FilterWithIsNull( Map<String, dynamic> json) =>
_$FilterWithIsNullImpl(
column: json['column'] as String, column: json['column'] as String,
invert: json['invert'] as bool? ?? false, invert: json['invert'] as bool? ?? false,
$type: json['runtimeType'] as String?, $type: json['runtimeType'] as String?,
); );
Map<String, dynamic> _$$_FilterWithIsNullToJson(_$_FilterWithIsNull instance) => Map<String, dynamic> _$$FilterWithIsNullImplToJson(
_$FilterWithIsNullImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'column': instance.column, 'column': instance.column,
'invert': instance.invert, 'invert': instance.invert,
'runtimeType': instance.$type, 'runtimeType': instance.$type,
}; };
_$_FilterWithBetweenInt _$$_FilterWithBetweenIntFromJson( _$FilterWithBetweenIntImpl _$$FilterWithBetweenIntImplFromJson(
Map<String, dynamic> json) => Map<String, dynamic> json) =>
_$_FilterWithBetweenInt( _$FilterWithBetweenIntImpl(
column: json['column'] as String, column: json['column'] as String,
from: json['from'] as int, from: (json['from'] as num).toInt(),
to: json['to'] as int, to: (json['to'] as num).toInt(),
$type: json['runtimeType'] as String?, $type: json['runtimeType'] as String?,
); );
Map<String, dynamic> _$$_FilterWithBetweenIntToJson( Map<String, dynamic> _$$FilterWithBetweenIntImplToJson(
_$_FilterWithBetweenInt instance) => _$FilterWithBetweenIntImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'column': instance.column, 'column': instance.column,
'from': instance.from, 'from': instance.from,
@@ -100,8 +105,8 @@ Map<String, dynamic> _$$_FilterWithBetweenIntToJson(
'runtimeType': instance.$type, 'runtimeType': instance.$type,
}; };
_$_FilterWithIsIn _$$_FilterWithIsInFromJson(Map<String, dynamic> json) => _$FilterWithIsInImpl _$$FilterWithIsInImplFromJson(Map<String, dynamic> json) =>
_$_FilterWithIsIn( _$FilterWithIsInImpl(
column: json['column'] as String, column: json['column'] as String,
invert: json['invert'] as bool? ?? false, invert: json['invert'] as bool? ?? false,
values: json['values'] == null values: json['values'] == null
@@ -110,7 +115,8 @@ _$_FilterWithIsIn _$$_FilterWithIsInFromJson(Map<String, dynamic> json) =>
$type: json['runtimeType'] as String?, $type: json['runtimeType'] as String?,
); );
Map<String, dynamic> _$$_FilterWithIsInToJson(_$_FilterWithIsIn instance) => Map<String, dynamic> _$$FilterWithIsInImplToJson(
_$FilterWithIsInImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'column': instance.column, 'column': instance.column,
'invert': instance.invert, 'invert': instance.invert,
@@ -120,7 +126,8 @@ Map<String, dynamic> _$$_FilterWithIsInToJson(_$_FilterWithIsIn instance) =>
'runtimeType': instance.$type, 'runtimeType': instance.$type,
}; };
_$_ListQuery _$$_ListQueryFromJson(Map<String, dynamic> json) => _$_ListQuery( _$ListQueryImpl _$$ListQueryImplFromJson(Map<String, dynamic> json) =>
_$ListQueryImpl(
page: json['page'] == null page: json['page'] == null
? const Pagination(limit: -1, offset: 0) ? const Pagination(limit: -1, offset: 0)
: Pagination.fromJson(json['page'] as Map<String, dynamic>), : Pagination.fromJson(json['page'] as Map<String, dynamic>),
@@ -133,7 +140,7 @@ _$_ListQuery _$$_ListQueryFromJson(Map<String, dynamic> json) => _$_ListQuery(
(value) => FilterWith.fromJson(value as Map<String, dynamic>)), (value) => FilterWith.fromJson(value as Map<String, dynamic>)),
); );
Map<String, dynamic> _$$_ListQueryToJson(_$_ListQuery instance) => Map<String, dynamic> _$$ListQueryImplToJson(_$ListQueryImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'page': instance.page, 'page': instance.page,
'sort': instance.sort, 'sort': instance.sort,

View File

@@ -12,7 +12,7 @@ part of 'settings.dart';
T _$identity<T>(T value) => value; T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError( final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
/// @nodoc /// @nodoc
mixin _$Settings { mixin _$Settings {
@@ -81,10 +81,11 @@ class _$SettingsCopyWithImpl<$Res, $Val extends Settings>
} }
/// @nodoc /// @nodoc
abstract class _$$_SettingsCopyWith<$Res> implements $SettingsCopyWith<$Res> { abstract class _$$SettingsImplCopyWith<$Res>
factory _$$_SettingsCopyWith( implements $SettingsCopyWith<$Res> {
_$_Settings value, $Res Function(_$_Settings) then) = factory _$$SettingsImplCopyWith(
__$$_SettingsCopyWithImpl<$Res>; _$SettingsImpl value, $Res Function(_$SettingsImpl) then) =
__$$SettingsImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call( $Res call(
@@ -97,11 +98,11 @@ abstract class _$$_SettingsCopyWith<$Res> implements $SettingsCopyWith<$Res> {
} }
/// @nodoc /// @nodoc
class __$$_SettingsCopyWithImpl<$Res> class __$$SettingsImplCopyWithImpl<$Res>
extends _$SettingsCopyWithImpl<$Res, _$_Settings> extends _$SettingsCopyWithImpl<$Res, _$SettingsImpl>
implements _$$_SettingsCopyWith<$Res> { implements _$$SettingsImplCopyWith<$Res> {
__$$_SettingsCopyWithImpl( __$$SettingsImplCopyWithImpl(
_$_Settings _value, $Res Function(_$_Settings) _then) _$SettingsImpl _value, $Res Function(_$SettingsImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -111,7 +112,7 @@ class __$$_SettingsCopyWithImpl<$Res>
Object? activeSource = freezed, Object? activeSource = freezed,
Object? app = null, Object? app = null,
}) { }) {
return _then(_$_Settings( return _then(_$SettingsImpl(
sources: null == sources sources: null == sources
? _value.sources ? _value.sources
: sources // ignore: cast_nullable_to_non_nullable : sources // ignore: cast_nullable_to_non_nullable
@@ -130,8 +131,8 @@ class __$$_SettingsCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$_Settings implements _Settings { class _$SettingsImpl implements _Settings {
const _$_Settings( const _$SettingsImpl(
{this.sources = const IListConst([]), {this.sources = const IListConst([]),
this.activeSource, this.activeSource,
this.app = const AppSettings()}); this.app = const AppSettings()});
@@ -151,10 +152,10 @@ class _$_Settings implements _Settings {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_Settings && other is _$SettingsImpl &&
const DeepCollectionEquality().equals(other.sources, sources) && const DeepCollectionEquality().equals(other.sources, sources) &&
(identical(other.activeSource, activeSource) || (identical(other.activeSource, activeSource) ||
other.activeSource == activeSource) && other.activeSource == activeSource) &&
@@ -168,15 +169,15 @@ class _$_Settings implements _Settings {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_SettingsCopyWith<_$_Settings> get copyWith => _$$SettingsImplCopyWith<_$SettingsImpl> get copyWith =>
__$$_SettingsCopyWithImpl<_$_Settings>(this, _$identity); __$$SettingsImplCopyWithImpl<_$SettingsImpl>(this, _$identity);
} }
abstract class _Settings implements Settings { abstract class _Settings implements Settings {
const factory _Settings( const factory _Settings(
{final IList<SourceSettings> sources, {final IList<SourceSettings> sources,
final SourceSettings? activeSource, final SourceSettings? activeSource,
final AppSettings app}) = _$_Settings; final AppSettings app}) = _$SettingsImpl;
@override @override
IList<SourceSettings> get sources; IList<SourceSettings> get sources;
@@ -186,7 +187,7 @@ abstract class _Settings implements Settings {
AppSettings get app; AppSettings get app;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_SettingsCopyWith<_$_Settings> get copyWith => _$$SettingsImplCopyWith<_$SettingsImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
@@ -245,22 +246,22 @@ class _$AppSettingsCopyWithImpl<$Res, $Val extends AppSettings>
} }
/// @nodoc /// @nodoc
abstract class _$$_AppSettingsCopyWith<$Res> abstract class _$$AppSettingsImplCopyWith<$Res>
implements $AppSettingsCopyWith<$Res> { implements $AppSettingsCopyWith<$Res> {
factory _$$_AppSettingsCopyWith( factory _$$AppSettingsImplCopyWith(
_$_AppSettings value, $Res Function(_$_AppSettings) then) = _$AppSettingsImpl value, $Res Function(_$AppSettingsImpl) then) =
__$$_AppSettingsCopyWithImpl<$Res>; __$$AppSettingsImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call({int maxBitrateWifi, int maxBitrateMobile, String? streamFormat}); $Res call({int maxBitrateWifi, int maxBitrateMobile, String? streamFormat});
} }
/// @nodoc /// @nodoc
class __$$_AppSettingsCopyWithImpl<$Res> class __$$AppSettingsImplCopyWithImpl<$Res>
extends _$AppSettingsCopyWithImpl<$Res, _$_AppSettings> extends _$AppSettingsCopyWithImpl<$Res, _$AppSettingsImpl>
implements _$$_AppSettingsCopyWith<$Res> { implements _$$AppSettingsImplCopyWith<$Res> {
__$$_AppSettingsCopyWithImpl( __$$AppSettingsImplCopyWithImpl(
_$_AppSettings _value, $Res Function(_$_AppSettings) _then) _$AppSettingsImpl _value, $Res Function(_$AppSettingsImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -270,7 +271,7 @@ class __$$_AppSettingsCopyWithImpl<$Res>
Object? maxBitrateMobile = null, Object? maxBitrateMobile = null,
Object? streamFormat = freezed, Object? streamFormat = freezed,
}) { }) {
return _then(_$_AppSettings( return _then(_$AppSettingsImpl(
maxBitrateWifi: null == maxBitrateWifi maxBitrateWifi: null == maxBitrateWifi
? _value.maxBitrateWifi ? _value.maxBitrateWifi
: maxBitrateWifi // ignore: cast_nullable_to_non_nullable : maxBitrateWifi // ignore: cast_nullable_to_non_nullable
@@ -289,8 +290,8 @@ class __$$_AppSettingsCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$_AppSettings extends _AppSettings { class _$AppSettingsImpl extends _AppSettings {
const _$_AppSettings( const _$AppSettingsImpl(
{this.maxBitrateWifi = 0, {this.maxBitrateWifi = 0,
this.maxBitrateMobile = 192, this.maxBitrateMobile = 192,
this.streamFormat = 'mp3'}) this.streamFormat = 'mp3'})
@@ -312,10 +313,10 @@ class _$_AppSettings extends _AppSettings {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_AppSettings && other is _$AppSettingsImpl &&
(identical(other.maxBitrateWifi, maxBitrateWifi) || (identical(other.maxBitrateWifi, maxBitrateWifi) ||
other.maxBitrateWifi == maxBitrateWifi) && other.maxBitrateWifi == maxBitrateWifi) &&
(identical(other.maxBitrateMobile, maxBitrateMobile) || (identical(other.maxBitrateMobile, maxBitrateMobile) ||
@@ -331,15 +332,15 @@ class _$_AppSettings extends _AppSettings {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_AppSettingsCopyWith<_$_AppSettings> get copyWith => _$$AppSettingsImplCopyWith<_$AppSettingsImpl> get copyWith =>
__$$_AppSettingsCopyWithImpl<_$_AppSettings>(this, _$identity); __$$AppSettingsImplCopyWithImpl<_$AppSettingsImpl>(this, _$identity);
} }
abstract class _AppSettings extends AppSettings { abstract class _AppSettings extends AppSettings {
const factory _AppSettings( const factory _AppSettings(
{final int maxBitrateWifi, {final int maxBitrateWifi,
final int maxBitrateMobile, final int maxBitrateMobile,
final String? streamFormat}) = _$_AppSettings; final String? streamFormat}) = _$AppSettingsImpl;
const _AppSettings._() : super._(); const _AppSettings._() : super._();
@override @override
@@ -350,7 +351,7 @@ abstract class _AppSettings extends AppSettings {
String? get streamFormat; String? get streamFormat;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_AppSettingsCopyWith<_$_AppSettings> get copyWith => _$$AppSettingsImplCopyWith<_$AppSettingsImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
@@ -454,11 +455,11 @@ class _$SubsonicSettingsCopyWithImpl<$Res, $Val extends SubsonicSettings>
} }
/// @nodoc /// @nodoc
abstract class _$$_SubsonicSettingsCopyWith<$Res> abstract class _$$SubsonicSettingsImplCopyWith<$Res>
implements $SubsonicSettingsCopyWith<$Res> { implements $SubsonicSettingsCopyWith<$Res> {
factory _$$_SubsonicSettingsCopyWith( factory _$$SubsonicSettingsImplCopyWith(_$SubsonicSettingsImpl value,
_$_SubsonicSettings value, $Res Function(_$_SubsonicSettings) then) = $Res Function(_$SubsonicSettingsImpl) then) =
__$$_SubsonicSettingsCopyWithImpl<$Res>; __$$SubsonicSettingsImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call( $Res call(
@@ -474,11 +475,11 @@ abstract class _$$_SubsonicSettingsCopyWith<$Res>
} }
/// @nodoc /// @nodoc
class __$$_SubsonicSettingsCopyWithImpl<$Res> class __$$SubsonicSettingsImplCopyWithImpl<$Res>
extends _$SubsonicSettingsCopyWithImpl<$Res, _$_SubsonicSettings> extends _$SubsonicSettingsCopyWithImpl<$Res, _$SubsonicSettingsImpl>
implements _$$_SubsonicSettingsCopyWith<$Res> { implements _$$SubsonicSettingsImplCopyWith<$Res> {
__$$_SubsonicSettingsCopyWithImpl( __$$SubsonicSettingsImplCopyWithImpl(_$SubsonicSettingsImpl _value,
_$_SubsonicSettings _value, $Res Function(_$_SubsonicSettings) _then) $Res Function(_$SubsonicSettingsImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -494,7 +495,7 @@ class __$$_SubsonicSettingsCopyWithImpl<$Res>
Object? password = null, Object? password = null,
Object? useTokenAuth = null, Object? useTokenAuth = null,
}) { }) {
return _then(_$_SubsonicSettings( return _then(_$SubsonicSettingsImpl(
id: null == id id: null == id
? _value.id ? _value.id
: id // ignore: cast_nullable_to_non_nullable : id // ignore: cast_nullable_to_non_nullable
@@ -537,8 +538,8 @@ class __$$_SubsonicSettingsCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$_SubsonicSettings extends _SubsonicSettings { class _$SubsonicSettingsImpl extends _SubsonicSettings {
const _$_SubsonicSettings( const _$SubsonicSettingsImpl(
{required this.id, {required this.id,
this.features = const IListConst([]), this.features = const IListConst([]),
required this.name, required this.name,
@@ -577,10 +578,10 @@ class _$_SubsonicSettings extends _SubsonicSettings {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_SubsonicSettings && other is _$SubsonicSettingsImpl &&
(identical(other.id, id) || other.id == id) && (identical(other.id, id) || other.id == id) &&
const DeepCollectionEquality().equals(other.features, features) && const DeepCollectionEquality().equals(other.features, features) &&
(identical(other.name, name) || other.name == name) && (identical(other.name, name) || other.name == name) &&
@@ -613,8 +614,9 @@ class _$_SubsonicSettings extends _SubsonicSettings {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_SubsonicSettingsCopyWith<_$_SubsonicSettings> get copyWith => _$$SubsonicSettingsImplCopyWith<_$SubsonicSettingsImpl> get copyWith =>
__$$_SubsonicSettingsCopyWithImpl<_$_SubsonicSettings>(this, _$identity); __$$SubsonicSettingsImplCopyWithImpl<_$SubsonicSettingsImpl>(
this, _$identity);
} }
abstract class _SubsonicSettings extends SubsonicSettings { abstract class _SubsonicSettings extends SubsonicSettings {
@@ -627,7 +629,7 @@ abstract class _SubsonicSettings extends SubsonicSettings {
required final DateTime createdAt, required final DateTime createdAt,
required final String username, required final String username,
required final String password, required final String password,
final bool useTokenAuth}) = _$_SubsonicSettings; final bool useTokenAuth}) = _$SubsonicSettingsImpl;
const _SubsonicSettings._() : super._(); const _SubsonicSettings._() : super._();
@override @override
@@ -650,7 +652,7 @@ abstract class _SubsonicSettings extends SubsonicSettings {
bool get useTokenAuth; bool get useTokenAuth;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_SubsonicSettingsCopyWith<_$_SubsonicSettings> get copyWith => _$$SubsonicSettingsImplCopyWith<_$SubsonicSettingsImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
@@ -714,11 +716,12 @@ class _$SubsonicSourceSettingsCopyWithImpl<$Res,
} }
/// @nodoc /// @nodoc
abstract class _$$_SubsonicSourceSettingsCopyWith<$Res> abstract class _$$SubsonicSourceSettingsImplCopyWith<$Res>
implements $SubsonicSourceSettingsCopyWith<$Res> { implements $SubsonicSourceSettingsCopyWith<$Res> {
factory _$$_SubsonicSourceSettingsCopyWith(_$_SubsonicSourceSettings value, factory _$$SubsonicSourceSettingsImplCopyWith(
$Res Function(_$_SubsonicSourceSettings) then) = _$SubsonicSourceSettingsImpl value,
__$$_SubsonicSourceSettingsCopyWithImpl<$Res>; $Res Function(_$SubsonicSourceSettingsImpl) then) =
__$$SubsonicSourceSettingsImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call({SourceSettings source, SubsonicSettings subsonic}); $Res call({SourceSettings source, SubsonicSettings subsonic});
@@ -728,12 +731,13 @@ abstract class _$$_SubsonicSourceSettingsCopyWith<$Res>
} }
/// @nodoc /// @nodoc
class __$$_SubsonicSourceSettingsCopyWithImpl<$Res> class __$$SubsonicSourceSettingsImplCopyWithImpl<$Res>
extends _$SubsonicSourceSettingsCopyWithImpl<$Res, extends _$SubsonicSourceSettingsCopyWithImpl<$Res,
_$_SubsonicSourceSettings> _$SubsonicSourceSettingsImpl>
implements _$$_SubsonicSourceSettingsCopyWith<$Res> { implements _$$SubsonicSourceSettingsImplCopyWith<$Res> {
__$$_SubsonicSourceSettingsCopyWithImpl(_$_SubsonicSourceSettings _value, __$$SubsonicSourceSettingsImplCopyWithImpl(
$Res Function(_$_SubsonicSourceSettings) _then) _$SubsonicSourceSettingsImpl _value,
$Res Function(_$SubsonicSourceSettingsImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -742,7 +746,7 @@ class __$$_SubsonicSourceSettingsCopyWithImpl<$Res>
Object? source = null, Object? source = null,
Object? subsonic = null, Object? subsonic = null,
}) { }) {
return _then(_$_SubsonicSourceSettings( return _then(_$SubsonicSourceSettingsImpl(
source: null == source source: null == source
? _value.source ? _value.source
: source // ignore: cast_nullable_to_non_nullable : source // ignore: cast_nullable_to_non_nullable
@@ -757,8 +761,8 @@ class __$$_SubsonicSourceSettingsCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$_SubsonicSourceSettings extends _SubsonicSourceSettings { class _$SubsonicSourceSettingsImpl extends _SubsonicSourceSettings {
const _$_SubsonicSourceSettings( const _$SubsonicSourceSettingsImpl(
{required this.source, required this.subsonic}) {required this.source, required this.subsonic})
: super._(); : super._();
@@ -773,10 +777,10 @@ class _$_SubsonicSourceSettings extends _SubsonicSourceSettings {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_SubsonicSourceSettings && other is _$SubsonicSourceSettingsImpl &&
(identical(other.source, source) || other.source == source) && (identical(other.source, source) || other.source == source) &&
(identical(other.subsonic, subsonic) || (identical(other.subsonic, subsonic) ||
other.subsonic == subsonic)); other.subsonic == subsonic));
@@ -788,15 +792,15 @@ class _$_SubsonicSourceSettings extends _SubsonicSourceSettings {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_SubsonicSourceSettingsCopyWith<_$_SubsonicSourceSettings> get copyWith => _$$SubsonicSourceSettingsImplCopyWith<_$SubsonicSourceSettingsImpl>
__$$_SubsonicSourceSettingsCopyWithImpl<_$_SubsonicSourceSettings>( get copyWith => __$$SubsonicSourceSettingsImplCopyWithImpl<
this, _$identity); _$SubsonicSourceSettingsImpl>(this, _$identity);
} }
abstract class _SubsonicSourceSettings extends SubsonicSourceSettings { abstract class _SubsonicSourceSettings extends SubsonicSourceSettings {
const factory _SubsonicSourceSettings( const factory _SubsonicSourceSettings(
{required final SourceSettings source, {required final SourceSettings source,
required final SubsonicSettings subsonic}) = _$_SubsonicSourceSettings; required final SubsonicSettings subsonic}) = _$SubsonicSourceSettingsImpl;
const _SubsonicSourceSettings._() : super._(); const _SubsonicSourceSettings._() : super._();
@override @override
@@ -805,6 +809,6 @@ abstract class _SubsonicSourceSettings extends SubsonicSourceSettings {
SubsonicSettings get subsonic; SubsonicSettings get subsonic;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_SubsonicSourceSettingsCopyWith<_$_SubsonicSourceSettings> get copyWith => _$$SubsonicSourceSettingsImplCopyWith<_$SubsonicSourceSettingsImpl>
throw _privateConstructorUsedError; get copyWith => throw _privateConstructorUsedError;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -6,15 +6,16 @@ part of 'support.dart';
// JsonSerializableGenerator // JsonSerializableGenerator
// ************************************************************************** // **************************************************************************
_$_QueueItemState _$$_QueueItemStateFromJson(Map<String, dynamic> json) => _$QueueItemStateImpl _$$QueueItemStateImplFromJson(Map<String, dynamic> json) =>
_$_QueueItemState( _$QueueItemStateImpl(
id: json['id'] as String, id: json['id'] as String,
contextType: $enumDecode(_$QueueContextTypeEnumMap, json['contextType']), contextType: $enumDecode(_$QueueContextTypeEnumMap, json['contextType']),
contextId: json['contextId'] as String?, contextId: json['contextId'] as String?,
contextTitle: json['contextTitle'] as String?, contextTitle: json['contextTitle'] as String?,
); );
Map<String, dynamic> _$$_QueueItemStateToJson(_$_QueueItemState instance) => Map<String, dynamic> _$$QueueItemStateImplToJson(
_$QueueItemStateImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'id': instance.id, 'id': instance.id,
'contextType': _$QueueContextTypeEnumMap[instance.contextType]!, 'contextType': _$QueueContextTypeEnumMap[instance.contextType]!,
@@ -31,9 +32,9 @@ const _$QueueContextTypeEnumMap = {
QueueContextType.artist: 'artist', QueueContextType.artist: 'artist',
}; };
_$_MediaItemData _$$_MediaItemDataFromJson(Map<String, dynamic> json) => _$MediaItemDataImpl _$$MediaItemDataImplFromJson(Map<String, dynamic> json) =>
_$_MediaItemData( _$MediaItemDataImpl(
sourceId: json['sourceId'] as int, sourceId: (json['sourceId'] as num).toInt(),
albumId: json['albumId'] as String?, albumId: json['albumId'] as String?,
artCache: artCache:
_$JsonConverterFromJson<Map<String, dynamic>, MediaItemArtCache>( _$JsonConverterFromJson<Map<String, dynamic>, MediaItemArtCache>(
@@ -42,7 +43,7 @@ _$_MediaItemData _$$_MediaItemDataFromJson(Map<String, dynamic> json) =>
contextId: json['contextId'] as String?, contextId: json['contextId'] as String?,
); );
Map<String, dynamic> _$$_MediaItemDataToJson(_$_MediaItemData instance) => Map<String, dynamic> _$$MediaItemDataImplToJson(_$MediaItemDataImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'sourceId': instance.sourceId, 'sourceId': instance.sourceId,
'albumId': instance.albumId, 'albumId': instance.albumId,
@@ -65,16 +66,17 @@ Json? _$JsonConverterToJson<Json, Value>(
) => ) =>
value == null ? null : toJson(value); value == null ? null : toJson(value);
_$_MediaItemArtCache _$$_MediaItemArtCacheFromJson(Map<String, dynamic> json) => _$MediaItemArtCacheImpl _$$MediaItemArtCacheImplFromJson(
_$_MediaItemArtCache( Map<String, dynamic> json) =>
_$MediaItemArtCacheImpl(
fullArtUri: Uri.parse(json['fullArtUri'] as String), fullArtUri: Uri.parse(json['fullArtUri'] as String),
fullArtCacheKey: json['fullArtCacheKey'] as String, fullArtCacheKey: json['fullArtCacheKey'] as String,
thumbnailArtUri: Uri.parse(json['thumbnailArtUri'] as String), thumbnailArtUri: Uri.parse(json['thumbnailArtUri'] as String),
thumbnailArtCacheKey: json['thumbnailArtCacheKey'] as String, thumbnailArtCacheKey: json['thumbnailArtCacheKey'] as String,
); );
Map<String, dynamic> _$$_MediaItemArtCacheToJson( Map<String, dynamic> _$$MediaItemArtCacheImplToJson(
_$_MediaItemArtCache instance) => _$MediaItemArtCacheImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'fullArtUri': instance.fullArtUri.toString(), 'fullArtUri': instance.fullArtUri.toString(),
'fullArtCacheKey': instance.fullArtCacheKey, 'fullArtCacheKey': instance.fullArtCacheKey,

View File

@@ -4,7 +4,6 @@ import 'dart:math';
import 'package:audio_service/audio_service.dart'; import 'package:audio_service/audio_service.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:drift/drift.dart' show Value; import 'package:drift/drift.dart' show Value;
import 'package:flutter/foundation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:just_audio/just_audio.dart'; import 'package:just_audio/just_audio.dart';
import 'package:pool/pool.dart'; import 'package:pool/pool.dart';
@@ -14,6 +13,7 @@ import 'package:synchronized/synchronized.dart';
import '../cache/image_cache.dart'; import '../cache/image_cache.dart';
import '../database/database.dart'; import '../database/database.dart';
import '../log.dart';
import '../models/music.dart'; import '../models/music.dart';
import '../models/query.dart'; import '../models/query.dart';
import '../models/support.dart'; import '../models/support.dart';
@@ -122,6 +122,10 @@ class AudioControl extends BaseAudioHandler with QueueHandler, SeekHandler {
)); ));
}); });
_player.playbackEventStream.doOnError((e, st) async {
log.warning('playbackEventStream', e, st);
});
shuffleIndicies.listen((value) { shuffleIndicies.listen((value) {
playbackState.add(playbackState.value.copyWith( playbackState.add(playbackState.value.copyWith(
shuffleMode: value != null shuffleMode: value != null
@@ -137,7 +141,7 @@ class AudioControl extends BaseAudioHandler with QueueHandler, SeekHandler {
_player.processingStateStream.listen((event) async { _player.processingStateStream.listen((event) async {
if (event == ProcessingState.completed) { if (event == ProcessingState.completed) {
if (_audioSource.length > 0) { if (_audioSource.length > 0) {
yell('completed'); log.fine('completed');
await stop(); await stop();
await seek(Duration.zero); await seek(Duration.zero);
} }
@@ -386,7 +390,7 @@ class AudioControl extends BaseAudioHandler with QueueHandler, SeekHandler {
mediaItem.add(slice.current!.mediaItem); mediaItem.add(slice.current!.mediaItem);
queue.add(list.map((e) => e.mediaItem).toList()); queue.add(list.map((e) => e.mediaItem).toList());
yell('addAll'); log.fine('addAll');
await _audioSource.addAll(list.map((e) => e.audioSource).toList()); await _audioSource.addAll(list.map((e) => e.audioSource).toList());
await _player.seek(Duration.zero, index: list.indexOf(slice.current!)); await _player.seek(Duration.zero, index: list.indexOf(slice.current!));
} }
@@ -410,7 +414,7 @@ class AudioControl extends BaseAudioHandler with QueueHandler, SeekHandler {
final sourceNeedsPrev = sourceIndex == 0; final sourceNeedsPrev = sourceIndex == 0;
if (sourceNeedsNext && slice.next != null) { if (sourceNeedsNext && slice.next != null) {
yell('add'); log.fine('add');
await _audioSource.add(slice.next!.audioSource); await _audioSource.add(slice.next!.audioSource);
} }
if (sourceNeedsPrev && slice.prev != null) { if (sourceNeedsPrev && slice.prev != null) {
@@ -497,7 +501,7 @@ class AudioControl extends BaseAudioHandler with QueueHandler, SeekHandler {
} }
Future<void> _insertFirstAudioSource(AudioSource source) { Future<void> _insertFirstAudioSource(AudioSource source) {
yell('insert'); log.fine('insert');
final wait = _audioSource.insert(0, source); final wait = _audioSource.insert(0, source);
_currentIndexIgnore.add(1); _currentIndexIgnore.add(1);
return wait; return wait;
@@ -505,20 +509,20 @@ class AudioControl extends BaseAudioHandler with QueueHandler, SeekHandler {
Future<void> _pruneAudioSources(int keepIndex) async { Future<void> _pruneAudioSources(int keepIndex) async {
if (keepIndex > 0) { if (keepIndex > 0) {
yell('removeRange 0'); log.fine('removeRange 0');
final wait = _audioSource.removeRange(0, keepIndex); final wait = _audioSource.removeRange(0, keepIndex);
_currentIndexIgnore.add(0); _currentIndexIgnore.add(0);
await wait; await wait;
} }
if (_audioSource.length > 1) { if (_audioSource.length > 1) {
yell('removeRange 1'); log.fine('removeRange 1');
await _audioSource.removeRange(1, _audioSource.length); await _audioSource.removeRange(1, _audioSource.length);
} }
} }
Future<void> _clearAudioSource([bool clearMetadata = false]) async { Future<void> _clearAudioSource([bool clearMetadata = false]) async {
// await _player.stop(); // await _player.stop();
yell('_clearAudioSource'); log.fine('_clearAudioSource');
await _audioSource.clear(); await _audioSource.clear();
if (clearMetadata) { if (clearMetadata) {
@@ -697,11 +701,3 @@ class AudioControl extends BaseAudioHandler with QueueHandler, SeekHandler {
} }
} }
} }
void yell(String msg) {
if (kDebugMode) {
print('=================================================================<');
print(msg);
print('=================================================================>');
}
}

View File

@@ -35,4 +35,5 @@ final audioControlProvider = Provider<AudioControl>.internal(
); );
typedef AudioControlRef = ProviderRef<AudioControl>; typedef AudioControlRef = ProviderRef<AudioControl>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -20,4 +20,5 @@ final cacheServiceProvider = Provider<CacheService>.internal(
); );
typedef CacheServiceRef = ProviderRef<CacheService>; typedef CacheServiceRef = ProviderRef<CacheService>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -534,7 +534,7 @@ class DownloadService extends _$DownloadService {
_port.asyncMap((dynamic data) async { _port.asyncMap((dynamic data) async {
final taskId = (data as List<dynamic>)[0] as String; final taskId = (data as List<dynamic>)[0] as String;
final status = DownloadTaskStatus(data[1] as int); final status = DownloadTaskStatus.fromInt(data[1] as int);
final progress = data[2] as int; final progress = data[2] as int;
var download = state.downloads.firstWhereOrNull( var download = state.downloads.firstWhereOrNull(
@@ -579,11 +579,11 @@ class DownloadService extends _$DownloadService {
@pragma('vm:entry-point') @pragma('vm:entry-point')
static void downloadCallback( static void downloadCallback(
String id, String id,
DownloadTaskStatus status, int status,
int progress, int progress,
) { ) {
IsolateNameServer.lookupPortByName('downloader_send_port')?.send( IsolateNameServer.lookupPortByName('downloader_send_port')?.send(
[id, status.value, progress], [id, status, progress],
); );
} }
} }

View File

@@ -12,7 +12,7 @@ part of 'download_service.dart';
T _$identity<T>(T value) => value; T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError( final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
/// @nodoc /// @nodoc
mixin _$DownloadState { mixin _$DownloadState {
@@ -86,11 +86,11 @@ class _$DownloadStateCopyWithImpl<$Res, $Val extends DownloadState>
} }
/// @nodoc /// @nodoc
abstract class _$$_DownloadStateCopyWith<$Res> abstract class _$$DownloadStateImplCopyWith<$Res>
implements $DownloadStateCopyWith<$Res> { implements $DownloadStateCopyWith<$Res> {
factory _$$_DownloadStateCopyWith( factory _$$DownloadStateImplCopyWith(
_$_DownloadState value, $Res Function(_$_DownloadState) then) = _$DownloadStateImpl value, $Res Function(_$DownloadStateImpl) then) =
__$$_DownloadStateCopyWithImpl<$Res>; __$$DownloadStateImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call( $Res call(
@@ -102,11 +102,11 @@ abstract class _$$_DownloadStateCopyWith<$Res>
} }
/// @nodoc /// @nodoc
class __$$_DownloadStateCopyWithImpl<$Res> class __$$DownloadStateImplCopyWithImpl<$Res>
extends _$DownloadStateCopyWithImpl<$Res, _$_DownloadState> extends _$DownloadStateCopyWithImpl<$Res, _$DownloadStateImpl>
implements _$$_DownloadStateCopyWith<$Res> { implements _$$DownloadStateImplCopyWith<$Res> {
__$$_DownloadStateCopyWithImpl( __$$DownloadStateImplCopyWithImpl(
_$_DownloadState _value, $Res Function(_$_DownloadState) _then) _$DownloadStateImpl _value, $Res Function(_$DownloadStateImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -118,7 +118,7 @@ class __$$_DownloadStateCopyWithImpl<$Res>
Object? listCancels = null, Object? listCancels = null,
Object? saveDir = null, Object? saveDir = null,
}) { }) {
return _then(_$_DownloadState( return _then(_$DownloadStateImpl(
downloads: null == downloads downloads: null == downloads
? _value.downloads ? _value.downloads
: downloads // ignore: cast_nullable_to_non_nullable : downloads // ignore: cast_nullable_to_non_nullable
@@ -145,8 +145,8 @@ class __$$_DownloadStateCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$_DownloadState implements _DownloadState { class _$DownloadStateImpl implements _DownloadState {
const _$_DownloadState( const _$DownloadStateImpl(
{this.downloads = const IListConst([]), {this.downloads = const IListConst([]),
this.deletes = const IListConst([]), this.deletes = const IListConst([]),
this.listDownloads = const IListConst([]), this.listDownloads = const IListConst([]),
@@ -174,10 +174,10 @@ class _$_DownloadState implements _DownloadState {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_DownloadState && other is _$DownloadStateImpl &&
const DeepCollectionEquality().equals(other.downloads, downloads) && const DeepCollectionEquality().equals(other.downloads, downloads) &&
const DeepCollectionEquality().equals(other.deletes, deletes) && const DeepCollectionEquality().equals(other.deletes, deletes) &&
const DeepCollectionEquality() const DeepCollectionEquality()
@@ -199,8 +199,8 @@ class _$_DownloadState implements _DownloadState {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_DownloadStateCopyWith<_$_DownloadState> get copyWith => _$$DownloadStateImplCopyWith<_$DownloadStateImpl> get copyWith =>
__$$_DownloadStateCopyWithImpl<_$_DownloadState>(this, _$identity); __$$DownloadStateImplCopyWithImpl<_$DownloadStateImpl>(this, _$identity);
} }
abstract class _DownloadState implements DownloadState { abstract class _DownloadState implements DownloadState {
@@ -209,7 +209,7 @@ abstract class _DownloadState implements DownloadState {
final IList<SourceId> deletes, final IList<SourceId> deletes,
final IList<SourceId> listDownloads, final IList<SourceId> listDownloads,
final IList<SourceId> listCancels, final IList<SourceId> listCancels,
required final String saveDir}) = _$_DownloadState; required final String saveDir}) = _$DownloadStateImpl;
@override @override
IList<Download> get downloads; IList<Download> get downloads;
@@ -223,7 +223,7 @@ abstract class _DownloadState implements DownloadState {
String get saveDir; String get saveDir;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_DownloadStateCopyWith<_$_DownloadState> get copyWith => _$$DownloadStateImplCopyWith<_$DownloadStateImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
@@ -319,10 +319,11 @@ class _$DownloadCopyWithImpl<$Res, $Val extends Download>
} }
/// @nodoc /// @nodoc
abstract class _$$_DownloadCopyWith<$Res> implements $DownloadCopyWith<$Res> { abstract class _$$DownloadImplCopyWith<$Res>
factory _$$_DownloadCopyWith( implements $DownloadCopyWith<$Res> {
_$_Download value, $Res Function(_$_Download) then) = factory _$$DownloadImplCopyWith(
__$$_DownloadCopyWithImpl<$Res>; _$DownloadImpl value, $Res Function(_$DownloadImpl) then) =
__$$DownloadImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call( $Res call(
@@ -337,11 +338,11 @@ abstract class _$$_DownloadCopyWith<$Res> implements $DownloadCopyWith<$Res> {
} }
/// @nodoc /// @nodoc
class __$$_DownloadCopyWithImpl<$Res> class __$$DownloadImplCopyWithImpl<$Res>
extends _$DownloadCopyWithImpl<$Res, _$_Download> extends _$DownloadCopyWithImpl<$Res, _$DownloadImpl>
implements _$$_DownloadCopyWith<$Res> { implements _$$DownloadImplCopyWith<$Res> {
__$$_DownloadCopyWithImpl( __$$DownloadImplCopyWithImpl(
_$_Download _value, $Res Function(_$_Download) _then) _$DownloadImpl _value, $Res Function(_$DownloadImpl) _then)
: super(_value, _then); : super(_value, _then);
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -356,7 +357,7 @@ class __$$_DownloadCopyWithImpl<$Res>
Object? timeCreated = null, Object? timeCreated = null,
Object? allowCellular = null, Object? allowCellular = null,
}) { }) {
return _then(_$_Download( return _then(_$DownloadImpl(
taskId: null == taskId taskId: null == taskId
? _value.taskId ? _value.taskId
: taskId // ignore: cast_nullable_to_non_nullable : taskId // ignore: cast_nullable_to_non_nullable
@@ -395,8 +396,8 @@ class __$$_DownloadCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$_Download extends _Download { class _$DownloadImpl extends _Download {
const _$_Download( const _$DownloadImpl(
{required this.taskId, {required this.taskId,
required this.status, required this.status,
required this.progress, required this.progress,
@@ -430,10 +431,10 @@ class _$_Download extends _Download {
} }
@override @override
bool operator ==(dynamic other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$_Download && other is _$DownloadImpl &&
(identical(other.taskId, taskId) || other.taskId == taskId) && (identical(other.taskId, taskId) || other.taskId == taskId) &&
(identical(other.status, status) || other.status == status) && (identical(other.status, status) || other.status == status) &&
(identical(other.progress, progress) || (identical(other.progress, progress) ||
@@ -456,8 +457,8 @@ class _$_Download extends _Download {
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$_DownloadCopyWith<_$_Download> get copyWith => _$$DownloadImplCopyWith<_$DownloadImpl> get copyWith =>
__$$_DownloadCopyWithImpl<_$_Download>(this, _$identity); __$$DownloadImplCopyWithImpl<_$DownloadImpl>(this, _$identity);
} }
abstract class _Download extends Download { abstract class _Download extends Download {
@@ -469,7 +470,7 @@ abstract class _Download extends Download {
required final String? filename, required final String? filename,
required final String savedDir, required final String savedDir,
required final int timeCreated, required final int timeCreated,
required final bool allowCellular}) = _$_Download; required final bool allowCellular}) = _$DownloadImpl;
const _Download._() : super._(); const _Download._() : super._();
@override @override
@@ -490,6 +491,6 @@ abstract class _Download extends Download {
bool get allowCellular; bool get allowCellular;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_DownloadCopyWith<_$_Download> get copyWith => _$$DownloadImplCopyWith<_$DownloadImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }

View File

@@ -6,7 +6,7 @@ part of 'download_service.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$downloadServiceHash() => r'c72c49f980e307f3013467e76b6564d14a34a736'; String _$downloadServiceHash() => r'd2aeed2c026de4dc7fa26b2331244b49e7e9f003';
/// See also [DownloadService]. /// See also [DownloadService].
@ProviderFor(DownloadService) @ProviderFor(DownloadService)
@@ -22,4 +22,5 @@ final downloadServiceProvider =
); );
typedef _$DownloadService = Notifier<DownloadState>; typedef _$DownloadService = Notifier<DownloadState>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -46,13 +46,15 @@ class SettingsService extends _$SettingsService {
features: IList(), features: IList(),
username: subsonic.username.value, username: subsonic.username.value,
password: subsonic.password.value, password: subsonic.password.value,
useTokenAuth: true, useTokenAuth: subsonic.useTokenAuth.value,
isActive: true, isActive: true,
createdAt: DateTime.now(), createdAt: DateTime.now(),
), ),
ref.read(httpClientProvider), ref.read(httpClientProvider),
); );
await client.test();
final features = IList([ final features = IList([
if (await client.testFeature(SubsonicFeature.emptyQuerySearch)) if (await client.testFeature(SubsonicFeature.emptyQuerySearch))
SubsonicFeature.emptyQuerySearch, SubsonicFeature.emptyQuerySearch,
@@ -66,6 +68,10 @@ class SettingsService extends _$SettingsService {
} }
Future<void> updateSource(SubsonicSettings source) async { Future<void> updateSource(SubsonicSettings source) async {
final client = SubsonicClient(source, ref.read(httpClientProvider));
await client.test();
await _db.updateSource(source); await _db.updateSource(source);
await init(); await init();
} }

View File

@@ -6,7 +6,7 @@ part of 'settings_service.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$settingsServiceHash() => r'85f2bd5eedc3f791fe03a6707748bc95277c6aaf'; String _$settingsServiceHash() => r'b53814d7d06c5d0a7ac82f447ac510e59a9598f0';
/// See also [SettingsService]. /// See also [SettingsService].
@ProviderFor(SettingsService) @ProviderFor(SettingsService)
@@ -22,4 +22,5 @@ final settingsServiceProvider =
); );
typedef _$SettingsService = Notifier<Settings>; typedef _$SettingsService = Notifier<Settings>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -20,4 +20,5 @@ final syncServiceProvider = NotifierProvider<SyncService, DateTime>.internal(
); );
typedef _$SyncService = Notifier<DateTime>; typedef _$SyncService = Notifier<DateTime>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -1,6 +1,8 @@
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:rxdart/rxdart.dart';
import '../database/database.dart'; import '../database/database.dart';
import '../log.dart';
import '../state/settings.dart'; import '../state/settings.dart';
abstract class BaseMusicSource { abstract class BaseMusicSource {
@@ -40,25 +42,33 @@ class MusicSource implements BaseMusicSource {
@override @override
Stream<Iterable<AlbumsCompanion>> allAlbums() { Stream<Iterable<AlbumsCompanion>> allAlbums() {
_testOnline(); _testOnline();
return _source.allAlbums(); return _source
.allAlbums()
.doOnError((e, st) => log.severe('allAlbums', e, st));
} }
@override @override
Stream<Iterable<ArtistsCompanion>> allArtists() { Stream<Iterable<ArtistsCompanion>> allArtists() {
_testOnline(); _testOnline();
return _source.allArtists(); return _source
.allArtists()
.doOnError((e, st) => log.severe('allArtists', e, st));
} }
@override @override
Stream<Iterable<PlaylistWithSongsCompanion>> allPlaylists() { Stream<Iterable<PlaylistWithSongsCompanion>> allPlaylists() {
_testOnline(); _testOnline();
return _source.allPlaylists(); return _source
.allPlaylists()
.doOnError((e, st) => log.severe('allPlaylists', e, st));
} }
@override @override
Stream<Iterable<SongsCompanion>> allSongs() { Stream<Iterable<SongsCompanion>> allSongs() {
_testOnline(); _testOnline();
return _source.allSongs(); return _source
.allSongs()
.doOnError((e, st) => log.severe('allSongs', e, st));
} }
@override @override

View File

@@ -6,6 +6,7 @@ import 'package:crypto/crypto.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:xml/xml.dart'; import 'package:xml/xml.dart';
import '../../log.dart';
import '../../models/settings.dart'; import '../../models/settings.dart';
import 'xml.dart'; import 'xml.dart';
@@ -89,12 +90,16 @@ class SubsonicClient {
final subsonicResponse = final subsonicResponse =
SubsonicResponse(XmlDocument.parse(utf8.decode(res.bodyBytes))); SubsonicResponse(XmlDocument.parse(utf8.decode(res.bodyBytes)));
if (subsonicResponse.status == Status.failed) { if (subsonicResponse.status == Status.failed) {
throw SubsonicException(subsonicResponse.xml); final error = SubsonicException(subsonicResponse.xml);
log.severe('Subsonic error', error);
throw error;
} }
return subsonicResponse; return subsonicResponse;
} }
Future<void> test() => get('ping');
Future<bool> testFeature(SubsonicFeature feature) async { Future<bool> testFeature(SubsonicFeature feature) async {
switch (feature) { switch (feature) {
case SubsonicFeature.emptyQuerySearch: case SubsonicFeature.emptyQuerySearch:

View File

@@ -144,7 +144,7 @@ class SubsonicSource implements MusicSource {
return Uri.tryParse(res.xml return Uri.tryParse(res.xml
.getElement('artistInfo2') .getElement('artistInfo2')
?.getElement(thumbnail ? 'smallImageUrl' : 'largeImageUrl') ?.getElement(thumbnail ? 'smallImageUrl' : 'largeImageUrl')
?.text ?? ?.value ??
''); '');
} }

View File

@@ -226,4 +226,5 @@ final lastAudioStateServiceProvider =
); );
typedef _$LastAudioStateService = AsyncNotifier<void>; typedef _$LastAudioStateService = AsyncNotifier<void>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -94,4 +94,5 @@ final initProvider = FutureProvider<void>.internal(
); );
typedef InitRef = FutureProviderRef<void>; typedef InitRef = FutureProviderRef<void>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

File diff suppressed because it is too large Load Diff

View File

@@ -76,4 +76,5 @@ final offlineModeProvider = NotifierProvider<OfflineMode, bool>.internal(
); );
typedef _$OfflineMode = Notifier<bool>; typedef _$OfflineMode = Notifier<bool>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -87,7 +87,6 @@ ColorTheme _colorTheme(_ColorThemeRef ref, Palette palette) {
final colorScheme = ColorScheme.fromSeed( final colorScheme = ColorScheme.fromSeed(
brightness: Brightness.dark, brightness: Brightness.dark,
seedColor: background?.color ?? Colors.purple[800]!, seedColor: background?.color ?? Colors.purple[800]!,
background: background?.color,
primaryContainer: primary?.color, primaryContainer: primary?.color,
onPrimaryContainer: primary?.bodyTextColor, onPrimaryContainer: primary?.bodyTextColor,
secondaryContainer: secondary?.color, secondaryContainer: secondary?.color,
@@ -96,8 +95,8 @@ ColorTheme _colorTheme(_ColorThemeRef ref, Palette palette) {
surfaceTint: vibrant?.color, surfaceTint: vibrant?.color,
); );
final hsv = HSVColor.fromColor(colorScheme.background); final hsv = HSVColor.fromColor(colorScheme.surface);
final hsl = HSLColor.fromColor(colorScheme.background); final hsl = HSLColor.fromColor(colorScheme.surface);
return base.copyWith( return base.copyWith(
theme: ThemeData( theme: ThemeData(
@@ -106,7 +105,7 @@ ColorTheme _colorTheme(_ColorThemeRef ref, Palette palette) {
brightness: base.theme.brightness, brightness: base.theme.brightness,
cardTheme: base.theme.cardTheme, cardTheme: base.theme.cardTheme,
), ),
gradientHigh: colorScheme.background, gradientHigh: colorScheme.surface,
darkBackground: hsv.withValue(kDarkBackgroundValue).toColor(), darkBackground: hsv.withValue(kDarkBackgroundValue).toColor(),
darkerBackground: hsl.withLightness(kDarkerBackgroundLightness).toColor(), darkerBackground: hsl.withLightness(kDarkerBackgroundLightness).toColor(),
onDarkerBackground: onDarkerBackground:
@@ -128,13 +127,13 @@ ColorTheme baseTheme(BaseThemeRef ref) {
), ),
); );
final hsv = HSVColor.fromColor(theme.colorScheme.background); final hsv = HSVColor.fromColor(theme.colorScheme.surface);
final hsl = HSLColor.fromColor(theme.colorScheme.background); final hsl = HSLColor.fromColor(theme.colorScheme.surface);
return ColorTheme( return ColorTheme(
theme: theme, theme: theme,
gradientHigh: theme.colorScheme.background, gradientHigh: theme.colorScheme.surface,
gradientLow: HSLColor.fromColor(theme.colorScheme.background) gradientLow: HSLColor.fromColor(theme.colorScheme.surface)
.withLightness(0.06) .withLightness(0.06)
.toColor(), .toColor(),
darkBackground: hsv.withValue(kDarkBackgroundValue).toColor(), darkBackground: hsv.withValue(kDarkBackgroundValue).toColor(),

View File

@@ -6,7 +6,7 @@ part of 'theme.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$colorThemeHash() => r'f5cc23cb5e2af379c02ae4b9756df72f9f6da5e6'; String _$colorThemeHash() => r'37d4eb17395341800b67f4f257c2cc49bf3dc91b';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {
@@ -29,8 +29,6 @@ class _SystemHash {
} }
} }
typedef _ColorThemeRef = AutoDisposeProviderRef<ColorTheme>;
/// See also [_colorTheme]. /// See also [_colorTheme].
@ProviderFor(_colorTheme) @ProviderFor(_colorTheme)
const _colorThemeProvider = _ColorThemeFamily(); const _colorThemeProvider = _ColorThemeFamily();
@@ -77,10 +75,10 @@ class _ColorThemeFamily extends Family<ColorTheme> {
class _ColorThemeProvider extends AutoDisposeProvider<ColorTheme> { class _ColorThemeProvider extends AutoDisposeProvider<ColorTheme> {
/// See also [_colorTheme]. /// See also [_colorTheme].
_ColorThemeProvider( _ColorThemeProvider(
this.palette, Palette palette,
) : super.internal( ) : this._internal(
(ref) => _colorTheme( (ref) => _colorTheme(
ref, ref as _ColorThemeRef,
palette, palette,
), ),
from: _colorThemeProvider, from: _colorThemeProvider,
@@ -92,10 +90,44 @@ class _ColorThemeProvider extends AutoDisposeProvider<ColorTheme> {
dependencies: _ColorThemeFamily._dependencies, dependencies: _ColorThemeFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
_ColorThemeFamily._allTransitiveDependencies, _ColorThemeFamily._allTransitiveDependencies,
palette: palette,
); );
_ColorThemeProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.palette,
}) : super.internal();
final Palette palette; final Palette palette;
@override
Override overrideWith(
ColorTheme Function(_ColorThemeRef provider) create,
) {
return ProviderOverride(
origin: this,
override: _ColorThemeProvider._internal(
(ref) => create(ref as _ColorThemeRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
palette: palette,
),
);
}
@override
AutoDisposeProviderElement<ColorTheme> createElement() {
return _ColorThemeProviderElement(this);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is _ColorThemeProvider && other.palette == palette; return other is _ColorThemeProvider && other.palette == palette;
@@ -110,7 +142,20 @@ class _ColorThemeProvider extends AutoDisposeProvider<ColorTheme> {
} }
} }
String _$baseThemeHash() => r'317a5ef77def208357a54b7938ef3d91666fce70'; mixin _ColorThemeRef on AutoDisposeProviderRef<ColorTheme> {
/// The parameter `palette` of this provider.
Palette get palette;
}
class _ColorThemeProviderElement extends AutoDisposeProviderElement<ColorTheme>
with _ColorThemeRef {
_ColorThemeProviderElement(super.provider);
@override
Palette get palette => (origin as _ColorThemeProvider).palette;
}
String _$baseThemeHash() => r'489ea7dcf66a57e6eda300c75d8af5fcaef85e8e';
/// See also [baseTheme]. /// See also [baseTheme].
@ProviderFor(baseTheme) @ProviderFor(baseTheme)
@@ -125,7 +170,6 @@ final baseThemeProvider = AutoDisposeProvider<ColorTheme>.internal(
typedef BaseThemeRef = AutoDisposeProviderRef<ColorTheme>; typedef BaseThemeRef = AutoDisposeProviderRef<ColorTheme>;
String _$albumArtPaletteHash() => r'8130b954ee3c67f53207593d4ed3dfbffb00c95d'; String _$albumArtPaletteHash() => r'8130b954ee3c67f53207593d4ed3dfbffb00c95d';
typedef AlbumArtPaletteRef = AutoDisposeFutureProviderRef<Palette>;
/// See also [albumArtPalette]. /// See also [albumArtPalette].
@ProviderFor(albumArtPalette) @ProviderFor(albumArtPalette)
@@ -173,10 +217,10 @@ class AlbumArtPaletteFamily extends Family<AsyncValue<Palette>> {
class AlbumArtPaletteProvider extends AutoDisposeFutureProvider<Palette> { class AlbumArtPaletteProvider extends AutoDisposeFutureProvider<Palette> {
/// See also [albumArtPalette]. /// See also [albumArtPalette].
AlbumArtPaletteProvider( AlbumArtPaletteProvider(
this.id, String id,
) : super.internal( ) : this._internal(
(ref) => albumArtPalette( (ref) => albumArtPalette(
ref, ref as AlbumArtPaletteRef,
id, id,
), ),
from: albumArtPaletteProvider, from: albumArtPaletteProvider,
@@ -188,10 +232,44 @@ class AlbumArtPaletteProvider extends AutoDisposeFutureProvider<Palette> {
dependencies: AlbumArtPaletteFamily._dependencies, dependencies: AlbumArtPaletteFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
AlbumArtPaletteFamily._allTransitiveDependencies, AlbumArtPaletteFamily._allTransitiveDependencies,
id: id,
); );
AlbumArtPaletteProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.id,
}) : super.internal();
final String id; final String id;
@override
Override overrideWith(
FutureOr<Palette> Function(AlbumArtPaletteRef provider) create,
) {
return ProviderOverride(
origin: this,
override: AlbumArtPaletteProvider._internal(
(ref) => create(ref as AlbumArtPaletteRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
id: id,
),
);
}
@override
AutoDisposeFutureProviderElement<Palette> createElement() {
return _AlbumArtPaletteProviderElement(this);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is AlbumArtPaletteProvider && other.id == id; return other is AlbumArtPaletteProvider && other.id == id;
@@ -206,9 +284,21 @@ class AlbumArtPaletteProvider extends AutoDisposeFutureProvider<Palette> {
} }
} }
mixin AlbumArtPaletteRef on AutoDisposeFutureProviderRef<Palette> {
/// The parameter `id` of this provider.
String get id;
}
class _AlbumArtPaletteProviderElement
extends AutoDisposeFutureProviderElement<Palette> with AlbumArtPaletteRef {
_AlbumArtPaletteProviderElement(super.provider);
@override
String get id => (origin as AlbumArtPaletteProvider).id;
}
String _$playlistArtPaletteHash() => String _$playlistArtPaletteHash() =>
r'6bc015688f354ea8d91dde86e2a7191ef1ef6496'; r'6bc015688f354ea8d91dde86e2a7191ef1ef6496';
typedef PlaylistArtPaletteRef = AutoDisposeFutureProviderRef<Palette>;
/// See also [playlistArtPalette]. /// See also [playlistArtPalette].
@ProviderFor(playlistArtPalette) @ProviderFor(playlistArtPalette)
@@ -256,10 +346,10 @@ class PlaylistArtPaletteFamily extends Family<AsyncValue<Palette>> {
class PlaylistArtPaletteProvider extends AutoDisposeFutureProvider<Palette> { class PlaylistArtPaletteProvider extends AutoDisposeFutureProvider<Palette> {
/// See also [playlistArtPalette]. /// See also [playlistArtPalette].
PlaylistArtPaletteProvider( PlaylistArtPaletteProvider(
this.id, String id,
) : super.internal( ) : this._internal(
(ref) => playlistArtPalette( (ref) => playlistArtPalette(
ref, ref as PlaylistArtPaletteRef,
id, id,
), ),
from: playlistArtPaletteProvider, from: playlistArtPaletteProvider,
@@ -271,10 +361,44 @@ class PlaylistArtPaletteProvider extends AutoDisposeFutureProvider<Palette> {
dependencies: PlaylistArtPaletteFamily._dependencies, dependencies: PlaylistArtPaletteFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
PlaylistArtPaletteFamily._allTransitiveDependencies, PlaylistArtPaletteFamily._allTransitiveDependencies,
id: id,
); );
PlaylistArtPaletteProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.id,
}) : super.internal();
final String id; final String id;
@override
Override overrideWith(
FutureOr<Palette> Function(PlaylistArtPaletteRef provider) create,
) {
return ProviderOverride(
origin: this,
override: PlaylistArtPaletteProvider._internal(
(ref) => create(ref as PlaylistArtPaletteRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
id: id,
),
);
}
@override
AutoDisposeFutureProviderElement<Palette> createElement() {
return _PlaylistArtPaletteProviderElement(this);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is PlaylistArtPaletteProvider && other.id == id; return other is PlaylistArtPaletteProvider && other.id == id;
@@ -289,6 +413,20 @@ class PlaylistArtPaletteProvider extends AutoDisposeFutureProvider<Palette> {
} }
} }
mixin PlaylistArtPaletteRef on AutoDisposeFutureProviderRef<Palette> {
/// The parameter `id` of this provider.
String get id;
}
class _PlaylistArtPaletteProviderElement
extends AutoDisposeFutureProviderElement<Palette>
with PlaylistArtPaletteRef {
_PlaylistArtPaletteProviderElement(super.provider);
@override
String get id => (origin as PlaylistArtPaletteProvider).id;
}
String _$mediaItemPaletteHash() => r'2f2744aa735c6056919197c283a367714d7e04e4'; String _$mediaItemPaletteHash() => r'2f2744aa735c6056919197c283a367714d7e04e4';
/// See also [mediaItemPalette]. /// See also [mediaItemPalette].
@@ -320,7 +458,6 @@ final mediaItemThemeProvider = AutoDisposeFutureProvider<ColorTheme>.internal(
typedef MediaItemThemeRef = AutoDisposeFutureProviderRef<ColorTheme>; typedef MediaItemThemeRef = AutoDisposeFutureProviderRef<ColorTheme>;
String _$albumArtThemeHash() => r'd3ee71b2df856f1763ec925e158ae2e0f613b9e0'; String _$albumArtThemeHash() => r'd3ee71b2df856f1763ec925e158ae2e0f613b9e0';
typedef AlbumArtThemeRef = AutoDisposeFutureProviderRef<ColorTheme>;
/// See also [albumArtTheme]. /// See also [albumArtTheme].
@ProviderFor(albumArtTheme) @ProviderFor(albumArtTheme)
@@ -368,10 +505,10 @@ class AlbumArtThemeFamily extends Family<AsyncValue<ColorTheme>> {
class AlbumArtThemeProvider extends AutoDisposeFutureProvider<ColorTheme> { class AlbumArtThemeProvider extends AutoDisposeFutureProvider<ColorTheme> {
/// See also [albumArtTheme]. /// See also [albumArtTheme].
AlbumArtThemeProvider( AlbumArtThemeProvider(
this.id, String id,
) : super.internal( ) : this._internal(
(ref) => albumArtTheme( (ref) => albumArtTheme(
ref, ref as AlbumArtThemeRef,
id, id,
), ),
from: albumArtThemeProvider, from: albumArtThemeProvider,
@@ -383,10 +520,44 @@ class AlbumArtThemeProvider extends AutoDisposeFutureProvider<ColorTheme> {
dependencies: AlbumArtThemeFamily._dependencies, dependencies: AlbumArtThemeFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
AlbumArtThemeFamily._allTransitiveDependencies, AlbumArtThemeFamily._allTransitiveDependencies,
id: id,
); );
AlbumArtThemeProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.id,
}) : super.internal();
final String id; final String id;
@override
Override overrideWith(
FutureOr<ColorTheme> Function(AlbumArtThemeRef provider) create,
) {
return ProviderOverride(
origin: this,
override: AlbumArtThemeProvider._internal(
(ref) => create(ref as AlbumArtThemeRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
id: id,
),
);
}
@override
AutoDisposeFutureProviderElement<ColorTheme> createElement() {
return _AlbumArtThemeProviderElement(this);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is AlbumArtThemeProvider && other.id == id; return other is AlbumArtThemeProvider && other.id == id;
@@ -401,8 +572,20 @@ class AlbumArtThemeProvider extends AutoDisposeFutureProvider<ColorTheme> {
} }
} }
mixin AlbumArtThemeRef on AutoDisposeFutureProviderRef<ColorTheme> {
/// The parameter `id` of this provider.
String get id;
}
class _AlbumArtThemeProviderElement
extends AutoDisposeFutureProviderElement<ColorTheme> with AlbumArtThemeRef {
_AlbumArtThemeProviderElement(super.provider);
@override
String get id => (origin as AlbumArtThemeProvider).id;
}
String _$playlistArtThemeHash() => r'1629552e1f3aa2a1e7d223ac1e078893042e5e3b'; String _$playlistArtThemeHash() => r'1629552e1f3aa2a1e7d223ac1e078893042e5e3b';
typedef PlaylistArtThemeRef = AutoDisposeFutureProviderRef<ColorTheme>;
/// See also [playlistArtTheme]. /// See also [playlistArtTheme].
@ProviderFor(playlistArtTheme) @ProviderFor(playlistArtTheme)
@@ -450,10 +633,10 @@ class PlaylistArtThemeFamily extends Family<AsyncValue<ColorTheme>> {
class PlaylistArtThemeProvider extends AutoDisposeFutureProvider<ColorTheme> { class PlaylistArtThemeProvider extends AutoDisposeFutureProvider<ColorTheme> {
/// See also [playlistArtTheme]. /// See also [playlistArtTheme].
PlaylistArtThemeProvider( PlaylistArtThemeProvider(
this.id, String id,
) : super.internal( ) : this._internal(
(ref) => playlistArtTheme( (ref) => playlistArtTheme(
ref, ref as PlaylistArtThemeRef,
id, id,
), ),
from: playlistArtThemeProvider, from: playlistArtThemeProvider,
@@ -465,10 +648,44 @@ class PlaylistArtThemeProvider extends AutoDisposeFutureProvider<ColorTheme> {
dependencies: PlaylistArtThemeFamily._dependencies, dependencies: PlaylistArtThemeFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
PlaylistArtThemeFamily._allTransitiveDependencies, PlaylistArtThemeFamily._allTransitiveDependencies,
id: id,
); );
PlaylistArtThemeProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.id,
}) : super.internal();
final String id; final String id;
@override
Override overrideWith(
FutureOr<ColorTheme> Function(PlaylistArtThemeRef provider) create,
) {
return ProviderOverride(
origin: this,
override: PlaylistArtThemeProvider._internal(
(ref) => create(ref as PlaylistArtThemeRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
id: id,
),
);
}
@override
AutoDisposeFutureProviderElement<ColorTheme> createElement() {
return _PlaylistArtThemeProviderElement(this);
}
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is PlaylistArtThemeProvider && other.id == id; return other is PlaylistArtThemeProvider && other.id == id;
@@ -482,4 +699,19 @@ class PlaylistArtThemeProvider extends AutoDisposeFutureProvider<ColorTheme> {
return _SystemHash.finish(hash); return _SystemHash.finish(hash);
} }
} }
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
mixin PlaylistArtThemeRef on AutoDisposeFutureProviderRef<ColorTheme> {
/// The parameter `id` of this provider.
String get id;
}
class _PlaylistArtThemeProviderElement
extends AutoDisposeFutureProviderElement<ColorTheme>
with PlaylistArtThemeRef {
_PlaylistArtThemeProviderElement(super.provider);
@override
String get id => (origin as PlaylistArtThemeProvider).id;
}
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,10 @@ homepage: https://github.com/austinried/subtracks
repository: https://github.com/austinried/subtracks repository: https://github.com/austinried/subtracks
issue_tracker: https://github.com/austinried/subtracks/issues issue_tracker: https://github.com/austinried/subtracks/issues
publish_to: 'none' publish_to: 'none'
version: 2.0.0-alpha.2+11 version: 2.0.0-alpha.3+12
environment: environment:
sdk: '>=2.19.2 <3.0.0' sdk: '>=3.5.0 <4.0.0'
dependencies: dependencies:
flutter: flutter:
@@ -22,7 +22,7 @@ dependencies:
path: ^1.8.2 path: ^1.8.2
path_provider: ^2.0.12 path_provider: ^2.0.12
flutter_dotenv: ^5.0.2 # TODO: remove before release flutter_dotenv: ^5.0.2 # TODO: remove before release
collection: ^1.17.0 collection: ^1.17.1
intl: any intl: any
flutter_hooks: ^0.18.5+1 flutter_hooks: ^0.18.5+1
hooks_riverpod: ^2.3.2 hooks_riverpod: ^2.3.2
@@ -55,18 +55,17 @@ dependencies:
synchronized: ^3.1.0 synchronized: ^3.1.0
flutter_keyboard_visibility: ^5.4.0 flutter_keyboard_visibility: ^5.4.0
connectivity_plus: ^3.0.4 connectivity_plus: ^3.0.4
package_info_plus: ^3.1.1 package_info_plus: ^8.1.1
url_launcher: ^6.1.10 url_launcher: ^6.1.10
logging: ^1.1.1
share_plus: ^7.0.0
# https://github.com/dart-lang/intl/issues/522#issuecomment-1469961807 # https://github.com/dart-lang/intl/issues/522#issuecomment-1469961807
dependency_overrides: dependency_overrides:
intl: ^0.18.0 intl: ^0.18.0
dev_dependencies: dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0 flutter_lints: ^2.0.0
test: ^1.22.0
build_runner: build_runner:
riverpod_generator: ^2.1.4 riverpod_generator: ^2.1.4
freezed: ^2.3.2 freezed: ^2.3.2