MrOzOn преди 5 години
родител
ревизия
69c4581b94

+ 3 - 0
core_api/src/main/java/com/mrozon/core_api/db/dao/MeasureTypeDao.kt

@@ -23,4 +23,7 @@ interface MeasureTypeDao {
     @Query("SELECT * FROM measure_type_table")
     fun getMeasureTypes(): Flow<List<MeasureTypeDb>>
 
+    @Query("SELECT * FROM measure_type_table")
+    fun getListMeasureTypes(): List<MeasureTypeDb>
+
 }

+ 2 - 1
feature_measure/src/main/java/com/mrozon/feature_measure/data/MeasureRepository.kt

@@ -1,10 +1,11 @@
 package com.mrozon.feature_measure.data
 
+import com.mrozon.core_api.entity.MeasureType
 import com.mrozon.core_api.entity.Person
 import com.mrozon.utils.network.Result
 import kotlinx.coroutines.flow.Flow
 
 interface MeasureRepository {
 
-    fun getPerson(id: Long): Flow<Result<Person>>
+    fun loadProfilePersonAndMeasureTypes(id: Long): Flow<Result<Pair<Person,List<MeasureType>>>>
 }

+ 8 - 4
feature_measure/src/main/java/com/mrozon/feature_measure/data/MeasureRepositoryImpl.kt

@@ -1,7 +1,9 @@
 package com.mrozon.feature_measure.data
 
 import com.mrozon.core_api.db.HealthDiaryDao
+import com.mrozon.core_api.entity.MeasureType
 import com.mrozon.core_api.entity.Person
+import com.mrozon.core_api.mapper.MeasureTypeToMeasureTypeDbMapper
 import com.mrozon.core_api.mapper.PersonToPersonDbMapper
 import com.mrozon.utils.network.Result
 import kotlinx.coroutines.flow.Flow
