mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
floating mini player works flawlessly
Custom bg-color for floating player for each title track album art go_true routing integrated floating player now disappears if not on home
This commit is contained in:
parent
d608fa7d02
commit
aaf74b46d4
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/components/Album/AlbumView.dart';
|
||||
@ -32,12 +33,7 @@ class AlbumCard extends HookConsumerWidget {
|
||||
description:
|
||||
"Album • ${artistsToString<ArtistSimple>(album.artists ?? [])}",
|
||||
onTap: () {
|
||||
Navigator.of(context).push(SpotubePageRoute(
|
||||
child: AlbumView(
|
||||
album,
|
||||
key: Key("album-${album.id}"),
|
||||
),
|
||||
));
|
||||
GoRouter.of(context).push("/album/${album.id}", extra: album);
|
||||
},
|
||||
onPlaybuttonPressed: () async {
|
||||
SpotifyApi spotify = ref.read(spotifyProvider);
|
||||
|
@ -1,8 +1,7 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/components/Artist/ArtistProfile.dart';
|
||||
import 'package:spotube/components/Shared/SpotubePageRoute.dart';
|
||||
|
||||
class ArtistCard extends StatelessWidget {
|
||||
final Artist artist;
|
||||
@ -17,12 +16,7 @@ class ArtistCard extends StatelessWidget {
|
||||
: "https://avatars.dicebear.com/api/open-peeps/${artist.id}.png?b=%231ed760&r=50&flip=1&translateX=3&translateY=-6");
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(SpotubePageRoute(
|
||||
child: ArtistProfile(
|
||||
artist.id!,
|
||||
key: Key("artist-${artist.id}"),
|
||||
),
|
||||
));
|
||||
GoRouter.of(context).push("/artist/${artist.id}");
|
||||
},
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: Ink(
|
||||
|
@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/components/Album/AlbumCard.dart';
|
||||
@ -243,13 +244,10 @@ class ArtistProfile extends HookConsumerWidget {
|
||||
TextButton(
|
||||
child: const Text("See All"),
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(SpotubePageRoute(
|
||||
child: ArtistAlbumView(
|
||||
artistId,
|
||||
snapshot.data?.name ?? "KRTX",
|
||||
key: Key("artist-album-$artistId"),
|
||||
),
|
||||
));
|
||||
GoRouter.of(context).push(
|
||||
"/artist-album/$artistId",
|
||||
extra: snapshot.data?.name ?? "KRTX",
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
|
@ -1,10 +1,9 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:spotify/spotify.dart' hide Image;
|
||||
import 'package:spotube/components/Settings.dart';
|
||||
import 'package:spotube/components/Shared/SpotubePageRoute.dart';
|
||||
import 'package:spotube/helpers/image-to-url-string.dart';
|
||||
import 'package:spotube/hooks/useBreakpoints.dart';
|
||||
import 'package:spotube/provider/SpotifyDI.dart';
|
||||
@ -30,11 +29,7 @@ class Sidebar extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
static void goToSettings(BuildContext context) {
|
||||
Navigator.of(context).push(SpotubePageRoute(
|
||||
child: const Settings(
|
||||
key: Key("settings"),
|
||||
),
|
||||
));
|
||||
GoRouter.of(context).push("/settings");
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/components/Settings.dart';
|
||||
@ -69,11 +70,7 @@ class Lyrics extends HookConsumerWidget {
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(SpotubePageRoute(
|
||||
child: const Settings(
|
||||
key: Key("settings"),
|
||||
),
|
||||
));
|
||||
GoRouter.of(context).push("/settings");
|
||||
},
|
||||
child: const Text("Add Access Token"))
|
||||
],
|
||||
|
@ -1,24 +1,23 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
import 'package:palette_generator/palette_generator.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:spotify/spotify.dart' hide Image;
|
||||
import 'package:spotube/components/Player/PlayerOverlay.dart';
|
||||
import 'package:spotube/components/Player/PlayerTrackDetails.dart';
|
||||
import 'package:spotube/components/Shared/DownloadTrackButton.dart';
|
||||
import 'package:spotube/components/Player/PlayerControls.dart';
|
||||
import 'package:spotube/helpers/artists-to-clickable-artists.dart';
|
||||
import 'package:spotube/helpers/image-to-url-string.dart';
|
||||
import 'package:spotube/helpers/search-youtube.dart';
|
||||
import 'package:spotube/hooks/useBreakpoints.dart';
|
||||
import 'package:spotube/hooks/usePaletteColor.dart';
|
||||
import 'package:spotube/models/LocalStorageKeys.dart';
|
||||
import 'package:spotube/provider/Playback.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:spotube/provider/SpotifyDI.dart';
|
||||
import 'package:spotube/provider/ThemeProvider.dart';
|
||||
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
|
||||
|
||||
class Player extends HookConsumerWidget {
|
||||
@ -26,6 +25,7 @@ class Player extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
Playback playback = ref.watch(playbackProvider);
|
||||
|
||||
final _isPlaying = useState(false);
|
||||
final _shuffled = useState(false);
|
||||
final _volume = useState(0.0);
|
||||
@ -200,7 +200,10 @@ class Player extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
final paletteColor = usePaletteColor(albumArt);
|
||||
|
||||
final controls = PlayerControls(
|
||||
iconColor: paletteColor.bodyTextColor,
|
||||
positionStream: player.positionStream,
|
||||
isPlaying: _isPlaying.value,
|
||||
duration: _duration.value ?? Duration.zero,
|
||||
@ -274,6 +277,7 @@ class Player extends HookConsumerWidget {
|
||||
builder: (context) => PlayerOverlay(
|
||||
controls: controls,
|
||||
albumArt: albumArt,
|
||||
paletteColor: paletteColor,
|
||||
),
|
||||
);
|
||||
// I can't believe useEffect doesn't run Post Frame aka
|
||||
|
@ -21,6 +21,7 @@ class PlayerControls extends HookConsumerWidget {
|
||||
final Function? onPrevious;
|
||||
final Function? onPlay;
|
||||
final Function? onPause;
|
||||
final Color? iconColor;
|
||||
const PlayerControls({
|
||||
required this.positionStream,
|
||||
required this.isPlaying,
|
||||
@ -33,6 +34,7 @@ class PlayerControls extends HookConsumerWidget {
|
||||
this.onPrevious,
|
||||
this.onPlay,
|
||||
this.onPause,
|
||||
this.iconColor,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@ -94,6 +96,7 @@ class PlayerControls extends HookConsumerWidget {
|
||||
}),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.skip_previous_rounded),
|
||||
color: iconColor,
|
||||
onPressed: () {
|
||||
onPrevious?.call();
|
||||
}),
|
||||
@ -101,11 +104,14 @@ class PlayerControls extends HookConsumerWidget {
|
||||
icon: Icon(
|
||||
isPlaying ? Icons.pause_rounded : Icons.play_arrow_rounded,
|
||||
),
|
||||
color: iconColor,
|
||||
onPressed: () => _playOrPause(null),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.skip_next_rounded),
|
||||
onPressed: () => onNext?.call()),
|
||||
icon: const Icon(Icons.skip_next_rounded),
|
||||
onPressed: () => onNext?.call(),
|
||||
color: iconColor,
|
||||
),
|
||||
if (breakpoint.isMoreThan(Breakpoints.md))
|
||||
IconButton(
|
||||
icon: const Icon(Icons.stop_rounded),
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:palette_generator/palette_generator.dart';
|
||||
import 'package:spotube/components/Player/PlayerTrackDetails.dart';
|
||||
import 'package:spotube/hooks/useBreakpoints.dart';
|
||||
@ -8,48 +8,57 @@ import 'package:spotube/hooks/useBreakpoints.dart';
|
||||
class PlayerOverlay extends HookWidget {
|
||||
final Widget controls;
|
||||
final String albumArt;
|
||||
final PaletteColor paletteColor;
|
||||
const PlayerOverlay({
|
||||
required this.controls,
|
||||
required this.albumArt,
|
||||
required this.paletteColor,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final breakpoint = useBreakpoints();
|
||||
final isCurrentRoute = useState<bool?>(null);
|
||||
|
||||
useEffect(() {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timer) {
|
||||
final matches = GoRouter.of(context).location == "/";
|
||||
if (matches != isCurrentRoute.value) {
|
||||
isCurrentRoute.value = matches;
|
||||
}
|
||||
});
|
||||
return null;
|
||||
});
|
||||
|
||||
if (isCurrentRoute.value == false) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
return Positioned(
|
||||
right: (breakpoint.isMd ? 10 : 5),
|
||||
left: (breakpoint.isSm ? 5 : 80),
|
||||
bottom: (breakpoint.isSm ? 63 : 10),
|
||||
child: FutureBuilder<PaletteGenerator>(
|
||||
future: PaletteGenerator.fromImageProvider(
|
||||
CachedNetworkImageProvider(
|
||||
albumArt,
|
||||
cacheKey: albumArt,
|
||||
maxHeight: 50,
|
||||
maxWidth: 50,
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: paletteColor.color,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: PlayerTrackDetails(
|
||||
albumArt: albumArt,
|
||||
color: paletteColor.bodyTextColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
builder: (context, snapshot) {
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: snapshot.hasData
|
||||
? snapshot.data!.colors.first
|
||||
: Colors.blueGrey[200],
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
PlayerTrackDetails(albumArt: albumArt),
|
||||
controls,
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
Expanded(child: controls),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,9 @@ import 'package:spotube/provider/Playback.dart';
|
||||
|
||||
class PlayerTrackDetails extends HookConsumerWidget {
|
||||
final String? albumArt;
|
||||
const PlayerTrackDetails({Key? key, this.albumArt}) : super(key: key);
|
||||
final Color? color;
|
||||
const PlayerTrackDetails({Key? key, this.albumArt, this.color})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
@ -36,13 +38,15 @@ class PlayerTrackDetails extends HookConsumerWidget {
|
||||
),
|
||||
if (breakpoint.isLessThanOrEqualTo(Breakpoints.md)) ...[
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
playback.currentTrack?.name ?? "Not playing",
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText1
|
||||
?.copyWith(fontWeight: FontWeight.bold),
|
||||
Flexible(
|
||||
child: Text(
|
||||
playback.currentTrack?.name ?? "Not playing",
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText1
|
||||
?.copyWith(fontWeight: FontWeight.bold, color: color),
|
||||
),
|
||||
),
|
||||
],
|
||||
// title of the currently playing track
|
||||
@ -53,10 +57,11 @@ class PlayerTrackDetails extends HookConsumerWidget {
|
||||
children: [
|
||||
Text(
|
||||
playback.currentTrack?.name ?? "Not playing",
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText1
|
||||
?.copyWith(fontWeight: FontWeight.bold),
|
||||
?.copyWith(fontWeight: FontWeight.bold, color: color),
|
||||
),
|
||||
artistsToClickableArtists(
|
||||
playback.currentTrack?.artists ?? [],
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/components/Playlist/PlaylistView.dart';
|
||||
@ -26,13 +27,9 @@ class PlaylistCard extends HookConsumerWidget {
|
||||
imageUrl: playlist.images![0].url!,
|
||||
isPlaying: isPlaylistPlaying,
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
SpotubePageRoute(
|
||||
child: PlaylistView(
|
||||
playlist,
|
||||
key: Key("playlist-${playlist.id}"),
|
||||
),
|
||||
),
|
||||
GoRouter.of(context).push(
|
||||
"/playlist/${playlist.id}",
|
||||
extra: playlist,
|
||||
);
|
||||
},
|
||||
onPlaybuttonPressed: () async {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:spotube/components/Settings/SettingsHotkeyTile.dart';
|
||||
@ -57,7 +58,7 @@ class Settings extends HookConsumerWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: ElevatedButton(
|
||||
onPressed: geniusAccessToken != null
|
||||
onPressed: geniusAccessToken.value != null
|
||||
? () async {
|
||||
SharedPreferences localStorage =
|
||||
await SharedPreferences.getInstance();
|
||||
@ -148,7 +149,7 @@ class Settings extends HookConsumerWidget {
|
||||
await SharedPreferences.getInstance();
|
||||
await localStorage.clear();
|
||||
auth.logout();
|
||||
Navigator.of(context).pop();
|
||||
GoRouter.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:spotube/components/Shared/AnchorButton.dart';
|
||||
|
||||
class LinkText<T> extends StatelessWidget {
|
||||
@ -6,12 +7,14 @@ class LinkText<T> extends StatelessWidget {
|
||||
final TextStyle style;
|
||||
final TextAlign? textAlign;
|
||||
final TextOverflow? overflow;
|
||||
final Route<T> route;
|
||||
final String route;
|
||||
final T? extra;
|
||||
const LinkText(
|
||||
this.text,
|
||||
this.route, {
|
||||
Key? key,
|
||||
this.textAlign,
|
||||
this.extra,
|
||||
this.overflow,
|
||||
this.style = const TextStyle(),
|
||||
}) : super(key: key);
|
||||
@ -20,8 +23,8 @@ class LinkText<T> extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return AnchorButton(
|
||||
text,
|
||||
onTap: () async {
|
||||
await Navigator.of(context).push(route);
|
||||
onTap: () {
|
||||
GoRouter.of(context).push(route, extra: extra);
|
||||
},
|
||||
key: key,
|
||||
overflow: overflow,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hotkey_manager/hotkey_manager.dart';
|
||||
|
||||
class RecordHotKeyDialog extends HookWidget {
|
||||
@ -66,7 +67,7 @@ class RecordHotKeyDialog extends HookWidget {
|
||||
TextButton(
|
||||
child: const Text('Cancel'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
GoRouter.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
@ -75,7 +76,7 @@ class RecordHotKeyDialog extends HookWidget {
|
||||
? null
|
||||
: () {
|
||||
onHotKeyRecorded(_hotKey.value);
|
||||
Navigator.of(context).pop();
|
||||
GoRouter.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class SpotubePageRoute extends PageRouteBuilder {
|
||||
final Widget child;
|
||||
@ -16,3 +17,20 @@ class SpotubePageRoute extends PageRouteBuilder {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SpotubePage extends CustomTransitionPage {
|
||||
SpotubePage({
|
||||
required Widget child,
|
||||
}) : super(
|
||||
child: child,
|
||||
transitionsBuilder: (BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
Widget child) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -180,9 +180,8 @@ class TrackTile extends HookWidget {
|
||||
Expanded(
|
||||
child: LinkText(
|
||||
track.value.album!.name!,
|
||||
SpotubePageRoute(
|
||||
child: AlbumView(track.value.album!),
|
||||
),
|
||||
"/album/${track.value.album?.id}",
|
||||
extra: track.value.album,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
|
@ -21,9 +21,7 @@ Widget artistsToClickableArtists(
|
||||
(artist.key != artists.length - 1)
|
||||
? "${artist.value.name}, "
|
||||
: artist.value.name!,
|
||||
SpotubePageRoute(
|
||||
child: ArtistProfile(artist.value.id!),
|
||||
),
|
||||
"/artist/${artist.value.id}",
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: textStyle,
|
||||
),
|
||||
|
@ -5,5 +5,5 @@ const uuid = Uuid();
|
||||
String imageToUrlString(List<Image>? images, {int index = 0}) {
|
||||
return images != null && images.isNotEmpty
|
||||
? images[0].url!
|
||||
: "https://avatars.dicebear.com/api/croodles-neutral/${uuid.v4()}.png";
|
||||
: "https://avatars.dicebear.com/api/bottts/${uuid.v4()}.png";
|
||||
}
|
||||
|
32
lib/hooks/usePaletteColor.dart
Normal file
32
lib/hooks/usePaletteColor.dart
Normal file
@ -0,0 +1,32 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:palette_generator/palette_generator.dart';
|
||||
|
||||
PaletteColor usePaletteColor(String imageUrl) {
|
||||
final paletteColor =
|
||||
useState<PaletteColor>(PaletteColor(Colors.grey[300]!, 0));
|
||||
|
||||
final context = useContext();
|
||||
|
||||
useEffect(() {
|
||||
PaletteGenerator.fromImageProvider(
|
||||
CachedNetworkImageProvider(
|
||||
imageUrl,
|
||||
cacheKey: imageUrl,
|
||||
maxHeight: 50,
|
||||
maxWidth: 50,
|
||||
),
|
||||
).then((palette) {
|
||||
final color = Theme.of(context).brightness == Brightness.light
|
||||
? palette.lightMutedColor ?? palette.lightVibrantColor
|
||||
: palette.darkMutedColor ?? palette.darkVibrantColor;
|
||||
if (color != null) {
|
||||
paletteColor.value = color;
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}, [imageUrl]);
|
||||
|
||||
return paletteColor.value;
|
||||
}
|
@ -3,10 +3,18 @@ import 'dart:io';
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:hotkey_manager/hotkey_manager.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/components/Album/AlbumView.dart';
|
||||
import 'package:spotube/components/Artist/ArtistAlbumView.dart';
|
||||
import 'package:spotube/components/Artist/ArtistProfile.dart';
|
||||
import 'package:spotube/components/Home/Home.dart';
|
||||
import 'package:spotube/components/Playlist/PlaylistView.dart';
|
||||
import 'package:spotube/components/Settings.dart';
|
||||
import 'package:spotube/components/Shared/SpotubePageRoute.dart';
|
||||
import 'package:spotube/models/LocalStorageKeys.dart';
|
||||
import 'package:spotube/provider/ThemeProvider.dart';
|
||||
|
||||
@ -25,6 +33,56 @@ void main() async {
|
||||
}
|
||||
|
||||
class MyApp extends HookConsumerWidget {
|
||||
final GoRouter _router = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: "/",
|
||||
builder: (context, state) => const Home(),
|
||||
),
|
||||
GoRoute(
|
||||
path: "/settings",
|
||||
pageBuilder: (context, state) => SpotubePage(
|
||||
child: const Settings(),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: "/album/:id",
|
||||
pageBuilder: (context, state) {
|
||||
assert(state.extra is AlbumSimple);
|
||||
return SpotubePage(child: AlbumView(state.extra as AlbumSimple));
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: "/artist/:id",
|
||||
pageBuilder: (context, state) {
|
||||
assert(state.params["id"] != null);
|
||||
return SpotubePage(child: ArtistProfile(state.params["id"]!));
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: "/artist-album/:id",
|
||||
pageBuilder: (context, state) {
|
||||
assert(state.params["id"] != null);
|
||||
assert(state.extra is String);
|
||||
return SpotubePage(
|
||||
child: ArtistAlbumView(
|
||||
state.params["id"]!,
|
||||
state.extra as String,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: "/playlist/:id",
|
||||
pageBuilder: (context, state) {
|
||||
assert(state.extra is PlaylistSimple);
|
||||
return SpotubePage(
|
||||
child: PlaylistView(state.extra as PlaylistSimple),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
var themeMode = ref.watch(themeProvider);
|
||||
@ -44,9 +102,12 @@ class MyApp extends HookConsumerWidget {
|
||||
themeNotifier.state = ThemeMode.system;
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}, []);
|
||||
|
||||
return MaterialApp(
|
||||
return MaterialApp.router(
|
||||
routeInformationParser: _router.routeInformationParser,
|
||||
routerDelegate: _router.routerDelegate,
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'Spotube',
|
||||
theme: ThemeData(
|
||||
@ -142,7 +203,6 @@ class MyApp extends HookConsumerWidget {
|
||||
canvasColor: Colors.blueGrey[900],
|
||||
),
|
||||
themeMode: themeMode,
|
||||
home: const Home(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user