MotorSignal-App/lib/features/dashboard/widgets/heading_indicator.dart

88 lines
2.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/theme/app_colors.dart';
import '../../../core/theme/app_typography.dart';
import '../../../services/compass_service.dart';
import '../../../services/telemetry_service.dart';
/// Isolated leaf widget for heading and cardinal direction.
///
/// Subscribes strictly to heading changes via [telemetryStreamProvider]
/// to isolate 20 Hz rebuilds to this widget.
class HeadingIndicator extends ConsumerWidget {
final bool compact;
const HeadingIndicator({
super.key,
this.compact = false,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final heading = ref.watch(
telemetryStreamProvider.select((s) => s.value?.heading ?? 0.0),
);
final isDark = Theme.of(context).brightness == Brightness.dark;
final cardinalColor = isDark ? AppColors.cyberCyan : AppColors.lightPrimary;
final degreesColor = isDark ? Colors.white70 : AppColors.lightOnSurfaceVariant;
final headingStr = CompassService.getHeadingString(heading);
if (compact) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.explore_outlined, color: cardinalColor, size: 14),
const SizedBox(width: 4),
Text(
headingStr,
style: TextStyle(
fontFamily: AppTypography.fontHeadline,
fontSize: 14,
fontWeight: FontWeight.w700,
color: cardinalColor,
),
),
const SizedBox(width: 4),
Text(
'${heading.toStringAsFixed(0)}°',
style: TextStyle(
fontFamily: AppTypography.fontTelemetry,
fontSize: 11,
fontWeight: FontWeight.w600,
color: degreesColor,
),
),
],
);
}
return Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
headingStr,
style: TextStyle(
fontFamily: AppTypography.fontHeadline,
fontSize: 20,
fontWeight: FontWeight.w700,
color: cardinalColor,
),
),
const SizedBox(width: 5),
Text(
'${heading.toStringAsFixed(0)}°',
style: TextStyle(
fontFamily: AppTypography.fontTelemetry,
fontSize: 14,
fontWeight: FontWeight.w600,
color: degreesColor,
),
),
],
);
}
}