diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/core/constants/vss_path.dart | 9 | ||||
-rw-r--r-- | lib/data/data_providers/app_provider.dart | 6 | ||||
-rw-r--r-- | lib/data/data_providers/audio_notifier.dart | 24 | ||||
-rw-r--r-- | lib/data/data_providers/units_notifier.dart | 65 | ||||
-rw-r--r-- | lib/data/data_providers/val_client.dart | 47 | ||||
-rw-r--r-- | lib/data/data_providers/vehicle_notifier.dart | 87 | ||||
-rw-r--r-- | lib/data/models/units.dart | 17 | ||||
-rw-r--r-- | lib/data/models/vehicle.dart | 16 | ||||
-rw-r--r-- | lib/export.dart | 1 | ||||
-rw-r--r-- | lib/presentation/router/routes/routes.dart | 2 | ||||
-rw-r--r-- | lib/presentation/screens/dashboard/widgets/car_status.dart | 95 | ||||
-rw-r--r-- | lib/presentation/screens/dashboard/widgets/circle_indicator.dart | 2 | ||||
-rw-r--r-- | lib/presentation/screens/dashboard/widgets/range.dart | 19 | ||||
-rw-r--r-- | lib/presentation/screens/settings/settings_screens/units/distance/distance_unit_screen.dart | 11 | ||||
-rw-r--r-- | lib/presentation/screens/settings/settings_screens/units/pressure/pressure_unit_screen.dart | 121 | ||||
-rw-r--r-- | lib/presentation/screens/settings/settings_screens/units/units_screen.dart | 16 |
16 files changed, 392 insertions, 146 deletions
diff --git a/lib/core/constants/vss_path.dart b/lib/core/constants/vss_path.dart index afba8de..cdb39f2 100644 --- a/lib/core/constants/vss_path.dart +++ b/lib/core/constants/vss_path.dart @@ -45,6 +45,12 @@ class VSSPath { 'Vehicle.Cabin.HVAC.Station.Row1.Driver.Temperature'; static const String vehiclePassengerTemperature = 'Vehicle.Cabin.HVAC.Station.Row1.Passenger.Temperature'; + static const String vehicleHmiDistanceUnit = + 'Vehicle.Cabin.Infotainment.HMI.DistanceUnit'; + static const String vehicleHmiTemperatureUnit = + 'Vehicle.Cabin.Infotainment.HMI.TemperatureUnit'; + static const String vehicleHmiPressureUnit = + 'Vehicle.Cabin.Infotainment.HMI.TirePressureUnit'; List<String> getSignalsList() { return const [ @@ -72,6 +78,9 @@ class VSSPath { vehicleFanSpeed, vehicleDriverTemperature, vehiclePassengerTemperature, + vehicleHmiDistanceUnit, + vehicleHmiTemperatureUnit, + vehicleHmiPressureUnit, ]; } } diff --git a/lib/data/data_providers/app_provider.dart b/lib/data/data_providers/app_provider.dart index 3d00d4c..ee6d29e 100644 --- a/lib/data/data_providers/app_provider.dart +++ b/lib/data/data_providers/app_provider.dart @@ -40,6 +40,7 @@ enum AppState { weather, distanceUnit, tempUnit, + pressureUnit, clock, date, time, @@ -78,9 +79,8 @@ final signalsProvider = StateNotifierProvider<SignalNotifier, Signals>((ref) { return SignalNotifier(const Signals.initial()); }); -final unitStateProvider = StateNotifierProvider<UnitsNotifier, Units>((ref) { - return UnitsNotifier(const Units.initial()); -}); +final unitStateProvider = + NotifierProvider<UnitsNotifier, Units>(UnitsNotifier.new); final audioStateProvider = NotifierProvider<AudioStateNotifier, AudioState>(AudioStateNotifier.new); diff --git a/lib/data/data_providers/audio_notifier.dart b/lib/data/data_providers/audio_notifier.dart index a601095..76b34a7 100644 --- a/lib/data/data_providers/audio_notifier.dart +++ b/lib/data/data_providers/audio_notifier.dart @@ -36,36 +36,36 @@ class AudioStateNotifier extends Notifier<AudioState> { ); } - bool handleSignalsUpdate(EntryUpdate update) { + bool handleSignalUpdate(DataEntry entry) { bool handled = true; - switch (update.entry.path) { + switch (entry.path) { case VSSPath.vehicleMediaVolume: - if (update.entry.value.hasUint32()) { - double value = update.entry.value.uint32.toDouble(); + if (entry.value.hasUint32()) { + double value = entry.value.uint32.toDouble(); state = state.copyWith(volume: value); } break; case VSSPath.vehicleMediaBalance: - if (update.entry.value.hasInt32()) { - double value = (update.entry.value.int32 + 100) / 20.0; + if (entry.value.hasInt32()) { + double value = (entry.value.int32 + 100) / 20.0; state = state.copyWith(balance: value); } break; case VSSPath.vehicleMediaFade: - if (update.entry.value.hasInt32()) { - double value = (update.entry.value.int32 + 100) / 20.0; + if (entry.value.hasInt32()) { + double value = (entry.value.int32 + 100) / 20.0; state = state.copyWith(fade: value); } break; case VSSPath.vehicleMediaTreble: - if (update.entry.value.hasInt32()) { - double value = (update.entry.value.int32 + 100) / 20.0; + if (entry.value.hasInt32()) { + double value = (entry.value.int32 + 100) / 20.0; state = state.copyWith(treble: value); } break; case VSSPath.vehicleMediaBass: - if (update.entry.value.hasInt32()) { - double value = (update.entry.value.int32 + 100) / 20.0; + if (entry.value.hasInt32()) { + double value = (entry.value.int32 + 100) / 20.0; state = state.copyWith(bass: value); } break; diff --git a/lib/data/data_providers/units_notifier.dart b/lib/data/data_providers/units_notifier.dart index f7c25aa..26b79da 100644 --- a/lib/data/data_providers/units_notifier.dart +++ b/lib/data/data_providers/units_notifier.dart @@ -1,13 +1,72 @@ -import '../../export.dart'; +import 'package:flutter_ics_homescreen/export.dart'; +import 'package:protos/val-api.dart'; -class UnitsNotifier extends StateNotifier<Units> { - UnitsNotifier(super.state); +class UnitsNotifier extends Notifier<Units> { + @override + Units build() { + return const Units.initial(); + } + + bool handleSignalUpdate(DataEntry entry) { + bool handled = true; + switch (entry.path) { + case VSSPath.vehicleHmiDistanceUnit: + if (entry.value.hasString()) { + String value = entry.value.string; + DistanceUnit unit = DistanceUnit.kilometers; + if (value != "KILOMETERS") unit = DistanceUnit.miles; + state = state.copyWith(distanceUnit: unit); + } + break; + case VSSPath.vehicleHmiTemperatureUnit: + if (entry.value.hasString()) { + String value = entry.value.string; + TemperatureUnit unit = TemperatureUnit.celsius; + if (value != "C") unit = TemperatureUnit.fahrenheit; + state = state.copyWith(temperatureUnit: unit); + } + break; + case VSSPath.vehicleHmiPressureUnit: + if (entry.value.hasString()) { + String value = entry.value.string; + PressureUnit unit = PressureUnit.kilopascals; + if (value != "KPA") unit = PressureUnit.psi; + state = state.copyWith(pressureUnit: unit); + } + break; + default: + handled = false; + } + return handled; + } void setDistanceUnit(DistanceUnit unit) { state = state.copyWith(distanceUnit: unit); + var valClient = ref.read(valClientProvider); + valClient.setString( + VSSPath.vehicleHmiDistanceUnit, + unit == DistanceUnit.kilometers ? "KILOMETERS" : "MILES", + true, + ); } void setTemperatureUnit(TemperatureUnit unit) { state = state.copyWith(temperatureUnit: unit); + var valClient = ref.read(valClientProvider); + valClient.setString( + VSSPath.vehicleHmiTemperatureUnit, + unit == TemperatureUnit.celsius ? "C" : "F", + true, + ); + } + + void setPressureUnit(PressureUnit unit) { + state = state.copyWith(pressureUnit: unit); + var valClient = ref.read(valClientProvider); + valClient.setString( + VSSPath.vehicleHmiPressureUnit, + unit == PressureUnit.kilopascals ? "KPA" : "PSI", + true, + ); } } diff --git a/lib/data/data_providers/val_client.dart b/lib/data/data_providers/val_client.dart index db962ee..5e7339c 100644 --- a/lib/data/data_providers/val_client.dart +++ b/lib/data/data_providers/val_client.dart @@ -29,15 +29,21 @@ class ValClient { } void run() async { - List<String> fewSignals = VSSPath().getSignalsList(); - var request = SubscribeRequest(); + List<String> signals = VSSPath().getSignalsList(); Map<String, String> metadata = {}; if (config.authorization.isNotEmpty) { metadata = {'authorization': "Bearer ${config.authorization}"}; } - for (int i = 0; i < fewSignals.length; i++) { + + // Initialize signal states + for (int i = 0; i < signals.length; i++) { + get(signals[i]); + } + + var request = SubscribeRequest(); + for (int i = 0; i < signals.length; i++) { var entry = SubscribeEntry(); - entry.path = fewSignals[i]; + entry.path = signals[i]; entry.fields.add(Field.FIELD_PATH); entry.fields.add(Field.FIELD_VALUE); request.entries.add(entry); @@ -48,7 +54,7 @@ class ValClient { responseStream.listen((value) async { for (var update in value.updates) { if (!(update.hasEntry() && update.entry.hasPath())) continue; - handleSignalsUpdate(update); + handleSignalUpdate(update.entry); } }, onError: (stacktrace, errorDescriptor) { debugPrint(stacktrace.toString()); @@ -58,11 +64,14 @@ class ValClient { } } - bool handleSignalsUpdate(EntryUpdate update) { - if (ref.read(vehicleProvider.notifier).handleSignalsUpdate(update)) { + bool handleSignalUpdate(DataEntry entry) { + if (ref.read(vehicleProvider.notifier).handleSignalUpdate(entry)) { + return true; + } + if (ref.read(audioStateProvider.notifier).handleSignalUpdate(entry)) { return true; } - return ref.read(audioStateProvider.notifier).handleSignalsUpdate(update); + return ref.read(unitStateProvider.notifier).handleSignalUpdate(entry); } void setUint32(String path, int value, [bool actuator = true]) async { @@ -114,4 +123,26 @@ class ValClient { } await stub.set(request, options: CallOptions(metadata: metadata)); } + + void get(String path) async { + var entry = EntryRequest()..path = path; + entry.fields.add(Field.FIELD_VALUE); + var request = GetRequest(); + request.entries.add(entry); + Map<String, String> metadata = {}; + if (config.authorization.isNotEmpty) { + metadata = {'authorization': "Bearer ${config.authorization}"}; + } + debugPrint("Getting {path} value"); + var response = + await stub.get(request, options: CallOptions(metadata: metadata)); + if (response.hasError()) { + debugPrint("Get request had error {response.error().reason}"); + return; + } + for (var entry in response.entries) { + if (!entry.hasPath()) continue; + handleSignalUpdate(entry); + } + } } diff --git a/lib/data/data_providers/vehicle_notifier.dart b/lib/data/data_providers/vehicle_notifier.dart index 6fafb8c..fb2de19 100644 --- a/lib/data/data_providers/vehicle_notifier.dart +++ b/lib/data/data_providers/vehicle_notifier.dart @@ -15,99 +15,93 @@ class VehicleNotifier extends Notifier<Vehicle> { state = state.copyWith(speed: newValue); } - bool handleSignalsUpdate(EntryUpdate update) { + bool handleSignalUpdate(DataEntry entry) { bool handled = true; - switch (update.entry.path) { + switch (entry.path) { case VSSPath.vehicleSpeed: - if (update.entry.value.hasFloat()) { - state = state.copyWith(speed: update.entry.value.float); + if (entry.value.hasFloat()) { + state = state.copyWith(speed: entry.value.float); } break; case VSSPath.vehicleInsideTemperature: - if (update.entry.value.hasFloat()) { - state = state.copyWith(insideTemperature: update.entry.value.float); + if (entry.value.hasFloat()) { + state = state.copyWith(insideTemperature: entry.value.float); } break; case VSSPath.vehicleOutsideTemperature: - if (update.entry.value.hasFloat()) { - state = state.copyWith(outsideTemperature: update.entry.value.float); + if (entry.value.hasFloat()) { + state = state.copyWith(outsideTemperature: entry.value.float); } break; case VSSPath.vehicleRange: - if (update.entry.value.hasUint32()) { - state = state.copyWith(range: update.entry.value.uint32); + if (entry.value.hasUint32()) { + state = state.copyWith(range: entry.value.uint32); } break; case VSSPath.vehicleFuelLevel: - if (update.entry.value.hasUint32()) { - state = state.copyWith(fuelLevel: update.entry.value.uint32); + if (entry.value.hasUint32()) { + state = state.copyWith(fuelLevel: entry.value.uint32); } break; case VSSPath.vehicleIsChildLockActiveLeft: - if (update.entry.value.hasBool_12()) { - state = - state.copyWith(isChildLockActiveLeft: update.entry.value.bool_12); + if (entry.value.hasBool_12()) { + state = state.copyWith(isChildLockActiveLeft: entry.value.bool_12); } break; case VSSPath.vehicleIsChildLockActiveRight: - if (update.entry.value.hasBool_12()) { - state = state.copyWith( - isChildLockActiveRight: update.entry.value.bool_12); + if (entry.value.hasBool_12()) { + state = state.copyWith(isChildLockActiveRight: entry.value.bool_12); } break; case VSSPath.vehicleEngineSpeed: - if (update.entry.value.hasFloat()) { - state = state.copyWith(engineSpeed: update.entry.value.float); + if (entry.value.hasFloat()) { + state = state.copyWith(engineSpeed: entry.value.float); } break; case VSSPath.vehicleFrontLeftTire: - if (update.entry.value.hasUint32()) { - state = state.copyWith(frontLeftTire: update.entry.value.uint32); + if (entry.value.hasUint32()) { + state = state.copyWith(frontLeftTire: entry.value.uint32); } break; case VSSPath.vehicleFrontRightTire: - if (update.entry.value.hasUint32()) { - state = state.copyWith(frontRightTire: update.entry.value.uint32); + if (entry.value.hasUint32()) { + state = state.copyWith(frontRightTire: entry.value.uint32); } break; case VSSPath.vehicleRearLeftTire: - if (update.entry.value.hasUint32()) { - state = state.copyWith(rearLeftTire: update.entry.value.uint32); + if (entry.value.hasUint32()) { + state = state.copyWith(rearLeftTire: entry.value.uint32); } break; case VSSPath.vehicleRearRightTire: - if (update.entry.value.hasUint32()) { - state = state.copyWith(rearRightTire: update.entry.value.uint32); + if (entry.value.hasUint32()) { + state = state.copyWith(rearRightTire: entry.value.uint32); } break; case VSSPath.vehicleIsAirConditioningActive: - if (update.entry.value.hasBool_12()) { - state = state.copyWith( - isAirConditioningActive: update.entry.value.bool_12); + if (entry.value.hasBool_12()) { + state = state.copyWith(isAirConditioningActive: entry.value.bool_12); } break; case VSSPath.vehicleIsFrontDefrosterActive: - if (update.entry.value.hasBool_12()) { - state = state.copyWith( - isFrontDefrosterActive: update.entry.value.bool_12); + if (entry.value.hasBool_12()) { + state = state.copyWith(isFrontDefrosterActive: entry.value.bool_12); } break; case VSSPath.vehicleIsRearDefrosterActive: - if (update.entry.value.hasBool_12()) { - state = - state.copyWith(isRearDefrosterActive: update.entry.value.bool_12); + if (entry.value.hasBool_12()) { + state = state.copyWith(isRearDefrosterActive: entry.value.bool_12); } break; case VSSPath.vehicleIsRecirculationActive: - if (update.entry.value.hasBool_12()) { - state = - state.copyWith(isRecirculationActive: update.entry.value.bool_12); + if (entry.value.hasBool_12()) { + state = state.copyWith(isRecirculationActive: entry.value.bool_12); } break; case VSSPath.vehicleFanSpeed: - if (update.entry.value.hasUint32()) { + if (entry.value.hasUint32()) { // Convert 0-100 to local 0-3 setting - var value = update.entry.value.uint32; + var value = entry.value.uint32; var fanSpeed = 0; if (value > 66) fanSpeed = 3; @@ -118,14 +112,13 @@ class VehicleNotifier extends Notifier<Vehicle> { } break; case VSSPath.vehicleDriverTemperature: - if (update.entry.value.hasInt32()) { - state = state.copyWith(driverTemperature: update.entry.value.int32); + if (entry.value.hasInt32()) { + state = state.copyWith(driverTemperature: entry.value.int32); } break; case VSSPath.vehiclePassengerTemperature: - if (update.entry.value.hasInt32()) { - state = - state.copyWith(passengerTemperature: update.entry.value.int32); + if (entry.value.hasInt32()) { + state = state.copyWith(passengerTemperature: entry.value.int32); } break; default: diff --git a/lib/data/models/units.dart b/lib/data/models/units.dart index 9e71213..c299a12 100644 --- a/lib/data/models/units.dart +++ b/lib/data/models/units.dart @@ -4,32 +4,39 @@ enum DistanceUnit { kilometers, miles } enum TemperatureUnit { celsius, fahrenheit } +enum PressureUnit { kilopascals, psi } + @immutable class Units { final DistanceUnit distanceUnit; final TemperatureUnit temperatureUnit; + final PressureUnit pressureUnit; const Units( this.distanceUnit, this.temperatureUnit, + this.pressureUnit, ); const Units.initial() : distanceUnit = DistanceUnit.kilometers, - temperatureUnit = TemperatureUnit.celsius; + temperatureUnit = TemperatureUnit.celsius, + pressureUnit = PressureUnit.kilopascals; Units copyWith({ DistanceUnit? distanceUnit, TemperatureUnit? temperatureUnit, + PressureUnit? pressureUnit, }) { return Units( distanceUnit ?? this.distanceUnit, temperatureUnit ?? this.temperatureUnit, + pressureUnit ?? this.pressureUnit, ); } @override String toString() => - 'Units(distanceUnit: $distanceUnit, temperatureUnit: $temperatureUnit)'; + 'Units(distanceUnit: $distanceUnit, temperatureUnit: $temperatureUnit, pressureUnit: $pressureUnit)'; @override bool operator ==(Object other) { @@ -37,9 +44,11 @@ class Units { return other is Units && other.distanceUnit == distanceUnit && - other.temperatureUnit == temperatureUnit; + other.temperatureUnit == temperatureUnit && + other.pressureUnit == pressureUnit; } @override - int get hashCode => distanceUnit.hashCode ^ temperatureUnit.hashCode; + int get hashCode => + distanceUnit.hashCode ^ temperatureUnit.hashCode ^ pressureUnit.hashCode; } diff --git a/lib/data/models/vehicle.dart b/lib/data/models/vehicle.dart index ad76620..dfeae05 100644 --- a/lib/data/models/vehicle.dart +++ b/lib/data/models/vehicle.dart @@ -57,10 +57,10 @@ class Vehicle { fuelLevel = 0, isChildLockActiveLeft = false, isChildLockActiveRight = true, - frontLeftTire = 33, - frontRightTire = 31, - rearLeftTire = 31, - rearRightTire = 32, + frontLeftTire = 228, + frontRightTire = 214, + rearLeftTire = 214, + rearRightTire = 221, isAirConditioningActive = false, isFrontDefrosterActive = false, isRearDefrosterActive = false, @@ -79,10 +79,10 @@ class Vehicle { fuelLevel = 49, isChildLockActiveLeft = false, isChildLockActiveRight = true, - frontLeftTire = 33, - frontRightTire = 31, - rearLeftTire = 31, - rearRightTire = 32, + frontLeftTire = 228, + frontRightTire = 214, + rearLeftTire = 214, + rearRightTire = 221, isAirConditioningActive = false, isFrontDefrosterActive = false, isRearDefrosterActive = false, diff --git a/lib/export.dart b/lib/export.dart index e97fd90..ef029c7 100644 --- a/lib/export.dart +++ b/lib/export.dart @@ -41,6 +41,7 @@ export 'presentation/screens/settings/settings_screens/units/units_screen.dart'; export 'presentation/screens/settings/settings_screens/version_info/version_info_screend.dart'; export 'presentation/screens/settings/settings_screens/units/distance/distance_unit_screen.dart'; export 'presentation/screens/settings/settings_screens/units/temperature/temperature_unit_screen.dart'; +export 'presentation/screens/settings/settings_screens/units/pressure/pressure_unit_screen.dart'; export 'package:flutter_ics_homescreen/presentation/screens/settings/settings_screens/profiles/widgets/new_profile_screen.dart'; export 'presentation/screens/apps/apps.dart'; diff --git a/lib/presentation/router/routes/routes.dart b/lib/presentation/router/routes/routes.dart index 45a1a14..328d495 100644 --- a/lib/presentation/router/routes/routes.dart +++ b/lib/presentation/router/routes/routes.dart @@ -45,6 +45,8 @@ List<Page<dynamic>> onGenerateAppViewPages( return [DistanceUnitPage.page()]; case AppState.tempUnit: return [TemperatureUnitPage.page()]; + case AppState.pressureUnit: + return [PressureUnitPage.page()]; case AppState.clock: return [ClockPage.page()]; case AppState.newProfile: diff --git a/lib/presentation/screens/dashboard/widgets/car_status.dart b/lib/presentation/screens/dashboard/widgets/car_status.dart index b824871..604d404 100644 --- a/lib/presentation/screens/dashboard/widgets/car_status.dart +++ b/lib/presentation/screens/dashboard/widgets/car_status.dart @@ -4,25 +4,13 @@ import 'package:gradient_borders/gradient_borders.dart'; import '../../../../export.dart'; -class CarStatus extends ConsumerStatefulWidget { +class CarStatus extends ConsumerWidget { const CarStatus({super.key}); @override - CarStatusState createState() => CarStatusState(); -} - -class CarStatusState extends ConsumerState<CarStatus> { - @override - void initState() { - super.initState(); - // "ref" can be used in all life-cycles of a StatefulWidget. - //ref.read(counterProvider); - } - - @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef Ref) { return Padding( - padding: const EdgeInsets.fromLTRB(0,0,0,84), + padding: const EdgeInsets.fromLTRB(0, 0, 0, 84), child: SizedBox( height: 440, width: 652, @@ -59,6 +47,18 @@ class LeftCarStatus extends ConsumerWidget { ref.watch(vehicleProvider.select((vehicle) => vehicle.frontLeftTire)); final rearLeftTire = ref.watch(vehicleProvider.select((vehicle) => vehicle.rearLeftTire)); + final unit = + ref.watch(unitStateProvider.select((unit) => unit.pressureUnit)); + + String frontLeftTireString = ""; + String rearLeftTireString = ""; + if (unit == PressureUnit.psi) { + frontLeftTireString = (frontLeftTire * 0.145038).toStringAsFixed(1); + rearLeftTireString = (rearLeftTire * 0.145038).toStringAsFixed(1); + } else { + frontLeftTireString = frontLeftTire.toString(); + rearLeftTireString = rearLeftTire.toString(); + } return Column( mainAxisAlignment: MainAxisAlignment.spaceAround, @@ -67,22 +67,21 @@ class LeftCarStatus extends ConsumerWidget { Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ - PSIProgressIndicator(value: frontLeftTire.toDouble()), + TirePressureProgressIndicator(value: frontLeftTire.toDouble()), Row( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, children: [ Text( - frontLeftTire.toStringAsFixed(1), + frontLeftTireString, style: GoogleFonts.brunoAce( - textStyle: TextStyle( - color: Colors.white, fontSize: 44), + textStyle: TextStyle(color: Colors.white, fontSize: 44), ), ), SizedBox( width: 5, ), - PSIWidget(), + TirePressureUnitWidget(), ], ), ], @@ -91,22 +90,21 @@ class LeftCarStatus extends ConsumerWidget { Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ - PSIProgressIndicator(value: rearLeftTire.toDouble()), + TirePressureProgressIndicator(value: rearLeftTire.toDouble()), Row( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, children: [ Text( - rearLeftTire.toStringAsFixed(1), + rearLeftTireString, style: GoogleFonts.brunoAce( - textStyle: TextStyle( - color: Colors.white, fontSize: 44), + textStyle: TextStyle(color: Colors.white, fontSize: 44), ), ), SizedBox( width: 5, ), - PSIWidget(), + TirePressureUnitWidget(), ], ), ], @@ -127,6 +125,18 @@ class RightCarStatus extends ConsumerWidget { ref.watch(vehicleProvider.select((vehicle) => vehicle.frontRightTire)); final rearRightTire = ref.watch(vehicleProvider.select((vehicle) => vehicle.rearRightTire)); + final unit = + ref.watch(unitStateProvider.select((unit) => unit.pressureUnit)); + + String frontRightTireString = ""; + String rearRightTireString = ""; + if (unit == PressureUnit.psi) { + frontRightTireString = (frontRightTire * 0.145038).toStringAsFixed(1); + rearRightTireString = (rearRightTire * 0.145038).toStringAsFixed(1); + } else { + frontRightTireString = frontRightTire.toString(); + rearRightTireString = rearRightTire.toString(); + } return Column( mainAxisAlignment: MainAxisAlignment.spaceAround, @@ -134,23 +144,21 @@ class RightCarStatus extends ConsumerWidget { children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ - PSIProgressIndicator(value: frontRightTire.toDouble()), + TirePressureProgressIndicator(value: frontRightTire.toDouble()), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( - frontRightTire.toStringAsFixed(1), + frontRightTireString, style: GoogleFonts.brunoAce( - textStyle: TextStyle( - color: Colors.white, fontSize: 44), + textStyle: TextStyle(color: Colors.white, fontSize: 44), ), ), SizedBox( width: 5, ), - PSIWidget(), + TirePressureUnitWidget(), ], ), ], @@ -159,22 +167,21 @@ class RightCarStatus extends ConsumerWidget { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - PSIProgressIndicator(value: rearRightTire.toDouble()), + TirePressureProgressIndicator(value: rearRightTire.toDouble()), Row( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - rearRightTire.toStringAsFixed(1), + rearRightTireString, style: GoogleFonts.brunoAce( - textStyle: TextStyle( - color: Colors.white, fontSize: 44), + textStyle: TextStyle(color: Colors.white, fontSize: 44), ), ), SizedBox( width: 5, ), - PSIWidget(), + TirePressureUnitWidget(), ], ), ], @@ -184,9 +191,9 @@ class RightCarStatus extends ConsumerWidget { } } -class PSIProgressIndicator extends StatelessWidget { +class TirePressureProgressIndicator extends StatelessWidget { final double value; - const PSIProgressIndicator({ + const TirePressureProgressIndicator({ Key? key, required this.value, // Require the value to be passed }) : super(key: key); @@ -208,7 +215,6 @@ class PSIProgressIndicator extends StatelessWidget { LinearGradient(colors: const [Colors.white30, Colors.white]), ), ), - ), Positioned( left: 3, @@ -231,17 +237,20 @@ class PSIProgressIndicator extends StatelessWidget { } } -class PSIWidget extends StatelessWidget { - const PSIWidget({ +class TirePressureUnitWidget extends ConsumerWidget { + const TirePressureUnitWidget({ super.key, }); @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { + final unit = + ref.watch(unitStateProvider.select((unit) => unit.pressureUnit)); + return Padding( padding: const EdgeInsets.only(left: 4.0, right: 1.0, bottom: 2.0), child: Text( - 'PSI', + unit == PressureUnit.kilopascals ? 'kPa' : 'PSI', style: TextStyle( fontSize: 26, ), diff --git a/lib/presentation/screens/dashboard/widgets/circle_indicator.dart b/lib/presentation/screens/dashboard/widgets/circle_indicator.dart index 6ff3613..e3a3ba5 100644 --- a/lib/presentation/screens/dashboard/widgets/circle_indicator.dart +++ b/lib/presentation/screens/dashboard/widgets/circle_indicator.dart @@ -189,7 +189,7 @@ class SpeedProgressIndicatorState extends ConsumerState<SpeedProgressIndicator> ), Text( - unit == DistanceUnit.kilometers ? 'Km/h' : 'Mph', + unit == DistanceUnit.kilometers ? 'km/h' : 'mph', style: const TextStyle(color: Colors.white, fontSize: 40), ), ], diff --git a/lib/presentation/screens/dashboard/widgets/range.dart b/lib/presentation/screens/dashboard/widgets/range.dart index aea92af..34435ae 100644 --- a/lib/presentation/screens/dashboard/widgets/range.dart +++ b/lib/presentation/screens/dashboard/widgets/range.dart @@ -10,8 +10,12 @@ class RangeWidget extends ConsumerWidget { final range = ref.watch(vehicleProvider.select((vehicle) => vehicle.range)); final unit = ref.watch(unitStateProvider.select((unit) => unit.distanceUnit)); + final rangeString = (unit == DistanceUnit.kilometers) + ? (range / 1000.0).toStringAsFixed(0) + : (range / 1609.0).toStringAsFixed(0); + return Container( - height:130, + height: 130, width: 306, // padding: const EdgeInsets.all(10), decoration: const ShapeDecoration( @@ -54,24 +58,19 @@ class RangeWidget extends ConsumerWidget { ), RichText( text: TextSpan( - - text: '$range', + text: rangeString, style: GoogleFonts.brunoAce( - - textStyle: - const TextStyle( + textStyle: const TextStyle( color: Colors.white, fontSize: 44, ), ), children: <TextSpan>[ TextSpan( - text: - unit == DistanceUnit.kilometers ? ' Km' : ' Mi', + text: unit == DistanceUnit.kilometers ? ' km' : ' mi', style: GoogleFonts.brunoAce( textStyle: const TextStyle( - color: Color(0xFFC1D8FF), - fontSize: 38), + color: Color(0xFFC1D8FF), fontSize: 38), ), ), ]), diff --git a/lib/presentation/screens/settings/settings_screens/units/distance/distance_unit_screen.dart b/lib/presentation/screens/settings/settings_screens/units/distance/distance_unit_screen.dart index 3e9c135..3d84604 100644 --- a/lib/presentation/screens/settings/settings_screens/units/distance/distance_unit_screen.dart +++ b/lib/presentation/screens/settings/settings_screens/units/distance/distance_unit_screen.dart @@ -11,7 +11,6 @@ class DistanceUnitPage extends ConsumerWidget { ref.watch(unitStateProvider.select((unit) => unit.distanceUnit)); return Scaffold( - body: Column( children: [ CommonTitle( @@ -48,13 +47,14 @@ class DistanceUnitPage extends ConsumerWidget { contentPadding: const EdgeInsets.symmetric( horizontal: 16.0, vertical: 40.0), leading: Text( - 'Kilometers', + 'kilometers', style: Theme.of(context).textTheme.titleMedium, ), //title: Text(widget.title), //enabled: isSwitchOn, trailing: unit == DistanceUnit.kilometers - ? const Icon(Icons.done, + ? const Icon( + Icons.done, color: AGLDemoColors.periwinkleColor, size: 48, ) @@ -90,13 +90,14 @@ class DistanceUnitPage extends ConsumerWidget { contentPadding: const EdgeInsets.symmetric( horizontal: 16.0, vertical: 40.0), leading: Text( - 'Miles', + 'miles', style: Theme.of(context).textTheme.titleMedium, ), //title: Text(widget.title), //enabled: isSwitchOn, trailing: unit == DistanceUnit.miles - ? const Icon(Icons.done, + ? const Icon( + Icons.done, color: AGLDemoColors.periwinkleColor, size: 48, ) diff --git a/lib/presentation/screens/settings/settings_screens/units/pressure/pressure_unit_screen.dart b/lib/presentation/screens/settings/settings_screens/units/pressure/pressure_unit_screen.dart new file mode 100644 index 0000000..5be8a05 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/units/pressure/pressure_unit_screen.dart @@ -0,0 +1,121 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +class PressureUnitPage extends ConsumerWidget { + const PressureUnitPage({super.key}); + + static Page<void> page() => + const MaterialPage<void>(child: PressureUnitPage()); + @override + Widget build(BuildContext context, WidgetRef ref) { + final unit = + ref.watch(unitStateProvider.select((unit) => unit.pressureUnit)); + + return Scaffold( + body: Column( + children: [ + CommonTitle( + title: 'Pressure', + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.units); + }, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 144), + child: ListView( + children: [ + Container( + height: 130, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: unit == PressureUnit.kilopascals + ? [0, 0.01, 0.8] + : [0.1, 1], + colors: unit == PressureUnit.kilopascals + ? <Color>[ + Colors.white, + Colors.blue, + const Color.fromARGB(16, 41, 98, 255) + ] + : <Color>[Colors.black, Colors.black12]), + ), + child: ListTile( + minVerticalPadding: 0.0, + contentPadding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 40.0), + leading: Text( + 'kilopascals', + style: Theme.of(context).textTheme.titleMedium, + ), + //title: Text(widget.title), + //enabled: isSwitchOn, + trailing: unit == PressureUnit.kilopascals + ? const Icon( + Icons.done, + color: AGLDemoColors.periwinkleColor, + size: 48, + ) + : null, + onTap: () { + ref + .read(unitStateProvider.notifier) + .setPressureUnit(PressureUnit.kilopascals); + }), + ), + const SizedBox( + height: 5, + ), + Container( + height: 130, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: unit == PressureUnit.psi + ? [0, 0.01, 0.8] + : [0.1, 1], + colors: unit == PressureUnit.psi + ? <Color>[ + Colors.white, + Colors.blue, + const Color.fromARGB(16, 41, 98, 255) + ] + : <Color>[Colors.black, Colors.black12]), + ), + child: ListTile( + minVerticalPadding: 0.0, + contentPadding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 40.0), + leading: Text( + 'PSI', + style: Theme.of(context).textTheme.titleMedium, + ), + //title: Text(widget.title), + //enabled: isSwitchOn, + trailing: unit == PressureUnit.psi + ? const Icon( + Icons.done, + color: AGLDemoColors.periwinkleColor, + size: 38, + ) + : null, + + onTap: () { + ref + .read(unitStateProvider.notifier) + .setPressureUnit(PressureUnit.psi); + }, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/units/units_screen.dart b/lib/presentation/screens/settings/settings_screens/units/units_screen.dart index 1c6e37c..fde7505 100644 --- a/lib/presentation/screens/settings/settings_screens/units/units_screen.dart +++ b/lib/presentation/screens/settings/settings_screens/units/units_screen.dart @@ -30,8 +30,8 @@ class UnitsPage extends ConsumerWidget { icon: Icons.calendar_month_outlined, title: 'Distance', unitName: unit.distanceUnit == DistanceUnit.kilometers - ? 'Kilometers' - : 'Miles', + ? 'kilometers' + : 'miles', hasSwich: false, voidCallback: () async { context @@ -50,6 +50,18 @@ class UnitsPage extends ConsumerWidget { .flow<AppState>() .update((next) => AppState.tempUnit); }), + UnitsTile( + icon: Icons.straighten, + title: 'Pressure', + unitName: unit.pressureUnit == PressureUnit.kilopascals + ? 'kilopascals' + : 'PSI', + hasSwich: true, + voidCallback: () { + context + .flow<AppState>() + .update((next) => AppState.pressureUnit); + }), ], ), ), |