1
0
mirror of https://github.com/dzeiocom/OpenHealth.git synced 2025-04-23 19:32:11 +00:00

Stated Adding Water Intake

This commit is contained in:
Florian Bouillon 2021-12-22 01:44:34 +01:00
parent e1f11e1ae2
commit 077397749c
Signed by: Florian Bouillon
GPG Key ID: 50BD648F12C86AB6
33 changed files with 1109 additions and 694 deletions

7
.gitignore vendored
View File

@ -1,12 +1,7 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
/.idea
.DS_Store
/build
/captures

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">
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="14e181ff" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2021-12-21T23:29:01.995426900Z" />
</component>
</project>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Reformat" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
</profile>
</component>

5
.idea/misc.xml generated
View File

@ -7,6 +7,8 @@
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_import.xml" value="0.1" />
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/menu/activity_main_drawer.xml" value="0.10989583333333333" />
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/menu/main.xml" value="0.1875" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/drawable/half_circle.xml" value="0.421" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/drawable/ic_ellipse_2.xml" value="0.4165" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/drawable/ic_logo_app.xml" value="0.163" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/activity_main.xml" value="0.5" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/app_bar_main.xml" value="0.5192107995846313" />
@ -15,9 +17,10 @@
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/dialog_edit_weight.xml" value="0.33" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/dialog_register_weight.xml" value="0.5" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_gallery.xml" value="0.3109375" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_home.xml" value="0.25" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_home.xml" value="0.6845493562231759" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_import.xml" value="0.55" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_list_weight.xml" value="0.33" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_water_home.xml" value="0.55" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/layout_item_weight.xml" value="0.5" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/nav_header_main.xml" value="0.3109375" />
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/menu/activity_main_drawer.xml" value="0.39947916666666666" />

View File

@ -5,10 +5,7 @@ import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.Menu
import androidx.appcompat.app.AppCompatActivity
import androidx.drawerlayout.widget.DrawerLayout
import androidx.navigation.NavController
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
@ -16,9 +13,6 @@ import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.dzeio.openhealth.core.BaseActivity
import com.dzeio.openhealth.databinding.ActivityMainBinding
import com.dzeio.openhealth.ui.main.home.HomeFragmentDirections
import com.google.android.material.navigation.NavigationView
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint

View File

