fix(ci): unblock Flutter 3.44 checks
This commit is contained in:
@@ -228,7 +228,7 @@ class MediaCardState extends State<MediaCard> with ContextMenuTapMixin<MediaCard
|
||||
final localPosterPath = _getLocalPosterPath(context, item);
|
||||
|
||||
final cardWidget = viewMode == ViewMode.grid
|
||||
? _buildGridCard(context, item, semanticLabel, localPosterPath)
|
||||
? _buildGridCard(context, item, localPosterPath)
|
||||
: _MediaCardList(
|
||||
item: item,
|
||||
semanticLabel: semanticLabel,
|
||||
@@ -260,7 +260,7 @@ class MediaCardState extends State<MediaCard> with ContextMenuTapMixin<MediaCard
|
||||
|
||||
/// Grid layout — inlined from former _MediaCardGrid, _PosterOverlay, and
|
||||
/// flattened Column. Semantics removed (InkWell provides button semantics).
|
||||
Widget _buildGridCard(BuildContext context, Object item, String semanticLabel, String? localPosterPath) {
|
||||
Widget _buildGridCard(BuildContext context, Object item, String? localPosterPath) {
|
||||
// Compute actual poster dimensions from card dimensions
|
||||
final posterWidth = widget.width != null ? widget.width! - 6 : null; // 3px padding each side
|
||||
final posterHeight = widget.height;
|
||||
@@ -385,10 +385,10 @@ class _MediaCardList extends StatelessWidget {
|
||||
return (item as MediaItem).usesWideAspectRatio(mode);
|
||||
}
|
||||
|
||||
double _posterWidth(BuildContext context) =>
|
||||
double _posterWidth() =>
|
||||
MediaCardListLayout.posterWidth(density: density, usesWideAspectRatio: _usesWideAspectRatio());
|
||||
|
||||
double _posterHeight(BuildContext context) =>
|
||||
double _posterHeight() =>
|
||||
MediaCardListLayout.posterHeight(density: density, usesWideAspectRatio: _usesWideAspectRatio());
|
||||
|
||||
double get _titleFontSize => 13 + LibraryDensity.factor(density) * 3; // 13–16
|
||||
@@ -461,7 +461,7 @@ class _MediaCardList extends StatelessWidget {
|
||||
return parts.join(' • ');
|
||||
}
|
||||
|
||||
String? _buildSubtitleText(BuildContext context) {
|
||||
String? _buildSubtitleText() {
|
||||
if (item is MediaPlaylist) {
|
||||
return null;
|
||||
} else if (item is MediaItem) {
|
||||
@@ -523,7 +523,7 @@ class _MediaCardList extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final metadataLine = _buildMetadataLine();
|
||||
final subtitle = _buildSubtitleText(context);
|
||||
final subtitle = _buildSubtitleText();
|
||||
|
||||
return InkWell(
|
||||
mouseCursor: SystemMouseCursors.click,
|
||||
@@ -540,8 +540,8 @@ class _MediaCardList extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: _posterWidth(context),
|
||||
height: _posterHeight(context),
|
||||
width: _posterWidth(),
|
||||
height: _posterHeight(),
|
||||
child: Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
|
||||
@@ -112,7 +112,6 @@ class _RatingBottomSheetState extends State<RatingBottomSheet> {
|
||||
children: [
|
||||
if (widget.serverClient != null)
|
||||
_buildServerRow(
|
||||
context,
|
||||
widget.serverClient!,
|
||||
_serverFocusNode,
|
||||
autofocus: focusIndex == 0,
|
||||
@@ -121,7 +120,6 @@ class _RatingBottomSheetState extends State<RatingBottomSheet> {
|
||||
),
|
||||
for (final source in trackerSources)
|
||||
_buildTrackerRow(
|
||||
context,
|
||||
source,
|
||||
_trackerFocusNode(source.service),
|
||||
autofocus: focusIndex == 0,
|
||||
@@ -149,7 +147,6 @@ class _RatingBottomSheetState extends State<RatingBottomSheet> {
|
||||
}
|
||||
|
||||
Widget _buildServerRow(
|
||||
BuildContext context,
|
||||
MediaServerClient client,
|
||||
FocusNode focusNode, {
|
||||
required bool autofocus,
|
||||
@@ -215,7 +212,6 @@ class _RatingBottomSheetState extends State<RatingBottomSheet> {
|
||||
}
|
||||
|
||||
Widget _buildTrackerRow(
|
||||
BuildContext context,
|
||||
_TrackerRatingSource source,
|
||||
FocusNode focusNode, {
|
||||
required bool autofocus,
|
||||
|
||||
@@ -80,7 +80,7 @@ class _ServerActivitiesButtonState extends State<ServerActivitiesButton> {
|
||||
|
||||
_panelNotifier.value = _PanelData.loading;
|
||||
_overlayEntry = OverlayEntry(
|
||||
builder: (ctx) => _buildOverlay(ctx, right: right, top: top),
|
||||
builder: (_) => _buildOverlay(right: right, top: top),
|
||||
);
|
||||
Overlay.of(context).insert(_overlayEntry!);
|
||||
_fetchActivities();
|
||||
@@ -146,7 +146,7 @@ class _ServerActivitiesButtonState extends State<ServerActivitiesButton> {
|
||||
unawaited(_fetchActivities());
|
||||
}
|
||||
|
||||
Widget _buildOverlay(BuildContext overlayContext, {required double right, required double top}) {
|
||||
Widget _buildOverlay({required double right, required double top}) {
|
||||
return Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
|
||||
@@ -606,16 +606,16 @@ class TvBrowseRailState extends State<TvBrowseRail> {
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
SizedBox(width: _selectorWidth(context), child: _buildShelfSelector(context, hub)),
|
||||
SizedBox(width: _selectorWidth(context), child: _buildShelfSelector(context)),
|
||||
SizedBox(width: selectorGap),
|
||||
Expanded(child: _buildActiveRail(context, hub, hasFocus)),
|
||||
Expanded(child: _buildActiveRail(hub, hasFocus)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildShelfSelector(BuildContext context, MediaHub activeHub) {
|
||||
Widget _buildShelfSelector(BuildContext context) {
|
||||
final scale = _scale(context);
|
||||
final visibleIndices = _visibleShelfIndices();
|
||||
final isScrollable = widget.hubs.length > visibleIndices.length;
|
||||
@@ -803,7 +803,7 @@ class TvBrowseRailState extends State<TvBrowseRail> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildActiveRail(BuildContext context, MediaHub hub, bool hasFocus) {
|
||||
Widget _buildActiveRail(MediaHub hub, bool hasFocus) {
|
||||
return SettingsBuilder(
|
||||
prefs: const [SettingsService.libraryDensity, SettingsService.episodePosterMode],
|
||||
builder: (context) => LayoutBuilder(
|
||||
|
||||
@@ -191,7 +191,7 @@ class TvSpotlightBackground extends StatelessWidget {
|
||||
],
|
||||
if (showPrimaryAction || actions != null) ...[
|
||||
SizedBox(height: (compact ? 18 : 26) * scale),
|
||||
actions ?? _buildPrimaryAction(context, colorScheme, media),
|
||||
actions ?? _buildPrimaryAction(context, media),
|
||||
],
|
||||
],
|
||||
);
|
||||
@@ -285,7 +285,7 @@ class TvSpotlightBackground extends StatelessWidget {
|
||||
|
||||
double _summaryFontSize(double scale) => (compact ? 18 : 20) * scale;
|
||||
|
||||
Widget _buildPrimaryAction(BuildContext context, ColorScheme colorScheme, MediaItem media) {
|
||||
Widget _buildPrimaryAction(BuildContext context, MediaItem media) {
|
||||
final scale = _scale(context);
|
||||
final hasProgress = media.hasActiveProgress;
|
||||
final minutesLeft = hasProgress && media.durationMs != null && media.viewOffsetMs != null
|
||||
|
||||
@@ -169,7 +169,7 @@ class ContentStripState extends State<ContentStrip> {
|
||||
});
|
||||
}
|
||||
|
||||
KeyEventResult _handleFocusItemKeyEvent(FocusNode node, KeyEvent event, int index, int totalItems, _StripTab page) {
|
||||
KeyEventResult _handleFocusItemKeyEvent(KeyEvent event, int index, int totalItems, _StripTab page) {
|
||||
if (!event.isActionable) return KeyEventResult.ignored;
|
||||
|
||||
final key = event.logicalKey;
|
||||
@@ -359,7 +359,6 @@ class ContentStripState extends State<ContentStrip> {
|
||||
void onTap() => unawaited(_handleChapterTap(chapter.startTime));
|
||||
|
||||
final item = _buildStripItem(
|
||||
context: context,
|
||||
isCurrent: isCurrent,
|
||||
isTablet: isTablet,
|
||||
thumbnail: chapter.thumb != null
|
||||
@@ -385,8 +384,8 @@ class ContentStripState extends State<ContentStrip> {
|
||||
child: FocusableWrapper(
|
||||
focusNode: _chapterFocusNodes[index],
|
||||
onSelect: onTap,
|
||||
onKeyEvent: (node, event) =>
|
||||
_handleFocusItemKeyEvent(node, event, index, widget.chapters.length, _StripTab.chapters),
|
||||
onKeyEvent: (_, event) =>
|
||||
_handleFocusItemKeyEvent(event, index, widget.chapters.length, _StripTab.chapters),
|
||||
onFocusChange: (hasFocus) {
|
||||
if (hasFocus) widget.onFocusActivity?.call();
|
||||
},
|
||||
@@ -441,7 +440,6 @@ class ContentStripState extends State<ContentStrip> {
|
||||
void onTap() => widget.onQueueItemSelected?.call(item);
|
||||
|
||||
final stripItem = _buildStripItem(
|
||||
context: context,
|
||||
isCurrent: isCurrent,
|
||||
isTablet: isTablet,
|
||||
thumbnail: item.thumbPath != null
|
||||
@@ -466,8 +464,7 @@ class ContentStripState extends State<ContentStrip> {
|
||||
child: FocusableWrapper(
|
||||
focusNode: _queueFocusNodes[index],
|
||||
onSelect: onTap,
|
||||
onKeyEvent: (node, event) =>
|
||||
_handleFocusItemKeyEvent(node, event, index, items.length, _StripTab.queue),
|
||||
onKeyEvent: (_, event) => _handleFocusItemKeyEvent(event, index, items.length, _StripTab.queue),
|
||||
onFocusChange: (hasFocus) {
|
||||
if (hasFocus) widget.onFocusActivity?.call();
|
||||
},
|
||||
@@ -499,7 +496,6 @@ class ContentStripState extends State<ContentStrip> {
|
||||
}
|
||||
|
||||
Widget _buildStripItem({
|
||||
required BuildContext context,
|
||||
required bool isCurrent,
|
||||
required Widget? thumbnail,
|
||||
required String title,
|
||||
|
||||
@@ -138,9 +138,9 @@ class _LiveTimelineBarState extends State<LiveTimelineBar> {
|
||||
return ClickableCursor(
|
||||
enabled: widget.enabled,
|
||||
child: GestureDetector(
|
||||
onHorizontalDragStart: widget.enabled ? _onDragStart : null,
|
||||
onHorizontalDragStart: widget.enabled ? (_) => _onDragStart() : null,
|
||||
onHorizontalDragUpdate: widget.enabled ? (details) => _onDragUpdate(details, _widthOf(context)) : null,
|
||||
onHorizontalDragEnd: widget.enabled ? _onDragEnd : null,
|
||||
onHorizontalDragEnd: widget.enabled ? (_) => _onDragEnd() : null,
|
||||
onTapUp: widget.enabled ? (details) => _onTap(details, _widthOf(context)) : null,
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
@@ -154,7 +154,7 @@ class _LiveTimelineBarState extends State<LiveTimelineBar> {
|
||||
);
|
||||
}
|
||||
|
||||
void _onDragStart(DragStartDetails details) {
|
||||
void _onDragStart() {
|
||||
setState(() {
|
||||
_isDragging = true;
|
||||
_dragPositionEpoch = _currentEpoch(widget.player.state.position);
|
||||
@@ -169,7 +169,7 @@ class _LiveTimelineBarState extends State<LiveTimelineBar> {
|
||||
});
|
||||
}
|
||||
|
||||
void _onDragEnd(DragEndDetails details) {
|
||||
void _onDragEnd() {
|
||||
final target = _dragPositionEpoch;
|
||||
setState(() => _isDragging = false);
|
||||
widget.onSeekEnd?.call(target);
|
||||
|
||||
@@ -153,7 +153,6 @@ class TrackChapterControls extends StatelessWidget {
|
||||
required IconData icon,
|
||||
required String semanticLabel,
|
||||
required VoidCallback? onPressed,
|
||||
required Tracks? tracks,
|
||||
required bool isMobile,
|
||||
required bool isDesktop,
|
||||
String? tooltip,
|
||||
@@ -166,8 +165,7 @@ class TrackChapterControls extends StatelessWidget {
|
||||
isActive: isActive,
|
||||
focusNode: focusNodes != null && focusNodes!.length > buttonIndex ? focusNodes![buttonIndex] : null,
|
||||
onKeyEvent: focusNodes != null
|
||||
? (node, event) =>
|
||||
_handleButtonKeyEvent(node, event, buttonIndex, _getButtonCount(tracks, isMobile, isDesktop))
|
||||
? (node, event) => _handleButtonKeyEvent(node, event, buttonIndex, _getButtonCount(isMobile, isDesktop))
|
||||
: null,
|
||||
onFocusChange: onFocusChange,
|
||||
onPressed: onPressed,
|
||||
@@ -203,7 +201,6 @@ class TrackChapterControls extends StatelessWidget {
|
||||
isActive: isActive,
|
||||
tooltip: t.videoControls.settingsButton,
|
||||
semanticLabel: t.videoControls.settingsButton,
|
||||
tracks: tracks,
|
||||
isMobile: isMobile,
|
||||
isDesktop: isDesktop,
|
||||
onPressed: () {
|
||||
@@ -259,7 +256,6 @@ class TrackChapterControls extends StatelessWidget {
|
||||
icon: icon,
|
||||
tooltip: t.videoControls.tracksButton,
|
||||
semanticLabel: t.videoControls.tracksButton,
|
||||
tracks: tracks,
|
||||
isMobile: isMobile,
|
||||
isDesktop: isDesktop,
|
||||
onPressed: () {
|
||||
@@ -298,7 +294,6 @@ class TrackChapterControls extends StatelessWidget {
|
||||
icon: Symbols.bookmarks_rounded,
|
||||
tooltip: t.videoControls.chaptersButton,
|
||||
semanticLabel: t.videoControls.chaptersButton,
|
||||
tracks: tracks,
|
||||
isMobile: isMobile,
|
||||
isDesktop: isDesktop,
|
||||
onPressed: () {
|
||||
@@ -329,7 +324,6 @@ class TrackChapterControls extends StatelessWidget {
|
||||
icon: Symbols.queue_rounded,
|
||||
tooltip: t.videoControls.queue,
|
||||
semanticLabel: t.videoControls.queue,
|
||||
tracks: tracks,
|
||||
isMobile: isMobile,
|
||||
isDesktop: isDesktop,
|
||||
onPressed: () {
|
||||
@@ -352,7 +346,6 @@ class TrackChapterControls extends StatelessWidget {
|
||||
icon: Symbols.picture_in_picture_alt,
|
||||
tooltip: t.videoControls.pipButton,
|
||||
semanticLabel: t.videoControls.pipButton,
|
||||
tracks: tracks,
|
||||
isMobile: isMobile,
|
||||
isDesktop: isDesktop,
|
||||
onPressed: onTogglePIPMode,
|
||||
@@ -370,7 +363,6 @@ class TrackChapterControls extends StatelessWidget {
|
||||
icon: _getBoxFitIcon(boxFitMode),
|
||||
tooltip: _getBoxFitTooltip(boxFitMode),
|
||||
semanticLabel: t.videoControls.aspectRatioButton,
|
||||
tracks: tracks,
|
||||
isMobile: isMobile,
|
||||
isDesktop: isDesktop,
|
||||
onPressed: onCycleBoxFitMode,
|
||||
@@ -388,7 +380,6 @@ class TrackChapterControls extends StatelessWidget {
|
||||
icon: isRotationLocked ? Symbols.screen_lock_rotation_rounded : Symbols.screen_rotation_rounded,
|
||||
tooltip: isRotationLocked ? t.videoControls.unlockRotation : t.videoControls.lockRotation,
|
||||
semanticLabel: t.videoControls.rotationLockButton,
|
||||
tracks: tracks,
|
||||
isMobile: isMobile,
|
||||
isDesktop: isDesktop,
|
||||
onPressed: onToggleRotationLock,
|
||||
@@ -406,7 +397,6 @@ class TrackChapterControls extends StatelessWidget {
|
||||
icon: Symbols.lock_rounded,
|
||||
tooltip: t.videoControls.lockScreen,
|
||||
semanticLabel: t.videoControls.screenLockButton,
|
||||
tracks: tracks,
|
||||
isMobile: isMobile,
|
||||
isDesktop: isDesktop,
|
||||
onPressed: onToggleScreenLock,
|
||||
@@ -425,7 +415,6 @@ class TrackChapterControls extends StatelessWidget {
|
||||
tooltip: t.videoControls.alwaysOnTopButton,
|
||||
semanticLabel: t.videoControls.alwaysOnTopButton,
|
||||
isActive: isAlwaysOnTop,
|
||||
tracks: tracks,
|
||||
isMobile: isMobile,
|
||||
isDesktop: isDesktop,
|
||||
onPressed: onToggleAlwaysOnTop,
|
||||
@@ -443,7 +432,6 @@ class TrackChapterControls extends StatelessWidget {
|
||||
icon: isFullscreen ? Symbols.fullscreen_exit_rounded : Symbols.fullscreen_rounded,
|
||||
tooltip: isFullscreen ? t.videoControls.exitFullscreenButton : t.videoControls.fullscreenButton,
|
||||
semanticLabel: isFullscreen ? t.videoControls.exitFullscreenButton : t.videoControls.fullscreenButton,
|
||||
tracks: tracks,
|
||||
isMobile: isMobile,
|
||||
isDesktop: isDesktop,
|
||||
onPressed: onToggleFullscreen,
|
||||
@@ -459,7 +447,7 @@ class TrackChapterControls extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// Calculate total button count for navigation
|
||||
int _getButtonCount(Tracks? tracks, bool isMobile, bool isDesktop) {
|
||||
int _getButtonCount(bool isMobile, bool isDesktop) {
|
||||
int count = 1; // Settings button always shown
|
||||
count++; // Audio & subtitles button always shown
|
||||
if (chapters.isNotEmpty && !hideChaptersAndQueue) count++;
|
||||
|
||||
@@ -10,7 +10,6 @@ import '../../../mpv/mpv.dart';
|
||||
import '../../../services/settings_service.dart';
|
||||
import '../../../i18n/strings.g.dart';
|
||||
import '../../../focus/focusable_wrapper.dart';
|
||||
import '../../../focus/input_mode_tracker.dart';
|
||||
|
||||
/// A volume control widget that displays a mute/unmute button and volume slider.
|
||||
///
|
||||
@@ -138,8 +137,6 @@ class _VolumeControlState extends State<VolumeControl> {
|
||||
builder: (context, snapshot) {
|
||||
final volume = snapshot.data ?? 100.0;
|
||||
final isMuted = volume == 0;
|
||||
final isKeyboardMode = InputModeTracker.isKeyboardMode(context);
|
||||
|
||||
final muteButton = Semantics(
|
||||
label: isMuted ? t.videoControls.unmuteButton : t.videoControls.muteButton,
|
||||
button: true,
|
||||
@@ -180,7 +177,7 @@ class _VolumeControlState extends State<VolumeControl> {
|
||||
else
|
||||
muteButton,
|
||||
const SizedBox(width: 8),
|
||||
_buildVolumeSlider(volume, isKeyboardMode, maxVolume),
|
||||
_buildVolumeSlider(volume, maxVolume),
|
||||
],
|
||||
);
|
||||
},
|
||||
@@ -189,7 +186,7 @@ class _VolumeControlState extends State<VolumeControl> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildVolumeSlider(double volume, bool isKeyboardMode, int maxVolume) {
|
||||
Widget _buildVolumeSlider(double volume, int maxVolume) {
|
||||
final maxVolumeDouble = maxVolume.toDouble();
|
||||
|
||||
// Calculate 100% marker position as fraction of slider width
|
||||
|
||||
Reference in New Issue
Block a user