mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-14 01:37:07 -07:00
feat: Improve media play button
This commit is contained in:
parent
9a6202bd0b
commit
5722defe34
3 changed files with 82 additions and 58 deletions
|
|
@ -74,6 +74,7 @@ class OverviewHeader extends ConsumerWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
crossAxisAlignment: crossAlignment,
|
crossAxisAlignment: crossAlignment,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
spacing: 16,
|
||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
child: ExcludeFocus(
|
child: ExcludeFocus(
|
||||||
|
|
@ -194,7 +195,7 @@ class OverviewHeader extends ConsumerWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
].addInBetween(const SizedBox(height: 21)),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import 'package:iconsax_plus/iconsax_plus.dart';
|
||||||
|
|
||||||
import 'package:fladder/models/item_base_model.dart';
|
import 'package:fladder/models/item_base_model.dart';
|
||||||
import 'package:fladder/screens/shared/animated_fade_size.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/adaptive_layout/adaptive_layout.dart';
|
||||||
import 'package:fladder/util/focus_provider.dart';
|
import 'package:fladder/util/focus_provider.dart';
|
||||||
import 'package:fladder/widgets/shared/ensure_visible.dart';
|
import 'package:fladder/widgets/shared/ensure_visible.dart';
|
||||||
|
|
@ -25,8 +24,8 @@ class MediaPlayButton extends ConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final progress = (item?.progress ?? 0) / 100.0;
|
final progress = (item?.progress ?? 0) / 100.0;
|
||||||
final padding = 3.0;
|
final radius = BorderRadius.circular(16);
|
||||||
final radius = FladderTheme.smallShape.borderRadius.subtract(BorderRadius.circular(padding));
|
final smallRadius = const Radius.circular(4);
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
Widget buttonTitle(Color contentColor) {
|
Widget buttonTitle(Color contentColor) {
|
||||||
|
|
@ -39,8 +38,8 @@ class MediaPlayButton extends ConsumerWidget {
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
item?.playButtonLabel(context) ?? "",
|
item?.playButtonLabel(context) ?? "",
|
||||||
maxLines: 2,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.clip,
|
overflow: TextOverflow.fade,
|
||||||
style: theme.textTheme.titleMedium?.copyWith(
|
style: theme.textTheme.titleMedium?.copyWith(
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
color: contentColor,
|
color: contentColor,
|
||||||
|
|
@ -63,55 +62,19 @@ class MediaPlayButton extends ConsumerWidget {
|
||||||
? const SizedBox.shrink(key: ValueKey('empty'))
|
? const SizedBox.shrink(key: ValueKey('empty'))
|
||||||
: Row(
|
: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
spacing: 4,
|
spacing: 4,
|
||||||
children: [
|
children: [
|
||||||
FocusButton(
|
Flexible(
|
||||||
onTap: () => onPressed?.call(false),
|
child: FocusButton(
|
||||||
onLongPress: () => onLongPressed?.call(false),
|
onTap: () => onPressed?.call(false),
|
||||||
autoFocus: AdaptiveLayout.inputDeviceOf(context) == InputDevice.dPad,
|
onLongPress: () => onLongPressed?.call(false),
|
||||||
darkOverlay: false,
|
autoFocus: AdaptiveLayout.inputDeviceOf(context) == InputDevice.dPad,
|
||||||
onFocusChanged: (value) {
|
borderRadius: radius.copyWith(
|
||||||
if (value) {
|
topRight: progress != 0 ? smallRadius : radius.topRight,
|
||||||
context.ensureVisible(
|
bottomRight: progress != 0 ? smallRadius : radius.bottomRight,
|
||||||
alignment: 1.0,
|
),
|
||||||
);
|
darkOverlay: false,
|
||||||
}
|
|
||||||
},
|
|
||||||
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),
|
|
||||||
onFocusChanged: (value) {
|
onFocusChanged: (value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
context.ensureVisible(
|
context.ensureVisible(
|
||||||
|
|
@ -119,11 +82,69 @@ class MediaPlayButton extends ConsumerWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Card(
|
child: Stack(
|
||||||
color: theme.colorScheme.primaryContainer,
|
alignment: Alignment.center,
|
||||||
shadowColor: Colors.transparent,
|
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(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(7.5),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
IconsaxPlusBold.refresh,
|
IconsaxPlusBold.refresh,
|
||||||
size: 29,
|
size: 29,
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ class FocusButton extends StatefulWidget {
|
||||||
final Function(TapDownDetails)? onSecondaryTapDown;
|
final Function(TapDownDetails)? onSecondaryTapDown;
|
||||||
final bool darkOverlay;
|
final bool darkOverlay;
|
||||||
final Function(bool focus)? onFocusChanged;
|
final Function(bool focus)? onFocusChanged;
|
||||||
|
final BorderRadiusGeometry? borderRadius;
|
||||||
|
|
||||||
const FocusButton({
|
const FocusButton({
|
||||||
this.child,
|
this.child,
|
||||||
|
|
@ -63,6 +64,7 @@ class FocusButton extends StatefulWidget {
|
||||||
this.onSecondaryTapDown,
|
this.onSecondaryTapDown,
|
||||||
this.darkOverlay = true,
|
this.darkOverlay = true,
|
||||||
this.onFocusChanged,
|
this.onFocusChanged,
|
||||||
|
this.borderRadius,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -176,7 +178,7 @@ class FocusButtonState extends State<FocusButton> {
|
||||||
.primaryContainer
|
.primaryContainer
|
||||||
.withValues(alpha: widget.darkOverlay ? 0.1 : 0),
|
.withValues(alpha: widget.darkOverlay ? 0.1 : 0),
|
||||||
border: Border.all(width: 3, color: Theme.of(context).colorScheme.onPrimaryContainer),
|
border: Border.all(width: 3, color: Theme.of(context).colorScheme.onPrimaryContainer),
|
||||||
borderRadius: FladderTheme.smallShape.borderRadius,
|
borderRadius: widget.borderRadius ?? FladderTheme.smallShape.borderRadius,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue