aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/core/constants/users_path.dart6
-rw-r--r--lib/data/data_providers/app.dart6
-rw-r--r--lib/data/data_providers/initialize_settings.dart12
-rw-r--r--lib/data/data_providers/units_notifier.dart83
-rw-r--r--lib/data/data_providers/users_notifier.dart128
-rw-r--r--lib/data/models/users.dart2
-rw-r--r--lib/export.dart1
-rw-r--r--lib/main.dart27
8 files changed, 241 insertions, 24 deletions
diff --git a/lib/core/constants/users_path.dart b/lib/core/constants/users_path.dart
new file mode 100644
index 0000000..47c2486
--- /dev/null
+++ b/lib/core/constants/users_path.dart
@@ -0,0 +1,6 @@
+class UsersPath {
+ static const String InfotainmentCurrentUser =
+ 'Infotainment.Users.selectedUser';
+ static const String InfotainmentUsers =
+ 'Infotainment.Users';
+}
diff --git a/lib/data/data_providers/app.dart b/lib/data/data_providers/app.dart
index 3368a83..05e56f0 100644
--- a/lib/data/data_providers/app.dart
+++ b/lib/data/data_providers/app.dart
@@ -12,13 +12,11 @@ class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return ProviderScope(
- child: MaterialApp(
+ return MaterialApp(
debugShowCheckedModeBanner: false,
theme: theme,
home: const AppView(),
- ),
- );
+ );
}
}
diff --git a/lib/data/data_providers/initialize_settings.dart b/lib/data/data_providers/initialize_settings.dart
new file mode 100644
index 0000000..b5a5e80
--- /dev/null
+++ b/lib/data/data_providers/initialize_settings.dart
@@ -0,0 +1,12 @@
+import 'package:flutter_ics_homescreen/export.dart';
+
+Future<void> initializeSettings(ProviderContainer container) async {
+ await container.read(usersProvider.notifier).loadSettingsUsers();
+ await container.read(unitStateProvider.notifier).loadSettingsUnits();
+ // Initialize other settings or providers if needed.
+}
+
+Future<void> initializeSettingsUser(Ref ref) async {
+ await ref.read(unitStateProvider.notifier).loadSettingsUnits();
+ // Initialize other settings or providers if needed.
+}
diff --git a/lib/data/data_providers/units_notifier.dart b/lib/data/data_providers/units_notifier.dart
index 68c9e65..daf9c92 100644
--- a/lib/data/data_providers/units_notifier.dart
+++ b/lib/data/data_providers/units_notifier.dart
@@ -1,12 +1,53 @@
import 'package:flutter_ics_homescreen/export.dart';
import 'package:protos/val_api.dart';
+import 'package:protos/storage-api.dart' as storage_api;
+import 'initialize_settings.dart';
+
class UnitsNotifier extends Notifier<Units> {
@override
Units build() {
return const Units.initial();
}
+ // Load Units state of the selected user from the storage API.
+ Future <void> loadSettingsUnits() async {
+ final storageClient = ref.read(storageClientProvider);
+ final userClient = ref.read(usersProvider);
+
+ try {
+ await initializeSettingsUser(ref);
+ } catch (e) {
+ print('Error loading settings of user: $e');
+ }
+
+ try {
+ // Read unit values from the selected user namespace.
+ final distanceResponse = await storageClient.read(storage_api.Key(key: VSSPath.vehicleHmiDistanceUnit, namespace: userClient.selectedUser.id));
+ final temperatureResponse = await storageClient.read(storage_api.Key(key: VSSPath.vehicleHmiTemperatureUnit, namespace: userClient.selectedUser.id));
+ final pressureResponse = await storageClient.read(storage_api.Key(key: VSSPath.vehicleHmiPressureUnit, namespace: userClient.selectedUser.id));
+
+ // Prepare state declaration and fall back to default values if the key is not present in the storage API.
+ final distanceUnit = distanceResponse.result == 'MILES'
+ ? DistanceUnit.miles
+ : DistanceUnit.kilometers;
+
+ final temperatureUnit = temperatureResponse.result == 'F'
+ ? TemperatureUnit.fahrenheit
+ : TemperatureUnit.celsius;
+
+ final pressureUnit = pressureResponse.result == 'PSI'
+ ? PressureUnit.psi
+ : PressureUnit.kilopascals;
+
+ state = Units(distanceUnit, temperatureUnit, pressureUnit);
+ } catch (e) {
+ // Fallback to initial defaults if error occurs.
+ print('Error loading settings for units: $e');
+ state = const Units.initial();
+ }
+ }
+
bool handleSignalUpdate(DataEntry entry) {
bool handled = true;
switch (entry.path) {
@@ -40,7 +81,7 @@ class UnitsNotifier extends Notifier<Units> {
return handled;
}
- void setDistanceUnit(DistanceUnit unit) {
+ Future <void> setDistanceUnit(DistanceUnit unit) async {
state = state.copyWith(distanceUnit: unit);
var valClient = ref.read(valClientProvider);
valClient.setString(
@@ -48,9 +89,21 @@ class UnitsNotifier extends Notifier<Units> {
unit == DistanceUnit.kilometers ? "KILOMETERS" : "MILES",
true,
);
+ // Write to storage API (to selected user namespace).
+ var storageClient = ref.read(storageClientProvider);
+ final userClient = ref.read(usersProvider);
+ try {
+ await storageClient.write(storage_api.KeyValue(
+ key: VSSPath.vehicleHmiDistanceUnit,
+ value: unit == DistanceUnit.kilometers ? 'KILOMETERS' : 'MILES',
+ namespace: userClient.selectedUser.id
+ ));
+ } catch (e) {
+ print('Error saving distance unit: $e');
+ }
}
- void setTemperatureUnit(TemperatureUnit unit) {
+ Future <void> setTemperatureUnit(TemperatureUnit unit) async {
state = state.copyWith(temperatureUnit: unit);
var valClient = ref.read(valClientProvider);
valClient.setString(
@@ -58,9 +111,21 @@ class UnitsNotifier extends Notifier<Units> {
unit == TemperatureUnit.celsius ? "C" : "F",
true,
);
+ // Write to storage API (to selected user namespace).
+ var storageClient = ref.read(storageClientProvider);
+ final userClient = ref.read(usersProvider);
+ try {
+ await storageClient.write(storage_api.KeyValue(
+ key: VSSPath.vehicleHmiTemperatureUnit,
+ value: unit == TemperatureUnit.celsius ? "C" : "F",
+ namespace: userClient.selectedUser.id
+ ));
+ } catch (e) {
+ print('Error saving distance unit: $e');
+ }
}
- void setPressureUnit(PressureUnit unit) {
+ Future <void> setPressureUnit(PressureUnit unit) async {
state = state.copyWith(pressureUnit: unit);
var valClient = ref.read(valClientProvider);
valClient.setString(
@@ -68,5 +133,17 @@ class UnitsNotifier extends Notifier<Units> {
unit == PressureUnit.kilopascals ? "KPA" : "PSI",
true,
);
+ // Write to storage API (to selected user namespace).
+ var storageClient = ref.read(storageClientProvider);
+ final userClient = ref.read(usersProvider);
+ try {
+ await storageClient.write(storage_api.KeyValue(
+ key: VSSPath.vehicleHmiPressureUnit,
+ value: unit == PressureUnit.kilopascals ? "KPA" : "PSI",
+ namespace: userClient.selectedUser.id
+ ));
+ } catch (e) {
+ print('Error saving distance unit: $e');
+ }
}
}
diff --git a/lib/data/data_providers/users_notifier.dart b/lib/data/data_providers/users_notifier.dart
index 8b48382..c2755f6 100644
--- a/lib/data/data_providers/users_notifier.dart
+++ b/lib/data/data_providers/users_notifier.dart
@@ -4,9 +4,65 @@ import 'package:uuid/uuid.dart';
import '../models/user.dart';
-class UsersNotifier extends StateNotifier<Users> {
- UsersNotifier(super.state) {
+import 'package:protos/storage-api.dart' as storage_api;
+import 'initialize_settings.dart';
+
+class UsersNotifier extends Notifier<Users> {
+ @override
+ Users build() {
+ // Initialize default state.
+ state = Users.initial();
loadUsers();
+ return state;
+ }
+
+ Future <void> loadSettingsUsers() async {
+ final storageClient = ref.read(storageClientProvider);
+ try {
+ // Access users branch.
+ final searchResponseUsers = await storageClient.search(storage_api.Key(key: UsersPath.InfotainmentUsers));
+ // Add default users if no users are inside the storage API.
+ if (searchResponseUsers.result.isEmpty) {
+ loadUsers();
+ await storageClient.write(storage_api.KeyValue(key: '${UsersPath.InfotainmentUsers}.${_users[0].id}.id', value: _users[0].id));
+ await storageClient.write(storage_api.KeyValue(key: '${UsersPath.InfotainmentUsers}.${_users[0].id}.name', value: _users[0].name));
+ await storageClient.write(storage_api.KeyValue(key: '${UsersPath.InfotainmentUsers}.${_users[1].id}.id', value: _users[1].id));
+ await storageClient.write(storage_api.KeyValue(key: '${UsersPath.InfotainmentUsers}.${_users[1].id}.name', value: _users[1].name));
+ await storageClient.write(storage_api.KeyValue(key: '${UsersPath.InfotainmentUsers}.${_users[2].id}.id', value: _users[2].id));
+ await storageClient.write(storage_api.KeyValue(key: '${UsersPath.InfotainmentUsers}.${_users[2].id}.name', value: _users[2].name));
+ await selectUser(_users[0].id);
+ }
+ else {
+ List<User> users = [];
+ List<String> idList = [];
+ // Get list of all ids.
+ for (var key in searchResponseUsers.result) {
+ var readResponse = await storageClient.read(storage_api.Key(key: key));
+ if (key.contains('.id')) {
+ idList.insert(0, readResponse.result);
+ }
+ }
+ // Extract names corresponding to ids.
+ for (var id in idList) {
+ var readResponse = await storageClient.read(storage_api.Key(key:'${UsersPath.InfotainmentUsers}.$id.name'));
+ users.insert(0, User(id: id, name: readResponse.result));
+ }
+ // Extract id of selected user.
+ final readResponseSelectedUser = await storageClient.read(storage_api.Key(key: UsersPath.InfotainmentCurrentUser));
+ User selectedUser;
+ final userCurrentId = readResponseSelectedUser.result;
+ // Extract name of selected user.
+ final readResponseCurrentUserName = await storageClient.read(storage_api.Key(key: '${UsersPath.InfotainmentUsers}.$userCurrentId.name'));
+ final userCurrentName = readResponseCurrentUserName.result;
+ selectedUser = User(id: userCurrentId, name: userCurrentName);
+ state = Users(users: users, selectedUser: selectedUser);
+ }
+ } catch (e) {
+ // Fallback to initial defaults if error.
+ print('Error loading settings for units: $e');
+ loadUsers();
+ state = state.copyWith(selectedUser: _users[0]);
+ }
}
void loadUsers() {
@@ -18,27 +74,81 @@ class UsersNotifier extends StateNotifier<Users> {
const User(id: '2', name: 'George'),
const User(id: '3', name: 'Riley'),
];
- void selectUser(String userId) {
+
+ Future <void> selectUser(String userId) async {
+ final storageClient = ref.read(storageClientProvider);
var seletedUser = state.users.firstWhere((user) => user.id == userId);
state = state.copyWith(selectedUser: seletedUser);
+ // Write to storage API.
+ try {
+ await storageClient.write(storage_api.KeyValue(
+ key: UsersPath.InfotainmentCurrentUser,
+ value: userId,
+ ));
+ } catch (e) {
+ print('Error saving user: $e');
+ }
+
+ try {
+ await initializeSettingsUser(ref);
+ } catch (e) {
+ print('Error loading settings of user: $e');
+ }
+
}
- void removeUser(String userId) {
+ Future <void> removeUser(String userId) async {
+ final storageClient = ref.read(storageClientProvider);
+ var currentUserId = state.selectedUser.id;
state.users.removeWhere((user) => user.id == userId);
- if (state.users.isNotEmpty) {
+
+ if (state.users.isNotEmpty && currentUserId == userId) {
state = state.copyWith(selectedUser: state.users.first);
+ //Write to API to change selected user.
+ await storageClient.write(storage_api.KeyValue(key: UsersPath.InfotainmentCurrentUser, value: state.users.first.id));
}
if (state.users.isEmpty) {
- state = state.copyWith(selectedUser: const User(id: '', name: ''));
+ state = state.copyWith(selectedUser: const User(id: '0', name: ''));
+ //Write to API to change selected user.
+ await storageClient.write(storage_api.KeyValue(key: UsersPath.InfotainmentCurrentUser, value: '0'));
+ }
+ // Delete from storage API.
+ try {
+ final searchResponse = await storageClient.search(storage_api.Key(key: userId));
+ final keyList = searchResponse.result;
+ //Delete id, name entries of the user from the default namespace.
+ for (final key in keyList) {
+ await storageClient.delete(storage_api.Key(
+ key: key
+ ));
+ }
+ //Delete all VSS keys from the user namespace.
+ await storageClient.deleteNodes(storage_api.Key(key: "Vehicle", namespace: userId));
+ } catch (e) {
+ print('Error removing user with id $userId: $e');
}
}
- void addUser(String userName) {
+ Future <void> addUser(String userName) async {
+ final storageClient = ref.read(storageClientProvider);
final id = const Uuid().v1();
final user = User(id: id, name: userName);
-
state.users.insert(0, user);
- state = state.copyWith(selectedUser: state.users.first);
+ // New user is automaticaly selected.
+ await selectUser(user.id);
+ // Write to storage API.
+ try {
+ await storageClient.write(storage_api.KeyValue(
+ key: '${UsersPath.InfotainmentUsers}.$id.name',
+ value: userName
+ ));
+ await storageClient.write(storage_api.KeyValue(
+ key: '${UsersPath.InfotainmentUsers}.$id.id',
+ value: id
+ ));
+ } catch (e) {
+ print('Error adding user with id $id: $e');
+ }
}
void editUser(User user) {
diff --git a/lib/data/models/users.dart b/lib/data/models/users.dart
index 9b4d027..0bb4070 100644
--- a/lib/data/models/users.dart
+++ b/lib/data/models/users.dart
@@ -16,7 +16,7 @@ class Users {
Users.initial()
//: users = <User>[],
: users = [],
- selectedUser = const User(id: '', name: '');
+ selectedUser = const User(id: '0', name: '');
Users copyWith({
List<User>? users,
diff --git a/lib/export.dart b/lib/export.dart
index 90ed196..be4026f 100644
--- a/lib/export.dart
+++ b/lib/export.dart
@@ -60,6 +60,7 @@ export 'presentation/screens/clock/clock.dart';
export 'core/utils/widgets/back_button.dart';
export 'core/constants/vss_path.dart';
+export 'core/constants/users_path.dart';
export 'core/constants/constants.dart';
//Common widgets
export 'presentation/common_widget/settings_top_bar.dart';
diff --git a/lib/main.dart b/lib/main.dart
index c7d84ee..0699f06 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,14 +1,27 @@
import 'package:device_preview/device_preview.dart';
import 'export.dart';
+import 'data/data_providers/initialize_settings.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
- runApp(DevicePreview(
- enabled: debugDisplay,
- tools: const [
- ...DevicePreview.defaultTools,
- ],
- builder: (context) => const App(),
- ));
+
+ // Initialize settings from storage API.
+ final container = ProviderContainer();
+ await initializeSettings(container);
+
+ // Pass the container to ProviderScope and then run the app.
+ runApp(
+ ProviderScope(
+ parent: container,
+ child: DevicePreview(
+ enabled: debugDisplay,
+ tools: const [
+ ...DevicePreview.defaultTools,
+ ],
+ builder: (context) => const App(),
+ ),
+ ),
+ );
}
+