Files
jamshalat-masjid-screen/lib/features/home/unsplash_background.dart
2026-03-31 14:37:14 +07:00

104 lines
2.9 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../data/services/unsplash_service.dart';
import '../../providers.dart';
/// Renders a securely rotating background using Unsplash API.
class UnsplashBackground extends ConsumerStatefulWidget {
const UnsplashBackground({super.key});
@override
ConsumerState<UnsplashBackground> createState() => _UnsplashBackgroundState();
}
class _UnsplashBackgroundState extends ConsumerState<UnsplashBackground> {
List<String> _urls = [];
int _currentIndex = 0;
Timer? _rotationTimer;
String? _lastKeyword;
int? _lastRotationHours;
@override
void initState() {
super.initState();
_initDataAndTimer();
}
void _initDataAndTimer() async {
final settings = ref.read(settingsProvider);
_lastKeyword = settings.unsplashKeyword;
_lastRotationHours = settings.unsplashRotationHours;
await _fetchImages(settings.unsplashKeyword);
_startTimer(settings.unsplashRotationHours);
}
Future<void> _fetchImages(String keyword) async {
final urls = await UnsplashService.instance.fetchLandscapeBackgrounds(keyword);
if (urls.isNotEmpty && mounted) {
setState(() {
_urls = urls;
_currentIndex = 0;
});
}
}
void _startTimer(int hours) {
_rotationTimer?.cancel();
if (hours <= 0) return;
_rotationTimer = Timer.periodic(Duration(hours: hours), (_) {
if (_urls.isNotEmpty && mounted) {
setState(() {
_currentIndex = (_currentIndex + 1) % _urls.length;
});
}
});
}
@override
void dispose() {
_rotationTimer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
final settings = ref.watch(settingsProvider);
// Watch for config changes
if (settings.unsplashKeyword != _lastKeyword) {
_lastKeyword = settings.unsplashKeyword;
// Re-fetch images organically
_fetchImages(settings.unsplashKeyword);
}
if (settings.unsplashRotationHours != _lastRotationHours) {
_lastRotationHours = settings.unsplashRotationHours;
_startTimer(settings.unsplashRotationHours);
}
if (!settings.useUnsplashBackground || _urls.isEmpty) {
return const SizedBox.shrink(); // Fallback to flat background handled underneath
}
return AnimatedSwitcher(
duration: const Duration(seconds: 3),
transitionBuilder: (child, animation) => FadeTransition(opacity: animation, child: child),
child: Image.network(
_urls[_currentIndex],
key: ValueKey(_urls[_currentIndex]),
fit: BoxFit.cover,
width: double.infinity,
height: double.infinity,
// Soft opacity behind the MainScreen's dark glass vignette
color: Colors.black.withValues(alpha: 0.5),
colorBlendMode: BlendMode.darken,
errorBuilder: (_, __, ___) => const SizedBox.shrink(),
),
);
}
}