From a985683d3a330dd06da3cb74b7a821405cc6eebe Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Wed, 10 Jan 2024 15:24:59 +0900 Subject: [PATCH 01/15] =?UTF-8?q?[add]=20#92=20RequestPlanLocationDto,=20R?= =?UTF-8?q?esponsePlanLocationDto=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../remote/request/RequestPlanLocationDto.kt | 10 +++++++ .../response/ResponsePlanLocationDto.kt | 27 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanLocationDto.kt create mode 100644 app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanLocationDto.kt diff --git a/app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanLocationDto.kt b/app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanLocationDto.kt new file mode 100644 index 00000000..ff85a423 --- /dev/null +++ b/app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanLocationDto.kt @@ -0,0 +1,10 @@ +package org.sopt.pingle.data.model.remote.request + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RequestPlanLocationDto( + @SerialName("search") + val search: String +) \ No newline at end of file diff --git a/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanLocationDto.kt b/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanLocationDto.kt new file mode 100644 index 00000000..182e63aa --- /dev/null +++ b/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanLocationDto.kt @@ -0,0 +1,27 @@ +package org.sopt.pingle.data.model.remote.response + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +data class ResponsePlanLocationDto( + @SerialName("code") + val code: Int, + @SerialName("message") + val message: String, + @SerialName("data") + val data: List +) { + @Serializable + data class Data( + @SerialName("x") + val xCoordinate: Double, + @SerialName("y") + val yCoordinate: Double, + @SerialName("location") + val locationName: String, + @SerialName("address") + val locationAddress: String, + @SerialName("roadAddress") + val locationRoadAddress: String, + ) +} From 6ce978b332ef4ee7a1accd2395fd1e2952b66c4a Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Wed, 10 Jan 2024 23:28:44 +0900 Subject: [PATCH 02/15] =?UTF-8?q?[chore]=20#92=20BaseRespone=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=ED=95=B4=20Dto=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...stPlanLocationDto.kt => RequestPlanDto.kt} | 6 ++--- .../model/remote/response/ResponsePlanDto.kt | 26 ++++++++++++++++++ .../response/ResponsePlanLocationDto.kt | 27 ------------------- 3 files changed, 29 insertions(+), 30 deletions(-) rename app/src/main/java/org/sopt/pingle/data/model/remote/request/{RequestPlanLocationDto.kt => RequestPlanDto.kt} (74%) create mode 100644 app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanDto.kt delete mode 100644 app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanLocationDto.kt diff --git a/app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanLocationDto.kt b/app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanDto.kt similarity index 74% rename from app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanLocationDto.kt rename to app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanDto.kt index ff85a423..df482684 100644 --- a/app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanLocationDto.kt +++ b/app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanDto.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable -data class RequestPlanLocationDto( +data class RequestPlanDto( @SerialName("search") - val search: String -) \ No newline at end of file + val search: String, +) diff --git a/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanDto.kt b/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanDto.kt new file mode 100644 index 00000000..ab6e7a6d --- /dev/null +++ b/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanDto.kt @@ -0,0 +1,26 @@ +package org.sopt.pingle.data.model.remote.response + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import org.sopt.pingle.domain.model.PlanLocationEntity + +@Serializable +data class ResponsePlanDto( + @SerialName("x") + val xCoordinate: Double, + @SerialName("y") + val yCoordinate: Double, + @SerialName("location") + val locationName: String, + @SerialName("address") + val locationAddress: String, + @SerialName("roadAddress") + val locationRoadAddress: String, +) { + fun toPlanLocationEntity() = PlanLocationEntity( + location = locationName, + address = locationAddress, + x = xCoordinate, + y = yCoordinate, + ) +} diff --git a/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanLocationDto.kt b/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanLocationDto.kt deleted file mode 100644 index 182e63aa..00000000 --- a/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanLocationDto.kt +++ /dev/null @@ -1,27 +0,0 @@ -package org.sopt.pingle.data.model.remote.response - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -data class ResponsePlanLocationDto( - @SerialName("code") - val code: Int, - @SerialName("message") - val message: String, - @SerialName("data") - val data: List -) { - @Serializable - data class Data( - @SerialName("x") - val xCoordinate: Double, - @SerialName("y") - val yCoordinate: Double, - @SerialName("location") - val locationName: String, - @SerialName("address") - val locationAddress: String, - @SerialName("roadAddress") - val locationRoadAddress: String, - ) -} From ff3cc01d1c5b8c7e7a9df79c4107ee6d561dd279 Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Thu, 11 Jan 2024 02:07:21 +0900 Subject: [PATCH 03/15] =?UTF-8?q?[feat]=20#92=20HiltViewModel,=20AndroidEn?= =?UTF-8?q?tryPoint=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/sopt/pingle/presentation/ui/main/plan/PlanActivity.kt | 2 ++ .../ui/main/plan/plancategory/PlanCategoryFragment.kt | 2 ++ .../ui/main/plan/planlocation/PlanLocationFragment.kt | 3 +++ .../ui/main/plan/planopenchatting/PlanOpenChattingFragment.kt | 2 ++ .../ui/main/plan/planrecruitment/PlanRecruitmentFragment.kt | 2 ++ .../plansummaryconfirmation/PlanSummaryConfirmationFragment.kt | 2 ++ .../presentation/ui/main/plan/plantitle/PlanTitleFragment.kt | 2 ++ 7 files changed, 15 insertions(+) diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanActivity.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanActivity.kt index eff9c241..2978d178 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanActivity.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanActivity.kt @@ -7,6 +7,7 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.viewpager2.widget.ViewPager2 +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import org.sopt.pingle.R @@ -21,6 +22,7 @@ import org.sopt.pingle.presentation.ui.main.plan.plantitle.PlanTitleFragment import org.sopt.pingle.util.base.BindingActivity import org.sopt.pingle.util.component.AllModalDialogFragment +@AndroidEntryPoint class PlanActivity : BindingActivity(R.layout.activity_plan) { private val planViewModel: PlanViewModel by viewModels() private lateinit var fragmentList: ArrayList diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plancategory/PlanCategoryFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plancategory/PlanCategoryFragment.kt index a5cb920c..97a3b7f7 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plancategory/PlanCategoryFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plancategory/PlanCategoryFragment.kt @@ -3,12 +3,14 @@ package org.sopt.pingle.presentation.ui.main.plan.plancategory import android.os.Bundle import android.view.View import androidx.fragment.app.activityViewModels +import dagger.hilt.android.AndroidEntryPoint import org.sopt.pingle.R import org.sopt.pingle.databinding.FragmentPlanCategoryBinding import org.sopt.pingle.presentation.type.CategoryType import org.sopt.pingle.presentation.ui.main.plan.PlanViewModel import org.sopt.pingle.util.base.BindingFragment +@AndroidEntryPoint class PlanCategoryFragment : BindingFragment(R.layout.fragment_plan_category) { private val viewModel by activityViewModels() diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt index d16fa424..dc3f677d 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt @@ -5,12 +5,14 @@ import android.view.KeyEvent import android.view.View import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.LinearLayoutManager +import dagger.hilt.android.AndroidEntryPoint import org.sopt.pingle.R import org.sopt.pingle.databinding.FragmentPlanLocationBinding import org.sopt.pingle.presentation.ui.main.plan.PlanViewModel import org.sopt.pingle.util.base.BindingFragment import org.sopt.pingle.util.context.hideKeyboard +@AndroidEntryPoint class PlanLocationFragment : BindingFragment(R.layout.fragment_plan_location) { private val planLocationViewModel by activityViewModels() @@ -26,6 +28,7 @@ class PlanLocationFragment : } private fun initLayout() { + planLocationViewModel.getPlanLocationList() binding.rvPlanLocationList.apply { this.layoutManager = LinearLayoutManager(context) adapter = planLocationAdapter diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planopenchatting/PlanOpenChattingFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planopenchatting/PlanOpenChattingFragment.kt index e310d001..cb865f37 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planopenchatting/PlanOpenChattingFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planopenchatting/PlanOpenChattingFragment.kt @@ -3,12 +3,14 @@ package org.sopt.pingle.presentation.ui.main.plan.planopenchatting import android.os.Bundle import android.view.View import androidx.fragment.app.activityViewModels +import dagger.hilt.android.AndroidEntryPoint import org.sopt.pingle.R import org.sopt.pingle.databinding.FragmentPlanOpenChattingBinding import org.sopt.pingle.presentation.ui.main.plan.PlanViewModel import org.sopt.pingle.util.base.BindingFragment import org.sopt.pingle.util.context.hideKeyboard +@AndroidEntryPoint class PlanOpenChattingFragment : BindingFragment(R.layout.fragment_plan_open_chatting) { private val planViewModel: PlanViewModel by activityViewModels() diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planrecruitment/PlanRecruitmentFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planrecruitment/PlanRecruitmentFragment.kt index e6b80e01..781dac7d 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planrecruitment/PlanRecruitmentFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planrecruitment/PlanRecruitmentFragment.kt @@ -6,6 +6,7 @@ import android.view.View import androidx.fragment.app.activityViewModels import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import org.sopt.pingle.R @@ -14,6 +15,7 @@ import org.sopt.pingle.presentation.ui.main.plan.PlanViewModel import org.sopt.pingle.util.base.BindingFragment import org.sopt.pingle.util.context.hideKeyboard +@AndroidEntryPoint class PlanRecruitmentFragment : BindingFragment(R.layout.fragment_plan_recruitment) { diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plansummaryconfirmation/PlanSummaryConfirmationFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plansummaryconfirmation/PlanSummaryConfirmationFragment.kt index 2d9f2ddb..488e9a1f 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plansummaryconfirmation/PlanSummaryConfirmationFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plansummaryconfirmation/PlanSummaryConfirmationFragment.kt @@ -3,12 +3,14 @@ package org.sopt.pingle.presentation.ui.main.plan.plansummaryconfirmation import android.os.Bundle import android.view.View import androidx.fragment.app.activityViewModels +import dagger.hilt.android.AndroidEntryPoint import org.sopt.pingle.R import org.sopt.pingle.databinding.FragmentPlanSummaryConfirmationBinding import org.sopt.pingle.presentation.ui.main.plan.PlanViewModel import org.sopt.pingle.util.base.BindingFragment import org.sopt.pingle.util.fragment.colorOf +@AndroidEntryPoint class PlanSummaryConfirmationFragment : BindingFragment(R.layout.fragment_plan_summary_confirmation) { private val viewModel by activityViewModels() diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plantitle/PlanTitleFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plantitle/PlanTitleFragment.kt index 7d2092e6..dfa81f94 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plantitle/PlanTitleFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plantitle/PlanTitleFragment.kt @@ -3,12 +3,14 @@ package org.sopt.pingle.presentation.ui.main.plan.plantitle import android.os.Bundle import android.view.View import androidx.fragment.app.activityViewModels +import dagger.hilt.android.AndroidEntryPoint import org.sopt.pingle.R import org.sopt.pingle.databinding.FragmentPlanTitleBinding import org.sopt.pingle.presentation.ui.main.plan.PlanViewModel import org.sopt.pingle.util.base.BindingFragment import org.sopt.pingle.util.context.hideKeyboard +@AndroidEntryPoint class PlanTitleFragment : BindingFragment(R.layout.fragment_plan_title) { private val planViewModel: PlanViewModel by activityViewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { From 8d7446a48bc8c882eb99bcd71aa1613c46a3cf32 Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Thu, 11 Jan 2024 07:04:58 +0900 Subject: [PATCH 04/15] =?UTF-8?q?[feat]=20#92=20=ED=81=B4=EB=A6=B0?= =?UTF-8?q?=EC=95=84=ED=82=A4=ED=85=8D=EC=B2=98=20=EB=B0=8F=20DI=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=ED=95=9C=20Repository,=20UseCase,=20DataSour?= =?UTF-8?q?ce,Service=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datasource/remote/PlanRemoteDataSource.kt | 8 +++++++ .../remote/PlanRemoteDataSourceImpl.kt | 14 ++++++++++++ .../model/remote/request/RequestPlanDto.kt | 2 +- .../model/remote/response/ResponsePlanDto.kt | 4 ++-- .../data/repository/PlanRepositoryImpl.kt | 22 +++++++++++++++++++ .../sopt/pingle/data/service/PlanService.kt | 19 ++++++++++++++++ .../org/sopt/pingle/di/DataSourceModule.kt | 6 +++++ .../org/sopt/pingle/di/RepositoryModule.kt | 6 +++++ .../java/org/sopt/pingle/di/ServiceModule.kt | 6 +++++ .../java/org/sopt/pingle/di/UseCaseModule.kt | 7 ++++++ .../domain/repository/PlanRepository.kt | 8 +++++++ .../usecase/GetPlanLocationListUseCase.kt | 12 ++++++++++ .../plan/plandatetime/PlanDateTimeFragment.kt | 2 ++ 13 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/org/sopt/pingle/data/datasource/remote/PlanRemoteDataSource.kt create mode 100644 app/src/main/java/org/sopt/pingle/data/datasourceimpl/remote/PlanRemoteDataSourceImpl.kt create mode 100644 app/src/main/java/org/sopt/pingle/data/repository/PlanRepositoryImpl.kt create mode 100644 app/src/main/java/org/sopt/pingle/data/service/PlanService.kt create mode 100644 app/src/main/java/org/sopt/pingle/domain/repository/PlanRepository.kt create mode 100644 app/src/main/java/org/sopt/pingle/domain/usecase/GetPlanLocationListUseCase.kt diff --git a/app/src/main/java/org/sopt/pingle/data/datasource/remote/PlanRemoteDataSource.kt b/app/src/main/java/org/sopt/pingle/data/datasource/remote/PlanRemoteDataSource.kt new file mode 100644 index 00000000..9d5be8f0 --- /dev/null +++ b/app/src/main/java/org/sopt/pingle/data/datasource/remote/PlanRemoteDataSource.kt @@ -0,0 +1,8 @@ +package org.sopt.pingle.data.datasource.remote + +import org.sopt.pingle.data.model.remote.response.ResponsePlanDto +import org.sopt.pingle.util.base.BaseResponse + +interface PlanRemoteDataSource { + suspend fun getPlanLocation(searchWord: String): BaseResponse> +} diff --git a/app/src/main/java/org/sopt/pingle/data/datasourceimpl/remote/PlanRemoteDataSourceImpl.kt b/app/src/main/java/org/sopt/pingle/data/datasourceimpl/remote/PlanRemoteDataSourceImpl.kt new file mode 100644 index 00000000..75815bfb --- /dev/null +++ b/app/src/main/java/org/sopt/pingle/data/datasourceimpl/remote/PlanRemoteDataSourceImpl.kt @@ -0,0 +1,14 @@ +package org.sopt.pingle.data.datasourceimpl.remote + +import javax.inject.Inject +import org.sopt.pingle.data.datasource.remote.PlanRemoteDataSource +import org.sopt.pingle.data.model.remote.response.ResponsePlanDto +import org.sopt.pingle.data.service.PlanService +import org.sopt.pingle.util.base.BaseResponse + +class PlanRemoteDataSourceImpl @Inject constructor( + private val planService: PlanService +) : PlanRemoteDataSource { + override suspend fun getPlanLocation(searchWord: String): BaseResponse> = + planService.getPlanLocationList(searchWord = searchWord) +} diff --git a/app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanDto.kt b/app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanDto.kt index df482684..cf22aaa0 100644 --- a/app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanDto.kt +++ b/app/src/main/java/org/sopt/pingle/data/model/remote/request/RequestPlanDto.kt @@ -6,5 +6,5 @@ import kotlinx.serialization.Serializable @Serializable data class RequestPlanDto( @SerialName("search") - val search: String, + val search: String ) diff --git a/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanDto.kt b/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanDto.kt index ab6e7a6d..f2988e37 100644 --- a/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanDto.kt +++ b/app/src/main/java/org/sopt/pingle/data/model/remote/response/ResponsePlanDto.kt @@ -15,12 +15,12 @@ data class ResponsePlanDto( @SerialName("address") val locationAddress: String, @SerialName("roadAddress") - val locationRoadAddress: String, + val locationRoadAddress: String ) { fun toPlanLocationEntity() = PlanLocationEntity( location = locationName, address = locationAddress, x = xCoordinate, - y = yCoordinate, + y = yCoordinate ) } diff --git a/app/src/main/java/org/sopt/pingle/data/repository/PlanRepositoryImpl.kt b/app/src/main/java/org/sopt/pingle/data/repository/PlanRepositoryImpl.kt new file mode 100644 index 00000000..9d43e791 --- /dev/null +++ b/app/src/main/java/org/sopt/pingle/data/repository/PlanRepositoryImpl.kt @@ -0,0 +1,22 @@ +package org.sopt.pingle.data.repository + +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import org.sopt.pingle.data.datasource.remote.PlanRemoteDataSource +import org.sopt.pingle.domain.model.PlanLocationEntity +import org.sopt.pingle.domain.repository.PlanRepository + +class PlanRepositoryImpl @Inject constructor( + private val planRemoteDataSource: PlanRemoteDataSource +) : PlanRepository { + override suspend fun getPlanLocationList(searchWord: String): Flow> = + flow { + val result = runCatching { + planRemoteDataSource.getPlanLocation(searchWord = searchWord).data.map { planLocation -> + planLocation.toPlanLocationEntity() + } + } + emit(result.getOrThrow()) + } +} diff --git a/app/src/main/java/org/sopt/pingle/data/service/PlanService.kt b/app/src/main/java/org/sopt/pingle/data/service/PlanService.kt new file mode 100644 index 00000000..060cd8a3 --- /dev/null +++ b/app/src/main/java/org/sopt/pingle/data/service/PlanService.kt @@ -0,0 +1,19 @@ +package org.sopt.pingle.data.service + +import org.sopt.pingle.data.model.remote.response.ResponsePlanDto +import org.sopt.pingle.util.base.BaseResponse +import retrofit2.http.GET +import retrofit2.http.Query + +interface PlanService { + @GET("$VERSION/$LOCATION") + suspend fun getPlanLocationList( + @Query(SEARCH_WORD) searchWord: String + ): BaseResponse> + + companion object { + const val VERSION = "v1" + const val LOCATION = "location" + const val SEARCH_WORD = "search" + } +} diff --git a/app/src/main/java/org/sopt/pingle/di/DataSourceModule.kt b/app/src/main/java/org/sopt/pingle/di/DataSourceModule.kt index 92780fcb..70b4ff55 100644 --- a/app/src/main/java/org/sopt/pingle/di/DataSourceModule.kt +++ b/app/src/main/java/org/sopt/pingle/di/DataSourceModule.kt @@ -8,9 +8,11 @@ import javax.inject.Singleton import org.sopt.pingle.data.datasource.local.DummyLocalDataSource import org.sopt.pingle.data.datasource.remote.DummyRemoteDataSource import org.sopt.pingle.data.datasource.remote.MapRemoteDataSource +import org.sopt.pingle.data.datasource.remote.PlanRemoteDataSource import org.sopt.pingle.data.datasourceimpl.local.DummyLocalDataSourceImpl import org.sopt.pingle.data.datasourceimpl.remote.DummyRemoteDataSourceImpl import org.sopt.pingle.data.datasourceimpl.remote.MapRemoteDataSourceImpl +import org.sopt.pingle.data.datasourceimpl.remote.PlanRemoteDataSourceImpl @Module @InstallIn(SingletonComponent::class) @@ -26,4 +28,8 @@ abstract class DataSourceModule { @Binds @Singleton abstract fun bindsMapRemoteDataSource(mapRemoteDataSourceImpl: MapRemoteDataSourceImpl): MapRemoteDataSource + + @Binds + @Singleton + abstract fun bindsPlanRemoteDataSource(planRemoteDataSourceImpl: PlanRemoteDataSourceImpl): PlanRemoteDataSource } diff --git a/app/src/main/java/org/sopt/pingle/di/RepositoryModule.kt b/app/src/main/java/org/sopt/pingle/di/RepositoryModule.kt index 81f14c1e..7804478a 100644 --- a/app/src/main/java/org/sopt/pingle/di/RepositoryModule.kt +++ b/app/src/main/java/org/sopt/pingle/di/RepositoryModule.kt @@ -7,8 +7,10 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Singleton import org.sopt.pingle.data.repository.DummyRepositoryImpl import org.sopt.pingle.data.repository.MapRepositoryImpl +import org.sopt.pingle.data.repository.PlanRepositoryImpl import org.sopt.pingle.domain.repository.DummyRepository import org.sopt.pingle.domain.repository.MapRepository +import org.sopt.pingle.domain.repository.PlanRepository @Module @InstallIn(SingletonComponent::class) @@ -20,4 +22,8 @@ abstract class RepositoryModule { @Binds @Singleton abstract fun bindsMapRepository(mapRepositoryImpl: MapRepositoryImpl): MapRepository + + @Binds + @Singleton + abstract fun bindsPlanRepository(planRepositoryImpl: PlanRepositoryImpl): PlanRepository } diff --git a/app/src/main/java/org/sopt/pingle/di/ServiceModule.kt b/app/src/main/java/org/sopt/pingle/di/ServiceModule.kt index 754022b6..eb79ba85 100644 --- a/app/src/main/java/org/sopt/pingle/di/ServiceModule.kt +++ b/app/src/main/java/org/sopt/pingle/di/ServiceModule.kt @@ -7,6 +7,7 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Singleton import org.sopt.pingle.data.service.DummyService import org.sopt.pingle.data.service.MapService +import org.sopt.pingle.data.service.PlanService import org.sopt.pingle.di.qualifier.Pingle import retrofit2.Retrofit import retrofit2.create @@ -23,4 +24,9 @@ object ServiceModule { @Singleton fun providesMapService(@Pingle retrofit: Retrofit): MapService = retrofit.create(MapService::class.java) + + @Provides + @Singleton + fun providesPlanService(@Pingle retrofit: Retrofit): PlanService = + retrofit.create(PlanService::class.java) } diff --git a/app/src/main/java/org/sopt/pingle/di/UseCaseModule.kt b/app/src/main/java/org/sopt/pingle/di/UseCaseModule.kt index 0c360644..7cb72420 100644 --- a/app/src/main/java/org/sopt/pingle/di/UseCaseModule.kt +++ b/app/src/main/java/org/sopt/pingle/di/UseCaseModule.kt @@ -7,8 +7,10 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Singleton import org.sopt.pingle.domain.repository.DummyRepository import org.sopt.pingle.domain.repository.MapRepository +import org.sopt.pingle.domain.repository.PlanRepository import org.sopt.pingle.domain.usecase.GetDummyUserListUseCase import org.sopt.pingle.domain.usecase.GetPinListWithoutFilteringUseCase +import org.sopt.pingle.domain.usecase.GetPlanLocationListUseCase import org.sopt.pingle.domain.usecase.SetDummyDataUseCase @Module @@ -28,4 +30,9 @@ class UseCaseModule { @Singleton fun providesGetPinListWithoutFilteringUseCase(mapRepository: MapRepository): GetPinListWithoutFilteringUseCase = GetPinListWithoutFilteringUseCase(mapRepository = mapRepository) + + @Provides + @Singleton + fun providesGetPlanLocationListUseCase(planRepository: PlanRepository): GetPlanLocationListUseCase = + GetPlanLocationListUseCase(planRepository = planRepository) } diff --git a/app/src/main/java/org/sopt/pingle/domain/repository/PlanRepository.kt b/app/src/main/java/org/sopt/pingle/domain/repository/PlanRepository.kt new file mode 100644 index 00000000..bdb310db --- /dev/null +++ b/app/src/main/java/org/sopt/pingle/domain/repository/PlanRepository.kt @@ -0,0 +1,8 @@ +package org.sopt.pingle.domain.repository + +import kotlinx.coroutines.flow.Flow +import org.sopt.pingle.domain.model.PlanLocationEntity + +interface PlanRepository { + suspend fun getPlanLocationList(searchWord: String): Flow> +} diff --git a/app/src/main/java/org/sopt/pingle/domain/usecase/GetPlanLocationListUseCase.kt b/app/src/main/java/org/sopt/pingle/domain/usecase/GetPlanLocationListUseCase.kt new file mode 100644 index 00000000..9075dd25 --- /dev/null +++ b/app/src/main/java/org/sopt/pingle/domain/usecase/GetPlanLocationListUseCase.kt @@ -0,0 +1,12 @@ +package org.sopt.pingle.domain.usecase + +import kotlinx.coroutines.flow.Flow +import org.sopt.pingle.domain.model.PlanLocationEntity +import org.sopt.pingle.domain.repository.PlanRepository + +class GetPlanLocationListUseCase( + private val planRepository: PlanRepository +) { + suspend operator fun invoke(searchWord: String): Flow> = + planRepository.getPlanLocationList(searchWord = searchWord) +} diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plandatetime/PlanDateTimeFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plandatetime/PlanDateTimeFragment.kt index 6a8971ca..7ea91916 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plandatetime/PlanDateTimeFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/plandatetime/PlanDateTimeFragment.kt @@ -3,6 +3,7 @@ package org.sopt.pingle.presentation.ui.main.plan.plandatetime import android.os.Bundle import android.view.View import androidx.fragment.app.activityViewModels +import dagger.hilt.android.AndroidEntryPoint import java.text.SimpleDateFormat import java.time.LocalDate import java.util.Locale @@ -12,6 +13,7 @@ import org.sopt.pingle.presentation.ui.main.plan.PlanViewModel import org.sopt.pingle.util.base.BindingFragment import org.sopt.pingle.util.component.PingleSnackbar +@AndroidEntryPoint class PlanDateTimeFragment : BindingFragment(R.layout.fragment_plan_date_time) { private val planViewModel: PlanViewModel by activityViewModels() From 5ea16ded699c335ffc1814eacc9c868a8b665546 Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Thu, 11 Jan 2024 07:05:18 +0900 Subject: [PATCH 05/15] =?UTF-8?q?[feat]=20#92=20=EB=8B=A8=EC=9D=BC?= =?UTF-8?q?=EC=84=A0=ED=83=9D=20=EB=A1=9C=EC=A7=81=EC=9D=84=20=EC=A0=9C?= =?UTF-8?q?=EC=99=B8=ED=95=9C=20=EC=84=9C=EB=B2=84=ED=86=B5=EC=8B=A0=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/model/PlanLocationModel.kt | 9 ++ .../ui/main/plan/PlanViewModel.kt | 98 ++++++++----------- .../plan/planlocation/PlanLocationFragment.kt | 43 +++++--- 3 files changed, 79 insertions(+), 71 deletions(-) create mode 100644 app/src/main/java/org/sopt/pingle/presentation/model/PlanLocationModel.kt diff --git a/app/src/main/java/org/sopt/pingle/presentation/model/PlanLocationModel.kt b/app/src/main/java/org/sopt/pingle/presentation/model/PlanLocationModel.kt new file mode 100644 index 00000000..cf00f36c --- /dev/null +++ b/app/src/main/java/org/sopt/pingle/presentation/model/PlanLocationModel.kt @@ -0,0 +1,9 @@ +package org.sopt.pingle.presentation.model + +import androidx.databinding.ObservableBoolean +import org.sopt.pingle.domain.model.PlanLocationEntity + +data class PlanLocationModel( + val planLocation: PlanLocationEntity, + var isSelected: ObservableBoolean = ObservableBoolean(false) +) diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt index 96af2293..5356edc1 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt @@ -2,18 +2,27 @@ package org.sopt.pingle.presentation.ui.main.plan import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch import org.sopt.pingle.domain.model.PlanLocationEntity +import org.sopt.pingle.domain.usecase.GetPlanLocationListUseCase import org.sopt.pingle.presentation.type.CategoryType import org.sopt.pingle.presentation.type.PlanType import org.sopt.pingle.util.combineAll +import org.sopt.pingle.util.view.UiState -class PlanViewModel : ViewModel() { +@HiltViewModel +class PlanViewModel @Inject constructor( + private val getPlanLocationListUseCase: GetPlanLocationListUseCase +) : ViewModel() { private val _currentPage = MutableStateFlow(FIRST_PAGE_POSITION) val currentPage get() = _currentPage.asStateFlow() val planTitle = MutableStateFlow("") @@ -106,16 +115,32 @@ class PlanViewModel : ViewModel() { _selectedTimeType.value = timeType } - private fun setPlanLocation(position: Int) { - _selectedLocation.value = _planLocationList.value[position] - } +// private fun setPlanLocation(position: Int) { +// _selectedLocation.value = _planLocationList.value[position] +// } private var oldPosition = DEFAULT_OLD_POSITION - private val _planLocationList = MutableStateFlow>(emptyList()) - val planLocationList get() = _planLocationList.asStateFlow() + private val _planLocationListState = + MutableStateFlow>>(UiState.Empty) + val planLocationListState get() = _planLocationListState.asStateFlow() + + fun getPlanLocationList(searchWord: String) { + viewModelScope.launch { + _planLocationListState.value = UiState.Loading + runCatching { + getPlanLocationListUseCase(searchWord).collect() { planLocationList -> + _planLocationListState.value = UiState.Success( + planLocationList + ) + } + }.onFailure { exception: Throwable -> + _planLocationListState.value = UiState.Error(exception.message) + } + } + } - fun updatePlanLocationList(position: Int) { + /*fun updatePlanLocationList(position: Int) { when (oldPosition) { DEFAULT_OLD_POSITION -> { setIsSelected(position) @@ -131,62 +156,23 @@ class PlanViewModel : ViewModel() { setIsSelected(position) } } - _selectedLocation.value = if (getIsSelected(position)) _planLocationList.value[position] else null + _selectedLocation.value = + if (getIsSelected(position)) _planLocationListState.value[position] else null oldPosition = position - } + }*/ - // 이전 값이 -> 초기값 + 셀렉티드 값이 있으면 - fun checkIsNull(): Boolean { - return _planLocationList.value.isEmpty() + // 이전 값이 -> 초기값 + 렉셀티드 값이 있으면 + /*fun checkIsNull(): Boolean { + return _planLocationListState.value.isEmpty() // TODO return planLocationList.value.isEmpty() - } + }*/ - private fun setIsSelected(position: Int) { - _planLocationList.value[position].isSelected.set(!_planLocationList.value[position].isSelected.get()) + /*private fun setIsSelected(position: Int) { + _planLocationListState.value[position].isSelected.set(!_planLocationListState.value[position].isSelected.get()) } private fun getIsSelected(position: Int) = _planLocationList.value[position].isSelected.get() - - init { - _planLocationList.value = listOf( - PlanLocationEntity( - location = "하얀집", - address = "서울 중구 퇴계로6길 12", - x = 123.5, - y = 56.7 - ), - PlanLocationEntity( - location = "하얀집2호점", - address = "서울 중구 퇴계로6길 12", - x = 123.5, - y = 56.7 - ), - PlanLocationEntity( - location = "하얀집3호점", - address = "서울 중구 퇴계로6길 12", - x = 123.5, - y = 56.7 - ), - PlanLocationEntity( - location = "하얀집 싫어싫어싫어", - address = "서울 중구 퇴계로6길 12", - x = 123.5, - y = 56.7 - ), - PlanLocationEntity( - location = "하얀집 좋아좋아좋아", - address = "서울 중구 퇴계로6길 12", - x = 123.5, - y = 56.7 - ), - PlanLocationEntity( - location = "하얀집웅시러", - address = "서울 중구 퇴계로6길 12", - x = 123.5, - y = 56.7 - ) - ) - } +*/ companion object { const val FIRST_PAGE_POSITION = 0 diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt index dc3f677d..10966084 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt @@ -4,13 +4,17 @@ import android.os.Bundle import android.view.KeyEvent import android.view.View import androidx.fragment.app.activityViewModels -import androidx.recyclerview.widget.LinearLayoutManager +import androidx.lifecycle.flowWithLifecycle +import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.sopt.pingle.R import org.sopt.pingle.databinding.FragmentPlanLocationBinding import org.sopt.pingle.presentation.ui.main.plan.PlanViewModel import org.sopt.pingle.util.base.BindingFragment import org.sopt.pingle.util.context.hideKeyboard +import org.sopt.pingle.util.view.UiState @AndroidEntryPoint class PlanLocationFragment : @@ -25,30 +29,25 @@ class PlanLocationFragment : initLayout() addListeners() + collectData() } private fun initLayout() { - planLocationViewModel.getPlanLocationList() - binding.rvPlanLocationList.apply { - this.layoutManager = LinearLayoutManager(context) - adapter = planLocationAdapter - /*addItemDecoration( - PlanLocationDivider(1, R.color.g_09), - )*/ - } - planLocationAdapter.submitList(planLocationViewModel.planLocationList.value) + binding.rvPlanLocationList.adapter = planLocationAdapter } private fun addListeners() { binding.ivPlanLocationSearchBtn.setOnClickListener { - checkListExist() + // checkListExist() + planLocationViewModel.getPlanLocationList(binding.etPlanLocationSearch.text.toString()) } val searchListener = binding.etPlanLocationSearch searchListener.setOnKeyListener( View.OnKeyListener { _, keyCode, event -> if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_UP) { - checkListExist() + // checkListExist() + planLocationViewModel.getPlanLocationList(binding.etPlanLocationSearch.text.toString()) requireActivity().hideKeyboard(searchListener) return@OnKeyListener true } @@ -57,11 +56,25 @@ class PlanLocationFragment : ) } + private fun collectData() { + planLocationViewModel.planLocationListState.flowWithLifecycle(lifecycle).onEach { uiState -> + when (uiState) { + is UiState.Success -> { + planLocationAdapter.submitList(uiState.data) + + planLocationAdapter.currentList + } + + else -> Unit + } + }.launchIn(lifecycleScope) + } + private fun deleteOldPosition(position: Int) { - planLocationViewModel.updatePlanLocationList(position) + // planLocationViewModel.updatePlanLocationList(position) } - private fun checkListExist() = if (planLocationViewModel.checkIsNull()) { + /* private fun checkListExist() = if (planLocationViewModel.checkIsNull()) { with(binding) { rvPlanLocationList.visibility = View.INVISIBLE layoutPlanLocationEmpty.visibility = View.VISIBLE @@ -71,7 +84,7 @@ class PlanLocationFragment : rvPlanLocationList.visibility = View.VISIBLE layoutPlanLocationEmpty.visibility = View.INVISIBLE } - } + }*/ override fun onDestroyView() { super.onDestroyView() From 296ee4175c4167d722ba0b9e81ecbfd674eb5a41 Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Thu, 11 Jan 2024 20:53:24 +0900 Subject: [PATCH 06/15] =?UTF-8?q?[feat]=20#102=20=EB=B2=88=EA=B0=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/main/plan/PlanViewModel.kt | 62 +++++++++++-------- .../plan/planlocation/PlanLocationFragment.kt | 17 ++--- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt index 5356edc1..7205dee5 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt @@ -3,7 +3,6 @@ package org.sopt.pingle.presentation.ui.main.plan import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -18,10 +17,11 @@ import org.sopt.pingle.presentation.type.CategoryType import org.sopt.pingle.presentation.type.PlanType import org.sopt.pingle.util.combineAll import org.sopt.pingle.util.view.UiState +import javax.inject.Inject @HiltViewModel class PlanViewModel @Inject constructor( - private val getPlanLocationListUseCase: GetPlanLocationListUseCase + private val getPlanLocationListUseCase: GetPlanLocationListUseCase, ) : ViewModel() { private val _currentPage = MutableStateFlow(FIRST_PAGE_POSITION) val currentPage get() = _currentPage.asStateFlow() @@ -38,15 +38,22 @@ class PlanViewModel @Inject constructor( val planOpenChattingLink = MutableStateFlow("") val planSummary = MutableStateFlow("") - private val _selectedLocation = MutableStateFlow(null) - val selectedLocation get() = _selectedLocation.asStateFlow() - private val _selectedCategory = MutableStateFlow(null) val selectedCategory get() = _selectedCategory.asStateFlow() private val _selectedRecruitment = MutableStateFlow("1") val selectedRecruitment get() = _selectedRecruitment.asStateFlow() + private val _planLocationListState = + MutableStateFlow>>(UiState.Empty) + val planLocationListState get() = _planLocationListState.asStateFlow() + + private val _planLocationList = MutableStateFlow>(emptyList()) + val planLocationList get() = _planLocationList.asStateFlow() + + private val _selectedLocation = MutableStateFlow(null) + val selectedLocation get() = _selectedLocation.asStateFlow() + val isPlanBtnEnabled: StateFlow = listOf( currentPage, selectedCategory, @@ -57,7 +64,7 @@ class PlanViewModel @Inject constructor( selectedLocation, selectedRecruitment, planOpenChattingLink, - planSummary + planSummary, ).combineAll() .map { values -> val currentPage = values[0] as Int @@ -115,24 +122,29 @@ class PlanViewModel @Inject constructor( _selectedTimeType.value = timeType } -// private fun setPlanLocation(position: Int) { -// _selectedLocation.value = _planLocationList.value[position] -// } + private fun setPlanLocation(position: Int) { + _selectedLocation.value = _planLocationList.value[position] + } private var oldPosition = DEFAULT_OLD_POSITION - private val _planLocationListState = - MutableStateFlow>>(UiState.Empty) - val planLocationListState get() = _planLocationListState.asStateFlow() - fun getPlanLocationList(searchWord: String) { viewModelScope.launch { _planLocationListState.value = UiState.Loading runCatching { getPlanLocationListUseCase(searchWord).collect() { planLocationList -> - _planLocationListState.value = UiState.Success( - planLocationList - ) + when (planLocationList.isEmpty()) { + true -> { + _planLocationListState.value = UiState.Empty + } + + false -> { + _planLocationList.value = planLocationList + _planLocationListState.value = UiState.Success( + planLocationList, + ) + } + } } }.onFailure { exception: Throwable -> _planLocationListState.value = UiState.Error(exception.message) @@ -140,7 +152,7 @@ class PlanViewModel @Inject constructor( } } - /*fun updatePlanLocationList(position: Int) { + fun updatePlanLocationList(position: Int) { when (oldPosition) { DEFAULT_OLD_POSITION -> { setIsSelected(position) @@ -157,22 +169,20 @@ class PlanViewModel @Inject constructor( } } _selectedLocation.value = - if (getIsSelected(position)) _planLocationListState.value[position] else null + if (getIsSelected(position)) _planLocationList.value[position] else null oldPosition = position - }*/ + } // 이전 값이 -> 초기값 + 렉셀티드 값이 있으면 - /*fun checkIsNull(): Boolean { - return _planLocationListState.value.isEmpty() - // TODO return planLocationList.value.isEmpty() - }*/ + fun checkIsNull(): Boolean { + return _planLocationList.value.isEmpty() + } - /*private fun setIsSelected(position: Int) { - _planLocationListState.value[position].isSelected.set(!_planLocationListState.value[position].isSelected.get()) + private fun setIsSelected(position: Int) { + _planLocationList.value[position].isSelected.set(!_planLocationList.value[position].isSelected.get()) } private fun getIsSelected(position: Int) = _planLocationList.value[position].isSelected.get() -*/ companion object { const val FIRST_PAGE_POSITION = 0 diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt index 10966084..f5711319 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt @@ -27,18 +27,13 @@ class PlanLocationFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - initLayout() addListeners() collectData() } - private fun initLayout() { - binding.rvPlanLocationList.adapter = planLocationAdapter - } - private fun addListeners() { binding.ivPlanLocationSearchBtn.setOnClickListener { - // checkListExist() + checkListExist() planLocationViewModel.getPlanLocationList(binding.etPlanLocationSearch.text.toString()) } @@ -46,7 +41,7 @@ class PlanLocationFragment : searchListener.setOnKeyListener( View.OnKeyListener { _, keyCode, event -> if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_UP) { - // checkListExist() + checkListExist() planLocationViewModel.getPlanLocationList(binding.etPlanLocationSearch.text.toString()) requireActivity().hideKeyboard(searchListener) return@OnKeyListener true @@ -60,8 +55,8 @@ class PlanLocationFragment : planLocationViewModel.planLocationListState.flowWithLifecycle(lifecycle).onEach { uiState -> when (uiState) { is UiState.Success -> { + binding.rvPlanLocationList.adapter = planLocationAdapter planLocationAdapter.submitList(uiState.data) - planLocationAdapter.currentList } @@ -71,10 +66,10 @@ class PlanLocationFragment : } private fun deleteOldPosition(position: Int) { - // planLocationViewModel.updatePlanLocationList(position) + planLocationViewModel.updatePlanLocationList(position) } - /* private fun checkListExist() = if (planLocationViewModel.checkIsNull()) { + private fun checkListExist() = if (planLocationViewModel.checkIsNull()) { with(binding) { rvPlanLocationList.visibility = View.INVISIBLE layoutPlanLocationEmpty.visibility = View.VISIBLE @@ -84,7 +79,7 @@ class PlanLocationFragment : rvPlanLocationList.visibility = View.VISIBLE layoutPlanLocationEmpty.visibility = View.INVISIBLE } - }*/ + } override fun onDestroyView() { super.onDestroyView() From 3c3131a0c794f0a02faeb94c8685e7dd1dfb2ab7 Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Thu, 11 Jan 2024 21:38:34 +0900 Subject: [PATCH 07/15] =?UTF-8?q?[mod]=20#102=20=EC=97=A0=ED=8B=B0?= =?UTF-8?q?=EB=B7=B0,=20=EB=B2=84=ED=8A=BC=20=EB=B9=84=ED=99=9C=EC=84=B1?= =?UTF-8?q?=ED=99=94=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/main/plan/PlanViewModel.kt | 23 +++++++--------- .../plan/planlocation/PlanLocationFragment.kt | 26 +++++++++---------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt index 7205dee5..aa684c03 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt @@ -3,9 +3,11 @@ package org.sopt.pingle.presentation.ui.main.plan import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.map @@ -45,8 +47,8 @@ class PlanViewModel @Inject constructor( val selectedRecruitment get() = _selectedRecruitment.asStateFlow() private val _planLocationListState = - MutableStateFlow>>(UiState.Empty) - val planLocationListState get() = _planLocationListState.asStateFlow() + MutableSharedFlow>>() + val planLocationListState get() = _planLocationListState.asSharedFlow() private val _planLocationList = MutableStateFlow>(emptyList()) val planLocationList get() = _planLocationList.asStateFlow() @@ -130,24 +132,24 @@ class PlanViewModel @Inject constructor( fun getPlanLocationList(searchWord: String) { viewModelScope.launch { - _planLocationListState.value = UiState.Loading + _planLocationListState.emit(UiState.Loading) + _planLocationList.value = emptyList() + _selectedLocation.value = null runCatching { getPlanLocationListUseCase(searchWord).collect() { planLocationList -> when (planLocationList.isEmpty()) { true -> { - _planLocationListState.value = UiState.Empty + _planLocationListState.emit(UiState.Empty) } false -> { _planLocationList.value = planLocationList - _planLocationListState.value = UiState.Success( - planLocationList, - ) + _planLocationListState.emit(UiState.Success(planLocationList)) } } } }.onFailure { exception: Throwable -> - _planLocationListState.value = UiState.Error(exception.message) + _planLocationListState.emit(UiState.Error(exception.message)) } } } @@ -173,11 +175,6 @@ class PlanViewModel @Inject constructor( oldPosition = position } - // 이전 값이 -> 초기값 + 렉셀티드 값이 있으면 - fun checkIsNull(): Boolean { - return _planLocationList.value.isEmpty() - } - private fun setIsSelected(position: Int) { _planLocationList.value[position].isSelected.set(!_planLocationList.value[position].isSelected.get()) } diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt index f5711319..dfa26460 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt @@ -33,7 +33,6 @@ class PlanLocationFragment : private fun addListeners() { binding.ivPlanLocationSearchBtn.setOnClickListener { - checkListExist() planLocationViewModel.getPlanLocationList(binding.etPlanLocationSearch.text.toString()) } @@ -41,7 +40,6 @@ class PlanLocationFragment : searchListener.setOnKeyListener( View.OnKeyListener { _, keyCode, event -> if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_UP) { - checkListExist() planLocationViewModel.getPlanLocationList(binding.etPlanLocationSearch.text.toString()) requireActivity().hideKeyboard(searchListener) return@OnKeyListener true @@ -58,6 +56,18 @@ class PlanLocationFragment : binding.rvPlanLocationList.adapter = planLocationAdapter planLocationAdapter.submitList(uiState.data) planLocationAdapter.currentList + + with(binding) { + rvPlanLocationList.visibility = View.VISIBLE + layoutPlanLocationEmpty.visibility = View.INVISIBLE + } + } + + is UiState.Empty -> { + with(binding) { + rvPlanLocationList.visibility = View.INVISIBLE + layoutPlanLocationEmpty.visibility = View.VISIBLE + } } else -> Unit @@ -69,18 +79,6 @@ class PlanLocationFragment : planLocationViewModel.updatePlanLocationList(position) } - private fun checkListExist() = if (planLocationViewModel.checkIsNull()) { - with(binding) { - rvPlanLocationList.visibility = View.INVISIBLE - layoutPlanLocationEmpty.visibility = View.VISIBLE - } - } else { - with(binding) { - rvPlanLocationList.visibility = View.VISIBLE - layoutPlanLocationEmpty.visibility = View.INVISIBLE - } - } - override fun onDestroyView() { super.onDestroyView() binding.rvPlanLocationList.adapter = null From 20a127a4f949bff97a771c43cc00b6883ed2bdb1 Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Thu, 11 Jan 2024 21:39:17 +0900 Subject: [PATCH 08/15] =?UTF-8?q?[chore]=20#102=20ktlint=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt index aa684c03..82fc42dd 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt @@ -3,6 +3,7 @@ package org.sopt.pingle.presentation.ui.main.plan import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted @@ -19,11 +20,10 @@ import org.sopt.pingle.presentation.type.CategoryType import org.sopt.pingle.presentation.type.PlanType import org.sopt.pingle.util.combineAll import org.sopt.pingle.util.view.UiState -import javax.inject.Inject @HiltViewModel class PlanViewModel @Inject constructor( - private val getPlanLocationListUseCase: GetPlanLocationListUseCase, + private val getPlanLocationListUseCase: GetPlanLocationListUseCase ) : ViewModel() { private val _currentPage = MutableStateFlow(FIRST_PAGE_POSITION) val currentPage get() = _currentPage.asStateFlow() @@ -66,7 +66,7 @@ class PlanViewModel @Inject constructor( selectedLocation, selectedRecruitment, planOpenChattingLink, - planSummary, + planSummary ).combineAll() .map { values -> val currentPage = values[0] as Int From 009ba196d0c8250bf571bb22182d797b141fcddf Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Thu, 11 Jan 2024 20:53:24 +0900 Subject: [PATCH 09/15] =?UTF-8?q?[feat]=20#92=20=EB=B2=88=EA=B0=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/main/plan/PlanViewModel.kt | 62 +++++++++++-------- .../plan/planlocation/PlanLocationFragment.kt | 17 ++--- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt index 5356edc1..7205dee5 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt @@ -3,7 +3,6 @@ package org.sopt.pingle.presentation.ui.main.plan import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -18,10 +17,11 @@ import org.sopt.pingle.presentation.type.CategoryType import org.sopt.pingle.presentation.type.PlanType import org.sopt.pingle.util.combineAll import org.sopt.pingle.util.view.UiState +import javax.inject.Inject @HiltViewModel class PlanViewModel @Inject constructor( - private val getPlanLocationListUseCase: GetPlanLocationListUseCase + private val getPlanLocationListUseCase: GetPlanLocationListUseCase, ) : ViewModel() { private val _currentPage = MutableStateFlow(FIRST_PAGE_POSITION) val currentPage get() = _currentPage.asStateFlow() @@ -38,15 +38,22 @@ class PlanViewModel @Inject constructor( val planOpenChattingLink = MutableStateFlow("") val planSummary = MutableStateFlow("") - private val _selectedLocation = MutableStateFlow(null) - val selectedLocation get() = _selectedLocation.asStateFlow() - private val _selectedCategory = MutableStateFlow(null) val selectedCategory get() = _selectedCategory.asStateFlow() private val _selectedRecruitment = MutableStateFlow("1") val selectedRecruitment get() = _selectedRecruitment.asStateFlow() + private val _planLocationListState = + MutableStateFlow>>(UiState.Empty) + val planLocationListState get() = _planLocationListState.asStateFlow() + + private val _planLocationList = MutableStateFlow>(emptyList()) + val planLocationList get() = _planLocationList.asStateFlow() + + private val _selectedLocation = MutableStateFlow(null) + val selectedLocation get() = _selectedLocation.asStateFlow() + val isPlanBtnEnabled: StateFlow = listOf( currentPage, selectedCategory, @@ -57,7 +64,7 @@ class PlanViewModel @Inject constructor( selectedLocation, selectedRecruitment, planOpenChattingLink, - planSummary + planSummary, ).combineAll() .map { values -> val currentPage = values[0] as Int @@ -115,24 +122,29 @@ class PlanViewModel @Inject constructor( _selectedTimeType.value = timeType } -// private fun setPlanLocation(position: Int) { -// _selectedLocation.value = _planLocationList.value[position] -// } + private fun setPlanLocation(position: Int) { + _selectedLocation.value = _planLocationList.value[position] + } private var oldPosition = DEFAULT_OLD_POSITION - private val _planLocationListState = - MutableStateFlow>>(UiState.Empty) - val planLocationListState get() = _planLocationListState.asStateFlow() - fun getPlanLocationList(searchWord: String) { viewModelScope.launch { _planLocationListState.value = UiState.Loading runCatching { getPlanLocationListUseCase(searchWord).collect() { planLocationList -> - _planLocationListState.value = UiState.Success( - planLocationList - ) + when (planLocationList.isEmpty()) { + true -> { + _planLocationListState.value = UiState.Empty + } + + false -> { + _planLocationList.value = planLocationList + _planLocationListState.value = UiState.Success( + planLocationList, + ) + } + } } }.onFailure { exception: Throwable -> _planLocationListState.value = UiState.Error(exception.message) @@ -140,7 +152,7 @@ class PlanViewModel @Inject constructor( } } - /*fun updatePlanLocationList(position: Int) { + fun updatePlanLocationList(position: Int) { when (oldPosition) { DEFAULT_OLD_POSITION -> { setIsSelected(position) @@ -157,22 +169,20 @@ class PlanViewModel @Inject constructor( } } _selectedLocation.value = - if (getIsSelected(position)) _planLocationListState.value[position] else null + if (getIsSelected(position)) _planLocationList.value[position] else null oldPosition = position - }*/ + } // 이전 값이 -> 초기값 + 렉셀티드 값이 있으면 - /*fun checkIsNull(): Boolean { - return _planLocationListState.value.isEmpty() - // TODO return planLocationList.value.isEmpty() - }*/ + fun checkIsNull(): Boolean { + return _planLocationList.value.isEmpty() + } - /*private fun setIsSelected(position: Int) { - _planLocationListState.value[position].isSelected.set(!_planLocationListState.value[position].isSelected.get()) + private fun setIsSelected(position: Int) { + _planLocationList.value[position].isSelected.set(!_planLocationList.value[position].isSelected.get()) } private fun getIsSelected(position: Int) = _planLocationList.value[position].isSelected.get() -*/ companion object { const val FIRST_PAGE_POSITION = 0 diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt index 10966084..f5711319 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt @@ -27,18 +27,13 @@ class PlanLocationFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - initLayout() addListeners() collectData() } - private fun initLayout() { - binding.rvPlanLocationList.adapter = planLocationAdapter - } - private fun addListeners() { binding.ivPlanLocationSearchBtn.setOnClickListener { - // checkListExist() + checkListExist() planLocationViewModel.getPlanLocationList(binding.etPlanLocationSearch.text.toString()) } @@ -46,7 +41,7 @@ class PlanLocationFragment : searchListener.setOnKeyListener( View.OnKeyListener { _, keyCode, event -> if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_UP) { - // checkListExist() + checkListExist() planLocationViewModel.getPlanLocationList(binding.etPlanLocationSearch.text.toString()) requireActivity().hideKeyboard(searchListener) return@OnKeyListener true @@ -60,8 +55,8 @@ class PlanLocationFragment : planLocationViewModel.planLocationListState.flowWithLifecycle(lifecycle).onEach { uiState -> when (uiState) { is UiState.Success -> { + binding.rvPlanLocationList.adapter = planLocationAdapter planLocationAdapter.submitList(uiState.data) - planLocationAdapter.currentList } @@ -71,10 +66,10 @@ class PlanLocationFragment : } private fun deleteOldPosition(position: Int) { - // planLocationViewModel.updatePlanLocationList(position) + planLocationViewModel.updatePlanLocationList(position) } - /* private fun checkListExist() = if (planLocationViewModel.checkIsNull()) { + private fun checkListExist() = if (planLocationViewModel.checkIsNull()) { with(binding) { rvPlanLocationList.visibility = View.INVISIBLE layoutPlanLocationEmpty.visibility = View.VISIBLE @@ -84,7 +79,7 @@ class PlanLocationFragment : rvPlanLocationList.visibility = View.VISIBLE layoutPlanLocationEmpty.visibility = View.INVISIBLE } - }*/ + } override fun onDestroyView() { super.onDestroyView() From e03ec5ff9a9da458185eae44df4aa7eef468ad88 Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Thu, 11 Jan 2024 21:38:34 +0900 Subject: [PATCH 10/15] =?UTF-8?q?[mod]=20#92=20=EC=97=A0=ED=8B=B0=EB=B7=B0?= =?UTF-8?q?,=20=EB=B2=84=ED=8A=BC=20=EB=B9=84=ED=99=9C=EC=84=B1=ED=99=94?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/main/plan/PlanViewModel.kt | 23 +++++++--------- .../plan/planlocation/PlanLocationFragment.kt | 26 +++++++++---------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt index 7205dee5..aa684c03 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt @@ -3,9 +3,11 @@ package org.sopt.pingle.presentation.ui.main.plan import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.map @@ -45,8 +47,8 @@ class PlanViewModel @Inject constructor( val selectedRecruitment get() = _selectedRecruitment.asStateFlow() private val _planLocationListState = - MutableStateFlow>>(UiState.Empty) - val planLocationListState get() = _planLocationListState.asStateFlow() + MutableSharedFlow>>() + val planLocationListState get() = _planLocationListState.asSharedFlow() private val _planLocationList = MutableStateFlow>(emptyList()) val planLocationList get() = _planLocationList.asStateFlow() @@ -130,24 +132,24 @@ class PlanViewModel @Inject constructor( fun getPlanLocationList(searchWord: String) { viewModelScope.launch { - _planLocationListState.value = UiState.Loading + _planLocationListState.emit(UiState.Loading) + _planLocationList.value = emptyList() + _selectedLocation.value = null runCatching { getPlanLocationListUseCase(searchWord).collect() { planLocationList -> when (planLocationList.isEmpty()) { true -> { - _planLocationListState.value = UiState.Empty + _planLocationListState.emit(UiState.Empty) } false -> { _planLocationList.value = planLocationList - _planLocationListState.value = UiState.Success( - planLocationList, - ) + _planLocationListState.emit(UiState.Success(planLocationList)) } } } }.onFailure { exception: Throwable -> - _planLocationListState.value = UiState.Error(exception.message) + _planLocationListState.emit(UiState.Error(exception.message)) } } } @@ -173,11 +175,6 @@ class PlanViewModel @Inject constructor( oldPosition = position } - // 이전 값이 -> 초기값 + 렉셀티드 값이 있으면 - fun checkIsNull(): Boolean { - return _planLocationList.value.isEmpty() - } - private fun setIsSelected(position: Int) { _planLocationList.value[position].isSelected.set(!_planLocationList.value[position].isSelected.get()) } diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt index f5711319..dfa26460 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt @@ -33,7 +33,6 @@ class PlanLocationFragment : private fun addListeners() { binding.ivPlanLocationSearchBtn.setOnClickListener { - checkListExist() planLocationViewModel.getPlanLocationList(binding.etPlanLocationSearch.text.toString()) } @@ -41,7 +40,6 @@ class PlanLocationFragment : searchListener.setOnKeyListener( View.OnKeyListener { _, keyCode, event -> if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_UP) { - checkListExist() planLocationViewModel.getPlanLocationList(binding.etPlanLocationSearch.text.toString()) requireActivity().hideKeyboard(searchListener) return@OnKeyListener true @@ -58,6 +56,18 @@ class PlanLocationFragment : binding.rvPlanLocationList.adapter = planLocationAdapter planLocationAdapter.submitList(uiState.data) planLocationAdapter.currentList + + with(binding) { + rvPlanLocationList.visibility = View.VISIBLE + layoutPlanLocationEmpty.visibility = View.INVISIBLE + } + } + + is UiState.Empty -> { + with(binding) { + rvPlanLocationList.visibility = View.INVISIBLE + layoutPlanLocationEmpty.visibility = View.VISIBLE + } } else -> Unit @@ -69,18 +79,6 @@ class PlanLocationFragment : planLocationViewModel.updatePlanLocationList(position) } - private fun checkListExist() = if (planLocationViewModel.checkIsNull()) { - with(binding) { - rvPlanLocationList.visibility = View.INVISIBLE - layoutPlanLocationEmpty.visibility = View.VISIBLE - } - } else { - with(binding) { - rvPlanLocationList.visibility = View.VISIBLE - layoutPlanLocationEmpty.visibility = View.INVISIBLE - } - } - override fun onDestroyView() { super.onDestroyView() binding.rvPlanLocationList.adapter = null From ed0741eae4da746c9e6e2bdaff7f7ce78663d1d0 Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Thu, 11 Jan 2024 21:39:17 +0900 Subject: [PATCH 11/15] =?UTF-8?q?[chore]=20#92=20ktlint=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt index aa684c03..82fc42dd 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt @@ -3,6 +3,7 @@ package org.sopt.pingle.presentation.ui.main.plan import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted @@ -19,11 +20,10 @@ import org.sopt.pingle.presentation.type.CategoryType import org.sopt.pingle.presentation.type.PlanType import org.sopt.pingle.util.combineAll import org.sopt.pingle.util.view.UiState -import javax.inject.Inject @HiltViewModel class PlanViewModel @Inject constructor( - private val getPlanLocationListUseCase: GetPlanLocationListUseCase, + private val getPlanLocationListUseCase: GetPlanLocationListUseCase ) : ViewModel() { private val _currentPage = MutableStateFlow(FIRST_PAGE_POSITION) val currentPage get() = _currentPage.asStateFlow() @@ -66,7 +66,7 @@ class PlanViewModel @Inject constructor( selectedLocation, selectedRecruitment, planOpenChattingLink, - planSummary, + planSummary ).combineAll() .map { values -> val currentPage = values[0] as Int From 016b037443f2148633199ed45ddbfcd74d286c2f Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Thu, 11 Jan 2024 22:11:20 +0900 Subject: [PATCH 12/15] =?UTF-8?q?[chore]=20#102=20ktlint=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/org/sopt/pingle/di/RepositoryModule.kt | 2 +- .../org/sopt/pingle/presentation/ui/auth/AuthActivity.kt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/sopt/pingle/di/RepositoryModule.kt b/app/src/main/java/org/sopt/pingle/di/RepositoryModule.kt index aaa3bca4..28f8090d 100644 --- a/app/src/main/java/org/sopt/pingle/di/RepositoryModule.kt +++ b/app/src/main/java/org/sopt/pingle/di/RepositoryModule.kt @@ -8,8 +8,8 @@ import javax.inject.Singleton import org.sopt.pingle.data.repository.AuthRepositoryImpl import org.sopt.pingle.data.repository.DummyRepositoryImpl import org.sopt.pingle.data.repository.MapRepositoryImpl -import org.sopt.pingle.domain.repository.AuthRepository import org.sopt.pingle.data.repository.PlanRepositoryImpl +import org.sopt.pingle.domain.repository.AuthRepository import org.sopt.pingle.domain.repository.DummyRepository import org.sopt.pingle.domain.repository.MapRepository import org.sopt.pingle.domain.repository.PlanRepository diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/auth/AuthActivity.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/auth/AuthActivity.kt index d2657c53..c04a1d73 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/auth/AuthActivity.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/auth/AuthActivity.kt @@ -5,6 +5,7 @@ import android.os.Bundle import androidx.activity.viewModels import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope +import com.kakao.sdk.common.util.Utility import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.flow.launchIn @@ -25,9 +26,8 @@ class AuthActivity : BindingActivity(R.layout.activity_auth override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - // TODO KeyHash 값 가져오기 -// val keyHash = Utility.getKeyHash(this) -// Timber.tag("KeyHash").d(keyHash) + val keyHash = Utility.getKeyHash(this) + Timber.tag("KeyHash").d(keyHash) addListeners() collectData() From cd848b262cf49955ec04bef63769bb12bbdfb4e6 Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Fri, 12 Jan 2024 00:18:27 +0900 Subject: [PATCH 13/15] =?UTF-8?q?[chore]=20#92=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/main/plan/planlocation/PlanLocationFragment.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt index dfa26460..f98e64f2 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt @@ -45,7 +45,7 @@ class PlanLocationFragment : return@OnKeyListener true } false - } + }, ) } @@ -56,7 +56,6 @@ class PlanLocationFragment : binding.rvPlanLocationList.adapter = planLocationAdapter planLocationAdapter.submitList(uiState.data) planLocationAdapter.currentList - with(binding) { rvPlanLocationList.visibility = View.VISIBLE layoutPlanLocationEmpty.visibility = View.INVISIBLE From 15ed99664ccc6146636d27f0c2bb5a477b5eb733 Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Fri, 12 Jan 2024 00:20:32 +0900 Subject: [PATCH 14/15] =?UTF-8?q?[chore]=20#92=20ktlint=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/main/plan/planlocation/PlanLocationFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt index f98e64f2..b41aee76 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt @@ -45,7 +45,7 @@ class PlanLocationFragment : return@OnKeyListener true } false - }, + } ) } From a0475391b68aea1b32895728707ff334000808c4 Mon Sep 17 00:00:00 2001 From: JIEUNI Date: Fri, 12 Jan 2024 00:29:42 +0900 Subject: [PATCH 15/15] =?UTF-8?q?[chore]=20#92=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81=20=EB=B0=8F=20ktlint=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/sopt/pingle/di/ServiceModule.kt | 2 +- .../java/org/sopt/pingle/di/UseCaseModule.kt | 2 +- .../plan/planlocation/PlanLocationFragment.kt | 17 ++++++++--------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/sopt/pingle/di/ServiceModule.kt b/app/src/main/java/org/sopt/pingle/di/ServiceModule.kt index 1df50da0..6c04eb0d 100644 --- a/app/src/main/java/org/sopt/pingle/di/ServiceModule.kt +++ b/app/src/main/java/org/sopt/pingle/di/ServiceModule.kt @@ -8,8 +8,8 @@ import javax.inject.Singleton import org.sopt.pingle.data.service.AuthService import org.sopt.pingle.data.service.DummyService import org.sopt.pingle.data.service.MapService -import org.sopt.pingle.data.service.PlanService import org.sopt.pingle.data.service.PingleService +import org.sopt.pingle.data.service.PlanService import org.sopt.pingle.di.qualifier.Pingle import retrofit2.Retrofit import retrofit2.create diff --git a/app/src/main/java/org/sopt/pingle/di/UseCaseModule.kt b/app/src/main/java/org/sopt/pingle/di/UseCaseModule.kt index 00382e35..3056b06f 100644 --- a/app/src/main/java/org/sopt/pingle/di/UseCaseModule.kt +++ b/app/src/main/java/org/sopt/pingle/di/UseCaseModule.kt @@ -12,9 +12,9 @@ import org.sopt.pingle.domain.repository.PlanRepository import org.sopt.pingle.domain.usecase.GetDummyUserListUseCase import org.sopt.pingle.domain.usecase.GetPinListWithoutFilteringUseCase import org.sopt.pingle.domain.usecase.GetPingleListUseCase +import org.sopt.pingle.domain.usecase.GetPlanLocationListUseCase import org.sopt.pingle.domain.usecase.PostPingleCancelUseCase import org.sopt.pingle.domain.usecase.PostPingleJoinUseCase -import org.sopt.pingle.domain.usecase.GetPlanLocationListUseCase import org.sopt.pingle.domain.usecase.SetDummyDataUseCase @Module diff --git a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt index b41aee76..ab73d563 100644 --- a/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt +++ b/app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/planlocation/PlanLocationFragment.kt @@ -27,10 +27,15 @@ class PlanLocationFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + initLayout() addListeners() collectData() } + private fun initLayout() { + binding.rvPlanLocationList.adapter = planLocationAdapter + } + private fun addListeners() { binding.ivPlanLocationSearchBtn.setOnClickListener { planLocationViewModel.getPlanLocationList(binding.etPlanLocationSearch.text.toString()) @@ -53,20 +58,14 @@ class PlanLocationFragment : planLocationViewModel.planLocationListState.flowWithLifecycle(lifecycle).onEach { uiState -> when (uiState) { is UiState.Success -> { - binding.rvPlanLocationList.adapter = planLocationAdapter planLocationAdapter.submitList(uiState.data) planLocationAdapter.currentList - with(binding) { - rvPlanLocationList.visibility = View.VISIBLE - layoutPlanLocationEmpty.visibility = View.INVISIBLE - } + binding.layoutPlanLocationEmpty.visibility = View.INVISIBLE } is UiState.Empty -> { - with(binding) { - rvPlanLocationList.visibility = View.INVISIBLE - layoutPlanLocationEmpty.visibility = View.VISIBLE - } + planLocationAdapter.submitList(null) + binding.layoutPlanLocationEmpty.visibility = View.VISIBLE } else -> Unit