diff --git a/lib/components/album/album_card.dart b/lib/components/album/album_card.dart index 5c94caf0..da66f276 100644 --- a/lib/components/album/album_card.dart +++ b/lib/components/album/album_card.dart @@ -53,7 +53,7 @@ class AlbumCard extends HookConsumerWidget { [playlistNotifier, query?.data, album.tracks], ); final int marginH = - useBreakpointValue(sm: 10, md: 15, lg: 20, xl: 20, xxl: 20); + useBreakpointValue(xs: 10, sm: 10, md: 15, lg: 20, xl: 20, xxl: 20); final updating = useState(false); final spotify = ref.watch(spotifyProvider); diff --git a/lib/components/artist/artist_card.dart b/lib/components/artist/artist_card.dart index cb695f6f..993e9f6a 100644 --- a/lib/components/artist/artist_card.dart +++ b/lib/components/artist/artist_card.dart @@ -35,6 +35,7 @@ class ArtistCard extends HookConsumerWidget { final radius = BorderRadius.circular(15); final double size = useBreakpointValue( + xs: 130, sm: 130, md: 150, others: 170, diff --git a/lib/components/library/playlist_generate/multi_select_field.dart b/lib/components/library/playlist_generate/multi_select_field.dart index d8de3da5..ed5eb38f 100644 --- a/lib/components/library/playlist_generate/multi_select_field.dart +++ b/lib/components/library/playlist_generate/multi_select_field.dart @@ -188,7 +188,7 @@ class _MultiSelectDialog extends HookWidget { return AlertDialog( scrollable: true, title: dialogTitle ?? const Text('Select'), - contentPadding: mediaQuery.isSm ? const EdgeInsets.all(16) : null, + contentPadding: mediaQuery.mdAndUp ? null : const EdgeInsets.all(16), insetPadding: const EdgeInsets.all(16), actions: [ OutlinedButton( diff --git a/lib/components/library/user_albums.dart b/lib/components/library/user_albums.dart index 8553a8c3..014a84f6 100644 --- a/lib/components/library/user_albums.dart +++ b/lib/components/library/user_albums.dart @@ -24,6 +24,7 @@ class UserAlbums extends HookConsumerWidget { final albumsQuery = useQueries.album.ofMine(ref); final spacing = useBreakpointValue( + xs: 0, sm: 0, others: 20, ); diff --git a/lib/components/player/player_track_details.dart b/lib/components/player/player_track_details.dart index 8b66b8b7..36c6ab25 100644 --- a/lib/components/player/player_track_details.dart +++ b/lib/components/player/player_track_details.dart @@ -39,7 +39,7 @@ class PlayerTrackDetails extends HookConsumerWidget { ), ), ), - if (mediaQuery.isSm || mediaQuery.isMd) + if (mediaQuery.mdAndDown) Flexible( child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/components/playlist/playlist_create_dialog.dart b/lib/components/playlist/playlist_create_dialog.dart index f5d32186..b7cee79d 100644 --- a/lib/components/playlist/playlist_create_dialog.dart +++ b/lib/components/playlist/playlist_create_dialog.dart @@ -121,7 +121,7 @@ class PlaylistCreateDialogButton extends HookConsumerWidget { final mediaQuery = MediaQuery.of(context); final spotify = ref.watch(spotifyProvider); - if (mediaQuery.isSm) { + if (mediaQuery.smAndDown) { return ElevatedButton( style: FilledButton.styleFrom( foregroundColor: Theme.of(context).colorScheme.primary, diff --git a/lib/components/root/bottom_player.dart b/lib/components/root/bottom_player.dart index 2b0bc1ff..70d14f8a 100644 --- a/lib/components/root/bottom_player.dart +++ b/lib/components/root/bottom_player.dart @@ -58,8 +58,7 @@ class BottomPlayer extends HookConsumerWidget { // returning an empty non spacious Container as the overlay will take // place in the global overlay stack aka [_entries] if (layoutMode == LayoutMode.compact || - ((mediaQuery.isSm || mediaQuery.isMd) && - layoutMode == LayoutMode.adaptive)) { + ((mediaQuery.mdAndDown) && layoutMode == LayoutMode.adaptive)) { return PlayerOverlay(albumArt: albumArt); } diff --git a/lib/components/root/sidebar.dart b/lib/components/root/sidebar.dart index b6c90e77..64525823 100644 --- a/lib/components/root/sidebar.dart +++ b/lib/components/root/sidebar.dart @@ -82,16 +82,17 @@ class Sidebar extends HookConsumerWidget { }, [controller]); useEffect(() { + if (!context.mounted) return; if (mediaQuery.lgAndUp && !controller.extended) { controller.setExtended(true); - } else if ((mediaQuery.isSm || mediaQuery.isMd) && controller.extended) { + } else if (mediaQuery.mdAndDown && controller.extended) { controller.setExtended(false); } return null; }, [mediaQuery, controller]); if (layoutMode == LayoutMode.compact || - (mediaQuery.isSm && layoutMode == LayoutMode.adaptive)) { + (mediaQuery.smAndDown && layoutMode == LayoutMode.adaptive)) { return Scaffold(body: child); } @@ -186,7 +187,7 @@ class SidebarHeader extends HookWidget { final mediaQuery = MediaQuery.of(context); final theme = Theme.of(context); - if (mediaQuery.isSm || mediaQuery.isMd) { + if (mediaQuery.mdAndDown) { return Container( height: 40, width: 40, @@ -236,7 +237,7 @@ class SidebarFooter extends HookConsumerWidget { final auth = ref.watch(AuthenticationNotifier.provider); - if (mediaQuery.isSm || mediaQuery.isMd) { + if (mediaQuery.mdAndDown) { return IconButton( icon: const Icon(SpotubeIcons.settings), onPressed: () => Sidebar.goToSettings(context), diff --git a/lib/components/shared/adaptive/adaptive_list_tile.dart b/lib/components/shared/adaptive/adaptive_list_tile.dart index 965250a4..33df44c1 100644 --- a/lib/components/shared/adaptive/adaptive_list_tile.dart +++ b/lib/components/shared/adaptive/adaptive_list_tile.dart @@ -17,7 +17,7 @@ class AdaptiveListTile extends HookWidget { this.title, this.subtitle, this.leading, - this.breakOn , + this.breakOn, }); @override @@ -27,10 +27,11 @@ class AdaptiveListTile extends HookWidget { return ListTile( title: title, subtitle: subtitle, - trailing: - breakOn ?? mediaQuery.isSm ? null : trailing?.call(context, null), + trailing: breakOn ?? mediaQuery.smAndDown + ? null + : trailing?.call(context, null), leading: leading, - onTap: breakOn ?? mediaQuery.isSm + onTap: breakOn ?? mediaQuery.smAndDown ? () { onTap?.call(); showDialog( diff --git a/lib/components/shared/playbutton_card.dart b/lib/components/shared/playbutton_card.dart index 517a7e2d..f381e7ce 100644 --- a/lib/components/shared/playbutton_card.dart +++ b/lib/components/shared/playbutton_card.dart @@ -40,6 +40,7 @@ class PlaybuttonCard extends HookWidget { final radius = BorderRadius.circular(15); final double size = useBreakpointValue( + xs: 130, sm: 130, md: 150, others: 170, @@ -47,6 +48,7 @@ class PlaybuttonCard extends HookWidget { 170; final end = useBreakpointValue( + xs: 15, sm: 15, others: 20, ) ?? diff --git a/lib/components/shared/shimmers/shimmer_artist_profile.dart b/lib/components/shared/shimmers/shimmer_artist_profile.dart index 077e24e3..940c4e81 100644 --- a/lib/components/shared/shimmers/shimmer_artist_profile.dart +++ b/lib/components/shared/shimmers/shimmer_artist_profile.dart @@ -21,6 +21,7 @@ class ShimmerArtistProfile extends HookWidget { shimmerTheme.shimmerBackgroundColor ?? Colors.grey; final avatarWidth = useBreakpointValue( + xs: MediaQuery.of(context).size.width * 0.80, sm: MediaQuery.of(context).size.width * 0.80, md: MediaQuery.of(context).size.width * 0.50, lg: MediaQuery.of(context).size.width * 0.30, diff --git a/lib/components/shared/shimmers/shimmer_categories.dart b/lib/components/shared/shimmers/shimmer_categories.dart index d93b70a4..e9f442d4 100644 --- a/lib/components/shared/shimmers/shimmer_categories.dart +++ b/lib/components/shared/shimmers/shimmer_categories.dart @@ -18,6 +18,7 @@ class ShimmerCategories extends HookWidget { shimmerTheme.shimmerBackgroundColor ?? Colors.grey; final shimmerCount = useBreakpointValue( + xs: 2, sm: 2, md: 3, lg: 3, diff --git a/lib/components/shared/shimmers/shimmer_lyrics.dart b/lib/components/shared/shimmers/shimmer_lyrics.dart index fd88ac6b..b0fba340 100644 --- a/lib/components/shared/shimmers/shimmer_lyrics.dart +++ b/lib/components/shared/shimmers/shimmer_lyrics.dart @@ -32,7 +32,7 @@ class ShimmerLyrics extends HookWidget { if (mediaQuery.isMd) { widthsCp.removeLast(); } - if (mediaQuery.isSm) { + if (mediaQuery.smAndDown) { widthsCp.removeLast(); widthsCp.removeLast(); } diff --git a/lib/components/shared/shimmers/shimmer_playbutton_card.dart b/lib/components/shared/shimmers/shimmer_playbutton_card.dart index 48671aa6..82da5bd9 100644 --- a/lib/components/shared/shimmers/shimmer_playbutton_card.dart +++ b/lib/components/shared/shimmers/shimmer_playbutton_card.dart @@ -86,6 +86,7 @@ class ShimmerPlaybuttonCard extends HookWidget { Widget build(BuildContext context) { final theme = Theme.of(context); final Size size = useBreakpointValue( + xs: const Size(130, 200), sm: const Size(130, 200), md: const Size(150, 220), others: const Size(170, 240), diff --git a/lib/components/shared/themed_button_tab_bar.dart b/lib/components/shared/themed_button_tab_bar.dart index ecf64134..ee107088 100644 --- a/lib/components/shared/themed_button_tab_bar.dart +++ b/lib/components/shared/themed_button_tab_bar.dart @@ -18,6 +18,7 @@ class ThemedButtonsTabBar extends HookWidget implements PreferredSizeWidget { ); final breakpoint = useBreakpointValue( + xs: 85.0, sm: 85.0, md: 35.0, others: 0.0, diff --git a/lib/components/shared/track_table/track_collection_view/track_collection_heading.dart b/lib/components/shared/track_table/track_collection_view/track_collection_heading.dart new file mode 100644 index 00000000..45104eee --- /dev/null +++ b/lib/components/shared/track_table/track_collection_view/track_collection_heading.dart @@ -0,0 +1,195 @@ +import 'dart:ui'; + +import 'package:fl_query/fl_query.dart'; +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:palette_generator/palette_generator.dart'; +import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/assets.gen.dart'; +import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/album/album_card.dart'; +import 'package:spotube/components/shared/image/universal_image.dart'; +import 'package:spotube/extensions/constrains.dart'; +import 'package:spotube/extensions/context.dart'; + +class TrackCollectionHeading extends HookConsumerWidget { + final String title; + final String? description; + final String titleImage; + final List buttons; + final AlbumSimple? album; + final Query, T> tracksSnapshot; + final bool isPlaying; + final void Function([Track? currentTrack]) onPlay; + final void Function([Track? currentTrack]) onShuffledPlay; + final PaletteColor? color; + + const TrackCollectionHeading({ + Key? key, + required this.title, + required this.titleImage, + required this.buttons, + required this.tracksSnapshot, + required this.isPlaying, + required this.onPlay, + required this.onShuffledPlay, + required this.color, + this.description, + this.album, + }) : super(key: key); + + @override + Widget build(BuildContext context, ref) { + final theme = Theme.of(context); + + return LayoutBuilder( + builder: (context, constrains) { + return DecoratedBox( + decoration: BoxDecoration( + image: DecorationImage( + image: UniversalImage.imageProvider(titleImage), + fit: BoxFit.cover, + ), + ), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), + child: DecoratedBox( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + Colors.black45, + theme.colorScheme.surface, + ], + begin: const FractionalOffset(0, 0), + end: const FractionalOffset(0, 1), + tileMode: TileMode.clamp, + ), + ), + child: Material( + type: MaterialType.transparency, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 20, + ), + child: Flex( + direction: + constrains.mdAndDown ? Axis.vertical : Axis.horizontal, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 200), + child: ClipRRect( + borderRadius: BorderRadius.circular(10), + child: UniversalImage( + path: titleImage, + placeholder: Assets.albumPlaceholder.path, + ), + ), + ), + const SizedBox(width: 10, height: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + Text( + title, + style: theme.textTheme.titleLarge!.copyWith( + color: Colors.white, + fontWeight: FontWeight.w600, + ), + ), + if (album != null) + Text( + "${AlbumType.from(album?.albumType).formatted} • ${context.l10n.released} • ${DateTime.tryParse( + album?.releaseDate ?? "", + )?.year}", + style: theme.textTheme.titleMedium!.copyWith( + color: Colors.white, + fontWeight: FontWeight.normal, + ), + ), + if (description != null) + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: constrains.mdAndDown ? 400 : 300, + ), + child: Text( + description!, + style: const TextStyle(color: Colors.white), + maxLines: 2, + overflow: TextOverflow.fade, + ), + ), + const SizedBox(height: 10), + IconTheme( + data: theme.iconTheme.copyWith( + color: Colors.white, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: buttons, + ), + ), + const SizedBox(height: 10), + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: constrains.mdAndDown ? 400 : 300, + ), + child: Row( + mainAxisSize: constrains.smAndUp + ? MainAxisSize.min + : MainAxisSize.min, + children: [ + Expanded( + child: FilledButton.icon( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + foregroundColor: color?.color, + ), + label: Text(context.l10n.shuffle), + icon: const Icon(SpotubeIcons.shuffle), + onPressed: + tracksSnapshot.data == null || isPlaying + ? null + : onShuffledPlay, + ), + ), + const SizedBox(width: 10), + Expanded( + child: FilledButton.icon( + style: ElevatedButton.styleFrom( + backgroundColor: color?.color, + foregroundColor: color?.bodyTextColor, + ), + onPressed: tracksSnapshot.data != null + ? onPlay + : null, + icon: Icon( + isPlaying + ? SpotubeIcons.stop + : SpotubeIcons.play, + ), + label: Text( + isPlaying + ? context.l10n.stop + : context.l10n.play, + ), + ), + ), + ], + ), + ), + ], + ) + ], + ), + ), + ), + ), + ), + ); + }, + ); + } +} diff --git a/lib/components/shared/track_table/track_collection_view.dart b/lib/components/shared/track_table/track_collection_view/track_collection_view.dart similarity index 50% rename from lib/components/shared/track_table/track_collection_view.dart rename to lib/components/shared/track_table/track_collection_view/track_collection_view.dart index b569d137..b2e639b5 100644 --- a/lib/components/shared/track_table/track_collection_view.dart +++ b/lib/components/shared/track_table/track_collection_view/track_collection_view.dart @@ -1,16 +1,12 @@ -import 'dart:ui'; - import 'package:fl_query/fl_query.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/components/album/album_card.dart'; import 'package:spotube/components/shared/shimmers/shimmer_track_tile.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; -import 'package:spotube/components/shared/image/universal_image.dart'; +import 'package:spotube/components/shared/track_table/track_collection_view/track_collection_heading.dart'; import 'package:spotube/components/shared/track_table/tracks_table_view.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/hooks/use_custom_status_bar_color.dart'; @@ -31,8 +27,8 @@ class TrackCollectionView extends HookConsumerWidget { final String titleImage; final bool isPlaying; final void Function([Track? currentTrack]) onPlay; - final void Function() onAddToQueue; final void Function([Track? currentTrack]) onShuffledPlay; + final void Function() onAddToQueue; final void Function() onShare; final Widget? heartBtn; final AlbumSimple? album; @@ -187,145 +183,17 @@ class TrackCollectionView extends HookConsumerWidget { : null, centerTitle: true, flexibleSpace: FlexibleSpaceBar( - background: DecoratedBox( - decoration: BoxDecoration( - image: DecorationImage( - image: UniversalImage.imageProvider(titleImage), - fit: BoxFit.cover, - ), - ), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: DecoratedBox( - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - Colors.black45, - theme.colorScheme.surface, - ], - begin: const FractionalOffset(0, 0), - end: const FractionalOffset(0, 1), - tileMode: TileMode.clamp, - ), - ), - child: Material( - type: MaterialType.transparency, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20, - ), - child: Wrap( - spacing: 20, - runSpacing: 20, - crossAxisAlignment: WrapCrossAlignment.center, - alignment: WrapAlignment.center, - runAlignment: WrapAlignment.center, - children: [ - Container( - constraints: - const BoxConstraints(maxHeight: 200), - child: ClipRRect( - borderRadius: BorderRadius.circular(10), - child: UniversalImage( - path: titleImage, - placeholder: - Assets.albumPlaceholder.path, - ), - ), - ), - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Text( - title, - style: theme.textTheme.titleLarge! - .copyWith( - color: Colors.white, - fontWeight: FontWeight.w600, - ), - ), - if (album != null) - Text( - "${AlbumType.from(album?.albumType).formatted} • ${context.l10n.released} • ${DateTime.tryParse( - album?.releaseDate ?? "", - )?.year}", - style: theme.textTheme.titleMedium! - .copyWith( - color: Colors.white, - fontWeight: FontWeight.normal, - ), - ), - if (description != null) - Text( - description!, - style: const TextStyle( - color: Colors.white), - maxLines: 2, - overflow: TextOverflow.fade, - ), - const SizedBox(height: 10), - IconTheme( - data: theme.iconTheme.copyWith( - color: Colors.white, - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: buttons, - ), - ), - const SizedBox(height: 10), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - FilledButton.icon( - style: ElevatedButton.styleFrom( - backgroundColor: Colors.white, - foregroundColor: color?.color, - ), - label: Text(context.l10n.shuffle), - icon: const Icon( - SpotubeIcons.shuffle), - onPressed: - tracksSnapshot.data == null || - isPlaying - ? null - : onShuffledPlay, - ), - const SizedBox(width: 10), - FilledButton.icon( - style: ElevatedButton.styleFrom( - backgroundColor: color?.color, - foregroundColor: - color?.bodyTextColor, - ), - onPressed: - tracksSnapshot.data != null - ? onPlay - : null, - icon: Icon( - isPlaying - ? SpotubeIcons.stop - : SpotubeIcons.play, - ), - label: Text( - isPlaying - ? context.l10n.stop - : context.l10n.play, - ), - ), - ], - ), - ], - ) - ], - ), - ), - ), - ), - ), + background: TrackCollectionHeading( + color: color, + title: title, + description: description, + titleImage: titleImage, + isPlaying: isPlaying, + onPlay: onPlay, + onShuffledPlay: onShuffledPlay, + tracksSnapshot: tracksSnapshot, + buttons: buttons, + album: album, ), ), ), @@ -361,7 +229,7 @@ class TrackCollectionView extends HookConsumerWidget { // scroll the flexible space // to allow more space for search results controller.animateTo( - 390, + 330, duration: const Duration(milliseconds: 200), curve: Curves.easeInOut, ); diff --git a/lib/components/shared/track_table/track_tile.dart b/lib/components/shared/track_table/track_tile.dart index 5f8b9753..5a9f33e7 100644 --- a/lib/components/shared/track_table/track_tile.dart +++ b/lib/components/shared/track_table/track_tile.dart @@ -61,7 +61,7 @@ class TrackTile extends HookConsumerWidget { return LayoutBuilder(builder: (context, constrains) { return HoverBuilder( - permanentState: isPlaying || constrains.isSm ? true : null, + permanentState: isPlaying || constrains.smAndDown ? true : null, builder: (context, isHovering) { return ListTile( selected: isPlaying, @@ -89,7 +89,7 @@ class TrackTile extends HookConsumerWidget { ), ), ) - else if (constrains.isSm) + else if (constrains.smAndDown) const SizedBox(width: 16), if (onChanged != null) Checkbox.adaptive( diff --git a/lib/components/shared/track_table/tracks_table_view.dart b/lib/components/shared/track_table/tracks_table_view.dart index df3ee164..d9589552 100644 --- a/lib/components/shared/track_table/tracks_table_view.dart +++ b/lib/components/shared/track_table/tracks_table_view.dart @@ -390,6 +390,7 @@ class TracksTableView extends HookConsumerWidget { if (isSliver) { return SliverSafeArea( + top: false, sliver: SliverList(delegate: SliverChildListDelegate(children)), ); } diff --git a/lib/extensions/constrains.dart b/lib/extensions/constrains.dart index b36087c4..8ee22320 100644 --- a/lib/extensions/constrains.dart +++ b/lib/extensions/constrains.dart @@ -1,25 +1,39 @@ import 'package:flutter/widgets.dart'; extension ContainerBreakpoints on BoxConstraints { - bool get isSm => biggest.width <= 640; + bool get isXs => biggest.width <= 480; + bool get isSm => biggest.width > 480 && biggest.width <= 640; bool get isMd => biggest.width > 640 && biggest.width <= 768; bool get isLg => biggest.width > 768 && biggest.width <= 1024; bool get isXl => biggest.width > 1024 && biggest.width <= 1280; bool get is2Xl => biggest.width > 1280; + bool get smAndUp => isSm || isMd || isLg || isXl || is2Xl; bool get mdAndUp => isMd || isLg || isXl || is2Xl; bool get lgAndUp => isLg || isXl || is2Xl; bool get xlAndUp => isXl || is2Xl; + + bool get smAndDown => isXs || isSm; + bool get mdAndDown => isXs || isSm || isMd; + bool get lgAndDown => isXs || isSm || isMd || isLg; + bool get xlAndDown => isXs || isSm || isMd || isLg || isXl; } extension ScreenBreakpoints on MediaQueryData { - bool get isSm => size.width <= 640; + bool get isXs => size.width <= 480; + bool get isSm => size.width > 480 && size.width <= 640; bool get isMd => size.width > 640 && size.width <= 768; bool get isLg => size.width > 768 && size.width <= 1024; bool get isXl => size.width > 1024 && size.width <= 1280; bool get is2Xl => size.width > 1280; + bool get smAndUp => isSm || isMd || isLg || isXl || is2Xl; bool get mdAndUp => isMd || isLg || isXl || is2Xl; bool get lgAndUp => isLg || isXl || is2Xl; bool get xlAndUp => isXl || is2Xl; + + bool get smAndDown => isXs || isSm; + bool get mdAndDown => isXs || isSm || isMd; + bool get lgAndDown => isXs || isSm || isMd || isLg; + bool get xlAndDown => isXs || isSm || isMd || isLg || isXl; } diff --git a/lib/hooks/use_breakpoint_value.dart b/lib/hooks/use_breakpoint_value.dart index 854af39a..b2592124 100644 --- a/lib/hooks/use_breakpoint_value.dart +++ b/lib/hooks/use_breakpoint_value.dart @@ -3,6 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:spotube/extensions/constrains.dart'; T useBreakpointValue({ + T? xs, T? sm, T? md, T? lg, @@ -10,8 +11,12 @@ T useBreakpointValue({ T? xxl, T? others, }) { - final isSomeNull = - sm == null || md == null || lg == null || xl == null || xxl == null; + final isSomeNull = xs == null || + sm == null || + md == null || + lg == null || + xl == null || + xxl == null; assert( (isSomeNull && others != null) || (!isSomeNull && others == null), 'You must provide a value for all breakpoints or a default value for others', @@ -20,7 +25,9 @@ T useBreakpointValue({ final mediaQuery = MediaQuery.of(context); if (isSomeNull) { - if (mediaQuery.isSm) { + if (mediaQuery.isXs) { + return xs ?? others!; + } else if (mediaQuery.isSm) { return sm ?? others!; } else if (mediaQuery.isMd) { return md ?? others!; @@ -32,7 +39,9 @@ T useBreakpointValue({ return lg ?? others!; } } else { - if (mediaQuery.isSm) { + if (mediaQuery.isXs) { + return xs; + } else if (mediaQuery.isSm) { return sm; } else if (mediaQuery.isMd) { return md; diff --git a/lib/pages/album/album.dart b/lib/pages/album/album.dart index ca04d726..69b542ee 100644 --- a/lib/pages/album/album.dart +++ b/lib/pages/album/album.dart @@ -4,7 +4,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/shared/heart_button.dart'; -import 'package:spotube/components/shared/track_table/track_collection_view.dart'; +import 'package:spotube/components/shared/track_table/track_collection_view/track_collection_view.dart'; import 'package:spotube/components/shared/track_table/tracks_table_view.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; @@ -67,7 +67,7 @@ class AlbumPage extends HookConsumerWidget { tracksSnapshot: tracksSnapshot, album: album, routePath: "/album/${album.id}", - bottomSpace: mediaQuery.isSm || mediaQuery.isMd, + bottomSpace: mediaQuery.mdAndDown, onPlay: ([track]) { if (tracksSnapshot.hasData) { if (!isAlbumPlaying) { diff --git a/lib/pages/artist/artist.dart b/lib/pages/artist/artist.dart index 865c43bc..44e40423 100644 --- a/lib/pages/artist/artist.dart +++ b/lib/pages/artist/artist.dart @@ -39,6 +39,7 @@ class ArtistPage extends HookConsumerWidget { final scaffoldMessenger = ScaffoldMessenger.of(context); final textTheme = theme.textTheme; final chipTextVariant = useBreakpointValue( + xs: textTheme.bodySmall, sm: textTheme.bodySmall, md: textTheme.bodyMedium, lg: textTheme.bodyLarge, @@ -49,6 +50,7 @@ class ArtistPage extends HookConsumerWidget { final mediaQuery = MediaQuery.of(context); final avatarWidth = useBreakpointValue( + xs: mediaQuery.size.width * 0.50, sm: mediaQuery.size.width * 0.50, md: mediaQuery.size.width * 0.40, lg: mediaQuery.size.width * 0.18, @@ -155,7 +157,7 @@ class ArtistPage extends HookConsumerWidget { ), Text( data.name!, - style: mediaQuery.isSm + style: mediaQuery.smAndDown ? textTheme.headlineSmall : textTheme.headlineMedium, ), @@ -166,8 +168,9 @@ class ArtistPage extends HookConsumerWidget { ), ), style: textTheme.bodyMedium?.copyWith( - fontWeight: - mediaQuery.isSm ? null : FontWeight.bold, + fontWeight: mediaQuery.mdAndUp + ? FontWeight.bold + : null, ), ), const SizedBox(height: 20), diff --git a/lib/pages/desktop_login/desktop_login.dart b/lib/pages/desktop_login/desktop_login.dart index 02f580f0..c2cc3695 100644 --- a/lib/pages/desktop_login/desktop_login.dart +++ b/lib/pages/desktop_login/desktop_login.dart @@ -35,7 +35,7 @@ class DesktopLoginPage extends HookConsumerWidget { children: [ Assets.spotubeLogoPng.image( width: MediaQuery.of(context).size.width * - (mediaQuery.isSm || mediaQuery.isMd ? .5 : .3), + (mediaQuery.mdAndDown ? .5 : .3), ), Text( context.l10n.add_spotify_credentials, diff --git a/lib/pages/playlist/playlist.dart b/lib/pages/playlist/playlist.dart index 15cc246b..170d9693 100644 --- a/lib/pages/playlist/playlist.dart +++ b/lib/pages/playlist/playlist.dart @@ -2,7 +2,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/components/shared/heart_button.dart'; -import 'package:spotube/components/shared/track_table/track_collection_view.dart'; +import 'package:spotube/components/shared/track_table/track_collection_view/track_collection_view.dart'; import 'package:spotube/components/shared/track_table/tracks_table_view.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/models/logger.dart'; @@ -99,7 +99,7 @@ class PlaylistView extends HookConsumerWidget { playlistNotifier.addTracks(tracksSnapshot.data!); } }, - bottomSpace: mediaQuery.isSm || mediaQuery.isMd, + bottomSpace: mediaQuery.mdAndDown, showShare: playlist.id != "user-liked-tracks", routePath: "/playlist/${playlist.id}", onShare: () {