mirror of
https://github.com/dzeiocom/OpenHealth.git
synced 2025-04-23 19:32:11 +00:00
Updated
This commit is contained in:
parent
8c33478e17
commit
e5615c9463
8
.idea/misc.xml
generated
8
.idea/misc.xml
generated
@ -3,9 +3,15 @@
|
|||||||
<component name="DesignSurface">
|
<component name="DesignSurface">
|
||||||
<option name="filePathToZoomLevelMap">
|
<option name="filePathToZoomLevelMap">
|
||||||
<map>
|
<map>
|
||||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_home.xml" value="0.33" />
|
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/drawable/ic_outline_hexagon_24.xml" value="0.3475" />
|
||||||
|
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/dialog_edit_weight.xml" value="0.5510416666666667" />
|
||||||
|
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_home.xml" value="0.67" />
|
||||||
<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/layout/fragment_import.xml" value="0.1" />
|
||||||
|
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_main_water_home.xml" value="0.5" />
|
||||||
|
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/layout_item_list.xml" value="0.5" />
|
||||||
|
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/layout_item_weight.xml" value="0.267983789260385" />
|
||||||
<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/activity_main_drawer.xml" value="0.10989583333333333" />
|
||||||
|
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/menu/fullscreen_dialog.xml" value="0.31197916666666664" />
|
||||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/menu/main.xml" value="0.1875" />
|
<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/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_ellipse_2.xml" value="0.4165" />
|
||||||
|
@ -23,19 +23,6 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.OpenHealth">
|
android:theme="@style/Theme.OpenHealth">
|
||||||
|
|
||||||
<receiver android:name=".services.BroadcastReceiver"
|
|
||||||
android:exported="false">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
|
||||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>
|
|
||||||
|
|
||||||
<!-- Water Intake -->
|
|
||||||
<service android:name=".services.WaterReminderService"
|
|
||||||
android:label="Water Intake service"
|
|
||||||
android:permission="android.permission.BIND_JOB_SERVICE" />
|
|
||||||
|
|
||||||
<!-- Samsung Health-->
|
<!-- Samsung Health-->
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="com.samsung.android.health.permission.read"
|
android:name="com.samsung.android.health.permission.read"
|
||||||
|
@ -15,8 +15,10 @@ import androidx.navigation.ui.AppBarConfiguration
|
|||||||
import androidx.navigation.ui.navigateUp
|
import androidx.navigation.ui.navigateUp
|
||||||
import androidx.navigation.ui.setupActionBarWithNavController
|
import androidx.navigation.ui.setupActionBarWithNavController
|
||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
|
import androidx.work.WorkManager
|
||||||
import com.dzeio.openhealth.core.BaseActivity
|
import com.dzeio.openhealth.core.BaseActivity
|
||||||
import com.dzeio.openhealth.databinding.ActivityMainBinding
|
import com.dzeio.openhealth.databinding.ActivityMainBinding
|
||||||
|
import com.dzeio.openhealth.interfaces.NotificationChannels
|
||||||
import com.dzeio.openhealth.services.WaterReminderService
|
import com.dzeio.openhealth.services.WaterReminderService
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
||||||
@ -27,14 +29,16 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
|
|
||||||
private lateinit var navController: NavController
|
private lateinit var navController: NavController
|
||||||
|
|
||||||
override val bindingInflater: (LayoutInflater) -> ActivityMainBinding = ActivityMainBinding::inflate
|
override val bindingInflater: (LayoutInflater) -> ActivityMainBinding =
|
||||||
|
ActivityMainBinding::inflate
|
||||||
|
|
||||||
override fun onCreated(savedInstanceState: Bundle?) {
|
override fun onCreated(savedInstanceState: Bundle?) {
|
||||||
super.onCreated(savedInstanceState)
|
super.onCreated(savedInstanceState)
|
||||||
|
|
||||||
setSupportActionBar(binding.toolbar)
|
setSupportActionBar(binding.toolbar)
|
||||||
|
|
||||||
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
val navHostFragment =
|
||||||
|
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
||||||
navController = navHostFragment.navController
|
navController = navHostFragment.navController
|
||||||
binding.navView.setupWithNavController(navController)
|
binding.navView.setupWithNavController(navController)
|
||||||
|
|
||||||
@ -46,9 +50,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
|
|
||||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||||
|
|
||||||
WaterReminderService.setup(this)
|
|
||||||
createNotificationChannel()
|
createNotificationChannel()
|
||||||
|
|
||||||
|
// Services
|
||||||
|
WorkManager.getInstance(this)
|
||||||
|
.cancelAllWork()
|
||||||
|
WaterReminderService.setup(this)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
@ -83,13 +91,21 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
private fun createNotificationChannel() {
|
private fun createNotificationChannel() {
|
||||||
// Create the NotificationChannel, but only on API 26+ because
|
// Create the NotificationChannel, but only on API 26+ because
|
||||||
// the NotificationChannel class is new and not in the support library
|
// the NotificationChannel class is new and not in the support library
|
||||||
|
|
||||||
|
val notificationManager: NotificationManager =
|
||||||
|
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val importance = NotificationManager.IMPORTANCE_DEFAULT
|
for (channel in NotificationChannels.values()) {
|
||||||
val channel = NotificationChannel("openhealth", "Default Channel", importance)
|
notificationManager.createNotificationChannel(
|
||||||
// Register the channel with the system
|
NotificationChannel(
|
||||||
val notificationManager: NotificationManager =
|
channel.id,
|
||||||
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
channel.channelName,
|
||||||
notificationManager.createNotificationChannel(channel)
|
channel.importance
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.dzeio.openhealth.adapters
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.dzeio.openhealth.core.BaseAdapter
|
||||||
|
import com.dzeio.openhealth.core.BaseViewHolder
|
||||||
|
import com.dzeio.openhealth.data.water.Water
|
||||||
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
|
import com.dzeio.openhealth.databinding.LayoutItemListBinding
|
||||||
|
import com.dzeio.openhealth.databinding.LayoutItemWeightBinding
|
||||||
|
|
||||||
|
class WaterAdapter() : BaseAdapter<Water, LayoutItemListBinding>() {
|
||||||
|
|
||||||
|
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> LayoutItemListBinding
|
||||||
|
get() = LayoutItemListBinding::inflate
|
||||||
|
|
||||||
|
var onItemClick: ((weight: Water) -> Unit)? = null
|
||||||
|
|
||||||
|
override fun onBindData(
|
||||||
|
holder: BaseViewHolder<LayoutItemListBinding>,
|
||||||
|
item: Water,
|
||||||
|
position: Int
|
||||||
|
) {
|
||||||
|
holder.binding.value.text = "${item.value}ml"
|
||||||
|
holder.binding.datetime.text = item.formatTimestamp()
|
||||||
|
holder.binding.edit.setOnClickListener {
|
||||||
|
onItemClick?.invoke(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,8 @@ import android.content.Context
|
|||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import com.dzeio.openhealth.data.weight.Water
|
import com.dzeio.openhealth.data.water.Water
|
||||||
import com.dzeio.openhealth.data.weight.WaterDao
|
import com.dzeio.openhealth.data.water.WaterDao
|
||||||
import com.dzeio.openhealth.data.weight.WeightDao
|
import com.dzeio.openhealth.data.weight.WeightDao
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.dzeio.openhealth.data.weight
|
package com.dzeio.openhealth.data.water
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
@ -12,23 +12,25 @@ data class Water(
|
|||||||
@PrimaryKey(autoGenerate = true) var id: Long = 0,
|
@PrimaryKey(autoGenerate = true) var id: Long = 0,
|
||||||
var value: Int = 0,
|
var value: Int = 0,
|
||||||
@ColumnInfo(index = true)
|
@ColumnInfo(index = true)
|
||||||
var timestamp: Long = System.currentTimeMillis(),
|
var timestamp: Long = 0,
|
||||||
var source: String = "OpenHealth"
|
var source: String = "OpenHealth"
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
val cal = Calendar.getInstance()
|
if (timestamp == (0).toLong()) {
|
||||||
cal.set(Calendar.HOUR_OF_DAY, 0)
|
val cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
|
||||||
cal.set(Calendar.MINUTE, 0)
|
cal.set(Calendar.HOUR_OF_DAY, 0)
|
||||||
cal.set(Calendar.SECOND, 0)
|
cal.set(Calendar.MINUTE, 0)
|
||||||
cal.set(Calendar.MILLISECOND, 0)
|
cal.set(Calendar.SECOND, 0)
|
||||||
|
cal.set(Calendar.MILLISECOND, 0)
|
||||||
|
|
||||||
timestamp = cal.timeInMillis
|
timestamp = cal.timeInMillis
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun formatTimestamp(): String = getDateInstance().format(Date(timestamp))
|
fun formatTimestamp(): String = getDateInstance().format(Date(timestamp))
|
||||||
|
|
||||||
fun isToday(): Boolean {
|
fun isToday(): Boolean {
|
||||||
val cal = Calendar.getInstance()
|
val cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
|
||||||
cal.set(Calendar.HOUR_OF_DAY, 0)
|
cal.set(Calendar.HOUR_OF_DAY, 0)
|
||||||
cal.set(Calendar.MINUTE, 0)
|
cal.set(Calendar.MINUTE, 0)
|
||||||
cal.set(Calendar.SECOND, 0)
|
cal.set(Calendar.SECOND, 0)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.dzeio.openhealth.data.weight
|
package com.dzeio.openhealth.data.water
|
||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
import com.dzeio.openhealth.core.BaseDao
|
import com.dzeio.openhealth.core.BaseDao
|
||||||
@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
@Dao
|
@Dao
|
||||||
interface WaterDao : BaseDao<Water> {
|
interface WaterDao : BaseDao<Water> {
|
||||||
|
|
||||||
@Query("SELECT * FROM Water")
|
@Query("SELECT * FROM Water ORDER BY timestamp")
|
||||||
fun getAll(): Flow<List<Water>>
|
fun getAll(): Flow<List<Water>>
|
||||||
|
|
||||||
@Query("SELECT * FROM Water where id = :weightId")
|
@Query("SELECT * FROM Water where id = :weightId")
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.dzeio.openhealth.data.weight
|
package com.dzeio.openhealth.data.water
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
|
@ -2,7 +2,7 @@ package com.dzeio.openhealth.di
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dzeio.openhealth.data.AppDatabase
|
import com.dzeio.openhealth.data.AppDatabase
|
||||||
import com.dzeio.openhealth.data.weight.WaterDao
|
import com.dzeio.openhealth.data.water.WaterDao
|
||||||
import com.dzeio.openhealth.data.weight.WeightDao
|
import com.dzeio.openhealth.data.weight.WeightDao
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.dzeio.openhealth.interfaces
|
||||||
|
|
||||||
|
import android.app.NotificationManager
|
||||||
|
|
||||||
|
enum class NotificationChannels(
|
||||||
|
val id: String,
|
||||||
|
val channelName: String,
|
||||||
|
val importance: Int
|
||||||
|
) {
|
||||||
|
// 3 is IMPORTANCE_DEFAULT
|
||||||
|
DEFAULT("default", "Default Channel", 3)
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.dzeio.openhealth.interfaces
|
||||||
|
|
||||||
|
enum class NotificationIds {
|
||||||
|
WaterIntake
|
||||||
|
}
|
@ -1,18 +0,0 @@
|
|||||||
package com.dzeio.openhealth.services
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.BroadcastReceiver
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.util.Log
|
|
||||||
|
|
||||||
class BroadcastReceiver : BroadcastReceiver() {
|
|
||||||
@SuppressLint("UnsafeProtectedBroadcastReceiver")
|
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
|
||||||
context?.let {
|
|
||||||
WaterReminderService.setup(it)
|
|
||||||
Log.d("OpenHealth/BR", "Scheduled Jobs!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -14,6 +14,8 @@ import com.dzeio.openhealth.Application
|
|||||||
import com.dzeio.openhealth.MainActivity
|
import com.dzeio.openhealth.MainActivity
|
||||||
import com.dzeio.openhealth.R
|
import com.dzeio.openhealth.R
|
||||||
import com.dzeio.openhealth.core.BaseService
|
import com.dzeio.openhealth.core.BaseService
|
||||||
|
import com.dzeio.openhealth.interfaces.NotificationChannels
|
||||||
|
import com.dzeio.openhealth.interfaces.NotificationIds
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@ -27,7 +29,7 @@ class WaterReminderService(
|
|||||||
fun setup(context: Context) {
|
fun setup(context: Context) {
|
||||||
schedule(
|
schedule(
|
||||||
TAG,
|
TAG,
|
||||||
PeriodicWorkRequestBuilder<WaterReminderService>(15, TimeUnit.MINUTES)
|
PeriodicWorkRequestBuilder<WaterReminderService>(1, TimeUnit.HOURS)
|
||||||
.addTag(TAG)
|
.addTag(TAG)
|
||||||
.build(),
|
.build(),
|
||||||
context
|
context
|
||||||
@ -39,48 +41,29 @@ class WaterReminderService(
|
|||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
Log.d(TAG, "Ran! ${Date().toLocaleString()}")
|
Log.d(TAG, "Ran! ${Date().toLocaleString()}")
|
||||||
with(NotificationManagerCompat.from(context)) {
|
with(NotificationManagerCompat.from(context)) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
val flag =
|
||||||
notify(
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0
|
||||||
(Math.random() * 100).toInt(), NotificationCompat.Builder(context, "openhealth")
|
val builder =
|
||||||
.setContentTitle("Did you drink?")
|
NotificationCompat.Builder(context, NotificationChannels.DEFAULT.channelName)
|
||||||
.setContentText("Drink now!")
|
.setContentTitle("Did you drink?")
|
||||||
.setSmallIcon(R.drawable.ic_logo_small)
|
.setContentText("Drink now! ${Date().toLocaleString()}")
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
.setSmallIcon(R.drawable.ic_logo_small)
|
||||||
.setContentIntent(
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
PendingIntent.getActivity(
|
.setContentIntent(
|
||||||
context,
|
PendingIntent.getActivity(
|
||||||
0,
|
context,
|
||||||
Intent(context, MainActivity::class.java).apply {
|
0,
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
Intent(context, MainActivity::class.java).apply {
|
||||||
},
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
PendingIntent.FLAG_IMMUTABLE
|
},
|
||||||
)
|
flag
|
||||||
)
|
)
|
||||||
.build()
|
).build()
|
||||||
)
|
notify(
|
||||||
} else {
|
NotificationIds.WaterIntake.ordinal,
|
||||||
notify(
|
builder
|
||||||
(Math.random() * 100).toInt(), NotificationCompat.Builder(context, "openhealth")
|
)
|
||||||
.setContentTitle("Did you drink?")
|
|
||||||
.setContentText("Drink now!")
|
|
||||||
.setSmallIcon(R.drawable.ic_logo_small)
|
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
||||||
.setContentIntent(
|
|
||||||
PendingIntent.getActivity(
|
|
||||||
context,
|
|
||||||
0,
|
|
||||||
Intent(context, MainActivity::class.java).apply {
|
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
},
|
|
||||||
0
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Result.success()
|
return Result.success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -11,9 +11,10 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.dzeio.openhealth.Application
|
||||||
import com.dzeio.openhealth.R
|
import com.dzeio.openhealth.R
|
||||||
import com.dzeio.openhealth.core.BaseFragment
|
import com.dzeio.openhealth.core.BaseFragment
|
||||||
import com.dzeio.openhealth.data.weight.Water
|
import com.dzeio.openhealth.data.water.Water
|
||||||
import com.dzeio.openhealth.databinding.FragmentHomeBinding
|
import com.dzeio.openhealth.databinding.FragmentHomeBinding
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
import com.dzeio.openhealth.ui.weight.AddWeightDialog
|
import com.dzeio.openhealth.ui.weight.AddWeightDialog
|
||||||
@ -39,14 +40,12 @@ import kotlin.math.min
|
|||||||
class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewModel::class.java) {
|
class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewModel::class.java) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "HomeFragment"
|
const val TAG = "${Application.TAG}/HomeFragment"
|
||||||
}
|
}
|
||||||
|
|
||||||
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentHomeBinding
|
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentHomeBinding
|
||||||
get() = FragmentHomeBinding::inflate
|
get() = FragmentHomeBinding::inflate
|
||||||
|
|
||||||
// private lateinit var fit: GoogleFit
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
@ -107,99 +106,62 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
|
|||||||
Log.d("T", "Trying to move")
|
Log.d("T", "Trying to move")
|
||||||
|
|
||||||
findNavController().navigate(HomeFragmentDirections.actionNavHomeToNavListWeight())
|
findNavController().navigate(HomeFragmentDirections.actionNavHomeToNavListWeight())
|
||||||
|
|
||||||
// requireActivity().supportFragmentManager.commit {
|
|
||||||
// replace(R.id.nav_host_fragment_content_main, ListWeightFragment())
|
|
||||||
// addToBackStack(null)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup Graph
|
binding.gotoWaterHome.setOnClickListener {
|
||||||
// binding.weightGraph.apply {
|
findNavController().navigate(HomeFragmentDirections.actionNavHomeToNavWaterHome())
|
||||||
// gridLabelRenderer.labelFormatter = DateAsXAxisLabelFormatter(
|
}
|
||||||
// requireContext(),
|
|
||||||
// DateFormat.getDateInstance(DateFormat.MEDIUM)
|
|
||||||
// )
|
|
||||||
// gridLabelRenderer.numHorizontalLabels = 3 // only 4 because of the space
|
|
||||||
// gridLabelRenderer.numVerticalLabels = 3
|
|
||||||
// gridLabelRenderer.gridStyle = GridLabelRenderer.GridStyle.HORIZONTAL
|
|
||||||
// viewport.isXAxisBoundsManual = true
|
|
||||||
// viewport.isScalable = true
|
|
||||||
// viewport.setScalableY(true)
|
|
||||||
// viewport.isScrollable = true
|
|
||||||
// viewport.setScrollableY(true)
|
|
||||||
// gridLabelRenderer.setHumanRounding(false);
|
|
||||||
// addSeries(serie)
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// private val serie: LineGraphSeries<DataPoint> = LineGraphSeries()
|
|
||||||
// private val entries = LineGraphSeries<DataPoint>()
|
|
||||||
|
|
||||||
private fun updateGraph(list: List<Weight>) {
|
private fun updateGraph(list: List<Weight>) {
|
||||||
if (list.isNotEmpty()) {
|
if (list.isNotEmpty()) {
|
||||||
val first = list[0].timestamp
|
|
||||||
val last = list[list.size - 1].timestamp
|
|
||||||
val weekFirst = last - 604800000
|
|
||||||
// binding.weightGraph.viewport.setMinX(if (first > weekFirst) first else weekFirst)
|
|
||||||
// binding.weightGraph.viewport.setMaxX(last);
|
|
||||||
|
|
||||||
|
|
||||||
val entries = ArrayList<Entry>()
|
val entries = ArrayList<Entry>()
|
||||||
for (item in list) {
|
for (item in list) {
|
||||||
entries.add(Entry(item.timestamp.toFloat(), item.weight))
|
entries.add(Entry(item.timestamp.toFloat(), item.weight))
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataSet = LineDataSet(entries, "Label")
|
val dataSet = LineDataSet(entries, "Label")
|
||||||
// binding.weightGraph.xAxis.axisMinimum = if (first > weekFirst) first.toFloat() else weekFirst.toFloat()
|
binding.weightGraph.apply {
|
||||||
// binding.weightGraph.setExtraOffsets(
|
|
||||||
// if (first > weekFirst) first.toFloat() else weekFirst.toFloat(),
|
// Setup
|
||||||
// 100f,
|
isAutoScaleMinMaxEnabled = true
|
||||||
// last.toFloat(),
|
legend.isEnabled = false
|
||||||
// 0f
|
isDragEnabled = true
|
||||||
// )
|
isScaleYEnabled = false
|
||||||
binding.weightGraph.isAutoScaleMinMaxEnabled = true
|
description = Description().apply { isEnabled = false }
|
||||||
//binding.weightGraph.setvir
|
isScaleXEnabled = true
|
||||||
binding.weightGraph.isDragEnabled = true
|
setPinchZoom(false)
|
||||||
binding.weightGraph.isScaleYEnabled = false
|
axisLeft.setLabelCount(0, true)
|
||||||
binding.weightGraph.description = Description().apply { isEnabled = false }
|
setDrawBorders(false)
|
||||||
binding.weightGraph.isScaleXEnabled = true
|
|
||||||
binding.weightGraph.setPinchZoom(false)
|
xAxis.apply {
|
||||||
binding.weightGraph.xAxis.setLabelCount(5, true)
|
valueFormatter = object : ValueFormatter() {
|
||||||
binding.weightGraph.xAxis.position = XAxis.XAxisPosition.BOTTOM
|
override fun getAxisLabel(value: Float, axis: AxisBase?): String {
|
||||||
binding.weightGraph.axisRight.isEnabled = false
|
return SimpleDateFormat(
|
||||||
binding.weightGraph.axisRight.setDrawGridLines(false)
|
"yyyy-MM-dd",
|
||||||
binding.weightGraph.xAxis.valueFormatter = object : ValueFormatter() {
|
Locale.getDefault()
|
||||||
override fun getAxisLabel(value: Float, axis: AxisBase?): String {
|
).format(Date(value.toLong()))
|
||||||
return SimpleDateFormat(
|
//return super.getAxisLabel(value, axis)
|
||||||
"yyyy-MM-dd",
|
}
|
||||||
Locale.getDefault()
|
}
|
||||||
).format(Date(value.toLong()))
|
position = XAxis.XAxisPosition.BOTTOM
|
||||||
//return super.getAxisLabel(value, axis)
|
setDrawGridLines(false)
|
||||||
|
setLabelCount(3, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply new dataset
|
||||||
|
data = LineData(dataSet)
|
||||||
|
|
||||||
|
// idk what I did but it works lol
|
||||||
|
setVisibleXRange(
|
||||||
|
0f, entries[entries.size - 1].x / 1000f
|
||||||
|
)
|
||||||
|
|
||||||
|
// BIS... :(
|
||||||
|
// Also it invalidate the view so I don't have to call invalidate
|
||||||
|
moveViewToX(entries[entries.size - 1].x - 1600000000f)
|
||||||
}
|
}
|
||||||
binding.weightGraph.data = LineData(dataSet)
|
|
||||||
binding.weightGraph.invalidate()
|
|
||||||
binding.weightGraph.setVisibleXRange(
|
|
||||||
(list[list.size - 1].timestamp - 604800000).toFloat(),
|
|
||||||
list[list.size - 1].timestamp.toFloat()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// binding.weightGraph.gridLabelRenderer.numHorizontalLabels = 3 // only 4 because of the space
|
|
||||||
// binding.weightGraph.gridLabelRenderer.numVerticalLabels = 3
|
|
||||||
//
|
|
||||||
// binding.weightGraph.viewport.maxXAxisSize = 604800000.0 * 2
|
|
||||||
//// binding.weightGraph.viewport.setMinimalViewport(0.0, 604800000.0, minValue.toDouble(), maxValue.toDouble())
|
|
||||||
//
|
|
||||||
// serie.resetData(list
|
|
||||||
// .map { DataPoint(Date(it.timestamp), it.weight.toDouble()) }
|
|
||||||
// .toTypedArray())
|
|
||||||
//
|
|
||||||
// binding.weightGraph.viewport.scrollToEnd()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
@ -212,6 +174,7 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewModel.water.observe(viewLifecycleOwner) {
|
viewModel.water.observe(viewLifecycleOwner) {
|
||||||
|
Log.d(TAG, "${it?.formatTimestamp()} $it")
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
updateWater(it.value)
|
updateWater(it.value)
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,8 +4,8 @@ import androidx.lifecycle.LiveData
|
|||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.dzeio.openhealth.core.BaseViewModel
|
import com.dzeio.openhealth.core.BaseViewModel
|
||||||
import com.dzeio.openhealth.data.weight.Water
|
import com.dzeio.openhealth.data.water.Water
|
||||||
import com.dzeio.openhealth.data.weight.WaterRepository
|
import com.dzeio.openhealth.data.water.WaterRepository
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
import com.dzeio.openhealth.data.weight.WeightRepository
|
import com.dzeio.openhealth.data.weight.WeightRepository
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
@ -1,2 +1,52 @@
|
|||||||
package com.dzeio.openhealth.ui.water
|
package com.dzeio.openhealth.ui.water
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.dzeio.openhealth.adapters.WaterAdapter
|
||||||
|
import com.dzeio.openhealth.adapters.WeightAdapter
|
||||||
|
import com.dzeio.openhealth.core.BaseFragment
|
||||||
|
import com.dzeio.openhealth.databinding.FragmentListWeightBinding
|
||||||
|
import com.dzeio.openhealth.databinding.FragmentMainWaterHomeBinding
|
||||||
|
import com.dzeio.openhealth.ui.home.HomeViewModel
|
||||||
|
import com.dzeio.openhealth.ui.weight.ListWeightFragmentDirections
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class WaterHomeFragment :
|
||||||
|
BaseFragment<WaterHomeViewModel, FragmentMainWaterHomeBinding>(WaterHomeViewModel::class.java) {
|
||||||
|
|
||||||
|
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentMainWaterHomeBinding =
|
||||||
|
FragmentMainWaterHomeBinding::inflate
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
viewModel.init()
|
||||||
|
|
||||||
|
val recycler = binding.list
|
||||||
|
|
||||||
|
val manager = LinearLayoutManager(requireContext())
|
||||||
|
recycler.layoutManager = manager
|
||||||
|
|
||||||
|
val adapter = WaterAdapter()
|
||||||
|
adapter.onItemClick = {
|
||||||
|
findNavController().navigate(
|
||||||
|
ListWeightFragmentDirections.actionNavListWeightToNavEditWeight(
|
||||||
|
it.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
//EditWeightDialog().show(requireActivity().supportFragmentManager, "dialog")
|
||||||
|
}
|
||||||
|
recycler.adapter = adapter
|
||||||
|
|
||||||
|
viewModel.items.observe(viewLifecycleOwner) {
|
||||||
|
adapter.set(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.dzeio.openhealth.ui.water
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.dzeio.openhealth.core.BaseViewModel
|
||||||
|
import com.dzeio.openhealth.data.water.Water
|
||||||
|
import com.dzeio.openhealth.data.water.WaterRepository
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class WaterHomeViewModel@Inject internal constructor(
|
||||||
|
private val waterRepository: WaterRepository
|
||||||
|
) : BaseViewModel() {
|
||||||
|
val items: MutableLiveData<List<Water>> = MutableLiveData()
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
waterRepository.getWaters().collectLatest {
|
||||||
|
items.postValue(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,9 +2,9 @@
|
|||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24"
|
android:viewportHeight="24">
|
||||||
android:tint="?attr/colorControlNormal">
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="@android:color/white"
|
android:pathData="M12.0001,1.7144L20.9078,6.8572V17.1429L12.0001,22.2858L3.0924,17.1429V6.8572L12.0001,1.7144Z"
|
||||||
android:pathData="M17.2,3H6.8l-5.2,9l5.2,9h10.4l5.2,-9L17.2,3zM16.05,19H7.95l-4.04,-7l4.04,-7h8.09l4.04,7L16.05,19z"/>
|
android:strokeWidth="2"
|
||||||
|
android:strokeColor="@android:color/white"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
android:src="@drawable/ic_baseline_add_24" />
|
android:src="@drawable/ic_baseline_add_24" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
android:id="@+id/goto_water_home"
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:src="@drawable/ic_outline_hexagon_24" />
|
android:src="@drawable/ic_outline_hexagon_24" />
|
||||||
|
62
app/src/main/res/layout/fragment_main_water_home.xml
Normal file
62
app/src/main/res/layout/fragment_main_water_home.xml
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<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"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".ui.water.WaterHomeFragment">
|
||||||
|
|
||||||
|
<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">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<com.github.mikephil.charting.charts.LineChart
|
||||||
|
android:id="@+id/chart"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:minHeight="200dp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginVertical="16dp"
|
||||||
|
android:gravity="end"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:weightSum="2">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/button_edit_default_intake"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
style="?attr/materialButtonOutlinedStyle"
|
||||||
|
android:text="Modify Default Intake" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:id="@+id/list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
|
||||||
|
tools:listitem="@layout/layout_item_weight" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
50
app/src/main/res/layout/layout_item_list.xml
Normal file
50
app/src/main/res/layout/layout_item_list.xml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
style="?attr/materialCardViewFilledStyle"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:id="@+id/edit"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:weightSum="1">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/value"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="xkg" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/datetime"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="Taken: yyyy-mm-dd" />
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/ic_baseline_edit_24" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
@ -24,6 +24,9 @@
|
|||||||
app:exitAnim="@android:anim/slide_out_right"
|
app:exitAnim="@android:anim/slide_out_right"
|
||||||
app:popEnterAnim="@android:anim/slide_in_left"
|
app:popEnterAnim="@android:anim/slide_in_left"
|
||||||
app:popExitAnim="@android:anim/slide_out_right" />
|
app:popExitAnim="@android:anim/slide_out_right" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_nav_home_to_nav_water_home"
|
||||||
|
app:destination="@id/nav_water_home" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
@ -57,4 +60,12 @@
|
|||||||
app:argType="long" />
|
app:argType="long" />
|
||||||
|
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/nav_water_home"
|
||||||
|
android:name="com.dzeio.openhealth.ui.water.WaterHomeFragment"
|
||||||
|
android:label="@string/nav_water_home"
|
||||||
|
tools:layout="@layout/fragment_water_home">
|
||||||
|
|
||||||
|
</fragment>
|
||||||
</navigation>
|
</navigation>
|
@ -13,4 +13,6 @@
|
|||||||
<string name="menu_import">Import</string>
|
<string name="menu_import">Import</string>
|
||||||
<string name="menu_list_weight">Weight List</string>
|
<string name="menu_list_weight">Weight List</string>
|
||||||
<string name="menu_edit_weight">Edit Weight</string>
|
<string name="menu_edit_weight">Edit Weight</string>
|
||||||
|
<string name="nav_list_water">Water Intake</string>
|
||||||
|
<string name="nav_water_home">Water Intake</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user