mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-09 07:28:14 -07:00
fix: Long press "play" button with dpad navigation
This commit is contained in:
parent
fd35ffb004
commit
3ce0ed6dbc
9 changed files with 188 additions and 121 deletions
|
|
@ -7,12 +7,13 @@ 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';
|
||||
|
||||
class MediaPlayButton extends ConsumerWidget {
|
||||
final ItemBaseModel? item;
|
||||
final VoidCallback? onPressed;
|
||||
final VoidCallback? onLongPressed;
|
||||
final Function(bool restart)? onPressed;
|
||||
final Function(bool restart)? onLongPressed;
|
||||
|
||||
const MediaPlayButton({
|
||||
required this.item,
|
||||
|
|
@ -26,17 +27,7 @@ class MediaPlayButton extends ConsumerWidget {
|
|||
final progress = (item?.progress ?? 0) / 100.0;
|
||||
final padding = 3.0;
|
||||
final radius = FladderTheme.smallShape.borderRadius.subtract(BorderRadius.circular(padding));
|
||||
final buttonState = WidgetStateProperty.resolveWith(
|
||||
(states) {
|
||||
return BorderSide(
|
||||
width: 2,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onPrimaryContainer
|
||||
.withValues(alpha: states.contains(WidgetState.focused) ? 0.9 : 0.0),
|
||||
);
|
||||
},
|
||||
);
|
||||
final theme = Theme.of(context);
|
||||
|
||||
Widget buttonTitle(Color contentColor) {
|
||||
return Padding(
|
||||
|
|
@ -50,10 +41,10 @@ class MediaPlayButton extends ConsumerWidget {
|
|||
item?.playButtonLabel(context) ?? "",
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.clip,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: contentColor,
|
||||
),
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: contentColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
|
|
@ -70,54 +61,79 @@ class MediaPlayButton extends ConsumerWidget {
|
|||
duration: const Duration(milliseconds: 250),
|
||||
child: onPressed == null
|
||||
? const SizedBox.shrink(key: ValueKey('empty'))
|
||||
: TextButton(
|
||||
onPressed: onPressed,
|
||||
onLongPress: onLongPressed,
|
||||
autofocus: AdaptiveLayout.inputDeviceOf(context) == InputDevice.dPad,
|
||||
style: ButtonStyle(
|
||||
side: buttonState,
|
||||
padding: const WidgetStatePropertyAll(EdgeInsets.zero),
|
||||
),
|
||||
onFocusChange: (value) {
|
||||
if (value) {
|
||||
context.ensureVisible(
|
||||
alignment: 1.0,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(padding),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
// Progress background
|
||||
Positioned.fill(
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: radius,
|
||||
),
|
||||
),
|
||||
),
|
||||
// Button content
|
||||
buttonTitle(Theme.of(context).colorScheme.onPrimaryContainer),
|
||||
Positioned.fill(
|
||||
child: ClipRect(
|
||||
clipper: _ProgressClipper(
|
||||
progress,
|
||||
),
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
borderRadius: radius,
|
||||
: Row(
|
||||
spacing: 2,
|
||||
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: Padding(
|
||||
padding: EdgeInsets.all(padding),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
// Progress background
|
||||
Positioned.fill(
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primaryContainer,
|
||||
borderRadius: radius,
|
||||
),
|
||||
),
|
||||
child: buttonTitle(Theme.of(context).colorScheme.onPrimary),
|
||||
),
|
||||
// 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) {
|
||||
if (value) {
|
||||
context.ensureVisible(
|
||||
alignment: 1.0,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Card(
|
||||
color: theme.colorScheme.primaryContainer,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Icon(
|
||||
IconsaxPlusBold.refresh,
|
||||
size: 29,
|
||||
color: theme.colorScheme.onPrimaryContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue