feat(tv-ui): add slideshow pattern mode and improve admin readability

This commit is contained in:
dwindown
2026-04-06 09:23:42 +07:00
parent 185c55a143
commit 414450125d
6 changed files with 312 additions and 34 deletions

View File

@@ -4,6 +4,7 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../data/local/models.dart';
import '../../data/services/unsplash_cache_service.dart';
import '../../providers.dart';
@@ -25,6 +26,7 @@ class _UnsplashBackgroundState extends ConsumerState<UnsplashBackground> {
String? _lastKeyword;
int? _lastRotationHours;
bool? _lastUseUnsplash;
int _lastHandledRotateNonce = 0;
@override
void initState() {
@@ -106,6 +108,50 @@ class _UnsplashBackgroundState extends ConsumerState<UnsplashBackground> {
}
}
void _showNextImage() {
if (_imagePaths.length <= 1 || !mounted) return;
setState(() {
_currentIndex = (_currentIndex + 1) % _imagePaths.length;
});
}
void _showPreviousImage() {
if (_imagePaths.length <= 1 || !mounted) return;
setState(() {
_currentIndex = (_currentIndex - 1 + _imagePaths.length) % _imagePaths.length;
});
}
Future<void> _handleManualRotate(
BackgroundRotateAction action,
AppSettings settings,
) async {
if (!settings.useUnsplashBackground) return;
if (_imagePaths.isEmpty) {
final cachedPaths = await UnsplashCacheService.instance.getCachedImagePaths(
settings.unsplashKeyword,
);
if (!mounted) return;
if (cachedPaths.isNotEmpty) {
_applyImagePaths(cachedPaths);
}
}
if (_imagePaths.isEmpty) return;
switch (action) {
case BackgroundRotateAction.next:
_showNextImage();
break;
case BackgroundRotateAction.previous:
_showPreviousImage();
break;
case BackgroundRotateAction.random:
_nextRandomImage();
break;
}
}
void _startTimer(int hours) {
_rotationTimer?.cancel();
if (hours <= 0) return;
@@ -125,6 +171,7 @@ class _UnsplashBackgroundState extends ConsumerState<UnsplashBackground> {
@override
Widget build(BuildContext context) {
final settings = ref.watch(settingsProvider);
final rotateCommand = ref.watch(backgroundRotateCommandProvider);
// Watch for config changes
if (settings.useUnsplashBackground != _lastUseUnsplash) {
@@ -146,6 +193,14 @@ class _UnsplashBackgroundState extends ConsumerState<UnsplashBackground> {
_startTimer(settings.unsplashRotationHours);
}
if (rotateCommand.nonce != _lastHandledRotateNonce) {
_lastHandledRotateNonce = rotateCommand.nonce;
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return;
_handleManualRotate(rotateCommand.action, settings);
});
}
if (!settings.useUnsplashBackground || _imagePaths.isEmpty) {
return const SizedBox.shrink(); // Fallback to flat background handled underneath
}