From 5722defe34a164ab25c6bd2b4062ca892c781026 Mon Sep 17 00:00:00 2001 From: PartyDonut Date: Thu, 9 Oct 2025 14:11:55 +0200 Subject: [PATCH] feat: Improve media play button --- .../components/overview_header.dart | 3 +- .../media/components/media_play_button.dart | 133 ++++++++++-------- lib/util/focus_provider.dart | 4 +- 3 files changed, 82 insertions(+), 58 deletions(-) diff --git a/lib/screens/details_screens/components/overview_header.dart b/lib/screens/details_screens/components/overview_header.dart index ac979fe..0cfb7a6 100644 --- a/lib/screens/details_screens/components/overview_header.dart +++ b/lib/screens/details_screens/components/overview_header.dart @@ -74,6 +74,7 @@ class OverviewHeader extends ConsumerWidget { mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: crossAlignment, mainAxisSize: MainAxisSize.min, + spacing: 16, children: [ Flexible( child: ExcludeFocus( @@ -194,7 +195,7 @@ class OverviewHeader extends ConsumerWidget { ], ), ), - ].addInBetween(const SizedBox(height: 21)), + ], ), ), ); diff --git a/lib/screens/shared/media/components/media_play_button.dart b/lib/screens/shared/media/components/media_play_button.dart index 2c15499..3a2a3cd 100644 --- a/lib/screens/shared/media/components/media_play_button.dart +++ b/lib/screens/shared/media/components/media_play_button.dart @@ -5,7 +5,6 @@ import 'package:iconsax_plus/iconsax_plus.dart'; import 'package:fladder/models/item_base_model.dart'; import 'package:fladder/screens/shared/animated_fade_size.dart'; -import 'package:fladder/theme.dart'; import 'package:fladder/util/adaptive_layout/adaptive_layout.dart'; import 'package:fladder/util/focus_provider.dart'; import 'package:fladder/widgets/shared/ensure_visible.dart'; @@ -25,8 +24,8 @@ class MediaPlayButton extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final progress = (item?.progress ?? 0) / 100.0; - final padding = 3.0; - final radius = FladderTheme.smallShape.borderRadius.subtract(BorderRadius.circular(padding)); + final radius = BorderRadius.circular(16); + final smallRadius = const Radius.circular(4); final theme = Theme.of(context); Widget buttonTitle(Color contentColor) { @@ -39,8 +38,8 @@ class MediaPlayButton extends ConsumerWidget { Flexible( child: Text( item?.playButtonLabel(context) ?? "", - maxLines: 2, - overflow: TextOverflow.clip, + maxLines: 1, + overflow: TextOverflow.fade, style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w700, color: contentColor, @@ -63,55 +62,19 @@ class MediaPlayButton extends ConsumerWidget { ? const SizedBox.shrink(key: ValueKey('empty')) : Row( mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, spacing: 4, children: [ - FocusButton( - onTap: () => onPressed?.call(false), - onLongPress: () => onLongPressed?.call(false), - autoFocus: AdaptiveLayout.inputDeviceOf(context) == InputDevice.dPad, - darkOverlay: false, - onFocusChanged: (value) { - if (value) { - context.ensureVisible( - alignment: 1.0, - ); - } - }, - child: Stack( - alignment: Alignment.center, - children: [ - // Progress background - Positioned.fill( - child: DecoratedBox( - decoration: BoxDecoration( - color: theme.colorScheme.primaryContainer, - borderRadius: radius, - ), - ), - ), - // Button content - buttonTitle(theme.colorScheme.onPrimaryContainer), - Positioned.fill( - child: ClipRect( - clipper: _ProgressClipper( - progress, - ), - child: DecoratedBox( - decoration: BoxDecoration( - color: theme.colorScheme.primary, - borderRadius: radius, - ), - child: buttonTitle(theme.colorScheme.onPrimary), - ), - ), - ), - ], - ), - ), - if (progress != 0) - FocusButton( - onTap: () => onPressed?.call(true), - onLongPress: () => onLongPressed?.call(true), + Flexible( + child: FocusButton( + onTap: () => onPressed?.call(false), + onLongPress: () => onLongPressed?.call(false), + autoFocus: AdaptiveLayout.inputDeviceOf(context) == InputDevice.dPad, + borderRadius: radius.copyWith( + topRight: progress != 0 ? smallRadius : radius.topRight, + bottomRight: progress != 0 ? smallRadius : radius.bottomRight, + ), + darkOverlay: false, onFocusChanged: (value) { if (value) { context.ensureVisible( @@ -119,11 +82,69 @@ class MediaPlayButton extends ConsumerWidget { ); } }, - child: Card( - color: theme.colorScheme.primaryContainer, - shadowColor: Colors.transparent, + child: Stack( + alignment: Alignment.center, + children: [ + // Progress background + Positioned.fill( + child: DecoratedBox( + decoration: BoxDecoration( + color: theme.colorScheme.primaryContainer, + borderRadius: radius.copyWith( + topRight: progress != 0 ? smallRadius : radius.topRight, + bottomRight: progress != 0 ? smallRadius : radius.bottomRight, + ), + ), + ), + ), + // Button content + buttonTitle(theme.colorScheme.onPrimaryContainer), + Positioned.fill( + child: ClipRect( + clipper: _ProgressClipper( + progress, + ), + child: DecoratedBox( + decoration: BoxDecoration( + color: theme.colorScheme.primary, + borderRadius: radius.copyWith( + topRight: progress != 0 ? smallRadius : radius.topRight, + bottomRight: progress != 0 ? smallRadius : radius.bottomRight, + ), + ), + child: buttonTitle(theme.colorScheme.onPrimary), + ), + ), + ), + ], + ), + ), + ), + if (progress != 0) + FocusButton( + onTap: () => onPressed?.call(true), + onLongPress: () => onLongPressed?.call(true), + borderRadius: radius.copyWith( + topLeft: progress != 0 ? smallRadius : radius.topLeft, + bottomLeft: progress != 0 ? smallRadius : radius.bottomLeft, + ), + onFocusChanged: (value) { + if (value) { + context.ensureVisible( + alignment: 1.0, + ); + } + }, + child: Container( + decoration: BoxDecoration( + color: theme.colorScheme.primaryContainer, + borderRadius: radius.copyWith( + topLeft: progress != 0 ? smallRadius : radius.topLeft, + bottomLeft: progress != 0 ? smallRadius : radius.bottomLeft, + ), + ), child: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(7.5), child: Icon( IconsaxPlusBold.refresh, size: 29, diff --git a/lib/util/focus_provider.dart b/lib/util/focus_provider.dart index 0c4fec8..386f942 100644 --- a/lib/util/focus_provider.dart +++ b/lib/util/focus_provider.dart @@ -52,6 +52,7 @@ class FocusButton extends StatefulWidget { final Function(TapDownDetails)? onSecondaryTapDown; final bool darkOverlay; final Function(bool focus)? onFocusChanged; + final BorderRadiusGeometry? borderRadius; const FocusButton({ this.child, @@ -63,6 +64,7 @@ class FocusButton extends StatefulWidget { this.onSecondaryTapDown, this.darkOverlay = true, this.onFocusChanged, + this.borderRadius, super.key, }); @@ -176,7 +178,7 @@ class FocusButtonState extends State { .primaryContainer .withValues(alpha: widget.darkOverlay ? 0.1 : 0), border: Border.all(width: 3, color: Theme.of(context).colorScheme.onPrimaryContainer), - borderRadius: FladderTheme.smallShape.borderRadius, + borderRadius: widget.borderRadius ?? FladderTheme.smallShape.borderRadius, ), ), ),