Lots of work on charges list... lots of work to do...

This commit is contained in:
Sockenklaus
2022-11-17 02:47:33 +01:00
parent 49eabce142
commit c20d5d55e5
12 changed files with 125 additions and 23 deletions

17
.idea/deploymentTargetDropDown.xml generated Normal file
View 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>

View File

@@ -11,12 +11,12 @@ android {
release { release {
} }
} }
compileSdk 32 compileSdk 33
defaultConfig { defaultConfig {
applicationId "com.sockenklaus.batterytracker" applicationId "com.sockenklaus.batterytracker"
minSdk 29 minSdk 29
targetSdk 32 targetSdk 33
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
@@ -63,6 +63,7 @@ android {
excludes += '/META-INF/{AL2.0,LGPL2.1}' excludes += '/META-INF/{AL2.0,LGPL2.1}'
} }
} }
namespace 'com.sockenklaus.batterytracker'
} }
dependencies { dependencies {
@@ -87,8 +88,6 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose: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.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1' implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
@@ -105,5 +104,4 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.4' androidTestImplementation 'androidx.test.ext:junit:1.1.4'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
} }

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools">
package="com.sockenklaus.batterytracker">
<application <application
android:allowBackup="true" android:allowBackup="true"

View File

@@ -19,7 +19,7 @@ interface BatteryDao {
@Query("Select * FROM batteries ORDER BY name COLLATE NOCASE ASC") @Query("Select * FROM batteries ORDER BY name COLLATE NOCASE ASC")
fun getBatteries(): Flow<List<Battery>> 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> fun getBatteryById(id: Int): Flow<Battery>
@Transaction @Transaction

View File

@@ -25,4 +25,7 @@ interface ChargeDao {
@Transaction @Transaction
@Query("SELECT * FROM batteries WHERE id = :id") @Query("SELECT * FROM batteries WHERE id = :id")
fun getBatteryAndCharges(id: Int): Flow<BatteryAndCharges> fun getBatteryAndCharges(id: Int): Flow<BatteryAndCharges>
@Query("SELECT * FROM charges WHERE battery_id = :id ORDER BY date DESC")
fun getChargesByBatteryId(id: Int): Flow<List<Charge>>
} }

View File

