From aaf74b46d4c6b6958af931599c7ab387122b0d7e Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 10 Mar 2022 15:11:02 +0600 Subject: [PATCH] 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 --- lib/components/Album/AlbumCard.dart | 8 +-- lib/components/Artist/ArtistCard.dart | 10 +-- lib/components/Artist/ArtistProfile.dart | 12 ++-- lib/components/Home/Sidebar.dart | 9 +-- lib/components/Lyrics.dart | 7 +- lib/components/Player/Player.dart | 10 ++- lib/components/Player/PlayerControls.dart | 10 ++- lib/components/Player/PlayerOverlay.dart | 65 +++++++++++-------- lib/components/Player/PlayerTrackDetails.dart | 23 ++++--- lib/components/Playlist/PlaylistCard.dart | 11 ++-- lib/components/Settings.dart | 5 +- lib/components/Shared/LinkText.dart | 9 ++- lib/components/Shared/RecordHotKeyDialog.dart | 5 +- lib/components/Shared/SpotubePageRoute.dart | 18 +++++ lib/components/Shared/TracksTableView.dart | 5 +- lib/helpers/artists-to-clickable-artists.dart | 4 +- lib/helpers/image-to-url-string.dart | 2 +- lib/hooks/usePaletteColor.dart | 32 +++++++++ lib/main.dart | 64 +++++++++++++++++- 19 files changed, 211 insertions(+), 98 deletions(-) create mode 100644 lib/hooks/usePaletteColor.dart diff --git a/lib/components/Album/AlbumCard.dart b/lib/components/Album/AlbumCard.dart index 8f723972..9aa17145 100644 --- a/lib/components/Album/AlbumCard.dart +++ b/lib/components/Album/AlbumCard.dart @@ -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(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); diff --git a/lib/components/Artist/ArtistCard.dart b/lib/components/Artist/ArtistCard.dart index 3d844c5c..9f2ead1a 100644 --- a/lib/components/Artist/ArtistCard.dart +++ b/lib/components/Artist/ArtistCard.dart @@ -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( diff --git a/lib/components/Artist/ArtistProfile.dart b/lib/components/Artist/ArtistProfile.dart index a8706689..0b3cd8b5 100644 --- a/lib/components/Artist/ArtistProfile.dart +++ b/lib/components/Artist/ArtistProfile.dart @@ -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", + ); }, ) ], diff --git a/lib/components/Home/Sidebar.dart b/lib/components/Home/Sidebar.dart index 8abb869d..da77a107 100644 --- a/lib/components/Home/Sidebar.dart +++ b/lib/components/Home/Sidebar.dart @@ -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 diff --git a/lib/components/Lyrics.dart b/lib/components/Lyrics.dart index 6cb5d83c..16cf56f5 100644 --- a/lib/components/Lyrics.dart +++ b/lib/components/Lyrics.dart @@ -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")) ], diff --git a/lib/components/Player/Player.dart b/lib/components/Player/Player.dart index 1aec567c..5879172a 100644 --- a/lib/components/Player/Player.dart +++ b/lib/components/Player/Player.dart @@ -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 diff --git a/lib/components/Player/PlayerControls.dart b/lib/components/Player/PlayerControls.dart index 0aac81dd..c5a5e4b5 100644 --- a/lib/components/Player/PlayerControls.dart +++ b/lib/components/Player/PlayerControls.dart @@ -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), diff --git a/lib/components/Player/PlayerOverlay.dart b/lib/components/Player/PlayerOverlay.dart index 1521fac8..a64662bb 100644 --- a/lib/components/Player/PlayerOverlay.dart +++ b/lib/components/Player/PlayerOverlay.dart @@ -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(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( - 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), + ], + ), + ), ); } } diff --git a/lib/components/Player/PlayerTrackDetails.dart b/lib/components/Player/PlayerTrackDetails.dart index 9d4962a1..9610756c 100644 --- a/lib/components/Player/PlayerTrackDetails.dart +++ b/lib/components/Player/PlayerTrackDetails.dart @@ -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 ?? [], diff --git a/lib/components/Playlist/PlaylistCard.dart b/lib/components/Playlist/PlaylistCard.dart index 5ba07808..8f854c41 100644 --- a/lib/components/Playlist/PlaylistCard.dart +++ b/lib/components/Playlist/PlaylistCard.dart @@ -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 { diff --git a/lib/components/Settings.dart b/lib/components/Settings.dart index 27ec712c..32060030 100644 --- a/lib/components/Settings.dart +++ b/lib/components/Settings.dart @@ -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(); }, ), ], diff --git a/lib/components/Shared/LinkText.dart b/lib/components/Shared/LinkText.dart index 9d5d63e3..d24aaf75 100644 --- a/lib/components/Shared/LinkText.dart +++ b/lib/components/Shared/LinkText.dart @@ -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 extends StatelessWidget { @@ -6,12 +7,14 @@ class LinkText extends StatelessWidget { final TextStyle style; final TextAlign? textAlign; final TextOverflow? overflow; - final Route 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 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, diff --git a/lib/components/Shared/RecordHotKeyDialog.dart b/lib/components/Shared/RecordHotKeyDialog.dart index e0fde237..40af28e2 100644 --- a/lib/components/Shared/RecordHotKeyDialog.dart +++ b/lib/components/Shared/RecordHotKeyDialog.dart @@ -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(); }, ), ], diff --git a/lib/components/Shared/SpotubePageRoute.dart b/lib/components/Shared/SpotubePageRoute.dart index 69a37da5..0f729873 100644 --- a/lib/components/Shared/SpotubePageRoute.dart +++ b/lib/components/Shared/SpotubePageRoute.dart @@ -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 animation, + Animation secondaryAnimation, + Widget child) { + return FadeTransition( + opacity: animation, + child: child, + ); + }, + ); +} diff --git a/lib/components/Shared/TracksTableView.dart b/lib/components/Shared/TracksTableView.dart index 78ed7e24..dcf7f036 100644 --- a/lib/components/Shared/TracksTableView.dart +++ b/lib/components/Shared/TracksTableView.dart @@ -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, ), ), diff --git a/lib/helpers/artists-to-clickable-artists.dart b/lib/helpers/artists-to-clickable-artists.dart index 030e8f3d..2ce58e98 100644 --- a/lib/helpers/artists-to-clickable-artists.dart +++ b/lib/helpers/artists-to-clickable-artists.dart @@ -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, ), diff --git a/lib/helpers/image-to-url-string.dart b/lib/helpers/image-to-url-string.dart index 0d4cc397..52731ff7 100644 --- a/lib/helpers/image-to-url-string.dart +++ b/lib/helpers/image-to-url-string.dart @@ -5,5 +5,5 @@ const uuid = Uuid(); String imageToUrlString(List? 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"; } diff --git a/lib/hooks/usePaletteColor.dart b/lib/hooks/usePaletteColor.dart new file mode 100644 index 00000000..75a21ca4 --- /dev/null +++ b/lib/hooks/usePaletteColor.dart @@ -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(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; +} diff --git a/lib/main.dart b/lib/main.dart index facab79d..ddf5ad8c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -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(), ); } }