@ -4,18 +4,27 @@ import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.dzeio.openhealth.data.weight.Water
import com.dzeio.openhealth.data.weight.WaterDao
import com.dzeio.openhealth.data.weight.WeightDao
import com.dzeio.openhealth.data.weight.Weight
@Database(entities = [Weight::class], version = 1, exportSchema = false)
@Database(
entities = [
Weight::class,
Water::class
], version = 1, exportSchema = false
)
abstract class AppDatabase : RoomDatabase() {
abstract fun weightDao(): WeightDao
abstract fun waterDao(): WaterDao
companion object {
private const val DATABASE_NAME = "open_health"
// For Singleton instantiation
@Volatile private var instance: AppDatabase? = null
@Volatile
private var instance: AppDatabase? = null
fun getInstance(context: Context): AppDatabase {
return instance ?: synchronized(this) {

View File

@ -0,0 +1,29 @@
package com.dzeio.openhealth.data.weight
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.sql.Date
import java.text.DateFormat.getDateInstance
import java.util.*
@Entity()
data class Water(
@PrimaryKey(autoGenerate = true) var id: Long = 0,
var value: Int = 0,
@ColumnInfo(index = true)
var timestamp: Long = System.currentTimeMillis(),
var source: String = "OpenHealth"
) {
init {
val cal = Calendar.getInstance()
cal.set(Calendar.HOUR_OF_DAY, 0)
cal.set(Calendar.MINUTE, 0)
cal.set(Calendar.SECOND, 0)
cal.set(Calendar.MILLISECOND, 0)
timestamp = cal.timeInMillis
}
fun formatTimestamp(): String = getDateInstance().format(Date(timestamp))
}

View File

@ -0,0 +1,26 @@
package com.dzeio.openhealth.data.weight
import androidx.room.*
import com.dzeio.openhealth.core.BaseDao
import dagger.Provides
import kotlinx.coroutines.flow.Flow
@Dao
interface WaterDao : BaseDao<Water> {
@Query("SELECT * FROM Water")
fun getAll(): Flow<List<Water>>
@Query("SELECT * FROM Water where id = :weightId")
fun getOne(weightId: Long): Flow<Water?>
@Query("Select count(*) from Water")
fun getCount(): Flow<Int>
@Query("Select * FROM Water WHERE id=(SELECT max(id) FROM Water)")
fun last(): Flow<Water?>
@Query("DELETE FROM Water where source = :source")
suspend fun deleteFromSource(source: String)
}

View File

@ -0,0 +1,32 @@
package com.dzeio.openhealth.data.weight
import android.util.Log
import kotlinx.coroutines.flow.*
import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class WaterRepository @Inject constructor(
private val waterDao: WaterDao
) {
fun getWaters() = waterDao.getAll()
fun lastWater() = waterDao.last()
fun getWater(id: Long) = waterDao.getOne(id)
suspend fun addWater(value: Water) = waterDao.insert(value)
suspend fun deleteWater(value: Water) = waterDao.delete(value)
suspend fun deleteFromSource(value: String) = waterDao.deleteFromSource(value)
fun todayWater() = lastWater().filter {
val cal = Calendar.getInstance()
cal.set(Calendar.HOUR_OF_DAY, 0)
cal.set(Calendar.MINUTE, 0)
cal.set(Calendar.SECOND, 0)
cal.set(Calendar.MILLISECOND, 0)
Log.d("WaterRepository", "${it?.timestamp} ${cal.timeInMillis}")
return@filter it?.timestamp == cal.timeInMillis
}
}

View File

@ -2,6 +2,7 @@ package com.dzeio.openhealth.di
import android.content.Context
import com.dzeio.openhealth.data.AppDatabase
import com.dzeio.openhealth.data.weight.WaterDao
import com.dzeio.openhealth.data.weight.WeightDao
import dagger.Module
import dagger.Provides
@ -24,4 +25,9 @@ class DatabaseModule {
fun provideWeightDao(appDatabase: AppDatabase): WeightDao {
return appDatabase.weightDao()
}
@Provides
fun provideWaterDao(appDatabase: AppDatabase): WaterDao {
return appDatabase.waterDao()
}
}

View File

@ -1,4 +1,4 @@
package com.dzeio.openhealth.connectors
package com.dzeio.openhealth.extensions
enum class DataType {
WEIGHT

View File

@ -1,10 +1,10 @@
package com.dzeio.openhealth.connectors
package com.dzeio.openhealth.extensions
import android.app.Activity
import android.content.Intent
import com.dzeio.openhealth.data.weight.Weight
abstract class Connector {
abstract class Extension {
enum class Data {
WEIGHT,
@ -13,7 +13,7 @@ abstract class Connector {
abstract val sourceID: String
open fun init(activity: Activity) {}
open fun init(activity: Activity): Array<Data> = arrayOf()
/**
* Same as Activity/Fragment onRequestPermissionResult
@ -27,5 +27,7 @@ abstract class Connector {
*/
open fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {}
open fun <T> import(data: Data, cb: (item: T, end: Boolean) -> Unit) {}
open fun importWeight(callback: (weight: Weight, end: Boolean) -> Unit) {}
}

View File

@ -1,4 +1,4 @@
package com.dzeio.openhealth.connectors
package com.dzeio.openhealth.extensions
import android.Manifest
import android.app.Activity
@ -12,7 +12,6 @@ import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.fitness.Fitness
import com.google.android.gms.fitness.FitnessOptions
import com.google.android.gms.fitness.data.DataPoint
import com.google.android.gms.fitness.data.DataSet
import com.google.android.gms.fitness.data.DataType
import com.google.android.gms.fitness.request.DataReadRequest
import java.text.DateFormat
@ -21,7 +20,7 @@ import java.util.concurrent.TimeUnit
class GoogleFit(
private val activity: Activity,
) : Connector() {
) : Extension() {
companion object {
const val TAG = "GoogleFitConnector"
}
@ -170,4 +169,18 @@ class GoogleFit(
checkPermissionsAndRun(Data.WEIGHT)
}
private lateinit var callback : (item: Any, end: Boolean) -> Unit
override fun <T> import(data: Data, cb: (item: T, end: Boolean) -> Unit) {
callback = cb as (item: Any, end: Boolean) -> Unit
when (data) {
Data.WEIGHT -> {
checkPermissionsAndRun(data)
}
else -> {
Log.d(TAG, "PRRRRRRRRRRRRR")
}
}
}
}

View File

@ -1,4 +1,4 @@
package com.dzeio.openhealth.connectors
package com.dzeio.openhealth.extensions
import android.Manifest
import android.app.Activity
@ -7,7 +7,6 @@ import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import com.dzeio.openhealth.data.AppDatabase
import com.dzeio.openhealth.data.weight.Weight
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.fitness.Fitness
@ -22,7 +21,6 @@ import com.google.android.gms.fitness.request.OnDataPointListener
import com.google.android.gms.fitness.request.SensorRequest
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.time.*
import java.util.*
import java.util.concurrent.TimeUnit

View File

@ -1,11 +1,11 @@
package com.dzeio.openhealth.connectors.samsunghealth
package com.dzeio.openhealth.extensions.samsunghealth
import android.app.Activity
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.dzeio.openhealth.connectors.Connector
import com.dzeio.openhealth.extensions.Extension
import com.dzeio.openhealth.data.weight.Weight
import com.samsung.android.sdk.healthdata.*
import com.samsung.android.sdk.healthdata.HealthConstants.StepCount
@ -18,7 +18,7 @@ import com.samsung.android.sdk.healthdata.HealthPermissionManager.*
*/
class SamsungHealth(
private val context: Activity
) : Connector() {
) : Extension() {
companion object {
const val TAG = "SamsungHealthConnector"

View File

@ -1,4 +1,4 @@
package com.dzeio.openhealth.connectors.samsunghealth
package com.dzeio.openhealth.extensions.samsunghealth
import android.os.Handler
import android.util.Log

View File

@ -1,32 +1,42 @@
package com.dzeio.openhealth.ui.main.home
package com.dzeio.openhealth.ui.home
import android.annotation.SuppressLint
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.commit
import android.widget.LinearLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.dzeio.openhealth.R
import com.dzeio.openhealth.core.BaseFragment
import com.dzeio.openhealth.data.weight.Water
import com.dzeio.openhealth.databinding.FragmentHomeBinding
import com.dzeio.openhealth.data.weight.Weight
import com.dzeio.openhealth.ui.dialogs.AddWeightDialog
import com.dzeio.openhealth.ui.main.list_weight.ListWeightFragment
import com.dzeio.openhealth.ui.weight.AddWeightDialog
import com.dzeio.openhealth.utils.BitmapUtils
import com.dzeio.openhealth.utils.DrawUtils
import com.github.mikephil.charting.components.AxisBase
import com.github.mikephil.charting.components.Description
import com.github.mikephil.charting.components.XAxis
import com.github.mikephil.charting.components.YAxis
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
import com.github.mikephil.charting.formatter.ValueFormatter
import com.google.android.material.color.MaterialColors
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList
@ -50,6 +60,54 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
AddWeightDialog().show(requireActivity().supportFragmentManager, null)
}
binding.fragmentHomeWaterAdd.setOnClickListener {
lifecycleScope.launchWhenStarted {
Log.d(TAG, "Collecting latest $this")
if (viewModel.fetchTodayWater().count() == 0) {
Log.d(TAG, "No value, Adding...")
val w = Water()
w.value = 200
viewModel.updateWater(w)
return@launchWhenStarted
}
try {
viewModel.fetchTodayWater().count()
val item = viewModel.fetchTodayWater().lastOrNull()
Log.d(TAG, "Collected latest $item")
if (item == null) {
val w = Water()
w.value = 200
viewModel.updateWater(w)
} else {
item.value += 200
viewModel.updateWater(item)
}
} catch (e: IOException) {
Log.e(TAG, "EXCEPTION", e)
}
}
}
binding.fragmentHomeWaterRemove.setOnClickListener {
lifecycleScope.launch {
val item = viewModel.fetchTodayWater().first()
Log.d(TAG, "Collected latest $it")
if (item != null) {
item.value -= 200
if (item.value == 0) {
viewModel.deleteWater(item)
} else {
viewModel.updateWater(item)
}
}
}
}
binding.listWeight.setOnClickListener {
Log.d("T", "Trying to move")
@ -106,7 +164,10 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
binding.weightGraph.axisRight.setDrawGridLines(false)
binding.weightGraph.xAxis.valueFormatter = object : ValueFormatter() {
override fun getAxisLabel(value: Float, axis: AxisBase?): String {
return SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date(value.toLong()))
return SimpleDateFormat(
"yyyy-MM-dd",
Locale.getDefault()
).format(Date(value.toLong()))
//return super.getAxisLabel(value, axis)
}
}
@ -121,6 +182,7 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
// )
}
@SuppressLint("PrivateResource")
override fun onStart() {
super.onStart()
@ -132,68 +194,48 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
updateGraph(it)
}
}
lifecycleScope.launchWhenStarted {
viewModel.fetchTodayWater().collect {
Log.d(TAG, "Pouet? $it")
if (it != null) {
updateWater(it.value)
} else {
updateWater(0)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
Log.d(TAG, "Activity Result!")
when (resultCode) {
RESULT_OK -> {
// fit.performActionForRequestCode(ActionRequestCode.FIND_DATA_SOURCES)
}
else -> {
Log.e(TAG, "Error: $requestCode, $resultCode")
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grantResults: IntArray) {
when {
grantResults.isEmpty() -> {
// If user interaction was interrupted, the permission request
// is cancelled and you receive empty arrays.
Log.i(TAG, "User interaction was cancelled.")
updateWater(0)
}
grantResults[0] == PackageManager.PERMISSION_GRANTED -> {
Log.d(TAG, "Granted")
// Permission was granted.
// val fitActionRequestCode = ActionRequestCode.values()[requestCode]
// fitActionRequestCode.let {
// // fit.signIn(ActionRequestCode.FIND_DATA_SOURCES)
// }
}
else -> {
// Permission denied.
private fun updateWater(water: Int) {
binding.fragmentHomeWaterCurrent.text = water.toString()
// In this Activity we've chosen to notify the user that they
// have rejected a core permission for the app since it makes the Activity useless.
// We're communicating this message in a Snackbar since this is a sample app, but
// core permissions would typically be best requested during a welcome-screen flow.
val graph = BitmapUtils.convertToMutable(
requireContext(),
BitmapFactory.decodeResource(resources, R.drawable.ellipse)
)
// Additionally, it is important to remember that a permission might have been
// rejected without asking the user for permission (device policy or "Never ask
// again" prompts). Therefore, a user interface affordance is typically implemented
// when permissions are denied. Otherwise, your app could appear unresponsive to
// touches or interactions which have required permissions.
Log.e(TAG, "Error")
// Snackbar.make(
// findViewById(R.id.main_activity_view),
// R.string.permission_denied_explanation,
// Snackbar.LENGTH_INDEFINITE)
// .setAction(R.string.settings) {
// // Build intent that displays the App settings screen.
// val intent = Intent()
// intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
// val uri = Uri.fromParts("package",
// BuildConfig.APPLICATION_ID, null)
// intent.data = uri
// intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
// startActivity(intent)
// }
// .show()
}
graph?.let { btmp ->
val canvas = Canvas(btmp)
DrawUtils.drawArc(
canvas,
100 * water / 1200,
MaterialColors.getColor(
requireView(),
com.google.android.material.R.attr.colorPrimary
)
)
canvas.save()
// val params = binding.background.layoutParams
// params.height = binding.background.measuredWidth
// binding.background.layoutParams = params
binding.background.setImageBitmap(graph)
}
}
}

View File

@ -1,14 +1,20 @@
package com.dzeio.openhealth.ui.main.home
package com.dzeio.openhealth.ui.home
import com.dzeio.openhealth.core.BaseViewModel
import com.dzeio.openhealth.data.weight.Water
import com.dzeio.openhealth.data.weight.WaterRepository
import com.dzeio.openhealth.data.weight.Weight
import com.dzeio.openhealth.data.weight.WeightRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.flow
import javax.inject.Inject
@HiltViewModel
class HomeViewModel @Inject internal constructor(
private val weightRepository: WeightRepository
private val weightRepository: WeightRepository,
private val waterRepository: WaterRepository
) : BaseViewModel() {
fun fetchWeights() = weightRepository.getWeights()
@ -20,4 +26,11 @@ class HomeViewModel @Inject internal constructor(
suspend fun deleteWeight(weight: Weight) = weightRepository.deleteWeight(weight)
suspend fun addWeight(weight: Weight) = weightRepository.addWeight(weight)
fun fetchTodayWater() = waterRepository.todayWater()
suspend fun updateWater(water: Water) = waterRepository.addWater(water)
suspend fun deleteWater(water: Water) = waterRepository.deleteWater(water)
}

View File

@ -1,4 +1,4 @@
package com.dzeio.openhealth.ui.main.imports
package com.dzeio.openhealth.ui.imports
import android.app.ProgressDialog
import android.content.Intent
@ -11,10 +11,10 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import androidx.lifecycle.lifecycleScope
import com.dzeio.openhealth.connectors.Connector
import com.dzeio.openhealth.connectors.GoogleFit
import com.dzeio.openhealth.extensions.Extension
import com.dzeio.openhealth.extensions.GoogleFit
//import com.dzeio.openhealth.connectors.GoogleFit
import com.dzeio.openhealth.connectors.samsunghealth.SamsungHealth
import com.dzeio.openhealth.extensions.samsunghealth.SamsungHealth
import com.dzeio.openhealth.core.BaseFragment
import com.dzeio.openhealth.databinding.FragmentImportBinding
import dagger.hilt.android.AndroidEntryPoint
@ -30,7 +30,7 @@ class ImportFragment : BaseFragment<ImportViewModel, FragmentImportBinding>(Impo
private lateinit var progressDialog: ProgressDialog
private lateinit var fit: Connector
private lateinit var fit: Extension
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -43,10 +43,8 @@ class ImportFragment : BaseFragment<ImportViewModel, FragmentImportBinding>(Impo
}
binding.importGoogleFit.setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
importFromGoogleFit()
}
}
binding.importSamsungHealth.setOnClickListener {
importFromSamsungHealth()
}

View File

@ -1,11 +1,10 @@
package com.dzeio.openhealth.ui.main.imports
package com.dzeio.openhealth.ui.imports
import androidx.lifecycle.MutableLiveData
import com.dzeio.openhealth.core.BaseViewModel
import com.dzeio.openhealth.data.weight.Weight
import com.dzeio.openhealth.data.weight.WeightRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import java.security.CodeSource
import javax.inject.Inject

View File

@ -0,0 +1,2 @@
package com.dzeio.openhealth.ui.water

View File

@ -1,6 +1,5 @@
package com.dzeio.openhealth.ui.dialogs
package com.dzeio.openhealth.ui.weight
import android.app.AlertDialog
import android.view.LayoutInflater
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
@ -8,7 +7,7 @@ import com.dzeio.openhealth.R
import com.dzeio.openhealth.core.BaseDialog
import com.dzeio.openhealth.data.weight.Weight
import com.dzeio.openhealth.databinding.DialogAddWeightBinding
import com.dzeio.openhealth.ui.main.home.HomeViewModel
import com.dzeio.openhealth.ui.home.HomeViewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect

View File

@ -1,17 +1,12 @@
package com.dzeio.openhealth.ui.dialogs
package com.dzeio.openhealth.ui.weight
import android.app.AlertDialog
import android.app.DatePickerDialog
import android.app.Dialog
import android.content.res.Resources
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.ViewGroup
import android.view.Window
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
@ -19,9 +14,8 @@ import androidx.navigation.fragment.navArgs
import com.dzeio.openhealth.R
import com.dzeio.openhealth.core.BaseFullscreenDialog
import com.dzeio.openhealth.data.weight.Weight
import com.dzeio.openhealth.databinding.DialogAddWeightBinding
import com.dzeio.openhealth.databinding.DialogEditWeightBinding
import com.dzeio.openhealth.ui.main.home.HomeViewModel
import com.dzeio.openhealth.ui.home.HomeViewModel
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.timepicker.MaterialTimePicker
@ -30,9 +24,11 @@ import kotlinx.coroutines.flow.collect
import java.util.*
@AndroidEntryPoint
class EditWeightDialog : BaseFullscreenDialog<HomeViewModel, DialogEditWeightBinding>(HomeViewModel::class.java) {
class EditWeightDialog :
BaseFullscreenDialog<HomeViewModel, DialogEditWeightBinding>(HomeViewModel::class.java) {
override val bindingInflater: (LayoutInflater) -> DialogEditWeightBinding = DialogEditWeightBinding::inflate
override val bindingInflater: (LayoutInflater) -> DialogEditWeightBinding =
DialogEditWeightBinding::inflate
override val isFullscreenLayout = true
@ -69,7 +65,8 @@ class EditWeightDialog : BaseFullscreenDialog<HomeViewModel, DialogEditWeightBin
viewModel.fetchWeight(args.id).collect {
weight = it!!
binding.layoutDialogEditWeightKg.value = it.weight.toInt()
binding.layoutDialogEditWeightGram.value = ((it.weight - it.weight.toInt()) * 10 ).toInt()
binding.layoutDialogEditWeightGram.value =
((it.weight - it.weight.toInt()) * 10).toInt()
binding.layoutDialogEditWeightTimestamp.setText(it.formatTimestamp())
}
@ -128,7 +125,8 @@ class EditWeightDialog : BaseFullscreenDialog<HomeViewModel, DialogEditWeightBin
private fun save() {
lifecycleScope.launchWhenCreated {
weight.weight = binding.layoutDialogEditWeightKg.value + (binding.layoutDialogEditWeightGram.value.toFloat() / 10)
weight.weight =
binding.layoutDialogEditWeightKg.value + (binding.layoutDialogEditWeightGram.value.toFloat() / 10)
viewModel.addWeight(weight)
findNavController().popBackStack()
}
@ -150,7 +148,12 @@ class EditWeightDialog : BaseFullscreenDialog<HomeViewModel, DialogEditWeightBin
findNavController().popBackStack()
}
}
.setIcon(ContextCompat.getDrawable(requireContext(), R.drawable.ic_outline_delete_24))
.setIcon(
ContextCompat.getDrawable(
requireContext(),
R.drawable.ic_outline_delete_24
)
)
.setNegativeButton("No") { _, _ -> }
.show()
true

View File

@ -1,28 +1,25 @@
package com.dzeio.openhealth.ui.main.list_weight
package com.dzeio.openhealth.ui.weight
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.dzeio.openhealth.adapters.WeightAdapter
import com.dzeio.openhealth.core.BaseFragment
import com.dzeio.openhealth.data.weight.Weight
import com.dzeio.openhealth.databinding.FragmentListWeightBinding
import com.dzeio.openhealth.ui.dialogs.EditWeightDialog
import com.dzeio.openhealth.ui.main.home.HomeViewModel
import com.dzeio.openhealth.ui.home.HomeViewModel
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import java.util.*
@AndroidEntryPoint
class ListWeightFragment : BaseFragment<HomeViewModel, FragmentListWeightBinding>(HomeViewModel::class.java) {
class ListWeightFragment :
BaseFragment<HomeViewModel, FragmentListWeightBinding>(HomeViewModel::class.java) {
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentListWeightBinding = FragmentListWeightBinding::inflate
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentListWeightBinding =
FragmentListWeightBinding::inflate
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@ -34,7 +31,11 @@ class ListWeightFragment : BaseFragment<HomeViewModel, FragmentListWeightBinding
val adapter = WeightAdapter()
adapter.onItemClick = {
findNavController().navigate(ListWeightFragmentDirections.actionNavListWeightToNavEditWeight(it.id))
findNavController().navigate(
ListWeightFragmentDirections.actionNavListWeightToNavEditWeight(
it.id
)
)
//EditWeightDialog().show(requireActivity().supportFragmentManager, "dialog")
}
recycler.adapter = adapter
@ -48,7 +49,5 @@ class ListWeightFragment : BaseFragment<HomeViewModel, FragmentListWeightBinding
}
}
}

View File

@ -0,0 +1,49 @@
package com.dzeio.openhealth.utils
import android.content.Context
import android.graphics.Bitmap
import java.io.File
import java.io.RandomAccessFile
import java.nio.channels.FileChannel
object BitmapUtils {
/**
* Find source of function lol
*/
fun convertToMutable(context: Context, imgIn: Bitmap): Bitmap? {
val width = imgIn.width
val height = imgIn.height
val type = imgIn.config
var outputFile: File? = null
val outputDir = context.cacheDir
try {
outputFile = File.createTempFile(
System.currentTimeMillis().toString(),
null,
outputDir
)
outputFile.deleteOnExit()
val randomAccessFile = RandomAccessFile(outputFile, "rw")
val channel = randomAccessFile.channel
val map = channel.map(
FileChannel.MapMode.READ_WRITE,
0,
(imgIn.rowBytes * height).toLong()
)
imgIn.copyPixelsToBuffer(map)
imgIn.recycle()
val result = Bitmap.createBitmap(width, height, type)
map.position(0)
result.copyPixelsFromBuffer(map)
channel.close()
randomAccessFile.close()
outputFile.delete()
return result
} catch (e: Exception) {
} finally {
outputFile?.delete()
}
return null
}
}

View File

@ -0,0 +1,30 @@
package com.dzeio.openhealth.utils
import android.graphics.*
object DrawUtils {
/**
* Fuck Graphics
*/
fun drawArc(canvas: Canvas, percent: Int, pColor: Int) {
canvas.width
val spacing = 120f
val r1 = RectF(
spacing,
spacing,
canvas.width - spacing,
canvas.height * 2 - spacing * 3
)
val paint = Paint()
paint.apply {
strokeWidth = 200f
style = Paint.Style.STROKE
color = pColor
isAntiAlias = true
strokeCap = Paint.Cap.ROUND
}
canvas.drawArc(r1, 180f, 180 * percent / 100f, false, paint)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="156dp"
android:height="81dp"
android:viewportWidth="156"
android:viewportHeight="81">
<path
android:pathData="M153,78C153,36.579 119.421,3 78,3C36.579,3 3,36.579 3,78"
android:strokeWidth="5"
android:fillColor="#00000000"
android:strokeColor="#C9C5CA"
android:strokeLineCap="round"/>
</vector>

View File

@ -1,10 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.home.HomeFragment">
android:orientation="vertical"
tools:context=".ui.home.HomeFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="2"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewFilledStyle"
@ -13,40 +20,173 @@
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:layout_weight="1">
<androidx.constraintlayout.widget.ConstraintLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout2"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="54dp"
android:layout_marginHorizontal="16dp"
android:gravity="fill_horizontal|center_vertical"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="16dp">
android:weightSum="2">
<TextView
style="@style/TextAppearance.Material3.TitleMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Weight"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:layout_weight="1" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginRight="16dp"
android:src="@drawable/ic_baseline_add_24" />
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_outline_hexagon_24" />
</LinearLayout>
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginBottom="8dp"
android:gravity="bottom"
android:weightSum="3">
<ImageView
android:id="@+id/fragment_home_water_remove"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginEnd="4dp"
android:layout_weight="1"
android:src="@drawable/ic_outline_hexagon_24"
app:layout_constraintBottom_toBottomOf="@+id/linearLayout"
app:layout_constraintEnd_toStartOf="@+id/linearLayout"
app:layout_constraintTop_toTopOf="@+id/linearLayout" />
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/background">
<TextView
android:id="@+id/fragment_home_water_current"
style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="900ml"
android:textAlignment="center" />
<TextView
android:id="@+id/fragment_home_water_total"
style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="1200ml"
android:textAlignment="center" />
</LinearLayout>
<ImageView
android:id="@+id/fragment_home_water_add"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginStart="4dp"
android:layout_weight="1"
android:src="@drawable/ic_baseline_add_24"
app:layout_constraintBottom_toBottomOf="@+id/linearLayout"
app:layout_constraintStart_toEndOf="@+id/linearLayout"
app:layout_constraintTop_toTopOf="@+id/linearLayout" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="2:1"
android:src="@drawable/ic_outline_hexagon_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<!-- Unused Currently -->
<!-- <com.google.android.material.card.MaterialCardView-->
<!-- style="?attr/materialCardViewFilledStyle"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginStart="16dp"-->
<!-- android:layout_marginTop="16dp"-->
<!-- android:layout_weight="1"-->
<!-- android:layout_marginEnd="16dp">-->
<!-- </com.google.android.material.card.MaterialCardView>-->
</LinearLayout>
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewFilledStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="54dp"
android:layout_marginHorizontal="16dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:weightSum="2">
<TextView
style="@style/TextAppearance.Material3.TitleMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Weight"
android:layout_weight="1" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end">
<ImageView
android:id="@+id/add_weight"
android:layout_width="24dp"
@ -58,24 +198,17 @@
android:id="@+id/list_weight"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_outline_hexagon_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:src="@drawable/ic_outline_hexagon_24" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/weight_graph"
android:layout_width="match_parent"
android:layout_height="200dp"
android:minHeight="200dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout2" />
android:minHeight="200dp" />
<!-- <com.jjoe64.graphview.GraphView-->
<!-- android:id="@+id/weight_graph"-->
@ -87,8 +220,8 @@
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@+id/constraintLayout2" />-->
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.imports.ImportFragment">
tools:context=".ui.imports.ImportFragment">
<TextView
android:id="@+id/text_slideshow"

View File

@ -11,4 +11,4 @@
android:padding="16dp"
tools:listitem="@layout/layout_item_weight"
tools:context=".ui.main.list_weight.ListWeightFragment" />
tools:context=".ui.weight.ListWeightFragment" />

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -7,7 +7,7 @@
<fragment
android:id="@+id/nav_home"
android:name="com.dzeio.openhealth.ui.main.home.HomeFragment"
android:name="com.dzeio.openhealth.ui.home.HomeFragment"
android:label="@string/menu_home"
tools:layout="@layout/fragment_home" >
<action
@ -28,13 +28,13 @@
<fragment
android:id="@+id/nav_import"
android:name="com.dzeio.openhealth.ui.main.imports.ImportFragment"
android:name="com.dzeio.openhealth.ui.imports.ImportFragment"
android:label="@string/menu_import"
tools:layout="@layout/fragment_import" />
<fragment
android:id="@+id/nav_list_weight"
android:name="com.dzeio.openhealth.ui.main.list_weight.ListWeightFragment"
android:name="com.dzeio.openhealth.ui.weight.ListWeightFragment"
android:label="@string/menu_list_weight"
tools:layout="@layout/fragment_list_weight" >
<action
@ -48,7 +48,7 @@
<fragment
android:id="@+id/nav_edit_weight"
android:name="com.dzeio.openhealth.ui.dialogs.EditWeightDialog"
android:name="com.dzeio.openhealth.ui.weight.EditWeightDialog"
android:label="@string/menu_edit_weight"
tools:layout="@layout/dialog_edit_weight">