From c20d5d55e5ebb32eaa10a1f49ba6bb3e1dfd2dbe Mon Sep 17 00:00:00 2001 From: Sockenklaus Date: Thu, 17 Nov 2022 02:47:33 +0100 Subject: [PATCH] Lots of work on charges list... lots of work to do... --- .idea/deploymentTargetDropDown.xml | 17 ++++++++++ app/build.gradle | 8 ++--- app/src/main/AndroidManifest.xml | 3 +- .../batterytracker/room/dao/BatteryDao.kt | 2 +- .../batterytracker/room/dao/ChargeDao.kt | 3 ++ .../batterytracker/ui/BatteryTracker.kt | 21 +++++++----- .../ui/composables/BatteryDetails.kt | 34 +++++++++++++++++-- .../ui/models/BatteryDetailsViewModel.kt | 31 +++++++++++++++++ .../batterytracker/ui/models/HomeViewModel.kt | 4 +-- .../batterytracker/ui/models/MainViewModel.kt | 19 +++++++++++ build.gradle | 4 +-- gradle/wrapper/gradle-wrapper.properties | 2 +- 12 files changed, 125 insertions(+), 23 deletions(-) create mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 app/src/main/java/com/sockenklaus/batterytracker/ui/models/BatteryDetailsViewModel.kt diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..30c176f --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 8446481..6355508 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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" @@ -63,6 +63,7 @@ android { excludes += '/META-INF/{AL2.0,LGPL2.1}' } } + namespace 'com.sockenklaus.batterytracker' } dependencies { @@ -87,8 +88,6 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1' - //implementation 'com.google.android.material:compose-theme-adapter:1.1.22' - implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.appcompat:appcompat:1.5.1' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' @@ -105,5 +104,4 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.4' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' - } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 52eddea..7dbfabc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> > - @Query("Select * FROM batteries WHERE id = :id") + @Query("SELECT * FROM batteries WHERE id = :id") fun getBatteryById(id: Int): Flow @Transaction diff --git a/app/src/main/java/com/sockenklaus/batterytracker/room/dao/ChargeDao.kt b/app/src/main/java/com/sockenklaus/batterytracker/room/dao/ChargeDao.kt index 46fdda0..8fa8846 100644 --- a/app/src/main/java/com/sockenklaus/batterytracker/room/dao/ChargeDao.kt +++ b/app/src/main/java/com/sockenklaus/batterytracker/room/dao/ChargeDao.kt @@ -25,4 +25,7 @@ interface ChargeDao { @Transaction @Query("SELECT * FROM batteries WHERE id = :id") fun getBatteryAndCharges(id: Int): Flow + + @Query("SELECT * FROM charges WHERE battery_id = :id ORDER BY date DESC") + fun getChargesByBatteryId(id: Int): Flow> } \ No newline at end of file diff --git a/app/src/main/java/com/sockenklaus/batterytracker/ui/BatteryTracker.kt b/app/src/main/java/com/sockenklaus/batterytracker/ui/BatteryTracker.kt index 5225a9b..f2aeee3 100644 --- a/app/src/main/java/com/sockenklaus/batterytracker/ui/BatteryTracker.kt +++ b/app/src/main/java/com/sockenklaus/batterytracker/ui/BatteryTracker.kt @@ -1,5 +1,6 @@ package com.sockenklaus.batterytracker.ui +import android.annotation.SuppressLint import androidx.compose.animation.AnimatedContent import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.clickable @@ -29,6 +30,7 @@ object Routes { const val BATTERY_DETAILS = "Battery Details" } +@SuppressLint("UnusedMaterialScaffoldPaddingParameter") @Composable fun BatteryTracker() { MaterialTheme { @@ -39,13 +41,15 @@ fun BatteryTracker() { scaffoldState = state.scaffoldState, topBar = { - when(state.currentScreen){ + when { + state.currentScreen.startsWith(Routes.BATTERY_DETAILS) -> { - Routes.BATTERY_DETAILS -> DetailsTopAppBar( - navController = state.navController, - drawerState = state.scaffoldState.drawerState, - appTitle = state.currentScreen - ) + DetailsTopAppBar( + navController = state.navController, + drawerState = state.scaffoldState.drawerState, + appTitle = state.currentScreen + ) + } else -> MainTopAppBar( drawerState = state.scaffoldState.drawerState, @@ -100,9 +104,10 @@ fun BatteryTracker() { route = "${Routes.BATTERY_DETAILS}/{batteryId}", arguments = listOf(navArgument("batteryId"){ type = NavType.IntType }) ) { navBackStackEntry -> - state.currentScreen = Routes.BATTERY_DETAILS + val id = navBackStackEntry.arguments?.getInt("batteryId") + state.currentScreen = Routes.BATTERY_DETAILS + ": " + state.getBatteryName(id = id) BatteryDetails( - batteryId = navBackStackEntry.arguments?.getInt("batteryId"), + batteryId = id, ) } } diff --git a/app/src/main/java/com/sockenklaus/batterytracker/ui/composables/BatteryDetails.kt b/app/src/main/java/com/sockenklaus/batterytracker/ui/composables/BatteryDetails.kt index 27d798b..d33463a 100644 --- a/app/src/main/java/com/sockenklaus/batterytracker/ui/composables/BatteryDetails.kt +++ b/app/src/main/java/com/sockenklaus/batterytracker/ui/composables/BatteryDetails.kt @@ -2,24 +2,54 @@ package com.sockenklaus.batterytracker.ui.composables import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding +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.ArrowBack import androidx.compose.runtime.* +import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController +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.BatteryDetailsViewModel +import java.time.format.DateTimeFormatter +import java.time.format.FormatStyle +import java.util.* +@OptIn(ExperimentalMaterialApi::class) @Composable fun BatteryDetails( batteryId: Int? = null ){ + val model: BatteryDetailsViewModel = viewModel() + val battery by model.battery.observeAsState() + val charges: List by model.charges.observeAsState(emptyList()) + Column( - modifier = Modifier.padding(16.dp) + modifier = Modifier.padding(bottom = 16.dp) ){ - Text(batteryId.toString()) + + 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)) + } + } + } } diff --git a/app/src/main/java/com/sockenklaus/batterytracker/ui/models/BatteryDetailsViewModel.kt b/app/src/main/java/com/sockenklaus/batterytracker/ui/models/BatteryDetailsViewModel.kt new file mode 100644 index 0000000..30b8357 --- /dev/null +++ b/app/src/main/java/com/sockenklaus/batterytracker/ui/models/BatteryDetailsViewModel.kt @@ -0,0 +1,31 @@ +package com.sockenklaus.batterytracker.ui.models + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.asLiveData +import com.sockenklaus.batterytracker.room.BatteryTrackerDB +import com.sockenklaus.batterytracker.room.entities.Battery +import com.sockenklaus.batterytracker.room.entities.Charge + +class BatteryDetailsViewModel( + application: Application, + state: SavedStateHandle +) : AndroidViewModel(application) { + + private val db = BatteryTrackerDB.getInstance(application) + + val battery: LiveData = if(state.get("batteryId") !== null) { + db.batteryDao().getBatteryById(state["batteryId"]!!).asLiveData() + } else { + MutableLiveData() + } + + val charges: LiveData> = if(state.get("batteryId") !== null){ + db.chargeDao().getChargesByBatteryId(state["batteryId"]!!).asLiveData() + } else { + MutableLiveData() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sockenklaus/batterytracker/ui/models/HomeViewModel.kt b/app/src/main/java/com/sockenklaus/batterytracker/ui/models/HomeViewModel.kt index 5b0fb51..9596845 100644 --- a/app/src/main/java/com/sockenklaus/batterytracker/ui/models/HomeViewModel.kt +++ b/app/src/main/java/com/sockenklaus/batterytracker/ui/models/HomeViewModel.kt @@ -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 } diff --git a/app/src/main/java/com/sockenklaus/batterytracker/ui/models/MainViewModel.kt b/app/src/main/java/com/sockenklaus/batterytracker/ui/models/MainViewModel.kt index 24781fb..686c20b 100644 --- a/app/src/main/java/com/sockenklaus/batterytracker/ui/models/MainViewModel.kt +++ b/app/src/main/java/com/sockenklaus/batterytracker/ui/models/MainViewModel.kt @@ -2,9 +2,12 @@ package com.sockenklaus.batterytracker.ui.models import androidx.compose.material.* import androidx.compose.runtime.* +import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.ViewModel import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController +import com.sockenklaus.batterytracker.room.BatteryTrackerDB +import com.sockenklaus.batterytracker.room.entities.Battery import com.sockenklaus.batterytracker.ui.Routes class MainViewModel : ViewModel() { @@ -19,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 + } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 8717394..eab1352 100644 --- a/build.gradle +++ b/build.gradle @@ -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 } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2224f9d..88fe103 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -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