88 lines
2.6 KiB
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: 16,
|
|
fontWeight: FontWeight.w800,
|
|
color: cardinalColor,
|
|
),
|
|
),
|
|
const SizedBox(width: 4),
|
|
Text(
|
|
'${heading.toStringAsFixed(0)}°',
|
|
style: TextStyle(
|
|
fontFamily: AppTypography.fontTelemetry,
|
|
fontSize: 12,
|
|
fontWeight: FontWeight.w700,
|
|
color: degreesColor,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
return Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.baseline,
|
|
textBaseline: TextBaseline.alphabetic,
|
|
children: [
|
|
Text(
|
|
headingStr,
|
|
style: TextStyle(
|
|
fontFamily: AppTypography.fontHeadline,
|
|
fontSize: 26,
|
|
fontWeight: FontWeight.w900,
|
|
color: cardinalColor,
|
|
),
|
|
),
|
|
const SizedBox(width: 6),
|
|
Text(
|
|
'${heading.toStringAsFixed(0)}°',
|
|
style: TextStyle(
|
|
fontFamily: AppTypography.fontTelemetry,
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.w700,
|
|
color: degreesColor,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|