@@ -12,15 +14,17 @@ import javax.inject.Singleton
 @Singleton
 class MeasureRepositoryImpl @Inject constructor(
     private val dao: HealthDiaryDao,
-    private val mapper: PersonToPersonDbMapper
+    private val mapperPerson: PersonToPersonDbMapper,
+    private val mapperMeasureType: MeasureTypeToMeasureTypeDbMapper
 ): MeasureRepository {
 
-    override fun getPerson(id: Long): Flow<Result<Person>> {
+    override fun loadProfilePersonAndMeasureTypes(id: Long): Flow<Result<Pair<Person, List<MeasureType>>>> {
         return flow {
             emit(Result.loading())
             try {
-                val response = dao.getPerson(id)
-                emit(Result.success(mapper.reverseMap(response)!!))
+                val person = mapperPerson.reverseMap(dao.getPerson(id))
+                val measureTypes = mapperMeasureType.reverseMap(dao.getListMeasureTypes())
+                emit(Result.success(Pair(person!!, measureTypes)))
             }
             catch (e: Exception){
                 emit(Result.error(e.message!!))

+ 9 - 0
feature_measure/src/main/java/com/mrozon/feature_measure/di/TabMeasureFragmentComponent.kt

@@ -2,6 +2,7 @@ package com.mrozon.feature_measure.di
 
 import com.mrozon.core_api.providers.AppWithFacade
 import com.mrozon.core_api.providers.ProvidersFacade
+import com.mrozon.feature_measure.presentation.ListMeasureFragment
 import com.mrozon.feature_measure.presentation.TabMeasureFragment
 import dagger.Component
 import javax.inject.Singleton
@@ -25,8 +26,16 @@ interface TabMeasureFragmentComponent {
             component.inject(fragment)
             return component
         }
+
+        fun injectFragment(fragment: ListMeasureFragment): TabMeasureFragmentComponent  {
+            val component = create((fragment.activity?.application
+                    as AppWithFacade).getFacade())
+            component.inject(fragment)
+            return component
+        }
     }
 
     fun inject(fragment: TabMeasureFragment)
+    fun inject(fragment: ListMeasureFragment)
 
 }

+ 7 - 1
feature_measure/src/main/java/com/mrozon/feature_measure/di/TabMeasureFragmentModule.kt

@@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModelProvider
 import com.mrozon.core_api.viewmodel.ViewModelKey
 import com.mrozon.feature_measure.data.MeasureRepository
 import com.mrozon.feature_measure.data.MeasureRepositoryImpl
+import com.mrozon.feature_measure.presentation.ListMeasureFragmentViewModel
 import com.mrozon.feature_measure.presentation.TabMeasureFragmentViewModel
 import dagger.Binds
 import dagger.Module
@@ -15,7 +16,12 @@ interface TabMeasureFragmentModule {
     @Binds
     @IntoMap
     @ViewModelKey(TabMeasureFragmentViewModel::class)
-    fun bindViewModel(viewmodel: TabMeasureFragmentViewModel): ViewModel
+    fun bindTabMeasureFragmentViewModel(viewmodel: TabMeasureFragmentViewModel): ViewModel
+
+    @Binds
+    @IntoMap
+    @ViewModelKey(ListMeasureFragmentViewModel::class)
+    fun bindListMeasureFragmentViewModel(viewmodel: ListMeasureFragmentViewModel): ViewModel
 
     @Binds
     fun viewModelFactory(factory: DaggerViewModelFactory): ViewModelProvider.Factory

+ 47 - 0
feature_measure/src/main/java/com/mrozon/feature_measure/presentation/ListMeasureFragment.kt

@@ -0,0 +1,47 @@
+package com.mrozon.feature_measure.presentation
+
+import android.content.Context
+import android.os.Bundle
+import androidx.fragment.app.viewModels
+import androidx.lifecycle.ViewModelProvider
+import com.mrozon.feature_measure.R
+import com.mrozon.feature_measure.databinding.FragmentListMeasureBinding
+import com.mrozon.feature_measure.di.TabMeasureFragmentComponent
+import com.mrozon.utils.base.BaseFragment
+import timber.log.Timber
+import javax.inject.Inject
+
+class ListMeasureFragment : BaseFragment<FragmentListMeasureBinding>() {
+
+    companion object {
+        private const val ARG_PERSON_ID = "person_id"
+        private const val ARG_MEASURE_TYPE_ID = "measure_type_id"
+
+        fun getInstance(personId: Long, measureTypeId: Long): ListMeasureFragment {
+            val fragment = ListMeasureFragment()
+            fragment.arguments = Bundle().apply {
+                putLong(ARG_PERSON_ID, personId)
+                putLong(ARG_MEASURE_TYPE_ID, measureTypeId)
+            }
+            return fragment
+        }
+    }
+
+    override fun getLayoutId(): Int = R.layout.fragment_list_measure
+
+    @Inject
+    lateinit var viewModelFactory: ViewModelProvider.Factory
+
+    private val viewModel by viewModels<ListMeasureFragmentViewModel> { viewModelFactory }
+
+    override fun onAttach(context: Context) {
+        super.onAttach(context)
+        TabMeasureFragmentComponent.injectFragment(this)
+        Timber.d("onAttach")
+    }
+
+    override fun subscribeUi() {
+
+    }
+
+}

+ 23 - 0
feature_measure/src/main/java/com/mrozon/feature_measure/presentation/ListMeasureFragmentViewModel.kt

@@ -0,0 +1,23 @@
+package com.mrozon.feature_measure.presentation
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.viewModelScope
+import com.mrozon.core_api.entity.Person
+import com.mrozon.core_api.providers.CoroutineContextProvider
+import com.mrozon.feature_measure.data.MeasureRepository
+import com.mrozon.utils.Event
+import com.mrozon.utils.base.BaseViewModel
+import com.mrozon.utils.network.Result
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import javax.inject.Inject
+
+class ListMeasureFragmentViewModel @Inject constructor(
+    private val repository: MeasureRepository,
+    private val coroutineContextProvider: CoroutineContextProvider
+): BaseViewModel() {
+
+
+}

+ 2 - 7
feature_measure/src/main/java/com/mrozon/feature_measure/presentation/TabMeasureAdapter.kt

@@ -12,12 +12,7 @@ class TabMeasureAdapter(
     override fun getItemCount(): Int = measureTypes.size
 
     override fun createFragment(position: Int): Fragment {
-//        val fragment = DemoObjectFragment()
-//        fragment.arguments = Bundle().apply {
-//            // Our object is just an integer :-P
-//            putInt(ARG_OBJECT, position + 1)
-//        }
-//        return fragment
-        TODO("Not yet implemented createFragment for current Measure for current person")
+        val id = measureTypes[position].id
+        return ListMeasureFragment.getInstance(personId, id)
     }
 }

+ 39 - 13
feature_measure/src/main/java/com/mrozon/feature_measure/presentation/TabMeasureFragment.kt

@@ -12,11 +12,18 @@ import androidx.lifecycle.Observer
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.observe
 import androidx.viewpager2.adapter.FragmentStateAdapter
+import coil.ImageLoader
+import coil.decode.SvgDecoder
+import coil.load
+import coil.request.Disposable
+import coil.request.ImageRequest
+import coil.size.Scale
 import com.google.android.material.tabs.TabItem
 import com.google.android.material.tabs.TabLayout
 import com.google.android.material.tabs.TabLayout.MODE_SCROLLABLE
 import com.google.android.material.tabs.TabLayoutMediator
 import com.mrozon.core_api.entity.Gender
+import com.mrozon.core_api.network.HealthDiaryService
 import com.mrozon.feature_measure.R
 import com.mrozon.feature_measure.databinding.FragmentTabMeasureBinding
 import com.mrozon.feature_measure.di.TabMeasureFragmentComponent
@@ -37,6 +44,8 @@ class TabMeasureFragment: BaseFragment<FragmentTabMeasureBinding>() {
 
     private val viewModel by viewModels<TabMeasureFragmentViewModel> { viewModelFactory }
 
+    private val disposables: List<Disposable> = mutableListOf()
+
     override fun onAttach(context: Context) {
         super.onAttach(context)
         TabMeasureFragmentComponent.injectFragment(this)
@@ -48,13 +57,20 @@ class TabMeasureFragment: BaseFragment<FragmentTabMeasureBinding>() {
 
         val id = arguments?.getLong("id", 0)?:0
         if(id>0){
-            viewModel.loadProfilePerson(id)
+            viewModel.loadProfilePersonAndMeasureTypes(id)
+        }
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+        disposables.forEach {
+            it.dispose()
         }
     }
 
     override fun subscribeUi() {
-        viewModel.selectedPerson.observe(viewLifecycleOwner, Observer { event ->
-            event.getContentIfNotHandled()?.let { result ->
+        viewModel.selectedPersonAndMeasureTypes.observe(viewLifecycleOwner, Observer { event ->
+            event.peekContent().let { result ->
                 when (result.status) {
                     Result.Status.LOADING -> {
                         binding?.progressBar?.visible(true)
@@ -63,17 +79,27 @@ class TabMeasureFragment: BaseFragment<FragmentTabMeasureBinding>() {
                         if(arguments?.containsKey("id") == true)
                             arguments?.remove("id")
                         binding?.progressBar?.visible(false)
-                        setTitleActionBar(result.data?.name!!)
-
-//                        binding?.measureTypesTabs?.tabMode = MODE_SCROLLABLE
-//                        binding?.measureTypesTabs?.addTab(TabLayout.Tab(),0)
-//                        binding?.measureTypesTabs?.addTab(TabLayout.Tab(),1)
-//                        binding?.measureTypesTabs?.addTab(TabLayout.Tab(),2)
-
-//                       TabLayoutMediator(binding?.measureTypesTabs!!, binding?.viewpager!!) { tab, position ->
-//                            tab.text = "position: $position"
-//                       }
+                        val person = result.data?.first
+                        val measureTypes = result.data?.second
+                        setTitleActionBar(person?.name?:"")
+                        binding?.viewpager?.adapter = TabMeasureAdapter(this,person?.id?:-1,
+                            measureTypes?: listOf())
 
+                        measureTypes?.let {
+                            TabLayoutMediator(binding?.measureTypesTabs!!, binding?.viewpager!!) { tab, position ->
+//                                tab.text = measureTypes[position].name
+                                val request = ImageRequest.Builder(requireContext())
+                                    .decoder(SvgDecoder(requireContext()))
+                                    .data(HealthDiaryService.ENDPOINT + measureTypes[position].url)
+                                    .size(48,48)
+                                    .scale(Scale.FILL)
+                                    .target { drawable ->
+                                        tab.icon = drawable
+                                    }
+                                    .build()
+                                disposables.plus(ImageLoader(requireContext()).enqueue(request))
+                            }.attach()
+                        }
                     }
                     Result.Status.ERROR -> {
                         binding?.progressBar?.visible(false)

+ 7 - 6
feature_measure/src/main/java/com/mrozon/feature_measure/presentation/TabMeasureFragmentViewModel.kt

@@ -3,6 +3,7 @@ package com.mrozon.feature_measure.presentation
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.viewModelScope
+import com.mrozon.core_api.entity.MeasureType
 import com.mrozon.core_api.entity.Person
 import com.mrozon.core_api.providers.CoroutineContextProvider
 import com.mrozon.feature_measure.data.MeasureRepository
@@ -19,15 +20,15 @@ class TabMeasureFragmentViewModel @Inject constructor(
     private val coroutineContextProvider: CoroutineContextProvider
 ): BaseViewModel() {
 
-    private var _selectedPerson = MutableLiveData<Event<Result<Person>>>()
-    val selectedPerson: LiveData<Event<Result<Person>>>
-        get() = _selectedPerson
+    private var _selectedPersonAndMeasureTypes = MutableLiveData<Event<Result<Pair<Person, List<MeasureType>>>>>()
+    val selectedPersonAndMeasureTypes: LiveData<Event<Result<Pair<Person, List<MeasureType>>>>>
+        get() = _selectedPersonAndMeasureTypes
 
-    fun loadProfilePerson(id: Long) {
+    fun loadProfilePersonAndMeasureTypes(id: Long) {
             viewModelScope.launch(coroutineContextProvider.IO) {
-                repository.getPerson(id).collect {
+                repository.loadProfilePersonAndMeasureTypes(id).collect {
                     withContext(coroutineContextProvider.Main) {
-                        _selectedPerson.value = Event(it)
+                        _selectedPersonAndMeasureTypes.value = Event(it)
                     }
                 }
             }

+ 55 - 0
feature_measure/src/main/res/layout/fragment_list_measure.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <data>
+
+    </data>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <com.google.android.material.floatingactionbutton.FloatingActionButton
+            android:id="@+id/fabAddMeasure"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="32dp"
+            android:layout_marginBottom="32dp"
+            android:clickable="true"
+            android:focusable="true"
+            app:fabSize="normal"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:srcCompat="@drawable/ic_add_24"
+            app:useCompatPadding="true"
+            tools:ignore="ContentDescription" />
+
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/rvMeasure"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="59dp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:listitem="@layout/item_measure" />
+
+        <ProgressBar
+            android:id="@+id/progressBar"
+            style="?android:attr/progressBarStyle"
+            android:layout_width="128dp"
+            android:layout_height="128dp"
+            android:indeterminate="true"
+            android:visibility="invisible"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:visibility="visible" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>

+ 4 - 2
feature_measure/src/main/res/layout/fragment_tab_measure.xml

@@ -12,10 +12,12 @@
         android:layout_height="match_parent">
 
         <com.google.android.material.tabs.TabLayout
+            android:id="@+id/measureTypesTabs"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:id="@+id/measureTypesTabs"
-            app:layout_constraintBottom_toBottomOf="parent"
+            android:background="@color/colorPrimary"
+            app:tabMode="fixed"
+            app:tabContentStart="56dp"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent">

+ 23 - 0
feature_measure/src/main/res/layout/item_measure.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:tools="http://schemas.android.com/tools"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <data>
+
+    </data>
+
+    <androidx.cardview.widget.CardView
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent">
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+    </androidx.cardview.widget.CardView>
+
+</layout>