diff --git a/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/1.json b/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/7.json
similarity index 93%
rename from android_app/app/schemas/com.health.openscale.core.database.AppDatabase/1.json
rename to android_app/app/schemas/com.health.openscale.core.database.AppDatabase/7.json
index df4097a3..7251c03d 100644
--- a/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/1.json
+++ b/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/7.json
@@ -1,12 +1,12 @@
{
"formatVersion": 1,
"database": {
- "version": 1,
- "identityHash": "e9e1b3a9fbc321cf52bf869c01f5be21",
+ "version": 7,
+ "identityHash": "d539026586245a45a135ae5bf3aaf73c",
"entities": [
{
"tableName": "User",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `birthDate` INTEGER NOT NULL, `gender` TEXT NOT NULL, `heightCm` REAL, `activityLevel` TEXT NOT NULL)",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `birthDate` INTEGER NOT NULL, `gender` TEXT NOT NULL, `heightCm` REAL NOT NULL, `activityLevel` TEXT NOT NULL, `scaleUnit` TEXT NOT NULL, `measureUnit` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
@@ -35,13 +35,26 @@
{
"fieldPath": "heightCm",
"columnName": "heightCm",
- "affinity": "REAL"
+ "affinity": "REAL",
+ "notNull": true
},
{
"fieldPath": "activityLevel",
"columnName": "activityLevel",
"affinity": "TEXT",
"notNull": true
+ },
+ {
+ "fieldPath": "scaleUnit",
+ "columnName": "scaleUnit",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "measureUnit",
+ "columnName": "measureUnit",
+ "affinity": "TEXT",
+ "notNull": true
}
],
"primaryKey": {
@@ -279,7 +292,7 @@
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
- "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e9e1b3a9fbc321cf52bf869c01f5be21')"
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd539026586245a45a135ae5bf3aaf73c')"
]
}
}
\ No newline at end of file
diff --git a/android_app/app/src/main/java/com/health/openscale/core/data/User.kt b/android_app/app/src/main/java/com/health/openscale/core/data/User.kt
index 83cfa587..382f6adb 100644
--- a/android_app/app/src/main/java/com/health/openscale/core/data/User.kt
+++ b/android_app/app/src/main/java/com/health/openscale/core/data/User.kt
@@ -26,6 +26,8 @@ data class User(
val name: String,
val birthDate: Long,
val gender: GenderType,
- val heightCm: Float? = null,
- val activityLevel: ActivityLevel
+ val heightCm: Float,
+ val activityLevel: ActivityLevel,
+ var scaleUnit: WeightUnit,
+ var measureUnit: MeasureUnit
)
\ No newline at end of file
diff --git a/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.kt b/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.kt
index ce3cee7b..c1f6d250 100644
--- a/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.kt
+++ b/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.kt
@@ -39,7 +39,7 @@ import com.health.openscale.core.utils.LogManager
MeasurementValue::class,
MeasurementType::class
],
- version = 1,
+ version = 7,
exportSchema = true
)
@TypeConverters(DatabaseConverters::class)
diff --git a/android_app/app/src/main/java/com/health/openscale/ui/screen/settings/UserDetailScreen.kt b/android_app/app/src/main/java/com/health/openscale/ui/screen/settings/UserDetailScreen.kt
index 4e084ca7..8cd3bb6e 100644
--- a/android_app/app/src/main/java/com/health/openscale/ui/screen/settings/UserDetailScreen.kt
+++ b/android_app/app/src/main/java/com/health/openscale/ui/screen/settings/UserDetailScreen.kt
@@ -22,6 +22,7 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.add
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
@@ -59,10 +60,13 @@ import androidx.navigation.NavController
import com.health.openscale.R
import com.health.openscale.core.data.ActivityLevel
import com.health.openscale.core.data.GenderType
+import com.health.openscale.core.data.MeasureUnit
import com.health.openscale.core.data.User
+import com.health.openscale.core.data.WeightUnit
import com.health.openscale.ui.screen.SharedViewModel
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
+import java.util.Calendar
import java.util.Date
import java.util.Locale
@@ -94,17 +98,29 @@ fun UserDetailScreen(
}
var name by remember { mutableStateOf(user?.name.orEmpty()) }
- var birthDate by remember { mutableStateOf(user?.birthDate ?: System.currentTimeMillis()) }
+ var birthDate by remember {
+ val initialBirthDate = user?.birthDate
+ if (initialBirthDate != null) {
+ mutableStateOf(initialBirthDate)
+ } else {
+ val calendar = Calendar.getInstance()
+ calendar.add(Calendar.YEAR, -18)
+ mutableStateOf(calendar.timeInMillis)
+ }
+ }
var gender by remember { mutableStateOf(user?.gender ?: GenderType.MALE) }
var height by remember { mutableStateOf(user?.heightCm?.toString().orEmpty()) }
var activityLevel by remember { mutableStateOf(user?.activityLevel ?: ActivityLevel.SEDENTARY) }
+ var scaleUnit by remember { mutableStateOf(user?.scaleUnit ?: WeightUnit.KG) }
+ var measureUnit by remember { mutableStateOf(user?.measureUnit ?: MeasureUnit.CM) }
val context = LocalContext.current
- // Date formatter for displaying the birth date. Consider device locale.
val dateFormatter = remember { SimpleDateFormat("dd.MM.yyyy", Locale.getDefault()) }
val datePickerState = rememberDatePickerState(initialSelectedDateMillis = birthDate)
var showDatePicker by remember { mutableStateOf(false) }
var activityLevelExpanded by remember { mutableStateOf(false) }
+ var scaleUnitExpanded by remember { mutableStateOf(false) }
+ var measureUnitExpanded by remember { mutableStateOf(false) }
if (showDatePicker) {
DatePickerDialog(
@@ -149,7 +165,9 @@ fun UserDetailScreen(
birthDate = birthDate,
gender = gender,
heightCm = validHeight,
- activityLevel = activityLevel
+ activityLevel = activityLevel,
+ scaleUnit = scaleUnit,
+ measureUnit = measureUnit
)
settingsViewModel.viewModelScope.launch {
if (isEdit) {
@@ -216,7 +234,6 @@ fun UserDetailScreen(
}
}
- Text(stringResource(id = R.string.user_detail_label_activity_level)) // "Activity Level"
ExposedDropdownMenuBox(
expanded = activityLevelExpanded,
onExpandedChange = { activityLevelExpanded = !activityLevelExpanded },
@@ -226,7 +243,7 @@ fun UserDetailScreen(
value = activityLevel.name.lowercase().replaceFirstChar { it.uppercaseChar().toString() },
onValueChange = {}, // Input is read-only, selection via dropdown
readOnly = true,
- label = { Text(stringResource(id = R.string.user_detail_label_select_level)) }, // "Select Level"
+ label = { Text(stringResource(id = R.string.user_detail_label_activity_level)) },
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = activityLevelExpanded)
},
@@ -252,6 +269,74 @@ fun UserDetailScreen(
}
}
+ ExposedDropdownMenuBox(
+ expanded = scaleUnitExpanded,
+ onExpandedChange = { scaleUnitExpanded = !scaleUnitExpanded },
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ OutlinedTextField(
+ value = scaleUnit.toString(),
+ onValueChange = {},
+ readOnly = true,
+ label = { Text(stringResource(id = R.string.user_detail_label_scale_unit)) },
+ trailingIcon = {
+ ExposedDropdownMenuDefaults.TrailingIcon(expanded = scaleUnitExpanded)
+ },
+ modifier = Modifier
+ .menuAnchor(type = MenuAnchorType.PrimaryNotEditable)
+ .fillMaxWidth()
+ )
+ ExposedDropdownMenu(
+ expanded = scaleUnitExpanded,
+ onDismissRequest = { scaleUnitExpanded = false }
+ ) {
+ WeightUnit.entries.forEach { selectionOption ->
+ DropdownMenuItem(
+ text = { Text(selectionOption.toString()) },
+ onClick = {
+ scaleUnit = selectionOption
+ scaleUnitExpanded = false
+ },
+ contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
+ )
+ }
+ }
+ }
+
+ ExposedDropdownMenuBox(
+ expanded = measureUnitExpanded,
+ onExpandedChange = { measureUnitExpanded = !measureUnitExpanded },
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ OutlinedTextField(
+ value = measureUnit.toString(),
+ onValueChange = {},
+ readOnly = true,
+ label = { Text(stringResource(id = R.string.user_detail_label_measure_unit)) },
+ trailingIcon = {
+ ExposedDropdownMenuDefaults.TrailingIcon(expanded = measureUnitExpanded)
+ },
+ modifier = Modifier
+ .menuAnchor(type = MenuAnchorType.PrimaryNotEditable)
+ .fillMaxWidth()
+ )
+ ExposedDropdownMenu(
+ expanded = measureUnitExpanded,
+ onDismissRequest = { measureUnitExpanded = false }
+ ) {
+ MeasureUnit.entries.forEach { selectionOption ->
+ DropdownMenuItem(
+ text = { Text(selectionOption.toString()) },
+ onClick = {
+ measureUnit = selectionOption
+ measureUnitExpanded = false
+ },
+ contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
+ )
+ }
+ }
+ }
+
Text(stringResource(id = R.string.user_detail_label_birth_date)) // "Birth Date"
OutlinedTextField(
value = dateFormatter.format(Date(birthDate)),
diff --git a/android_app/app/src/main/res/values-de/strings.xml b/android_app/app/src/main/res/values-de/strings.xml
index 40eaae12..55c549e9 100644
--- a/android_app/app/src/main/res/values-de/strings.xml
+++ b/android_app/app/src/main/res/values-de/strings.xml
@@ -51,9 +51,10 @@
Größe (cm)
Geschlecht
Aktivitätslevel
- Level auswählen
Geburtsdatum
Bitte geben Sie gültige Daten ein
+ Gewichtseinheit
+ Größeneinheit
%.1f cm
Alter: %1$d, Größe: %2$s
Benutzer bearbeiten
diff --git a/android_app/app/src/main/res/values/strings.xml b/android_app/app/src/main/res/values/strings.xml
index 43d36626..6d036b98 100644
--- a/android_app/app/src/main/res/values/strings.xml
+++ b/android_app/app/src/main/res/values/strings.xml
@@ -52,9 +52,10 @@
Height (cm)
Gender
Activity Level
- Select Level
Birth Date
Please enter valid data
+ Scale Unit
+ Measure Unit
%.1f cm
Age: %1$d, Height: %2$s
Edit user