Compare commits

...

3 Commits

Author SHA1 Message Date
Bart Ribbers
4a3379a046
Merge 10280a99038a22cd69a9bef73747ebe767b18070 into b0bb26f84b66d9970d9d86e66b4696ae7d994eb0 2024-12-10 21:54:34 +01:00
Bart Ribbers
10280a9903 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 21:52:56 +01:00
Bart Ribbers
686e0a2dba chore: upgrade to Flutter 3.24.5
At the time of writing the latest Flutter version.
2024-12-10 21:30:53 +01:00
26 changed files with 456 additions and 425 deletions

2
.fvmrc
View File

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

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 localPropertiesFile = rootProject.file('local.properties')
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')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
@ -21,10 +22,6 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
@ -53,7 +50,7 @@ android {
applicationId "com.subtracks2"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 19
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
@ -81,8 +78,4 @@ android {
flutter {
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 {
repositories {
google()
@ -26,6 +13,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
tasks.register("clean", Delete) {
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")
def properties = new Properties()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
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
Widget build(BuildContext context) {
final theme = Theme.of(context);
return FloatingActionButton(
heroTag: null,
onPressed: onPressed,
@ -44,7 +46,7 @@ class RadioPlayFab extends StatelessWidget {
right: -10,
child: Icon(
Icons.play_arrow_rounded,
color: Theme.of(context).colorScheme.primaryContainer,
color: theme.colorScheme.primaryContainer,
size: 26,
),
),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -72,6 +72,8 @@ class PagedGridQueryView<T> extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final mediaQuery = MediaQuery.of(context);
SliverGridDelegate gridDelegate;
double spacing;
@ -92,7 +94,7 @@ class PagedGridQueryView<T> extends HookConsumerWidget {
}
final listView = PagedGridView<int, T>(
padding: MediaQuery.of(context).padding + EdgeInsets.all(spacing),
padding: mediaQuery.padding + EdgeInsets.all(spacing),
pagingController: pagingController,
builderDelegate: PagedChildBuilderDelegate(
itemBuilder: (context, item, index) =>
@ -127,6 +129,7 @@ class SyncAllRefresh extends HookConsumerWidget {
try {
await ref.read(syncServiceProvider.notifier).syncAll();
} catch (e) {
if (!context.mounted) return;
showErrorSnackbar(context, e.toString());
}
},

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -131,11 +131,11 @@ class _SectionHeader extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context).textTheme;
final theme = Theme.of(context);
return Padding(
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();
if (files.isEmpty) return;
// ignore: use_build_context_synchronously
if (!context.mounted) return;
final value = await showDialog<String>(
context: context,
builder: (context) => MultipleChoiceDialog<String>(

View File

@ -76,8 +76,8 @@ class SourcePage extends HookConsumerWidget {
onChanged: (value) => forcePlaintextPassword.value = value,
);
return WillPopScope(
onWillPop: () async => !isSaving.value && !isDeleting.value,
return PopScope(
canPop: !isSaving.value && !isDeleting.value,
child: Scaffold(
appBar: AppBar(),
floatingActionButton: Row(
@ -164,6 +164,7 @@ class SourcePage extends HookConsumerWidget {
);
}
} catch (e, st) {
if (!context.mounted) return;
showErrorSnackbar(context, e.toString());
log.severe('Saving source', e, st);
error = true;

View File

@ -534,7 +534,7 @@ class DownloadService extends _$DownloadService {
_port.asyncMap((dynamic data) async {
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;
var download = state.downloads.firstWhereOrNull(
@ -579,11 +579,11 @@ class DownloadService extends _$DownloadService {
@pragma('vm:entry-point')
static void downloadCallback(
String id,
DownloadTaskStatus status,
int status,
int progress,
) {
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
.getElement('artistInfo2')
?.getElement(thumbnail ? 'smallImageUrl' : 'largeImageUrl')
?.text ??
?.value ??
'');
}

View File

@ -87,7 +87,6 @@ ColorTheme _colorTheme(_ColorThemeRef ref, Palette palette) {
final colorScheme = ColorScheme.fromSeed(
brightness: Brightness.dark,
seedColor: background?.color ?? Colors.purple[800]!,
background: background?.color,
primaryContainer: primary?.color,
onPrimaryContainer: primary?.bodyTextColor,
secondaryContainer: secondary?.color,
@ -96,8 +95,8 @@ ColorTheme _colorTheme(_ColorThemeRef ref, Palette palette) {
surfaceTint: vibrant?.color,
);
final hsv = HSVColor.fromColor(colorScheme.background);
final hsl = HSLColor.fromColor(colorScheme.background);
final hsv = HSVColor.fromColor(colorScheme.surface);
final hsl = HSLColor.fromColor(colorScheme.surface);
return base.copyWith(
theme: ThemeData(
@ -106,7 +105,7 @@ ColorTheme _colorTheme(_ColorThemeRef ref, Palette palette) {
brightness: base.theme.brightness,
cardTheme: base.theme.cardTheme,
),
gradientHigh: colorScheme.background,
gradientHigh: colorScheme.surface,
darkBackground: hsv.withValue(kDarkBackgroundValue).toColor(),
darkerBackground: hsl.withLightness(kDarkerBackgroundLightness).toColor(),
onDarkerBackground:
@ -128,13 +127,13 @@ ColorTheme baseTheme(BaseThemeRef ref) {
),
);
final hsv = HSVColor.fromColor(theme.colorScheme.background);
final hsl = HSLColor.fromColor(theme.colorScheme.background);
final hsv = HSVColor.fromColor(theme.colorScheme.surface);
final hsl = HSLColor.fromColor(theme.colorScheme.surface);
return ColorTheme(
theme: theme,
gradientHigh: theme.colorScheme.background,
gradientLow: HSLColor.fromColor(theme.colorScheme.background)
gradientHigh: theme.colorScheme.surface,
gradientLow: HSLColor.fromColor(theme.colorScheme.surface)
.withLightness(0.06)
.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
environment:
sdk: '>=2.19.2 <3.0.0'
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
@ -55,7 +55,7 @@ dependencies:
synchronized: ^3.1.0
flutter_keyboard_visibility: ^5.4.0
connectivity_plus: ^3.0.4
package_info_plus: ^3.1.1
package_info_plus: ^8.1.1
url_launcher: ^6.1.10
logging: ^1.1.1
share_plus: ^7.0.0