Files
jamshalat-masjid-screen/lib/features/home/slideshow_screen.dart

202 lines
6.2 KiB
Dart

import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import '../../core/sacred_tokens.dart';
import '../../providers.dart';
class SlideshowScreen extends ConsumerStatefulWidget {
const SlideshowScreen({super.key});
@override
ConsumerState<SlideshowScreen> createState() => _SlideshowScreenState();
}
class _SlideshowScreenState extends ConsumerState<SlideshowScreen> {
static int _globalImageIndex = 0;
int _localImageIndex = 0;
@override
void initState() {
super.initState();
final settings = ref.read(settingsProvider);
if (settings.slideshowImages.isNotEmpty) {
_localImageIndex = _globalImageIndex;
_globalImageIndex = (_globalImageIndex + 1) % settings.slideshowImages.length;
}
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final s = size.width / 1920;
final screenData = ref.watch(screenStateProvider);
final settings = ref.watch(settingsProvider);
Widget renderImage() {
if (settings.slideshowImages.isEmpty) {
return _buildErrorImage(s);
}
final imgPath = settings.slideshowImages[_localImageIndex % settings.slideshowImages.length];
return Image.file(
File(imgPath),
fit: BoxFit.cover,
errorBuilder: (ctx, err, stack) => _buildErrorImage(s),
);
}
return Scaffold(
backgroundColor: Colors.black,
body: Stack(
fit: StackFit.expand,
children: [
// 1. Poster Image
renderImage(),
// 2. Subtle Dark Gradient Overlay at bottom so the "glass bar" pops out cleanly
Positioned(
left: 0,
right: 0,
bottom: 0,
height: 300 * s,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
Colors.black.withValues(alpha: 0.8),
Colors.transparent,
],
),
),
),
),
// 3. Glassmorphic Bottom Bar (Always showing Clock and Next Prayer)
Positioned(
left: 64 * s,
right: 64 * s,
bottom: 64 * s,
child: ClipRRect(
borderRadius: BorderRadius.circular(SacredRadii.xl),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 40, sigmaY: 40),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 48 * s, vertical: 32 * s),
decoration: BoxDecoration(
color: SacredColors.surfaceContainerLowest.withValues(alpha: 0.4),
borderRadius: BorderRadius.circular(SacredRadii.xl),
border: Border.all(color: Colors.white.withValues(alpha: 0.1)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Left: Mosque Name
Text(
settings.masjidName,
style: GoogleFonts.plusJakartaSans(
fontSize: 32 * s,
fontWeight: FontWeight.w800,
color: Colors.white,
letterSpacing: 1 * s,
),
),
// Center: Clock
_buildMiniClock(s, screenData),
// Right: Next Prayer
if (screenData.nextPrayer != null && screenData.timeUntilNext != null)
_buildNextPrayer(s, screenData),
],
),
),
),
),
),
],
),
);
}
Widget _buildMiniClock(double s, ScreenStateData data) {
final timeStr = "${data.now.hour.toString().padLeft(2, '0')}:${data.now.minute.toString().padLeft(2, '0')}";
final secStr = data.now.second.toString().padLeft(2, '0');
return Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
timeStr,
style: GoogleFonts.plusJakartaSans(
fontSize: 64 * s,
fontWeight: FontWeight.w800,
color: Colors.white,
height: 1.0,
),
),
SizedBox(width: 8 * s),
Padding(
padding: EdgeInsets.only(bottom: 8 * s),
child: Text(
secStr,
style: GoogleFonts.plusJakartaSans(
fontSize: 32 * s,
fontWeight: FontWeight.w700,
color: SacredColors.primary,
),
),
),
],
);
}
Widget _buildNextPrayer(double s, ScreenStateData data) {
final dur = data.timeUntilNext!;
final h = dur.inHours;
final m = (dur.inMinutes % 60);
final countDownStr = h > 0 ? "-$h jam $m mnt" : "-$m mnt";
final prayerTitle = data.nextPrayer!.id.toUpperCase();
return Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'MENJELANG $prayerTitle',
style: GoogleFonts.plusJakartaSans(
fontSize: 20 * s,
fontWeight: FontWeight.w700,
color: SacredColors.onSurfaceVariant.withValues(alpha: 0.9),
letterSpacing: 2 * s,
),
),
SizedBox(height: 4 * s),
Text(
countDownStr,
style: GoogleFonts.manrope(
fontSize: 28 * s,
fontWeight: FontWeight.w800,
color: SacredColors.primary,
),
),
],
);
}
Widget _buildErrorImage(double s) {
return Container(
color: SacredColors.surfaceContainerLow,
child: Center(
child: Icon(Icons.broken_image, size: 64 * s, color: SacredColors.onSurfaceVariant),
),
);
}
}