import 'dart:async'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import '../../../core/theme/app_colors.dart'; import '../../../core/widgets/app_icon.dart'; import '../../../core/widgets/pressable.dart'; import '../../home/gps_speed_controller.dart'; import '../../home/obd_controller.dart'; import '../../home/telemetry_settings_controller.dart'; import '../../home/weather_controller.dart'; /// Time, speed, temperature and a Home shortcut for the Jellyfin pages. class JellyfinStatusStrip extends StatefulWidget { const JellyfinStatusStrip({super.key}); @override State createState() => _JellyfinStatusStripState(); } class _JellyfinStatusStripState extends State { late DateTime _now = DateTime.now(); Timer? _timer; @override void initState() { super.initState(); _scheduleTick(); } void _scheduleTick() { _timer?.cancel(); final now = DateTime.now(); final next = DateTime( now.year, now.month, now.day, now.hour, now.minute, ).add(const Duration(minutes: 1)); _timer = Timer(next.difference(now) + const Duration(milliseconds: 80), () { if (!mounted) return; setState(() => _now = DateTime.now()); _scheduleTick(); }); } @override void dispose() { _timer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { final colors = context.colors; final theme = Theme.of(context); final telemetry = context.watch(); final obd = context.watch(); final gps = context.watch(); final weather = context.watch(); final useObdSpeed = telemetry.speedEnabled && telemetry.speedUseObd && obd.hasTelemetry; final speed = !telemetry.speedEnabled ? null : useObdSpeed ? obd.speedKmh : gps.speedKmh; final useObdTemperature = telemetry.temperatureUseObd && obd.ambientCelsius != null; final temperature = !telemetry.temperatureEnabled ? null : useObdTemperature ? obd.ambientCelsius : (weather.hasTemperature ? weather.temperatureCelsius : null); final locale = Localizations.localeOf(context).toLanguageTag(); final use24Hour = MediaQuery.alwaysUse24HourFormatOf(context); final time = (use24Hour ? DateFormat.Hm(locale) : DateFormat.jm(locale)) .format(_now); return Container( key: const ValueKey('jellyfin-status-strip'), padding: const EdgeInsets.fromLTRB(16, 8, 8, 8), child: Row( mainAxisSize: MainAxisSize.min, children: [ Text( time, style: theme.textTheme.labelLarge?.copyWith( color: colors.ink, fontSize: 16, fontFeatures: const [FontFeature.tabularFigures()], ), ), const SizedBox(width: 14), _StripMetric( iconAsset: 'assets/icons/gauge.svg', text: speed == null ? '-- km/h' : '${speed.round()} km/h', available: speed != null, ), const SizedBox(width: 14), _StripMetric( iconAsset: 'assets/icons/thermometer.svg', text: temperature == null ? '--°C' : '${temperature.round()}°C', available: temperature != null, ), const SizedBox(width: 10), Pressable( onTap: () => Navigator.of(context).popUntil((route) => route.isFirst), semanticLabel: 'Go to home', pressedScale: 0.92, child: Container( width: 42, height: 42, decoration: BoxDecoration( color: colors.surfaceStrong, shape: BoxShape.circle, border: Border.all(color: colors.border), ), alignment: Alignment.center, child: AppIcon( 'assets/icons/home.svg', size: 21, color: colors.ink, ), ), ), ], ), ); } } class _StripMetric extends StatelessWidget { const _StripMetric({ required this.iconAsset, required this.text, required this.available, }); final String iconAsset; final String text; final bool available; @override Widget build(BuildContext context) { final colors = context.colors; final theme = Theme.of(context); return Row( mainAxisSize: MainAxisSize.min, children: [ AppIcon( iconAsset, size: 18, color: available ? colors.inkMuted : colors.inkFaint, ), const SizedBox(width: 6), Text( text, style: theme.textTheme.labelLarge?.copyWith( color: available ? colors.ink : colors.inkFaint, fontFeatures: const [FontFeature.tabularFigures()], ), ), ], ); } }