feature: Add actions for media segments (#236)

Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
PartyDonut 2025-02-23 16:56:49 +01:00 committed by GitHub
parent f0414439f3
commit e4b8a050c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 155 additions and 23 deletions

View file

@ -4,8 +4,10 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:auto_route/auto_route.dart';
import 'package:collection/collection.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fladder/models/items/media_segments_model.dart';
import 'package:fladder/models/settings/home_settings_model.dart';
import 'package:fladder/models/settings/video_player_settings.dart';
import 'package:fladder/providers/connectivity_provider.dart';
@ -130,6 +132,40 @@ class _PlayerSettingsPageState extends ConsumerState<PlayerSettingsPage> {
),
),
const Divider(),
SettingsLabelDivider(label: context.localized.mediaSegmentActions),
...videoSettings.segmentSkipSettings.entries.sorted((a, b) => b.key.index.compareTo(a.key.index)).map(
(entry) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Row(
children: [
Expanded(
child: Text(
entry.key.label(context),
style: Theme.of(context).textTheme.titleLarge,
),
),
EnumBox(
current: entry.value.label(context),
itemBuilder: (context) => SegmentSkip.values
.map(
(value) => PopupMenuItem(
value: value,
child: Text(value.label(context)),
onTap: () {
final newEntries = videoSettings.segmentSkipSettings.map(
(key, currentValue) => MapEntry(key, key == entry.key ? value : currentValue));
ref.read(videoPlayerSettingsProvider.notifier).state =
ref.read(videoPlayerSettingsProvider).copyWith(segmentSkipSettings: newEntries);
},
),
)
.toList(),
)
],
),
),
),
const Divider(),
SettingsLabelDivider(label: context.localized.advanced),
if (PlayerOptions.available.length != 1)
SettingsListTile(

View file

@ -65,16 +65,22 @@ class OpenQueueButton extends ConsumerWidget {
class SkipSegmentButton extends ConsumerWidget {
final MediaSegment? segment;
final SegmentSkip? skipType;
final bool isOverlayVisible;
final Function() pressedSkip;
const SkipSegmentButton(
{required this.segment, required this.isOverlayVisible, required this.pressedSkip, super.key});
const SkipSegmentButton({
required this.segment,
this.skipType,
required this.isOverlayVisible,
required this.pressedSkip,
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
return AnimatedFadeSize(
child: segment != null
child: segment != null && skipType != SegmentSkip.none
? AnimatedOpacity(
opacity: isOverlayVisible ? 1 : 0.15,
duration: const Duration(milliseconds: 500),

View file

@ -166,6 +166,13 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
final position = ref.watch(mediaPlaybackProvider.select((value) => value.position));
MediaSegment? segment = mediaSegments?.atPosition(position);
bool forceShow = segment?.forceShow(position) ?? false;
final segmentSkipType = ref
.watch(videoPlayerSettingsProvider.select((value) => value.segmentSkipSettings[segment?.type]));
final autoSkip =
forceShow == true && segmentSkipType == SegmentSkip.skip && player.lastState?.buffering == false;
if (autoSkip) {
skipToSegmentEnd(segment);
}
return Stack(
children: [
Align(
@ -174,6 +181,7 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
padding: const EdgeInsets.all(32),
child: SkipSegmentButton(
segment: segment,
skipType: segmentSkipType,
isOverlayVisible: forceShow ? true : showOverlay,
pressedSkip: () => skipToSegmentEnd(segment),
),