From a4927c7013c83727a40333d4744e46bfcb022e58 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 9 Mar 2023 23:24:09 +0600 Subject: [PATCH 1/3] refactor: working dissect of platform_ui --- lib/collections/spotube_icons.dart | 12 +- lib/components/artist/artist_card.dart | 66 +--- lib/components/desktop_login/login_form.dart | 24 +- lib/components/genre/category_card.dart | 10 +- lib/components/library/user_albums.dart | 13 +- lib/components/library/user_artists.dart | 18 +- lib/components/library/user_downloads.dart | 19 +- lib/components/library/user_local_tracks.dart | 6 +- lib/components/library/user_playlists.dart | 11 +- lib/components/lyrics/zoom_controls.dart | 12 +- lib/components/player/player_actions.dart | 8 +- lib/components/player/player_controls.dart | 26 +- lib/components/player/player_overlay.dart | 3 +- lib/components/player/player_queue.dart | 26 +- .../player/player_track_details.dart | 6 +- .../player/sibling_tracks_sheet.dart | 19 +- .../playlist/playlist_create_dialog.dart | 84 ++--- lib/components/root/bottom_player.dart | 50 +-- lib/components/root/sidebar.dart | 167 +++------- .../root/spotube_navigation_bar.dart | 23 +- .../settings/color_scheme_picker_dialog.dart | 52 +-- .../shared/adaptive/adaptive_list_tile.dart | 12 +- .../adaptive/adaptive_popup_menu_button.dart | 19 +- lib/components/shared/compact_search.dart | 17 +- .../dialogs/confirm_download_dialog.dart | 60 +--- .../dialogs/playlist_add_track_dialog.dart | 59 +--- .../shared/dialogs/prompt_dialog.dart | 51 +-- .../dialogs/replace_downloaded_dialog.dart | 60 +--- .../shared/fallbacks/anonymous_fallback.dart | 8 +- lib/components/shared/heart_button.dart | 10 +- .../shared/links/anchor_button.dart | 3 +- .../shared/page_window_title_bar.dart | 124 +++---- lib/components/shared/playbutton_card.dart | 113 ++----- .../shimmers/shimmer_artist_profile.dart | 4 +- .../shared/shimmers/shimmer_categories.dart | 4 +- .../shared/shimmers/shimmer_lyrics.dart | 4 +- .../shimmers/shimmer_playbutton_card.dart | 4 +- .../shared/shimmers/shimmer_track_tile.dart | 4 +- .../shared/sort_tracks_dropdown.dart | 70 ++-- lib/components/shared/spotube_page_route.dart | 28 +- .../track_table/track_collection_view.dart | 101 +++--- .../shared/track_table/track_tile.dart | 189 ++++++----- .../shared/track_table/tracks_table_view.dart | 67 ++-- lib/hooks/use_custom_status_bar_color.dart | 3 +- lib/hooks/use_platform_property.dart | 10 - lib/hooks/use_update_checker.dart | 18 +- lib/main.dart | 48 +-- lib/pages/artist/artist.dart | 96 +++--- lib/pages/desktop_login/desktop_login.dart | 23 +- lib/pages/desktop_login/login_tutorial.dart | 40 ++- lib/pages/home/home.dart | 83 ++--- lib/pages/home/personalized.dart | 7 +- lib/pages/library/library.dart | 68 ++-- lib/pages/lyrics/lyrics.dart | 172 +++++----- lib/pages/mobile_login/mobile_login.dart | 4 +- lib/pages/player/player.dart | 55 ++-- lib/pages/root/root_app.dart | 13 +- lib/pages/search/search.dart | 66 ++-- lib/pages/settings/about.dart | 31 +- lib/pages/settings/blacklist.dart | 30 +- lib/pages/settings/settings.dart | 309 +++++++----------- lib/themes/dark_theme.dart | 120 ------- lib/themes/light_theme.dart | 122 ------- lib/themes/theme.dart | 40 +++ macos/Flutter/GeneratedPluginRegistrant.swift | 2 - pubspec.lock | 88 +---- pubspec.yaml | 8 - 67 files changed, 1145 insertions(+), 1977 deletions(-) delete mode 100644 lib/hooks/use_platform_property.dart delete mode 100644 lib/themes/dark_theme.dart delete mode 100644 lib/themes/light_theme.dart create mode 100644 lib/themes/theme.dart diff --git a/lib/collections/spotube_icons.dart b/lib/collections/spotube_icons.dart index 2866cb8f..3d259491 100644 --- a/lib/collections/spotube_icons.dart +++ b/lib/collections/spotube_icons.dart @@ -1,13 +1,13 @@ -import 'package:fluent_ui/fluent_ui.dart'; +import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:flutter_feather_icons/flutter_feather_icons.dart'; abstract class SpotubeIcons { - static const home = FluentIcons.home; + static const home = FluentIcons.home_12_regular; static const search = FeatherIcons.search; - static const library = FluentIcons.library; + static const library = FluentIcons.library_16_regular; static const music = FeatherIcons.music; - static const play = FluentIcons.play; + static const play = FluentIcons.play_12_regular; static const pause = FeatherIcons.pause; static const skipForward = FeatherIcons.skipForward; static const skipBack = FeatherIcons.skipBack; @@ -16,8 +16,8 @@ abstract class SpotubeIcons { static const refresh = FeatherIcons.refreshCw; static const settings = FeatherIcons.settings; static const shuffle = FeatherIcons.shuffle; - static const repeat = FluentIcons.repeat_all; - static const repeatOne = FluentIcons.repeat_one; + static const repeat = FluentIcons.arrow_repeat_all_16_regular; + static const repeatOne = Icons.repeat_one_rounded; static const remove = FeatherIcons.minus; static const removeFilled = FeatherIcons.minusCircle; static const add = FeatherIcons.plus; diff --git a/lib/components/artist/artist_card.dart b/lib/components/artist/artist_card.dart index 86743fde..49b75150 100644 --- a/lib/components/artist/artist_card.dart +++ b/lib/components/artist/artist_card.dart @@ -1,12 +1,10 @@ import 'package:auto_size_text/auto_size_text.dart'; -import 'package:fluent_ui/fluent_ui.dart' hide Colors; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/components/shared/hover_builder.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; -import 'package:spotube/hooks/use_platform_property.dart'; import 'package:spotube/provider/blacklist_provider.dart'; import 'package:spotube/utils/service_utils.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; @@ -30,75 +28,35 @@ class ArtistCard extends HookConsumerWidget { ), ), ); - final boxShadow = usePlatformProperty( - (context) => PlatformProperty( - android: BoxShadow( - blurRadius: 10, - offset: const Offset(0, 3), - spreadRadius: 5, - color: Theme.of(context).colorScheme.shadow, - ), - ios: null, - macos: null, - linux: BoxShadow( - blurRadius: 6, - color: Theme.of(context).shadowColor.withOpacity(0.3), - ), - windows: null, - ), - ); - - final splash = usePlatformProperty( - (context) => PlatformProperty.only( - android: InkRipple.splashFactory, - other: NoSplash.splashFactory, - ), - ); return SizedBox( height: 240, width: 200, child: InkWell( - splashFactory: splash, onTap: () { ServiceUtils.navigate(context, "/artist/${artist.id}"); }, - customBorder: platform == TargetPlatform.windows - ? Border.all( - color: FluentTheme.maybeOf(context) - ?.micaBackgroundColor - .withOpacity(.7) ?? - Colors.transparent, - width: 1, - ) - : null, - borderRadius: BorderRadius.circular( - platform == TargetPlatform.windows ? 5 : 8, - ), + borderRadius: BorderRadius.circular(8), child: HoverBuilder(builder: (context, isHovering) { return Ink( width: 200, decoration: BoxDecoration( - color: PlatformTheme.of(context).secondaryBackgroundColor, - borderRadius: BorderRadius.circular( - platform == TargetPlatform.windows ? 5 : 8, - ), + color: Theme.of(context).cardColor, + borderRadius: BorderRadius.circular(8), boxShadow: [ - if (boxShadow != null) boxShadow, + BoxShadow( + blurRadius: 10, + offset: const Offset(0, 3), + spreadRadius: 5, + color: Theme.of(context).colorScheme.shadow, + ), ], border: isBlackListed ? Border.all( color: Colors.red[400]!, width: 2, ) - : [TargetPlatform.windows, TargetPlatform.macOS] - .contains(platform) - ? Border.all( - color: PlatformTheme.of(context).borderColor ?? - Colors.transparent, - width: 1, - ) - : null, + : null, ), child: Padding( padding: const EdgeInsets.all(15), @@ -138,7 +96,7 @@ class ArtistCard extends HookConsumerWidget { artist.name!, maxLines: 2, textAlign: TextAlign.center, - style: PlatformTextTheme.of(context).body?.copyWith( + style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.bold, ), ), diff --git a/lib/components/desktop_login/login_form.dart b/lib/components/desktop_login/login_form.dart index 3ee493a6..fe7c222f 100644 --- a/lib/components/desktop_login/login_form.dart +++ b/lib/components/desktop_login/login_form.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/provider/authentication_provider.dart'; class TokenLoginForm extends HookConsumerWidget { @@ -25,27 +25,31 @@ class TokenLoginForm extends HookConsumerWidget { ), child: Column( children: [ - PlatformTextField( + TextField( controller: directCodeController, - placeholder: "Spotify \"sp_dc\" Cookie", - label: "sp_dc Cookie", + decoration: const InputDecoration( + hintText: "Spotify \"sp_dc\" Cookie", + labelText: "sp_dc Cookie", + ), keyboardType: TextInputType.visiblePassword, ), const SizedBox(height: 10), - PlatformTextField( + TextField( controller: keyCodeController, - placeholder: "Spotify \"sp_key\" Cookie", - label: "sp_key Cookie", + decoration: const InputDecoration( + hintText: "Spotify \"sp_key\" Cookie", + labelText: "sp_key Cookie", + ), keyboardType: TextInputType.visiblePassword, ), const SizedBox(height: 20), - PlatformFilledButton( + FilledButton( onPressed: () async { if (keyCodeController.text.isEmpty || directCodeController.text.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( - content: PlatformText("Please fill in all fields"), + content: Text("Please fill in all fields"), behavior: SnackBarBehavior.floating, ), ); @@ -61,7 +65,7 @@ class TokenLoginForm extends HookConsumerWidget { onDone?.call(); } }, - child: const PlatformText("Submit"), + child: const Text("Submit"), ) ], ), diff --git a/lib/components/genre/category_card.dart b/lib/components/genre/category_card.dart index 5b2bbf9c..264c5ef9 100644 --- a/lib/components/genre/category_card.dart +++ b/lib/components/genre/category_card.dart @@ -2,7 +2,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart' hide Page; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/components/shared/shimmers/shimmer_playbutton_card.dart'; import 'package:spotube/components/shared/waypoint.dart'; @@ -39,13 +39,15 @@ class CategoryCard extends HookConsumerWidget { padding: const EdgeInsets.all(8.0), child: Row( children: [ - PlatformText.headline(category.name ?? "Unknown"), + Text( + category.name ?? "Unknown", + style: Theme.of(context).textTheme.titleLarge, + ), ], ), ), playlistQuery.hasPageError && !playlistQuery.hasPageData - ? PlatformText( - "Something Went Wrong\n${playlistQuery.errors.first}") + ? Text("Something Went Wrong\n${playlistQuery.errors.first}") : SizedBox( height: 245, child: ScrollConfiguration( diff --git a/lib/components/library/user_albums.dart b/lib/components/library/user_albums.dart index ebcaa9dc..3c4a409b 100644 --- a/lib/components/library/user_albums.dart +++ b/lib/components/library/user_albums.dart @@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:collection/collection.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/album/album_card.dart'; import 'package:spotube/components/shared/playbutton_card.dart'; @@ -65,16 +65,17 @@ class UserAlbums extends HookConsumerWidget { physics: const AlwaysScrollableScrollPhysics(), child: Material( type: MaterialType.transparency, - textStyle: PlatformTheme.of(context).textTheme!.body!, - color: PlatformTheme.of(context).scaffoldBackgroundColor, + color: Theme.of(context).scaffoldBackgroundColor, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ - PlatformTextField( + TextField( onChanged: (value) => searchText.value = value, - prefixIcon: SpotubeIcons.filter, - placeholder: 'Filter Albums...', + decoration: const InputDecoration( + prefixIcon: Icon(SpotubeIcons.filter), + hintText: 'Filter albums...', + ), ), const SizedBox(height: 20), Wrap( diff --git a/lib/components/library/user_artists.dart b/lib/components/library/user_artists.dart index a522b7f4..ccabb0c6 100644 --- a/lib/components/library/user_artists.dart +++ b/lib/components/library/user_artists.dart @@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:collection/collection.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/fallbacks/anonymous_fallback.dart'; @@ -56,25 +56,27 @@ class UserArtists extends HookConsumerWidget { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: ColoredBox( - color: PlatformTheme.of(context).scaffoldBackgroundColor!, - child: PlatformTextField( + color: Theme.of(context).scaffoldBackgroundColor, + child: TextField( onChanged: (value) => searchText.value = value, - prefixIcon: SpotubeIcons.filter, - placeholder: 'Filter artists...', + decoration: const InputDecoration( + prefixIcon: Icon(SpotubeIcons.filter), + hintText: 'Filter artists...', + ), ), ), ), ), - backgroundColor: PlatformTheme.of(context).scaffoldBackgroundColor, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, body: artistQuery.pages.isEmpty ? Padding( padding: const EdgeInsets.all(20), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: const [ - PlatformCircularProgressIndicator(), + CircularProgressIndicator(), SizedBox(width: 10), - PlatformText("Loading..."), + Text("Loading..."), ], ), ) diff --git a/lib/components/library/user_downloads.dart b/lib/components/library/user_downloads.dart index d0da5d33..44249e93 100644 --- a/lib/components/library/user_downloads.dart +++ b/lib/components/library/user_downloads.dart @@ -1,7 +1,7 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/provider/downloader_provider.dart'; @@ -26,20 +26,19 @@ class UserDownloads extends HookConsumerWidget { child: AutoSizeText( "Currently downloading (${downloader.currentlyRunning})", maxLines: 1, - style: PlatformTextTheme.of(context).headline, + style: Theme.of(context).textTheme.headlineMedium, ), ), const SizedBox(width: 10), - PlatformFilledButton( - style: ButtonStyle( - backgroundColor: MaterialStatePropertyAll(Colors.red[50]), - foregroundColor: MaterialStatePropertyAll(Colors.red[400]), + FilledButton( + style: FilledButton.styleFrom( + backgroundColor: Colors.red[50], + foregroundColor: Colors.red[400], ), onPressed: downloader.currentlyRunning > 0 ? downloader.cancelAll : null, - isSecondary: true, - child: const PlatformText("Cancel All"), + child: const Text("Cancel All"), ), ], ), @@ -49,7 +48,7 @@ class UserDownloads extends HookConsumerWidget { itemCount: downloader.inQueue.length, itemBuilder: (context, index) { final track = downloader.inQueue.elementAt(index); - return PlatformListTile( + return ListTile( title: Text(track.name ?? ''), leading: Padding( padding: const EdgeInsets.symmetric(horizontal: 5), @@ -68,7 +67,7 @@ class UserDownloads extends HookConsumerWidget { trailing: const SizedBox( width: 30, height: 30, - child: PlatformCircularProgressIndicator(), + child: CircularProgressIndicator(), ), subtitle: Text( TypeConversionUtils.artists_X_String( diff --git a/lib/components/library/user_local_tracks.dart b/lib/components/library/user_local_tracks.dart index 9db22b92..65778fce 100644 --- a/lib/components/library/user_local_tracks.dart +++ b/lib/components/library/user_local_tracks.dart @@ -12,7 +12,7 @@ import 'package:mime/mime.dart'; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/compact_search.dart'; @@ -189,7 +189,7 @@ class UserLocalTracks extends HookConsumerWidget { child: Row( children: [ const SizedBox(width: 10), - PlatformFilledButton( + FilledButton( onPressed: trackSnapshot.value != null ? () { if (trackSnapshot.value?.isNotEmpty == true) { @@ -221,7 +221,7 @@ class UserLocalTracks extends HookConsumerWidget { }, ), const SizedBox(width: 10), - PlatformFilledButton( + FilledButton( child: const Icon(SpotubeIcons.refresh), onPressed: () { ref.refresh(localTracksProvider); diff --git a/lib/components/library/user_playlists.dart b/lib/components/library/user_playlists.dart index d618b3e1..80137964 100644 --- a/lib/components/library/user_playlists.dart +++ b/lib/components/library/user_playlists.dart @@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:collection/collection.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/playlist/playlist_create_dialog.dart'; @@ -94,15 +94,16 @@ class UserPlaylists extends HookConsumerWidget { physics: const AlwaysScrollableScrollPhysics(), child: Material( type: MaterialType.transparency, - textStyle: PlatformTheme.of(context).textTheme!.body!, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ - PlatformTextField( + TextField( onChanged: (value) => searchText.value = value, - placeholder: "Filter your playlists...", - prefixIcon: SpotubeIcons.filter, + decoration: const InputDecoration( + hintText: "Filter your playlists...", + prefixIcon: Icon(SpotubeIcons.filter), + ), ), const SizedBox(height: 20), if (playlistsQuery.isLoading || !playlistsQuery.hasData) diff --git a/lib/components/lyrics/zoom_controls.dart b/lib/components/lyrics/zoom_controls.dart index 6b26616a..f50ea71d 100644 --- a/lib/components/lyrics/zoom_controls.dart +++ b/lib/components/lyrics/zoom_controls.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/spotube_icons.dart'; class ZoomControls extends HookWidget { @@ -32,15 +32,15 @@ class ZoomControls extends HookWidget { @override Widget build(BuildContext context) { final actions = [ - PlatformIconButton( + IconButton( icon: decreaseIcon, onPressed: () { if (value == min) return; onChanged(value - interval); }, ), - PlatformText("$value$unit"), - PlatformIconButton( + Text("$value$unit"), + IconButton( icon: increaseIcon, onPressed: () { if (value == max) return; @@ -51,9 +51,7 @@ class ZoomControls extends HookWidget { return Container( decoration: BoxDecoration( - color: PlatformTheme.of(context) - .secondaryBackgroundColor - ?.withOpacity(0.7), + color: Theme.of(context).cardColor.withOpacity(0.7), borderRadius: BorderRadius.circular(10), ), constraints: BoxConstraints( diff --git a/lib/components/player/player_actions.dart b/lib/components/player/player_actions.dart index 10be9f29..a667a068 100644 --- a/lib/components/player/player_actions.dart +++ b/lib/components/player/player_actions.dart @@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/player/player_queue.dart'; @@ -54,7 +54,7 @@ class PlayerActions extends HookConsumerWidget { return Row( mainAxisAlignment: mainAxisAlignment, children: [ - PlatformIconButton( + IconButton( icon: const Icon(SpotubeIcons.queue), tooltip: 'Queue', onPressed: playlist != null @@ -80,7 +80,7 @@ class PlayerActions extends HookConsumerWidget { : null, ), if (!isLocalTrack) - PlatformIconButton( + IconButton( icon: const Icon(SpotubeIcons.alternativeRoute), tooltip: "Alternative Track Sources", onPressed: playlist?.activeTrack != null @@ -115,7 +115,7 @@ class PlayerActions extends HookConsumerWidget { ), ) else - PlatformIconButton( + IconButton( tooltip: 'Download track', icon: Icon( isDownloaded ? SpotubeIcons.done : SpotubeIcons.download, diff --git a/lib/components/player/player_controls.dart b/lib/components/player/player_controls.dart index 5c041e5e..73e0fc9f 100644 --- a/lib/components/player/player_controls.dart +++ b/lib/components/player/player_controls.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/collections/intents.dart'; import 'package:spotube/models/logger.dart'; @@ -106,9 +106,9 @@ class PlayerControls extends HookConsumerWidget { return Column( children: [ - PlatformTooltip( + Tooltip( message: "Slide to seek forward or backward", - child: PlatformSlider( + child: Slider( // cannot divide by zero // there's an edge case for value being bigger // than total duration. Keeping it resolved @@ -135,10 +135,10 @@ class PlayerControls extends HookConsumerWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - PlatformText( + Text( "$currentMinutes:$currentSeconds", ), - PlatformText("$totalMinutes:$totalSeconds"), + Text("$totalMinutes:$totalSeconds"), ], ), ), @@ -149,14 +149,14 @@ class PlayerControls extends HookConsumerWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - PlatformIconButton( + IconButton( tooltip: playlist?.isShuffled == true ? "Unshuffle playlist" : "Shuffle playlist", icon: Icon( SpotubeIcons.shuffle, color: playlist?.isShuffled == true - ? PlatformTheme.of(context).primaryColor + ? Theme.of(context).primaryColor : null, ), onPressed: playlist == null @@ -169,7 +169,7 @@ class PlayerControls extends HookConsumerWidget { } }, ), - PlatformIconButton( + IconButton( tooltip: "Previous track", icon: Icon( SpotubeIcons.skipBack, @@ -177,13 +177,13 @@ class PlayerControls extends HookConsumerWidget { ), onPressed: playlistNotifier.previous, ), - PlatformIconButton( + IconButton( tooltip: playing ? "Pause playback" : "Resume playback", icon: playlist?.isLoading == true ? const SizedBox( height: 20, width: 20, - child: PlatformCircularProgressIndicator(), + child: CircularProgressIndicator(), ) : Icon( playing ? SpotubeIcons.pause : SpotubeIcons.play, @@ -194,7 +194,7 @@ class PlayerControls extends HookConsumerWidget { PlayPauseIntent(ref), ), ), - PlatformIconButton( + IconButton( tooltip: "Next track", icon: Icon( SpotubeIcons.skipForward, @@ -202,7 +202,7 @@ class PlayerControls extends HookConsumerWidget { ), onPressed: playlistNotifier.next, ), - PlatformIconButton( + IconButton( tooltip: playlist?.isLooping != true ? "Loop Track" : "Repeat playlist", @@ -211,7 +211,7 @@ class PlayerControls extends HookConsumerWidget { ? SpotubeIcons.repeatOne : SpotubeIcons.repeat, color: playlist?.isLooping == true - ? PlatformTheme.of(context).primaryColor + ? Theme.of(context).primaryColor : null, ), onPressed: playlist == null || playlist.isLoading diff --git a/lib/components/player/player_overlay.dart b/lib/components/player/player_overlay.dart index 553bb783..6877362e 100644 --- a/lib/components/player/player_overlay.dart +++ b/lib/components/player/player_overlay.dart @@ -4,7 +4,7 @@ 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:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/player/player_track_details.dart'; import 'package:spotube/hooks/use_palette_color.dart'; @@ -59,7 +59,6 @@ class PlayerOverlay extends HookConsumerWidget { duration: const Duration(milliseconds: 250), opacity: canShow ? 1 : 0, child: Material( - textStyle: PlatformTheme.of(context).textTheme!.body!, type: MaterialType.transparency, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, diff --git a/lib/components/player/player_queue.dart b/lib/components/player/player_queue.dart index c72967fb..c0a9b6ac 100644 --- a/lib/components/player/player_queue.dart +++ b/lib/components/player/player_queue.dart @@ -3,7 +3,7 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/fallbacks/not_found.dart'; @@ -36,8 +36,7 @@ class PlayerQueue extends HookConsumerWidget { topLeft: Radius.circular(10), topRight: Radius.circular(10), ); - final headlineColor = - PlatformTheme.of(context).textTheme?.subheading?.color; + final headlineColor = Theme.of(context).textTheme.headlineSmall?.color; useEffect(() { if (playlist == null) return null; @@ -61,9 +60,7 @@ class PlayerQueue extends HookConsumerWidget { top: 5.0, ), decoration: BoxDecoration( - color: PlatformTheme.of(context) - .scaffoldBackgroundColor - ?.withOpacity(0.5), + color: Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5), borderRadius: borderRadius, ), child: Column( @@ -80,7 +77,7 @@ class PlayerQueue extends HookConsumerWidget { Row( children: [ const SizedBox(width: 10), - PlatformText( + Text( "${tracks.length} tracks in Queue", style: TextStyle( color: headlineColor, @@ -89,14 +86,13 @@ class PlayerQueue extends HookConsumerWidget { ), ), const Spacer(), - PlatformFilledButton( - style: ButtonStyle( - backgroundColor: MaterialStatePropertyAll( - PlatformTheme.of(context) - .scaffoldBackgroundColor - ?.withOpacity(0.5)), - foregroundColor: MaterialStatePropertyAll( - PlatformTheme.of(context).textTheme?.subheading?.color), + FilledButton( + style: FilledButton.styleFrom( + backgroundColor: Theme.of(context) + .scaffoldBackgroundColor + .withOpacity(0.5), + foregroundColor: + Theme.of(context).textTheme.headlineSmall?.color, ), child: Row( children: const [ diff --git a/lib/components/player/player_track_details.dart b/lib/components/player/player_track_details.dart index 26df2ba7..f8878443 100644 --- a/lib/components/player/player_track_details.dart +++ b/lib/components/player/player_track_details.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/hooks/use_breakpoints.dart'; @@ -37,7 +37,7 @@ class PlayerTrackDetails extends HookConsumerWidget { ), if (breakpoint.isLessThanOrEqualTo(Breakpoints.md)) Flexible( - child: PlatformText( + child: Text( playback?.activeTrack.name ?? "Not playing", overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.bold, color: color), @@ -50,7 +50,7 @@ class PlayerTrackDetails extends HookConsumerWidget { flex: 1, child: Column( children: [ - PlatformText( + Text( playback?.activeTrack.name ?? "Not playing", overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.bold, color: color), diff --git a/lib/components/player/sibling_tracks_sheet.dart b/lib/components/player/sibling_tracks_sheet.dart index 683ec23a..96f4502d 100644 --- a/lib/components/player/sibling_tracks_sheet.dart +++ b/lib/components/player/sibling_tracks_sheet.dart @@ -3,7 +3,7 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/models/spotube_track.dart'; import 'package:spotube/provider/playlist_queue_provider.dart'; @@ -50,16 +50,15 @@ class SiblingTracksSheet extends HookConsumerWidget { margin: const EdgeInsets.all(8.0), decoration: BoxDecoration( borderRadius: borderRadius, - color: PlatformTheme.of(context) - .scaffoldBackgroundColor! - .withOpacity(.3), + color: Theme.of(context).scaffoldBackgroundColor.withOpacity(.3), ), child: Scaffold( backgroundColor: Colors.transparent, - appBar: PlatformAppBar( + appBar: AppBar( centerTitle: true, - title: PlatformText.subheading( + title: Text( 'Alternative Tracks Sources', + style: Theme.of(context).textTheme.headlineSmall, ), automaticallyImplyLeading: false, backgroundColor: Colors.transparent, @@ -71,8 +70,8 @@ class SiblingTracksSheet extends HookConsumerWidget { itemCount: siblings.length, itemBuilder: (context, index) { final video = siblings[index]; - return PlatformListTile( - title: PlatformText(video.title), + return ListTile( + title: Text(video.title), leading: Padding( padding: const EdgeInsets.all(8.0), child: UniversalImage( @@ -84,12 +83,12 @@ class SiblingTracksSheet extends HookConsumerWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), - trailing: PlatformText( + trailing: Text( PrimitiveUtils.toReadableDuration( video.duration ?? Duration.zero, ), ), - subtitle: PlatformText(video.author), + subtitle: Text(video.author), enabled: playlist?.isLoading != true, selected: playlist?.isLoading != true && video.id.value == diff --git a/lib/components/playlist/playlist_create_dialog.dart b/lib/components/playlist/playlist_create_dialog.dart index 9dad8bc3..82f71dd8 100644 --- a/lib/components/playlist/playlist_create_dialog.dart +++ b/lib/components/playlist/playlist_create_dialog.dart @@ -1,11 +1,9 @@ import 'package:fl_query_hooks/fl_query_hooks.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/spotube_icons.dart'; -import 'package:spotube/components/root/sidebar.dart'; import 'package:spotube/provider/spotify_provider.dart'; class PlaylistCreateDialog extends HookConsumerWidget { @@ -17,10 +15,10 @@ class PlaylistCreateDialog extends HookConsumerWidget { return SizedBox( width: 200, - child: PlatformTextButton( + child: TextButton( onPressed: () { - showPlatformAlertDialog( - context, + showDialog( + context: context, builder: (context) { return HookBuilder(builder: (context) { final playlistName = useTextEditingController(); @@ -48,48 +46,18 @@ class PlaylistCreateDialog extends HookConsumerWidget { navigator.pop(); } - return PlatformAlertDialog( - macosAppIcon: Sidebar.brandLogo(), - title: const PlatformText("Create a Playlist"), - primaryActions: [ - PlatformBuilder( - fallback: PlatformBuilderFallback.android, - android: (context, _) { - return PlatformFilledButton( - onPressed: onCreate, - child: const Text("Create"), - ); - }, - ios: (context, data) { - return CupertinoDialogAction( - isDefaultAction: true, - onPressed: onCreate, - child: const Text("Create"), - ); + return AlertDialog( + title: const Text("Create a Playlist"), + actions: [ + OutlinedButton( + child: const Text("Cancel"), + onPressed: () { + Navigator.pop(context); }, ), - ], - secondaryActions: [ - PlatformBuilder( - fallback: PlatformBuilderFallback.android, - android: (context, _) { - return PlatformFilledButton( - isSecondary: true, - child: const Text("Cancel"), - onPressed: () { - Navigator.pop(context); - }, - ); - }, - ios: (context, data) { - return CupertinoDialogAction( - onPressed: () { - Navigator.pop(context); - }, - isDestructiveAction: true, - child: const Text("Cancel"), - ); - }, + FilledButton( + onPressed: onCreate, + child: const Text("Create"), ), ], content: Container( @@ -98,28 +66,32 @@ class PlaylistCreateDialog extends HookConsumerWidget { child: ListView( shrinkWrap: true, children: [ - PlatformTextField( + TextField( controller: playlistName, - placeholder: "Name of the playlist", - label: "Playlist Name", + decoration: const InputDecoration( + hintText: "Name of the playlist", + labelText: "Playlist Name", + ), ), const SizedBox(height: 10), - PlatformTextField( + TextField( controller: description, - placeholder: "Description...", + decoration: const InputDecoration( + hintText: "Description...", + ), keyboardType: TextInputType.multiline, maxLines: 5, ), const SizedBox(height: 10), - PlatformCheckbox( + CheckboxListTile( + title: const Text("Public"), value: public.value, - label: const PlatformText("Public"), onChanged: (val) => public.value = val ?? false, ), const SizedBox(height: 10), - PlatformCheckbox( + CheckboxListTile( + title: const Text("Collaborative"), value: collaborative.value, - label: const PlatformText("Collaborative"), onChanged: (val) => collaborative.value = val ?? false, ), @@ -141,7 +113,7 @@ class PlaylistCreateDialog extends HookConsumerWidget { mainAxisAlignment: MainAxisAlignment.center, children: const [ Icon(SpotubeIcons.addFilled, size: 40), - PlatformText("Create Playlist", style: TextStyle(fontSize: 20)), + Text("Create Playlist", style: TextStyle(fontSize: 20)), ], ), ), diff --git a/lib/components/root/bottom_player.dart b/lib/components/root/bottom_player.dart index 92f23ff3..226dd09f 100644 --- a/lib/components/root/bottom_player.dart +++ b/lib/components/root/bottom_player.dart @@ -1,17 +1,13 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:macos_ui/macos_ui.dart'; -import 'package:fluent_ui/fluent_ui.dart' as fluent_ui; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/assets.gen.dart'; 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/hooks/use_breakpoints.dart'; -import 'package:spotube/hooks/use_platform_property.dart'; import 'package:spotube/models/logger.dart'; import 'package:flutter/material.dart'; import 'package:spotube/provider/playlist_queue_provider.dart'; @@ -52,51 +48,13 @@ class BottomPlayer extends HookConsumerWidget { ); } - final backgroundColor = usePlatformProperty( - (context) => PlatformProperty( - android: Theme.of(context).backgroundColor, - ios: CupertinoTheme.of(context).scaffoldBackgroundColor, - macos: MacosTheme.of(context).brightness == Brightness.dark - ? Colors.grey[800] - : Colors.blueGrey[50], - linux: Theme.of(context).backgroundColor, - windows: fluent_ui.FluentTheme.maybeOf(context)?.micaBackgroundColor, - ), - ); - - final border = usePlatformProperty( - (context) => PlatformProperty( - android: null, - ios: Border( - top: BorderSide( - color: PlatformTheme.of(context).borderColor ?? Colors.transparent, - width: 1, - ), - ), - macos: Border( - top: BorderSide( - color: PlatformTheme.of(context).borderColor ?? Colors.transparent, - width: 1, - ), - ), - linux: Border( - top: BorderSide( - color: PlatformTheme.of(context).borderColor ?? Colors.transparent, - width: 1, - ), - ), - windows: null, - ), - ); - return DecoratedBox( decoration: BoxDecoration( - color: backgroundColor, - border: border, + color: Theme.of(context).colorScheme.background, ), child: Material( type: MaterialType.transparency, - textStyle: PlatformTheme.of(context).textTheme!.body!, + textStyle: Theme.of(context).textTheme.bodyMedium!, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -141,7 +99,7 @@ class BottomPlayer extends HookConsumerWidget { } } }, - child: PlatformSlider( + child: Slider( min: 0, max: 1, value: volume.value, diff --git a/lib/components/root/sidebar.dart b/lib/components/root/sidebar.dart index e8197b76..9c572b28 100644 --- a/lib/components/root/sidebar.dart +++ b/lib/components/root/sidebar.dart @@ -1,9 +1,8 @@ -import 'package:badges/badges.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' hide Badge; -import 'package:platform_ui/platform_ui.dart'; +import 'package:flutter/material.dart'; + import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/side_bar_tiles.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -16,7 +15,6 @@ import 'package:spotube/provider/user_preferences_provider.dart'; import 'package:spotube/services/queries/queries.dart'; import 'package:spotube/utils/platform.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; -import 'package:fluent_ui/fluent_ui.dart' as fluent_ui; class Sidebar extends HookConsumerWidget { final int selectedIndex; @@ -57,127 +55,64 @@ class Sidebar extends HookConsumerWidget { final layoutMode = ref.watch(userPreferencesProvider.select((s) => s.layoutMode)); - if (breakpoints.isMd) { - return Row( - children: [ - NavigationRail( - selectedIndex: selectedIndex, - onDestinationSelected: onSelectedIndexChanged, - labelType: NavigationRailLabelType.all, - extended: false, - backgroundColor: PlatformTheme.of(context).scaffoldBackgroundColor, - leading: Column( - children: [ - if (kIsMacOS) macSpacer, - brandLogo(), - ], - ), - trailing: PlatformIconButton( - icon: const Icon(fluent_ui.FluentIcons.settings), - onPressed: () => goToSettings(context), - ), - destinations: [ - for (final e in sidebarTileList) - NavigationRailDestination( - icon: Badge( - badgeColor: PlatformTheme.of(context).primaryColor!, - showBadge: e.title == "Library" && downloadCount > 0, - badgeContent: Text( - downloadCount.toString(), - style: const TextStyle( - color: Colors.white, - fontSize: 10, - ), - ), - child: Icon(e.icon), - ), - label: PlatformText.label( - e.title, - style: selectedIndex == sidebarTileList.indexOf(e) - ? TextStyle( - color: PlatformTheme.of(context).primaryColor, - fontWeight: FontWeight.bold, - ) - : null, - ), - ), - ], - ), - Container( - width: 1, - height: double.infinity, - color: PlatformTheme.of(context).borderColor, - ), - Expanded(child: child) - ], - ); - } - if (layoutMode == LayoutMode.compact || (breakpoints.isSm && layoutMode == LayoutMode.adaptive)) { - return PlatformScaffold(body: child); + return Scaffold(body: child); } - return SafeArea( - top: false, - child: PlatformSidebar( - currentIndex: selectedIndex, - onIndexChanged: onSelectedIndexChanged, - body: Map.fromEntries( - sidebarTileList.map( + return Row( + children: [ + NavigationRail( + selectedIndex: selectedIndex, + onDestinationSelected: onSelectedIndexChanged, + destinations: sidebarTileList.map( (e) { - final icon = Icon(e.icon); - return MapEntry( - PlatformSidebarItem( - icon: Badge( - badgeColor: PlatformTheme.of(context).primaryColor!, - showBadge: e.title == "Library" && downloadCount > 0, - badgeContent: Text( - downloadCount.toString(), - style: const TextStyle( - color: Colors.white, - fontSize: 10, - ), - ), - child: icon, - ), - title: Text( - e.title, + return NavigationRailDestination( + icon: Badge( + backgroundColor: Theme.of(context).primaryColor, + isLabelVisible: e.title == "Library" && downloadCount > 0, + label: Text( + downloadCount.toString(), style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, + color: Colors.white, + fontSize: 10, ), ), + child: Icon(e.icon), + ), + label: Text( + e.title, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), ), - child, ); }, + ).toList(), + extended: true, + leading: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + if (kIsMacOS) macSpacer, + Row( + children: [ + brandLogo(), + const SizedBox(width: 10), + Text( + "Spotube", + style: Theme.of(context).textTheme.titleLarge, + ), + ], + ), + ], + ), ), + trailing: const SidebarFooter(), ), - expanded: true, - header: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - if (kIsMacOS) macSpacer, - Row( - children: [ - brandLogo(), - const SizedBox(width: 10), - PlatformText.headline("Spotube"), - ], - ), - ], - ), - ), - windowsFooterItems: [ - fluent_ui.PaneItemAction( - icon: const Icon(SpotubeIcons.settings), - onTap: () => goToSettings(context), - ), - ], - footer: const SidebarFooter(), - ), + Expanded(child: child) + ], ); } } @@ -211,7 +146,7 @@ class SidebarFooter extends HookConsumerWidget { children: [ if (auth != null && data == null) const Center( - child: PlatformCircularProgressIndicator(), + child: CircularProgressIndicator(), ) else if (data != null) Flexible( @@ -236,16 +171,16 @@ class SidebarFooter extends HookConsumerWidget { maxLines: 1, softWrap: false, overflow: TextOverflow.fade, - style: PlatformTheme.of(context) + style: Theme.of(context) .textTheme - ?.body + .bodyMedium ?.copyWith(fontWeight: FontWeight.bold), ), ), ], ), ), - PlatformIconButton( + 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 bb874401..ff42ea0a 100644 --- a/lib/components/root/spotube_navigation_bar.dart +++ b/lib/components/root/spotube_navigation_bar.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/side_bar_tiles.dart'; import 'package:spotube/components/root/sidebar.dart'; import 'package:spotube/hooks/use_breakpoints.dart'; @@ -37,19 +37,30 @@ class SpotubeNavigationBar extends HookConsumerWidget { if (layoutMode == LayoutMode.extended || (breakpoint.isMoreThan(Breakpoints.sm) && layoutMode == LayoutMode.adaptive)) return const SizedBox(); - return PlatformBottomNavigationBar( + return BottomNavigationBar( items: [ ...navbarTileList.map( (e) { - return PlatformBottomNavigationBarItem( - icon: e.icon, + return BottomNavigationBarItem( + icon: Badge( + backgroundColor: Theme.of(context).primaryColor, + isLabelVisible: e.title == "Library" && downloadCount > 0, + label: Text( + downloadCount.toString(), + style: const TextStyle( + color: Colors.white, + fontSize: 10, + ), + ), + child: Icon(e.icon), + ), label: e.title, ); }, ), ], - selectedIndex: insideSelectedIndex.value, - onSelectedIndexChanged: (i) { + currentIndex: insideSelectedIndex.value, + onTap: (i) { insideSelectedIndex.value = i; if (navbarTileList[i].title == "Settings") { Sidebar.goToSettings(context); diff --git a/lib/components/settings/color_scheme_picker_dialog.dart b/lib/components/settings/color_scheme_picker_dialog.dart index cb4d10b6..735f1e31 100644 --- a/lib/components/settings/color_scheme_picker_dialog.dart +++ b/lib/components/settings/color_scheme_picker_dialog.dart @@ -1,9 +1,7 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; -import 'package:spotube/components/root/sidebar.dart'; + import 'package:spotube/provider/user_preferences_provider.dart'; final colorsMap = { @@ -59,48 +57,18 @@ class ColorSchemePickerDialog extends HookConsumerWidget { Navigator.pop(context); } - return PlatformAlertDialog( - macosAppIcon: Sidebar.brandLogo(), + return AlertDialog( title: Text("Pick ${schemeType.name} color scheme"), - primaryActions: [ - PlatformBuilder( - android: (context, data) { - return PlatformFilledButton( - onPressed: onOk, - child: const Text("Save"), - ); + actions: [ + OutlinedButton( + child: const Text("Cancel"), + onPressed: () { + Navigator.pop(context); }, - ios: (context, data) { - return CupertinoDialogAction( - onPressed: onOk, - isDefaultAction: true, - child: const Text("Save"), - ); - }, - fallback: PlatformBuilderFallback.android, ), - ], - secondaryActions: [ - PlatformBuilder( - fallback: PlatformBuilderFallback.android, - android: (context, _) { - return PlatformFilledButton( - isSecondary: true, - child: const Text("Cancel"), - onPressed: () { - Navigator.pop(context); - }, - ); - }, - ios: (context, data) { - return CupertinoDialogAction( - onPressed: () { - Navigator.pop(context); - }, - isDestructiveAction: true, - child: const Text("Cancel"), - ); - }, + FilledButton( + onPressed: onOk, + child: const Text("Save"), ), ], content: SizedBox( diff --git a/lib/components/shared/adaptive/adaptive_list_tile.dart b/lib/components/shared/adaptive/adaptive_list_tile.dart index 2f69ea9a..c648bc38 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:platform_ui/platform_ui.dart'; -import 'package:spotube/components/root/sidebar.dart'; + import 'package:spotube/hooks/use_breakpoints.dart'; class AdaptiveListTile extends HookWidget { @@ -26,7 +25,7 @@ class AdaptiveListTile extends HookWidget { Widget build(BuildContext context) { final breakpoint = useBreakpoints(); - return PlatformListTile( + return ListTile( title: title, subtitle: subtitle, trailing: @@ -35,13 +34,12 @@ class AdaptiveListTile extends HookWidget { onTap: breakpoint.isLessThan(breakOn) ? () { onTap?.call(); - showPlatformAlertDialog( - context, + showDialog( + context: context, barrierDismissible: true, builder: (context) { return StatefulBuilder(builder: (context, update) { - return PlatformAlertDialog( - macosAppIcon: Sidebar.brandLogo(), + return AlertDialog( title: title != null ? Row( crossAxisAlignment: CrossAxisAlignment.center, diff --git a/lib/components/shared/adaptive/adaptive_popup_menu_button.dart b/lib/components/shared/adaptive/adaptive_popup_menu_button.dart index b6af5350..c9b557e6 100644 --- a/lib/components/shared/adaptive/adaptive_popup_menu_button.dart +++ b/lib/components/shared/adaptive/adaptive_popup_menu_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:popover/popover.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/hooks/use_breakpoints.dart'; @@ -23,12 +23,14 @@ class Action extends StatelessWidget { @override Widget build(BuildContext context) { if (isExpanded != true) { - return PlatformIconButton( + return IconButton( icon: icon, onPressed: onPressed, - backgroundColor: backgroundColor, - tooltip: text is PlatformText - ? (text as PlatformText).data + style: IconButton.styleFrom( + backgroundColor: backgroundColor, + ), + tooltip: text is Text + ? (text as Text).data : text.toStringShallow().split(",").last.replaceAll( "\"", "", @@ -36,7 +38,7 @@ class Action extends StatelessWidget { ); } - return PlatformListTile( + return ListTile( tileColor: backgroundColor, onTap: onPressed, leading: icon, @@ -59,7 +61,7 @@ class AdaptiveActions extends HookWidget { final breakpoint = useBreakpoints(); if (breakpoint.isLessThan(breakOn)) { - return PlatformIconButton( + return IconButton( icon: const Icon(SpotubeIcons.moreHorizontal), onPressed: () { showPopover( @@ -83,8 +85,7 @@ class AdaptiveActions extends HookWidget { .toList(), ); }, - backgroundColor: - PlatformTheme.of(context).secondaryBackgroundColor!, + backgroundColor: Theme.of(context).cardColor, ); }, ); diff --git a/lib/components/shared/compact_search.dart b/lib/components/shared/compact_search.dart index ec2e9686..70815291 100644 --- a/lib/components/shared/compact_search.dart +++ b/lib/components/shared/compact_search.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:popover/popover.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -20,11 +20,11 @@ class CompactSearch extends HookWidget { @override Widget build(BuildContext context) { - return PlatformIconButton( + return IconButton( onPressed: () { showPopover( context: context, - backgroundColor: PlatformTheme.of(context).secondaryBackgroundColor!, + backgroundColor: Theme.of(context).cardColor, transitionDuration: const Duration(milliseconds: 100), barrierColor: Colors.transparent, arrowDxOffset: -6, @@ -32,14 +32,13 @@ class CompactSearch extends HookWidget { return Container( padding: const EdgeInsets.all(8.0), width: 300, - child: PlatformTextField( + child: TextField( autofocus: true, onChanged: onChanged, - placeholder: placeholder, - prefixIcon: icon, - padding: platform == TargetPlatform.android - ? const EdgeInsets.all(0) - : null, + decoration: InputDecoration( + hintText: placeholder, + prefixIcon: Icon(icon), + ), ), ); }, diff --git a/lib/components/shared/dialogs/confirm_download_dialog.dart b/lib/components/shared/dialogs/confirm_download_dialog.dart index 9b916965..bf8676f1 100644 --- a/lib/components/shared/dialogs/confirm_download_dialog.dart +++ b/lib/components/shared/dialogs/confirm_download_dialog.dart @@ -1,16 +1,13 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/components/shared/image/universal_image.dart'; -import 'package:spotube/components/root/sidebar.dart'; class ConfirmDownloadDialog extends StatelessWidget { const ConfirmDownloadDialog({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return PlatformAlertDialog( - macosAppIcon: Sidebar.brandLogo(), + return AlertDialog( title: Padding( padding: const EdgeInsets.all(15), child: Row( @@ -62,48 +59,21 @@ class ConfirmDownloadDialog extends StatelessWidget { ), ), ), - primaryActions: [ - PlatformBuilder( - android: (context, _) { - return PlatformFilledButton( - style: const ButtonStyle( - foregroundColor: MaterialStatePropertyAll(Colors.white), - backgroundColor: MaterialStatePropertyAll(Colors.red), - ), - onPressed: () => Navigator.of(context).pop(true), - child: const Text("Accept"), - ); - }, - ios: (context, data) { - return CupertinoDialogAction( - onPressed: () => Navigator.of(context).pop(true), - isDestructiveAction: true, - child: const Text("Accept"), - ); - }, - ) - ], - secondaryActions: [ - PlatformBuilder( - fallback: PlatformBuilderFallback.android, - android: (context, _) { - return PlatformFilledButton( - child: const Text("Decline"), - onPressed: () { - Navigator.pop(context, false); - }, - ); - }, - ios: (context, data) { - return CupertinoDialogAction( - onPressed: () { - Navigator.pop(context, false); - }, - isDefaultAction: true, - child: const Text("Decline"), - ); + actions: [ + OutlinedButton( + child: const Text("Decline"), + onPressed: () { + Navigator.pop(context, false); }, ), + FilledButton( + style: FilledButton.styleFrom( + foregroundColor: Colors.white, + backgroundColor: Colors.red, + ), + onPressed: () => Navigator.of(context).pop(true), + child: const Text("Accept"), + ), ], ); } diff --git a/lib/components/shared/dialogs/playlist_add_track_dialog.dart b/lib/components/shared/dialogs/playlist_add_track_dialog.dart index 9a8d2003..a02729e9 100644 --- a/lib/components/shared/dialogs/playlist_add_track_dialog.dart +++ b/lib/components/shared/dialogs/playlist_add_track_dialog.dart @@ -1,7 +1,7 @@ -import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/provider/spotify_provider.dart'; import 'package:spotube/services/queries/queries.dart'; @@ -42,61 +42,32 @@ class PlaylistAddTrackDialog extends HookConsumerWidget { ).then((_) => Navigator.pop(context)); } - return PlatformAlertDialog( - title: const PlatformText("Add to Playlist"), - secondaryActions: [ - PlatformBuilder( - fallback: PlatformBuilderFallback.android, - android: (context, _) { - return PlatformFilledButton( - isSecondary: true, - child: const Text("Cancel"), - onPressed: () { - Navigator.pop(context); - }, - ); - }, - ios: (context, data) { - return CupertinoDialogAction( - onPressed: () { - Navigator.pop(context); - }, - isDestructiveAction: true, - child: const Text("Cancel"), - ); + return AlertDialog( + title: const Text("Add to Playlist"), + actions: [ + OutlinedButton( + child: const Text("Cancel"), + onPressed: () { + Navigator.pop(context); }, ), - ], - primaryActions: [ - PlatformBuilder( - fallback: PlatformBuilderFallback.android, - android: (context, _) { - return PlatformFilledButton( - onPressed: onAdd, - child: const Text("Add"), - ); - }, - ios: (context, data) { - return CupertinoDialogAction( - isDefaultAction: true, - onPressed: onAdd, - child: const Text("Add"), - ); - }, + FilledButton( + onPressed: onAdd, + child: const Text("Add"), ), ], content: SizedBox( height: 300, width: 300, child: !userPlaylists.hasData - ? const Center(child: PlatformCircularProgressIndicator()) + ? const Center(child: CircularProgressIndicator()) : ListView.builder( shrinkWrap: true, itemCount: filteredPlaylists!.length, itemBuilder: (context, index) { final playlist = filteredPlaylists.elementAt(index); - return PlatformCheckbox( - label: PlatformText(playlist.name!), + return CheckboxListTile( + title: Text(playlist.name!), value: playlistsCheck.value[playlist.id] ?? false, onChanged: (val) { playlistsCheck.value = { diff --git a/lib/components/shared/dialogs/prompt_dialog.dart b/lib/components/shared/dialogs/prompt_dialog.dart index 0cc86e67..6fd54a98 100644 --- a/lib/components/shared/dialogs/prompt_dialog.dart +++ b/lib/components/shared/dialogs/prompt_dialog.dart @@ -1,6 +1,4 @@ -import 'package:flutter/cupertino.dart'; -import 'package:platform_ui/platform_ui.dart'; -import 'package:spotube/components/root/sidebar.dart'; +import 'package:flutter/material.dart'; Future showPromptDialog({ required BuildContext context, @@ -9,40 +7,21 @@ Future showPromptDialog({ String okText = "Ok", String cancelText = "Cancel", }) async { - return showPlatformAlertDialog( - context, + return showDialog( + context: context, builder: (context) { - return PlatformAlertDialog( - title: PlatformText(title), - content: PlatformText(message), - macosAppIcon: Sidebar.brandLogo(), - primaryActions: [ - if (platform == TargetPlatform.iOS) - CupertinoDialogAction( - isDefaultAction: false, - isDestructiveAction: true, - child: PlatformText(okText), - onPressed: () => Navigator.of(context).pop(true), - ) - else - PlatformFilledButton( - child: PlatformText(okText), - onPressed: () => Navigator.of(context).pop(true), - ), - ], - secondaryActions: [ - if (platform == TargetPlatform.iOS) - CupertinoDialogAction( - isDefaultAction: true, - child: PlatformText(cancelText), - onPressed: () => Navigator.of(context).pop(false), - ) - else - PlatformFilledButton( - isSecondary: true, - onPressed: () => Navigator.of(context).pop(false), - child: PlatformText(cancelText), - ), + return AlertDialog( + title: Text(title), + content: Text(message), + actions: [ + OutlinedButton( + onPressed: () => Navigator.of(context).pop(false), + child: Text(cancelText), + ), + FilledButton( + child: Text(okText), + onPressed: () => Navigator.of(context).pop(true), + ), ], ); }, diff --git a/lib/components/shared/dialogs/replace_downloaded_dialog.dart b/lib/components/shared/dialogs/replace_downloaded_dialog.dart index f5228860..3587bc8a 100644 --- a/lib/components/shared/dialogs/replace_downloaded_dialog.dart +++ b/lib/components/shared/dialogs/replace_downloaded_dialog.dart @@ -1,9 +1,7 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; -import 'package:spotube/components/root/sidebar.dart'; final replaceDownloadedFileState = StateProvider((ref) => null); @@ -16,8 +14,7 @@ class ReplaceDownloadedDialog extends ConsumerWidget { Widget build(BuildContext context, ref) { final groupValue = ref.watch(replaceDownloadedFileState); - return PlatformAlertDialog( - macosAppIcon: Sidebar.brandLogo(), + return AlertDialog( title: Text("Track ${track.name} Already Exists"), content: Column( mainAxisSize: MainAxisSize.min, @@ -26,7 +23,7 @@ class ReplaceDownloadedDialog extends ConsumerWidget { RadioListTile( dense: true, contentPadding: EdgeInsets.zero, - activeColor: PlatformTheme.of(context).primaryColor, + activeColor: Theme.of(context).primaryColor, value: true, groupValue: groupValue, onChanged: (value) { @@ -39,7 +36,7 @@ class ReplaceDownloadedDialog extends ConsumerWidget { RadioListTile( dense: true, contentPadding: EdgeInsets.zero, - activeColor: PlatformTheme.of(context).primaryColor, + activeColor: Theme.of(context).primaryColor, value: false, groupValue: groupValue, onChanged: (value) { @@ -51,48 +48,17 @@ class ReplaceDownloadedDialog extends ConsumerWidget { ), ], ), - primaryActions: [ - PlatformBuilder( - fallback: PlatformBuilderFallback.android, - android: (context, _) { - return PlatformFilledButton( - child: const Text("Yes"), - onPressed: () { - Navigator.pop(context, true); - }, - ); - }, - ios: (context, data) { - return CupertinoDialogAction( - onPressed: () { - Navigator.pop(context, true); - }, - isDefaultAction: true, - child: const Text("Yes"), - ); + actions: [ + OutlinedButton( + child: const Text("No"), + onPressed: () { + Navigator.pop(context, false); }, ), - ], - secondaryActions: [ - PlatformBuilder( - fallback: PlatformBuilderFallback.android, - android: (context, _) { - return PlatformFilledButton( - isSecondary: true, - child: const Text("No"), - onPressed: () { - Navigator.pop(context, false); - }, - ); - }, - ios: (context, data) { - return CupertinoDialogAction( - onPressed: () { - Navigator.pop(context, false); - }, - isDestructiveAction: true, - child: const Text("No"), - ); + FilledButton( + child: const Text("Yes"), + onPressed: () { + Navigator.pop(context, true); }, ), ], diff --git a/lib/components/shared/fallbacks/anonymous_fallback.dart b/lib/components/shared/fallbacks/anonymous_fallback.dart index aa72d462..fce80a08 100644 --- a/lib/components/shared/fallbacks/anonymous_fallback.dart +++ b/lib/components/shared/fallbacks/anonymous_fallback.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/provider/authentication_provider.dart'; import 'package:spotube/utils/service_utils.dart'; @@ -20,10 +20,10 @@ class AnonymousFallback extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const PlatformText("You're not logged in"), + const Text("You're not logged in"), const SizedBox(height: 10), - PlatformFilledButton( - child: const PlatformText("Login with Spotify"), + FilledButton( + child: const Text("Login with Spotify"), onPressed: () => ServiceUtils.navigate(context, "/settings"), ) ], diff --git a/lib/components/shared/heart_button.dart b/lib/components/shared/heart_button.dart index 5c7e6811..363fecc5 100644 --- a/lib/components/shared/heart_button.dart +++ b/lib/components/shared/heart_button.dart @@ -2,7 +2,7 @@ import 'package:fl_query/fl_query.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/hooks/use_palette_color.dart'; @@ -34,7 +34,7 @@ class HeartButton extends ConsumerWidget { if (auth == null) return Container(); - return PlatformIconButton( + return IconButton( tooltip: tooltip, icon: Icon( icon ?? (!isLiked ? SpotubeIcons.heart : SpotubeIcons.heartFilled), @@ -95,7 +95,7 @@ class TrackHeartButton extends HookConsumerWidget { useQueries.playlist.tracksOfQuery(ref, "user-liked-tracks"); final toggler = useTrackToggleLike(track, ref); if (toggler.item3.isLoading || !toggler.item3.hasData) { - return const PlatformCircularProgressIndicator(); + return const CircularProgressIndicator(); } return HeartButton( @@ -150,7 +150,7 @@ class PlaylistHeartButton extends HookConsumerWidget { ).dominantColor; if (me.isLoading || !me.hasData) { - return const PlatformCircularProgressIndicator(); + return const CircularProgressIndicator(); } return HeartButton( @@ -193,7 +193,7 @@ class AlbumHeartButton extends HookConsumerWidget { ); if (me.isLoading || !me.hasData) { - return const PlatformCircularProgressIndicator(); + return const CircularProgressIndicator(); } return HeartButton( diff --git a/lib/components/shared/links/anchor_button.dart b/lib/components/shared/links/anchor_button.dart index 9660cfc1..ede984e9 100644 --- a/lib/components/shared/links/anchor_button.dart +++ b/lib/components/shared/links/anchor_button.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:platform_ui/platform_ui.dart'; class AnchorButton extends HookWidget { final String text; @@ -29,7 +28,7 @@ class AnchorButton extends HookWidget { onTap: onTap, child: MouseRegion( cursor: MaterialStateMouseCursor.clickable, - child: PlatformText( + child: Text( text, style: style.copyWith( decoration: diff --git a/lib/components/shared/page_window_title_bar.dart b/lib/components/shared/page_window_title_bar.dart index a0248ee1..eda6cf1d 100644 --- a/lib/components/shared/page_window_title_bar.dart +++ b/lib/components/shared/page_window_title_bar.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:platform_ui/platform_ui.dart'; import 'package:spotube/utils/platform.dart'; + import 'package:window_manager/window_manager.dart'; -class PageWindowTitleBar extends StatefulHookWidget with PreferredSizeWidget { +class PageWindowTitleBar extends StatefulHookWidget + implements PreferredSizeWidget { final Widget? leading; final bool automaticallyImplyLeading; final List? actions; @@ -18,13 +19,12 @@ class PageWindowTitleBar extends StatefulHookWidget with PreferredSizeWidget { final TextStyle? toolbarTextStyle; final TextStyle? titleTextStyle; final double? titleWidth; - final Widget? center; - final bool hideWhenWindows; + final Widget? title; - PageWindowTitleBar({ + const PageWindowTitleBar({ Key? key, this.actions, - this.center, + this.title, this.toolbarOpacity = 1, this.backgroundColor, this.actionsIconTheme, @@ -37,13 +37,10 @@ class PageWindowTitleBar extends StatefulHookWidget with PreferredSizeWidget { this.titleTextStyle, this.titleWidth, this.toolbarTextStyle, - this.hideWhenWindows = true, }) : super(key: key); @override - Size get preferredSize => Size.fromHeight( - platform == TargetPlatform.windows ? 33 : kToolbarHeight, - ); + Size get preferredSize => const Size.fromHeight(kToolbarHeight); @override State createState() => _PageWindowTitleBarState(); @@ -54,33 +51,6 @@ class _PageWindowTitleBarState extends State { Widget build(BuildContext context) { final isMaximized = useState(null); - useEffect(() { - if (platform == TargetPlatform.windows && - widget.hideWhenWindows && - Navigator.of(context).canPop()) { - final entry = OverlayEntry( - builder: (context) => const Positioned( - left: 5, - top: 5, - child: PlatformBackButton(), - ), - ); - - WidgetsBinding.instance.addPostFrameCallback((_) { - Overlay.of(context)?.insert(entry); - }); - - return () { - entry.remove(); - }; - } - return null; - }, [platform, widget.hideWhenWindows]); - - if (platform == TargetPlatform.windows && widget.hideWhenWindows) { - return const SizedBox.shrink(); - } - maximizeOrRestore() async { if (await windowManager.isMaximized()) { await windowManager.unmaximize(); @@ -91,42 +61,52 @@ class _PageWindowTitleBarState extends State { } } - return PlatformAppBar( - actions: [ - ...?widget.actions, - if (!kIsMacOS && !kIsMobile) - PlatformWindowButtons( - isMaximized: () async => - isMaximized.value ?? await windowManager.isMaximized(), - onMaximize: maximizeOrRestore, - onRestore: maximizeOrRestore, - onMinimize: () { - windowManager.minimize(); - }, - onClose: () { - windowManager.close(); - }, - showCloseButton: true, - showMaximizeButton: true, - showMinimizeButton: true, - ), - ], - onDrag: () { - if (kIsDesktop) windowManager.startDragging(); + return GestureDetector( + onHorizontalDragStart: (details) { + if (kIsDesktop) { + windowManager.startDragging(); + } }, - title: widget.center, - toolbarOpacity: widget.toolbarOpacity, - backgroundColor: widget.backgroundColor, - actionsIconTheme: widget.actionsIconTheme, - automaticallyImplyLeading: widget.automaticallyImplyLeading, - centerTitle: widget.centerTitle, - foregroundColor: widget.foregroundColor, - leading: widget.leading, - leadingWidth: widget.leadingWidth, - titleSpacing: widget.titleSpacing, - titleTextStyle: widget.titleTextStyle, - titleWidth: widget.titleWidth, - toolbarTextStyle: widget.toolbarTextStyle, + onVerticalDragStart: (details) { + if (kIsDesktop) { + windowManager.startDragging(); + } + }, + child: AppBar( + leading: widget.leading, + automaticallyImplyLeading: widget.automaticallyImplyLeading, + actions: [ + ...?widget.actions, + if (kIsDesktop && !kIsMacOS) ...[ + IconButton( + icon: const Icon(Icons.minimize), + onPressed: () => windowManager.minimize(), + ), + IconButton( + icon: Icon( + isMaximized.value ?? false + ? Icons.fullscreen_exit + : Icons.fullscreen, + ), + onPressed: maximizeOrRestore, + ), + IconButton( + icon: const Icon(Icons.close), + onPressed: () => windowManager.close(), + ), + ] + ], + backgroundColor: widget.backgroundColor, + foregroundColor: widget.foregroundColor, + actionsIconTheme: widget.actionsIconTheme, + centerTitle: widget.centerTitle, + titleSpacing: widget.titleSpacing, + toolbarOpacity: widget.toolbarOpacity, + leadingWidth: widget.leadingWidth, + toolbarTextStyle: widget.toolbarTextStyle, + titleTextStyle: widget.titleTextStyle, + title: widget.title, + ), ); } } diff --git a/lib/components/shared/playbutton_card.dart b/lib/components/shared/playbutton_card.dart index cdf55642..3f16bf7a 100644 --- a/lib/components/shared/playbutton_card.dart +++ b/lib/components/shared/playbutton_card.dart @@ -1,12 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/hover_builder.dart'; import 'package:spotube/components/shared/spotube_marquee_text.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; -import 'package:spotube/hooks/use_platform_property.dart'; enum PlaybuttonCardViewType { square, list } @@ -38,32 +37,7 @@ class PlaybuttonCard extends HookWidget { @override Widget build(BuildContext context) { - final backgroundColor = PlatformTheme.of(context).secondaryBackgroundColor; - - final boxShadow = usePlatformProperty( - (context) => PlatformProperty( - android: BoxShadow( - blurRadius: 10, - offset: const Offset(0, 3), - spreadRadius: 5, - color: Theme.of(context).colorScheme.shadow, - ), - ios: null, - macos: null, - linux: BoxShadow( - blurRadius: 6, - color: Theme.of(context).shadowColor.withOpacity(0.3), - ), - windows: null, - ), - ); - - final splash = usePlatformProperty( - (context) => PlatformProperty.only( - android: InkRipple.splashFactory, - other: NoSplash.splashFactory, - ), - ); + final backgroundColor = Theme.of(context).cardColor; final isSquare = viewType == PlaybuttonCardViewType.square; @@ -72,7 +46,6 @@ class PlaybuttonCard extends HookWidget { child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(8), - splashFactory: splash, highlightColor: Colors.black12, child: ConstrainedBox( constraints: BoxConstraints( @@ -80,18 +53,19 @@ class PlaybuttonCard extends HookWidget { maxHeight: !isSquare ? 60 : double.infinity, ), child: HoverBuilder(builder: (context, isHovering) { - final playButton = PlatformIconButton( + final playButton = IconButton( onPressed: onPlaybuttonPressed, - backgroundColor: PlatformTheme.of(context).primaryColor, - hoverColor: - PlatformTheme.of(context).primaryColor?.withOpacity(0.5), + style: IconButton.styleFrom( + backgroundColor: Theme.of(context).primaryColor, + hoverColor: Theme.of(context).primaryColor.withOpacity(0.5), + ), icon: isLoading ? SizedBox( height: 23, width: 23, - child: PlatformCircularProgressIndicator( + child: CircularProgressIndicator( color: ThemeData.estimateBrightnessForColor( - PlatformTheme.of(context).primaryColor!, + Theme.of(context).primaryColor, ) == Brightness.dark ? Colors.white @@ -103,31 +77,22 @@ class PlaybuttonCard extends HookWidget { color: Colors.white, ), ); - final addToQueueButton = PlatformIconButton( + final addToQueueButton = IconButton( onPressed: isLoading ? null : onAddToQueuePressed, - backgroundColor: - PlatformTheme.of(context).secondaryBackgroundColor, - hoverColor: PlatformTheme.of(context) - .secondaryBackgroundColor - ?.withOpacity(0.5), + style: IconButton.styleFrom( + backgroundColor: Theme.of(context).cardColor, + hoverColor: Theme.of(context) + .cardColor + .withOpacity(isLoading ? 1 : 0.5), + ), icon: const Icon(SpotubeIcons.queueAdd), ); - final image = Padding( - padding: EdgeInsets.all( - platform == TargetPlatform.windows ? 5 : 0, - ), - child: ClipRRect( - borderRadius: BorderRadius.circular( - [TargetPlatform.windows, TargetPlatform.linux] - .contains(platform) - ? 5 - : 8, - ), - child: UniversalImage( - path: imageUrl, - width: isSquare ? 200 : 60, - placeholder: (context, url) => Assets.placeholder.image(), - ), + final image = ClipRRect( + borderRadius: BorderRadius.circular(8), + child: UniversalImage( + path: imageUrl, + width: isSquare ? 200 : 60, + placeholder: (context, url) => Assets.placeholder.image(), ), ); @@ -147,8 +112,7 @@ class PlaybuttonCard extends HookWidget { mainAxisAlignment: MainAxisAlignment.end, children: [ if (!isPlaying) addToQueueButton, - if (platform != TargetPlatform.linux) - const SizedBox(height: 5), + const SizedBox(height: 5), playButton, ], ), @@ -178,7 +142,7 @@ class PlaybuttonCard extends HookWidget { height: 30, child: SpotubeMarqueeText( text: description!, - style: PlatformTextTheme.of(context).caption, + style: Theme.of(context).textTheme.bodySmall, isHovering: isHovering, ), ), @@ -205,14 +169,15 @@ class PlaybuttonCard extends HookWidget { children: [ TextSpan( text: title, - style: PlatformTextTheme.of(context) - .body + style: Theme.of(context) + .textTheme + .bodyMedium ?.copyWith(fontWeight: FontWeight.bold), ), if (description != null) TextSpan( text: '\n$description', - style: PlatformTextTheme.of(context).caption, + style: Theme.of(context).textTheme.bodySmall, ), ], ), @@ -235,23 +200,15 @@ class PlaybuttonCard extends HookWidget { return Ink( decoration: BoxDecoration( color: backgroundColor, - borderRadius: BorderRadius.circular( - [TargetPlatform.windows, TargetPlatform.linux] - .contains(platform) - ? 5 - : 8, - ), + borderRadius: BorderRadius.circular(8), boxShadow: [ - if (boxShadow != null) boxShadow, + BoxShadow( + blurRadius: 10, + offset: const Offset(0, 3), + spreadRadius: 5, + color: Theme.of(context).colorScheme.shadow, + ), ], - border: [TargetPlatform.windows, TargetPlatform.macOS] - .contains(platform) - ? Border.all( - color: PlatformTheme.of(context).borderColor ?? - Colors.transparent, - width: 1, - ) - : null, ), child: isSquare ? square : list, ); diff --git a/lib/components/shared/shimmers/shimmer_artist_profile.dart b/lib/components/shared/shimmers/shimmer_artist_profile.dart index 58786192..1eee7d4b 100644 --- a/lib/components/shared/shimmers/shimmer_artist_profile.dart +++ b/lib/components/shared/shimmers/shimmer_artist_profile.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:skeleton_text/skeleton_text.dart'; import 'package:spotube/components/shared/shimmers/shimmer_track_tile.dart'; import 'package:spotube/extensions/theme.dart'; @@ -11,7 +11,7 @@ class ShimmerArtistProfile extends HookWidget { @override Widget build(BuildContext context) { - final isDark = PlatformTheme.of(context).brightness == Brightness.dark; + final isDark = Theme.of(context).brightness == Brightness.dark; final shimmerTheme = ShimmerColorTheme( shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200], shimmerColor: isDark ? Colors.grey[800] : Colors.grey[300], diff --git a/lib/components/shared/shimmers/shimmer_categories.dart b/lib/components/shared/shimmers/shimmer_categories.dart index fdefb645..163292b4 100644 --- a/lib/components/shared/shimmers/shimmer_categories.dart +++ b/lib/components/shared/shimmers/shimmer_categories.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/components/shared/shimmers/shimmer_playbutton_card.dart'; import 'package:spotube/extensions/theme.dart'; @@ -8,7 +8,7 @@ class ShimmerCategories extends StatelessWidget { @override Widget build(BuildContext context) { - final isDark = PlatformTheme.of(context).brightness == Brightness.dark; + final isDark = Theme.of(context).brightness == Brightness.dark; final shimmerTheme = ShimmerColorTheme( shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200], ); diff --git a/lib/components/shared/shimmers/shimmer_lyrics.dart b/lib/components/shared/shimmers/shimmer_lyrics.dart index 1dc9ab86..37a241ea 100644 --- a/lib/components/shared/shimmers/shimmer_lyrics.dart +++ b/lib/components/shared/shimmers/shimmer_lyrics.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:skeleton_text/skeleton_text.dart'; import 'package:spotube/extensions/theme.dart'; import 'package:spotube/hooks/use_breakpoints.dart'; @@ -12,7 +12,7 @@ class ShimmerLyrics extends HookWidget { @override Widget build(BuildContext context) { - final isDark = PlatformTheme.of(context).brightness == Brightness.dark; + final isDark = Theme.of(context).brightness == Brightness.dark; final shimmerTheme = ShimmerColorTheme( shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200], shimmerColor: isDark ? Colors.grey[800] : Colors.grey[300], diff --git a/lib/components/shared/shimmers/shimmer_playbutton_card.dart b/lib/components/shared/shimmers/shimmer_playbutton_card.dart index 605a79a8..f584dfc2 100644 --- a/lib/components/shared/shimmers/shimmer_playbutton_card.dart +++ b/lib/components/shared/shimmers/shimmer_playbutton_card.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/extensions/theme.dart'; class ShimmerPlaybuttonCardPainter extends CustomPainter { @@ -53,7 +53,7 @@ class ShimmerPlaybuttonCard extends StatelessWidget { @override Widget build(BuildContext context) { - final isDark = PlatformTheme.of(context).brightness == Brightness.dark; + final isDark = Theme.of(context).brightness == Brightness.dark; final shimmerTheme = ShimmerColorTheme( shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200], shimmerColor: isDark ? Colors.grey[800] : Colors.grey[300], diff --git a/lib/components/shared/shimmers/shimmer_track_tile.dart b/lib/components/shared/shimmers/shimmer_track_tile.dart index 7f483750..8caee3e3 100644 --- a/lib/components/shared/shimmers/shimmer_track_tile.dart +++ b/lib/components/shared/shimmers/shimmer_track_tile.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/extensions/theme.dart'; class ShimmerTrackTilePainter extends CustomPainter { @@ -67,7 +67,7 @@ class ShimmerTrackTile extends StatelessWidget { @override Widget build(BuildContext context) { - final isDark = PlatformTheme.of(context).brightness == Brightness.dark; + final isDark = Theme.of(context).brightness == Brightness.dark; final shimmerTheme = ShimmerColorTheme( shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200], shimmerColor: isDark ? Colors.grey[800] : Colors.grey[300], diff --git a/lib/components/shared/sort_tracks_dropdown.dart b/lib/components/shared/sort_tracks_dropdown.dart index 135b7b7d..b3717b53 100644 --- a/lib/components/shared/sort_tracks_dropdown.dart +++ b/lib/components/shared/sort_tracks_dropdown.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/library/user_local_tracks.dart'; @@ -14,39 +14,41 @@ class SortTracksDropdown extends StatelessWidget { @override Widget build(BuildContext context) { - return PlatformPopupMenuButton( - items: [ - PlatformPopupMenuItem( - value: SortBy.none, - enabled: value != SortBy.none, - child: const Text("None"), - ), - PlatformPopupMenuItem( - value: SortBy.ascending, - enabled: value != SortBy.ascending, - child: const Text("Sort by A-Z"), - ), - PlatformPopupMenuItem( - value: SortBy.descending, - enabled: value != SortBy.descending, - child: const Text("Sort by Z-A"), - ), - PlatformPopupMenuItem( - value: SortBy.dateAdded, - enabled: value != SortBy.dateAdded, - child: const Text("Sort by Date"), - ), - PlatformPopupMenuItem( - value: SortBy.artist, - enabled: value != SortBy.artist, - child: const Text("Sort by Artist"), - ), - PlatformPopupMenuItem( - value: SortBy.album, - enabled: value != SortBy.album, - child: const Text("Sort by Album"), - ), - ], + return PopupMenuButton( + itemBuilder: (context) { + return [ + PopupMenuItem( + value: SortBy.none, + enabled: value != SortBy.none, + child: const Text("None"), + ), + PopupMenuItem( + value: SortBy.ascending, + enabled: value != SortBy.ascending, + child: const Text("Sort by A-Z"), + ), + PopupMenuItem( + value: SortBy.descending, + enabled: value != SortBy.descending, + child: const Text("Sort by Z-A"), + ), + PopupMenuItem( + value: SortBy.dateAdded, + enabled: value != SortBy.dateAdded, + child: const Text("Sort by Date"), + ), + PopupMenuItem( + value: SortBy.artist, + enabled: value != SortBy.artist, + child: const Text("Sort by Artist"), + ), + PopupMenuItem( + value: SortBy.album, + enabled: value != SortBy.album, + child: const Text("Sort by Album"), + ), + ]; + }, onSelected: onChanged, tooltip: "Sort tracks", child: const Icon(SpotubeIcons.sort), diff --git a/lib/components/shared/spotube_page_route.dart b/lib/components/shared/spotube_page_route.dart index 48af33b3..92049fb1 100644 --- a/lib/components/shared/spotube_page_route.dart +++ b/lib/components/shared/spotube_page_route.dart @@ -1,27 +1,5 @@ -import 'package:fluent_ui/fluent_ui.dart'; -import 'package:go_router/go_router.dart'; -import 'package:platform_ui/platform_ui.dart'; +import 'package:flutter/material.dart'; -class SpotubePage extends CustomTransitionPage { - SpotubePage({ - required super.child, - }) : super( - transitionsBuilder: (context, animation, secondaryAnimation, child) { - return child; - }, - ); - - @override - Route createRoute(BuildContext context) { - if (platform == TargetPlatform.windows) { - return FluentPageRoute( - builder: (context) => child, - settings: this, - maintainState: maintainState, - barrierLabel: barrierLabel, - fullscreenDialog: fullscreenDialog, - ); - } - return super.createRoute(context); - } +class SpotubePage extends MaterialPage { + const SpotubePage({required super.child}); } diff --git a/lib/components/shared/track_table/track_collection_view.dart b/lib/components/shared/track_table/track_collection_view.dart index a0e25a54..718bde50 100644 --- a/lib/components/shared/track_table/track_collection_view.dart +++ b/lib/components/shared/track_table/track_collection_view.dart @@ -4,7 +4,7 @@ import 'package:collection/collection.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/compact_search.dart'; @@ -72,7 +72,7 @@ class TrackCollectionView extends HookConsumerWidget { final List buttons = [ if (showShare) - PlatformIconButton( + IconButton( icon: Icon( SpotubeIcons.share, color: color?.titleTextColor, @@ -80,7 +80,7 @@ class TrackCollectionView extends HookConsumerWidget { onPressed: onShare, ), if (heartBtn != null && auth != null) heartBtn!, - PlatformIconButton( + IconButton( tooltip: "Shuffle", icon: Icon( SpotubeIcons.shuffle, @@ -91,7 +91,7 @@ class TrackCollectionView extends HookConsumerWidget { const SizedBox(width: 5), // add to queue playlist if (!isPlaying) - PlatformIconButton( + IconButton( onPressed: tracksSnapshot.data != null ? onAddToQueue : null, icon: Icon( SpotubeIcons.queueAdd, @@ -99,8 +99,10 @@ class TrackCollectionView extends HookConsumerWidget { ), ), // play playlist - PlatformIconButton( - backgroundColor: PlatformTheme.of(context).primaryColor, + IconButton( + style: IconButton.styleFrom( + backgroundColor: Theme.of(context).primaryColor, + ), onPressed: tracksSnapshot.data != null ? onPlay : null, icon: Icon(isPlaying ? SpotubeIcons.stop : SpotubeIcons.play), ), @@ -136,7 +138,7 @@ class TrackCollectionView extends HookConsumerWidget { }, [tracksSnapshot.data, searchText.value]); useCustomStatusBarColor( - color?.color ?? PlatformTheme.of(context).scaffoldBackgroundColor!, + color?.color ?? Theme.of(context).scaffoldBackgroundColor, GoRouter.of(context).location == routePath, ); @@ -156,60 +158,38 @@ class TrackCollectionView extends HookConsumerWidget { final searchbar = ConstrainedBox( constraints: const BoxConstraints( - maxWidth: 400, + maxWidth: 300, maxHeight: 50, ), - child: PlatformTextField( + child: TextField( controller: searchController, onChanged: (value) => searchText.value = value, - placeholder: "Search tracks...", - backgroundColor: Colors.transparent, - focusedBackgroundColor: Colors.transparent, - style: TextStyle( - color: color?.titleTextColor, + style: TextStyle(color: color?.titleTextColor), + decoration: InputDecoration( + hintText: "Search tracks...", + hintStyle: TextStyle(color: color?.titleTextColor), + border: Theme.of(context).inputDecorationTheme.border?.copyWith( + borderSide: BorderSide( + color: color?.titleTextColor ?? Colors.white, + ), + ), + prefixIconColor: color?.titleTextColor, + prefixIcon: const Icon(SpotubeIcons.search), ), - placeholderStyle: TextStyle( - color: color?.titleTextColor, - ), - focusedStyle: TextStyle( - color: color?.titleTextColor, - ), - borderColor: color?.titleTextColor, - prefixIconColor: color?.titleTextColor, - cursorColor: color?.titleTextColor, - prefixIcon: SpotubeIcons.search, ), ); - useEffect(() { - OverlayEntry? entry; - WidgetsBinding.instance.addPostFrameCallback((_) { - if (platform == TargetPlatform.windows && - kIsDesktop && - !collapsed.value) { - entry = OverlayEntry(builder: (context) { - return Positioned( - left: 40, - top: 7, - child: searchbar, - ); - }); - Overlay.of(context).insert(entry!); - } - }); - return () => entry?.remove(); - }, [color?.titleTextColor, collapsed.value]); - return SafeArea( - child: PlatformScaffold( + child: Scaffold( appBar: kIsDesktop ? PageWindowTitleBar( backgroundColor: color?.color, foregroundColor: color?.titleTextColor, + leadingWidth: 400, leading: Row( mainAxisSize: MainAxisSize.min, children: [ - PlatformBackButton(color: color?.titleTextColor), + BackButton(color: color?.titleTextColor), const SizedBox(width: 10), searchbar, ], @@ -239,18 +219,19 @@ class TrackCollectionView extends HookConsumerWidget { expandedHeight: 400, automaticallyImplyLeading: kIsMobile, leading: kIsMobile - ? PlatformBackButton(color: color?.titleTextColor) + ? BackButton(color: color?.titleTextColor) : null, iconTheme: IconThemeData(color: color?.titleTextColor), primary: true, backgroundColor: color?.color, title: collapsed.value - ? PlatformText.headline( + ? Text( title, - style: TextStyle( - color: color?.titleTextColor, - fontWeight: FontWeight.w600, - ), + style: + Theme.of(context).textTheme.titleLarge!.copyWith( + color: color?.titleTextColor, + fontWeight: FontWeight.w600, + ), ) : null, centerTitle: true, @@ -268,7 +249,6 @@ class TrackCollectionView extends HookConsumerWidget { ), ), child: Material( - textStyle: PlatformTheme.of(context).textTheme!.body!, type: MaterialType.transparency, child: Padding( padding: const EdgeInsets.symmetric( @@ -299,15 +279,18 @@ class TrackCollectionView extends HookConsumerWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - PlatformText.headline( + Text( title, - style: TextStyle( - color: color?.titleTextColor, - fontWeight: FontWeight.w600, - ), + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith( + color: color?.titleTextColor, + fontWeight: FontWeight.w600, + ), ), if (description != null) - PlatformText( + Text( description!, style: TextStyle( color: color?.bodyTextColor, @@ -335,7 +318,7 @@ class TrackCollectionView extends HookConsumerWidget { return const ShimmerTrackTile(); } else if (tracksSnapshot.hasError) { return SliverToBoxAdapter( - child: PlatformText("Error ${tracksSnapshot.error}")); + child: Text("Error ${tracksSnapshot.error}")); } return TracksTableView( diff --git a/lib/components/shared/track_table/track_tile.dart b/lib/components/shared/track_table/track_tile.dart index f82bb9f1..5e6df7f9 100644 --- a/lib/components/shared/track_table/track_tile.dart +++ b/lib/components/shared/track_table/track_tile.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart' hide Action; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart' hide Image; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/spotube_icons.dart'; @@ -11,7 +11,6 @@ import 'package:spotube/components/shared/adaptive/adaptive_popup_menu_button.da 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/components/root/sidebar.dart'; import 'package:spotube/hooks/use_breakpoints.dart'; import 'package:spotube/models/logger.dart'; import 'package:spotube/provider/authentication_provider.dart'; @@ -85,7 +84,7 @@ class TrackTile extends HookConsumerWidget { SnackBar( width: 300, behavior: SnackBarBehavior.floating, - content: PlatformText( + content: Text( "Copied $data to clipboard", textAlign: TextAlign.center, ), @@ -95,78 +94,77 @@ class TrackTile extends HookConsumerWidget { } Future actionAddToPlaylist() async { - showPlatformAlertDialog(context, builder: (context) { - return FutureBuilder>( - future: spotify.playlists.me.all().then((playlists) async { - final me = await spotify.me.get(); - return playlists.where((playlist) => - playlist.owner?.id != null && playlist.owner!.id == me.id); - }), - builder: (context, snapshot) { - return HookBuilder(builder: (context) { - final playlistsCheck = useState({}); - return PlatformAlertDialog( - macosAppIcon: Sidebar.brandLogo(), - title: PlatformText( - "Add `${track.value.name}` to following Playlists", - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - secondaryActions: [ - PlatformFilledButton( - isSecondary: true, - child: const PlatformText("Cancel"), - onPressed: () => Navigator.pop(context), - ), - ], - primaryActions: [ - PlatformFilledButton( - child: const PlatformText("Add"), - onPressed: () async { - final selectedPlaylists = playlistsCheck.value.entries - .where((entry) => entry.value) - .map((entry) => entry.key); + showDialog( + context: context, + builder: (context) { + return FutureBuilder>( + future: spotify.playlists.me.all().then((playlists) async { + final me = await spotify.me.get(); + return playlists.where((playlist) => + playlist.owner?.id != null && + playlist.owner!.id == me.id); + }), + builder: (context, snapshot) { + return HookBuilder(builder: (context) { + final playlistsCheck = useState({}); + return AlertDialog( + title: Text( + "Add `${track.value.name}` to following Playlists", + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + actions: [ + OutlinedButton( + child: const Text("Cancel"), + onPressed: () => Navigator.pop(context), + ), + FilledButton( + child: const Text("Add"), + onPressed: () async { + final selectedPlaylists = playlistsCheck + .value.entries + .where((entry) => entry.value) + .map((entry) => entry.key); - await Future.wait( - selectedPlaylists.map( - (playlistId) => spotify.playlists - .addTrack(track.value.uri!, playlistId), - ), - ).then((_) => Navigator.pop(context)); - }, - ) - ], - content: SizedBox( - height: 300, - width: 300, - child: !snapshot.hasData - ? const Center( - child: PlatformCircularProgressIndicator()) - : ListView.builder( - shrinkWrap: true, - itemCount: snapshot.data!.length, - itemBuilder: (context, index) { - final playlist = snapshot.data!.elementAt(index); - return PlatformCheckbox( - label: PlatformText(playlist.name!), - value: - playlistsCheck.value[playlist.id] ?? false, - onChanged: (val) { - playlistsCheck.value = { - ...playlistsCheck.value, - playlist.id!: val == true - }; + await Future.wait( + selectedPlaylists.map( + (playlistId) => spotify.playlists + .addTrack(track.value.uri!, playlistId), + ), + ).then((_) => Navigator.pop(context)); + }, + ) + ], + content: SizedBox( + height: 300, + width: 300, + child: !snapshot.hasData + ? const Center(child: CircularProgressIndicator()) + : ListView.builder( + shrinkWrap: true, + itemCount: snapshot.data!.length, + itemBuilder: (context, index) { + final playlist = + snapshot.data!.elementAt(index); + return Checkbox( + value: playlistsCheck.value[playlist.id] ?? + false, + onChanged: (val) { + playlistsCheck.value = { + ...playlistsCheck.value, + playlist.id!: val == true + }; + }, + ); }, - ); - }, - ), - ), - ); - }); - }); - }); + ), + ), + ); + }); + }); + }); } final String thumbnailUrl = TypeConversionUtils.image_X_UrlString( @@ -189,11 +187,10 @@ class TrackTile extends HookConsumerWidget { ), child: Material( type: MaterialType.transparency, - textStyle: PlatformTheme.of(context).textTheme!.body!, child: Row( children: [ if (showCheck) - PlatformCheckbox( + Checkbox( value: isChecked, onChanged: (s) => onCheckChange?.call(s), ) @@ -229,16 +226,17 @@ class TrackTile extends HookConsumerWidget { ), Padding( padding: const EdgeInsets.all(8.0), - child: PlatformIconButton( + child: IconButton( icon: Icon( playlist?.activeTrack.id == track.value.id ? SpotubeIcons.pause : SpotubeIcons.play, color: Colors.white, ), - backgroundColor: PlatformTheme.of(context).primaryColor, - hoverColor: - PlatformTheme.of(context).primaryColor?.withOpacity(0.5), + style: IconButton.styleFrom( + backgroundColor: Theme.of(context).primaryColor, + hoverColor: Theme.of(context).primaryColor.withOpacity(0.5), + ), onPressed: !isBlackListed ? () => onTrackPlayButtonPressed?.call( track.value, @@ -255,7 +253,7 @@ class TrackTile extends HookConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Flexible( - child: PlatformText( + child: Text( track.value.name ?? "", style: TextStyle( fontWeight: FontWeight.bold, @@ -266,7 +264,7 @@ class TrackTile extends HookConsumerWidget { ), if (isBlackListed) ...[ const SizedBox(width: 5), - PlatformText( + Text( "Blacklisted", style: TextStyle( color: Colors.red[400], @@ -278,7 +276,7 @@ class TrackTile extends HookConsumerWidget { ], ), isLocal - ? PlatformText( + ? Text( TypeConversionUtils.artists_X_String( track.value.artists ?? []), ) @@ -294,7 +292,7 @@ class TrackTile extends HookConsumerWidget { if (breakpoint.isMoreThan(Breakpoints.md) && showAlbum) Expanded( child: isLocal - ? PlatformText(track.value.album?.name ?? "") + ? Text(track.value.album?.name ?? "") : LinkText( track.value.album!.name!, "/album/${track.value.album?.id}", @@ -304,7 +302,7 @@ class TrackTile extends HookConsumerWidget { ), if (!breakpoint.isSm) ...[ const SizedBox(width: 10), - PlatformText(duration), + Text(duration), ], const SizedBox(width: 10), if (!isLocal) @@ -313,13 +311,12 @@ class TrackTile extends HookConsumerWidget { if (!playlistQueueNotifier.isTrackOnQueue(track.value)) Action( icon: const Icon(SpotubeIcons.queueAdd), - text: const PlatformText("Add to queue"), + text: const Text("Add to queue"), onPressed: () { playlistQueueNotifier.add([track.value]); ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: PlatformText( - "Added ${track.value.name} to queue"), + content: Text("Added ${track.value.name} to queue"), ), ); }, @@ -327,13 +324,13 @@ class TrackTile extends HookConsumerWidget { else Action( icon: const Icon(SpotubeIcons.queueRemove), - text: const PlatformText("Remove from queue"), + text: const Text("Remove from queue"), onPressed: () { playlistQueueNotifier.remove([track.value]); ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: PlatformText( - "Removed ${track.value.name} from queue"), + content: + Text("Removed ${track.value.name} from queue"), ), ); }, @@ -346,7 +343,7 @@ class TrackTile extends HookConsumerWidget { color: Colors.pink, ) : const Icon(SpotubeIcons.heart), - text: const PlatformText("Save as favorite"), + text: const Text("Save as favorite"), onPressed: () { toggler.item2.mutate(toggler.item1); }, @@ -354,7 +351,7 @@ class TrackTile extends HookConsumerWidget { if (auth != null) Action( icon: const Icon(SpotubeIcons.playlistAdd), - text: const PlatformText("Add To playlist"), + text: const Text("Add To playlist"), onPressed: actionAddToPlaylist, ), if (userPlaylist && auth != null) @@ -362,10 +359,10 @@ class TrackTile extends HookConsumerWidget { icon: (removeTrack.isMutating || !removeTrack.hasData) && removingTrack.value == track.value.uri ? const Center( - child: PlatformCircularProgressIndicator(), + child: CircularProgressIndicator(), ) : const Icon(SpotubeIcons.removeFilled), - text: const PlatformText("Remove from playlist"), + text: const Text("Remove from playlist"), onPressed: () { removingTrack.value = track.value.uri; removeTrack.mutate(track.value.uri!); @@ -373,7 +370,7 @@ class TrackTile extends HookConsumerWidget { ), Action( icon: const Icon(SpotubeIcons.share), - text: const PlatformText("Share"), + text: const Text("Share"), onPressed: () { actionShare(track.value); }, @@ -384,7 +381,7 @@ class TrackTile extends HookConsumerWidget { color: isBlackListed ? Colors.white : Colors.red[400], ), backgroundColor: isBlackListed ? Colors.red[400] : null, - text: PlatformText( + text: Text( "${isBlackListed ? "Remove from" : "Add to"} blacklist", style: TextStyle( color: isBlackListed ? Colors.white : Colors.red[400], diff --git a/lib/components/shared/track_table/tracks_table_view.dart b/lib/components/shared/track_table/tracks_table_view.dart index d2ee91ce..d115582d 100644 --- a/lib/components/shared/track_table/tracks_table_view.dart +++ b/lib/components/shared/track_table/tracks_table_view.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/dialogs/confirm_download_dialog.dart'; @@ -71,7 +71,7 @@ class TracksTableView extends HookConsumerWidget { if (heading != null) heading!, Row( children: [ - PlatformCheckbox( + Checkbox( value: selected.value.length == sortedTracks.length, onChanged: (checked) { if (!showCheck.value) showCheck.value = true; @@ -85,7 +85,7 @@ class TracksTableView extends HookConsumerWidget { ), Padding( padding: const EdgeInsets.all(8.0), - child: PlatformText( + child: Text( "#", textAlign: TextAlign.center, style: tableHeadStyle, @@ -94,7 +94,7 @@ class TracksTableView extends HookConsumerWidget { Expanded( child: Row( children: [ - PlatformText( + Text( "Title", style: tableHeadStyle, overflow: TextOverflow.ellipsis, @@ -108,7 +108,7 @@ class TracksTableView extends HookConsumerWidget { Expanded( child: Row( children: [ - PlatformText( + Text( "Album", overflow: TextOverflow.ellipsis, style: tableHeadStyle, @@ -119,7 +119,7 @@ class TracksTableView extends HookConsumerWidget { ], if (!breakpoint.isSm) ...[ const SizedBox(width: 10), - PlatformText("Time", style: tableHeadStyle), + Text("Time", style: tableHeadStyle), const SizedBox(width: 10), ], SortTracksDropdown( @@ -131,44 +131,45 @@ class TracksTableView extends HookConsumerWidget { .state = value; }, ), - PlatformPopupMenuButton( - closeAfterClick: false, + PopupMenuButton( tooltip: "More Actions", - items: [ - PlatformPopupMenuItem( - enabled: selectedTracks.isNotEmpty, - value: "download", - child: Row( - children: [ - const Icon(SpotubeIcons.download), - const SizedBox(width: 5), - PlatformText( - "Download ${selectedTracks.isNotEmpty ? "(${selectedTracks.length})" : ""}", - ), - ], - ), - ), - if (!userPlaylist) - PlatformPopupMenuItem( + itemBuilder: (context) { + return [ + PopupMenuItem( enabled: selectedTracks.isNotEmpty, - value: "add-to-playlist", + value: "download", child: Row( children: [ - const Icon(SpotubeIcons.playlistAdd), + const Icon(SpotubeIcons.download), const SizedBox(width: 5), - PlatformText( - "Add (${selectedTracks.length}) to Playlist", + Text( + "Download ${selectedTracks.isNotEmpty ? "(${selectedTracks.length})" : ""}", ), ], ), ), - ], + if (!userPlaylist) + PopupMenuItem( + enabled: selectedTracks.isNotEmpty, + value: "add-to-playlist", + child: Row( + children: [ + const Icon(SpotubeIcons.playlistAdd), + const SizedBox(width: 5), + Text( + "Add (${selectedTracks.length}) to Playlist", + ), + ], + ), + ), + ]; + }, onSelected: (action) async { switch (action) { case "download": { - final confirmed = await showPlatformAlertDialog( - context, + final confirmed = await showDialog( + context: context, builder: (context) { return const ConfirmDownloadDialog(); }, @@ -183,8 +184,8 @@ class TracksTableView extends HookConsumerWidget { } case "add-to-playlist": { - await showPlatformAlertDialog( - context, + await showDialog( + context: context, builder: (context) { return PlaylistAddTrackDialog( tracks: selectedTracks.toList(), diff --git a/lib/hooks/use_custom_status_bar_color.dart b/lib/hooks/use_custom_status_bar_color.dart index bf6b8ab4..b0b893df 100644 --- a/lib/hooks/use_custom_status_bar_color.dart +++ b/lib/hooks/use_custom_status_bar_color.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:platform_ui/platform_ui.dart'; void useCustomStatusBarColor( Color color, @@ -9,7 +8,7 @@ void useCustomStatusBarColor( bool noSetBGColor = false, }) { final context = useContext(); - final backgroundColor = PlatformTheme.of(context).scaffoldBackgroundColor!; + final backgroundColor = Theme.of(context).scaffoldBackgroundColor!; resetStatusbar() => SystemChrome.setSystemUIOverlayStyle( SystemUiOverlayStyle( statusBarColor: backgroundColor, // status bar color diff --git a/lib/hooks/use_platform_property.dart b/lib/hooks/use_platform_property.dart deleted file mode 100644 index d074d574..00000000 --- a/lib/hooks/use_platform_property.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:platform_ui/platform_ui.dart'; - -T usePlatformProperty( - PlatformProperty Function(BuildContext context) getProperties) { - final context = useContext(); - - return getProperties(context).resolve(platform ?? Theme.of(context).platform); -} diff --git a/lib/hooks/use_update_checker.dart b/lib/hooks/use_update_checker.dart index 294cea99..9a4ccb9d 100644 --- a/lib/hooks/use_update_checker.dart +++ b/lib/hooks/use_update_checker.dart @@ -5,8 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:http/http.dart' as http; -import 'package:platform_ui/platform_ui.dart'; -import 'package:spotube/components/root/sidebar.dart'; + import 'package:spotube/components/shared/links/anchor_button.dart'; import 'package:spotube/hooks/use_package_info.dart'; import 'package:spotube/provider/user_preferences_provider.dart'; @@ -56,18 +55,17 @@ void useUpdateChecker(WidgetRef ref) { (latestVersion.isPreRelease && !currentVersion.isPreRelease) || (!latestVersion.isPreRelease && currentVersion.isPreRelease)) return; if (latestVersion <= currentVersion) return; - showPlatformAlertDialog( - context, + showDialog( + context: context, barrierDismissible: true, barrierColor: Colors.black26, builder: (context) { const url = "https://spotube.netlify.app/other-downloads/stable-downloads"; - return PlatformAlertDialog( - macosAppIcon: Sidebar.brandLogo(), - title: const PlatformText("Spotube has an update"), - primaryActions: [ - PlatformFilledButton( + return AlertDialog( + title: const Text("Spotube has an update"), + actions: [ + FilledButton( child: const Text("Download Now"), onPressed: () => download(url), ), @@ -79,7 +77,7 @@ void useUpdateChecker(WidgetRef ref) { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - const PlatformText("Read the latest "), + const Text("Read the latest "), AnchorButton( "release notes", style: const TextStyle(color: Colors.blue), diff --git a/lib/main.dart b/lib/main.dart index eb566af2..79f66ec5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,7 +11,6 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:package_info_plus/package_info_plus.dart'; -import 'package:platform_ui/platform_ui.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:spotube/collections/cache_keys.dart'; import 'package:spotube/collections/env.dart'; @@ -25,7 +24,7 @@ import 'package:spotube/provider/user_preferences_provider.dart'; import 'package:spotube/services/audio_player.dart'; import 'package:spotube/services/pocketbase.dart'; import 'package:spotube/services/youtube.dart'; -import 'package:spotube/themes/light_theme.dart'; +import 'package:spotube/themes/theme.dart'; import 'package:spotube/utils/platform.dart'; import 'package:window_manager/window_manager.dart'; import 'package:window_size/window_size.dart'; @@ -157,8 +156,8 @@ void main(List rawArgs) async { logger.v( "[onFileExists] download confirmation for ${track.name}", ); - return showPlatformAlertDialog( - context, + return showDialog( + context: context, builder: (_) => ReplaceDownloadedDialog(track: track), ).then((s) => s ?? false); @@ -206,14 +205,6 @@ class SpotubeState extends ConsumerState with WidgetsBindingObserver { super.initState(); SharedPreferences.getInstance().then(((value) => localStorage = value)); WidgetsBinding.instance.addObserver(this); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - setState(() { - appPlatform = Theme.of(context).platform; - if (appPlatform == TargetPlatform.macOS) { - appPlatform = TargetPlatform.android; - } - }); - }); } @override @@ -243,16 +234,6 @@ class SpotubeState extends ConsumerState with WidgetsBindingObserver { prevSize = size; } - TargetPlatform appPlatform = TargetPlatform.android; - - void changePlatform(TargetPlatform targetPlatform) { - appPlatform = targetPlatform; - if (appPlatform == TargetPlatform.macOS) { - appPlatform = TargetPlatform.android; - } - setState(() {}); - } - @override Widget build(BuildContext context) { final themeMode = @@ -268,9 +249,7 @@ class SpotubeState extends ConsumerState with WidgetsBindingObserver { }; }, []); - platform = appPlatform; - - return PlatformApp.router( + return MaterialApp.router( routeInformationParser: router.routeInformationParser, routerDelegate: router.routerDelegate, routeInformationProvider: router.routeInformationProvider, @@ -279,17 +258,10 @@ class SpotubeState extends ConsumerState with WidgetsBindingObserver { builder: (context, child) { return DragToResizeArea(child: child!); }, - androidTheme: theme(accentMaterialColor, Brightness.light), - androidDarkTheme: theme(accentMaterialColor, Brightness.dark), - linuxTheme: linuxTheme, - linuxDarkTheme: linuxDarkTheme, - iosTheme: themeMode == ThemeMode.dark ? iosDarkTheme : iosTheme, - windowsTheme: windowsTheme, - windowsDarkTheme: windowsDarkTheme, - macosTheme: macosTheme, - macosDarkTheme: macosDarkTheme, themeMode: themeMode, - shortcuts: PlatformProperty.all({ + theme: theme(accentMaterialColor, Brightness.light), + darkTheme: theme(accentMaterialColor, Brightness.dark), + shortcuts: { ...WidgetsApp.defaultShortcuts.map((key, value) { return MapEntry( LogicalKeySet.fromSet(key.triggers?.toSet() ?? {}), @@ -324,14 +296,14 @@ class SpotubeState extends ConsumerState with WidgetsBindingObserver { LogicalKeyboardKey.control, LogicalKeyboardKey.shift, ): CloseAppIntent(), - }), - actions: PlatformProperty.all({ + }, + actions: { ...WidgetsApp.defaultActions, PlayPauseIntent: PlayPauseAction(), NavigationIntent: NavigationAction(), HomeTabIntent: HomeTabAction(), CloseAppIntent: CloseAppAction(), - }), + }, ); } } diff --git a/lib/pages/artist/artist.dart b/lib/pages/artist/artist.dart index d939fedf..d8e07abe 100644 --- a/lib/pages/artist/artist.dart +++ b/lib/pages/artist/artist.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/shimmers/shimmer_artist_profile.dart'; @@ -33,13 +33,13 @@ class ArtistPage extends HookConsumerWidget { Widget build(BuildContext context, ref) { SpotifyApi spotify = ref.watch(spotifyProvider); final parentScrollController = useScrollController(); - final textTheme = PlatformTheme.of(context).textTheme; + final textTheme = Theme.of(context).textTheme; final chipTextVariant = useBreakpointValue( - sm: textTheme!.caption, - md: textTheme.body, - lg: textTheme.subheading, - xl: textTheme.headline, - xxl: textTheme.headline, + sm: textTheme.bodySmall, + md: textTheme.bodyMedium, + lg: textTheme.bodyLarge, + xl: textTheme.titleSmall, + xxl: textTheme.titleMedium, ); final avatarWidth = useBreakpointValue( @@ -58,9 +58,9 @@ class ArtistPage extends HookConsumerWidget { final auth = ref.watch(AuthenticationNotifier.provider); return SafeArea( - child: PlatformScaffold( - appBar: PageWindowTitleBar( - leading: const PlatformBackButton(), + child: Scaffold( + appBar: const PageWindowTitleBar( + leading: BackButton(), ), body: HookBuilder( builder: (context) { @@ -70,7 +70,7 @@ class ArtistPage extends HookConsumerWidget { return const ShimmerArtistProfile(); } else if (artistsQuery.hasError) { return Center( - child: PlatformText(artistsQuery.error.toString()), + child: Text(artistsQuery.error.toString()), ); } @@ -116,7 +116,7 @@ class ArtistPage extends HookConsumerWidget { decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(50)), - child: PlatformText( + child: Text( data.type!.toUpperCase(), style: chipTextVariant?.copyWith( color: Colors.white, @@ -132,7 +132,7 @@ class ArtistPage extends HookConsumerWidget { color: Colors.red[400], borderRadius: BorderRadius.circular(50)), - child: PlatformText( + child: Text( "Blacklisted", style: chipTextVariant?.copyWith( color: Colors.white, @@ -142,18 +142,18 @@ class ArtistPage extends HookConsumerWidget { ] ], ), - PlatformText( + Text( data.name!, style: breakpoint.isSm - ? textTheme.subheading - : textTheme.headline, + ? textTheme.headlineSmall + : textTheme.headlineMedium, ), - PlatformText( + Text( "${PrimitiveUtils.toReadableNumber(data.followers!.total!.toDouble())} followers", - style: breakpoint.isSm - ? textTheme.body - : textTheme.body - ?.copyWith(fontWeight: FontWeight.bold), + style: textTheme.bodyMedium?.copyWith( + fontWeight: + breakpoint.isSm ? null : FontWeight.bold, + ), ), const SizedBox(height: 20), Row( @@ -170,14 +170,13 @@ class ArtistPage extends HookConsumerWidget { return const SizedBox( height: 20, width: 20, - child: - PlatformCircularProgressIndicator(), + child: CircularProgressIndicator(), ); } final queryBowl = QueryClient.of(context); - return PlatformFilledButton( + return FilledButton( onPressed: () async { try { isFollowingQuery.data! @@ -199,7 +198,7 @@ class ArtistPage extends HookConsumerWidget { "user-follows-artists-query/$artistId"); } }, - child: PlatformText( + child: Text( isFollowingQuery.data! ? "Following" : "Follow", @@ -208,7 +207,7 @@ class ArtistPage extends HookConsumerWidget { }, ), const SizedBox(width: 5), - PlatformIconButton( + IconButton( tooltip: "Add to blacklisted artists", icon: Icon( SpotubeIcons.userRemove, @@ -216,8 +215,10 @@ class ArtistPage extends HookConsumerWidget { ? Colors.red[400] : Colors.white, ), - backgroundColor: - isBlackListed ? Colors.red[400] : null, + style: IconButton.styleFrom( + backgroundColor: + isBlackListed ? Colors.red[400] : null, + ), onPressed: () async { if (isBlackListed) { ref @@ -238,7 +239,7 @@ class ArtistPage extends HookConsumerWidget { } }, ), - PlatformIconButton( + IconButton( icon: const Icon(SpotubeIcons.share), onPressed: () async { await Clipboard.setData( @@ -250,7 +251,7 @@ class ArtistPage extends HookConsumerWidget { const SnackBar( width: 300, behavior: SnackBarBehavior.floating, - content: PlatformText( + content: Text( "Artist URL copied to clipboard", textAlign: TextAlign.center, ), @@ -279,10 +280,10 @@ class ArtistPage extends HookConsumerWidget { ); if (topTracksQuery.isLoading || !topTracksQuery.hasData) { - return const PlatformCircularProgressIndicator(); + return const CircularProgressIndicator(); } else if (topTracksQuery.hasError) { return Center( - child: PlatformText(topTracksQuery.error.toString()), + child: Text(topTracksQuery.error.toString()), ); } @@ -305,13 +306,12 @@ class ArtistPage extends HookConsumerWidget { return Column(children: [ Row( children: [ - PlatformText( + Text( "Top Tracks", - style: - PlatformTheme.of(context).textTheme?.headline, + style: Theme.of(context).textTheme.headlineSmall, ), if (!isPlaylistPlaying) - PlatformIconButton( + IconButton( icon: const Icon( SpotubeIcons.queueAdd, ), @@ -321,7 +321,7 @@ class ArtistPage extends HookConsumerWidget { SnackBar( width: 300, behavior: SnackBarBehavior.floating, - content: PlatformText( + content: Text( "Added ${topTracks.length} tracks to queue", textAlign: TextAlign.center, ), @@ -329,17 +329,17 @@ class ArtistPage extends HookConsumerWidget { ); }, ), - if (platform != TargetPlatform.linux) - const SizedBox(width: 5), - PlatformIconButton( + const SizedBox(width: 5), + IconButton( icon: Icon( isPlaylistPlaying ? SpotubeIcons.stop : SpotubeIcons.play, color: Colors.white, ), - backgroundColor: - PlatformTheme.of(context).primaryColor, + style: IconButton.styleFrom( + backgroundColor: Theme.of(context).primaryColor, + ), onPressed: () => playPlaylist(topTracks.toList()), ) ], @@ -364,16 +364,16 @@ class ArtistPage extends HookConsumerWidget { }, ), const SizedBox(height: 50), - PlatformText( + Text( "Albums", - style: PlatformTheme.of(context).textTheme?.headline, + style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox(height: 10), ArtistAlbumList(artistId), const SizedBox(height: 20), - PlatformText( + Text( "Fans also likes", - style: PlatformTheme.of(context).textTheme?.headline, + style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox(height: 10), HookBuilder( @@ -384,10 +384,10 @@ class ArtistPage extends HookConsumerWidget { ); if (relatedArtists.isLoading || !relatedArtists.hasData) { - return const PlatformCircularProgressIndicator(); + return const CircularProgressIndicator(); } else if (relatedArtists.hasError) { return Center( - child: PlatformText(relatedArtists.error.toString()), + child: Text(relatedArtists.error.toString()), ); } diff --git a/lib/pages/desktop_login/desktop_login.dart b/lib/pages/desktop_login/desktop_login.dart index aaa59f7e..a99e9050 100644 --- a/lib/pages/desktop_login/desktop_login.dart +++ b/lib/pages/desktop_login/desktop_login.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.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'; @@ -15,10 +15,9 @@ class DesktopLoginPage extends HookConsumerWidget { final breakpoint = useBreakpoints(); return SafeArea( - child: PlatformScaffold( - appBar: PageWindowTitleBar( - leading: const PlatformBackButton(), - hideWhenWindows: false, + child: Scaffold( + appBar: const PageWindowTitleBar( + leading: BackButton(), ), body: SingleChildScrollView( child: Center( @@ -26,7 +25,7 @@ class DesktopLoginPage extends HookConsumerWidget { margin: const EdgeInsets.all(10), padding: const EdgeInsets.all(10), decoration: BoxDecoration( - color: PlatformTheme.of(context).secondaryBackgroundColor, + color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(10), ), child: Column( @@ -35,11 +34,13 @@ class DesktopLoginPage extends HookConsumerWidget { width: MediaQuery.of(context).size.width * (breakpoint <= Breakpoints.md ? .5 : .3), ), - PlatformText.subheading( + Text( "Add your spotify credentials to get started", + style: Theme.of(context).textTheme.titleMedium, ), - PlatformText.label( + Text( "Don't worry, any of your credentials won't be collected or shared with anyone", + style: Theme.of(context).textTheme.labelMedium, ), const SizedBox(height: 10), TokenLoginForm( @@ -50,9 +51,9 @@ class DesktopLoginPage extends HookConsumerWidget { alignment: WrapAlignment.center, crossAxisAlignment: WrapCrossAlignment.center, children: [ - const PlatformText("Don't know how to do this?"), - PlatformTextButton( - child: const PlatformText( + const Text("Don't know how to do this?"), + TextButton( + child: const Text( "Follow along the Step by Step guide", ), onPressed: () => GoRouter.of(context).push( diff --git a/lib/pages/desktop_login/login_tutorial.dart b/lib/pages/desktop_login/login_tutorial.dart index 8f211013..de725553 100644 --- a/lib/pages/desktop_login/login_tutorial.dart +++ b/lib/pages/desktop_login/login_tutorial.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:introduction_screen/introduction_screen.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/components/desktop_login/login_form.dart'; import 'package:spotube/components/shared/links/hyper_link.dart'; @@ -21,14 +21,13 @@ class LoginTutorial extends ConsumerWidget { final key = GlobalKey>(); final pageDecoration = PageDecoration( - bodyTextStyle: PlatformTheme.of(context).textTheme!.body!, - titleTextStyle: PlatformTheme.of(context).textTheme!.subheading!, + bodyTextStyle: Theme.of(context).textTheme.bodyMedium!, + titleTextStyle: Theme.of(context).textTheme.headlineMedium!, ); - return PlatformScaffold( + return Scaffold( appBar: PageWindowTitleBar( - hideWhenWindows: false, - leading: PlatformTextButton( - child: const PlatformText("Exit"), + leading: TextButton( + child: const Text("Exit"), onPressed: () { Navigator.of(context).pop(); }, @@ -36,29 +35,27 @@ class LoginTutorial extends ConsumerWidget { ), body: IntroductionScreen( key: key, - globalBackgroundColor: - PlatformTheme.of(context).scaffoldBackgroundColor, - overrideBack: PlatformFilledButton( - isSecondary: true, - child: const Center(child: PlatformText("Previous")), + globalBackgroundColor: Theme.of(context).scaffoldBackgroundColor, + overrideBack: OutlinedButton( + child: const Center(child: Text("Previous")), onPressed: () { (key.currentState as IntroductionScreenState).previous(); }, ), - overrideNext: PlatformFilledButton( - child: const Center(child: PlatformText("Next")), + overrideNext: FilledButton( + child: const Center(child: Text("Next")), onPressed: () { (key.currentState as IntroductionScreenState).next(); }, ), showBackButton: true, - overrideDone: PlatformFilledButton( + overrideDone: FilledButton( onPressed: authenticationNotifier.isLoggedIn ? () { ServiceUtils.navigate(context, "/"); } : null, - child: const Center(child: PlatformText("Done")), + child: const Center(child: Text("Done")), ), pages: [ PageViewModel( @@ -67,14 +64,14 @@ class LoginTutorial extends ConsumerWidget { image: Assets.tutorial.step1.image(), bodyWidget: Wrap( children: const [ - PlatformText( + Text( "First, Go to ", ), Hyperlink( "accounts.spotify.com ", "https://accounts.spotify.com", ), - PlatformText( + Text( "and Login/Sign up if you're not logged in", ), ], @@ -84,7 +81,7 @@ class LoginTutorial extends ConsumerWidget { decoration: pageDecoration, title: "Step 2", image: Assets.tutorial.step2.image(), - bodyWidget: const PlatformText( + bodyWidget: const Text( "1. Once you're logged in, press F12 or Mouse Right Click > Inspect to Open the Browser devtools.\n2. Then go the \"Application\" Tab (Chrome, Edge, Brave etc..) or \"Storage\" Tab (Firefox, Palemoon etc..)\n3. Go to the \"Cookies\" section then the \"https://accounts.spotify.com\" subsection", textAlign: TextAlign.left, ), @@ -93,7 +90,7 @@ class LoginTutorial extends ConsumerWidget { decoration: pageDecoration, title: "Step 3", image: Assets.tutorial.step3.image(), - bodyWidget: const PlatformText( + bodyWidget: const Text( "Copy the values of \"sp_dc\" and \"sp_key\" Cookies", textAlign: TextAlign.left, ), @@ -114,8 +111,9 @@ class LoginTutorial extends ConsumerWidget { title: "Step 5", bodyWidget: Column( children: [ - PlatformText.label( + Text( "Paste the copied \"sp_dc\" and \"sp_key\" values in the respective fields", + style: Theme.of(context).textTheme.labelMedium, ), const SizedBox(height: 10), TokenLoginForm( diff --git a/lib/pages/home/home.dart b/lib/pages/home/home.dart index 0b7681e3..b785d38a 100644 --- a/lib/pages/home/home.dart +++ b/lib/pages/home/home.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; -import 'package:spotube/collections/spotube_icons.dart'; + import 'package:spotube/components/shared/page_window_title_bar.dart'; import 'package:spotube/pages/home/genres.dart'; import 'package:spotube/pages/home/personalized.dart'; @@ -12,57 +10,38 @@ class HomePage extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - final index = useState(0); - final tabbar = PlatformTabBar( - androidIsScrollable: true, - selectedIndex: index.value, - onSelectedIndexChanged: (value) => index.value = value, - isNavigational: - PlatformProperty.byPlatformGroup(mobile: false, desktop: true), - tabs: [ - PlatformTab( - label: 'Genres', - icon: PlatformProperty.only( - android: const SizedBox.shrink(), - other: const Icon(SpotubeIcons.genres), - ).resolve(platform!), - ), - PlatformTab( - label: 'Personalized', - icon: PlatformProperty.only( - android: const SizedBox.shrink(), - other: const Icon(SpotubeIcons.personalized), - ).resolve(platform!), - ), - ], - ); - - return PlatformScaffold( - appBar: platform == TargetPlatform.windows - ? PreferredSize( - preferredSize: const Size.fromHeight(40), - child: tabbar, - ) - : PageWindowTitleBar( - titleWidth: 347, - centerTitle: true, - center: tabbar, - ), - body: AnimatedSwitcher( - duration: const Duration(milliseconds: 300), - transitionBuilder: (child, animation) => SlideTransition( - position: animation.drive( - Tween( - begin: const Offset(1, 0), - end: const Offset(0, 0), - ), + return DefaultTabController( + length: 2, + child: Scaffold( + appBar: const PageWindowTitleBar( + titleWidth: 347, + centerTitle: true, + title: TabBar( + isScrollable: true, + tabs: [ + Tab(text: 'Genres'), + Tab(text: 'Personalized'), + ], + ), + ), + body: AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + transitionBuilder: (child, animation) => SlideTransition( + position: animation.drive( + Tween( + begin: const Offset(1, 0), + end: const Offset(0, 0), + ), + ), + child: child, + ), + child: const TabBarView( + children: [ + GenrePage(), + PersonalizedPage(), + ], ), - child: child, ), - child: [ - const GenrePage(), - const PersonalizedPage(), - ][index.value], ), ); } diff --git a/lib/pages/home/personalized.dart b/lib/pages/home/personalized.dart index a502103d..3c80ba8c 100644 --- a/lib/pages/home/personalized.dart +++ b/lib/pages/home/personalized.dart @@ -2,7 +2,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart' hide Page; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/components/album/album_card.dart'; import 'package:spotube/components/playlist/playlist_card.dart'; @@ -53,7 +53,10 @@ class PersonalizedItemCard extends HookWidget { padding: const EdgeInsets.all(8.0), child: Row( children: [ - PlatformText.headline(title), + Text( + title, + style: Theme.of(context).textTheme.titleLarge, + ), ], ), ), diff --git a/lib/pages/library/library.dart b/lib/pages/library/library.dart index d18ce290..2d4dc7b3 100644 --- a/lib/pages/library/library.dart +++ b/lib/pages/library/library.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart' hide Image; -import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/components/library/user_local_tracks.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; import 'package:spotube/components/library/user_albums.dart'; @@ -13,43 +12,34 @@ class LibraryPage extends HookConsumerWidget { const LibraryPage({Key? key}) : super(key: key); @override Widget build(BuildContext context, ref) { - final index = useState(0); - - final body = [ - const UserPlaylists(), - const UserLocalTracks(), - const UserDownloads(), - const UserArtists(), - const UserAlbums(), - ][index.value]; - - final tabbar = PlatformTabBar( - androidIsScrollable: true, - selectedIndex: index.value, - onSelectedIndexChanged: (value) => index.value = value, - isNavigational: - PlatformProperty.byPlatformGroup(mobile: false, desktop: true), - tabs: [ - PlatformTab(label: 'Playlists', icon: const SizedBox.shrink()), - PlatformTab(label: 'Tracks', icon: const SizedBox.shrink()), - PlatformTab(label: 'Downloads', icon: const SizedBox.shrink()), - PlatformTab(label: 'Artists', icon: const SizedBox.shrink()), - PlatformTab(label: 'Albums', icon: const SizedBox.shrink()), - ], - ); - return SafeArea( - child: PlatformScaffold( - appBar: platform == TargetPlatform.windows - ? PreferredSize( - preferredSize: const Size.fromHeight(40), - child: tabbar, - ) - : PageWindowTitleBar( - titleWidth: 347, - centerTitle: true, - center: tabbar, - ), - body: body, + return const SafeArea( + child: DefaultTabController( + length: 5, + child: Scaffold( + appBar: PageWindowTitleBar( + titleWidth: 347, + centerTitle: true, + title: TabBar( + isScrollable: true, + tabs: [ + Tab(text: 'Playlists'), + Tab(text: 'Tracks'), + Tab(text: 'Downloads'), + Tab(text: 'Artists'), + Tab(text: 'Albums'), + ], + ), + ), + body: TabBarView( + children: [ + UserPlaylists(), + UserLocalTracks(), + UserDownloads(), + UserArtists(), + UserAlbums(), + ], + ), + ), ), ); } diff --git a/lib/pages/lyrics/lyrics.dart b/lib/pages/lyrics/lyrics.dart index ee61deef..58d93db4 100644 --- a/lib/pages/lyrics/lyrics.dart +++ b/lib/pages/lyrics/lyrics.dart @@ -3,7 +3,7 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; @@ -31,7 +31,6 @@ class LyricsPage extends HookConsumerWidget { [playlist?.activeTrack.album?.images], ); final palette = usePaletteColor(albumArt, ref); - final index = useState(0); useCustomStatusBarColor( palette.color, @@ -39,102 +38,101 @@ class LyricsPage extends HookConsumerWidget { noSetBGColor: true, ); - Widget body = [ - SyncedLyrics(palette: palette, isModal: isModal), - PlainLyrics(palette: palette, isModal: isModal), - ][index.value]; - - final tabbar = PreferredSize( - preferredSize: const Size.fromHeight(50), - child: PlatformTabBar( - isNavigational: PlatformProperty.only(linux: true, other: false), - selectedIndex: index.value, - onSelectedIndexChanged: (value) => index.value = value, - backgroundColor: PlatformTheme.of(context).scaffoldBackgroundColor, - tabs: [ - PlatformTab( - label: "Synced", - icon: const SizedBox.shrink(), - color: PlatformTextTheme.of(context).caption?.color, - ), - PlatformTab( - label: "Plain", - icon: const SizedBox.shrink(), - color: PlatformTextTheme.of(context).caption?.color, - ), - ], - ), + const tabbar = TabBar( + isScrollable: true, + tabs: [ + Tab(text: "Synced"), + Tab(text: "Plain"), + ], ); if (isModal) { - return SafeArea( - child: Container( - clipBehavior: Clip.hardEdge, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background.withOpacity(.4), - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(10), - topRight: Radius.circular(10), + return DefaultTabController( + length: 2, + child: SafeArea( + child: Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.background.withOpacity(.4), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10), + ), ), - ), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 50, sigmaY: 50), - child: Column( - children: [ - const SizedBox(height: 5), - Container( - height: 7, - width: 150, - decoration: BoxDecoration( - color: palette.titleTextColor, - borderRadius: BorderRadius.circular(10), - ), - ), - PlatformAppBar( - title: tabbar, - backgroundColor: Colors.transparent, - automaticallyImplyLeading: false, - toolbarOpacity: platform == TargetPlatform.iOS ? 0 : 1, - actions: [ - PlatformIconButton( - icon: const Icon(SpotubeIcons.minimize), - onPressed: () => Navigator.of(context).pop(), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 50, sigmaY: 50), + child: Column( + children: [ + const SizedBox(height: 5), + Container( + height: 7, + width: 150, + decoration: BoxDecoration( + color: palette.titleTextColor, + borderRadius: BorderRadius.circular(10), ), - const SizedBox(width: 5), - ], - ), - Expanded(child: body), - ], + ), + AppBar( + title: tabbar, + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + toolbarOpacity: 1, + actions: [ + IconButton( + icon: const Icon(SpotubeIcons.minimize), + onPressed: () => Navigator.of(context).pop(), + ), + const SizedBox(width: 5), + ], + ), + Expanded( + child: TabBarView( + children: [ + SyncedLyrics(palette: palette, isModal: isModal), + PlainLyrics(palette: palette, isModal: isModal), + ], + ), + ), + ], + ), ), ), ), ); } - return PlatformScaffold( - extendBodyBehindAppBar: true, - appBar: !kIsMacOS - ? (platform != TargetPlatform.windows && !isModal - ? PageWindowTitleBar( - toolbarOpacity: 0, - backgroundColor: Colors.transparent, - center: tabbar, - ) - : tabbar) - : null, - body: Container( - clipBehavior: Clip.hardEdge, - decoration: BoxDecoration( - image: DecorationImage( - image: UniversalImage.imageProvider(albumArt), - fit: BoxFit.cover, + return DefaultTabController( + length: 2, + child: Scaffold( + extendBodyBehindAppBar: true, + appBar: !kIsMacOS + ? const PageWindowTitleBar( + toolbarOpacity: 0, + backgroundColor: Colors.transparent, + title: tabbar, + ) + : tabbar as PreferredSizeWidget?, + body: Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + image: DecorationImage( + image: UniversalImage.imageProvider(albumArt), + fit: BoxFit.cover, + ), + borderRadius: BorderRadius.circular(8), ), - borderRadius: BorderRadius.circular(8), - ), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), - child: ColoredBox( - color: palette.color.withOpacity(.7), - child: SafeArea(child: body), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), + child: ColoredBox( + color: palette.color.withOpacity(.7), + child: SafeArea( + child: TabBarView( + children: [ + SyncedLyrics(palette: palette, isModal: isModal), + PlainLyrics(palette: palette, isModal: isModal), + ], + ), + ), + ), ), ), ), diff --git a/lib/pages/mobile_login/mobile_login.dart b/lib/pages/mobile_login/mobile_login.dart index 82edaa78..7ab0ea2a 100644 --- a/lib/pages/mobile_login/mobile_login.dart +++ b/lib/pages/mobile_login/mobile_login.dart @@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/provider/authentication_provider.dart'; import 'package:spotube/utils/platform.dart'; @@ -24,7 +24,7 @@ class WebViewLogin extends HookConsumerWidget { ); } - return PlatformScaffold( + return Scaffold( body: SafeArea( child: InAppWebView( initialOptions: InAppWebViewGroupOptions( diff --git a/lib/pages/player/player.dart b/lib/pages/player/player.dart index 202eb256..093f742e 100644 --- a/lib/pages/player/player.dart +++ b/lib/pages/player/player.dart @@ -5,7 +5,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:palette_generator/palette_generator.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/player/player_actions.dart'; @@ -65,20 +65,12 @@ class PlayerView extends HookConsumerWidget { noSetBGColor: true, ); - return PlatformScaffold( + return Scaffold( appBar: PageWindowTitleBar( - hideWhenWindows: false, backgroundColor: Colors.transparent, foregroundColor: paletteColor.titleTextColor, - toolbarOpacity: - PlatformProperty.only(android: 1.0, windows: 1.0, other: 0.0) - .resolve(platform ?? Theme.of(context).platform), - leading: PlatformBackButton( - color: PlatformProperty.only( - macos: Colors.black, - other: paletteColor.titleTextColor, - ).resolve(platform!), - ), + toolbarOpacity: 1, + leading: BackButton(color: paletteColor.titleTextColor), ), extendBodyBehindAppBar: true, body: Container( @@ -91,7 +83,6 @@ class PlayerView extends HookConsumerWidget { child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), child: Material( - textStyle: PlatformTheme.of(context).textTheme!.body!, color: paletteColor.color.withOpacity(.5), child: SafeArea( child: Column( @@ -104,11 +95,13 @@ class PlayerView extends HookConsumerWidget { height: 30, child: SpotubeMarqueeText( text: currentTrack?.name ?? "Not playing", - style: - Theme.of(context).textTheme.headline5?.copyWith( - fontWeight: FontWeight.bold, - color: paletteColor.titleTextColor, - ), + style: Theme.of(context) + .textTheme + .headlineSmall + ?.copyWith( + fontWeight: FontWeight.bold, + color: paletteColor.titleTextColor, + ), isHovering: true, ), ), @@ -117,20 +110,24 @@ class PlayerView extends HookConsumerWidget { TypeConversionUtils.artists_X_String( currentTrack?.artists ?? [], ), - style: - Theme.of(context).textTheme.headline6!.copyWith( - fontWeight: FontWeight.bold, - color: paletteColor.bodyTextColor, - ), + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: paletteColor.bodyTextColor, + ), ) else TypeConversionUtils.artists_X_ClickableArtists( currentTrack?.artists ?? [], - textStyle: - Theme.of(context).textTheme.headline6!.copyWith( - fontWeight: FontWeight.bold, - color: paletteColor.bodyTextColor, - ), + textStyle: Theme.of(context) + .textTheme + .titleLarge! + .copyWith( + fontWeight: FontWeight.bold, + color: paletteColor.bodyTextColor, + ), onRouteChange: (route) { GoRouter.of(context).pop(); GoRouter.of(context).push(route); @@ -193,7 +190,7 @@ class PlayerView extends HookConsumerWidget { mainAxisAlignment: MainAxisAlignment.spaceEvenly, floatingQueue: false, extraActions: [ - PlatformIconButton( + IconButton( tooltip: "Open Lyrics", icon: const Icon(SpotubeIcons.music), onPressed: () { diff --git a/lib/pages/root/root_app.dart b/lib/pages/root/root_app.dart index b696a5f3..43620606 100644 --- a/lib/pages/root/root_app.dart +++ b/lib/pages/root/root_app.dart @@ -3,12 +3,10 @@ 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:platform_ui/platform_ui.dart'; import 'package:spotube/components/shared/dialogs/replace_downloaded_dialog.dart'; import 'package:spotube/components/root/bottom_player.dart'; import 'package:spotube/components/root/sidebar.dart'; import 'package:spotube/components/root/spotube_navigation_bar.dart'; -import 'package:spotube/components/shared/page_window_title_bar.dart'; import 'package:spotube/hooks/use_update_checker.dart'; import 'package:spotube/provider/downloader_provider.dart'; @@ -35,8 +33,8 @@ class RootApp extends HookConsumerWidget { useEffect(() { downloader.onFileExists = (track) async { if (!isMounted()) return false; - return await showPlatformAlertDialog( - context, + return await showDialog( + context: context, builder: (context) => ReplaceDownloadedDialog( track: track, ), @@ -49,7 +47,7 @@ class RootApp extends HookConsumerWidget { // checks for latest version of the application useUpdateChecker(ref); - final backgroundColor = PlatformTheme.of(context).scaffoldBackgroundColor!; + final backgroundColor = Theme.of(context).scaffoldBackgroundColor; useEffect(() { SystemChrome.setSystemUIOverlayStyle( @@ -63,10 +61,7 @@ class RootApp extends HookConsumerWidget { return null; }, [backgroundColor]); - return PlatformScaffold( - appBar: platform == TargetPlatform.windows - ? PageWindowTitleBar(hideWhenWindows: false) as PreferredSizeWidget? - : null, + return Scaffold( body: Sidebar( selectedIndex: index.value, onSelectedIndexChanged: (i) { diff --git a/lib/pages/search/search.dart b/lib/pages/search/search.dart index 1c4b247b..1209add6 100644 --- a/lib/pages/search/search.dart +++ b/lib/pages/search/search.dart @@ -4,7 +4,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart' hide Page; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotify/spotify.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/album/album_card.dart'; @@ -62,7 +62,7 @@ class SearchPage extends HookConsumerWidget { } return SafeArea( - child: PlatformScaffold( + child: Scaffold( appBar: kIsDesktop && !kIsMacOS ? PageWindowTitleBar() : null, body: !authenticationNotifier.isLoggedIn ? const AnonymousFallback() @@ -73,15 +73,12 @@ class SearchPage extends HookConsumerWidget { horizontal: 20, vertical: 10, ), - color: PlatformTheme.of(context).scaffoldBackgroundColor, - child: PlatformTextField( - prefixIcon: SpotubeIcons.search, - prefixIconColor: PlatformProperty.only( - ios: - PlatformTheme.of(context).textTheme?.caption?.color, - other: null, - ).resolve(platform!), - placeholder: "Search...", + color: Theme.of(context).scaffoldBackgroundColor, + child: TextField( + decoration: const InputDecoration( + prefixIcon: Icon(SpotubeIcons.search), + hintText: "Search...", + ), onSubmitted: (value) async { ref.read(searchTermStateProvider.notifier).state = value; @@ -133,11 +130,15 @@ class SearchPage extends HookConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ if (tracks.isNotEmpty) - PlatformText.headline("Songs"), + Text( + "Songs", + style: + Theme.of(context).textTheme.titleLarge!, + ), if (searchTrack.isLoadingPage) - const PlatformCircularProgressIndicator() + const CircularProgressIndicator() else if (searchTrack.hasPageError) - PlatformText(searchTrack.errors.lastOrNull + Text(searchTrack.errors.lastOrNull ?.toString() ?? "") else @@ -182,17 +183,21 @@ class SearchPage extends HookConsumerWidget { if (searchTrack.hasNextPage && tracks.isNotEmpty) Center( - child: PlatformTextButton( + child: TextButton( onPressed: searchTrack.isRefreshingPage ? null : () => searchTrack.fetchNext(), child: searchTrack.isRefreshingPage - ? const PlatformCircularProgressIndicator() - : const PlatformText("Load more"), + ? const CircularProgressIndicator() + : const Text("Load more"), ), ), if (playlists.isNotEmpty) - PlatformText.headline("Playlists"), + Text( + "Playlists", + style: + Theme.of(context).textTheme.titleLarge!, + ), const SizedBox(height: 10), ScrollConfiguration( behavior: @@ -236,16 +241,20 @@ class SearchPage extends HookConsumerWidget { ), ), if (searchPlaylist.isLoadingPage) - const PlatformCircularProgressIndicator(), + const CircularProgressIndicator(), if (searchPlaylist.hasPageError) - PlatformText( + Text( searchPlaylist.errors.lastOrNull ?.toString() ?? "", ), const SizedBox(height: 20), if (artists.isNotEmpty) - PlatformText.headline("Artists"), + Text( + "Artists", + style: + Theme.of(context).textTheme.titleLarge!, + ), const SizedBox(height: 10), ScrollConfiguration( behavior: @@ -289,16 +298,21 @@ class SearchPage extends HookConsumerWidget { ), ), if (searchArtist.isLoadingPage) - const PlatformCircularProgressIndicator(), + const CircularProgressIndicator(), if (searchArtist.hasPageError) - PlatformText( + Text( searchArtist.errors.lastOrNull ?.toString() ?? "", ), const SizedBox(height: 20), if (albums.isNotEmpty) - PlatformText.subheading("Albums"), + Text( + "Albums", + style: Theme.of(context) + .textTheme + .titleMedium!, + ), const SizedBox(height: 10), ScrollConfiguration( behavior: @@ -340,9 +354,9 @@ class SearchPage extends HookConsumerWidget { ), ), if (searchAlbum.isLoadingPage) - const PlatformCircularProgressIndicator(), + const CircularProgressIndicator(), if (searchAlbum.hasPageError) - PlatformText( + Text( searchAlbum.errors.lastOrNull?.toString() ?? "", ), diff --git a/lib/pages/settings/about.dart b/lib/pages/settings/about.dart index 0ae82686..6e51a4cd 100644 --- a/lib/pages/settings/about.dart +++ b/lib/pages/settings/about.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:platform_ui/platform_ui.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; @@ -17,10 +16,10 @@ class AboutSpotube extends HookConsumerWidget { Widget build(BuildContext context, ref) { final packageInfo = usePackageInfo(); - return PlatformScaffold( + return Scaffold( appBar: PageWindowTitleBar( - leading: const PlatformBackButton(), - center: const PlatformText("About Spotube"), + leading: const BackButton(), + title: const Text("About Spotube"), ), body: SingleChildScrollView( child: Padding( @@ -35,14 +34,15 @@ class AboutSpotube extends HookConsumerWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - PlatformText.headline( + Text( "Spotube, a light-weight, cross-platform, free-for-all spotify client", + style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 20), Row( mainAxisSize: MainAxisSize.min, children: [ - const PlatformText( + const Text( "Founder: Kingkor Roy Tirtho", style: TextStyle( fontWeight: FontWeight.bold, @@ -60,11 +60,11 @@ class AboutSpotube extends HookConsumerWidget { ], ), const SizedBox(height: 5), - PlatformText( + Text( "Version: v${packageInfo.version}", ), const SizedBox(height: 5), - PlatformText( + Text( "Build Number: ${packageInfo.buildNumber.replaceAll(".", " ")}", ), const SizedBox(height: 5), @@ -75,7 +75,7 @@ class AboutSpotube extends HookConsumerWidget { mode: LaunchMode.externalApplication, ); }, - child: const PlatformText( + child: const Text( "Repository: https://github.com/KRTirtho/spotube", ), ), @@ -87,7 +87,7 @@ class AboutSpotube extends HookConsumerWidget { mode: LaunchMode.externalApplication, ); }, - child: const PlatformText( + child: const Text( "License: BSD-4-Clause", ), ), @@ -99,7 +99,7 @@ class AboutSpotube extends HookConsumerWidget { mode: LaunchMode.externalApplication, ); }, - child: const PlatformText( + child: const Text( "Bugs+Issues: https://github.com/KRTirtho/spotube/issues", ), ), @@ -178,21 +178,24 @@ class AboutSpotube extends HookConsumerWidget { ], ), const SizedBox(height: 20), - PlatformText.caption( + Text( "Made with ❤️ in Bangladesh🇧🇩", textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodySmall, ), - PlatformText.caption( + Text( "© 2021-${DateTime.now().year} Kingkor Roy Tirtho", textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodySmall, ), const SizedBox(height: 20), ConstrainedBox( constraints: const BoxConstraints(maxWidth: 750), child: SafeArea( - child: PlatformText.caption( + child: Text( licenseText, textAlign: TextAlign.justify, + style: Theme.of(context).textTheme.bodySmall, ), ), ), diff --git a/lib/pages/settings/blacklist.dart b/lib/pages/settings/blacklist.dart index 7297b024..ed78a5e1 100644 --- a/lib/pages/settings/blacklist.dart +++ b/lib/pages/settings/blacklist.dart @@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:collection/collection.dart'; import 'package:fuzzywuzzy/fuzzywuzzy.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; import 'package:spotube/provider/blacklist_provider.dart'; @@ -35,23 +35,23 @@ class BlackListPage extends HookConsumerWidget { [blacklist, searchText.value], ); - return PlatformScaffold( + return Scaffold( appBar: PageWindowTitleBar( - center: const PlatformText("Blacklist"), + title: const Text("Blacklist"), centerTitle: true, - leading: const PlatformBackButton(), + leading: const BackButton(), ), body: Column( mainAxisSize: MainAxisSize.min, children: [ Padding( - padding: platform == TargetPlatform.windows - ? const EdgeInsets.all(8.0).copyWith(left: 45) - : const EdgeInsets.all(8.0), - child: PlatformTextField( + padding: const EdgeInsets.all(8.0), + child: TextField( onChanged: (value) => searchText.value = value, - placeholder: "Search", - prefixIcon: SpotubeIcons.search, + decoration: const InputDecoration( + hintText: "Search", + prefixIcon: Icon(SpotubeIcons.search), + ), ), ), ListView.builder( @@ -59,11 +59,11 @@ class BlackListPage extends HookConsumerWidget { itemCount: filteredBlacklist.length, itemBuilder: (context, index) { final item = filteredBlacklist.elementAt(index); - return PlatformListTile( - leading: PlatformText("${index + 1}."), - title: PlatformText("${item.name} (${item.type.name})"), - subtitle: PlatformText.caption(item.id), - trailing: PlatformIconButton( + return ListTile( + leading: Text("${index + 1}."), + title: Text("${item.name} (${item.type.name})"), + subtitle: Text(item.id), + trailing: IconButton( icon: Icon(SpotubeIcons.trash, color: Colors.red[400]), onPressed: () { ref diff --git a/lib/pages/settings/settings.dart b/lib/pages/settings/settings.dart index b71cf751..bc41a915 100644 --- a/lib/pages/settings/settings.dart +++ b/lib/pages/settings/settings.dart @@ -4,12 +4,11 @@ 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:platform_ui/platform_ui.dart'; + import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/settings/color_scheme_picker_dialog.dart'; import 'package:spotube/components/shared/adaptive/adaptive_list_tile.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; -import 'package:spotube/main.dart'; import 'package:spotube/collections/spotify_markets.dart'; import 'package:spotube/provider/authentication_provider.dart'; import 'package:spotube/provider/user_preferences_provider.dart'; @@ -24,7 +23,9 @@ class SettingsPage extends HookConsumerWidget { final auth = ref.watch(AuthenticationNotifier.provider); final pickColorScheme = useCallback((ColorSchemeType schemeType) { - return () => showPlatformAlertDialog(context, builder: (context) { + return () => showDialog( + context: context, + builder: (context) { return ColorSchemePickerDialog( schemeType: schemeType, ); @@ -40,9 +41,9 @@ class SettingsPage extends HookConsumerWidget { }, [preferences.downloadLocation]); return SafeArea( - child: PlatformScaffold( + child: Scaffold( appBar: PageWindowTitleBar( - center: PlatformText.headline("Settings"), + title: const Text("Settings"), centerTitle: true, ), body: Row( @@ -53,17 +54,18 @@ class SettingsPage extends HookConsumerWidget { constraints: const BoxConstraints(maxWidth: 1366), child: ListView( children: [ - PlatformText( + Text( " Account", - style: PlatformTextTheme.of(context) - .headline + style: Theme.of(context) + .textTheme + .headlineSmall ?.copyWith(fontWeight: FontWeight.bold), ), if (auth == null) AdaptiveListTile( leading: Icon( SpotubeIcons.login, - color: PlatformTheme.of(context).primaryColor, + color: Theme.of(context).primaryColor, ), title: SizedBox( height: 50, @@ -74,12 +76,12 @@ class SettingsPage extends HookConsumerWidget { "Login with your Spotify account", maxLines: 1, style: TextStyle( - color: PlatformTheme.of(context).primaryColor, + color: Theme.of(context).primaryColor, ), ), ), ), - trailing: (context, update) => PlatformFilledButton( + trailing: (context, update) => FilledButton( onPressed: () { GoRouter.of(context).push("/login"); }, @@ -90,15 +92,14 @@ class SettingsPage extends HookConsumerWidget { ), ), ), - child: PlatformText( - "Connect with Spotify".toUpperCase()), + child: Text("Connect with Spotify".toUpperCase()), ), ) else Builder(builder: (context) { - return PlatformListTile( + return ListTile( leading: const Icon(SpotubeIcons.logout), - title: SizedBox( + title: const SizedBox( height: 50, width: 180, child: Align( @@ -106,11 +107,10 @@ class SettingsPage extends HookConsumerWidget { child: AutoSizeText( "Log out of this account", maxLines: 1, - style: PlatformTextTheme.of(context).body, ), ), ), - trailing: PlatformFilledButton( + trailing: FilledButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all(Colors.red), @@ -124,44 +124,40 @@ class SettingsPage extends HookConsumerWidget { .logout(); GoRouter.of(context).pop(); }, - child: const PlatformText("Logout"), + child: const Text("Logout"), ), ); }), - PlatformText( + Text( " Appearance", - style: PlatformTextTheme.of(context) - .headline + style: Theme.of(context) + .textTheme + .headlineSmall ?.copyWith(fontWeight: FontWeight.bold), ), AdaptiveListTile( leading: const Icon(SpotubeIcons.dashboard), - title: const PlatformText("Layout Mode"), - subtitle: const PlatformText( + title: const Text("Layout Mode"), + subtitle: const Text( "Override responsive layout mode settings", ), - trailing: (context, update) => - PlatformDropDownMenu( - value: preferences.layoutMode, - items: [ - PlatformDropDownMenuItem( + trailing: (context, update) => DropdownMenu( + dropdownMenuEntries: const [ + DropdownMenuEntry( value: LayoutMode.adaptive, - child: const PlatformText( - "Adaptive", - ), + label: "Adaptive", ), - PlatformDropDownMenuItem( + DropdownMenuEntry( value: LayoutMode.compact, - child: const PlatformText( - "Compact", - ), + label: "Compact", ), - PlatformDropDownMenuItem( + DropdownMenuEntry( value: LayoutMode.extended, - child: const PlatformText("Extended"), + label: "Extended", ), ], - onChanged: (value) { + initialSelection: preferences.layoutMode, + onSelected: (value) { if (value != null) { preferences.setLayoutMode(value); update?.call(() {}); @@ -171,25 +167,24 @@ class SettingsPage extends HookConsumerWidget { ), AdaptiveListTile( leading: const Icon(SpotubeIcons.darkMode), - title: const PlatformText("Theme"), - trailing: (context, update) => - PlatformDropDownMenu( - value: preferences.themeMode, - items: [ - PlatformDropDownMenuItem( + title: const Text("Theme"), + trailing: (context, update) => DropdownMenu( + initialSelection: preferences.themeMode, + dropdownMenuEntries: const [ + DropdownMenuEntry( value: ThemeMode.dark, - child: const PlatformText("Dark"), + label: "Dark", ), - PlatformDropDownMenuItem( + DropdownMenuEntry( value: ThemeMode.light, - child: const PlatformText("Light"), + label: "Light", ), - PlatformDropDownMenuItem( + DropdownMenuEntry( value: ThemeMode.system, - child: const PlatformText("System"), + label: "System", ), ], - onChanged: (value) { + onSelected: (value) { if (value != null) { preferences.setThemeMode(value); update?.call(() {}); @@ -197,45 +192,9 @@ class SettingsPage extends HookConsumerWidget { }, ), ), - AdaptiveListTile( - leading: const Icon(SpotubeIcons.platform), - title: const PlatformText("Mimic Platform"), - trailing: (context, update) => - DropdownButton( - value: Spotube.of(context).appPlatform, - items: const [ - DropdownMenuItem( - value: TargetPlatform.android, - child: PlatformText("Android (Material You)"), - ), - DropdownMenuItem( - value: TargetPlatform.iOS, - child: PlatformText("iOS (Cupertino)"), - ), - DropdownMenuItem( - value: TargetPlatform.macOS, - child: PlatformText("macOS (Aqua)"), - ), - DropdownMenuItem( - value: TargetPlatform.linux, - child: PlatformText("Linux (GTK+Libadwaita)"), - ), - DropdownMenuItem( - value: TargetPlatform.windows, - child: PlatformText("Windows 11 (Fluent UI)"), - ), - ], - onChanged: (value) { - if (value != null) { - Spotube.of(context).changePlatform(value); - update?.call(() {}); - } - }, - ), - ), - PlatformListTile( + ListTile( leading: const Icon(SpotubeIcons.palette), - title: const PlatformText("Accent Color"), + title: const Text("Accent Color"), contentPadding: const EdgeInsets.symmetric( horizontal: 15, vertical: 5, @@ -247,41 +206,37 @@ class SettingsPage extends HookConsumerWidget { ), onTap: pickColorScheme(ColorSchemeType.accent), ), - PlatformListTile( - leading: const Icon(SpotubeIcons.album), - title: const PlatformText("Rotating Album Art"), - trailing: PlatformSwitch( - value: preferences.rotatingAlbumArt, - onChanged: (state) { - preferences.setRotatingAlbumArt(state); - }, - ), + SwitchListTile( + secondary: const Icon(SpotubeIcons.album), + title: const Text("Rotating Album Art"), + value: preferences.rotatingAlbumArt, + onChanged: (state) { + preferences.setRotatingAlbumArt(state); + }, ), - PlatformText( + Text( " Playback", - style: PlatformTextTheme.of(context) - .headline + style: Theme.of(context) + .textTheme + .headlineSmall ?.copyWith(fontWeight: FontWeight.bold), ), AdaptiveListTile( leading: const Icon(SpotubeIcons.audioQuality), - title: const PlatformText("Audio Quality"), - trailing: (context, update) => - PlatformDropDownMenu( - value: preferences.audioQuality, - items: [ - PlatformDropDownMenuItem( + title: const Text("Audio Quality"), + trailing: (context, update) => DropdownMenu( + initialSelection: preferences.audioQuality, + dropdownMenuEntries: const [ + DropdownMenuEntry( value: AudioQuality.high, - child: const PlatformText( - "High", - ), + label: "High", ), - PlatformDropDownMenuItem( + DropdownMenuEntry( value: AudioQuality.low, - child: const PlatformText("Low"), + label: "Low", ), ], - onChanged: (value) { + onSelected: (value) { if (value != null) { preferences.setAudioQuality(value); update?.call(() {}); @@ -289,37 +244,31 @@ class SettingsPage extends HookConsumerWidget { }, ), ), - PlatformListTile( - leading: const Icon(SpotubeIcons.download), - title: const PlatformText( - "Pre download and play", - ), - subtitle: const PlatformText( + SwitchListTile( + secondary: const Icon(SpotubeIcons.download), + title: const Text("Pre download and play"), + subtitle: const Text( "Instead of streaming audio, download bytes and play instead (Recommended for higher bandwidth users)", ), - trailing: PlatformSwitch( - value: preferences.predownload, - onChanged: (state) { - preferences.setPredownload(state); - }, - ), + value: preferences.predownload, + onChanged: (state) { + preferences.setPredownload(state); + }, ), - PlatformListTile( - leading: const Icon(SpotubeIcons.fastForward), - title: const PlatformText( + SwitchListTile( + secondary: const Icon(SpotubeIcons.fastForward), + title: const Text( "Skip non-music segments (SponsorBlock)", ), - trailing: PlatformSwitch( - value: preferences.skipSponsorSegments, - onChanged: (state) { - preferences.setSkipSponsorSegments(state); - }, - ), + value: preferences.skipSponsorSegments, + onChanged: (state) { + preferences.setSkipSponsorSegments(state); + }, ), - PlatformListTile( + ListTile( leading: const Icon(SpotubeIcons.playlistRemove), - title: const PlatformText("Blacklist"), - subtitle: const PlatformText( + title: const Text("Blacklist"), + subtitle: const Text( "Blacklisted tracks and artists", ), onTap: () { @@ -327,31 +276,30 @@ class SettingsPage extends HookConsumerWidget { }, trailing: const Icon(SpotubeIcons.angleRight), ), - PlatformText( + Text( " Search", - style: PlatformTextTheme.of(context) - .headline + style: Theme.of(context) + .textTheme + .headlineSmall ?.copyWith(fontWeight: FontWeight.bold), ), AdaptiveListTile( leading: const Icon(SpotubeIcons.shoppingBag), - title: const PlatformText("Market Place"), - subtitle: PlatformText.caption( - "Recommendation Country", - ), + title: const Text("Market Place"), + subtitle: const Text("Recommendation Country"), trailing: (context, update) => ConstrainedBox( constraints: const BoxConstraints(maxWidth: 350), - child: PlatformDropDownMenu( - value: preferences.recommendationMarket, - items: spotifyMarkets + child: DropdownMenu( + initialSelection: preferences.recommendationMarket, + dropdownMenuEntries: spotifyMarkets .map( - (country) => (PlatformDropDownMenuItem( + (country) => DropdownMenuEntry( value: country.first, - child: PlatformText(country.last), - )), + label: country.last, + ), ) .toList(), - onChanged: (value) { + onSelected: (value) { if (value == null) return; preferences.setRecommendationMarket( value as String, @@ -361,37 +309,36 @@ class SettingsPage extends HookConsumerWidget { ), ), ), - PlatformText( + Text( " Downloads", - style: PlatformTextTheme.of(context) - .headline + style: Theme.of(context) + .textTheme + .headlineSmall ?.copyWith(fontWeight: FontWeight.bold), ), - PlatformListTile( + ListTile( leading: const Icon(SpotubeIcons.download), - title: const PlatformText("Download Location"), - subtitle: PlatformText(preferences.downloadLocation), - trailing: PlatformFilledButton( + title: const Text("Download Location"), + subtitle: Text(preferences.downloadLocation), + trailing: FilledButton( onPressed: pickDownloadLocation, child: const Icon(SpotubeIcons.folder), ), onTap: pickDownloadLocation, ), - PlatformListTile( - leading: const Icon(SpotubeIcons.lyrics), - title: const PlatformText( - "Download lyrics along with the Track"), - trailing: PlatformSwitch( - value: preferences.saveTrackLyrics, - onChanged: (state) { - preferences.setSaveTrackLyrics(state); - }, - ), + SwitchListTile( + secondary: const Icon(SpotubeIcons.lyrics), + title: const Text("Download lyrics along with the Track"), + value: preferences.saveTrackLyrics, + onChanged: (state) { + preferences.setSaveTrackLyrics(state); + }, ), - PlatformText( + Text( " About", - style: PlatformTextTheme.of(context) - .headline + style: Theme.of(context) + .textTheme + .headlineSmall ?.copyWith(fontWeight: FontWeight.bold), ), AdaptiveListTile( @@ -414,7 +361,7 @@ class SettingsPage extends HookConsumerWidget { ), ), ), - trailing: (context, update) => PlatformFilledButton( + trailing: (context, update) => FilledButton( style: ButtonStyle( backgroundColor: MaterialStatePropertyAll(Colors.red[100]), @@ -434,23 +381,21 @@ class SettingsPage extends HookConsumerWidget { children: const [ Icon(SpotubeIcons.heart), SizedBox(width: 5), - PlatformText("Please Sponsor/Donate"), + Text("Please Sponsor/Donate"), ], ), ), ), - PlatformListTile( - leading: const Icon(SpotubeIcons.update), - title: const PlatformText("Check for Update"), - trailing: PlatformSwitch( - value: preferences.checkUpdate, - onChanged: (checked) => - preferences.setCheckUpdate(checked), - ), + SwitchListTile( + secondary: const Icon(SpotubeIcons.update), + title: const Text("Check for Update"), + value: preferences.checkUpdate, + onChanged: (checked) => + preferences.setCheckUpdate(checked), ), - PlatformListTile( + ListTile( leading: const Icon(SpotubeIcons.info), - title: const PlatformText("About Spotube"), + title: const Text("About Spotube"), trailing: const Icon(SpotubeIcons.angleRight), onTap: () { GoRouter.of(context).push("/settings/about"); diff --git a/lib/themes/dark_theme.dart b/lib/themes/dark_theme.dart deleted file mode 100644 index a2d735e1..00000000 --- a/lib/themes/dark_theme.dart +++ /dev/null @@ -1,120 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:spotube/extensions/theme.dart'; - -ThemeData darkTheme({ - required MaterialColor accentMaterialColor, - required MaterialColor backgroundMaterialColor, -}) { - return ThemeData( - useMaterial3: true, - brightness: Brightness.dark, - extensions: [ - ShimmerColorTheme( - shimmerBackgroundColor: backgroundMaterialColor[700], - shimmerColor: backgroundMaterialColor[800], - ) - ], - primaryColor: accentMaterialColor, - splashFactory: NoSplash.splashFactory, - primarySwatch: accentMaterialColor, - backgroundColor: backgroundMaterialColor[900], - scaffoldBackgroundColor: backgroundMaterialColor[900], - dialogBackgroundColor: backgroundMaterialColor[800], - shadowColor: Colors.black26, - buttonTheme: ButtonThemeData( - buttonColor: accentMaterialColor, - ), - iconTheme: IconThemeData(size: 16, color: Colors.grey[50]), - inputDecorationTheme: InputDecorationTheme( - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(20), - borderSide: BorderSide( - color: accentMaterialColor[400]!, - width: 2.0, - ), - ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(20), - borderSide: BorderSide( - color: backgroundMaterialColor[800]!, - ), - ), - ), - navigationRailTheme: NavigationRailThemeData( - backgroundColor: backgroundMaterialColor[800], - unselectedIconTheme: IconThemeData( - color: Colors.grey[300], - opacity: 1, - size: 18, - ), - selectedIconTheme: IconThemeData( - color: backgroundMaterialColor[850], - size: 18, - ), - selectedLabelTextStyle: TextStyle(color: accentMaterialColor[300]), - unselectedLabelTextStyle: TextStyle(color: Colors.grey[300]), - indicatorColor: accentMaterialColor[300], - ), - navigationBarTheme: NavigationBarThemeData( - backgroundColor: backgroundMaterialColor[900], - height: 45, - indicatorColor: accentMaterialColor[300], - labelBehavior: NavigationDestinationLabelBehavior.alwaysHide, - iconTheme: MaterialStateProperty.resolveWith((states) { - if (states.contains(MaterialState.selected)) { - return IconThemeData( - color: Colors.grey[900], - size: 18, - ); - } - return IconThemeData( - color: Colors.grey[300], - size: 18, - ); - }), - ), - cardTheme: CardTheme( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), - color: backgroundMaterialColor[900], - elevation: 20, - ), - elevatedButtonTheme: ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - foregroundColor: accentMaterialColor[300], - textStyle: const TextStyle( - fontWeight: FontWeight.bold, - ), - ), - ), - popupMenuTheme: PopupMenuThemeData( - color: backgroundMaterialColor[800], - elevation: 2, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(18.0), - ), - ), - dialogTheme: DialogTheme(backgroundColor: backgroundMaterialColor[900]), - cardColor: backgroundMaterialColor[800], - canvasColor: backgroundMaterialColor[800], - listTileTheme: const ListTileThemeData(horizontalTitleGap: 0), - checkboxTheme: CheckboxThemeData( - fillColor: MaterialStateProperty.resolveWith((states) { - if (states.contains(MaterialState.selected)) { - return accentMaterialColor[500]; - } - return null; - }), - ), - tabBarTheme: TabBarTheme( - indicator: const BoxDecoration(color: Colors.transparent), - labelColor: accentMaterialColor[500], - unselectedLabelColor: Colors.white, - labelStyle: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), - unselectedLabelStyle: - const TextStyle(fontWeight: FontWeight.w600, fontSize: 16), - ), - appBarTheme: AppBarTheme( - backgroundColor: backgroundMaterialColor[900], - ), - ); -} diff --git a/lib/themes/light_theme.dart b/lib/themes/light_theme.dart deleted file mode 100644 index d38f529c..00000000 --- a/lib/themes/light_theme.dart +++ /dev/null @@ -1,122 +0,0 @@ -import 'package:adwaita/adwaita.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:macos_ui/macos_ui.dart'; -import 'package:spotube/extensions/theme.dart'; -import 'package:fluent_ui/fluent_ui.dart' as fluent_ui; - -ThemeData theme(Color seed, Brightness brightness) { - final scheme = ColorScheme.fromSeed( - seedColor: seed, - shadow: Colors.black12, - brightness: brightness, - ); - return ThemeData( - useMaterial3: true, - colorScheme: scheme, - listTileTheme: ListTileThemeData( - horizontalTitleGap: 0, - iconColor: scheme.onSurface, - ), - inputDecorationTheme: InputDecorationTheme( - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(15), - ), - ), - iconTheme: IconThemeData(size: 16, color: scheme.onSurface), - navigationBarTheme: const NavigationBarThemeData( - labelBehavior: NavigationDestinationLabelBehavior.alwaysHide, - height: 50, - iconTheme: MaterialStatePropertyAll( - IconThemeData(size: 18), - ), - ), - tabBarTheme: TabBarTheme( - indicatorSize: TabBarIndicatorSize.tab, - labelStyle: const TextStyle(fontWeight: FontWeight.w600), - labelColor: scheme.primary, - overlayColor: MaterialStateProperty.all(Colors.transparent), - indicator: BoxDecoration( - color: scheme.secondaryContainer, - borderRadius: BorderRadius.circular(15), - ), - ), - ); -} - -final windowsTheme = fluent_ui.ThemeData.light().copyWith( - iconTheme: const IconThemeData(size: 16), - buttonTheme: fluent_ui.ButtonThemeData( - iconButtonStyle: fluent_ui.ButtonStyle( - iconSize: fluent_ui.ButtonState.all(20), - ), - ), -); -final windowsDarkTheme = fluent_ui.ThemeData.dark().copyWith( - iconTheme: const IconThemeData(size: 16), - buttonTheme: fluent_ui.ButtonThemeData( - iconButtonStyle: fluent_ui.ButtonStyle( - iconSize: fluent_ui.ButtonState.all(20), - ), - ), -); -final macosTheme = MacosThemeData.light().copyWith( - pushButtonTheme: const PushButtonThemeData( - secondaryColor: Colors.white, - ), - iconTheme: const MacosIconThemeData(size: 16), - typography: MacosTypography(color: Colors.grey[900]!), -); -final macosDarkTheme = MacosThemeData.dark().copyWith( - pushButtonTheme: const PushButtonThemeData( - secondaryColor: Colors.white, - ), - iconTheme: const MacosIconThemeData(size: 16), - typography: MacosTypography(color: MacosColors.textColor), -); -const iosTheme = CupertinoThemeData(brightness: Brightness.light); -const iosDarkTheme = CupertinoThemeData( - brightness: Brightness.dark, -); - -final linuxTheme = AdwaitaThemeData.light().copyWith( - primaryColor: const Color(0xFF3582e5), - iconTheme: const IconThemeData(size: 16), - extensions: [ - ShimmerColorTheme( - shimmerBackgroundColor: Colors.grey[300], - shimmerColor: Colors.grey[400], - ) - ], - switchTheme: SwitchThemeData( - trackColor: MaterialStateProperty.resolveWith((states) { - if (states.contains(MaterialState.selected)) { - return const Color(0xFF3582e5); - } - return Colors.grey[300]; - }), - ), - colorScheme: const ColorScheme.light( - primary: Color(0xFF3582e5), - ), - progressIndicatorTheme: const ProgressIndicatorThemeData( - color: Color(0xFF3582e5), - ), - listTileTheme: ListTileThemeData( - iconColor: Colors.grey[900], - horizontalTitleGap: 0, - ), -); -final linuxDarkTheme = AdwaitaThemeData.dark().copyWith( - iconTheme: IconThemeData(size: 16, color: Colors.grey[50]), - extensions: [ - ShimmerColorTheme( - shimmerBackgroundColor: Colors.grey[800], - shimmerColor: Colors.grey[900], - ) - ], - listTileTheme: ListTileThemeData( - iconColor: Colors.grey[50], - horizontalTitleGap: 0, - ), -); diff --git a/lib/themes/theme.dart b/lib/themes/theme.dart new file mode 100644 index 00000000..b87e7ab0 --- /dev/null +++ b/lib/themes/theme.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; + +ThemeData theme(Color seed, Brightness brightness) { + final scheme = ColorScheme.fromSeed( + seedColor: seed, + shadow: Colors.black12, + brightness: brightness, + ); + return ThemeData( + useMaterial3: true, + colorScheme: scheme, + listTileTheme: ListTileThemeData( + horizontalTitleGap: 0, + iconColor: scheme.onSurface, + ), + inputDecorationTheme: InputDecorationTheme( + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15), + ), + ), + iconTheme: IconThemeData(size: 16, color: scheme.onSurface), + navigationBarTheme: const NavigationBarThemeData( + labelBehavior: NavigationDestinationLabelBehavior.alwaysHide, + height: 50, + iconTheme: MaterialStatePropertyAll( + IconThemeData(size: 18), + ), + ), + tabBarTheme: TabBarTheme( + indicatorSize: TabBarIndicatorSize.tab, + labelStyle: const TextStyle(fontWeight: FontWeight.w600), + labelColor: scheme.primary, + overlayColor: MaterialStateProperty.all(Colors.transparent), + indicator: BoxDecoration( + color: scheme.secondaryContainer, + borderRadius: BorderRadius.circular(15), + ), + ), + ); +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index cb3b7f70..3ded505b 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -10,7 +10,6 @@ import audio_session import audioplayers_darwin import catcher import device_info_plus -import macos_ui import metadata_god import package_info_plus import path_provider_foundation @@ -27,7 +26,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) CatcherPlugin.register(with: registry.registrar(forPlugin: "CatcherPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) - MacOSUiPlugin.register(with: registry.registrar(forPlugin: "MacOSUiPlugin")) MetadataGodPlugin.register(with: registry.registrar(forPlugin: "MetadataGodPlugin")) FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 843eb3f8..e9ce8f14 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -9,14 +9,6 @@ packages: url: "https://pub.dev" source: hosted version: "52.0.0" - adwaita: - dependency: "direct main" - description: - name: adwaita - sha256: "535781747357779fa2830815e0a1b6b7888c8c538194ba73ac4fc8d82412baec" - url: "https://pub.dev" - source: hosted - version: "0.5.2" analyzer: dependency: transitive description: @@ -546,14 +538,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0-alpha.1" - fluent_ui: - dependency: "direct main" - description: - name: fluent_ui - sha256: ff172e78492faad2c9eca01b24ea8341f2bd6e1ce6986b15d4886fd2e7c3fb09 - url: "https://pub.dev" - source: hosted - version: "4.3.0" fluentui_system_icons: dependency: "direct main" description: @@ -671,11 +655,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" - flutter_localizations: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" flutter_mailer: dependency: transitive description: @@ -782,14 +761,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" - gsettings: - dependency: transitive - description: - name: gsettings - sha256: fe90d719e09a6f36607021047e642068a0c98839d9633db00b91633420ae8b0d - url: "https://pub.dev" - source: hosted - version: "0.2.7" hive: dependency: "direct main" description: @@ -910,22 +881,6 @@ packages: url: "https://pub.dev" source: hosted version: "6.6.1" - libadwaita: - dependency: "direct main" - description: - name: libadwaita - sha256: de4dba194e6ba468af70988891164cc616126dc7ccbc4f42756851be93aa6de6 - url: "https://pub.dev" - source: hosted - version: "1.2.5" - libadwaita_core: - dependency: transitive - description: - name: libadwaita_core - sha256: "1a7689e4130e96be4b0ec615863fded25cd86c2b95a682e7cec9659d420de37c" - url: "https://pub.dev" - source: hosted - version: "0.5.4" lints: dependency: transitive description: @@ -950,14 +905,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" - macos_ui: - dependency: "direct main" - description: - name: macos_ui - sha256: "2b31858b56d44e807cf192c58cf6660b584c997f4746496d4892a903c1c27a49" - url: "https://pub.dev" - source: hosted - version: "1.9.1" mailer: dependency: transitive description: @@ -1206,15 +1153,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0" - platform_ui: - dependency: "direct main" - description: - path: "." - ref: "339ea7922d2f881d9a72b565aeebc7e2c4b22509" - resolved-ref: "339ea7922d2f881d9a72b565aeebc7e2c4b22509" - url: "https://github.com/KRTirtho/platform_ui.git" - source: git - version: "0.1.0" plugin_platform_interface: dependency: transitive description: @@ -1255,14 +1193,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.8+1" - popover_gtk: - dependency: transitive - description: - name: popover_gtk - sha256: c293bfa3bcb9436fe189f20f6397199ce996ba40d4b081e26793adcf3ceac45b - url: "https://pub.dev" - source: hosted - version: "0.2.6+3" process: dependency: transitive description: @@ -1327,14 +1257,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.1" - recase: - dependency: transitive - description: - name: recase - sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 - url: "https://pub.dev" - source: hosted - version: "4.1.0" riverpod: dependency: transitive description: @@ -1359,14 +1281,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.6" - scroll_pos: - dependency: transitive - description: - name: scroll_pos - sha256: cfca311b6b8d51538ff90e206fbe6ce3b36e7125ea6da4a40eb626c7f9f083b1 - url: "https://pub.dev" - source: hosted - version: "0.3.0" scroll_to_index: dependency: "direct main" description: @@ -1808,4 +1722,4 @@ packages: version: "1.12.3" sdks: dart: ">=2.19.0 <3.0.0" - flutter: ">=3.7.0" + flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 043badd4..c533d0e2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,6 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: - adwaita: ^0.5.2 args: ^2.3.2 async: ^2.9.0 audio_service: ^0.18.9 @@ -29,7 +28,6 @@ dependencies: file_picker: ^5.2.2 fl_query: ^1.0.0-alpha.0 fl_query_hooks: ^1.0.0-alpha.0 - fluent_ui: ^4.3.0 fluentui_system_icons: ^1.1.189 flutter: sdk: flutter @@ -50,9 +48,7 @@ dependencies: introduction_screen: ^3.0.2 json_annotation: ^4.8.0 json_serializable: ^6.6.0 - libadwaita: ^1.2.5 logger: ^1.1.0 - macos_ui: ^1.9.0 marquee: ^2.2.3 metadata_god: ^0.3.2 mime: ^1.0.2 @@ -61,10 +57,6 @@ dependencies: path: ^1.8.0 path_provider: ^2.0.8 permission_handler: ^10.2.0 - platform_ui: - git: - url: https://github.com/KRTirtho/platform_ui.git - ref: 339ea7922d2f881d9a72b565aeebc7e2c4b22509 pocketbase: ^0.7.1+1 popover: ^0.2.6+3 queue: ^3.1.0+1 From f8a2b9afd85d7bbb9981bd3a83fa3184f578fff0 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 10 Mar 2023 13:00:07 +0600 Subject: [PATCH 2/3] refactor: sidebar trailing widget in the end and use NavigationBar instead of BottomNavigationBar --- lib/components/root/sidebar.dart | 165 ++++++++++-------- .../root/spotube_navigation_bar.dart | 10 +- pubspec.lock | 8 + 3 files changed, 105 insertions(+), 78 deletions(-) diff --git a/lib/components/root/sidebar.dart b/lib/components/root/sidebar.dart index 9c572b28..5cffb0aa 100644 --- a/lib/components/root/sidebar.dart +++ b/lib/components/root/sidebar.dart @@ -90,26 +90,14 @@ class Sidebar extends HookConsumerWidget { ); }, ).toList(), - extended: true, - leading: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - if (kIsMacOS) macSpacer, - Row( - children: [ - brandLogo(), - const SizedBox(width: 10), - Text( - "Spotube", - style: Theme.of(context).textTheme.titleLarge, - ), - ], - ), - ], + extended: breakpoints > Breakpoints.md, + leading: const SidebarHeader(), + trailing: const Expanded( + child: Align( + alignment: Alignment.bottomCenter, + child: SidebarFooter(), ), ), - trailing: const SidebarFooter(), ), Expanded(child: child) ], @@ -117,6 +105,38 @@ class Sidebar extends HookConsumerWidget { } } +class SidebarHeader extends HookWidget { + const SidebarHeader({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final breakpoint = useBreakpoints(); + + if (breakpoint <= Breakpoints.md) { + return Sidebar.brandLogo(); + } + + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + if (kIsMacOS) const SizedBox(height: 25), + Row( + children: [ + Sidebar.brandLogo(), + const SizedBox(width: 10), + Text( + "Spotube", + style: Theme.of(context).textTheme.titleLarge, + ), + ], + ), + ], + ), + ); + } +} + class SidebarFooter extends HookConsumerWidget { const SidebarFooter({ Key? key, @@ -124,68 +144,67 @@ class SidebarFooter extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { - return SizedBox( - width: 256, - child: HookBuilder( - builder: (context) { - final me = useQueries.user.me(ref); - final data = me.data; + final breakpoint = useBreakpoints(); + final me = useQueries.user.me(ref); + final data = me.data; - final avatarImg = TypeConversionUtils.image_X_UrlString( - data?.images, - index: (data?.images?.length ?? 1) - 1, - placeholder: ImagePlaceholder.artist, - ); + final avatarImg = TypeConversionUtils.image_X_UrlString( + data?.images, + index: (data?.images?.length ?? 1) - 1, + placeholder: ImagePlaceholder.artist, + ); - final auth = ref.watch(AuthenticationNotifier.provider); + final auth = ref.watch(AuthenticationNotifier.provider); - return Padding( - padding: const EdgeInsets.all(16).copyWith(left: 0), + if (breakpoint <= Breakpoints.md) { + return IconButton( + icon: const Icon(SpotubeIcons.settings), + onPressed: () => Sidebar.goToSettings(context), + ); + } + + return Container( + padding: const EdgeInsets.only(left: 12), + width: 250, + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (auth != null && data == null) + const CircularProgressIndicator() + else if (data != null) + Flexible( child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if (auth != null && data == null) - const Center( - child: CircularProgressIndicator(), - ) - else if (data != null) - Flexible( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - CircleAvatar( - backgroundImage: - UniversalImage.imageProvider(avatarImg), - onBackgroundImageError: (exception, stackTrace) => - Assets.userPlaceholder.image( - height: 16, - width: 16, - ), - ), - const SizedBox( - width: 10, - ), - Flexible( - child: Text( - data.displayName ?? "Guest", - maxLines: 1, - softWrap: false, - overflow: TextOverflow.fade, - style: Theme.of(context) - .textTheme - .bodyMedium - ?.copyWith(fontWeight: FontWeight.bold), - ), - ), - ], - ), + CircleAvatar( + backgroundImage: UniversalImage.imageProvider(avatarImg), + onBackgroundImageError: (exception, stackTrace) => + Assets.userPlaceholder.image( + height: 16, + width: 16, ), - IconButton( - icon: const Icon(SpotubeIcons.settings), - onPressed: () => Sidebar.goToSettings(context)), + ), + const SizedBox(width: 10), + Flexible( + child: Text( + data.displayName ?? "Guest", + maxLines: 1, + softWrap: false, + overflow: TextOverflow.fade, + style: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith(fontWeight: FontWeight.bold), + ), + ), ], - )); - }, + ), + ), + 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 ff42ea0a..9c32673f 100644 --- a/lib/components/root/spotube_navigation_bar.dart +++ b/lib/components/root/spotube_navigation_bar.dart @@ -37,11 +37,11 @@ class SpotubeNavigationBar extends HookConsumerWidget { if (layoutMode == LayoutMode.extended || (breakpoint.isMoreThan(Breakpoints.sm) && layoutMode == LayoutMode.adaptive)) return const SizedBox(); - return BottomNavigationBar( - items: [ + return NavigationBar( + destinations: [ ...navbarTileList.map( (e) { - return BottomNavigationBarItem( + return NavigationDestination( icon: Badge( backgroundColor: Theme.of(context).primaryColor, isLabelVisible: e.title == "Library" && downloadCount > 0, @@ -59,8 +59,8 @@ class SpotubeNavigationBar extends HookConsumerWidget { }, ), ], - currentIndex: insideSelectedIndex.value, - onTap: (i) { + selectedIndex: insideSelectedIndex.value, + onDestinationSelected: (i) { insideSelectedIndex.value = i; if (navbarTileList[i].title == "Settings") { Sidebar.goToSettings(context); diff --git a/pubspec.lock b/pubspec.lock index e9ce8f14..a4f1b5ad 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -551,6 +551,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_adaptive_scaffold: + dependency: "direct main" + description: + name: flutter_adaptive_scaffold + sha256: d5842a235ec810320c7e6dac282876d93bccf231201be6e684b016cd717c0576 + url: "https://pub.dev" + source: hosted + version: "0.1.0" flutter_app_builder: dependency: transitive description: From a25bc9aac8284c54d3fe065fb16edd0132ebf760 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 10 Mar 2023 13:10:04 +0600 Subject: [PATCH 3/3] chore: pubspec update --- pubspec.lock | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index a4f1b5ad..e9ce8f14 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -551,14 +551,6 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_adaptive_scaffold: - dependency: "direct main" - description: - name: flutter_adaptive_scaffold - sha256: d5842a235ec810320c7e6dac282876d93bccf231201be6e684b016cd717c0576 - url: "https://pub.dev" - source: hosted - version: "0.1.0" flutter_app_builder: dependency: transitive description: