From c8b4f8ec819e074ca0ef8321bf72c6b16e820166 Mon Sep 17 00:00:00 2001 From: pump9918 Date: Wed, 17 Jan 2024 23:52:05 +0900 Subject: [PATCH] =?UTF-8?q?#76=20[feat]=20=ED=96=89=EB=B3=B5=EB=A3=A8?= =?UTF-8?q?=ED=8B=B4=20=EC=B6=94=EA=B0=80=20API=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EB=B0=8F=20=EB=B7=B0=ED=8E=98=EC=9D=B4=EC=A0=80=20subRoutineId?= =?UTF-8?q?=20=EC=98=B5=EC=A0=80=EB=B9=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/PostMemberHappyRoutineRequest.kt | 10 ++++ .../MemberHappyRoutinePostResponse.kt | 10 ++++ .../MemberHappinessRoutineRepositoryImpl.kt | 15 ++++++ .../service/MemberHappinessRoutineService.kt | 12 +++++ .../MemberHappinessRoutineDataSource.kt | 14 +++++ .../com/sopetit/softie/di/RepositoryModule.kt | 8 +++ .../softie/di/RetrofitServiceModule.kt | 5 ++ .../MemberHappinessRoutineRepository.kt | 7 +++ .../usecase/PostMemberHappyRoutineUseCase.kt | 12 +++++ .../detail/HappyDetailActivity.kt | 52 +++++++++++++------ .../detail/HappyDetailCardPagerAdapter.kt | 9 ++++ .../detail/HappyDetailCardViewModel.kt | 33 +++++++++++- 12 files changed, 171 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/com/sopetit/softie/data/entity/request/PostMemberHappyRoutineRequest.kt create mode 100644 app/src/main/java/com/sopetit/softie/data/entity/response/MemberHappyRoutinePostResponse.kt create mode 100644 app/src/main/java/com/sopetit/softie/data/repositoryImpl/MemberHappinessRoutineRepositoryImpl.kt create mode 100644 app/src/main/java/com/sopetit/softie/data/service/MemberHappinessRoutineService.kt create mode 100644 app/src/main/java/com/sopetit/softie/data/source/MemberHappinessRoutineDataSource.kt create mode 100644 app/src/main/java/com/sopetit/softie/domain/repository/MemberHappinessRoutineRepository.kt create mode 100644 app/src/main/java/com/sopetit/softie/domain/usecase/PostMemberHappyRoutineUseCase.kt diff --git a/app/src/main/java/com/sopetit/softie/data/entity/request/PostMemberHappyRoutineRequest.kt b/app/src/main/java/com/sopetit/softie/data/entity/request/PostMemberHappyRoutineRequest.kt new file mode 100644 index 00000000..5299ebad --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/data/entity/request/PostMemberHappyRoutineRequest.kt @@ -0,0 +1,10 @@ +package com.sopetit.softie.data.entity.request + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class PostMemberHappyRoutineRequest( + @SerialName("subRoutineId") + val subRoutineId: Int +) diff --git a/app/src/main/java/com/sopetit/softie/data/entity/response/MemberHappyRoutinePostResponse.kt b/app/src/main/java/com/sopetit/softie/data/entity/response/MemberHappyRoutinePostResponse.kt new file mode 100644 index 00000000..321addab --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/data/entity/response/MemberHappyRoutinePostResponse.kt @@ -0,0 +1,10 @@ +package com.sopetit.softie.data.entity.response + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class MemberHappyRoutinePostResponse( + @SerialName("routineId") + val routineId: Int +) diff --git a/app/src/main/java/com/sopetit/softie/data/repositoryImpl/MemberHappinessRoutineRepositoryImpl.kt b/app/src/main/java/com/sopetit/softie/data/repositoryImpl/MemberHappinessRoutineRepositoryImpl.kt new file mode 100644 index 00000000..6961b661 --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/data/repositoryImpl/MemberHappinessRoutineRepositoryImpl.kt @@ -0,0 +1,15 @@ +package com.sopetit.softie.data.repositoryImpl + +import com.sopetit.softie.data.entity.request.PostMemberHappyRoutineRequest +import com.sopetit.softie.data.source.MemberHappinessRoutineDataSource +import com.sopetit.softie.domain.repository.MemberHappinessRoutineRepository +import javax.inject.Inject + +class MemberHappinessRoutineRepositoryImpl @Inject constructor( + private val memberHappinessRoutineDataSource: MemberHappinessRoutineDataSource +) : MemberHappinessRoutineRepository { + override suspend fun postMemberHappinessRoutine(request: PostMemberHappyRoutineRequest): Result = + runCatching { memberHappinessRoutineDataSource.postMemberHappyRoutine(request) }.map { + requireNotNull(it.data).routineId + } +} diff --git a/app/src/main/java/com/sopetit/softie/data/service/MemberHappinessRoutineService.kt b/app/src/main/java/com/sopetit/softie/data/service/MemberHappinessRoutineService.kt new file mode 100644 index 00000000..2d2ad7c3 --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/data/service/MemberHappinessRoutineService.kt @@ -0,0 +1,12 @@ +package com.sopetit.softie.data.service + +import com.sopetit.softie.data.entity.BaseResponse +import com.sopetit.softie.data.entity.request.PostMemberHappyRoutineRequest +import com.sopetit.softie.data.entity.response.MemberHappyRoutinePostResponse +import retrofit2.http.Body +import retrofit2.http.POST + +interface MemberHappinessRoutineService { + @POST("api/v1/routines/happiness/member") + suspend fun postMemberHappyRoutine(@Body request: PostMemberHappyRoutineRequest): BaseResponse +} diff --git a/app/src/main/java/com/sopetit/softie/data/source/MemberHappinessRoutineDataSource.kt b/app/src/main/java/com/sopetit/softie/data/source/MemberHappinessRoutineDataSource.kt new file mode 100644 index 00000000..ec250675 --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/data/source/MemberHappinessRoutineDataSource.kt @@ -0,0 +1,14 @@ +package com.sopetit.softie.data.source + +import com.sopetit.softie.data.entity.BaseResponse +import com.sopetit.softie.data.entity.request.PostMemberHappyRoutineRequest +import com.sopetit.softie.data.entity.response.MemberHappyRoutinePostResponse +import com.sopetit.softie.data.service.MemberHappinessRoutineService +import javax.inject.Inject + +class MemberHappinessRoutineDataSource @Inject constructor( + private val memberHappinessRoutineService: MemberHappinessRoutineService +) { + suspend fun postMemberHappyRoutine(request: PostMemberHappyRoutineRequest): BaseResponse = + memberHappinessRoutineService.postMemberHappyRoutine(request) +} diff --git a/app/src/main/java/com/sopetit/softie/di/RepositoryModule.kt b/app/src/main/java/com/sopetit/softie/di/RepositoryModule.kt index 9739dd55..2d968c87 100644 --- a/app/src/main/java/com/sopetit/softie/di/RepositoryModule.kt +++ b/app/src/main/java/com/sopetit/softie/di/RepositoryModule.kt @@ -3,10 +3,12 @@ package com.sopetit.softie.di import com.sopetit.softie.data.repositoryImpl.DailyRoutineRepositoryImpl import com.sopetit.softie.data.repositoryImpl.DollRepositoryImpl import com.sopetit.softie.data.repositoryImpl.HappinessRoutineRepositoryImpl +import com.sopetit.softie.data.repositoryImpl.MemberHappinessRoutineRepositoryImpl import com.sopetit.softie.data.repositoryImpl.MemberRepositoryImpl import com.sopetit.softie.domain.repository.DailyRoutineRepository import com.sopetit.softie.domain.repository.DollRepository import com.sopetit.softie.domain.repository.HappinessRoutineRepository +import com.sopetit.softie.domain.repository.MemberHappinessRoutineRepository import com.sopetit.softie.domain.repository.MemberRepository import dagger.Binds import dagger.Module @@ -40,4 +42,10 @@ abstract class RepositoryModule { abstract fun bindToHappinessRoutineRepository( happinessRoutineRepositoryImpl: HappinessRoutineRepositoryImpl ): HappinessRoutineRepository + + @Binds + @Singleton + abstract fun bindToMemberHappinessRoutineRepository( + memberHappinessRoutineRepositoryImpl: MemberHappinessRoutineRepositoryImpl + ): MemberHappinessRoutineRepository } diff --git a/app/src/main/java/com/sopetit/softie/di/RetrofitServiceModule.kt b/app/src/main/java/com/sopetit/softie/di/RetrofitServiceModule.kt index 6df16a62..c2e41a30 100644 --- a/app/src/main/java/com/sopetit/softie/di/RetrofitServiceModule.kt +++ b/app/src/main/java/com/sopetit/softie/di/RetrofitServiceModule.kt @@ -3,6 +3,7 @@ package com.sopetit.softie.di import com.sopetit.softie.data.service.DailyRoutineService import com.sopetit.softie.data.service.DollService import com.sopetit.softie.data.service.HappinessRoutineService +import com.sopetit.softie.data.service.MemberHappinessRoutineService import com.sopetit.softie.data.service.MemberService import dagger.Module import dagger.Provides @@ -28,4 +29,8 @@ object RetrofitServiceModule { @Provides fun providesDollService(@RetrofitModule.SoftieType retrofit: Retrofit): DollService = retrofit.create(DollService::class.java) + + @Provides + fun providesMemberHappinessRoutineService(@RetrofitModule.SoftieType retrofit: Retrofit): MemberHappinessRoutineService = + retrofit.create(MemberHappinessRoutineService::class.java) } diff --git a/app/src/main/java/com/sopetit/softie/domain/repository/MemberHappinessRoutineRepository.kt b/app/src/main/java/com/sopetit/softie/domain/repository/MemberHappinessRoutineRepository.kt new file mode 100644 index 00000000..bbbb212e --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/domain/repository/MemberHappinessRoutineRepository.kt @@ -0,0 +1,7 @@ +package com.sopetit.softie.domain.repository + +import com.sopetit.softie.data.entity.request.PostMemberHappyRoutineRequest + +interface MemberHappinessRoutineRepository { + suspend fun postMemberHappinessRoutine(request: PostMemberHappyRoutineRequest): Result +} diff --git a/app/src/main/java/com/sopetit/softie/domain/usecase/PostMemberHappyRoutineUseCase.kt b/app/src/main/java/com/sopetit/softie/domain/usecase/PostMemberHappyRoutineUseCase.kt new file mode 100644 index 00000000..96274d1b --- /dev/null +++ b/app/src/main/java/com/sopetit/softie/domain/usecase/PostMemberHappyRoutineUseCase.kt @@ -0,0 +1,12 @@ +package com.sopetit.softie.domain.usecase + +import com.sopetit.softie.data.entity.request.PostMemberHappyRoutineRequest +import com.sopetit.softie.domain.repository.MemberHappinessRoutineRepository +import javax.inject.Inject + +class PostMemberHappyRoutineUseCase @Inject constructor( + private val memberHappinessRoutineRepository: MemberHappinessRoutineRepository +) { + suspend operator fun invoke(request: PostMemberHappyRoutineRequest) = + memberHappinessRoutineRepository.postMemberHappinessRoutine(request) +} diff --git a/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailActivity.kt b/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailActivity.kt index be769ef7..ae63b4dd 100644 --- a/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailActivity.kt +++ b/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailActivity.kt @@ -30,8 +30,7 @@ import kotlinx.coroutines.launch class HappyDetailActivity : BindingActivity(R.layout.activity_happy_add_detail) { private lateinit var viewPager: ViewPager2 - private lateinit var happyRoutineAddCardPagerAdapter: HappyDetailCardPagerAdapter - + private val happyRoutineAddCardPagerAdapter = HappyDetailCardPagerAdapter() private val viewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { @@ -41,8 +40,19 @@ class HappyDetailActivity : setStatusBarColorFromResource(R.color.background) val routineId = intent.getIntExtra(ID, -1).toString() - viewModel.getHappyCard(routineId) + setInitBinding(routineId) + setCurrentCard() + setBackEnter() + setupAdapter(routineId) + setIndicator() + initSetLoading() + initViewPager() + initPagerDiv(0, 90) + } + + private fun setInitBinding(routineId: String) { + viewModel.getHappyCard(routineId) viewModel.happyCardResponse.observe(this) { happyCard -> happyCard?.let { with(binding) { @@ -51,16 +61,29 @@ class HappyDetailActivity : tvHappyAddDetailSubtitle.text = happyCard.title tvHappyAddDetailTitle.setTextColor(Color.parseColor(happyCard.nameColor)) } - setBottomSheetEnter(happyCard.iconImageUrl) + viewModel.mySubroutineId.observe(this) { mySubRoutineId -> + mySubRoutineId?.let { + setBottomSheetEnter(happyCard.iconImageUrl, mySubRoutineId) + } + } } } + } - initSetLoading() - setBackEnter() - setupAdapter(routineId) - setIndicator() - initViewPager() - initPagerDiv(0, 90) + private fun setCurrentCard() { + viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + super.onPageSelected(position) + val currentSubRoutineId = getCurrentSelectedSubRoutineId() + viewModel.setSubRoutineId(currentSubRoutineId) + } + }) + } + + private fun getCurrentSelectedSubRoutineId(): Int { + val currentItem = binding.vpHappyAddDetailCard.currentItem + val itemId = happyRoutineAddCardPagerAdapter.getItemId(currentItem) + return itemId.toInt() } private fun setBackEnter() { @@ -69,13 +92,13 @@ class HappyDetailActivity : } } - private fun setBottomSheetEnter(icon: String) { + private fun setBottomSheetEnter(icon: String, subRoutineId: Int) { binding.btnHappyDetailAdd.setOnClickListener { - initHappyRoutineAddBottomSheet(icon) + initHappyRoutineAddBottomSheet(icon, subRoutineId) } } - private fun initHappyRoutineAddBottomSheet(icon: String) { + private fun initHappyRoutineAddBottomSheet(icon: String, subRoutineId: Int) { BindingBottomSheet.Builder().build( isDrawable = false, imageDrawable = 0, @@ -90,6 +113,7 @@ class HappyDetailActivity : backBtnAction = {}, doBtnAction = { moveToProgress() + viewModel.postAddRoutine(subRoutineId) } ).show(this.supportFragmentManager, OriginalBottomSheet.BOTTOM_SHEET_TAG) } @@ -104,8 +128,6 @@ class HappyDetailActivity : private fun setupAdapter(routineId: String) { with(binding) { - happyRoutineAddCardPagerAdapter = - HappyDetailCardPagerAdapter() vpHappyAddDetailCard.adapter = happyRoutineAddCardPagerAdapter } viewModel.happyCardResponse.observe(this) { happyCard -> diff --git a/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailCardPagerAdapter.kt b/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailCardPagerAdapter.kt index 1b815e6c..ab2d7b8f 100644 --- a/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailCardPagerAdapter.kt +++ b/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailCardPagerAdapter.kt @@ -56,6 +56,15 @@ class HappyDetailCardPagerAdapter() : } } + override fun getItemId(position: Int): Long { + val itemCount = currentList.size + if (position in 0 until itemCount) { + return currentList[position].subRoutineId.toLong() + } else { + return RecyclerView.NO_ID + } + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HappyPagerViewHolder { val binding = ItemHappyAddDetailCardBinding.inflate( LayoutInflater.from(parent.context), diff --git a/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailCardViewModel.kt b/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailCardViewModel.kt index 1a1682ec..354ae760 100644 --- a/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailCardViewModel.kt +++ b/app/src/main/java/com/sopetit/softie/ui/happyroutine/detail/HappyDetailCardViewModel.kt @@ -4,8 +4,10 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.sopetit.softie.data.entity.request.PostMemberHappyRoutineRequest import com.sopetit.softie.domain.entity.HappyCard import com.sopetit.softie.domain.usecase.GetHappyCardUseCase +import com.sopetit.softie.domain.usecase.PostMemberHappyRoutineUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import timber.log.Timber @@ -13,11 +15,21 @@ import javax.inject.Inject @HiltViewModel class HappyDetailCardViewModel @Inject constructor( - private val getHappyCardUseCase: GetHappyCardUseCase + private val getHappyCardUseCase: GetHappyCardUseCase, + private val postMemberHappyRoutineUseCase: PostMemberHappyRoutineUseCase ) : ViewModel() { private val _happyCardResponse = MutableLiveData() val happyCardResponse: LiveData get() = _happyCardResponse + + private val _isPostAddRoutine: MutableLiveData = MutableLiveData() + val isPostAddRoutine: LiveData + get() = _isPostAddRoutine + + private val _mySubroutineId: MutableLiveData = MutableLiveData() + val mySubroutineId: LiveData + get() = _mySubroutineId + fun getHappyCard(routineId: String) { viewModelScope.launch { getHappyCardUseCase(routineId) @@ -29,4 +41,23 @@ class HappyDetailCardViewModel @Inject constructor( } } } + + fun postAddRoutine(subRoutineId: Int) { + viewModelScope.launch { + postMemberHappyRoutineUseCase.invoke( + PostMemberHappyRoutineRequest( + subRoutineId + ) + ).onSuccess { + _isPostAddRoutine.value = true + }.onFailure { throwable -> + _isPostAddRoutine.value = false + Timber.e("서버 통신 실패 ${throwable.message}") + } + } + } + + fun setSubRoutineId(subRoutineId: Int) { + _mySubroutineId.value = subRoutineId + } }