Compare commits
10 Commits
5ea0a4a921
...
84c40317a5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84c40317a5 | ||
|
|
cd1ce2ccda | ||
|
|
a7c92b020b | ||
|
|
c20d5d55e5 | ||
|
|
49eabce142 | ||
|
|
6e0eb1c8f4 | ||
|
|
0f99fb589c | ||
|
|
8ca5db7c52 | ||
|
|
3b2e09c134 | ||
|
|
ebbee65330 |
17
.idea/deploymentTargetDropDown.xml
generated
Normal file
17
.idea/deploymentTargetDropDown.xml
generated
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetDropDown">
|
||||
<targetSelectedWithDropDown>
|
||||
<Target>
|
||||
<type value="QUICK_BOOT_TARGET" />
|
||||
<deviceKey>
|
||||
<Key>
|
||||
<type value="VIRTUAL_DEVICE_PATH" />
|
||||
<value value="C:\Android\.android\avd\Pixel_3a_API_30_x86.avd" />
|
||||
</Key>
|
||||
</deviceKey>
|
||||
</Target>
|
||||
</targetSelectedWithDropDown>
|
||||
<timeTargetWasSelectedWithDropDown value="2022-11-16T20:26:11.531085900Z" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -11,12 +11,12 @@ android {
|
||||
release {
|
||||
}
|
||||
}
|
||||
compileSdk 32
|
||||
compileSdk 33
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.sockenklaus.batterytracker"
|
||||
minSdk 29
|
||||
targetSdk 32
|
||||
targetSdk 33
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -41,6 +41,8 @@ android {
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
applicationIdSuffix '.release'
|
||||
versionNameSuffix 'release'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
@@ -63,50 +65,46 @@ android {
|
||||
excludes += '/META-INF/{AL2.0,LGPL2.1}'
|
||||
}
|
||||
}
|
||||
namespace 'com.sockenklaus.batterytracker'
|
||||
flavorDimensions
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.room:room-runtime:2.4.2'
|
||||
implementation 'androidx.room:room-rxjava3:2.4.2'
|
||||
implementation "androidx.room:room-paging:2.4.2"
|
||||
implementation "androidx.room:room-ktx:2.4.2"
|
||||
kapt 'androidx.room:room-compiler:2.4.2'
|
||||
implementation 'androidx.room:room-runtime:2.4.3'
|
||||
implementation 'androidx.room:room-rxjava3:2.4.3'
|
||||
implementation "androidx.room:room-paging:2.4.3"
|
||||
implementation "androidx.room:room-ktx:2.4.3"
|
||||
kapt 'androidx.room:room-compiler:2.4.3'
|
||||
|
||||
implementation "androidx.compose.ui:ui:1.3.0-alpha01"
|
||||
implementation "androidx.compose.ui:ui-tooling-preview:1.3.0-alpha01"
|
||||
implementation 'androidx.compose.material:material-icons-extended:1.3.0-alpha01'
|
||||
implementation 'androidx.compose.material:material:1.3.0-alpha01'
|
||||
implementation 'androidx.compose.runtime:runtime-livedata:1.1.1'
|
||||
implementation 'androidx.compose.animation:animation:1.3.0-alpha01'
|
||||
implementation 'androidx.compose.ui:ui-tooling:1.3.0-alpha01'
|
||||
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.3.0-alpha01'
|
||||
debugImplementation "androidx.compose.ui:ui-test-manifest:1.1.1"
|
||||
implementation "androidx.compose.ui:ui:1.4.0-alpha02"
|
||||
implementation "androidx.compose.ui:ui-tooling-preview:1.4.0-alpha02"
|
||||
implementation 'androidx.compose.material:material-icons-extended:1.4.0-alpha02'
|
||||
implementation 'androidx.compose.material:material:1.4.0-alpha02'
|
||||
implementation 'androidx.compose.runtime:runtime-livedata:1.3.1'
|
||||
implementation 'androidx.compose.animation:animation:1.4.0-alpha02'
|
||||
implementation 'androidx.compose.ui:ui-tooling:1.4.0-alpha02'
|
||||
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.4.0-alpha02'
|
||||
debugImplementation "androidx.compose.ui:ui-test-manifest:1.3.1"
|
||||
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1'
|
||||
|
||||
|
||||
|
||||
implementation 'com.google.android.material:material:1.7.0-alpha03'
|
||||
implementation 'com.google.android.material:compose-theme-adapter:1.1.14'
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.8.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.2'
|
||||
implementation 'androidx.core:core-ktx:1.9.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
|
||||
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.0'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.5.0'
|
||||
implementation "androidx.navigation:navigation-compose:2.5.0"
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'
|
||||
implementation "androidx.navigation:navigation-compose:2.5.3"
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
|
||||
implementation 'androidx.activity:activity-compose:1.5.0'
|
||||
implementation 'androidx.activity:activity-compose:1.6.1'
|
||||
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.sockenklaus.batterytracker">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
||||
@@ -16,10 +16,10 @@ interface BatteryDao {
|
||||
@Update
|
||||
fun updateBattery(battery: Battery): Int
|
||||
|
||||
@Query("Select * FROM batteries ORDER BY name ASC")
|
||||
@Query("Select * FROM batteries ORDER BY name COLLATE NOCASE ASC")
|
||||
fun getBatteries(): Flow<List<Battery>>
|
||||
|
||||
@Query("Select * FROM batteries WHERE id = :id")
|
||||
@Query("SELECT * FROM batteries WHERE id = :id")
|
||||
fun getBatteryById(id: Int): Flow<Battery>
|
||||
|
||||
@Transaction
|
||||
|
||||
@@ -25,4 +25,7 @@ interface ChargeDao {
|
||||
@Transaction
|
||||
@Query("SELECT * FROM batteries WHERE id = :id")
|
||||
fun getBatteryAndCharges(id: Int): Flow<BatteryAndCharges>
|
||||
|
||||
@Query("SELECT * FROM charges WHERE battery_id = :id ORDER BY created_at DESC")
|
||||
fun getChargesByBatteryId(id: Int): Flow<List<Charge>>
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.sockenklaus.batterytracker.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.wrapContentWidth
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
@@ -24,36 +24,44 @@ import com.sockenklaus.batterytracker.ui.models.MainViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object Routes {
|
||||
const val HOME = "home"
|
||||
const val ADD_BATTERY = "add_battery"
|
||||
const val ADD_CHARGE = "add_charge"
|
||||
const val BATTERY_DETAILS = "battery_details"
|
||||
const val HOME = "Home"
|
||||
const val ADD_BATTERY = "Add Battery"
|
||||
const val ADD_CHARGE = "Add Charge"
|
||||
const val BATTERY_DETAILS = "Battery Details"
|
||||
}
|
||||
|
||||
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun BatteryTracker() {
|
||||
MaterialTheme {
|
||||
val state: MainViewModel = viewModel()
|
||||
state.init()
|
||||
|
||||
/**
|
||||
* TODO Is there a smarter way to work with Scaffold? Is it possible to change the
|
||||
* components of the Scaffold from within the composables?
|
||||
*/
|
||||
Scaffold(
|
||||
scaffoldState = state.scaffoldState,
|
||||
|
||||
topBar = {
|
||||
when(state.currentScreen){
|
||||
when {
|
||||
state.currentScreen.startsWith(Routes.BATTERY_DETAILS) -> {
|
||||
|
||||
Routes.BATTERY_DETAILS -> DetailsTopAppBar(
|
||||
DetailsTopAppBar(
|
||||
navController = state.navController,
|
||||
changeCurrentScreen = { state.currentScreen = it }
|
||||
drawerState = state.scaffoldState.drawerState,
|
||||
appTitle = state.currentScreen
|
||||
)
|
||||
}
|
||||
|
||||
else -> MainTopAppBar(
|
||||
drawerState = state.scaffoldState.drawerState,
|
||||
appTitle = state.appTitle
|
||||
appTitle = state.currentScreen,
|
||||
)
|
||||
}
|
||||
}
|
||||
) { innerPadding ->
|
||||
) {
|
||||
ModalDrawer(
|
||||
drawerState = state.scaffoldState.drawerState,
|
||||
drawerContent = {
|
||||
@@ -63,38 +71,48 @@ fun BatteryTracker() {
|
||||
route = Routes.HOME,
|
||||
state = state,
|
||||
)
|
||||
|
||||
NavListItem(
|
||||
icon = Icons.Default.BatteryChargingFull,
|
||||
textId = R.string.nav_add_charge,
|
||||
route = Routes.ADD_CHARGE,
|
||||
state = state,
|
||||
)
|
||||
|
||||
NavListItem(
|
||||
icon = Icons.Default.BatteryFull,
|
||||
textId = R.string.nav_add_battery,
|
||||
route = Routes.ADD_BATTERY,
|
||||
state = state,
|
||||
)
|
||||
}
|
||||
) {
|
||||
NavHost(
|
||||
navController = state.navController,
|
||||
startDestination = Routes.HOME,
|
||||
modifier = Modifier.padding(innerPadding))
|
||||
)
|
||||
{
|
||||
composable(Routes.HOME) { Home(state.navController, state) }
|
||||
composable(Routes.ADD_CHARGE) { AddCharge(state.navController) }
|
||||
composable(Routes.ADD_BATTERY) { AddBattery(state.navController) }
|
||||
composable(Routes.HOME) {
|
||||
state.currentScreen = Routes.HOME
|
||||
Home(state.navController)
|
||||
}
|
||||
composable(
|
||||
route = Routes.ADD_CHARGE
|
||||
){
|
||||
AddCharge(
|
||||
navController = state.navController
|
||||
)
|
||||
}
|
||||
composable(
|
||||
route = "${Routes.ADD_CHARGE}/{batteryId}",
|
||||
arguments = listOf(navArgument("batteryId"){ type = NavType.IntType })
|
||||
) {
|
||||
val id = it.arguments?.getInt("batteryId")
|
||||
state.currentScreen = "${Routes.ADD_CHARGE} for Battery ${state.getBatteryName(id = id)}"
|
||||
AddCharge(
|
||||
batteryId = id,
|
||||
navController = state.navController
|
||||
)
|
||||
}
|
||||
composable(Routes.ADD_BATTERY) {
|
||||
state.currentScreen = Routes.ADD_BATTERY
|
||||
AddBattery(state.navController)
|
||||
}
|
||||
composable(
|
||||
route = "${Routes.BATTERY_DETAILS}/{batteryId}",
|
||||
arguments = listOf(navArgument("batteryId"){ type = NavType.IntType })
|
||||
) { navBackStackEntry ->
|
||||
val id = navBackStackEntry.arguments?.getInt("batteryId")
|
||||
state.currentScreen = Routes.BATTERY_DETAILS + ": " + state.getBatteryName(id = id)
|
||||
BatteryDetails(
|
||||
navController = state.navController,
|
||||
batteryId = navBackStackEntry.arguments?.getInt("batteryId"),
|
||||
appState = state
|
||||
batteryId = id ,
|
||||
navController = state.navController
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -162,9 +180,7 @@ fun NavListItem(
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
scope.launch {
|
||||
state.appTitle = text
|
||||
state.navController.navigate(route)
|
||||
state.currentScreen = route
|
||||
state.scaffoldState.drawerState.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.sockenklaus.batterytracker.ui.composables
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
@@ -10,11 +11,14 @@ import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import com.sockenklaus.batterytracker.R
|
||||
import com.sockenklaus.batterytracker.ui.Routes
|
||||
import com.sockenklaus.batterytracker.ui.composables.util.MyOutlinedTextFieldWithSuffix
|
||||
import com.sockenklaus.batterytracker.ui.models.AddBatteryViewModel
|
||||
import com.sockenklaus.batterytracker.util.validateDecimal
|
||||
@@ -24,13 +28,18 @@ fun AddBattery(navController: NavController){
|
||||
val model: AddBatteryViewModel = viewModel()
|
||||
val batteries by model.batteries.observeAsState(emptyList())
|
||||
|
||||
val outerPadding = 24.dp
|
||||
val outerPadding = 16.dp
|
||||
val innerPadding = 16.dp
|
||||
|
||||
Column(
|
||||
Modifier.padding(outerPadding)
|
||||
) {
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
){
|
||||
|
||||
MyOutlinedTextFieldWithSuffix(
|
||||
value = model.batteryName,
|
||||
onValueChange = { value ->
|
||||
@@ -42,11 +51,32 @@ fun AddBattery(navController: NavController){
|
||||
model.batteryHelperId = R.string.helper_battery_not_unique
|
||||
}
|
||||
},
|
||||
singleLine = true,
|
||||
labelId = R.string.hint_enter_battery_name,
|
||||
leadingIcon = { Icon(Icons.Default.Tag, "Icon Tag") },
|
||||
isError = model.batteryHasError,
|
||||
helperTextId = model.batteryHelperId
|
||||
helperTextId = model.batteryHelperId,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
capitalization = if(model.switchAutoCap) KeyboardCapitalization.Characters else KeyboardCapitalization.None,
|
||||
autoCorrect = false,
|
||||
keyboardType = KeyboardType.Ascii,
|
||||
imeAction = ImeAction.Next
|
||||
)
|
||||
)
|
||||
|
||||
Column() {
|
||||
Switch(
|
||||
checked = model.switchAutoCap,
|
||||
onCheckedChange = { model.switchAutoCap = !model.switchAutoCap }
|
||||
)
|
||||
Text(
|
||||
text = "Auto-Cap.",
|
||||
style = MaterialTheme.typography.caption
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Spacer(Modifier.size(innerPadding))
|
||||
|
||||
@@ -56,24 +86,38 @@ fun AddBattery(navController: NavController){
|
||||
model.declaredCapacity = validateDecimal(it, model.declaredCapacity)
|
||||
},
|
||||
labelId = R.string.hint_enter_declared_capacity,
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Decimal,
|
||||
imeAction = ImeAction.Done
|
||||
),
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = {
|
||||
saveBattery(model = model, navController = navController)
|
||||
}
|
||||
),
|
||||
leadingIcon = { Icon(Icons.Default.BatteryFull, "Icon Battery Full") },
|
||||
suffix = "Ah"
|
||||
suffix = "Ah",
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(Modifier.size(outerPadding))
|
||||
|
||||
ExtendedFloatingActionButton(
|
||||
onClick = {
|
||||
if(model.batteryName.isBlank()) model.batteryHasError = true
|
||||
|
||||
if(!model.batteryHasError && model.saveBattery(model.batteryName, model.declaredCapacity)){
|
||||
navController.navigate("home")
|
||||
}
|
||||
},
|
||||
onClick = { saveBattery(model = model, navController = navController) },
|
||||
icon = { Icon(Icons.Default.Save, "Icon Save") },
|
||||
text = { Text(stringResource(R.string.button_save_battery)) },
|
||||
modifier = Modifier.align(Alignment.End)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveBattery(
|
||||
model: AddBatteryViewModel,
|
||||
navController: NavController
|
||||
){
|
||||
if(model.batteryName.isBlank()) model.batteryHasError = true
|
||||
|
||||
if(!model.batteryHasError && model.saveBattery(model.batteryName, model.declaredCapacity)) {
|
||||
navController.navigate(Routes.HOME)
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.sockenklaus.batterytracker.ui.composables
|
||||
|
||||
import android.app.DatePickerDialog
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
@@ -16,12 +17,15 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import com.sockenklaus.batterytracker.R
|
||||
import com.sockenklaus.batterytracker.room.entities.Battery
|
||||
import com.sockenklaus.batterytracker.ui.Routes
|
||||
import com.sockenklaus.batterytracker.ui.composables.util.MyOutlinedTextFieldWithSuffix
|
||||
import com.sockenklaus.batterytracker.ui.models.AddChargeViewModel
|
||||
import com.sockenklaus.batterytracker.ui.theme.Gray500
|
||||
@@ -33,14 +37,23 @@ import java.util.*
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun AddCharge(navController: NavController){
|
||||
val outerPadding = 24.dp
|
||||
fun AddCharge(
|
||||
batteryId: Int? = null,
|
||||
navController: NavController
|
||||
){
|
||||
val outerPadding = 16.dp
|
||||
val innerPadding = 16.dp
|
||||
|
||||
var bIdExpanded by remember { mutableStateOf(false)}
|
||||
val model: AddChargeViewModel = viewModel()
|
||||
val batteries by model.batteries.observeAsState(emptyList())
|
||||
|
||||
if(batteryId != null && batteries.any { it.id == batteryId }) {
|
||||
model.batteryName = TextFieldValue(
|
||||
text = batteries.find { it.id == batteryId }!!.name
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
Modifier.padding(outerPadding)
|
||||
) {
|
||||
@@ -49,11 +62,12 @@ fun AddCharge(navController: NavController){
|
||||
onExpandedChange = { bIdExpanded = !bIdExpanded}
|
||||
) {
|
||||
|
||||
val filteringOptions = batteries.filter { it.name.contains(model.batteryId.text, ignoreCase = true)}
|
||||
val filteringOptions = batteries.filter { it.name.contains(model.batteryName.text, ignoreCase = true)}
|
||||
OutlinedTextField(
|
||||
value = model.batteryId,
|
||||
enabled = batteryId == null,
|
||||
value = model.batteryName,
|
||||
onValueChange = {
|
||||
model.batteryId = it
|
||||
model.batteryName = it
|
||||
model.batteryHasError = false
|
||||
model.batteryHelper = R.string.helper_required
|
||||
bIdExpanded = filteringOptions.size > 1
|
||||
@@ -65,7 +79,17 @@ fun AddCharge(navController: NavController){
|
||||
},
|
||||
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
isError = model.batteryHasError
|
||||
isError = model.batteryHasError,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Next
|
||||
),
|
||||
keyboardActions = KeyboardActions(
|
||||
onNext = {
|
||||
bIdExpanded = false
|
||||
defaultKeyboardAction(ImeAction.Next)
|
||||
}
|
||||
),
|
||||
singleLine = true
|
||||
)
|
||||
|
||||
if(filteringOptions.isNotEmpty()) {
|
||||
@@ -76,7 +100,7 @@ fun AddCharge(navController: NavController){
|
||||
for (filteringOption in filteringOptions) {
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
model.batteryId = TextFieldValue(
|
||||
model.batteryName = TextFieldValue(
|
||||
text = filteringOption.name,
|
||||
selection = TextRange(filteringOption.name.length)
|
||||
)
|
||||
@@ -104,12 +128,21 @@ fun AddCharge(navController: NavController){
|
||||
model.charge = validateDecimal(it, model.charge)
|
||||
model.chargeHasError = false
|
||||
},
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Decimal,
|
||||
imeAction = ImeAction.Done
|
||||
),
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = {
|
||||
saveCharge(batteries, model, navController)
|
||||
}
|
||||
),
|
||||
labelId = R.string.hint_charge,
|
||||
leadingIcon = { Icon(Icons.Default.BatteryChargingFull, "Icon Battery Charging Full") },
|
||||
isError = model.chargeHasError,
|
||||
helperTextId = R.string.helper_required,
|
||||
suffix = "Ah"
|
||||
suffix = "Ah",
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
|
||||
Spacer(Modifier.size(innerPadding))
|
||||
@@ -124,21 +157,18 @@ fun AddCharge(navController: NavController){
|
||||
ExtendedFloatingActionButton(
|
||||
text = { Text(stringResource(R.string.button_save_charge)) },
|
||||
onClick = {
|
||||
if(!batteries.any{ it.name == model.batteryId.text }){
|
||||
if(!batteries.any{ it.name == model.batteryName.text }){
|
||||
model.batteryHasError = true
|
||||
model.batteryHelper = R.string.helper_battery_not_found
|
||||
}
|
||||
if(model.batteryId.text.isBlank()){
|
||||
if(model.batteryName.text.isBlank()){
|
||||
model.batteryHasError = true
|
||||
model.batteryHelper = R.string.helper_required
|
||||
}
|
||||
if(model.charge.isBlank()){
|
||||
model.chargeHasError = true
|
||||
}
|
||||
|
||||
if(!model.batteryHasError && !model.chargeHasError && model.saveCharge(batteries, model.batteryId.text, model.charge, model.date)){
|
||||
navController.navigate("home")
|
||||
}
|
||||
saveCharge(batteries, model, navController)
|
||||
},
|
||||
icon = { Icon(Icons.Default.Save, "Icon Save") },
|
||||
modifier = Modifier.align(Alignment.End)
|
||||
@@ -147,6 +177,31 @@ fun AddCharge(navController: NavController){
|
||||
}
|
||||
}
|
||||
|
||||
fun saveCharge(
|
||||
batteries: List<Battery>,
|
||||
model: AddChargeViewModel,
|
||||
navController: NavController
|
||||
) {
|
||||
if(!batteries.any{ it.name == model.batteryName.text }){
|
||||
model.batteryHasError = true
|
||||
model.batteryHelper = R.string.helper_battery_not_found
|
||||
}
|
||||
if(model.batteryName.text.isBlank()){
|
||||
model.batteryHasError = true
|
||||
model.batteryHelper = R.string.helper_required
|
||||
}
|
||||
if(model.charge.isBlank()){
|
||||
model.chargeHasError = true
|
||||
}
|
||||
|
||||
if(!model.batteryHasError && !model.chargeHasError && model.saveCharge(batteries, model.batteryName.text, model.charge, model.date)){
|
||||
val id = model.getBatId(
|
||||
batteries,
|
||||
model.batteryName.text
|
||||
)
|
||||
navController.navigate("${Routes.BATTERY_DETAILS}/${id}")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ChargeDatePicker(
|
||||
|
||||
@@ -1,77 +1,94 @@
|
||||
package com.sockenklaus.batterytracker.ui.composables
|
||||
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.OnBackPressedDispatcher
|
||||
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TopAppBar
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import com.sockenklaus.batterytracker.R
|
||||
import com.sockenklaus.batterytracker.room.entities.Battery
|
||||
import com.sockenklaus.batterytracker.room.entities.Charge
|
||||
import com.sockenklaus.batterytracker.ui.AppBarTitle
|
||||
import com.sockenklaus.batterytracker.ui.Routes
|
||||
import com.sockenklaus.batterytracker.ui.models.MainViewModel
|
||||
import com.sockenklaus.batterytracker.ui.models.BatteryDetailsViewModel
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.format.FormatStyle
|
||||
import java.util.*
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun BatteryDetails(
|
||||
navController: NavController,
|
||||
batteryId: Int? = null,
|
||||
appState: MainViewModel
|
||||
batteryId: Int?,
|
||||
navController: NavController
|
||||
){
|
||||
var onBack = {
|
||||
val backTarget = navController.previousBackStackEntry?.destination?.route ?: Routes.HOME
|
||||
appState.currentScreen = backTarget
|
||||
navController.navigate(backTarget)
|
||||
val model: BatteryDetailsViewModel = viewModel()
|
||||
val battery by model.battery.collectAsState(Battery(name = ""))
|
||||
val charges: List<Charge> by model.charges.collectAsState(emptyList())
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
){
|
||||
|
||||
val outputFormat = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.GERMANY)
|
||||
|
||||
LazyColumn(
|
||||
state = LazyListState()
|
||||
) {
|
||||
items(charges){ charge ->
|
||||
ListItem(
|
||||
text = { Text("Charge: " + charge.charge.toString() + " Ah") },
|
||||
secondaryText = { Text("Date: " + charge.date.format(outputFormat)) }
|
||||
|
||||
)
|
||||
Divider(Modifier.padding(horizontal = 16.dp))
|
||||
}
|
||||
}
|
||||
ExtendedFloatingActionButton(
|
||||
text = { Text(stringResource(R.string.add_charge)) },
|
||||
onClick = {
|
||||
navController.navigate("${Routes.ADD_CHARGE}/${battery.id}")
|
||||
},
|
||||
icon = { Icon(Icons.Default.Add, "Icon Add") },
|
||||
modifier = Modifier.align(Alignment.BottomEnd)
|
||||
.padding(16.dp)
|
||||
)
|
||||
}
|
||||
|
||||
BackPressHandler(onBackPressed = onBack)
|
||||
|
||||
Text(batteryId.toString())
|
||||
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun DetailsTopAppBar(
|
||||
navController: NavController,
|
||||
changeCurrentScreen: (String) -> Unit
|
||||
appTitle: String,
|
||||
drawerState: DrawerState
|
||||
){
|
||||
TopAppBar(
|
||||
title = { Text("Details") },
|
||||
title = {
|
||||
AppBarTitle(
|
||||
drawerTarget = drawerState.targetValue,
|
||||
appTitle = appTitle
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = {
|
||||
navController.navigate("home")
|
||||
changeCurrentScreen(Routes.HOME)
|
||||
navController.navigate(Routes.HOME)
|
||||
}
|
||||
) {
|
||||
Icon(Icons.Default.ArrowBack, null)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BackPressHandler(
|
||||
backPressedDispatcher: OnBackPressedDispatcher? = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher,
|
||||
onBackPressed: () -> Unit
|
||||
) {
|
||||
val currentOnBackPressed by rememberUpdatedState(newValue = onBackPressed)
|
||||
|
||||
val backCallback = remember {
|
||||
object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
currentOnBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DisposableEffect(key1 = backPressedDispatcher) {
|
||||
backPressedDispatcher?.addCallback(backCallback)
|
||||
|
||||
onDispose {
|
||||
backCallback.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,22 @@
|
||||
package com.sockenklaus.batterytracker.ui.composables
|
||||
|
||||
import android.telecom.Call
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
@@ -20,36 +25,50 @@ import com.sockenklaus.batterytracker.room.entities.Battery
|
||||
import com.sockenklaus.batterytracker.ui.Routes
|
||||
import com.sockenklaus.batterytracker.ui.composables.util.MyOutlinedTextFieldWithSuffix
|
||||
import com.sockenklaus.batterytracker.ui.models.HomeViewModel
|
||||
import com.sockenklaus.batterytracker.ui.models.MainViewModel
|
||||
import java.lang.reflect.GenericDeclaration
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun Home(
|
||||
navController: NavController,
|
||||
appState: MainViewModel
|
||||
navController: NavController
|
||||
) {
|
||||
val model: HomeViewModel = viewModel()
|
||||
val batteries by model.batteries.observeAsState(emptyList<Battery>())
|
||||
var filterText by remember { mutableStateOf("")}
|
||||
|
||||
val filteredList = batteries.filter { it.name.contains(filterText, ignoreCase = true) }
|
||||
val modHorizontalPadding = Modifier.padding(horizontal = 16.dp)
|
||||
|
||||
Column {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
){
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 16.dp)
|
||||
.fillMaxHeight()
|
||||
) {
|
||||
MyOutlinedTextFieldWithSuffix(
|
||||
value = filterText,
|
||||
onValueChange = { filterText = it },
|
||||
labelId = R.string.hint_filter_batteries,
|
||||
modifier = Modifier.padding(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
top = 16.dp,
|
||||
start = 16.dp,
|
||||
end = 16.dp,
|
||||
top = 16.dp
|
||||
end = 16.dp
|
||||
)
|
||||
.fillMaxWidth(),
|
||||
singleLine = true,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Search
|
||||
),
|
||||
keyboardActions = KeyboardActions(
|
||||
onSearch = {
|
||||
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
LazyColumn(
|
||||
state = LazyListState()
|
||||
state = LazyListState(),
|
||||
) {
|
||||
items(filteredList){ battery ->
|
||||
ListItem(
|
||||
@@ -65,13 +84,22 @@ fun Home(
|
||||
},
|
||||
modifier = Modifier.clickable {
|
||||
navController.navigate("${Routes.BATTERY_DETAILS}/${battery.id}")
|
||||
appState.currentScreen = Routes.BATTERY_DETAILS
|
||||
}
|
||||
)
|
||||
Divider(modHorizontalPadding)
|
||||
Divider(Modifier.padding(horizontal = 16.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
ExtendedFloatingActionButton(
|
||||
text = { Text(stringResource(R.string.nav_add_battery)) },
|
||||
icon = { Icon(Icons.Default.Add, contentDescription = "Add Battery") },
|
||||
onClick = {
|
||||
navController.navigate(Routes.ADD_BATTERY)
|
||||
},
|
||||
modifier = Modifier.padding(16.dp)
|
||||
.align(Alignment.BottomEnd)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -21,90 +21,6 @@ import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.sockenklaus.batterytracker.ui.theme.Gray500
|
||||
|
||||
/*@Composable
|
||||
fun TopAppBar(
|
||||
title: @Composable () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
navigationIcon: @Composable (() -> Unit)? = null,
|
||||
actions: @Composable RowScope.() -> Unit = {},
|
||||
backgroundColor: Color = MaterialTheme.colors.primarySurface,
|
||||
contentColor: Color = contentColorFor(backgroundColor),
|
||||
elevation: Dp = AppBarDefaults.TopAppBarElevation
|
||||
) {
|
||||
AppBar(
|
||||
backgroundColor,
|
||||
contentColor,
|
||||
elevation,
|
||||
AppBarDefaults.ContentPadding,
|
||||
RectangleShape,
|
||||
modifier
|
||||
) {
|
||||
if (navigationIcon == null) {
|
||||
Spacer(Modifier.width(16.dp - 4.dp))
|
||||
} else {
|
||||
Row(Modifier.fillMaxHeight().width(72.dp - 4.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
CompositionLocalProvider(
|
||||
LocalContentAlpha provides ContentAlpha.high,
|
||||
content = navigationIcon
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
Modifier.fillMaxHeight().weight(1f),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
ProvideTextStyle(value = MaterialTheme.typography.h6) {
|
||||
CompositionLocalProvider(
|
||||
LocalContentAlpha provides ContentAlpha.high,
|
||||
content = title
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
|
||||
Row(
|
||||
Modifier.fillMaxHeight(),
|
||||
horizontalArrangement = Arrangement.End,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
content = actions
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
private fun AppBar(
|
||||
backgroundColor: Color,
|
||||
contentColor: Color,
|
||||
elevation: Dp,
|
||||
contentPadding: PaddingValues,
|
||||
shape: Shape,
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable RowScope.() -> Unit
|
||||
) {
|
||||
Surface(
|
||||
color = backgroundColor,
|
||||
contentColor = contentColor,
|
||||
elevation = elevation,
|
||||
shape = shape,
|
||||
modifier = modifier
|
||||
) {
|
||||
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth()
|
||||
.padding(contentPadding)
|
||||
.height(56.dp),
|
||||
horizontalArrangement = Arrangement.Start,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
fun MyOutlinedTextFieldWithSuffix(
|
||||
@@ -142,11 +58,11 @@ fun MyOutlinedTextFieldWithSuffix(
|
||||
Gray500
|
||||
}
|
||||
|
||||
Column() {
|
||||
BasicTextField(
|
||||
value = value,
|
||||
modifier = modifier
|
||||
.padding(top = 8.dp)
|
||||
|
||||
.background(colors.backgroundColor(enabled).value, shape)
|
||||
.defaultMinSize(
|
||||
minWidth = TextFieldDefaults.MinWidth,
|
||||
@@ -168,9 +84,11 @@ fun MyOutlinedTextFieldWithSuffix(
|
||||
value = value,
|
||||
visualTransformation = visualTransformation,
|
||||
innerTextField = {
|
||||
Row {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
val alignModifier = Modifier.alignByBaseline()
|
||||
Box(alignModifier.weight(1f)){
|
||||
Box(alignModifier){
|
||||
innerTextField()
|
||||
}
|
||||
Text(
|
||||
@@ -208,3 +126,4 @@ fun MyOutlinedTextFieldWithSuffix(
|
||||
modifier = Modifier.padding(start = 16.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ class AddBatteryViewModel(application: Application): AndroidViewModel(applicatio
|
||||
var batteryName by mutableStateOf("")
|
||||
var batteryHasError by mutableStateOf(false)
|
||||
var batteryHelperId by mutableStateOf(R.string.helper_required)
|
||||
var switchAutoCap by mutableStateOf(true)
|
||||
|
||||
var declaredCapacity by mutableStateOf("")
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.sockenklaus.batterytracker.ui.models
|
||||
|
||||
import android.app.Application
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
@@ -23,7 +22,7 @@ class AddChargeViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
private val db = BatteryTrackerDB.getInstance(application)
|
||||
var batteries: LiveData<List<Battery>> = db.batteryDao().getBatteries().asLiveData()
|
||||
|
||||
var batteryId by mutableStateOf(TextFieldValue(""))
|
||||
var batteryName by mutableStateOf(TextFieldValue(""))
|
||||
var date: LocalDate by mutableStateOf(LocalDate.now())
|
||||
var charge by mutableStateOf("")
|
||||
|
||||
@@ -32,6 +31,14 @@ class AddChargeViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
|
||||
var chargeHasError by mutableStateOf(false)
|
||||
|
||||
fun getBatId(
|
||||
batteries: List<Battery>,
|
||||
name: String
|
||||
) : Int? {
|
||||
|
||||
return batteries.find { it.name == name }?.id
|
||||
}
|
||||
|
||||
fun saveCharge(
|
||||
batteryList: List<Battery>,
|
||||
batteryName: String,
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.sockenklaus.batterytracker.ui.models
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.*
|
||||
import com.sockenklaus.batterytracker.room.BatteryTrackerDB
|
||||
import com.sockenklaus.batterytracker.room.entities.Battery
|
||||
import com.sockenklaus.batterytracker.room.entities.Charge
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class BatteryDetailsViewModel(
|
||||
application: Application,
|
||||
state: SavedStateHandle
|
||||
) : AndroidViewModel(application) {
|
||||
|
||||
private val db = BatteryTrackerDB.getInstance(application)
|
||||
|
||||
val battery: Flow<Battery> = if(state.get<Int?>("batteryId") !== null) {
|
||||
db.batteryDao().getBatteryById(state["batteryId"]!!)
|
||||
} else {
|
||||
MutableStateFlow(Battery(name=""))
|
||||
}
|
||||
|
||||
val charges: Flow<List<Charge>> = if(state.get<Int?>("batteryId") !== null){
|
||||
db.chargeDao().getChargesByBatteryId(state["batteryId"]!!)
|
||||
} else {
|
||||
MutableStateFlow(emptyList())
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||
val batteryAndCharges = batteriesAndCharges?.find{ it.battery.id == batteryId }
|
||||
|
||||
if((batteryAndCharges != null) && batteryAndCharges.charges.isNotEmpty()){
|
||||
return batteryAndCharges.charges.map { it.charge }.min()
|
||||
return batteryAndCharges.charges.minOfOrNull { it.charge }
|
||||
}
|
||||
return null
|
||||
}
|
||||
@@ -32,7 +32,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||
val batteryAndCharges = batteriesAndCharges?.find { it.battery.id == batteryId }
|
||||
|
||||
if((batteryAndCharges != null) && batteryAndCharges.charges.isNotEmpty()) {
|
||||
return batteryAndCharges.charges.map { it.charge }.max()
|
||||
return batteryAndCharges.charges.maxOfOrNull { it.charge }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -2,17 +2,16 @@ package com.sockenklaus.batterytracker.ui.models
|
||||
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.graphics.BlendMode.Companion.Screen
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.sockenklaus.batterytracker.ui.AppBarTitle
|
||||
import com.sockenklaus.batterytracker.room.BatteryTrackerDB
|
||||
import com.sockenklaus.batterytracker.room.entities.Battery
|
||||
import com.sockenklaus.batterytracker.ui.Routes
|
||||
import com.sockenklaus.batterytracker.ui.ToggleDrawerButton
|
||||
|
||||
class MainViewModel : ViewModel() {
|
||||
|
||||
var appTitle by mutableStateOf("Home")
|
||||
var currentScreen by mutableStateOf(Routes.HOME)
|
||||
|
||||
lateinit var navController: NavHostController
|
||||
@@ -23,4 +22,20 @@ class MainViewModel : ViewModel() {
|
||||
navController = rememberNavController()
|
||||
scaffoldState = rememberScaffoldState()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun getBatteryName(
|
||||
id: Int?
|
||||
) : String {
|
||||
val db = BatteryTrackerDB.getInstance(LocalContext.current)
|
||||
val battery = id?.let { db.batteryDao().getBatteryById(it).collectAsState(initial = Battery(name="")) }
|
||||
|
||||
var name = ""
|
||||
|
||||
if (battery != null){
|
||||
name = battery.value.name
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<string name="nav_header_title">Navigation</string>
|
||||
<string name="nav_home">Home</string>
|
||||
<string name="nav_add_charge">Add Charge</string>
|
||||
<string name="add_charge">Add Charge</string>
|
||||
<string name="nav_add_battery">Add Battery</string>
|
||||
|
||||
<string name="battery_id">Battery ID</string>
|
||||
|
||||
@@ -5,8 +5,8 @@ ext {
|
||||
}
|
||||
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
id 'com.android.application' version '7.2.1' apply false
|
||||
id 'com.android.library' version '7.2.1' apply false
|
||||
id 'com.android.application' version '7.3.1' apply false
|
||||
id 'com.android.library' version '7.3.1' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
|
||||
id 'org.jetbrains.kotlin.kapt' version '1.7.0' apply false
|
||||
}
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Sun Jul 10 23:29:55 CEST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
Reference in New Issue
Block a user