diff --git a/lib/components/shared/track_table/track_collection_view/track_collection_heading.dart b/lib/components/shared/track_table/track_collection_view/track_collection_heading.dart index 45104eee..49bcd99c 100644 --- a/lib/components/shared/track_table/track_collection_view/track_collection_heading.dart +++ b/lib/components/shared/track_table/track_collection_view/track_collection_heading.dart @@ -71,118 +71,121 @@ class TrackCollectionHeading extends HookConsumerWidget { padding: const EdgeInsets.symmetric( horizontal: 20, ), - child: Flex( - direction: - constrains.mdAndDown ? Axis.vertical : Axis.horizontal, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ConstrainedBox( - constraints: const BoxConstraints(maxHeight: 200), - child: ClipRRect( - borderRadius: BorderRadius.circular(10), - child: UniversalImage( - path: titleImage, - placeholder: Assets.albumPlaceholder.path, + child: SafeArea( + child: Flex( + direction: constrains.mdAndDown + ? Axis.vertical + : Axis.horizontal, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 200), + child: ClipRRect( + borderRadius: BorderRadius.circular(10), + child: UniversalImage( + path: titleImage, + placeholder: Assets.albumPlaceholder.path, + ), ), ), - ), - const SizedBox(width: 10, height: 10), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - Text( - title, - style: theme.textTheme.titleLarge!.copyWith( - color: Colors.white, - fontWeight: FontWeight.w600, - ), - ), - if (album != null) + const SizedBox(width: 10, height: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ Text( - "${AlbumType.from(album?.albumType).formatted} • ${context.l10n.released} • ${DateTime.tryParse( - album?.releaseDate ?? "", - )?.year}", - style: theme.textTheme.titleMedium!.copyWith( + title, + style: theme.textTheme.titleLarge!.copyWith( color: Colors.white, - fontWeight: FontWeight.normal, + fontWeight: FontWeight.w600, ), ), - if (description != null) + if (album != null) + Text( + "${AlbumType.from(album?.albumType).formatted} • ${context.l10n.released} • ${DateTime.tryParse( + album?.releaseDate ?? "", + )?.year}", + style: theme.textTheme.titleMedium!.copyWith( + color: Colors.white, + fontWeight: FontWeight.normal, + ), + ), + if (description != null) + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: constrains.mdAndDown ? 400 : 300, + ), + child: Text( + description!, + style: const TextStyle(color: Colors.white), + maxLines: 2, + overflow: TextOverflow.fade, + ), + ), + const SizedBox(height: 10), + IconTheme( + data: theme.iconTheme.copyWith( + color: Colors.white, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: buttons, + ), + ), + const SizedBox(height: 10), ConstrainedBox( constraints: BoxConstraints( maxWidth: constrains.mdAndDown ? 400 : 300, ), - child: Text( - description!, - style: const TextStyle(color: Colors.white), - maxLines: 2, - overflow: TextOverflow.fade, + child: Row( + mainAxisSize: constrains.smAndUp + ? MainAxisSize.min + : MainAxisSize.min, + children: [ + Expanded( + child: FilledButton.icon( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + foregroundColor: color?.color, + ), + label: Text(context.l10n.shuffle), + icon: const Icon(SpotubeIcons.shuffle), + onPressed: tracksSnapshot.data == null || + isPlaying + ? null + : onShuffledPlay, + ), + ), + const SizedBox(width: 10), + Expanded( + child: FilledButton.icon( + style: ElevatedButton.styleFrom( + backgroundColor: color?.color, + foregroundColor: color?.bodyTextColor, + ), + onPressed: tracksSnapshot.data != null + ? onPlay + : null, + icon: Icon( + isPlaying + ? SpotubeIcons.stop + : SpotubeIcons.play, + ), + label: Text( + isPlaying + ? context.l10n.stop + : context.l10n.play, + ), + ), + ), + ], ), ), - const SizedBox(height: 10), - IconTheme( - data: theme.iconTheme.copyWith( - color: Colors.white, - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: buttons, - ), - ), - const SizedBox(height: 10), - ConstrainedBox( - constraints: BoxConstraints( - maxWidth: constrains.mdAndDown ? 400 : 300, - ), - child: Row( - mainAxisSize: constrains.smAndUp - ? MainAxisSize.min - : MainAxisSize.min, - children: [ - Expanded( - child: FilledButton.icon( - style: ElevatedButton.styleFrom( - backgroundColor: Colors.white, - foregroundColor: color?.color, - ), - label: Text(context.l10n.shuffle), - icon: const Icon(SpotubeIcons.shuffle), - onPressed: - tracksSnapshot.data == null || isPlaying - ? null - : onShuffledPlay, - ), - ), - const SizedBox(width: 10), - Expanded( - child: FilledButton.icon( - style: ElevatedButton.styleFrom( - backgroundColor: color?.color, - foregroundColor: color?.bodyTextColor, - ), - onPressed: tracksSnapshot.data != null - ? onPlay - : null, - icon: Icon( - isPlaying - ? SpotubeIcons.stop - : SpotubeIcons.play, - ), - label: Text( - isPlaying - ? context.l10n.stop - : context.l10n.play, - ), - ), - ), - ], - ), - ), - ], - ) - ], + ], + ) + ], + ), ), ), ), diff --git a/lib/components/shared/track_table/track_collection_view/track_collection_view.dart b/lib/components/shared/track_table/track_collection_view/track_collection_view.dart index c0caad96..419fb2d2 100644 --- a/lib/components/shared/track_table/track_collection_view/track_collection_view.dart +++ b/lib/components/shared/track_table/track_collection_view/track_collection_view.dart @@ -106,139 +106,136 @@ class TrackCollectionView extends HookConsumerWidget { return () => controller.removeListener(listener); }, [collapsed.value]); - return SafeArea( - bottom: false, - child: Scaffold( - appBar: kIsDesktop - ? const PageWindowTitleBar( - backgroundColor: Colors.transparent, - foregroundColor: Colors.white, - leadingWidth: 400, - leading: Align( - alignment: Alignment.centerLeft, - child: BackButton(color: Colors.white), + return Scaffold( + appBar: kIsDesktop + ? const PageWindowTitleBar( + backgroundColor: Colors.transparent, + foregroundColor: Colors.white, + leadingWidth: 400, + leading: Align( + alignment: Alignment.centerLeft, + child: BackButton(color: Colors.white), + ), + ) + : null, + extendBodyBehindAppBar: kIsDesktop, + body: RefreshIndicator( + onRefresh: () async { + await tracksSnapshot.refresh(); + }, + child: CustomScrollView( + controller: controller, + physics: const AlwaysScrollableScrollPhysics(), + slivers: [ + SliverAppBar( + actions: [ + AnimatedScale( + duration: const Duration(milliseconds: 200), + scale: collapsed.value ? 1 : 0, + child: Row( + mainAxisSize: MainAxisSize.min, + children: buttons, + ), ), - ) - : null, - extendBodyBehindAppBar: kIsDesktop, - body: RefreshIndicator( - onRefresh: () async { - await tracksSnapshot.refresh(); - }, - child: CustomScrollView( - controller: controller, - physics: const AlwaysScrollableScrollPhysics(), - slivers: [ - SliverAppBar( - actions: [ - AnimatedScale( - duration: const Duration(milliseconds: 200), - scale: collapsed.value ? 1 : 0, - child: Row( - mainAxisSize: MainAxisSize.min, - children: buttons, - ), + AnimatedScale( + duration: const Duration(milliseconds: 200), + scale: collapsed.value ? 1 : 0, + child: IconButton( + tooltip: context.l10n.shuffle, + icon: const Icon(SpotubeIcons.shuffle), + onPressed: isPlaying ? null : onShuffledPlay, ), - AnimatedScale( - duration: const Duration(milliseconds: 200), - scale: collapsed.value ? 1 : 0, - child: IconButton( - tooltip: context.l10n.shuffle, - icon: const Icon(SpotubeIcons.shuffle), - onPressed: isPlaying ? null : onShuffledPlay, + ), + AnimatedScale( + duration: const Duration(milliseconds: 200), + scale: collapsed.value ? 1 : 0, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + shape: const CircleBorder(), + backgroundColor: theme.colorScheme.inversePrimary, ), + onPressed: tracksSnapshot.data != null ? onPlay : null, + child: Icon( + isPlaying ? SpotubeIcons.stop : SpotubeIcons.play), ), - AnimatedScale( - duration: const Duration(milliseconds: 200), - scale: collapsed.value ? 1 : 0, - child: ElevatedButton( - style: ElevatedButton.styleFrom( - shape: const CircleBorder(), - backgroundColor: theme.colorScheme.inversePrimary, + ), + ], + floating: false, + pinned: true, + expandedHeight: 400, + automaticallyImplyLeading: kIsMobile, + leading: + kIsMobile ? const BackButton(color: Colors.white) : null, + iconTheme: IconThemeData(color: color?.titleTextColor), + primary: true, + backgroundColor: color?.color, + title: collapsed.value + ? Text( + title, + style: theme.textTheme.titleMedium!.copyWith( + color: color?.titleTextColor, + fontWeight: FontWeight.w600, ), - onPressed: tracksSnapshot.data != null ? onPlay : null, - child: Icon( - isPlaying ? SpotubeIcons.stop : SpotubeIcons.play), - ), - ), - ], - floating: false, - pinned: true, - expandedHeight: 400, - automaticallyImplyLeading: kIsMobile, - leading: - kIsMobile ? const BackButton(color: Colors.white) : null, - iconTheme: IconThemeData(color: color?.titleTextColor), - primary: true, - backgroundColor: color?.color, - title: collapsed.value - ? Text( - title, - style: theme.textTheme.titleMedium!.copyWith( - color: color?.titleTextColor, - fontWeight: FontWeight.w600, - ), - ) - : null, - centerTitle: true, - flexibleSpace: FlexibleSpaceBar( - background: TrackCollectionHeading( - color: color, - title: title, - description: description, - titleImage: titleImage, - isPlaying: isPlaying, - onPlay: onPlay, - onShuffledPlay: onShuffledPlay, - tracksSnapshot: tracksSnapshot, - buttons: buttons, - album: album, - ), + ) + : null, + centerTitle: true, + flexibleSpace: FlexibleSpaceBar( + background: TrackCollectionHeading( + color: color, + title: title, + description: description, + titleImage: titleImage, + isPlaying: isPlaying, + onPlay: onPlay, + onShuffledPlay: onShuffledPlay, + tracksSnapshot: tracksSnapshot, + buttons: buttons, + album: album, ), ), - HookBuilder( - builder: (context) { - if (tracksSnapshot.isLoading || !tracksSnapshot.hasData) { - return const ShimmerTrackTile(); - } else if (tracksSnapshot.hasError) { - return SliverToBoxAdapter( - child: Text( - context.l10n.error(tracksSnapshot.error ?? ""), - ), - ); - } - - return TracksTableView( - (tracksSnapshot.data ?? []).map( - (track) { - if (track is Track) { - return track; - } else { - return TypeConversionUtils.simpleTrack_X_Track( - track, - album!, - ); - } - }, - ).toList(), - onTrackPlayButtonPressed: onPlay, - playlistId: id, - userPlaylist: isOwned, - onFiltering: () { - // scroll the flexible space - // to allow more space for search results - controller.animateTo( - 330, - duration: const Duration(milliseconds: 200), - curve: Curves.easeInOut, - ); - }, + ), + HookBuilder( + builder: (context) { + if (tracksSnapshot.isLoading || !tracksSnapshot.hasData) { + return const ShimmerTrackTile(); + } else if (tracksSnapshot.hasError) { + return SliverToBoxAdapter( + child: Text( + context.l10n.error(tracksSnapshot.error ?? ""), + ), ); - }, - ) - ], - ), - )), - ); + } + + return TracksTableView( + (tracksSnapshot.data ?? []).map( + (track) { + if (track is Track) { + return track; + } else { + return TypeConversionUtils.simpleTrack_X_Track( + track, + album!, + ); + } + }, + ).toList(), + onTrackPlayButtonPressed: onPlay, + playlistId: id, + userPlaylist: isOwned, + onFiltering: () { + // scroll the flexible space + // to allow more space for search results + controller.animateTo( + 330, + duration: const Duration(milliseconds: 200), + curve: Curves.easeInOut, + ); + }, + ); + }, + ) + ], + ), + )); } } diff --git a/lib/main.dart b/lib/main.dart index f9037e35..5541673d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -132,7 +132,7 @@ Future main(List rawArgs) async { runApp( DevicePreview( availableLocales: L10n.all, - enabled: !kReleaseMode, + enabled: !kReleaseMode && DesktopTools.platform.isDesktop, builder: (context) { return ProviderScope( child: QueryClientProvider(