fix: ios dialog action buttons, local tracks crashing app, shimmer color and android wrong status bar color

This commit is contained in:
Kingkor Roy Tirtho 2022-12-09 15:46:51 +06:00
parent 359fcee98c
commit 90c1200a08
17 changed files with 326 additions and 135 deletions

View File

@ -242,7 +242,8 @@ class UserLocalTracks extends HookConsumerWidget {
),
);
},
loading: () => const ShimmerTrackTile(noSliver: true),
loading: () =>
const Expanded(child: ShimmerTrackTile(noSliver: true)),
error: (error, stackTrace) =>
Text(error.toString() + stackTrace.toString()),
)

View File

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
@ -21,25 +22,57 @@ class LyricDelayAdjustDialog extends HookConsumerWidget {
macosAppIcon: Sidebar.brandLogo(),
title: const Center(child: Text("Adjust Lyrics Delay")),
secondaryActions: [
PlatformFilledButton(
isSecondary: true,
onPressed: () {
Navigator.of(context).pop();
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, _) {
return PlatformFilledButton(
isSecondary: true,
child: const Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
);
},
ios: (context, data) {
return CupertinoDialogAction(
onPressed: () {
Navigator.pop(context);
},
isDestructiveAction: true,
child: const Text("Cancel"),
);
},
child: const Text("Cancel"),
),
],
primaryActions: [
PlatformFilledButton(
child: const Text("Done"),
onPressed: () {
Navigator.of(context).pop(
Duration(
milliseconds: getValue().toInt(),
),
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, _) {
return PlatformFilledButton(
child: const Text("Done"),
onPressed: () {
Navigator.of(context).pop(
Duration(
milliseconds: getValue().toInt(),
),
);
},
);
},
)
ios: (context, data) {
return CupertinoDialogAction(
onPressed: () {
Navigator.of(context).pop(
Duration(
milliseconds: getValue().toInt(),
),
);
},
isDefaultAction: true,
child: const Text("Done"),
);
},
),
],
content: SizedBox(
height: 100,

View File

@ -1,4 +1,5 @@
import 'package:fl_query/fl_query.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
@ -25,36 +26,66 @@ class PlaylistCreateDialog extends HookConsumerWidget {
final public = useState(false);
final collaborative = useState(false);
onCreate() async {
if (playlistName.text.isEmpty) return;
final me = await spotify.me.get();
await spotify.playlists.createPlaylist(
me.id!,
playlistName.text,
collaborative: collaborative.value,
public: public.value,
description: description.text,
);
await QueryBowl.of(context)
.getQuery(
Queries.playlist.ofMine.queryKey,
)
?.refetch();
Navigator.pop(context);
}
return PlatformAlertDialog(
macosAppIcon: Sidebar.brandLogo(),
title: const Text("Create a Playlist"),
primaryActions: [
PlatformFilledButton(
child: const Text("Create"),
onPressed: () async {
if (playlistName.text.isEmpty) return;
final me = await spotify.me.get();
await spotify.playlists.createPlaylist(
me.id!,
playlistName.text,
collaborative: collaborative.value,
public: public.value,
description: description.text,
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, _) {
return PlatformFilledButton(
onPressed: onCreate,
child: const Text("Create"),
);
await QueryBowl.of(context)
.getQuery(
Queries.playlist.ofMine.queryKey,
)
?.refetch();
Navigator.pop(context);
},
)
ios: (context, data) {
return CupertinoDialogAction(
isDefaultAction: true,
onPressed: onCreate,
child: const Text("Create"),
);
},
),
],
secondaryActions: [
PlatformFilledButton(
isSecondary: true,
onPressed: () => Navigator.of(context).pop(),
child: const Text("Cancel"),
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, _) {
return PlatformFilledButton(
isSecondary: true,
child: const Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
);
},
ios: (context, data) {
return CupertinoDialogAction(
onPressed: () {
Navigator.pop(context);
},
isDestructiveAction: true,
child: const Text("Cancel"),
);
},
),
],
content: Container(

View File

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
@ -67,32 +68,60 @@ class ColorSchemePickerDialog extends HookConsumerWidget {
},
).key);
onOk() {
switch (schemeType) {
case ColorSchemeType.accent:
preferences.setAccentColorScheme(colorsMap[active.value]!);
break;
default:
preferences.setBackgroundColorScheme(
colorsMap[active.value]!,
);
}
Navigator.pop(context);
}
return PlatformAlertDialog(
macosAppIcon: Sidebar.brandLogo(),
title: Text("Pick ${schemeType.name} color scheme"),
primaryActions: [
PlatformFilledButton(
child: const Text("Save"),
onPressed: () {
switch (schemeType) {
case ColorSchemeType.accent:
preferences.setAccentColorScheme(colorsMap[active.value]!);
break;
default:
preferences.setBackgroundColorScheme(
colorsMap[active.value]!,
);
}
Navigator.pop(context);
PlatformBuilder(
android: (context, data) {
return PlatformFilledButton(
onPressed: onOk,
child: const Text("Save"),
);
},
)
ios: (context, data) {
return CupertinoDialogAction(
onPressed: onOk,
isDefaultAction: true,
child: const Text("Save"),
);
},
fallback: PlatformBuilderFallback.android,
),
],
secondaryActions: [
PlatformFilledButton(
isSecondary: true,
child: const Text("Cancel"),
onPressed: () {
Navigator.pop(context);
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, _) {
return PlatformFilledButton(
isSecondary: true,
child: const Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
);
},
ios: (context, data) {
return CupertinoDialogAction(
onPressed: () {
Navigator.pop(context);
},
isDestructiveAction: true,
child: const Text("Cancel"),
);
},
),
],

View File

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:spotube/components/shared/image/universal_image.dart';
@ -62,20 +63,46 @@ class ConfirmDownloadDialog extends StatelessWidget {
),
),
primaryActions: [
PlatformFilledButton(
style: const ButtonStyle(
foregroundColor: MaterialStatePropertyAll(Colors.white),
backgroundColor: MaterialStatePropertyAll(Colors.red),
),
onPressed: () => Navigator.of(context).pop(true),
child: const Text("Accept"),
PlatformBuilder(
android: (context, _) {
return PlatformFilledButton(
style: const ButtonStyle(
foregroundColor: MaterialStatePropertyAll(Colors.white),
backgroundColor: MaterialStatePropertyAll(Colors.red),
),
onPressed: () => Navigator.of(context).pop(true),
child: const Text("Accept"),
);
},
ios: (context, data) {
return CupertinoDialogAction(
onPressed: () => Navigator.of(context).pop(true),
isDestructiveAction: true,
child: const Text("Accept"),
);
},
)
],
secondaryActions: [
PlatformFilledButton(
isSecondary: true,
child: const Text("Decline"),
onPressed: () => Navigator.of(context).pop(false),
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, _) {
return PlatformFilledButton(
child: const Text("Decline"),
onPressed: () {
Navigator.pop(context, false);
},
);
},
ios: (context, data) {
return CupertinoDialogAction(
onPressed: () {
Navigator.pop(context, false);
},
isDefaultAction: true,
child: const Text("Decline"),
);
},
),
],
);

View File

@ -1,4 +1,5 @@
import 'package:fl_query_hooks/fl_query_hooks.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
@ -31,36 +32,66 @@ class PlaylistAddTrackDialog extends HookConsumerWidget {
);
final playlistsCheck = useState(<String, bool>{});
Future<void> onAdd() async {
final selectedPlaylists = playlistsCheck.value.entries
.where((entry) => entry.value)
.map((entry) => entry.key);
await Future.wait(
selectedPlaylists.map(
(playlistId) => spotify.playlists.addTracks(
tracks
.map(
(track) => track.uri!,
)
.toList(),
playlistId),
),
).then((_) => Navigator.pop(context));
}
return PlatformAlertDialog(
title: const PlatformText("Add to Playlist"),
secondaryActions: [
PlatformFilledButton(
isSecondary: true,
child: const PlatformText("Cancel"),
onPressed: () => Navigator.pop(context),
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, _) {
return PlatformFilledButton(
isSecondary: true,
child: const Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
);
},
ios: (context, data) {
return CupertinoDialogAction(
onPressed: () {
Navigator.pop(context);
},
isDestructiveAction: true,
child: const Text("Cancel"),
);
},
),
],
primaryActions: [
PlatformFilledButton(
child: const PlatformText("Add"),
onPressed: () async {
final selectedPlaylists = playlistsCheck.value.entries
.where((entry) => entry.value)
.map((entry) => entry.key);
await Future.wait(
selectedPlaylists.map(
(playlistId) => spotify.playlists.addTracks(
tracks
.map(
(track) => track.uri!,
)
.toList(),
playlistId),
),
).then((_) => Navigator.pop(context));
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, _) {
return PlatformFilledButton(
onPressed: onAdd,
child: const Text("Add"),
);
},
)
ios: (context, data) {
return CupertinoDialogAction(
isDefaultAction: true,
onPressed: onAdd,
child: const Text("Add"),
);
},
),
],
content: SizedBox(
height: 300,

View File

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:platform_ui/platform_ui.dart';
@ -51,19 +52,47 @@ class ReplaceDownloadedDialog extends ConsumerWidget {
],
),
primaryActions: [
PlatformFilledButton(
child: const Text("Yes"),
onPressed: () {
Navigator.pop(context, true);
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, _) {
return PlatformFilledButton(
child: const Text("Yes"),
onPressed: () {
Navigator.pop(context, true);
},
);
},
)
ios: (context, data) {
return CupertinoDialogAction(
onPressed: () {
Navigator.pop(context, true);
},
isDefaultAction: true,
child: const Text("Yes"),
);
},
),
],
secondaryActions: [
PlatformFilledButton(
isSecondary: true,
child: const Text("No"),
onPressed: () {
Navigator.pop(context, false);
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, _) {
return PlatformFilledButton(
isSecondary: true,
child: const Text("No"),
onPressed: () {
Navigator.pop(context, false);
},
);
},
ios: (context, data) {
return CupertinoDialogAction(
onPressed: () {
Navigator.pop(context, false);
},
isDestructiveAction: true,
child: const Text("No"),
);
},
),
],

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:skeleton_text/skeleton_text.dart';
import 'package:spotube/components/shared/shimmers/shimmer_track_tile.dart';
import 'package:spotube/extensions/theme.dart';
@ -10,12 +11,14 @@ class ShimmerArtistProfile extends HookWidget {
@override
Widget build(BuildContext context) {
final shimmerColor =
Theme.of(context).extension<ShimmerColorTheme>()?.shimmerColor ??
Colors.white;
final shimmerBackgroundColor = Theme.of(context)
.extension<ShimmerColorTheme>()
?.shimmerBackgroundColor;
final isDark = PlatformTheme.of(context).brightness == Brightness.dark;
final shimmerTheme = ShimmerColorTheme(
shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200],
shimmerColor: isDark ? Colors.grey[800] : Colors.grey[300],
);
final shimmerColor = shimmerTheme.shimmerColor ?? Colors.white;
final shimmerBackgroundColor =
shimmerTheme.shimmerBackgroundColor ?? Colors.grey;
final avatarWidth = useBreakpointValue(
sm: MediaQuery.of(context).size.width * 0.80,

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:spotube/components/shared/shimmers/shimmer_playbutton_card.dart';
import 'package:spotube/extensions/theme.dart';
@ -7,13 +8,12 @@ class ShimmerCategories extends StatelessWidget {
@override
Widget build(BuildContext context) {
final shimmerColor =
Theme.of(context).extension<ShimmerColorTheme>()?.shimmerColor ??
Colors.white;
final shimmerBackgroundColor = Theme.of(context)
.extension<ShimmerColorTheme>()
?.shimmerBackgroundColor ??
Colors.grey;
final isDark = PlatformTheme.of(context).brightness == Brightness.dark;
final shimmerTheme = ShimmerColorTheme(
shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200],
);
final shimmerBackgroundColor =
shimmerTheme.shimmerBackgroundColor ?? Colors.grey;
return Padding(
padding: const EdgeInsets.all(8.0),

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:skeleton_text/skeleton_text.dart';
import 'package:spotube/extensions/theme.dart';
import 'package:spotube/hooks/use_breakpoints.dart';
@ -11,13 +12,14 @@ class ShimmerLyrics extends HookWidget {
@override
Widget build(BuildContext context) {
final shimmerColor =
Theme.of(context).extension<ShimmerColorTheme>()?.shimmerColor ??
Colors.white;
final shimmerBackgroundColor = Theme.of(context)
.extension<ShimmerColorTheme>()
?.shimmerBackgroundColor ??
Colors.grey;
final isDark = PlatformTheme.of(context).brightness == Brightness.dark;
final shimmerTheme = ShimmerColorTheme(
shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200],
shimmerColor: isDark ? Colors.grey[800] : Colors.grey[300],
);
final shimmerColor = shimmerTheme.shimmerColor ?? Colors.white;
final shimmerBackgroundColor =
shimmerTheme.shimmerBackgroundColor ?? Colors.grey;
final breakpoint = useBreakpoints();

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:spotube/extensions/theme.dart';
class ShimmerPlaybuttonCardPainter extends CustomPainter {
@ -52,7 +53,11 @@ class ShimmerPlaybuttonCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final shimmerTheme = Theme.of(context).extension<ShimmerColorTheme>();
final isDark = PlatformTheme.of(context).brightness == Brightness.dark;
final shimmerTheme = ShimmerColorTheme(
shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200],
shimmerColor: isDark ? Colors.grey[800] : Colors.grey[300],
);
return Row(
mainAxisSize: MainAxisSize.min,
@ -61,10 +66,10 @@ class ShimmerPlaybuttonCard extends StatelessWidget {
CustomPaint(
size: const Size(200, 250),
painter: ShimmerPlaybuttonCardPainter(
background: shimmerTheme?.shimmerBackgroundColor ??
background: shimmerTheme.shimmerBackgroundColor ??
Theme.of(context).scaffoldBackgroundColor,
foreground:
shimmerTheme?.shimmerColor ?? Theme.of(context).cardColor,
shimmerTheme.shimmerColor ?? Theme.of(context).cardColor,
),
),
const SizedBox(width: 10),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:spotube/extensions/theme.dart';
class ShimmerTrackTilePainter extends CustomPainter {
@ -66,7 +67,11 @@ class ShimmerTrackTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
final shimmerTheme = Theme.of(context).extension<ShimmerColorTheme>();
final isDark = PlatformTheme.of(context).brightness == Brightness.dark;
final shimmerTheme = ShimmerColorTheme(
shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200],
shimmerColor: isDark ? Colors.grey[800] : Colors.grey[300],
);
if (noSliver) {
return ListView.builder(
@ -77,10 +82,10 @@ class ShimmerTrackTile extends StatelessWidget {
child: CustomPaint(
size: const Size(double.infinity, 50),
painter: ShimmerTrackTilePainter(
background: shimmerTheme?.shimmerBackgroundColor ??
background: shimmerTheme.shimmerBackgroundColor ??
Theme.of(context).scaffoldBackgroundColor,
foreground:
shimmerTheme?.shimmerColor ?? Theme.of(context).cardColor,
shimmerTheme.shimmerColor ?? Theme.of(context).cardColor,
),
),
);

View File

@ -98,7 +98,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
final collapsed = useState(false);
useCustomStatusBarColor(
color?.color ?? Theme.of(context).backgroundColor,
color?.color ?? PlatformTheme.of(context).scaffoldBackgroundColor!,
GoRouter.of(context).location == routePath,
);

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:platform_ui/platform_ui.dart';
void useCustomStatusBarColor(
Color color,
@ -8,7 +9,7 @@ void useCustomStatusBarColor(
bool noSetBGColor = false,
}) {
final context = useContext();
final backgroundColor = Theme.of(context).backgroundColor;
final backgroundColor = PlatformTheme.of(context).scaffoldBackgroundColor!;
resetStatusbar() => SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
statusBarColor: backgroundColor, // status bar color

View File

@ -89,7 +89,7 @@ class PlayerView extends HookConsumerWidget {
textStyle: PlatformTheme.of(context).textTheme!.body!,
color: paletteColor.color.withOpacity(.5),
child: SafeArea(
child: ListView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(10),

View File

@ -51,7 +51,7 @@ class RootApp extends HookConsumerWidget {
// checks for latest version of the application
useUpdateChecker(ref);
final backgroundColor = Theme.of(context).backgroundColor;
final backgroundColor = PlatformTheme.of(context).scaffoldBackgroundColor!;
useEffect(() {
SystemChrome.setSystemUIOverlayStyle(

View File

@ -126,9 +126,6 @@ final windowsTheme = fluent_ui.ThemeData.light().copyWith(
iconSize: fluent_ui.ButtonState.all(20),
),
),
navigationPaneTheme: fluent_ui.NavigationPaneThemeData(
backgroundColor: Colors.grey[100]?.withOpacity(0.5),
),
);
final windowsDarkTheme = fluent_ui.ThemeData.dark().copyWith(
buttonTheme: fluent_ui.ButtonThemeData(
@ -136,9 +133,6 @@ final windowsDarkTheme = fluent_ui.ThemeData.dark().copyWith(
iconSize: fluent_ui.ButtonState.all(20),
),
),
navigationPaneTheme: fluent_ui.NavigationPaneThemeData(
backgroundColor: Colors.grey[900]?.withOpacity(0.5),
),
);
final macosTheme = MacosThemeData.light().copyWith(
pushButtonTheme: const PushButtonThemeData(