@@ -1,5 +1,6 @@
package com.sockenklaus.batterytracker.ui package com.sockenklaus.batterytracker.ui
import android.annotation.SuppressLint
import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@@ -29,6 +30,7 @@ object Routes {
const val BATTERY_DETAILS = "Battery Details" const val BATTERY_DETAILS = "Battery Details"
} }
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable @Composable
fun BatteryTracker() { fun BatteryTracker() {
MaterialTheme { MaterialTheme {
@@ -39,13 +41,15 @@ fun BatteryTracker() {
scaffoldState = state.scaffoldState, scaffoldState = state.scaffoldState,
topBar = { topBar = {
when(state.currentScreen){ when {
state.currentScreen.startsWith(Routes.BATTERY_DETAILS) -> {
Routes.BATTERY_DETAILS -> DetailsTopAppBar( DetailsTopAppBar(
navController = state.navController, navController = state.navController,
drawerState = state.scaffoldState.drawerState, drawerState = state.scaffoldState.drawerState,
appTitle = state.currentScreen appTitle = state.currentScreen
) )
}
else -> MainTopAppBar( else -> MainTopAppBar(
drawerState = state.scaffoldState.drawerState, drawerState = state.scaffoldState.drawerState,
@@ -100,9 +104,10 @@ fun BatteryTracker() {
route = "${Routes.BATTERY_DETAILS}/{batteryId}", route = "${Routes.BATTERY_DETAILS}/{batteryId}",
arguments = listOf(navArgument("batteryId"){ type = NavType.IntType }) arguments = listOf(navArgument("batteryId"){ type = NavType.IntType })
) { navBackStackEntry -> ) { navBackStackEntry ->
state.currentScreen = Routes.BATTERY_DETAILS val id = navBackStackEntry.arguments?.getInt("batteryId")
state.currentScreen = Routes.BATTERY_DETAILS + ": " + state.getBatteryName(id = id)
BatteryDetails( BatteryDetails(
batteryId = navBackStackEntry.arguments?.getInt("batteryId"), batteryId = id,
) )
} }
} }

View File

@@ -2,24 +2,54 @@ package com.sockenklaus.batterytracker.ui.composables
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding 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.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.sockenklaus.batterytracker.room.entities.Charge
import com.sockenklaus.batterytracker.ui.AppBarTitle import com.sockenklaus.batterytracker.ui.AppBarTitle
import com.sockenklaus.batterytracker.ui.Routes 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 @Composable
fun BatteryDetails( fun BatteryDetails(
batteryId: Int? = null batteryId: Int? = null
){ ){
val model: BatteryDetailsViewModel = viewModel()
val battery by model.battery.observeAsState()
val charges: List<Charge> by model.charges.observeAsState(emptyList())
Column( 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))
}
}
} }
} }

View File

@@ -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<Battery> = if(state.get<Int?>("batteryId") !== null) {
db.batteryDao().getBatteryById(state["batteryId"]!!).asLiveData()
} else {
MutableLiveData()
}
val charges: LiveData<List<Charge>> = if(state.get<Int?>("batteryId") !== null){
db.chargeDao().getChargesByBatteryId(state["batteryId"]!!).asLiveData()
} else {
MutableLiveData()
}
}

View File

@@ -21,7 +21,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
val batteryAndCharges = batteriesAndCharges?.find{ it.battery.id == batteryId } val batteryAndCharges = batteriesAndCharges?.find{ it.battery.id == batteryId }
if((batteryAndCharges != null) && batteryAndCharges.charges.isNotEmpty()){ if((batteryAndCharges != null) && batteryAndCharges.charges.isNotEmpty()){
return batteryAndCharges.charges.map { it.charge }.min() return batteryAndCharges.charges.minOfOrNull { it.charge }
} }
return null return null
} }
@@ -32,7 +32,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
val batteryAndCharges = batteriesAndCharges?.find { it.battery.id == batteryId } val batteryAndCharges = batteriesAndCharges?.find { it.battery.id == batteryId }
if((batteryAndCharges != null) && batteryAndCharges.charges.isNotEmpty()) { if((batteryAndCharges != null) && batteryAndCharges.charges.isNotEmpty()) {
return batteryAndCharges.charges.map { it.charge }.max() return batteryAndCharges.charges.maxOfOrNull { it.charge }
} }
return null return null
} }

View File

@@ -2,9 +2,12 @@ package com.sockenklaus.batterytracker.ui.models
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.sockenklaus.batterytracker.room.BatteryTrackerDB
import com.sockenklaus.batterytracker.room.entities.Battery
import com.sockenklaus.batterytracker.ui.Routes import com.sockenklaus.batterytracker.ui.Routes
class MainViewModel : ViewModel() { class MainViewModel : ViewModel() {
@@ -19,4 +22,20 @@ class MainViewModel : ViewModel() {
navController = rememberNavController() navController = rememberNavController()
scaffoldState = rememberScaffoldState() 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
}
} }

View File

@@ -5,8 +5,8 @@ ext {
} }
}// Top-level build file where you can add configuration options common to all sub-projects/modules. }// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id 'com.android.application' version '7.2.1' apply false id 'com.android.application' version '7.3.1' apply false
id 'com.android.library' version '7.2.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.android' version '1.7.0' apply false
id 'org.jetbrains.kotlin.kapt' version '1.7.0' apply false id 'org.jetbrains.kotlin.kapt' version '1.7.0' apply false
} }

View File

@@ -1,6 +1,6 @@
#Sun Jul 10 23:29:55 CEST 2022 #Sun Jul 10 23:29:55 CEST 2022
distributionBase=GRADLE_USER_HOME 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 distributionPath=wrapper/dists
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME