import 'package:flutter/material.dart'; import 'package:plezy/widgets/app_icon.dart'; import 'package:material_symbols_icons/symbols.dart'; import '../../../i18n/strings.g.dart'; import '../../../mpv/mpv.dart'; import '../../../theme/mono_tokens.dart'; import '../../../utils/track_label_builder.dart'; import '../../../widgets/focusable_list_tile.dart'; class TrackSelectionHelper { /// Get the appropriate empty message based on track type static String getEmptyMessage() { if (T == SubtitleTrack) { return t.videoControls.noSubtitlesAvailable; } else if (T == AudioTrack) { return t.videoControls.noAudioTracksAvailable; } return t.videoControls.noTracksAvailable; } static Widget buildEmptyState() { return Center(child: Text(getEmptyMessage())); } /// Check if "Off" is selected for a track static bool isOffSelected(T? selectedTrack, bool Function(T track)? isOffTrack) { return selectedTrack == null || (isOffTrack?.call(selectedTrack) ?? false); } static String getTrackId(T track) { if (track is AudioTrack) { return track.id; } else if (track is SubtitleTrack) { return track.id; } return ''; } static Widget buildOffTile({ required BuildContext context, required bool isSelected, required VoidCallback onTap, Key? key, FocusNode? focusNode, VoidCallback? onLongPress, VoidCallback? onSecondaryTap, Widget? badge, }) { return _buildSelectableTile( context: context, key: key, label: t.common.off, isSelected: isSelected, onTap: onTap, focusNode: focusNode, onLongPress: onLongPress, onSecondaryTap: onSecondaryTap, badge: badge, ); } static Widget buildTrackTile({ required BuildContext context, required TrackLabel label, required bool isSelected, required VoidCallback onTap, Key? key, FocusNode? focusNode, VoidCallback? onLongPress, VoidCallback? onSecondaryTap, Widget? badge, }) { return _buildSelectableTile( context: context, key: key, label: label.primary, secondaryLabel: label.secondary, isSelected: isSelected, onTap: onTap, focusNode: focusNode, onLongPress: onLongPress, onSecondaryTap: onSecondaryTap, badge: badge, ); } /// Build a numbered badge for primary/secondary subtitle indicators. static Widget buildTrackBadge(BuildContext context, int number) { final colorScheme = Theme.of(context).colorScheme; return Container( width: 18, height: 18, decoration: BoxDecoration(color: colorScheme.primary, borderRadius: BorderRadius.circular(4)), alignment: .center, child: Text( number.toString(), style: TextStyle(color: colorScheme.onPrimary, fontSize: 11, fontWeight: .bold), ), ); } static Widget _buildSelectableTile({ required BuildContext context, required String label, required bool isSelected, required VoidCallback onTap, String? secondaryLabel, Key? key, FocusNode? focusNode, VoidCallback? onLongPress, VoidCallback? onSecondaryTap, Widget? badge, }) { final primaryColor = Theme.of(context).colorScheme.primary; Widget? trailing; if (badge != null) { trailing = badge; } else if (isSelected) { trailing = AppIcon(Symbols.check_rounded, fill: 1, color: primaryColor); } Widget tile = FocusableListTile( key: key, focusNode: focusNode, selected: isSelected, title: Text( label, style: TextStyle(color: isSelected ? primaryColor : null), maxLines: 1, overflow: .ellipsis, ), subtitle: secondaryLabel == null ? null : Text( secondaryLabel, style: TextStyle( color: isSelected ? primaryColor.withValues(alpha: 0.7) : tokens(context).textMuted, fontSize: 12, ), maxLines: 1, overflow: .ellipsis, ), trailing: trailing, onTap: onTap, onLongPress: onLongPress, ); if (onSecondaryTap != null) { tile = GestureDetector(onSecondaryTap: onSecondaryTap, child: tile); } return tile; } }