night_mode_overlay.dart 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:intl/intl.dart';
  4. /// Black night screen with a very dim clock. Tapping anywhere returns.
  5. class NightModeOverlay extends StatefulWidget {
  6. const NightModeOverlay({super.key, required this.onDismiss});
  7. final VoidCallback onDismiss;
  8. @override
  9. State<NightModeOverlay> createState() => _NightModeOverlayState();
  10. }
  11. class _NightModeOverlayState extends State<NightModeOverlay> {
  12. late DateTime _now = DateTime.now();
  13. Timer? _timer;
  14. @override
  15. void initState() {
  16. super.initState();
  17. _scheduleTick();
  18. }
  19. void _scheduleTick() {
  20. _timer?.cancel();
  21. final now = DateTime.now();
  22. final next = DateTime(
  23. now.year,
  24. now.month,
  25. now.day,
  26. now.hour,
  27. now.minute,
  28. ).add(const Duration(minutes: 1));
  29. _timer = Timer(next.difference(now) + const Duration(milliseconds: 80), () {
  30. if (!mounted) return;
  31. setState(() => _now = DateTime.now());
  32. _scheduleTick();
  33. });
  34. }
  35. @override
  36. void dispose() {
  37. _timer?.cancel();
  38. super.dispose();
  39. }
  40. @override
  41. Widget build(BuildContext context) {
  42. final locale = Localizations.localeOf(context).toLanguageTag();
  43. final use24Hour = MediaQuery.alwaysUse24HourFormatOf(context);
  44. final time = (use24Hour ? DateFormat.Hm(locale) : DateFormat.jm(locale))
  45. .format(_now);
  46. return Semantics(
  47. button: true,
  48. label: 'Exit night mode',
  49. child: GestureDetector(
  50. behavior: HitTestBehavior.opaque,
  51. onTap: widget.onDismiss,
  52. child: ColoredBox(
  53. color: Colors.black,
  54. child: Center(
  55. child: Text(
  56. time,
  57. maxLines: 1,
  58. style: TextStyle(
  59. color: Colors.white.withValues(alpha: 0.12),
  60. fontSize: 84,
  61. fontWeight: FontWeight.w300,
  62. height: 1,
  63. fontFeatures: const [FontFeature.tabularFigures()],
  64. ),
  65. ),
  66. ),
  67. ),
  68. ),
  69. );
  70. }
  71. }