Merge 10280a99038a22cd69a9bef73747ebe767b18070 into b0bb26f84b66d9970d9d86e66b4696ae7d994eb0

This commit is contained in:
Bart Ribbers 2024-12-10 21:54:34 +01:00 committed by GitHub
commit 4a3379a046
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 462 additions and 433 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

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

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

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

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

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

@ -72,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;
@ -92,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) =>
@ -127,6 +129,7 @@ class SyncAllRefresh extends HookConsumerWidget {
try { try {
await ref.read(syncServiceProvider.notifier).syncAll(); await ref.read(syncServiceProvider.notifier).syncAll();
} catch (e) { } catch (e) {
if (!context.mounted) return;
showErrorSnackbar(context, e.toString()); showErrorSnackbar(context, e.toString());
} }
}, },

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

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

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

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

@ -191,7 +191,7 @@ class _ShareLogsButton extends StatelessWidget {
final files = await logFiles(); final files = await logFiles();
if (files.isEmpty) return; if (files.isEmpty) return;
// ignore: use_build_context_synchronously if (!context.mounted) return;
final value = await showDialog<String>( final value = await showDialog<String>(
context: context, context: context,
builder: (context) => MultipleChoiceDialog<String>( builder: (context) => MultipleChoiceDialog<String>(

View File

@ -76,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(
@ -164,6 +164,7 @@ class SourcePage extends HookConsumerWidget {
); );
} }
} catch (e, st) { } catch (e, st) {
if (!context.mounted) return;
showErrorSnackbar(context, e.toString()); showErrorSnackbar(context, e.toString());
log.severe('Saving source', e, st); log.severe('Saving source', e, st);
error = true; error = true;

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

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

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

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ publish_to: 'none'
version: 2.0.0-alpha.3+12 version: 2.0.0-alpha.3+12
environment: environment:
sdk: '>=2.19.2 <3.0.0' sdk: '>=3.0.0 <4.0.0'
dependencies: dependencies:
flutter: flutter:
@ -55,7 +55,7 @@ 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 logging: ^1.1.1
share_plus: ^7.0.0 share_plus: ^7.0.0