temperature_settings_card.dart 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. import '../../core/theme/app_colors.dart';
  4. import '../../core/widgets/app_icon.dart';
  5. import '../home/obd_controller.dart';
  6. import '../home/telemetry_settings_controller.dart';
  7. import 'settings_widgets.dart';
  8. /// Settings card for the outside-temperature row and its data source.
  9. class TemperatureSettingsCard extends StatelessWidget {
  10. const TemperatureSettingsCard({super.key});
  11. @override
  12. Widget build(BuildContext context) {
  13. final colors = context.colors;
  14. final theme = Theme.of(context);
  15. final telemetry = context.watch<TelemetrySettingsController>();
  16. final obd = context.watch<ObdController>();
  17. return Column(
  18. crossAxisAlignment: CrossAxisAlignment.start,
  19. children: [
  20. Row(
  21. children: [
  22. Container(
  23. width: 42,
  24. height: 42,
  25. decoration: BoxDecoration(
  26. color: colors.accentSoft,
  27. borderRadius: BorderRadius.circular(14),
  28. ),
  29. alignment: Alignment.center,
  30. child: AppIcon(
  31. 'assets/icons/thermometer.svg',
  32. size: 20,
  33. color: colors.accent,
  34. ),
  35. ),
  36. const SizedBox(width: 14),
  37. Expanded(
  38. child: Column(
  39. crossAxisAlignment: CrossAxisAlignment.start,
  40. children: [
  41. Text('Show temperature', style: theme.textTheme.titleMedium),
  42. const SizedBox(height: 2),
  43. Text(
  44. 'Show the outside temperature below the clock.',
  45. style: theme.textTheme.bodySmall?.copyWith(
  46. color: colors.inkMuted,
  47. ),
  48. ),
  49. ],
  50. ),
  51. ),
  52. const SizedBox(width: 8),
  53. SettingsSwitch(
  54. value: telemetry.temperatureEnabled,
  55. semanticsLabel: telemetry.temperatureEnabled
  56. ? 'Hide the outside temperature'
  57. : 'Show the outside temperature',
  58. onChanged: (value) async {
  59. final ok = await telemetry.setTemperatureEnabled(value);
  60. if (!ok && context.mounted) {
  61. _message(
  62. context,
  63. telemetry.weatherError ??
  64. 'Location permission is required for weather.',
  65. );
  66. }
  67. },
  68. ),
  69. ],
  70. ),
  71. if (obd.hasConfiguredAdapter && telemetry.temperatureEnabled) ...[
  72. Divider(color: colors.border, height: 30),
  73. Row(
  74. children: [
  75. Expanded(
  76. child: Column(
  77. crossAxisAlignment: CrossAxisAlignment.start,
  78. children: [
  79. Text(
  80. 'Use OBD-II for temperature',
  81. style: theme.textTheme.bodyLarge,
  82. ),
  83. const SizedBox(height: 2),
  84. Text(
  85. 'GPS and the weather provider are used when this is off.',
  86. style: theme.textTheme.bodySmall?.copyWith(
  87. color: colors.inkMuted,
  88. ),
  89. ),
  90. ],
  91. ),
  92. ),
  93. const SizedBox(width: 8),
  94. SettingsSwitch(
  95. value: telemetry.temperatureUseObd,
  96. semanticsLabel: telemetry.temperatureUseObd
  97. ? 'Use GPS and weather for temperature'
  98. : 'Use OBD-II for temperature',
  99. onChanged: (value) async {
  100. final ok = await telemetry.setTemperatureUseObd(value);
  101. if (!ok && context.mounted) {
  102. _message(
  103. context,
  104. telemetry.weatherError ??
  105. 'Location permission is required for weather.',
  106. );
  107. }
  108. },
  109. ),
  110. ],
  111. ),
  112. ],
  113. if (telemetry.temperatureEnabled &&
  114. telemetry.weatherError != null &&
  115. (!telemetry.weatherEnabled || !telemetry.temperatureUseObd)) ...[
  116. const SizedBox(height: 6),
  117. Text(
  118. telemetry.weatherError!,
  119. style: theme.textTheme.bodySmall?.copyWith(color: colors.inkMuted),
  120. ),
  121. ],
  122. ],
  123. );
  124. }
  125. void _message(BuildContext context, String message) {
  126. final messenger = ScaffoldMessenger.of(context);
  127. messenger.hideCurrentSnackBar();
  128. messenger.showSnackBar(SnackBar(content: Text(message)));
  129. }
  130. }