import 'dart:async'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../../../core/theme/app_colors.dart'; /// Large, quiet clock. It sleeps until the next minute instead of ticking /// every second. class ClockBlock extends StatefulWidget { const ClockBlock({super.key, required this.compact}); final bool compact; @override State createState() => _ClockBlockState(); } class _ClockBlockState 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 theme = Theme.of(context); final colors = context.colors; final locale = Localizations.localeOf(context).toLanguageTag(); final use24Hour = MediaQuery.alwaysUse24HourFormatOf(context); final time = (use24Hour ? DateFormat.Hm(locale) : DateFormat.jm(locale)) .format(_now); final date = DateFormat('EEEE, d MMMM', locale).format(_now); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( time, maxLines: 1, style: theme.textTheme.displayLarge?.copyWith( fontSize: widget.compact ? 56 : 72, fontFeatures: const [FontFeature.tabularFigures()], height: 0.95, ), ), const SizedBox(height: 10), Row( mainAxisSize: MainAxisSize.min, children: [ Container( width: 6, height: 6, decoration: BoxDecoration( color: colors.accent, shape: BoxShape.circle, ), ), const SizedBox(width: 10), Text( date, maxLines: 1, overflow: TextOverflow.ellipsis, style: theme.textTheme.titleMedium?.copyWith( color: colors.inkMuted, fontWeight: FontWeight.w500, fontSize: widget.compact ? 14 : 16, ), ), ], ), ], ); } }