diff --git a/lib/components/player/player_track_details.dart b/lib/components/player/player_track_details.dart index 2c400e986..b44a6d225 100644 --- a/lib/components/player/player_track_details.dart +++ b/lib/components/player/player_track_details.dart @@ -4,7 +4,7 @@ import 'package:spotify/spotify.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; @@ -17,7 +17,7 @@ class PlayerTrackDetails extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final theme = Theme.of(context); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final playback = ref.watch(ProxyPlaylistNotifier.provider); return Row( @@ -37,7 +37,7 @@ class PlayerTrackDetails extends HookConsumerWidget { ), ), ), - if (breakpoint.isLessThanOrEqualTo(Breakpoints.md)) + if (mediaQuery.isSm || mediaQuery.isMd) Flexible( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -60,7 +60,7 @@ class PlayerTrackDetails extends HookConsumerWidget { ], ), ), - if (breakpoint.isMoreThan(Breakpoints.md)) + if (mediaQuery.lgAndUp) Flexible( flex: 1, child: Column( diff --git a/lib/components/root/bottom_player.dart b/lib/components/root/bottom_player.dart index e453696fa..d1c9ca625 100644 --- a/lib/components/root/bottom_player.dart +++ b/lib/components/root/bottom_player.dart @@ -12,8 +12,8 @@ import 'package:spotube/components/player/player_actions.dart'; import 'package:spotube/components/player/player_overlay.dart'; import 'package:spotube/components/player/player_track_details.dart'; import 'package:spotube/components/player/player_controls.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; import 'package:spotube/hooks/use_brightness_value.dart'; import 'package:spotube/models/logger.dart'; import 'package:flutter/material.dart'; @@ -33,7 +33,7 @@ class BottomPlayer extends HookConsumerWidget { final layoutMode = ref.watch(userPreferencesProvider.select((s) => s.layoutMode)); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); String albumArt = useMemoized( () => playlist.activeTrack?.album?.images?.isNotEmpty == true @@ -57,7 +57,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 || - (breakpoint.isLessThanOrEqualTo(Breakpoints.md) && + ((mediaQuery.isSm || mediaQuery.isMd) && layoutMode == LayoutMode.adaptive)) { return PlayerOverlay(albumArt: albumArt); } diff --git a/lib/components/root/sidebar.dart b/lib/components/root/sidebar.dart index 3bbb2d606..b6c90e77b 100644 --- a/lib/components/root/sidebar.dart +++ b/lib/components/root/sidebar.dart @@ -9,8 +9,8 @@ import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/side_bar_tiles.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; import 'package:spotube/hooks/use_brightness_value.dart'; import 'package:spotube/hooks/use_sidebarx_controller.dart'; import 'package:spotube/provider/download_manager_provider.dart'; @@ -49,7 +49,7 @@ class Sidebar extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final breakpoints = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final downloadCount = ref.watch( downloadManagerProvider.select((s) => s.length), @@ -60,7 +60,7 @@ class Sidebar extends HookConsumerWidget { final controller = useSidebarXController( selectedIndex: selectedIndex, - extended: breakpoints > Breakpoints.md, + extended: mediaQuery.lgAndUp, ); final theme = Theme.of(context); @@ -82,16 +82,16 @@ class Sidebar extends HookConsumerWidget { }, [controller]); useEffect(() { - if (breakpoints > Breakpoints.md && !controller.extended) { + if (mediaQuery.lgAndUp && !controller.extended) { controller.setExtended(true); - } else if (breakpoints <= Breakpoints.md && controller.extended) { + } else if ((mediaQuery.isSm || mediaQuery.isMd) && controller.extended) { controller.setExtended(false); } return null; - }, [breakpoints, controller]); + }, [mediaQuery, controller]); if (layoutMode == LayoutMode.compact || - (breakpoints.isSm && layoutMode == LayoutMode.adaptive)) { + (mediaQuery.isSm && layoutMode == LayoutMode.adaptive)) { return Scaffold(body: child); } @@ -183,10 +183,10 @@ class SidebarHeader extends HookWidget { @override Widget build(BuildContext context) { - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final theme = Theme.of(context); - if (breakpoint <= Breakpoints.md) { + if (mediaQuery.isSm || mediaQuery.isMd) { return Container( height: 40, width: 40, @@ -224,7 +224,7 @@ class SidebarFooter extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final theme = Theme.of(context); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final me = useQueries.user.me(ref); final data = me.data; @@ -236,7 +236,7 @@ class SidebarFooter extends HookConsumerWidget { final auth = ref.watch(AuthenticationNotifier.provider); - if (breakpoint <= Breakpoints.md) { + if (mediaQuery.isSm || mediaQuery.isMd) { return IconButton( icon: const Icon(SpotubeIcons.settings), onPressed: () => Sidebar.goToSettings(context), diff --git a/lib/components/root/spotube_navigation_bar.dart b/lib/components/root/spotube_navigation_bar.dart index 2bf4dfc69..111e7dd59 100644 --- a/lib/components/root/spotube_navigation_bar.dart +++ b/lib/components/root/spotube_navigation_bar.dart @@ -7,8 +7,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/collections/side_bar_tiles.dart'; import 'package:spotube/components/root/sidebar.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; import 'package:spotube/hooks/use_brightness_value.dart'; import 'package:spotube/provider/download_manager_provider.dart'; import 'package:spotube/provider/user_preferences_provider.dart'; @@ -29,7 +29,7 @@ class SpotubeNavigationBar extends HookConsumerWidget { final downloadCount = ref.watch( downloadManagerProvider.select((s) => s.length), ); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final layoutMode = ref.watch(userPreferencesProvider.select((s) => s.layoutMode)); @@ -49,8 +49,9 @@ class SpotubeNavigationBar extends HookConsumerWidget { }, [selectedIndex]); if (layoutMode == LayoutMode.extended || - (breakpoint.isMoreThan(Breakpoints.sm) && - layoutMode == LayoutMode.adaptive)) return const SizedBox(); + (mediaQuery.mdAndUp && layoutMode == LayoutMode.adaptive)) { + return const SizedBox(); + } return ClipRect( child: BackdropFilter( diff --git a/lib/components/shared/adaptive/adaptive_list_tile.dart b/lib/components/shared/adaptive/adaptive_list_tile.dart index c648bc381..965250a4e 100644 --- a/lib/components/shared/adaptive/adaptive_list_tile.dart +++ b/lib/components/shared/adaptive/adaptive_list_tile.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; - -import 'package:spotube/hooks/use_breakpoints.dart'; +import 'package:spotube/extensions/constrains.dart'; class AdaptiveListTile extends HookWidget { final Widget Function(BuildContext, StateSetter?)? trailing; @@ -9,7 +8,7 @@ class AdaptiveListTile extends HookWidget { final Widget? subtitle; final Widget? leading; final void Function()? onTap; - final Breakpoints breakOn; + final bool? breakOn; const AdaptiveListTile({ super.key, @@ -18,20 +17,20 @@ class AdaptiveListTile extends HookWidget { this.title, this.subtitle, this.leading, - this.breakOn = Breakpoints.md, + this.breakOn , }); @override Widget build(BuildContext context) { - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); return ListTile( title: title, subtitle: subtitle, trailing: - breakpoint.isLessThan(breakOn) ? null : trailing?.call(context, null), + breakOn ?? mediaQuery.isSm ? null : trailing?.call(context, null), leading: leading, - onTap: breakpoint.isLessThan(breakOn) + onTap: breakOn ?? mediaQuery.isSm ? () { onTap?.call(); showDialog( diff --git a/lib/components/shared/adaptive/adaptive_popup_menu_button.dart b/lib/components/shared/adaptive/adaptive_popup_menu_button.dart index c9b557e61..45f22825b 100644 --- a/lib/components/shared/adaptive/adaptive_popup_menu_button.dart +++ b/lib/components/shared/adaptive/adaptive_popup_menu_button.dart @@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:popover/popover.dart'; import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; +import 'package:spotube/extensions/constrains.dart'; class Action extends StatelessWidget { final Widget text; @@ -49,18 +49,18 @@ class Action extends StatelessWidget { class AdaptiveActions extends HookWidget { final List actions; - final Breakpoints breakOn; + final bool? breakOn; const AdaptiveActions({ required this.actions, - this.breakOn = Breakpoints.lg, + this.breakOn, super.key, }); @override Widget build(BuildContext context) { - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); - if (breakpoint.isLessThan(breakOn)) { + if (breakOn ?? mediaQuery.lgAndUp) { return IconButton( icon: const Icon(SpotubeIcons.moreHorizontal), onPressed: () { diff --git a/lib/components/shared/adaptive/adaptive_select_tile.dart b/lib/components/shared/adaptive/adaptive_select_tile.dart index 0a44697d6..17e652b71 100644 --- a/lib/components/shared/adaptive/adaptive_select_tile.dart +++ b/lib/components/shared/adaptive/adaptive_select_tile.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; +import 'package:spotube/extensions/constrains.dart'; class AdaptiveSelectTile extends HookWidget { final Widget title; @@ -12,8 +12,6 @@ class AdaptiveSelectTile extends HookWidget { final List> options; - final Breakpoints breakAfterOr; - /// Show the smaller value when the breakpoint is reached /// /// If false, the control will be hidden when the breakpoint is reached @@ -21,6 +19,8 @@ class AdaptiveSelectTile extends HookWidget { /// Defaults to `true` final bool showValueWhenUnfolded; + final bool? breakLayout; + const AdaptiveSelectTile({ required this.title, required this.value, @@ -29,7 +29,7 @@ class AdaptiveSelectTile extends HookWidget { this.controlAffinity = ListTileControlAffinity.trailing, this.subtitle, this.secondary, - this.breakAfterOr = Breakpoints.md, + this.breakLayout, this.showValueWhenUnfolded = true, super.key, }); @@ -37,7 +37,7 @@ class AdaptiveSelectTile extends HookWidget { @override Widget build(BuildContext context) { final theme = Theme.of(context); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final rawControl = DropdownButton( items: options, value: value, @@ -55,7 +55,7 @@ class AdaptiveSelectTile extends HookWidget { .child, [value, options]); - final control = breakpoint >= breakAfterOr + final control = breakLayout ?? mediaQuery.mdAndUp ? rawControl : showValueWhenUnfolded ? Container( @@ -85,7 +85,7 @@ class AdaptiveSelectTile extends HookWidget { trailing: controlAffinity == ListTileControlAffinity.leading ? secondary : control, - onTap: breakpoint >= breakAfterOr + onTap: breakLayout ?? mediaQuery.mdAndUp ? null : () { showDialog( diff --git a/lib/components/shared/shimmers/shimmer_lyrics.dart b/lib/components/shared/shimmers/shimmer_lyrics.dart index 37a241ea2..fd88ac6ba 100644 --- a/lib/components/shared/shimmers/shimmer_lyrics.dart +++ b/lib/components/shared/shimmers/shimmer_lyrics.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:skeleton_text/skeleton_text.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/theme.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; const widths = [20, 56, 89, 60, 25, 69]; @@ -21,7 +21,7 @@ class ShimmerLyrics extends HookWidget { final shimmerBackgroundColor = shimmerTheme.shimmerBackgroundColor ?? Colors.grey; - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); return ListView.builder( itemCount: 20, @@ -29,10 +29,10 @@ class ShimmerLyrics extends HookWidget { physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { final widthsCp = [...widths]; - if (breakpoint.isMd) { + if (mediaQuery.isMd) { widthsCp.removeLast(); } - if (breakpoint.isSm) { + if (mediaQuery.isSm) { widthsCp.removeLast(); widthsCp.removeLast(); } diff --git a/lib/components/shared/track_table/track_tile.dart b/lib/components/shared/track_table/track_tile.dart index ffbc07429..d6e5bd541 100644 --- a/lib/components/shared/track_table/track_tile.dart +++ b/lib/components/shared/track_table/track_tile.dart @@ -10,8 +10,8 @@ import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/heart_button.dart'; import 'package:spotube/components/shared/links/link_text.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; import 'package:spotube/models/logger.dart'; import 'package:spotube/provider/authentication_provider.dart'; import 'package:spotube/provider/blacklist_provider.dart'; @@ -66,7 +66,7 @@ class TrackTile extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final theme = Theme.of(context); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final isBlackListed = ref.watch( BlackListNotifier.provider.select( (blacklist) => blacklist.contains( @@ -233,7 +233,7 @@ class TrackTile extends HookConsumerWidget { ), Padding( padding: EdgeInsets.symmetric( - horizontal: breakpoint.isMoreThan(Breakpoints.md) ? 8.0 : 0, + horizontal: mediaQuery.lgAndUp ? 8.0 : 0, vertical: 8.0, ), child: ClipRRect( @@ -278,7 +278,7 @@ class TrackTile extends HookConsumerWidget { track.value.name ?? "", style: TextStyle( fontWeight: FontWeight.bold, - fontSize: breakpoint.isSm ? 14 : 17, + fontSize: mediaQuery.isSm ? 14 : 17, ), overflow: TextOverflow.ellipsis, ), @@ -304,13 +304,13 @@ class TrackTile extends HookConsumerWidget { : TypeConversionUtils.artists_X_ClickableArtists( track.value.artists ?? [], textStyle: TextStyle( - fontSize: breakpoint.isLessThan(Breakpoints.lg) + fontSize: mediaQuery.isSm || mediaQuery.isMd ? 12 : 14)), ], ), ), - if (breakpoint.isMoreThan(Breakpoints.md) && showAlbum) + if (mediaQuery.lgAndUp && showAlbum) Expanded( child: isLocal ? Text(track.value.album?.name ?? "") @@ -321,7 +321,7 @@ class TrackTile extends HookConsumerWidget { overflow: TextOverflow.ellipsis, ), ), - if (!breakpoint.isSm) ...[ + if (!mediaQuery.isSm) ...[ const SizedBox(width: 10), Text(duration), ], diff --git a/lib/components/shared/track_table/tracks_table_view.dart b/lib/components/shared/track_table/tracks_table_view.dart index ae6dbdf58..3fbd317e2 100644 --- a/lib/components/shared/track_table/tracks_table_view.dart +++ b/lib/components/shared/track_table/tracks_table_view.dart @@ -10,8 +10,9 @@ import 'package:spotube/components/shared/fallbacks/not_found.dart'; import 'package:spotube/components/shared/sort_tracks_dropdown.dart'; import 'package:spotube/components/shared/track_table/track_tile.dart'; import 'package:spotube/components/library/user_local_tracks.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; + import 'package:spotube/provider/download_manager_provider.dart'; import 'package:spotube/provider/blacklist_provider.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; @@ -48,7 +49,7 @@ class TracksTableView extends HookConsumerWidget { TextStyle tableHeadStyle = const TextStyle(fontWeight: FontWeight.bold, fontSize: 16); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final selected = useState>([]); final showCheck = useState(false); @@ -106,7 +107,7 @@ class TracksTableView extends HookConsumerWidget { ), ), // used alignment of this table-head - if (breakpoint.isMoreThan(Breakpoints.md)) ...[ + if (mediaQuery.lgAndUp) ...[ const SizedBox(width: 100), Expanded( child: Row( @@ -120,7 +121,7 @@ class TracksTableView extends HookConsumerWidget { ), ) ], - if (!breakpoint.isSm) ...[ + if (!mediaQuery.isSm) ...[ const SizedBox(width: 10), Text(context.l10n.time, style: tableHeadStyle), const SizedBox(width: 10), diff --git a/lib/extensions/constrains.dart b/lib/extensions/constrains.dart index 361ec799c..b36087c4c 100644 --- a/lib/extensions/constrains.dart +++ b/lib/extensions/constrains.dart @@ -5,7 +5,7 @@ extension ContainerBreakpoints on BoxConstraints { 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 && biggest.width <= 1536; + bool get is2Xl => biggest.width > 1280; bool get mdAndUp => isMd || isLg || isXl || is2Xl; bool get lgAndUp => isLg || isXl || is2Xl; @@ -17,7 +17,7 @@ extension ScreenBreakpoints on MediaQueryData { 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 && size.width <= 1536; + bool get is2Xl => size.width > 1280; bool get mdAndUp => isMd || isLg || isXl || is2Xl; bool get lgAndUp => isLg || isXl || is2Xl; diff --git a/lib/hooks/use_breakpoint_value.dart b/lib/hooks/use_breakpoint_value.dart index e7abf08b6..854af39a0 100644 --- a/lib/hooks/use_breakpoint_value.dart +++ b/lib/hooks/use_breakpoint_value.dart @@ -1,4 +1,6 @@ -import 'package:spotube/hooks/use_breakpoints.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:spotube/extensions/constrains.dart'; T useBreakpointValue({ T? sm, @@ -14,28 +16,29 @@ T useBreakpointValue({ (isSomeNull && others != null) || (!isSomeNull && others == null), 'You must provide a value for all breakpoints or a default value for others', ); - final breakpoint = useBreakpoints(); + final context = useContext(); + final mediaQuery = MediaQuery.of(context); if (isSomeNull) { - if (breakpoint.isSm) { + if (mediaQuery.isSm) { return sm ?? others!; - } else if (breakpoint.isMd) { + } else if (mediaQuery.isMd) { return md ?? others!; - } else if (breakpoint.isXl) { + } else if (mediaQuery.isXl) { return xl ?? others!; - } else if (breakpoint.isXxl) { + } else if (mediaQuery.is2Xl) { return xxl ?? others!; } else { return lg ?? others!; } } else { - if (breakpoint.isSm) { + if (mediaQuery.isSm) { return sm; - } else if (breakpoint.isMd) { + } else if (mediaQuery.isMd) { return md; - } else if (breakpoint.isXl) { + } else if (mediaQuery.isXl) { return xl; - } else if (breakpoint.isXxl) { + } else if (mediaQuery.is2Xl) { return xxl; } else { return lg; diff --git a/lib/hooks/use_breakpoints.dart b/lib/hooks/use_breakpoints.dart deleted file mode 100644 index 7177ed8d8..000000000 --- a/lib/hooks/use_breakpoints.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; - -class BreakpointUtils { - Breakpoints breakpoint; - List breakpointList = [ - Breakpoints.sm, - Breakpoints.md, - Breakpoints.lg, - Breakpoints.xl, - Breakpoints.xxl - ]; - BreakpointUtils(this.breakpoint); - - bool get isSm => breakpoint == Breakpoints.sm; - bool get isMd => breakpoint == Breakpoints.md; - bool get isLg => breakpoint == Breakpoints.lg; - bool get isXl => breakpoint == Breakpoints.xl; - bool get isXxl => breakpoint == Breakpoints.xxl; - - bool isMoreThanOrEqualTo(Breakpoints b) { - return breakpointList - .sublist(breakpointList.indexOf(b)) - .contains(breakpoint); - } - - bool isLessThanOrEqualTo(Breakpoints b) { - return breakpointList - .sublist(0, breakpointList.indexOf(b) + 1) - .contains(breakpoint); - } - - bool isMoreThan(Breakpoints b) { - return breakpointList - .sublist(breakpointList.indexOf(b) + 1) - .contains(breakpoint); - } - - bool isLessThan(Breakpoints b) { - return breakpointList - .sublist(0, breakpointList.indexOf(b)) - .contains(breakpoint); - } - - bool operator >(other) { - return isMoreThan(other); - } - - bool operator <(other) { - return isLessThan(other); - } - - bool operator >=(other) { - return isMoreThanOrEqualTo(other); - } - - bool operator <=(other) { - return isLessThanOrEqualTo(other); - } - - @override - String toString() { - return "BreakpointUtils($breakpoint)"; - } -} - -enum Breakpoints { sm, md, lg, xl, xxl } - -BreakpointUtils useBreakpoints() { - final context = useContext(); - final width = MediaQuery.of(context).size.width; - final breakpoint = useState(Breakpoints.lg); - final utils = BreakpointUtils(breakpoint.value); - - useEffect(() { - if (width > 1920 && breakpoint.value != Breakpoints.xxl) { - breakpoint.value = Breakpoints.xxl; - } else if (width > 1366 && - width <= 1920 && - breakpoint.value != Breakpoints.xl) { - breakpoint.value = Breakpoints.xl; - } else if (width > 800 && - width <= 1366 && - breakpoint.value != Breakpoints.lg) { - breakpoint.value = Breakpoints.lg; - } else if (width > 500 && - width <= 800 && - breakpoint.value != Breakpoints.md) { - breakpoint.value = Breakpoints.md; - } else if (width >= 250 && - width <= 500 && - breakpoint.value != Breakpoints.sm) { - breakpoint.value = Breakpoints.sm; - } - return null; - }, [width]); - - useEffect(() { - utils.breakpoint = breakpoint.value; - return null; - }, [breakpoint.value]); - - return utils; -} diff --git a/lib/pages/album/album.dart b/lib/pages/album/album.dart index 322524d84..ca04d726f 100644 --- a/lib/pages/album/album.dart +++ b/lib/pages/album/album.dart @@ -6,7 +6,7 @@ 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/tracks_table_view.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/services/queries/queries.dart'; import 'package:spotube/utils/service_utils.dart'; @@ -53,7 +53,7 @@ class AlbumPage extends HookConsumerWidget { ), [album.images]); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final isAlbumPlaying = useMemoized( () => playlist.containsTracks(tracksSnapshot.data ?? []), @@ -67,7 +67,7 @@ class AlbumPage extends HookConsumerWidget { tracksSnapshot: tracksSnapshot, album: album, routePath: "/album/${album.id}", - bottomSpace: breakpoint.isLessThanOrEqualTo(Breakpoints.md), + bottomSpace: mediaQuery.isSm || mediaQuery.isMd, onPlay: ([track]) { if (tracksSnapshot.hasData) { if (!isAlbumPlaying) { diff --git a/lib/pages/artist/artist.dart b/lib/pages/artist/artist.dart index bcf3e3f67..62cb3e24d 100644 --- a/lib/pages/artist/artist.dart +++ b/lib/pages/artist/artist.dart @@ -12,9 +12,9 @@ import 'package:spotube/components/shared/track_table/track_tile.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/components/artist/artist_album_list.dart'; import 'package:spotube/components/artist/artist_card.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/hooks/use_breakpoint_value.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; import 'package:spotube/models/logger.dart'; import 'package:spotube/provider/authentication_provider.dart'; import 'package:spotube/provider/blacklist_provider.dart'; @@ -55,8 +55,6 @@ class ArtistPage extends HookConsumerWidget { xxl: mediaQuery.size.width * 0.18, ); - final breakpoint = useBreakpoints(); - final playlistNotifier = ref.watch(ProxyPlaylistNotifier.notifier); final playlist = ref.watch(ProxyPlaylistNotifier.provider); @@ -154,7 +152,7 @@ class ArtistPage extends HookConsumerWidget { ), Text( data.name!, - style: breakpoint.isSm + style: mediaQuery.isSm ? textTheme.headlineSmall : textTheme.headlineMedium, ), @@ -166,7 +164,7 @@ class ArtistPage extends HookConsumerWidget { ), style: textTheme.bodyMedium?.copyWith( fontWeight: - breakpoint.isSm ? null : FontWeight.bold, + mediaQuery.isSm ? null : FontWeight.bold, ), ), const SizedBox(height: 20), diff --git a/lib/pages/desktop_login/desktop_login.dart b/lib/pages/desktop_login/desktop_login.dart index bb9fed346..02f580f0c 100644 --- a/lib/pages/desktop_login/desktop_login.dart +++ b/lib/pages/desktop_login/desktop_login.dart @@ -5,15 +5,15 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/components/desktop_login/login_form.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; class DesktopLoginPage extends HookConsumerWidget { const DesktopLoginPage({Key? key}) : super(key: key); @override Widget build(BuildContext context, ref) { - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final theme = Theme.of(context); final color = theme.colorScheme.surfaceVariant.withOpacity(.3); @@ -35,7 +35,7 @@ class DesktopLoginPage extends HookConsumerWidget { children: [ Assets.spotubeLogoPng.image( width: MediaQuery.of(context).size.width * - (breakpoint <= Breakpoints.md ? .5 : .3), + (mediaQuery.isSm || mediaQuery.isMd ? .5 : .3), ), Text( context.l10n.add_spotify_credentials, diff --git a/lib/pages/lyrics/lyrics.dart b/lib/pages/lyrics/lyrics.dart index fb1f01799..d4c29449d 100644 --- a/lib/pages/lyrics/lyrics.dart +++ b/lib/pages/lyrics/lyrics.dart @@ -9,8 +9,8 @@ import 'package:spotube/components/shared/fallbacks/anonymous_fallback.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/themed_button_tab_bar.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; import 'package:spotube/hooks/use_custom_status_bar_color.dart'; import 'package:spotube/hooks/use_palette_color.dart'; import 'package:spotube/pages/lyrics/plain_lyrics.dart'; @@ -36,7 +36,7 @@ class LyricsPage extends HookConsumerWidget { [playlist.activeTrack?.album?.images], ); final palette = usePaletteColor(albumArt, ref); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); useCustomStatusBarColor( palette.color, @@ -117,7 +117,7 @@ class LyricsPage extends HookConsumerWidget { return DefaultTabController( length: 2, child: SafeArea( - bottom: breakpoint > Breakpoints.md, + bottom: mediaQuery.mdAndUp, child: Scaffold( extendBodyBehindAppBar: true, appBar: !kIsMacOS diff --git a/lib/pages/lyrics/plain_lyrics.dart b/lib/pages/lyrics/plain_lyrics.dart index 609a46921..eadb2efe5 100644 --- a/lib/pages/lyrics/plain_lyrics.dart +++ b/lib/pages/lyrics/plain_lyrics.dart @@ -6,7 +6,8 @@ import 'package:palette_generator/palette_generator.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/lyrics/zoom_controls.dart'; import 'package:spotube/components/shared/shimmers/shimmer_lyrics.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; +import 'package:spotube/extensions/constrains.dart'; + import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/services/queries/queries.dart'; @@ -26,11 +27,9 @@ class PlainLyrics extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final playlist = ref.watch(ProxyPlaylistNotifier.provider); - final lyricsQuery = useQueries.lyrics.spotifySynced( - ref, - playlist?.activeTrack, - ); - final breakpoint = useBreakpoints(); + final lyricsQuery = + useQueries.lyrics.spotifySynced(ref, playlist.activeTrack); + final mediaQuery = MediaQuery.of(context); final textTheme = Theme.of(context).textTheme; final textZoomLevel = useState(defaultTextZoom); @@ -44,7 +43,7 @@ class PlainLyrics extends HookConsumerWidget { Center( child: Text( playlist.activeTrack?.name ?? "", - style: breakpoint >= Breakpoints.md + style: mediaQuery.mdAndUp ? textTheme.displaySmall : textTheme.headlineMedium?.copyWith( fontSize: 25, @@ -56,7 +55,7 @@ class PlainLyrics extends HookConsumerWidget { child: Text( TypeConversionUtils.artists_X_String( playlist.activeTrack?.artists ?? []), - style: (breakpoint >= Breakpoints.md + style: (mediaQuery.mdAndUp ? textTheme.headlineSmall : textTheme.titleLarge) ?.copyWith(color: palette.bodyTextColor), diff --git a/lib/pages/lyrics/synced_lyrics.dart b/lib/pages/lyrics/synced_lyrics.dart index 49a36a728..51464fd30 100644 --- a/lib/pages/lyrics/synced_lyrics.dart +++ b/lib/pages/lyrics/synced_lyrics.dart @@ -6,8 +6,8 @@ import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/lyrics/zoom_controls.dart'; import 'package:spotube/components/shared/shimmers/shimmer_lyrics.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/hooks/use_auto_scroll_controller.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; import 'package:spotube/hooks/use_synced_lyrics.dart'; import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; @@ -33,13 +33,13 @@ class SyncedLyrics extends HookConsumerWidget { Widget build(BuildContext context, ref) { final playlist = ref.watch(ProxyPlaylistNotifier.provider); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final controller = useAutoScrollController(); final delay = ref.watch(_delay); final timedLyricsQuery = - useQueries.lyrics.spotifySynced(ref, playlist?.activeTrack); + useQueries.lyrics.spotifySynced(ref, playlist.activeTrack); final lyricValue = timedLyricsQuery.data; @@ -63,9 +63,9 @@ class SyncedLyrics extends HookConsumerWidget { ref.read(_delay.notifier).state = 0; }); return null; - }, [playlist?.activeTrack]); + }, [playlist.activeTrack]); - final headlineTextStyle = (breakpoint >= Breakpoints.md + final headlineTextStyle = (mediaQuery.mdAndUp ? textTheme.displaySmall : textTheme.headlineMedium?.copyWith(fontSize: 25)) ?.copyWith(color: palette.titleTextColor); @@ -86,7 +86,7 @@ class SyncedLyrics extends HookConsumerWidget { child: Text( TypeConversionUtils.artists_X_String( playlist.activeTrack?.artists ?? []), - style: breakpoint >= Breakpoints.md + style: mediaQuery.mdAndUp ? textTheme.headlineSmall : textTheme.titleLarge, ), @@ -139,7 +139,7 @@ class SyncedLyrics extends HookConsumerWidget { }, ), ), - if (playlist?.activeTrack != null && + if (playlist.activeTrack != null && (lyricValue == null || lyricValue.lyrics.isEmpty == true)) const Expanded(child: ShimmerLyrics()), ], diff --git a/lib/pages/player/player.dart b/lib/pages/player/player.dart index 6f96a99aa..2831b71a5 100644 --- a/lib/pages/player/player.dart +++ b/lib/pages/player/player.dart @@ -12,7 +12,7 @@ import 'package:spotube/components/player/player_controls.dart'; import 'package:spotube/components/shared/animated_gradient.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/hooks/use_custom_status_bar_color.dart'; import 'package:spotube/hooks/use_palette_color.dart'; import 'package:spotube/models/local_track.dart'; @@ -36,16 +36,16 @@ class PlayerView extends HookConsumerWidget { final isLocalTrack = ref.watch(ProxyPlaylistNotifier.provider.select( (value) => value.activeTrack is LocalTrack, )); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); useEffect(() { - if (breakpoint.isMoreThan(Breakpoints.md)) { + if (mediaQuery.lgAndUp) { WidgetsBinding.instance.addPostFrameCallback((_) { GoRouter.of(context).pop(); }); } return null; - }, [breakpoint]); + }, [mediaQuery.lgAndUp]); String albumArt = useMemoized( () => TypeConversionUtils.image_X_UrlString( diff --git a/lib/pages/playlist/playlist.dart b/lib/pages/playlist/playlist.dart index 9a5db13a6..15cc246bf 100644 --- a/lib/pages/playlist/playlist.dart +++ b/lib/pages/playlist/playlist.dart @@ -4,7 +4,7 @@ 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/tracks_table_view.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/models/logger.dart'; import 'package:flutter/material.dart'; import 'package:spotify/spotify.dart'; @@ -48,7 +48,7 @@ class PlaylistView extends HookConsumerWidget { final proxyPlaylist = ref.watch(ProxyPlaylistNotifier.provider); final playlistNotifier = ref.watch(ProxyPlaylistNotifier.notifier); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final meSnapshot = useQueries.user.me(ref); final tracksSnapshot = useQueries.playlist.tracksOfQuery(ref, playlist.id!); @@ -99,7 +99,7 @@ class PlaylistView extends HookConsumerWidget { playlistNotifier.addTracks(tracksSnapshot.data!); } }, - bottomSpace: breakpoint.isLessThanOrEqualTo(Breakpoints.md), + bottomSpace: mediaQuery.isSm || mediaQuery.isMd, showShare: playlist.id != "user-liked-tracks", routePath: "/playlist/${playlist.id}", onShare: () { diff --git a/lib/pages/search/search.dart b/lib/pages/search/search.dart index 68fb71b17..13a0f496c 100644 --- a/lib/pages/search/search.dart +++ b/lib/pages/search/search.dart @@ -16,8 +16,8 @@ import 'package:spotube/components/shared/track_table/track_tile.dart'; import 'package:spotube/components/shared/waypoint.dart'; import 'package:spotube/components/artist/artist_card.dart'; import 'package:spotube/components/playlist/playlist_card.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; import 'package:spotube/provider/authentication_provider.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/services/queries/queries.dart'; @@ -41,7 +41,7 @@ class SearchPage extends HookConsumerWidget { final albumController = useScrollController(); final playlistController = useScrollController(); final artistController = useScrollController(); - final breakpoint = useBreakpoints(); + final mediaQuery = MediaQuery.of(context); final searchTerm = ref.watch(searchTermStateProvider); @@ -216,10 +216,9 @@ class SearchPage extends HookConsumerWidget { }, ), child: Scrollbar( - scrollbarOrientation: - breakpoint > Breakpoints.md - ? ScrollbarOrientation.bottom - : ScrollbarOrientation.top, + scrollbarOrientation: mediaQuery.lgAndUp + ? ScrollbarOrientation.bottom + : ScrollbarOrientation.top, controller: playlistController, child: Waypoint( onTouchEdge: () { diff --git a/lib/pages/settings/settings.dart b/lib/pages/settings/settings.dart index 0ba031ee6..39e7d2bb1 100644 --- a/lib/pages/settings/settings.dart +++ b/lib/pages/settings/settings.dart @@ -16,8 +16,8 @@ import 'package:spotube/components/shared/adaptive/adaptive_list_tile.dart'; import 'package:spotube/components/shared/adaptive/adaptive_select_tile.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; import 'package:spotube/collections/spotify_markets.dart'; +import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; -import 'package:spotube/hooks/use_breakpoints.dart'; import 'package:spotube/l10n/l10n.dart'; import 'package:spotube/provider/download_manager_provider.dart'; import 'package:spotube/provider/authentication_provider.dart'; @@ -35,6 +35,7 @@ class SettingsPage extends HookConsumerWidget { final isDownloading = ref.watch(downloadManagerProvider.select((s) => s.isNotEmpty)); final theme = Theme.of(context); + final mediaQuery = MediaQuery.of(context); final pickColorScheme = useCallback(() { return () => showDialog( @@ -169,7 +170,7 @@ class SettingsPage extends HookConsumerWidget { ], ), AdaptiveSelectTile( - breakAfterOr: Breakpoints.lg, + breakLayout: mediaQuery.lgAndUp, secondary: const Icon(SpotubeIcons.shoppingBag), title: Text(context.l10n.market_place_region), subtitle: Text(context.l10n.recommendation_country),