From 39399b61b7874be0f19d4e0f0e85da8e1241a425 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 17 Jul 2024 13:18:36 +0900 Subject: [PATCH 01/83] =?UTF-8?q?[feat/#29]=20=ED=99=88=20repository,=20da?= =?UTF-8?q?tasource=20=ED=8C=8C=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/depromeet/data/datasource/HomeDataSource.kt | 5 +++++ .../data/datasource/remote/HomeDataSourceImpl.kt | 10 ++++++++++ .../java/com/depromeet/data/remote/HomeApiService.kt | 4 ++++ .../depromeet/data/repository/HomeRepositoryImpl.kt | 10 ++++++++++ .../com/depromeet/domain/repository/HomeRepository.kt | 4 ++++ 5 files changed, 33 insertions(+) create mode 100644 data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt create mode 100644 data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt create mode 100644 data/src/main/java/com/depromeet/data/remote/HomeApiService.kt create mode 100644 data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt create mode 100644 domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt new file mode 100644 index 00000000..bedf8564 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -0,0 +1,5 @@ +package com.depromeet.data.datasource + +interface HomeDataSource { + +} \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt new file mode 100644 index 00000000..7871d45b --- /dev/null +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -0,0 +1,10 @@ +package com.depromeet.data.datasource.remote + +import com.depromeet.data.datasource.HomeDataSource +import com.depromeet.data.remote.HomeApiService +import javax.inject.Inject + +class HomeDataSourceImpl @Inject constructor( + private val homeApiService: HomeApiService +) : HomeDataSource { +} \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt new file mode 100644 index 00000000..467c1d41 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -0,0 +1,4 @@ +package com.depromeet.data.remote + +interface HomeApiService { +} \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt new file mode 100644 index 00000000..37c97760 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -0,0 +1,10 @@ +package com.depromeet.data.repository + +import com.depromeet.data.datasource.HomeDataSource +import com.depromeet.domain.repository.HomeRepository +import javax.inject.Inject + +class HomeRepositoryImpl @Inject constructor( + private val homeDataSource: HomeDataSource, +) : HomeRepository { +} \ No newline at end of file diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt new file mode 100644 index 00000000..c69e229f --- /dev/null +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -0,0 +1,4 @@ +package com.depromeet.domain.repository + +interface HomeRepository { +} \ No newline at end of file From 107bc25ec4cf00ee912fa04d6598418cc4dece3b Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:49:21 +0900 Subject: [PATCH 02/83] =?UTF-8?q?[feat/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=20=EA=B8=B0=EB=A1=9D=20=EA=B8=B0=EB=A1=9D=EB=B3=84=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/seatrecord/SeatRecordActivity.kt | 5 +++++ .../seatrecord/adapter/MonthRecordAdapter.kt | 5 +++++ .../seatrecord/adapter/RecentRecordAdapter.kt | 13 ++++++++++--- .../src/main/res/layout/item_recent_record.xml | 12 ++++++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 200d9ebf..d79fc083 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -165,6 +165,11 @@ class SeatRecordActivity : BaseActivity( startActivity(this) } } + + override fun onMoreRecordClick(item: ReviewMockData) { + //TODO : 버튼은 있지만 동작 정의가 없어서 추후 생기면 진행 예정 + RecordEditDialog().apply { show(supportFragmentManager, this.tag) } + } } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt index dfe493b0..15983fa8 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt @@ -18,6 +18,7 @@ class MonthRecordAdapter() : ListAdapter ) { interface OnItemRecordClickListener { fun onItemRecordClick(item: ReviewMockData) + fun onMoreRecordClick(item: ReviewMockData) } var itemRecordClickListener: OnItemRecordClickListener? = null @@ -56,6 +57,10 @@ class MonthRecordViewHolder( override fun onItemRecordClick(item: ReviewMockData) { itemRecordClickListener?.onItemRecordClick(item) } + + override fun onItemMoreClick(item: ReviewMockData) { + itemRecordClickListener?.onMoreRecordClick(item) + } } } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt index 9d13f27d..36e19eb1 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt @@ -23,6 +23,7 @@ class RecentRecordAdapter( ) { interface OnItemRecordClickListener { fun onItemRecordClick(item: ReviewMockData) + fun onItemMoreClick(item: ReviewMockData) } var itemRecordClickListener: OnItemRecordClickListener? = null @@ -38,9 +39,15 @@ class RecentRecordAdapter( } override fun onBindViewHolder(holder: RecentRecordViewHolder, position: Int) { - holder.bind(getItem(position)) - holder.itemView.setOnClickListener { - itemRecordClickListener?.onItemRecordClick(getItem(position)) + with(holder) { + bind(getItem(position)) + itemView.setOnClickListener { + itemRecordClickListener?.onItemRecordClick(getItem(position)) + } + binding.ibRecentStadiumMore.setOnClickListener { + itemRecordClickListener?.onItemMoreClick(getItem(position)) + } + } } } diff --git a/presentation/src/main/res/layout/item_recent_record.xml b/presentation/src/main/res/layout/item_recent_record.xml index 94fe7bba..1b999586 100644 --- a/presentation/src/main/res/layout/item_recent_record.xml +++ b/presentation/src/main/res/layout/item_recent_record.xml @@ -46,6 +46,18 @@ tools:ignore="contentDescription" tools:src="@drawable/ic_stadium_test" /> + + Date: Wed, 17 Jul 2024 16:29:41 +0900 Subject: [PATCH 03/83] =?UTF-8?q?[feat/#29]=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=8B=A4=EC=9D=B4=EC=96=BC=EB=A1=9C=EA=B7=B8=20=EA=B0=81=20?= =?UTF-8?q?=EB=B7=B0=20=EB=B6=84=EA=B8=B0=20=EC=B2=98=EB=A6=AC=20=EB=B0=8F?= =?UTF-8?q?=20=EB=82=B4=20=EC=8B=9C=EC=95=BC=EA=B8=B0=EB=A1=9D=20=EB=8B=A4?= =?UTF-8?q?=EC=9D=B4=EC=96=BC=EB=A1=9C=EA=B7=B8=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/ConfirmDeleteDialog.kt | 32 ++++++++++++++++-- .../seatrecord/RecordEditDialog.kt | 33 +++++++++++++++++-- .../seatrecord/SeatDetailRecordActivity.kt | 10 ++++-- .../seatrecord/SeatRecordActivity.kt | 17 +++++++--- .../viewmodel/SeatRecordViewModel.kt | 22 +++++++++++++ 5 files changed, 102 insertions(+), 12 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt index 2f7aedf6..28f81d64 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt @@ -5,11 +5,13 @@ import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.View import android.view.WindowManager -import androidx.fragment.app.activityViewModels +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider import com.depromeet.core.base.BindingDialogFragment import com.depromeet.presentation.R import com.depromeet.presentation.databinding.FragmentConfirmDeleteDialogBinding import com.depromeet.presentation.seatrecord.viewmodel.SeatDetailViewModel +import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -17,11 +19,31 @@ class ConfirmDeleteDialog : BindingDialogFragment ViewModelProvider(requireActivity())[SeatDetailViewModel::class.java] + SeatRecordActivity.SEAT_RECORD_TAG -> ViewModelProvider(requireActivity())[SeatRecordViewModel::class.java] + else -> throw IllegalArgumentException("알수 없는 뷰모델 태그") + } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -36,7 +58,11 @@ class ConfirmDeleteDialog : BindingDialogFragment (viewModel as SeatDetailViewModel).removeReviewData() + is SeatRecordViewModel -> (viewModel as SeatRecordViewModel).removeReviewData() + else -> throw IllegalArgumentException("알 수 없는 뷰모델") + } dismiss() } binding.btConfirmCancel.setOnClickListener { diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt index cc3c0529..ab0a926b 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt @@ -2,11 +2,13 @@ package com.depromeet.presentation.seatrecord import android.os.Bundle import android.view.View -import androidx.fragment.app.activityViewModels +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider import com.depromeet.core.base.BindingBottomSheetDialog import com.depromeet.presentation.R import com.depromeet.presentation.databinding.FragmentRecordEditBottomSheetBinding import com.depromeet.presentation.seatrecord.viewmodel.SeatDetailViewModel +import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -14,11 +16,32 @@ class RecordEditDialog : BindingBottomSheetDialog ViewModelProvider(requireActivity())[SeatDetailViewModel::class.java] + SeatRecordActivity.SEAT_RECORD_TAG -> ViewModelProvider(requireActivity())[SeatRecordViewModel::class.java] + else -> throw IllegalArgumentException("알수 없는 뷰모델 태그") + } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -33,7 +56,11 @@ class RecordEditDialog : BindingBottomSheetDialog (viewModel as SeatDetailViewModel).setDeleteEvent() + is SeatRecordViewModel -> (viewModel as SeatRecordViewModel).setDeleteEvent() + else -> throw IllegalArgumentException("알 수 없는 뷰모델") + } dismiss() } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt index a62488e8..89745de9 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt @@ -14,6 +14,10 @@ import dagger.hilt.android.AndroidEntryPoint class SeatDetailRecordActivity : BaseActivity( ActivitySeatDetailRecordBinding::inflate ) { + companion object { + const val SEAT_DETAIL_TAG = "SEAT_DETAIL" + } + private lateinit var detailRecordAdapter: DetailRecordAdapter private val viewModel: SeatDetailViewModel by viewModels() @@ -40,13 +44,15 @@ class SeatDetailRecordActivity : BaseActivity( object : DetailRecordAdapter.OnDetailItemClickListener { override fun onItemMoreClickListener(item: ReviewDetailMockData) { viewModel.setEditReviewId(item.reviewId) - RecordEditDialog().apply { show(supportFragmentManager, this.tag) } + RecordEditDialog.newInstance(SEAT_DETAIL_TAG) + .apply { show(supportFragmentManager, this.tag) } } } } private fun moveConfirmationDialog() { - ConfirmDeleteDialog().apply { show(supportFragmentManager, this.tag) } + ConfirmDeleteDialog.newInstance(SEAT_DETAIL_TAG) + .apply { show(supportFragmentManager, this.tag) } } } \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index d79fc083..83a3205f 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -31,6 +31,7 @@ class SeatRecordActivity : BaseActivity( companion object { private const val START_SPACING_DP = 20 private const val BETWEEN_SPACING_DP = 8 + const val SEAT_RECORD_TAG = "seatRecord" } private lateinit var dateMonthAdapter: DateMonthAdapter @@ -56,6 +57,10 @@ class SeatRecordActivity : BaseActivity( dateMonthAdapter.submitList(updatedMonthList) } + viewModel.deleteClickedEvent.asLiveData().observe(this) { state -> + if (state) moveConfirmationDialog() + } + setClickListener() } @@ -86,8 +91,6 @@ class SeatRecordActivity : BaseActivity( private fun initDateSpinner() { val year = listOf("2024년", "2023년", "2022년", "2021년") -// val adapter = ArrayAdapter(this, R.layout.item_custom_month_spinner_view, year) -// adapter.setDropDownViewResource(R.layout.item_custom_month_spinner_dropdown) val adapter = SpotSpinner( this, @@ -167,11 +170,17 @@ class SeatRecordActivity : BaseActivity( } override fun onMoreRecordClick(item: ReviewMockData) { - //TODO : 버튼은 있지만 동작 정의가 없어서 추후 생기면 진행 예정 - RecordEditDialog().apply { show(supportFragmentManager, this.tag) } + viewModel.setEditReviewId(item.id) + RecordEditDialog.newInstance(SEAT_RECORD_TAG) + .apply { show(supportFragmentManager, this.tag) } } } } } + + private fun moveConfirmationDialog() { + ConfirmDeleteDialog.newInstance(SEAT_RECORD_TAG) + .apply { show(supportFragmentManager, this.tag) } + } } \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index 6a930a63..06c0d13c 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -22,6 +22,12 @@ class SeatRecordViewModel @Inject constructor() : ViewModel() { private val _selectedYear = MutableStateFlow(2024) + private val _deleteClickedEvent = MutableStateFlow(false) + val deleteClickedEvent = _deleteClickedEvent.asStateFlow() + + private val _editReviewId = MutableStateFlow(0) + val editReviewId = _editReviewId.asStateFlow() + fun getSeatRecords() { makeSeatRecordData().onEach { @@ -40,4 +46,20 @@ class SeatRecordViewModel @Inject constructor() : ViewModel() { _selectedMonth.value = month } + fun setEditReviewId(id: Int) { + _editReviewId.value = id + } + + fun setDeleteEvent() { + _deleteClickedEvent.value = true + } + + fun removeReviewData() { + val currentList = _uiState.value.reviews + val updatedList = currentList.filter { review -> + review.id != editReviewId.value + } + _uiState.value = uiState.value.copy(reviews = updatedList) + _deleteClickedEvent.value = false + } } \ No newline at end of file From 8527664bd191efc4ef791e529507ae6803caadc5 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:34:44 +0900 Subject: [PATCH 04/83] =?UTF-8?q?[feat/#29]=20=EA=B8=B0=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=94=ED=85=80=EC=8B=9C=ED=8A=B8=20?= =?UTF-8?q?=EB=8B=A4=EC=9D=B4=EC=96=BC=EB=A1=9C=EA=B7=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=ED=95=98=EA=B8=B0=20=EC=A0=9C=EC=99=B8(1=EC=B0=A8=20M?= =?UTF-8?q?VP=20=EC=A0=9C=EC=99=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/RecordEditDialog.kt | 9 +++--- .../fragment_record_edit_bottom_sheet.xml | 32 ++++++++++--------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt index ab0a926b..e7c17312 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt @@ -51,10 +51,11 @@ class RecordEditDialog : BindingBottomSheetDialog (viewModel as SeatDetailViewModel).setDeleteEvent() diff --git a/presentation/src/main/res/layout/fragment_record_edit_bottom_sheet.xml b/presentation/src/main/res/layout/fragment_record_edit_bottom_sheet.xml index 66ebc21d..4c7560d7 100644 --- a/presentation/src/main/res/layout/fragment_record_edit_bottom_sheet.xml +++ b/presentation/src/main/res/layout/fragment_record_edit_bottom_sheet.xml @@ -5,20 +5,20 @@ android:layout_height="wrap_content" android:background="@drawable/rect_white_fill_top20"> - + + + + + + + + + + + + + + + app:layout_constraintTop_toBottomOf="parent" /> \ No newline at end of file From 3243c50f92510e0b7206d82267bd23ac2f5c6910 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:38:07 +0900 Subject: [PATCH 05/83] =?UTF-8?q?[fix/#29]=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=8B=A4=EC=9D=B4=EC=96=BC=EB=A1=9C=EA=B7=B8=20margin=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EC=A3=BC=EC=84=9D=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/RecordEditDialog.kt | 5 ----- .../fragment_record_edit_bottom_sheet.xml | 20 +++---------------- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt index e7c17312..ef3faf92 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt @@ -51,11 +51,6 @@ class RecordEditDialog : BindingBottomSheetDialog (viewModel as SeatDetailViewModel).setDeleteEvent() diff --git a/presentation/src/main/res/layout/fragment_record_edit_bottom_sheet.xml b/presentation/src/main/res/layout/fragment_record_edit_bottom_sheet.xml index 4c7560d7..7829f035 100644 --- a/presentation/src/main/res/layout/fragment_record_edit_bottom_sheet.xml +++ b/presentation/src/main/res/layout/fragment_record_edit_bottom_sheet.xml @@ -5,28 +5,14 @@ android:layout_height="wrap_content" android:background="@drawable/rect_white_fill_top20"> - - - - - - - - - - - - - - - + app:layout_constraintBottom_toBottomOf="parent" /> \ No newline at end of file From 212c1b54d164a042175c7c6d01774d9fba83f1be Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:49:57 +0900 Subject: [PATCH 06/83] =?UTF-8?q?[feat/#29]=20=EC=A2=8C=EC=84=9D=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20FAB=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/SeatDetailRecordActivity.kt | 10 ++++++ .../layout/activity_seat_detail_record.xml | 31 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt index 89745de9..35c514a8 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt @@ -34,6 +34,8 @@ class SeatDetailRecordActivity : BaseActivity( if (state) moveConfirmationDialog() } + setClickListener() + } private fun setDetailRecordAdapter() { @@ -55,4 +57,12 @@ class SeatDetailRecordActivity : BaseActivity( .apply { show(supportFragmentManager, this.tag) } } + private fun setClickListener() { + with(binding){ + fabDetailUp.setOnClickListener { + rvDetailRecord.smoothScrollToPosition(0) + } + } + } + } \ No newline at end of file diff --git a/presentation/src/main/res/layout/activity_seat_detail_record.xml b/presentation/src/main/res/layout/activity_seat_detail_record.xml index 37a885b2..eb8521dc 100644 --- a/presentation/src/main/res/layout/activity_seat_detail_record.xml +++ b/presentation/src/main/res/layout/activity_seat_detail_record.xml @@ -17,6 +17,37 @@ app:menuIconColor="@color/gray900" app:navigationIcon="@drawable/ic_back" /> + + + + + Date: Wed, 17 Jul 2024 18:43:53 +0900 Subject: [PATCH 07/83] =?UTF-8?q?[feat/#29]=20floatingActionButton=20->=20?= =?UTF-8?q?ImageButton=20(=EB=84=A4=EC=9D=B4=EB=B0=8D=EC=9D=80=20=EB=8F=99?= =?UTF-8?q?=EC=9D=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/res/drawable/circlr_gray900_fill.xml | 6 ++++ .../layout/activity_seat_detail_record.xml | 27 +++++++++-------- .../main/res/layout/activity_seat_record.xml | 29 +++++++++---------- 3 files changed, 33 insertions(+), 29 deletions(-) create mode 100644 presentation/src/main/res/drawable/circlr_gray900_fill.xml diff --git a/presentation/src/main/res/drawable/circlr_gray900_fill.xml b/presentation/src/main/res/drawable/circlr_gray900_fill.xml new file mode 100644 index 00000000..e480c00d --- /dev/null +++ b/presentation/src/main/res/drawable/circlr_gray900_fill.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/presentation/src/main/res/layout/activity_seat_detail_record.xml b/presentation/src/main/res/layout/activity_seat_detail_record.xml index eb8521dc..a45b4491 100644 --- a/presentation/src/main/res/layout/activity_seat_detail_record.xml +++ b/presentation/src/main/res/layout/activity_seat_detail_record.xml @@ -17,35 +17,34 @@ app:menuIconColor="@color/gray900" app:navigationIcon="@drawable/ic_back" /> - - - - From 2da52b6cede9571e5315ce6a695f2756d44cd5fe Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 17 Jul 2024 19:02:04 +0900 Subject: [PATCH 08/83] =?UTF-8?q?[feat/#29]=20MockData=20=EB=82=A0?= =?UTF-8?q?=EC=A7=9C=EB=B3=84=20=EC=A0=95=EB=A0=AC=20=ED=86=B5=ED=95=B4=20?= =?UTF-8?q?UI=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/seatrecord/mockdata/SeatRecordMockData.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt index b542400e..876a099f 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt @@ -83,7 +83,7 @@ fun makeRecordDetailData(): List { ) ) } - return list + return list.sortedBy { it.date } } val monthList = listOf( From 25793a804b5aaceed88b6608fd37ee695e78f766 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 17 Jul 2024 23:07:16 +0900 Subject: [PATCH 09/83] =?UTF-8?q?[feat/#29]=20Home=20DIModule=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/depromeet/spot/di/DataSourceModule.kt | 7 +++++++ .../main/java/com/depromeet/spot/di/RepositoryModule.kt | 7 +++++++ app/src/main/java/com/depromeet/spot/di/ServiceModule.kt | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/app/src/main/java/com/depromeet/spot/di/DataSourceModule.kt b/app/src/main/java/com/depromeet/spot/di/DataSourceModule.kt index 6523f8b3..77f66fb5 100644 --- a/app/src/main/java/com/depromeet/spot/di/DataSourceModule.kt +++ b/app/src/main/java/com/depromeet/spot/di/DataSourceModule.kt @@ -1,6 +1,7 @@ package com.depromeet.spot.di import com.depromeet.data.datasource.ExampleDataSource +import com.depromeet.data.datasource.HomeDataSource import com.depromeet.data.datasource.WebSvgDataSource import com.depromeet.data.datasource.remote.ExampleDataSourcelmpl import com.depromeet.data.datasource.remote.WebSvgDataSourceImpl @@ -25,4 +26,10 @@ abstract class DataSourceModule { abstract fun bindWebSvgDataSource( webSvgDataSourceImpl: WebSvgDataSourceImpl ): WebSvgDataSource + + @Binds + @Singleton + abstract fun bindHomeDataSource( + homeDataSourceImpl: WebSvgDataSourceImpl + ) : HomeDataSource } diff --git a/app/src/main/java/com/depromeet/spot/di/RepositoryModule.kt b/app/src/main/java/com/depromeet/spot/di/RepositoryModule.kt index 26e3e4dc..d851acd8 100644 --- a/app/src/main/java/com/depromeet/spot/di/RepositoryModule.kt +++ b/app/src/main/java/com/depromeet/spot/di/RepositoryModule.kt @@ -3,6 +3,7 @@ package com.depromeet.spot.di import com.depromeet.data.repository.ExampleRepositoryImpl import com.depromeet.data.repository.WebSvgRepositoryImpl import com.depromeet.domain.repository.ExampleRepository +import com.depromeet.domain.repository.HomeRepository import com.depromeet.domain.repository.WebSvgRepository import dagger.Binds import dagger.Module @@ -26,4 +27,10 @@ abstract class RepositoryModule { abstract fun bindWebSvgRepository( webSvgRepositoryImpl: WebSvgRepositoryImpl ): WebSvgRepository + + @Binds + @Singleton + abstract fun bindHomeRepository( + homeRepositoryImpl: ExampleRepositoryImpl + ) : HomeRepository } diff --git a/app/src/main/java/com/depromeet/spot/di/ServiceModule.kt b/app/src/main/java/com/depromeet/spot/di/ServiceModule.kt index e0770772..805b416a 100644 --- a/app/src/main/java/com/depromeet/spot/di/ServiceModule.kt +++ b/app/src/main/java/com/depromeet/spot/di/ServiceModule.kt @@ -1,6 +1,7 @@ package com.depromeet.spot.di import com.depromeet.data.remote.ExampleService +import com.depromeet.data.remote.HomeApiService import com.depromeet.data.remote.WebSvgApiService import dagger.Module import dagger.Provides @@ -22,4 +23,9 @@ object ServiceModule { @Singleton fun provideWebSvgService(@WebSvg retrofit: Retrofit): WebSvgApiService = retrofit.create(WebSvgApiService::class.java) + + @Provides + @Singleton + fun provideHomeService(retrofit: Retrofit): HomeApiService = + retrofit.create(HomeApiService::class.java) } From 3d4aa3f408dd105c76998d8a1ce59ee9c9c5f39c Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 16:32:55 +0900 Subject: [PATCH 10/83] =?UTF-8?q?[feature/#29]=20Home=20DIModule=20Home=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/depromeet/spot/di/DataSourceModule.kt | 5 +++-- .../main/java/com/depromeet/spot/di/RepositoryModule.kt | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/depromeet/spot/di/DataSourceModule.kt b/app/src/main/java/com/depromeet/spot/di/DataSourceModule.kt index 8a8a6ce5..7788eb56 100644 --- a/app/src/main/java/com/depromeet/spot/di/DataSourceModule.kt +++ b/app/src/main/java/com/depromeet/spot/di/DataSourceModule.kt @@ -6,6 +6,7 @@ import com.depromeet.data.datasource.SeatReviewDataSource import com.depromeet.data.datasource.ViewfinderDataSource import com.depromeet.data.datasource.WebSvgDataSource import com.depromeet.data.datasource.remote.ExampleDataSourcelmpl +import com.depromeet.data.datasource.remote.HomeDataSourceImpl import com.depromeet.data.datasource.remote.SeatReviewDataSourceImpl import com.depromeet.data.datasource.remote.WebSvgDataSourceImpl import dagger.Binds @@ -34,8 +35,8 @@ abstract class DataSourceModule { @Binds @Singleton abstract fun bindHomeDataSource( - homeDataSourceImpl: WebSvgDataSourceImpl - ) : HomeDataSource + homeDataSourceImpl: HomeDataSourceImpl, + ): HomeDataSource @Binds @Singleton diff --git a/app/src/main/java/com/depromeet/spot/di/RepositoryModule.kt b/app/src/main/java/com/depromeet/spot/di/RepositoryModule.kt index 5f07d209..0f259cd7 100644 --- a/app/src/main/java/com/depromeet/spot/di/RepositoryModule.kt +++ b/app/src/main/java/com/depromeet/spot/di/RepositoryModule.kt @@ -1,13 +1,14 @@ package com.depromeet.spot.di import com.depromeet.data.repository.ExampleRepositoryImpl +import com.depromeet.data.repository.HomeRepositoryImpl import com.depromeet.data.repository.SeatReviewRepositoryImpl import com.depromeet.data.repository.ViewfinderRepositoryImpl import com.depromeet.data.repository.WebSvgRepositoryImpl import com.depromeet.domain.repository.ExampleRepository +import com.depromeet.domain.repository.HomeRepository import com.depromeet.domain.repository.SeatReviewRepository import com.depromeet.domain.repository.ViewfinderRepository -import com.depromeet.domain.repository.HomeRepository import com.depromeet.domain.repository.WebSvgRepository import dagger.Binds import dagger.Module @@ -34,8 +35,8 @@ abstract class RepositoryModule { @Binds @Singleton abstract fun bindHomeRepository( - homeRepositoryImpl: ExampleRepositoryImpl - ) : HomeRepository + homeRepositoryImpl: HomeRepositoryImpl, + ): HomeRepository @Binds @Singleton From cf1ae85393ccc8e7a8aa71e689491ac18c0c5625 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 16:34:26 +0900 Subject: [PATCH 11/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=20=EA=B8=B0=EB=A1=9D=20API=20data=20=EC=9E=91?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/datasource/HomeDataSource.kt | 7 +- .../datasource/remote/HomeDataSourceImpl.kt | 12 ++- .../com/depromeet/data/mapper/HomeMapper.kt | 63 ++++++++++++++ .../model/request/RequestMySeatRecordDto.kt | 17 ++++ .../response/home/ResponseMySeatRecordDto.kt | 83 +++++++++++++++++++ .../depromeet/data/remote/HomeApiService.kt | 11 +++ .../data/repository/HomeRepositoryImpl.kt | 10 +++ 7 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt create mode 100644 data/src/main/java/com/depromeet/data/model/request/RequestMySeatRecordDto.kt create mode 100644 data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt index bedf8564..c90100e5 100644 --- a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -1,5 +1,10 @@ package com.depromeet.data.datasource -interface HomeDataSource { +import com.depromeet.data.model.request.RequestMySeatRecordDto +import com.depromeet.data.model.response.home.ResponseMySeatRecordDto +interface HomeDataSource { + suspend fun getMySeatRecordData( + requestMySeatRecordDto: RequestMySeatRecordDto, + ): ResponseMySeatRecordDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index 7871d45b..d0e5ec88 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -1,10 +1,20 @@ package com.depromeet.data.datasource.remote import com.depromeet.data.datasource.HomeDataSource +import com.depromeet.data.model.request.RequestMySeatRecordDto +import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.remote.HomeApiService import javax.inject.Inject class HomeDataSourceImpl @Inject constructor( - private val homeApiService: HomeApiService + private val homeApiService: HomeApiService, ) : HomeDataSource { + override suspend fun getMySeatRecordData(requestMySeatRecordDto: RequestMySeatRecordDto): ResponseMySeatRecordDto { + return homeApiService.getMySeatRecord( + requestMySeatRecordDto.offset, + requestMySeatRecordDto.limit, + requestMySeatRecordDto.year, + requestMySeatRecordDto.month + ) + } } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt new file mode 100644 index 00000000..4bf1b373 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt @@ -0,0 +1,63 @@ +package com.depromeet.data.mapper + +import com.depromeet.data.model.request.RequestMySeatRecordDto +import com.depromeet.data.model.response.home.ResponseMySeatRecordDto +import com.depromeet.domain.entity.request.home.MySeatRecordRequest +import com.depromeet.domain.entity.response.home.MySeatRecordResponse + +fun ResponseMySeatRecordDto.toMySeatRecordResponse() = MySeatRecordResponse( + reviews = reviews.map { it.toReviewResponse() }, + totalCount = totalCount, + filteredCount = filteredCount, + offset = offset, + limit = limit, + hasMore = hasMore, + filter = filter.toFilterResponse() +) + +fun ResponseMySeatRecordDto.ResponseFilterDto.toFilterResponse() = + MySeatRecordResponse.FilterResponse( + stadiumId = stadiumId, + year = year, + month = month + ) + + +fun ResponseMySeatRecordDto.ResponseReviewDto.toReviewResponse() = + MySeatRecordResponse.ReviewResponse( + id = id, + stadiumId = stadiumId, + stadiumName = stadiumName, + blockId = blockId, + blockName = blockName, + seatId = seatId, + rowId = rowId, + seatNumber = seatNumber, + date = date, + content = content, + createdAt = createdAt, + updatedAt = updatedAt, + images = images.map { it.toReviewImageResponse() }, + keywords = keywords.map { it.toReviewKeywordResponse() } + ) + +fun ResponseMySeatRecordDto.ResponseReviewDto.ResponseReviewImageDto.toReviewImageResponse() = + MySeatRecordResponse.ReviewResponse.ReviewImageResponse( + id = id, + url = url + ) + +fun ResponseMySeatRecordDto.ResponseReviewDto.ResponseReviewKeywordDto.toReviewKeywordResponse() = + MySeatRecordResponse.ReviewResponse.ReviewKeywordResponse( + id = id, + content = content, + isPositive = isPositive + ) + + +fun MySeatRecordRequest.toMySeatRecordRequestDto() = RequestMySeatRecordDto( + offset = offset, + limit = limit, + year = year, + month = month +) \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/model/request/RequestMySeatRecordDto.kt b/data/src/main/java/com/depromeet/data/model/request/RequestMySeatRecordDto.kt new file mode 100644 index 00000000..193e2027 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/model/request/RequestMySeatRecordDto.kt @@ -0,0 +1,17 @@ +package com.depromeet.data.model.request + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RequestMySeatRecordDto( + @SerialName("offset") + val offset: Int? = null, + @SerialName("limit") + val limit: Int? = null, + @SerialName("year") + val year: Int? = null, + @SerialName("month") + val month: Int? = null, +) + diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt new file mode 100644 index 00000000..4680c9b7 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt @@ -0,0 +1,83 @@ +package com.depromeet.data.model.response.home + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + + +@Serializable +data class ResponseMySeatRecordDto( + @SerialName("reviews") + val reviews: List, + @SerialName("totalCount") + val totalCount: Int, + @SerialName("filteredCount") + val filteredCount: Int, + @SerialName("offset") + val offset: Int, + @SerialName("limit") + val limit: Int, + @SerialName("hasMore") + val hasMore: Boolean, + @SerialName("filter") + val filter: ResponseFilterDto, +) { + @Serializable + data class ResponseReviewDto( + @SerialName("id") + val id: Int, + @SerialName("stadiumId") + val stadiumId: Int, + @SerialName("stadiumName") + val stadiumName: String, + @SerialName("blockId") + val blockId: Int, + @SerialName("blockName") + val blockName: String, + @SerialName("seatId") + val seatId: Int, + @SerialName("rowId") + val rowId: Int, + @SerialName("seatNumber") + val seatNumber: Int, + @SerialName("date") + val date: String, + @SerialName("content") + val content: String, + @SerialName("createdAt") + val createdAt: String, + @SerialName("updatedAt") + val updatedAt: String, + @SerialName("images") + val images: List, + @SerialName("keywords") + val keywords: List, + ) { + @Serializable + data class ResponseReviewImageDto( + @SerialName("id") + val id: Int, + @SerialName("url") + val url: String, + ) + + @Serializable + data class ResponseReviewKeywordDto( + @SerialName("id") + val id: Int, + @SerialName("content") + val content: String, + @SerialName("isPositive") + val isPositive: Boolean, + ) + } + + @Serializable + data class ResponseFilterDto( + @SerialName("stadiumId") + val stadiumId: Int, + @SerialName("year") + val year: Int, + @SerialName("month") + val month: Int, + ) +} diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index 467c1d41..c9d45a15 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -1,4 +1,15 @@ package com.depromeet.data.remote +import com.depromeet.data.model.response.home.ResponseMySeatRecordDto +import retrofit2.http.GET +import retrofit2.http.Query + interface HomeApiService { + @GET("/api/v1/reviews") + suspend fun getMySeatRecord( + @Query("offset") offset: Int?, + @Query("limit") limit: Int?, + @Query("year") year: Int?, + @Query("month") month: Int?, + ): ResponseMySeatRecordDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index 37c97760..ca2b011a 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -1,10 +1,20 @@ package com.depromeet.data.repository import com.depromeet.data.datasource.HomeDataSource +import com.depromeet.data.mapper.toMySeatRecordRequestDto +import com.depromeet.data.mapper.toMySeatRecordResponse +import com.depromeet.domain.entity.request.home.MySeatRecordRequest +import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.repository.HomeRepository import javax.inject.Inject class HomeRepositoryImpl @Inject constructor( private val homeDataSource: HomeDataSource, ) : HomeRepository { + override suspend fun getMySeatRecord(mySeatRecordRequest: MySeatRecordRequest): Result { + return runCatching { + homeDataSource.getMySeatRecordData(mySeatRecordRequest.toMySeatRecordRequestDto()) + .toMySeatRecordResponse() + } + } } \ No newline at end of file From 9ff62952585527b7b68d18871d52f8937e4ff1c1 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 16:34:48 +0900 Subject: [PATCH 12/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=20=EA=B8=B0=EB=A1=9D=20API=20domain=20=EC=9E=91?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/home/MySeatRecordRequest.kt | 10 +++++ .../response/home/MySeatRecordResponse.kt | 45 +++++++++++++++++++ .../domain/repository/HomeRepository.kt | 6 +++ 3 files changed, 61 insertions(+) create mode 100644 domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt create mode 100644 domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt diff --git a/domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt b/domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt new file mode 100644 index 00000000..82ddf7d6 --- /dev/null +++ b/domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt @@ -0,0 +1,10 @@ +package com.depromeet.domain.entity.request.home + +data class MySeatRecordRequest( + val offset: Int ?= null, + val limit: Int ?= 50, + val year: Int ?= 2024, + val month: Int ?= null, +) + + diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt new file mode 100644 index 00000000..9d05bcb7 --- /dev/null +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt @@ -0,0 +1,45 @@ +package com.depromeet.domain.entity.response.home + +data class MySeatRecordResponse( + val reviews: List = emptyList(), + val totalCount: Int = 0, + val filteredCount: Int = 0, + val offset: Int = 0, + val limit: Int = 0, + val hasMore: Boolean = false, + val filter: FilterResponse = FilterResponse(), +) { + data class ReviewResponse( + val id: Int, + val stadiumId: Int, + val stadiumName: String = "", + val blockId: Int = 0, + val blockName: String = "", + val seatId: Int = 0, + val rowId: Int = 0, + val seatNumber: Int = 0, + val date: String = "", + val content: String = "", + val createdAt: String = "", + val updatedAt: String = "", + val images: List = emptyList(), + val keywords: List = emptyList(), + ) { + data class ReviewImageResponse( + val id: Int = 0, + val url: String = "", + ) + + data class ReviewKeywordResponse( + val id: Int = 0, + val content: String = "", + val isPositive: Boolean = false, + ) + } + + data class FilterResponse( + val stadiumId: Int = 0, + val year: Int = 0, + val month: Int = 0, + ) +} diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt index c69e229f..9b8a382e 100644 --- a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -1,4 +1,10 @@ package com.depromeet.domain.repository +import com.depromeet.domain.entity.request.home.MySeatRecordRequest +import com.depromeet.domain.entity.response.home.MySeatRecordResponse + interface HomeRepository { + suspend fun getMySeatRecord( + mySeatRecordRequest: MySeatRecordRequest, + ): Result } \ No newline at end of file From 09ff726d49ad22bfaaf1192ee8cd67e91eaecee6 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:24:34 +0900 Subject: [PATCH 13/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=20=EA=B8=B0=EB=A1=9D=20API=20Presentaiton=20module=20?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/SeatRecordActivity.kt | 49 +++++++++++++++---- .../seatrecord/adapter/MonthRecordAdapter.kt | 31 ++++++------ .../seatrecord/adapter/RecentRecordAdapter.kt | 18 ++++--- .../seatrecord/uiMapper/HomeMapper.kt | 22 +++++++++ .../viewmodel/SeatRecordViewModel.kt | 48 +++++++++++------- 5 files changed, 117 insertions(+), 51 deletions(-) create mode 100644 presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 83a3205f..14186554 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -9,20 +9,24 @@ import androidx.lifecycle.asLiveData import coil.load import coil.transform.CircleCropTransformation import com.depromeet.core.base.BaseActivity +import com.depromeet.core.state.UiState import com.depromeet.designsystem.SpotSpinner import com.depromeet.designsystem.extension.dpToPx +import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ActivitySeatRecordBinding +import com.depromeet.presentation.extension.extractMonth +import com.depromeet.presentation.extension.toast import com.depromeet.presentation.seatrecord.adapter.DateMonthAdapter import com.depromeet.presentation.seatrecord.adapter.LinearSpacingItemDecoration import com.depromeet.presentation.seatrecord.adapter.MonthRecordAdapter import com.depromeet.presentation.seatrecord.mockdata.MonthData import com.depromeet.presentation.seatrecord.mockdata.ProfileDetailData -import com.depromeet.presentation.seatrecord.mockdata.ReviewMockData -import com.depromeet.presentation.seatrecord.mockdata.groupByMonth import com.depromeet.presentation.seatrecord.mockdata.monthList +import com.depromeet.presentation.seatrecord.uiMapper.MonthReviewData import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel import dagger.hilt.android.AndroidEntryPoint +import timber.log.Timber @AndroidEntryPoint class SeatRecordActivity : BaseActivity( @@ -46,9 +50,27 @@ class SeatRecordActivity : BaseActivity( viewModel.getSeatRecords() - viewModel.uiState.asLiveData().observe(this) { - setProfile(it.profileDetailData) - initReviewExist(it.reviews) + viewModel.uiState.asLiveData().observe(this) { state -> + when (state) { + is UiState.Success -> { + Timber.d("성공") + //setProfile() //사용자 프로필 데이터 서버에서 아직 안내려줌 + setReviewList(state.data.reviews) + } + + is UiState.Loading -> { + toast("로딩중") + } + + is UiState.Empty -> { + toast("오류 발생 빈값") + } + + is UiState.Failure -> { + Timber.d("test : ${state.msg}") + } + + } } viewModel.selectedMonth.asLiveData().observe(this) { val updatedMonthList = monthList.map { monthData -> @@ -138,7 +160,7 @@ class SeatRecordActivity : BaseActivity( } } - private fun initReviewExist(reviews: List) { + private fun setReviewList(reviews: List) { if (reviews.isEmpty()) { with(binding) { "${viewModel.selectedMonth.value}년".also { tvRecordYear.text = it } @@ -156,11 +178,17 @@ class SeatRecordActivity : BaseActivity( rvRecordMonthDetail.adapter = monthRecordAdapter ssvRecord.header = binding.clRecordStickyHeader } - monthRecordAdapter.submitList(reviews.groupByMonth()) + val groupList = + reviews.groupBy { it.date.extractMonth(false) }.map { (month, reviews) -> + MonthReviewData(month, reviews) + } +// monthRecordAdapter.submitList(reviews.groupByMonth()) + monthRecordAdapter.submitList(groupList) monthRecordAdapter.itemRecordClickListener = object : MonthRecordAdapter.OnItemRecordClickListener { - override fun onItemRecordClick(item: ReviewMockData) { + + override fun onItemRecordClick(item: MySeatRecordResponse.ReviewResponse) { Intent( this@SeatRecordActivity, SeatDetailRecordActivity::class.java @@ -169,11 +197,12 @@ class SeatRecordActivity : BaseActivity( } } - override fun onMoreRecordClick(item: ReviewMockData) { - viewModel.setEditReviewId(item.id) + override fun onMoreRecordClick(reviewId: Int) { + viewModel.setEditReviewId(reviewId) RecordEditDialog.newInstance(SEAT_RECORD_TAG) .apply { show(supportFragmentManager, this.tag) } } + } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt index 15983fa8..ed35b799 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt @@ -4,21 +4,22 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.presentation.databinding.ItemRecentMonthBinding -import com.depromeet.presentation.extension.extractMonth -import com.depromeet.presentation.seatrecord.mockdata.MonthReviewData -import com.depromeet.presentation.seatrecord.mockdata.ReviewMockData +import com.depromeet.presentation.seatrecord.uiMapper.MonthReviewData import com.depromeet.presentation.util.ItemDiffCallback -class MonthRecordAdapter() : ListAdapter( - ItemDiffCallback( - onItemsTheSame = { oldItem, newItem -> oldItem.month == newItem.month }, - onContentsTheSame = { oldItem, newItem -> oldItem == newItem } - ) -) { + +class MonthRecordAdapter() : + ListAdapter( + ItemDiffCallback( + onItemsTheSame = { oldItem, newItem -> oldItem.month == newItem.month }, + onContentsTheSame = { oldItem, newItem -> oldItem == newItem } + ) + ) { interface OnItemRecordClickListener { - fun onItemRecordClick(item: ReviewMockData) - fun onMoreRecordClick(item: ReviewMockData) + fun onItemRecordClick(item: MySeatRecordResponse.ReviewResponse) + fun onMoreRecordClick(reviewId: Int) } var itemRecordClickListener: OnItemRecordClickListener? = null @@ -49,17 +50,17 @@ class MonthRecordViewHolder( fun bind(item: MonthReviewData) { with(binding) { adapter = RecentRecordAdapter() - tvRecentMonth.text = item.month.extractMonth(true) + "${item.month}월".also { tvRecentMonth.text = it } rvRecentPost.adapter = adapter adapter.submitList(item.reviews) adapter.itemRecordClickListener = object : RecentRecordAdapter.OnItemRecordClickListener { - override fun onItemRecordClick(item: ReviewMockData) { + override fun onItemRecordClick(item: MySeatRecordResponse.ReviewResponse) { itemRecordClickListener?.onItemRecordClick(item) } - override fun onItemMoreClick(item: ReviewMockData) { - itemRecordClickListener?.onMoreRecordClick(item) + override fun onItemMoreClick(item: MySeatRecordResponse.ReviewResponse) { + itemRecordClickListener?.onMoreRecordClick(item.id) } } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt index 36e19eb1..da6b148f 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt @@ -6,24 +6,25 @@ import androidx.compose.material.MaterialTheme import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.presentation.databinding.ItemRecentRecordBinding import com.depromeet.presentation.extension.extractDay import com.depromeet.presentation.extension.getDayOfWeek import com.depromeet.presentation.extension.loadAndClip -import com.depromeet.presentation.seatrecord.mockdata.ReviewMockData +import com.depromeet.presentation.seatrecord.uiMapper.toUiKeyword import com.depromeet.presentation.util.ItemDiffCallback import com.depromeet.presentation.viewfinder.compose.KeywordFlowRow class RecentRecordAdapter( -) : ListAdapter( +) : ListAdapter( ItemDiffCallback( onItemsTheSame = { oldItem, newItem -> oldItem.id == newItem.id }, onContentsTheSame = { oldItem, newItem -> oldItem == newItem } ) ) { interface OnItemRecordClickListener { - fun onItemRecordClick(item: ReviewMockData) - fun onItemMoreClick(item: ReviewMockData) + fun onItemRecordClick(item: MySeatRecordResponse.ReviewResponse) + fun onItemMoreClick(item: MySeatRecordResponse.ReviewResponse) } var itemRecordClickListener: OnItemRecordClickListener? = null @@ -60,9 +61,9 @@ class RecentRecordViewHolder( } - fun bind(item: ReviewMockData) { + fun bind(item: MySeatRecordResponse.ReviewResponse) { with(binding) { - ivRecentImage.loadAndClip(item.image) + ivRecentImage.loadAndClip(item.images[0].url) tvRecentDateDay.text = item.date.extractDay() tvRecentDay.text = item.date.getDayOfWeek() tvRecentBlockName.text = item.blockName @@ -72,7 +73,7 @@ class RecentRecordViewHolder( setContent { MaterialTheme { KeywordFlowRow( - keywords = item.keyword, + keywords = item.keywords.map { it.toUiKeyword() }, overflowIndex = MAX_VISIBLE_CHIPS ) } @@ -80,4 +81,5 @@ class RecentRecordViewHolder( } } } -} \ No newline at end of file + +} diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt new file mode 100644 index 00000000..c2841d2a --- /dev/null +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt @@ -0,0 +1,22 @@ +package com.depromeet.presentation.seatrecord.uiMapper + +import com.depromeet.domain.entity.response.home.MySeatRecordResponse +import com.depromeet.presentation.viewfinder.sample.Keyword + +/** + * 리팩토링 예정 + */ +data class MonthReviewData( + val month: String, + val reviews: List, +) + +/** + * 우선 Ui Mapper로 임시 처리 추후 관희 flowRow 변경 사항에 따라 수정 예정 + */ +fun MySeatRecordResponse.ReviewResponse.ReviewKeywordResponse.toUiKeyword() = + Keyword( + message = content, + type = if (isPositive) 1 else 0, + like = 0 + ) \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index 06c0d13c..e4847534 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -2,25 +2,30 @@ package com.depromeet.presentation.seatrecord.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.depromeet.presentation.seatrecord.mockdata.RecordDetailMockData -import com.depromeet.presentation.seatrecord.mockdata.makeSeatRecordData +import com.depromeet.core.state.UiState +import com.depromeet.domain.entity.request.home.MySeatRecordRequest +import com.depromeet.domain.entity.response.home.MySeatRecordResponse +import com.depromeet.domain.repository.HomeRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import javax.inject.Inject + @HiltViewModel -class SeatRecordViewModel @Inject constructor() : ViewModel() { +class SeatRecordViewModel @Inject constructor( + private val homeRepository: HomeRepository, +) : ViewModel() { - private val _uiState = MutableStateFlow(RecordDetailMockData()) + private val _uiState = MutableStateFlow>(UiState.Loading) val uiState = _uiState.asStateFlow() private val _selectedMonth = MutableStateFlow(0) val selectedMonth = _selectedMonth.asStateFlow() private val _selectedYear = MutableStateFlow(2024) + val selectedYear = _selectedYear.asStateFlow() private val _deleteClickedEvent = MutableStateFlow(false) val deleteClickedEvent = _deleteClickedEvent.asStateFlow() @@ -30,12 +35,19 @@ class SeatRecordViewModel @Inject constructor() : ViewModel() { fun getSeatRecords() { - makeSeatRecordData().onEach { - _uiState.value = _uiState.value.copy( - profileDetailData = it.profileDetailData, - reviews = it.reviews - ) - }.launchIn(viewModelScope) + val month = if (selectedMonth.value == 0) null else selectedMonth.value + viewModelScope.launch { + homeRepository.getMySeatRecord( + MySeatRecordRequest( + selectedYear.value, + month + ) + ).onSuccess { data -> + _uiState.value = UiState.Success(data) + }.onFailure { + _uiState.value = UiState.Failure(it.message ?: "실패") + } + } } fun setSelectedYear(year: Int) { @@ -55,11 +67,11 @@ class SeatRecordViewModel @Inject constructor() : ViewModel() { } fun removeReviewData() { - val currentList = _uiState.value.reviews - val updatedList = currentList.filter { review -> - review.id != editReviewId.value - } - _uiState.value = uiState.value.copy(reviews = updatedList) - _deleteClickedEvent.value = false +// val currentList = _uiState.value. +// val updatedList = currentList.filter { review -> +// review.id != editReviewId.value +// } +// _uiState.value = uiState.value.copy(reviews = updatedList) +// _deleteClickedEvent.value = false } } \ No newline at end of file From 7f805c1dcfaa4806002c40e4cd23c21e70c81c25 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:30:54 +0900 Subject: [PATCH 14/83] =?UTF-8?q?[refactor/#29]=20SeatRecordActivity=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=ED=99=94=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/SeatRecordActivity.kt | 63 ++++---- .../seatrecord/mockdata/SeatRecordMockData.kt | 150 +++++++++--------- 2 files changed, 109 insertions(+), 104 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 14186554..4dc9bedc 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -45,11 +45,44 @@ class SeatRecordActivity : BaseActivity( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + viewModel.getSeatRecords() + initView() + initEvent() + initObserver() + + + } + + private fun initView() { initDateSpinner() initMonthAdapter() + } - viewModel.getSeatRecords() + private fun initEvent() { + with(binding) { + recordSpotAppbar.setNavigationOnClickListener { + finish() + } + recordSpotAppbar.setMenuOnClickListener { + //셋팅 이동 + } + fabRecordUp.setOnClickListener { + ssvRecord.smoothScrollTo(0, 0) + } + } + } + private fun initObserver() { + viewModel.selectedMonth.asLiveData().observe(this) { + val updatedMonthList = monthList.map { monthData -> + monthData.copy(isClicked = monthData.month == it) + } + dateMonthAdapter.submitList(updatedMonthList) + } + + viewModel.deleteClickedEvent.asLiveData().observe(this) { state -> + if (state) moveConfirmationDialog() + } viewModel.uiState.asLiveData().observe(this) { state -> when (state) { is UiState.Success -> { @@ -69,33 +102,6 @@ class SeatRecordActivity : BaseActivity( is UiState.Failure -> { Timber.d("test : ${state.msg}") } - - } - } - viewModel.selectedMonth.asLiveData().observe(this) { - val updatedMonthList = monthList.map { monthData -> - monthData.copy(isClicked = monthData.month == it) - } - dateMonthAdapter.submitList(updatedMonthList) - } - - viewModel.deleteClickedEvent.asLiveData().observe(this) { state -> - if (state) moveConfirmationDialog() - } - - setClickListener() - } - - private fun setClickListener() { - with(binding) { - recordSpotAppbar.setNavigationOnClickListener { - finish() - } - recordSpotAppbar.setMenuOnClickListener { - //셋팅 이동 - } - fabRecordUp.setOnClickListener { - ssvRecord.smoothScrollTo(0, 0) } } } @@ -182,7 +188,6 @@ class SeatRecordActivity : BaseActivity( reviews.groupBy { it.date.extractMonth(false) }.map { (month, reviews) -> MonthReviewData(month, reviews) } -// monthRecordAdapter.submitList(reviews.groupByMonth()) monthRecordAdapter.submitList(groupList) monthRecordAdapter.itemRecordClickListener = diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt index 876a099f..b485df6a 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt @@ -12,80 +12,6 @@ data class MonthData( var isClicked: Boolean = false, ) -data class RecordDetailMockData( - val profileDetailData: ProfileDetailData = ProfileDetailData(), - val reviews: List = emptyList(), -) - -data class ProfileDetailData( - val nickName: String= "", - val profileImage: String ="", - val level: Int =0, - val titleName: String = "", - val recordCount: Int = 0, -) - -@Parcelize -data class ReviewMockData( - val id: Int =0, - val date: String ="", - val image: String ="", - val stadiumName: String ="", - val blockName: String ="", - val keyword: List = emptyList(), -) : Parcelable - -data class MonthReviewData( - val month: String, - val reviews: List, -) - -fun List.groupByMonth(): List { - val groupedData = this.groupBy { it.date.extractMonth(false) } - return groupedData.map { (month, reviews) -> - MonthReviewData(month, reviews) - } -} - -fun makeSeatRecordData(): Flow = flow { - emit( - RecordDetailMockData( - profileDetailData = ProfileDetailData( - nickName = "노균욱", - profileImage = "https://picsum.photos/600/400", - level = 6, - titleName = "전설의 직관러", - recordCount = 37 - ), - reviews = makeRecordDetailData() - ) - ) -} - - -fun makeRecordDetailData(): List { - val list = mutableListOf() - for (i in 1..8) { - list.add( - ReviewMockData( - id = i, - date = "2024-0${i % 4 + 1}-12", - image = "https://picsum.photos/600/400", - stadiumName = "서울 잠실 야구장", - blockName = "1루 네이비석 304블록", - keyword = listOf( - Keyword("🙍‍서서 응원하는 존", 44, 0), - Keyword("☀️ 온종일 햇빛 존", 44, 1), - Keyword("🙍‍서서 응원하는 존", 44, 1), - Keyword("🙍‍서서 응원하는 존", 44, 0), - Keyword("🙍‍서서 응원하는 존", 44, 0) - ), - ) - ) - } - return list.sortedBy { it.date } -} - val monthList = listOf( MonthData(0, true), MonthData(1, false), @@ -100,4 +26,78 @@ val monthList = listOf( MonthData(10, false), MonthData(11, false), MonthData(12, false), -) \ No newline at end of file +) + +data class ProfileDetailData( + val nickName: String= "", + val profileImage: String ="", + val level: Int =0, + val titleName: String = "", + val recordCount: Int = 0, +) + +//data class RecordDetailMockData( +// val profileDetailData: ProfileDetailData = ProfileDetailData(), +// val reviews: List = emptyList(), +//) + +//@Parcelize +//data class ReviewMockData( +// val id: Int =0, +// val date: String ="", +// val image: String ="", +// val stadiumName: String ="", +// val blockName: String ="", +// val keyword: List = emptyList(), +//) : Parcelable +//data class MonthReviewData( +// val month: String, +// val reviews: List, +//) +// +//fun List.groupByMonth(): List { +// val groupedData = this.groupBy { it.date.extractMonth(false) } +// return groupedData.map { (month, reviews) -> +// MonthReviewData(month, reviews) +// } +//} +// +//fun makeSeatRecordData(): Flow = flow { +// emit( +// RecordDetailMockData( +// profileDetailData = ProfileDetailData( +// nickName = "노균욱", +// profileImage = "https://picsum.photos/600/400", +// level = 6, +// titleName = "전설의 직관러", +// recordCount = 37 +// ), +// reviews = makeRecordDetailData() +// ) +// ) +//} +// +// +//fun makeRecordDetailData(): List { +// val list = mutableListOf() +// for (i in 1..8) { +// list.add( +// ReviewMockData( +// id = i, +// date = "2024-0${i % 4 + 1}-12", +// image = "https://picsum.photos/600/400", +// stadiumName = "서울 잠실 야구장", +// blockName = "1루 네이비석 304블록", +// keyword = listOf( +// Keyword("🙍‍서서 응원하는 존", 44, 0), +// Keyword("☀️ 온종일 햇빛 존", 44, 1), +// Keyword("🙍‍서서 응원하는 존", 44, 1), +// Keyword("🙍‍서서 응원하는 존", 44, 0), +// Keyword("🙍‍서서 응원하는 존", 44, 0) +// ), +// ) +// ) +// } +// return list.sortedBy { it.date } +//} + From 7421fcbb5cf50d3f7d419ca667ea7a4510a00da8 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:49:50 +0900 Subject: [PATCH 15/83] =?UTF-8?q?[feature/#29]=20=EC=9B=94,=EB=85=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EB=82=B4=20?= =?UTF-8?q?=EC=8B=9C=EC=95=BC=EA=B8=B0=EB=A1=9D=20api=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=20=EB=B0=8F=20=EB=A6=AC=EB=B7=B0=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/SeatRecordActivity.kt | 6 +++++- .../seatrecord/viewmodel/SeatRecordViewModel.kt | 16 ++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 4dc9bedc..73ddb371 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -77,8 +77,12 @@ class SeatRecordActivity : BaseActivity( val updatedMonthList = monthList.map { monthData -> monthData.copy(isClicked = monthData.month == it) } + viewModel.getSeatRecords() dateMonthAdapter.submitList(updatedMonthList) } + viewModel.selectedYear.asLiveData().observe(this) { + viewModel.getSeatRecords() + } viewModel.deleteClickedEvent.asLiveData().observe(this) { state -> if (state) moveConfirmationDialog() @@ -87,7 +91,7 @@ class SeatRecordActivity : BaseActivity( when (state) { is UiState.Success -> { Timber.d("성공") - //setProfile() //사용자 프로필 데이터 서버에서 아직 안내려줌 + /*** setProfile() ->사용자 프로필 데이터 아직 서버 api명세서에 없음 */ setReviewList(state.data.reviews) } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index e4847534..57a9fdcc 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -67,11 +67,15 @@ class SeatRecordViewModel @Inject constructor( } fun removeReviewData() { -// val currentList = _uiState.value. -// val updatedList = currentList.filter { review -> -// review.id != editReviewId.value -// } -// _uiState.value = uiState.value.copy(reviews = updatedList) -// _deleteClickedEvent.value = false + val currentState = uiState.value + if (currentState is UiState.Success) { + val updatedList = currentState.data.reviews.filter { review -> + review.id != editReviewId.value + } + /** 여기서 서버에서 통신이 성공 -> uistate업로드 (api 명세 아직 없음)*/ + _uiState.value = UiState.Success(currentState.data.copy(reviews = updatedList)) + _deleteClickedEvent.value = false + } + } } \ No newline at end of file From 7e791a0873c494c8308f54d04b0e9a5a72ec51c7 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 21:18:44 +0900 Subject: [PATCH 16/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=20=EA=B8=B0=EB=A1=9D=20->=20=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EC=9D=B4=EB=8F=99=20=EC=8B=9C=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EB=A1=9C=EC=BB=AC=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/SeatDetailRecordActivity.kt | 55 +++++++++---- .../seatrecord/SeatRecordActivity.kt | 14 ++-- .../seatrecord/adapter/DetailRecordAdapter.kt | 32 ++++---- .../seatrecord/uiMapper/HomeMapper.kt | 77 ++++++++++++++++++- .../viewmodel/SeatDetailViewModel.kt | 24 +++--- .../viewmodel/SeatRecordViewModel.kt | 15 +++- 6 files changed, 163 insertions(+), 54 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt index 35c514a8..7ca46284 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt @@ -1,12 +1,14 @@ package com.depromeet.presentation.seatrecord +import android.os.Build import android.os.Bundle import androidx.activity.viewModels +import androidx.annotation.ChecksSdkIntAtLeast import androidx.lifecycle.asLiveData import com.depromeet.core.base.BaseActivity import com.depromeet.presentation.databinding.ActivitySeatDetailRecordBinding import com.depromeet.presentation.seatrecord.adapter.DetailRecordAdapter -import com.depromeet.presentation.seatrecord.mockdata.ReviewDetailMockData +import com.depromeet.presentation.seatrecord.uiMapper.ReviewUiData import com.depromeet.presentation.seatrecord.viewmodel.SeatDetailViewModel import dagger.hilt.android.AndroidEntryPoint @@ -23,19 +25,36 @@ class SeatDetailRecordActivity : BaseActivity( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + initView() + initEvent() + initObserver() + } + + private fun initView() { + getDataExtra { id, reviews -> + viewModel.setReviewData(id, reviews) + } setDetailRecordAdapter() - viewModel.getReviewData() + } + + private fun initEvent() { + with(binding) { + fabDetailUp.setOnClickListener { + rvDetailRecord.smoothScrollToPosition(0) + } + } + } + + private fun initObserver() { + viewModel.uiState.asLiveData().observe(this) { - detailRecordAdapter.submitList(it.list) + detailRecordAdapter.submitList(it) } viewModel.deleteClickedEvent.asLiveData().observe(this) { state -> if (state) moveConfirmationDialog() } - - setClickListener() - } private fun setDetailRecordAdapter() { @@ -44,8 +63,8 @@ class SeatDetailRecordActivity : BaseActivity( detailRecordAdapter.itemMoreClickListener = object : DetailRecordAdapter.OnDetailItemClickListener { - override fun onItemMoreClickListener(item: ReviewDetailMockData) { - viewModel.setEditReviewId(item.reviewId) + override fun onItemMoreClickListener(item: ReviewUiData) { + viewModel.setEditReviewId(item.id) RecordEditDialog.newInstance(SEAT_DETAIL_TAG) .apply { show(supportFragmentManager, this.tag) } } @@ -57,11 +76,21 @@ class SeatDetailRecordActivity : BaseActivity( .apply { show(supportFragmentManager, this.tag) } } - private fun setClickListener() { - with(binding){ - fabDetailUp.setOnClickListener { - rvDetailRecord.smoothScrollToPosition(0) - } + @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.TIRAMISU, lambda = 0) + private fun getDataExtra(callback: (recordId: Int, recordList: ArrayList) -> Unit) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + callback( + intent?.getIntExtra(SeatRecordActivity.RECORD_ID, 0) ?: 0, + intent?.getParcelableArrayListExtra( + SeatRecordActivity.RECORD_LIST, + ReviewUiData::class.java + ) ?: arrayListOf() + ) + } else { + callback( + intent?.getIntExtra(SeatRecordActivity.RECORD_ID, 0) ?: 0, + intent?.getParcelableArrayListExtra(SeatRecordActivity.RECORD_LIST) ?: arrayListOf() + ) } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 73ddb371..0e4325a0 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -33,9 +33,11 @@ class SeatRecordActivity : BaseActivity( ActivitySeatRecordBinding::inflate ) { companion object { + const val SEAT_RECORD_TAG = "seatRecord" + const val RECORD_ID = "record_id" + const val RECORD_LIST = "record_list" private const val START_SPACING_DP = 20 private const val BETWEEN_SPACING_DP = 8 - const val SEAT_RECORD_TAG = "seatRecord" } private lateinit var dateMonthAdapter: DateMonthAdapter @@ -77,12 +79,8 @@ class SeatRecordActivity : BaseActivity( val updatedMonthList = monthList.map { monthData -> monthData.copy(isClicked = monthData.month == it) } - viewModel.getSeatRecords() dateMonthAdapter.submitList(updatedMonthList) } - viewModel.selectedYear.asLiveData().observe(this) { - viewModel.getSeatRecords() - } viewModel.deleteClickedEvent.asLiveData().observe(this) { state -> if (state) moveConfirmationDialog() @@ -90,7 +88,6 @@ class SeatRecordActivity : BaseActivity( viewModel.uiState.asLiveData().observe(this) { state -> when (state) { is UiState.Success -> { - Timber.d("성공") /*** setProfile() ->사용자 프로필 데이터 아직 서버 api명세서에 없음 */ setReviewList(state.data.reviews) } @@ -202,8 +199,9 @@ class SeatRecordActivity : BaseActivity( this@SeatRecordActivity, SeatDetailRecordActivity::class.java ).apply { - startActivity(this) - } + putExtra(RECORD_ID, item.id) + putParcelableArrayListExtra(RECORD_LIST, viewModel.getUiReviewsData()) + }.let(::startActivity) } override fun onMoreRecordClick(reviewId: Int) { diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DetailRecordAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DetailRecordAdapter.kt index 50873c6d..de6d9ae1 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DetailRecordAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DetailRecordAdapter.kt @@ -8,22 +8,21 @@ import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 -import coil.load -import coil.transform.CircleCropTransformation import com.depromeet.presentation.databinding.ItemSeatReviewDetailBinding -import com.depromeet.presentation.seatrecord.mockdata.ReviewDetailMockData +import com.depromeet.presentation.seatrecord.uiMapper.ReviewUiData +import com.depromeet.presentation.seatrecord.uiMapper.toUiKeyword import com.depromeet.presentation.util.ItemDiffCallback import com.depromeet.presentation.util.applyBoldSpan import com.depromeet.presentation.viewfinder.compose.KeywordFlowRow -class DetailRecordAdapter() : ListAdapter( +class DetailRecordAdapter() : ListAdapter( ItemDiffCallback( - onItemsTheSame = { oldItem, newItem -> oldItem.reviewId == newItem.reviewId }, + onItemsTheSame = { oldItem, newItem -> oldItem.id == newItem.id }, onContentsTheSame = { oldItem, newItem -> oldItem == newItem } ) ) { interface OnDetailItemClickListener { - fun onItemMoreClickListener(item: ReviewDetailMockData) + fun onItemMoreClickListener(item: ReviewUiData) } var itemMoreClickListener: OnDetailItemClickListener? = null @@ -55,24 +54,25 @@ class ReviewDetailViewHolder( private const val MAX_VISIBLE_CHIPS = 3 } - fun bind(item: ReviewDetailMockData) { + fun bind(item: ReviewUiData) { with(binding) { - ivDetailProfileImage.load(item.profileImage) { - transformations(CircleCropTransformation()) - } - tvDetailNickname.text = item.nickName - "Lv.${item.level}".also { tvDetailLevel.text = it } + //TODO : 서버 데이터 바뀔거니 기억해두기 +// ivDetailProfileImage.load(item.profileImage) { +// transformations(CircleCropTransformation()) +// } +// tvDetailNickname.text = item.nickName +// "Lv.${item.level}".also { tvDetailLevel.text = it } tvDetailStadium.text = item.stadiumName - tvDetailBlock.text = item.stadiumName - tvDetailDate.text = item.createdAt + tvDetailBlock.text = item.blockName + tvDetailDate.text = item.date tvDetailContent.text = item.content - initImageViewPager(item.images) + initImageViewPager(item.images.map { it.url }) cvDetailKeyword.apply { setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { MaterialTheme { KeywordFlowRow( - keywords = item.keywords, + keywords = item.keywords.map { it.toUiKeyword() }, overflowIndex = MAX_VISIBLE_CHIPS ) } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt index c2841d2a..8d4fa43c 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt @@ -1,7 +1,9 @@ package com.depromeet.presentation.seatrecord.uiMapper +import android.os.Parcelable import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.presentation.viewfinder.sample.Keyword +import kotlinx.parcelize.Parcelize /** * 리팩토링 예정 @@ -11,6 +13,37 @@ data class MonthReviewData( val reviews: List, ) +@Parcelize +data class ReviewUiData( + val id: Int, + val stadiumId: Int, + val stadiumName: String, + val blockId: Int, + val blockName: String, + val seatId: Int, + val rowId: Int, + val seatNumber: Int, + val date: String, + val content: String, + val createdAt: String, + val updatedAt: String, + val images: List, + val keywords: List, +) : Parcelable { + @Parcelize + data class ReviewImageUiData( + val id: Int, + val url: String, + ) : Parcelable + + @Parcelize + data class ReviewKeywordUiData( + val id: Int, + val content: String, + val isPositive: Boolean, + ) : Parcelable +} + /** * 우선 Ui Mapper로 임시 처리 추후 관희 flowRow 변경 사항에 따라 수정 예정 */ @@ -19,4 +52,46 @@ fun MySeatRecordResponse.ReviewResponse.ReviewKeywordResponse.toUiKeyword() = message = content, type = if (isPositive) 1 else 0, like = 0 - ) \ No newline at end of file + ) + +fun ReviewUiData.ReviewKeywordUiData.toUiKeyword() = + Keyword( + message = content, + type = if (isPositive) 1 else 0, + like = 0 + ) + + +fun MySeatRecordResponse.ReviewResponse.toUiModel(): ReviewUiData { + return ReviewUiData( + id = id, + stadiumId = stadiumId, + stadiumName = stadiumName, + blockId = blockId, + blockName = blockName, + seatId = seatId, + rowId = rowId, + seatNumber = seatNumber, + date = date, + content = content, + createdAt = createdAt, + updatedAt = updatedAt, + images = images.map { it.toUiModel() }, + keywords = keywords.map { it.toUiModel() } + ) +} + +fun MySeatRecordResponse.ReviewResponse.ReviewImageResponse.toUiModel(): ReviewUiData.ReviewImageUiData { + return ReviewUiData.ReviewImageUiData( + id = id, + url = url + ) +} + +fun MySeatRecordResponse.ReviewResponse.ReviewKeywordResponse.toUiModel(): ReviewUiData.ReviewKeywordUiData { + return ReviewUiData.ReviewKeywordUiData( + id = id, + content = content, + isPositive = isPositive + ) +} \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatDetailViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatDetailViewModel.kt index 4f56c821..4ee0c692 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatDetailViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatDetailViewModel.kt @@ -1,20 +1,16 @@ package com.depromeet.presentation.seatrecord.viewmodel import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.depromeet.presentation.seatrecord.mockdata.ReviewDetailMockResult -import com.depromeet.presentation.seatrecord.mockdata.mockReviewDetailListData +import com.depromeet.presentation.seatrecord.uiMapper.ReviewUiData import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach import javax.inject.Inject @HiltViewModel class SeatDetailViewModel @Inject constructor() : ViewModel() { - private val _uiState = MutableStateFlow(ReviewDetailMockResult()) + private val _uiState = MutableStateFlow(emptyList()) val uiState = _uiState.asStateFlow() private val _deleteClickedEvent = MutableStateFlow(false) @@ -23,20 +19,18 @@ class SeatDetailViewModel @Inject constructor() : ViewModel() { private val _editReviewId = MutableStateFlow(0) val editReviewId = _editReviewId.asStateFlow() - - fun getReviewData() { - mockReviewDetailListData().onEach { - _uiState.value = _uiState.value.copy(list = it) - }.launchIn(viewModelScope) + fun setReviewData(id: Int, reviews: List) { + _uiState.value = reviews } - fun removeReviewData() { - val currentList = _uiState.value.list + val currentList = _uiState.value val updatedList = currentList.filter { review -> - review.reviewId != _editReviewId.value + review.id != _editReviewId.value } - _uiState.value = _uiState.value.copy(list = updatedList) + + /** 투두 : 삭제 api 연동 **/ + _uiState.value = updatedList _deleteClickedEvent.value = false } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index 57a9fdcc..ce851683 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -6,18 +6,20 @@ import com.depromeet.core.state.UiState import com.depromeet.domain.entity.request.home.MySeatRecordRequest import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.repository.HomeRepository +import com.depromeet.presentation.seatrecord.uiMapper.ReviewUiData +import com.depromeet.presentation.seatrecord.uiMapper.toUiModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import javax.inject.Inject - @HiltViewModel class SeatRecordViewModel @Inject constructor( private val homeRepository: HomeRepository, ) : ViewModel() { + private val _uiState = MutableStateFlow>(UiState.Loading) val uiState = _uiState.asStateFlow() @@ -52,10 +54,12 @@ class SeatRecordViewModel @Inject constructor( fun setSelectedYear(year: Int) { _selectedYear.value = year + getSeatRecords() } fun setSelectedMonth(month: Int) { _selectedMonth.value = month + getSeatRecords() } fun setEditReviewId(id: Int) { @@ -78,4 +82,13 @@ class SeatRecordViewModel @Inject constructor( } } + + fun getUiReviewsData(): ArrayList { + val currentState = uiState.value + return if (currentState is UiState.Success) { + ArrayList(currentState.data.reviews.map { it.toUiModel() }) + } else { + arrayListOf() + } + } } \ No newline at end of file From c37782d7fc0f3756fb64fa21a0547ed0681eb105 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 21:39:19 +0900 Subject: [PATCH 17/83] =?UTF-8?q?[feature/#29]=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=9D=B4=EB=8F=99=EC=8B=9C=20ID=EC=99=80?= =?UTF-8?q?=20=EC=9D=BC=EC=B9=98=ED=95=98=EB=8A=94=20=EA=B5=AC=EC=97=AD?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20scroll?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/seatrecord/SeatDetailRecordActivity.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt index 7ca46284..23c5ded7 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt @@ -32,10 +32,15 @@ class SeatDetailRecordActivity : BaseActivity( } private fun initView() { + setDetailRecordAdapter() getDataExtra { id, reviews -> + val position = reviews.indexOfFirst { it.id == id } + if(position != -1){ + binding.rvDetailRecord.scrollToPosition(position) + } viewModel.setReviewData(id, reviews) } - setDetailRecordAdapter() + } private fun initEvent() { From d408c95ebb08b69c20ea41110125f92250ab3746 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 22:33:58 +0900 Subject: [PATCH 18/83] =?UTF-8?q?[feature/#29]=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EC=95=BC=EA=B5=AC=20=EA=B5=AC=EB=8B=A8=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20data=20module=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../depromeet/data/datasource/HomeDataSource.kt | 3 +++ .../data/datasource/remote/HomeDataSourceImpl.kt | 5 +++++ .../java/com/depromeet/data/mapper/HomeMapper.kt | 9 +++++++++ .../model/response/home/ResponseBaseballTeamDto.kt | 14 ++++++++++++++ .../com/depromeet/data/remote/HomeApiService.kt | 4 ++++ .../data/repository/HomeRepositoryImpl.kt | 8 ++++++++ 6 files changed, 43 insertions(+) create mode 100644 data/src/main/java/com/depromeet/data/model/response/home/ResponseBaseballTeamDto.kt diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt index c90100e5..32a34501 100644 --- a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -1,10 +1,13 @@ package com.depromeet.data.datasource import com.depromeet.data.model.request.RequestMySeatRecordDto +import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto interface HomeDataSource { suspend fun getMySeatRecordData( requestMySeatRecordDto: RequestMySeatRecordDto, ): ResponseMySeatRecordDto + + suspend fun getBaseballTeamData(): List } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index d0e5ec88..bec2b664 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -2,6 +2,7 @@ package com.depromeet.data.datasource.remote import com.depromeet.data.datasource.HomeDataSource import com.depromeet.data.model.request.RequestMySeatRecordDto +import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.remote.HomeApiService import javax.inject.Inject @@ -17,4 +18,8 @@ class HomeDataSourceImpl @Inject constructor( requestMySeatRecordDto.month ) } + + override suspend fun getBaseballTeamData(): List { + return homeApiService.getBaseballTeam() + } } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt index 4bf1b373..617f9bd3 100644 --- a/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt +++ b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt @@ -1,8 +1,10 @@ package com.depromeet.data.mapper import com.depromeet.data.model.request.RequestMySeatRecordDto +import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.domain.entity.request.home.MySeatRecordRequest +import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse fun ResponseMySeatRecordDto.toMySeatRecordResponse() = MySeatRecordResponse( @@ -60,4 +62,11 @@ fun MySeatRecordRequest.toMySeatRecordRequestDto() = RequestMySeatRecordDto( limit = limit, year = year, month = month +) + +/** baseball team **/ +fun ResponseBaseballTeamDto.toBaseballTeamResponse() = BaseballTeamResponse( + id = id, + name = name, + logo = logo ) \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseBaseballTeamDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseBaseballTeamDto.kt new file mode 100644 index 00000000..cb46627e --- /dev/null +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseBaseballTeamDto.kt @@ -0,0 +1,14 @@ +package com.depromeet.data.model.response.home + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponseBaseballTeamDto( + @SerialName("id") + val id : Int, + @SerialName("name") + val name : String, + @SerialName("logo") + val logo : String +) diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index c9d45a15..36f99acb 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -1,5 +1,6 @@ package com.depromeet.data.remote +import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import retrofit2.http.GET import retrofit2.http.Query @@ -12,4 +13,7 @@ interface HomeApiService { @Query("year") year: Int?, @Query("month") month: Int?, ): ResponseMySeatRecordDto + + @GET("/api/v1/baseball-teams") + suspend fun getBaseballTeam(): List } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index ca2b011a..2e95a8cf 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -1,9 +1,11 @@ package com.depromeet.data.repository import com.depromeet.data.datasource.HomeDataSource +import com.depromeet.data.mapper.toBaseballTeamResponse import com.depromeet.data.mapper.toMySeatRecordRequestDto import com.depromeet.data.mapper.toMySeatRecordResponse import com.depromeet.domain.entity.request.home.MySeatRecordRequest +import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.repository.HomeRepository import javax.inject.Inject @@ -17,4 +19,10 @@ class HomeRepositoryImpl @Inject constructor( .toMySeatRecordResponse() } } + + override suspend fun getBaseballTeam(): Result> { + return runCatching { + homeDataSource.getBaseballTeamData().map { it.toBaseballTeamResponse() } + } + } } \ No newline at end of file From 5ab570644e24047fc2ee0bf462624b8a4e900e2d Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 22:34:18 +0900 Subject: [PATCH 19/83] =?UTF-8?q?[feature/#29]=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EC=95=BC=EA=B5=AC=20=EA=B5=AC=EB=8B=A8=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20domain=20module=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/entity/response/home/BaseballTeamResponse.kt | 8 ++++++++ .../com/depromeet/domain/repository/HomeRepository.kt | 3 +++ 2 files changed, 11 insertions(+) create mode 100644 domain/src/main/java/com/depromeet/domain/entity/response/home/BaseballTeamResponse.kt diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/BaseballTeamResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/BaseballTeamResponse.kt new file mode 100644 index 00000000..5d7e859d --- /dev/null +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/BaseballTeamResponse.kt @@ -0,0 +1,8 @@ +package com.depromeet.domain.entity.response.home + +data class BaseballTeamResponse( + val id : Int, + val name : String = "", + val logo : String = "", + val isClicked : Boolean = false +) diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt index 9b8a382e..2d9e0e2a 100644 --- a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -1,10 +1,13 @@ package com.depromeet.domain.repository import com.depromeet.domain.entity.request.home.MySeatRecordRequest +import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse interface HomeRepository { suspend fun getMySeatRecord( mySeatRecordRequest: MySeatRecordRequest, ): Result + + suspend fun getBaseballTeam() : Result> } \ No newline at end of file From f4db40967b911dfb391856697d1298a8c3047c9a Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 22:39:53 +0900 Subject: [PATCH 20/83] =?UTF-8?q?[feature/#29]=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EC=95=BC=EA=B5=AC=20=EA=B5=AC=EB=8B=A8=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20presentation=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/home/ProfileEditActivity.kt | 51 ++++++------ .../home/adapter/BaseballTeamAdapter.kt | 10 +-- .../home/mockdata/ProfileEditMockData.kt | 26 +++---- .../home/viewmodel/ProfileEditViewModel.kt | 77 +++++++++---------- 4 files changed, 80 insertions(+), 84 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index daebf722..bdb6fa0e 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -6,16 +6,15 @@ import android.view.View import androidx.activity.viewModels import androidx.core.widget.addTextChangedListener import androidx.lifecycle.asLiveData -import coil.load -import coil.transform.CircleCropTransformation import com.depromeet.core.base.BaseActivity +import com.depromeet.core.state.UiState +import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ActivityProfileEditBinding import com.depromeet.presentation.extension.NickNameError +import com.depromeet.presentation.extension.toast +import com.depromeet.presentation.home.adapter.BaseballTeamAdapter import com.depromeet.presentation.home.adapter.GridSpacingItemDecoration -import com.depromeet.presentation.home.adapter.ProfileEditTeamAdapter -import com.depromeet.presentation.home.mockdata.TeamData -import com.depromeet.presentation.home.viewmodel.EditUiState import com.depromeet.presentation.home.viewmodel.ProfileEditViewModel import dagger.hilt.android.AndroidEntryPoint @@ -28,7 +27,7 @@ class ProfileEditActivity : BaseActivity( private const val GRID_SPACING = 40 } - private lateinit var adapter: ProfileEditTeamAdapter + private lateinit var adapter: BaseballTeamAdapter private val viewModel: ProfileEditViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { @@ -37,10 +36,26 @@ class ProfileEditActivity : BaseActivity( navigateToPhotoPicker() onClickTeam() observeNickName() - viewModel.getInformation() + viewModel.getBaseballTeam() - viewModel.uiState.asLiveData().observe(this) { state -> - updateUI(state) + viewModel.team.asLiveData().observe(this) { state -> + when (state) { + is UiState.Success -> { + adapter.submitList(state.data) + } + + is UiState.Loading -> { + toast("로딩 중") + } + + is UiState.Empty -> { + toast("빈값 에러") + } + + is UiState.Failure -> { + toast("통신 실패") + } + } } binding.ibProfileEditClose.setOnClickListener { finish() } @@ -48,18 +63,8 @@ class ProfileEditActivity : BaseActivity( } - private fun updateUI(state: EditUiState) { - binding.ivProfileEditImage.load(state.image) { - transformations(CircleCropTransformation()) - placeholder(R.drawable.ic_default_profile) - error(R.drawable.ic_default_profile) - } - binding.etProfileEditNickname.setText(state.nickName) - adapter.submitList(state.teamList) - } - private fun setCheerTeamList() { - adapter = ProfileEditTeamAdapter() + adapter = BaseballTeamAdapter() binding.rvProfileEditTeam.adapter = adapter binding.rvProfileEditTeam.addItemDecoration( GridSpacingItemDecoration( @@ -125,9 +130,9 @@ class ProfileEditActivity : BaseActivity( } private fun onClickTeam() { - adapter.itemClubClickListener = object : ProfileEditTeamAdapter.OnItemClubClickListener { - override fun onItemClubClick(item: TeamData) { - viewModel.updateClickTeam(item) + adapter.itemClubClickListener = object : BaseballTeamAdapter.OnItemClubClickListener { + override fun onItemClubClick(item: BaseballTeamResponse) { + viewModel.setClickedBaseballTeam(item.id) binding.tvProfileEditNoTeam.setBackgroundResource(R.drawable.rect_gray100_line_10) } } diff --git a/presentation/src/main/java/com/depromeet/presentation/home/adapter/BaseballTeamAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/home/adapter/BaseballTeamAdapter.kt index ce983450..6456a8b0 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/adapter/BaseballTeamAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/adapter/BaseballTeamAdapter.kt @@ -7,20 +7,20 @@ import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import coil.load +import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ItemBaseballTeamBinding -import com.depromeet.presentation.home.mockdata.TeamData import com.depromeet.presentation.util.ItemDiffCallback -class ProfileEditTeamAdapter : ListAdapter( +class BaseballTeamAdapter : ListAdapter( ItemDiffCallback( onItemsTheSame = { oldItem, newItem -> oldItem.name == newItem.name }, onContentsTheSame = { oldItem, newItem -> oldItem == newItem } ) ) { interface OnItemClubClickListener { - fun onItemClubClick(item: TeamData) + fun onItemClubClick(item: BaseballTeamResponse) } var itemClubClickListener: OnItemClubClickListener? = null @@ -46,9 +46,9 @@ class ProfileEditTeamAdapter : ListAdapter( class ProfileEditTeamViewHolder( private val binding: ItemBaseballTeamBinding, ) : RecyclerView.ViewHolder(binding.root) { - fun bind(item: TeamData) { + fun bind(item: BaseballTeamResponse) { with(binding) { - ivTeamImage.load(item.image) { + ivTeamImage.load(item.logo) { placeholder(R.drawable.ic_lg_team) error(R.drawable.ic_x_close) } diff --git a/presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt b/presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt index f8726880..ece7d8a5 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt @@ -1,10 +1,6 @@ package com.depromeet.presentation.home.mockdata import android.os.Parcelable -import com.depromeet.presentation.R -import com.depromeet.presentation.home.viewmodel.EditUiState -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow import kotlinx.parcelize.Parcelize @Parcelize @@ -16,14 +12,14 @@ data class TeamData( ) : Parcelable -fun mockDataProfileEdit(): Flow = flow { - - val testData = mutableListOf() - testData.add(TeamData(1, "삼성 라이온즈", R.drawable.ic_lg_team, true)) - testData.add(TeamData(2, "안드 화이팅!!", R.drawable.ic_lg_team, false)) - for (i in 3 until 20) { - testData.add(TeamData(i, "LG 트윈스", R.drawable.ic_lg_team, false)) - } - - emit(EditUiState("https://picsum.photos/600/400", "노균욱", testData)) -} \ No newline at end of file +//fun mockDataProfileEdit(): Flow = flow { +// +// val testData = mutableListOf() +// testData.add(TeamData(1, "삼성 라이온즈", R.drawable.ic_lg_team, true)) +// testData.add(TeamData(2, "안드 화이팅!!", R.drawable.ic_lg_team, false)) +// for (i in 3 until 20) { +// testData.add(TeamData(i, "LG 트윈스", R.drawable.ic_lg_team, false)) +// } +// +// emit(EditUiState("https://picsum.photos/600/400", "노균욱", testData)) +//} \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt index 67e24df8..7981b5ab 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt @@ -2,30 +2,24 @@ package com.depromeet.presentation.home.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.depromeet.core.state.UiState +import com.depromeet.domain.entity.response.home.BaseballTeamResponse +import com.depromeet.domain.repository.HomeRepository import com.depromeet.presentation.extension.NickNameError import com.depromeet.presentation.extension.validateNickName -import com.depromeet.presentation.home.mockdata.TeamData -import com.depromeet.presentation.home.mockdata.mockDataProfileEdit import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import javax.inject.Inject -data class EditUiState( - val image: String = "", - val nickName: String = "", - val teamList: List = emptyList(), -) - - @HiltViewModel -class ProfileEditViewModel @Inject constructor() : ViewModel() { +class ProfileEditViewModel @Inject constructor( + private val homeRepository: HomeRepository, +) : ViewModel() { - private val _uiState = MutableStateFlow(EditUiState()) - val uiState: StateFlow = _uiState.asStateFlow() + private val _team = MutableStateFlow>>(UiState.Loading) + val team = _team.asStateFlow() private val _nickName = MutableStateFlow("") val nickName = _nickName.asStateFlow() @@ -33,41 +27,42 @@ class ProfileEditViewModel @Inject constructor() : ViewModel() { private val _nickNameError = MutableStateFlow(NickNameError.NoError) val nickNameError = _nickNameError.asStateFlow() - fun getInformation() { - mockDataProfileEdit().onEach { - _uiState.value = it - }.launchIn(viewModelScope) + private val _profileImage = MutableStateFlow("") + val profileImage = _profileImage.asStateFlow() + + fun getBaseballTeam() { + viewModelScope.launch { + homeRepository.getBaseballTeam() + .onSuccess { + _team.value = UiState.Success(it) + }.onFailure { + _team.value = UiState.Failure(it.message ?: "실패") + } + } } fun setProfileImage(uri: String) { - val newState = _uiState.value.copy(image = uri) - _uiState.value = newState + _profileImage.value = uri } - fun updateClickTeam(team: TeamData) { - val currentTeamList = uiState.value.teamList.toMutableList() - val newCheckedTeamIndex = currentTeamList.indexOfFirst { it.id == team.id }.apply { - if (this == -1) return - } - val beforeCheckedTeamIndex = currentTeamList.indexOfFirst { it.isClicked } - - if (newCheckedTeamIndex == beforeCheckedTeamIndex) { - return - } - - currentTeamList[newCheckedTeamIndex] = - currentTeamList[newCheckedTeamIndex].copy(isClicked = true) - if (beforeCheckedTeamIndex != -1) { - currentTeamList[beforeCheckedTeamIndex] = - currentTeamList[beforeCheckedTeamIndex].copy(isClicked = false) + fun setClickedBaseballTeam(id: Int) { + val currentState = team.value + if (currentState is UiState.Success) { + val updatedList = currentState.data.map { team -> + team.copy(isClicked = team.id == id) + } + _team.value = UiState.Success(updatedList) } - - _uiState.value = _uiState.value.copy(teamList = currentTeamList) } fun deleteCheerTeam() { - val currentTeamList = uiState.value.teamList.map { it.copy(isClicked = false) } - _uiState.value = _uiState.value.copy(teamList = currentTeamList) + val currentState = team.value + if (currentState is UiState.Success) { + val updatedList = currentState.data.map { team -> + team.copy(isClicked = false) + } + _team.value = UiState.Success(updatedList) + } } fun updateNickName(nickName: String) { From 7cd00e1b5f31164000ccb4e16827ee3c428e4cd8 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 23:12:24 +0900 Subject: [PATCH 21/83] =?UTF-8?q?[feature/#29]=20=ED=99=88=20->=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=88=98=EC=A0=95=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=EC=8B=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A0=84?= =?UTF-8?q?=EB=8B=AC=20=EB=B0=8F=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/home/HomeActivity.kt | 38 ++++++++----------- .../presentation/home/ProfileEditActivity.kt | 22 +++++++++++ .../home/mockdata/HomeMockData.kt | 12 +++--- .../home/viewmodel/HomeViewModel.kt | 8 ++-- .../home/viewmodel/ProfileEditViewModel.kt | 18 ++++++++- .../src/main/res/drawable/ic_camera_14.xml | 10 +++++ .../main/res/layout/activity_profile_edit.xml | 11 ++++-- 7 files changed, 81 insertions(+), 38 deletions(-) create mode 100644 presentation/src/main/res/drawable/ic_camera_14.xml diff --git a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt index 45cf890a..f549b188 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt @@ -8,10 +8,8 @@ import androidx.activity.viewModels import androidx.lifecycle.asLiveData import coil.load import com.depromeet.core.base.BaseActivity -import com.depromeet.core.state.UiState import com.depromeet.presentation.databinding.ActivityHomeBinding import com.depromeet.presentation.extension.loadAndClip -import com.depromeet.presentation.extension.toast import com.depromeet.presentation.home.viewmodel.HomeUiState import com.depromeet.presentation.home.viewmodel.HomeViewModel import com.depromeet.presentation.util.applyBoldAndSizeSpan @@ -21,6 +19,12 @@ import dagger.hilt.android.AndroidEntryPoint class HomeActivity : BaseActivity( ActivityHomeBinding::inflate ) { + companion object { + const val PROFILE_NAME = "profile_name" + const val PROFILE_IMAGE = "profile_image" + const val PROFILE_CHEER_TEAM = "profile_cheer_team" + } + private val viewModel: HomeViewModel by viewModels() private val sightList: List by lazy { listOf( @@ -38,29 +42,13 @@ class HomeActivity : BaseActivity( binding.clMainSight.clipToOutline = true viewModel.uiState.asLiveData().observe(this) { state -> - when (state) { - is UiState.Loading -> { - toast("로딩중") - } - - is UiState.Empty -> { - toast("빈값") - } - - is UiState.Success -> { - updateUi(state.data) - } - - is UiState.Failure -> { - toast("통신 실패") - } - } + updateUi(state) } viewModel.getInformation() } - + private fun updateUi(state: HomeUiState) { with(binding) { val profile = state.profile @@ -68,7 +56,7 @@ class HomeActivity : BaseActivity( "Lv.${profile.level} ${profile.title}".also { tvHomeLevel.text = it } setSpannableString(profile.nickName, profile.writeCount) - ivHomeCheerTeam.load(profile.cheerTeam) + ivHomeCheerTeam.load(profile.teamImage) tvHomeRecentRecordName.text = recentSight.location tvHomeRecentRecordDate.text = recentSight.date @@ -108,7 +96,13 @@ class HomeActivity : BaseActivity( } private fun navigateToProfileEditActivity() { - Intent(this, ProfileEditActivity::class.java).apply { startActivity(this) } + Intent(this, ProfileEditActivity::class.java).apply { + with(viewModel.uiState.value.profile) { + putExtra(PROFILE_NAME, this.nickName) + putExtra(PROFILE_IMAGE, this.image) + putExtra(PROFILE_CHEER_TEAM, this.teamId) + } + }.let(::startActivity) } private fun setSpannableString( diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index bdb6fa0e..30f7b05c 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -6,6 +6,8 @@ import android.view.View import androidx.activity.viewModels import androidx.core.widget.addTextChangedListener import androidx.lifecycle.asLiveData +import coil.load +import coil.transform.CircleCropTransformation import com.depromeet.core.base.BaseActivity import com.depromeet.core.state.UiState import com.depromeet.domain.entity.response.home.BaseballTeamResponse @@ -36,8 +38,20 @@ class ProfileEditActivity : BaseActivity( navigateToPhotoPicker() onClickTeam() observeNickName() + + getDataExtra { name, image, cheerTeam -> + viewModel.setProfile(name, image, cheerTeam) + binding.etProfileEditNickname.setText(name) + } + viewModel.getBaseballTeam() + viewModel.profileImage.asLiveData().observe(this) { state -> + binding.ivProfileEditImage.load(state) { + transformations(CircleCropTransformation()) + } + } + viewModel.team.asLiveData().observe(this) { state -> when (state) { is UiState.Success -> { @@ -152,4 +166,12 @@ class ProfileEditActivity : BaseActivity( fragment.show(supportFragmentManager, fragment.tag) } + private fun getDataExtra(callback: (name: String, profileImage: String, cheerTeam: Int) -> Unit) { + callback( + intent?.getStringExtra(HomeActivity.PROFILE_NAME) ?: "", + intent?.getStringExtra(HomeActivity.PROFILE_IMAGE) ?: "", + intent?.getIntExtra(HomeActivity.PROFILE_CHEER_TEAM, 0) ?: 0 + ) + } + } \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/home/mockdata/HomeMockData.kt b/presentation/src/main/java/com/depromeet/presentation/home/mockdata/HomeMockData.kt index 813345ab..22ad8930 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/mockdata/HomeMockData.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/mockdata/HomeMockData.kt @@ -14,10 +14,12 @@ import kotlin.random.Random @Parcelize data class Profile( val nickName: String = "", + val image : String = "", val writeCount: Int = 0, val level: Int = 0, val title: String = "", - val cheerTeam: String = "", + val teamImage: String = "", + val teamId : Int = 0 ) : Parcelable @Parcelize @@ -59,10 +61,10 @@ fun mockDataProfile(): Flow = flow { val profileList = listOf( - Profile("노균욱", 23, 5, "야구장 VIP", "https://picsum.photos/600/400"), - Profile("윤성식", 12, 4, "응원 단장", "https://picsum.photos/600/400"), - Profile("박민주", 2, 2, "직관 첫 걸음", "https://picsum.photos/600/400"), - Profile("조관희", 7, 3, "직관의 여유", "https://picsum.photos/600/400"), + Profile("노균욱", "https://picsum.photos/600/400",23, 5, "야구장 VIP", "https://picsum.photos/600/400",1), + Profile("윤성식", "https://picsum.photos/600/400",12, 4, "응원 단장", "https://picsum.photos/600/400",1), + Profile("박민주", "https://picsum.photos/600/400",2, 2, "직관 첫 걸음", "https://picsum.photos/600/400",1), + Profile("조관희", "https://picsum.photos/600/400",7, 3, "직관의 여유", "https://picsum.photos/600/400",1), ) val recentSightList = listOf( RecentSight("서울 잠실 야구장", "2024년 7월 20일", "3루 네이비석 3054블럭", emptyList()), diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt index c5cd001a..021edb72 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt @@ -3,13 +3,11 @@ package com.depromeet.presentation.home.viewmodel import android.os.Parcelable import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.depromeet.core.state.UiState import com.depromeet.presentation.home.mockdata.Profile import com.depromeet.presentation.home.mockdata.RecentSight import com.depromeet.presentation.home.mockdata.mockDataProfile import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -25,12 +23,12 @@ data class HomeUiState( @HiltViewModel class HomeViewModel @Inject constructor() : ViewModel() { - private val _uiState = MutableStateFlow>(UiState.Loading) - val uiState: StateFlow> = _uiState.asStateFlow() + private val _uiState = MutableStateFlow(HomeUiState()) + val uiState = _uiState.asStateFlow() fun getInformation() { mockDataProfile().onEach { - _uiState.value = UiState.Success(it) + _uiState.value = it }.launchIn(viewModelScope) } } \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt index 7981b5ab..a720a0be 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt @@ -30,11 +30,17 @@ class ProfileEditViewModel @Inject constructor( private val _profileImage = MutableStateFlow("") val profileImage = _profileImage.asStateFlow() + private val _cheerTeam = MutableStateFlow(0) + val cheerTeam = _cheerTeam.asStateFlow() + fun getBaseballTeam() { viewModelScope.launch { homeRepository.getBaseballTeam() - .onSuccess { - _team.value = UiState.Success(it) + .onSuccess { teams -> + val updatedTeams = teams.map { team -> + team.copy(isClicked = team.id == cheerTeam.value) + } + _team.value = UiState.Success(updatedTeams) }.onFailure { _team.value = UiState.Failure(it.message ?: "실패") } @@ -52,6 +58,7 @@ class ProfileEditViewModel @Inject constructor( team.copy(isClicked = team.id == id) } _team.value = UiState.Success(updatedList) + _cheerTeam.value = id } } @@ -62,9 +69,16 @@ class ProfileEditViewModel @Inject constructor( team.copy(isClicked = false) } _team.value = UiState.Success(updatedList) + _cheerTeam.value = 0 } } + fun setProfile(name: String, image: String, cheerTeam: Int) { + _nickName.value = name + _profileImage.value = image + _cheerTeam.value = cheerTeam + } + fun updateNickName(nickName: String) { _nickName.value = nickName _nickNameError.value = nickName.validateNickName() diff --git a/presentation/src/main/res/drawable/ic_camera_14.xml b/presentation/src/main/res/drawable/ic_camera_14.xml new file mode 100644 index 00000000..8625f5d3 --- /dev/null +++ b/presentation/src/main/res/drawable/ic_camera_14.xml @@ -0,0 +1,10 @@ + + + diff --git a/presentation/src/main/res/layout/activity_profile_edit.xml b/presentation/src/main/res/layout/activity_profile_edit.xml index 4d8d6bf7..db23fd8a 100644 --- a/presentation/src/main/res/layout/activity_profile_edit.xml +++ b/presentation/src/main/res/layout/activity_profile_edit.xml @@ -33,7 +33,8 @@ android:background="@android:color/transparent" android:src="@drawable/ic_x_close" app:layout_constraintStart_toEndOf="@id/gl_start" - app:layout_constraintTop_toBottomOf="@id/gl_top" /> + app:layout_constraintTop_toBottomOf="@id/gl_top" + tools:ignore="contentDescription"/> + app:layout_constraintTop_toTopOf="parent" + tools:ignore="contentDescription"/> + app:layout_constraintEnd_toEndOf="@id/iv_profile_edit_image" + tools:ignore="contentDescription"/> Date: Thu, 18 Jul 2024 23:19:52 +0900 Subject: [PATCH 22/83] =?UTF-8?q?[refactor/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=88=98=EC=A0=95=20=EC=95=A1=ED=8B=B0=EB=B9=84?= =?UTF-8?q?=ED=8B=B0=20=ED=95=A8=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/home/ProfileEditActivity.kt | 80 +++++++++++-------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index 30f7b05c..e9fdb93e 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -34,49 +34,35 @@ class ProfileEditActivity : BaseActivity( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setCheerTeamList() - navigateToPhotoPicker() - onClickTeam() - observeNickName() + viewModel.getBaseballTeam() + initView() + initEvent() + initObserver() + } + + private fun initView() { getDataExtra { name, image, cheerTeam -> viewModel.setProfile(name, image, cheerTeam) binding.etProfileEditNickname.setText(name) } + setCheerTeamList() + } - viewModel.getBaseballTeam() - - viewModel.profileImage.asLiveData().observe(this) { state -> - binding.ivProfileEditImage.load(state) { - transformations(CircleCropTransformation()) - } - } - - viewModel.team.asLiveData().observe(this) { state -> - when (state) { - is UiState.Success -> { - adapter.submitList(state.data) - } - - is UiState.Loading -> { - toast("로딩 중") - } - - is UiState.Empty -> { - toast("빈값 에러") - } - - is UiState.Failure -> { - toast("통신 실패") - } - } - } - + private fun initEvent() { binding.ibProfileEditClose.setOnClickListener { finish() } binding.tvProfileEditComplete.setOnClickListener { finish() } + navigateToPhotoPicker() + onClickTeam() + } + private fun initObserver() { + observeNickName() + observeTeam() + observeProfileImage() } + private fun setCheerTeamList() { adapter = BaseballTeamAdapter() binding.rvProfileEditTeam.adapter = adapter @@ -126,6 +112,36 @@ class ProfileEditActivity : BaseActivity( } } + private fun observeProfileImage() { + viewModel.profileImage.asLiveData().observe(this) { state -> + binding.ivProfileEditImage.load(state) { + transformations(CircleCropTransformation()) + } + } + } + + private fun observeTeam() { + viewModel.team.asLiveData().observe(this) { state -> + when (state) { + is UiState.Success -> { + adapter.submitList(state.data) + } + + is UiState.Loading -> { + toast("로딩 중") + } + + is UiState.Empty -> { + toast("빈값 에러") + } + + is UiState.Failure -> { + toast("통신 실패") + } + } + } + } + private fun updateCompletionStatus(isError: Boolean, error: String) = if (isError) { with(binding) { etProfileEditNickname.setBackgroundResource(R.drawable.rect_warning01red_line_6) From 8931d58c22e57c02f10e6681eaff3a340bea241f Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 18 Jul 2024 23:39:29 +0900 Subject: [PATCH 23/83] =?UTF-8?q?[refactor/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=88=98=EC=A0=95=20=EC=95=88=ED=95=A0=EC=8B=9C,?= =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84=20=EA=B7=9C=EC=B9=99=20=EC=9C=A0?= =?UTF-8?q?=EB=AC=B4=20text=20complete=20enabled=20=EB=B3=80=EA=B2=BD=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 --- .../presentation/home/ProfileEditActivity.kt | 12 ++++++-- .../home/viewmodel/ProfileEditViewModel.kt | 30 ++++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index e9fdb93e..e0790918 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -43,7 +43,7 @@ class ProfileEditActivity : BaseActivity( private fun initView() { getDataExtra { name, image, cheerTeam -> - viewModel.setProfile(name, image, cheerTeam) + viewModel.initProfile(name, image, cheerTeam) binding.etProfileEditNickname.setText(name) } setCheerTeamList() @@ -60,6 +60,7 @@ class ProfileEditActivity : BaseActivity( observeNickName() observeTeam() observeProfileImage() + observeChange() } @@ -120,6 +121,13 @@ class ProfileEditActivity : BaseActivity( } } + private fun observeChange() { + viewModel.changeEnabled.asLiveData().observe(this) { state -> + binding.tvProfileEditComplete.isEnabled = state + + } + } + private fun observeTeam() { viewModel.team.asLiveData().observe(this) { state -> when (state) { @@ -147,7 +155,6 @@ class ProfileEditActivity : BaseActivity( etProfileEditNickname.setBackgroundResource(R.drawable.rect_warning01red_line_6) tvProfileEditNicknameError.visibility = View.VISIBLE tvProfileEditNicknameError.text = error - tvProfileEditComplete.isEnabled = false } } else { @@ -155,7 +162,6 @@ class ProfileEditActivity : BaseActivity( etProfileEditNickname.setBackgroundResource(R.drawable.rect_gray100_line_6) tvProfileEditNicknameError.visibility = View.GONE tvProfileEditNicknameError.text = error - tvProfileEditComplete.isEnabled = true } } diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt index a720a0be..629114d3 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt @@ -10,6 +10,7 @@ import com.depromeet.presentation.extension.validateNickName import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch import javax.inject.Inject @@ -33,6 +34,27 @@ class ProfileEditViewModel @Inject constructor( private val _cheerTeam = MutableStateFlow(0) val cheerTeam = _cheerTeam.asStateFlow() + val changeEnabled = MutableStateFlow(false) + private var initialNickName: String = "" + private var initialProfileImage: String = "" + private var initialCheerTeam: Int = 0 + + init { + viewModelScope.launch { + combine( + nickName, + profileImage, + cheerTeam, + nickNameError + ) { nickName, profileImage, cheerTeam, nickNameError -> + (nickName != initialNickName || profileImage != initialProfileImage + || cheerTeam != initialCheerTeam) && nickNameError == NickNameError.NoError + }.collect { isChanged -> + changeEnabled.value = isChanged + } + } + } + fun getBaseballTeam() { viewModelScope.launch { homeRepository.getBaseballTeam() @@ -73,10 +95,16 @@ class ProfileEditViewModel @Inject constructor( } } - fun setProfile(name: String, image: String, cheerTeam: Int) { + fun initProfile(name: String, image: String, cheerTeam: Int) { + initialNickName = name + initialProfileImage = image + initialCheerTeam = cheerTeam + _nickName.value = name _profileImage.value = image _cheerTeam.value = cheerTeam + + changeEnabled.value = false } fun updateNickName(nickName: String) { From 20eafcb7499f88de6842cef455d0cf5baf17b9c6 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 01:10:59 +0900 Subject: [PATCH 24/83] =?UTF-8?q?[feature/#29]=20presignedUrl=20=EB=B0=9B?= =?UTF-8?q?=EA=B8=B0=20data,domain=20=EB=AA=A8=EB=93=88=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/depromeet/data/datasource/HomeDataSource.kt | 5 +++++ .../data/datasource/remote/HomeDataSourceImpl.kt | 5 +++++ .../java/com/depromeet/data/remote/HomeApiService.kt | 8 ++++++++ .../com/depromeet/data/repository/HomeRepositoryImpl.kt | 9 +++++++++ .../com/depromeet/domain/repository/HomeRepository.kt | 5 +++++ 5 files changed, 32 insertions(+) diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt index 32a34501..7bdf22a1 100644 --- a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -10,4 +10,9 @@ interface HomeDataSource { ): ResponseMySeatRecordDto suspend fun getBaseballTeamData(): List + + suspend fun postProfileImagePresigned( + fileExtension : String, + memberId : Int + ) : String } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index bec2b664..d3bad1cb 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -22,4 +22,9 @@ class HomeDataSourceImpl @Inject constructor( override suspend fun getBaseballTeamData(): List { return homeApiService.getBaseballTeam() } + + override suspend fun postProfileImagePresigned(fileExtension: String, memberId: Int): String { + return homeApiService.postProfileImagePresigned(fileExtension, memberId) + } + } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index 36f99acb..333571e5 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -3,6 +3,8 @@ package com.depromeet.data.remote import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.Path import retrofit2.http.Query interface HomeApiService { @@ -16,4 +18,10 @@ interface HomeApiService { @GET("/api/v1/baseball-teams") suspend fun getBaseballTeam(): List + + @POST("/api/v1/members/{memberId}/profile/images") + suspend fun postProfileImagePresigned( + @Path("fileExtension") fileExtension : String, + @Path("memberId") memberId : Int + ) : String } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index 2e95a8cf..a0003004 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -25,4 +25,13 @@ class HomeRepositoryImpl @Inject constructor( homeDataSource.getBaseballTeamData().map { it.toBaseballTeamResponse() } } } + + override suspend fun postProfileImagePresigned( + presignedUrl: String, + memberId: Int, + ): Result { + return runCatching { + homeDataSource.postProfileImagePresigned(presignedUrl, memberId) + } + } } \ No newline at end of file diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt index 2d9e0e2a..99eaa913 100644 --- a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -10,4 +10,9 @@ interface HomeRepository { ): Result suspend fun getBaseballTeam() : Result> + + suspend fun postProfileImagePresigned( + presignedUrl : String, + memberId : Int + ) : Result } \ No newline at end of file From 0b0f44974cf299892ff1c5d98708b22f1eb71b89 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:16:53 +0900 Subject: [PATCH 25/83] =?UTF-8?q?[feature/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20PresignedUrl=20data=20=EB=AA=A8=EB=93=88=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 --- .../data/datasource/HomeDataSource.kt | 12 +++++++++--- .../datasource/remote/HomeDataSourceImpl.kt | 18 ++++++++++++++++-- .../com/depromeet/data/mapper/HomeMapper.kt | 7 +++++++ .../model/request/RequestFileExtensionDto.kt | 10 ++++++++++ .../response/home/ResponsePresignedUrlDto.kt | 10 ++++++++++ .../depromeet/data/remote/HomeApiService.kt | 18 +++++++++++++++--- .../data/repository/HomeRepositoryImpl.kt | 15 ++++++++++++--- 7 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 data/src/main/java/com/depromeet/data/model/request/RequestFileExtensionDto.kt create mode 100644 data/src/main/java/com/depromeet/data/model/response/home/ResponsePresignedUrlDto.kt diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt index 7bdf22a1..f7804536 100644 --- a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -3,6 +3,7 @@ package com.depromeet.data.datasource import com.depromeet.data.model.request.RequestMySeatRecordDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto +import com.depromeet.data.model.response.home.ResponsePresignedUrlDto interface HomeDataSource { suspend fun getMySeatRecordData( @@ -12,7 +13,12 @@ interface HomeDataSource { suspend fun getBaseballTeamData(): List suspend fun postProfileImagePresigned( - fileExtension : String, - memberId : Int - ) : String + fileExtension: String, + memberId: Int, + ): ResponsePresignedUrlDto + + suspend fun putProfileImage( + presignedUrl: String, + image: ByteArray, + ) } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index d3bad1cb..cf1191c8 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -1,10 +1,14 @@ package com.depromeet.data.datasource.remote import com.depromeet.data.datasource.HomeDataSource +import com.depromeet.data.model.request.RequestFileExtensionDto import com.depromeet.data.model.request.RequestMySeatRecordDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto +import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.data.remote.HomeApiService +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.RequestBody.Companion.toRequestBody import javax.inject.Inject class HomeDataSourceImpl @Inject constructor( @@ -23,8 +27,18 @@ class HomeDataSourceImpl @Inject constructor( return homeApiService.getBaseballTeam() } - override suspend fun postProfileImagePresigned(fileExtension: String, memberId: Int): String { - return homeApiService.postProfileImagePresigned(fileExtension, memberId) + override suspend fun postProfileImagePresigned( + fileExtension: String, + memberId: Int, + ): ResponsePresignedUrlDto { + return homeApiService.postProfileImagePresigned( + RequestFileExtensionDto(fileExtension), + memberId + ) } + override suspend fun putProfileImage(presignedUrl: String, image: ByteArray) { + val mediaType = "image/*".toMediaTypeOrNull() + return homeApiService.putProfileImage(presignedUrl, image.toRequestBody(mediaType)) + } } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt index 617f9bd3..1537580c 100644 --- a/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt +++ b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt @@ -3,9 +3,11 @@ package com.depromeet.data.mapper import com.depromeet.data.model.request.RequestMySeatRecordDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto +import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.domain.entity.request.home.MySeatRecordRequest import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse +import com.depromeet.domain.entity.response.home.PresignedUrlResponse fun ResponseMySeatRecordDto.toMySeatRecordResponse() = MySeatRecordResponse( reviews = reviews.map { it.toReviewResponse() }, @@ -69,4 +71,9 @@ fun ResponseBaseballTeamDto.toBaseballTeamResponse() = BaseballTeamResponse( id = id, name = name, logo = logo +) + +/** PresignedUrl Mapper **/ +fun ResponsePresignedUrlDto.toPresignedUrlResponse() = PresignedUrlResponse( + presignedUrl = presignedUrl ) \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/model/request/RequestFileExtensionDto.kt b/data/src/main/java/com/depromeet/data/model/request/RequestFileExtensionDto.kt new file mode 100644 index 00000000..f4a12ba8 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/model/request/RequestFileExtensionDto.kt @@ -0,0 +1,10 @@ +package com.depromeet.data.model.request + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RequestFileExtensionDto( + @SerialName("fileExtension") + val fileExtension: String, +) diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponsePresignedUrlDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponsePresignedUrlDto.kt new file mode 100644 index 00000000..c673ce56 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponsePresignedUrlDto.kt @@ -0,0 +1,10 @@ +package com.depromeet.data.model.response.home + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponsePresignedUrlDto( + @SerialName("presignedUrl") + val presignedUrl : String +) diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index 333571e5..55749137 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -1,11 +1,17 @@ package com.depromeet.data.remote +import com.depromeet.data.model.request.RequestFileExtensionDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto +import com.depromeet.data.model.response.home.ResponsePresignedUrlDto +import okhttp3.RequestBody +import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.POST +import retrofit2.http.PUT import retrofit2.http.Path import retrofit2.http.Query +import retrofit2.http.Url interface HomeApiService { @GET("/api/v1/reviews") @@ -21,7 +27,13 @@ interface HomeApiService { @POST("/api/v1/members/{memberId}/profile/images") suspend fun postProfileImagePresigned( - @Path("fileExtension") fileExtension : String, - @Path("memberId") memberId : Int - ) : String + @Body body: RequestFileExtensionDto, + @Path("memberId") memberId: Int, + ): ResponsePresignedUrlDto + + @PUT + suspend fun putProfileImage( + @Url preSignedUrl: String, + @Body image: RequestBody, + ) } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index a0003004..4187b6c1 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -4,9 +4,11 @@ import com.depromeet.data.datasource.HomeDataSource import com.depromeet.data.mapper.toBaseballTeamResponse import com.depromeet.data.mapper.toMySeatRecordRequestDto import com.depromeet.data.mapper.toMySeatRecordResponse +import com.depromeet.data.mapper.toPresignedUrlResponse import com.depromeet.domain.entity.request.home.MySeatRecordRequest import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse +import com.depromeet.domain.entity.response.home.PresignedUrlResponse import com.depromeet.domain.repository.HomeRepository import javax.inject.Inject @@ -27,11 +29,18 @@ class HomeRepositoryImpl @Inject constructor( } override suspend fun postProfileImagePresigned( - presignedUrl: String, + fileExtension: String, memberId: Int, - ): Result { + ): Result { return runCatching { - homeDataSource.postProfileImagePresigned(presignedUrl, memberId) + homeDataSource.postProfileImagePresigned(fileExtension, memberId) + .toPresignedUrlResponse() + } + } + + override suspend fun putProfileImage(presignedUrl: String, image: ByteArray): Result { + return runCatching { + homeDataSource.putProfileImage(presignedUrl, image) } } } \ No newline at end of file From 0572629e424a22cd0d29787cdf1b967d612cf2ad Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:17:17 +0900 Subject: [PATCH 26/83] =?UTF-8?q?[feature/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20PresignedUrl=20domain=20=EB=AA=A8=EB=93=88=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 --- .../entity/response/home/PresignedUrlResponse.kt | 5 +++++ .../depromeet/domain/repository/HomeRepository.kt | 14 ++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 domain/src/main/java/com/depromeet/domain/entity/response/home/PresignedUrlResponse.kt diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/PresignedUrlResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/PresignedUrlResponse.kt new file mode 100644 index 00000000..691502a3 --- /dev/null +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/PresignedUrlResponse.kt @@ -0,0 +1,5 @@ +package com.depromeet.domain.entity.response.home + +data class PresignedUrlResponse( + val presignedUrl: String = "" +) \ No newline at end of file diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt index 99eaa913..68421ffe 100644 --- a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -3,16 +3,22 @@ package com.depromeet.domain.repository import com.depromeet.domain.entity.request.home.MySeatRecordRequest import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse +import com.depromeet.domain.entity.response.home.PresignedUrlResponse interface HomeRepository { suspend fun getMySeatRecord( mySeatRecordRequest: MySeatRecordRequest, ): Result - suspend fun getBaseballTeam() : Result> + suspend fun getBaseballTeam(): Result> suspend fun postProfileImagePresigned( - presignedUrl : String, - memberId : Int - ) : Result + fileExtension: String, + memberId: Int, + ): Result + + suspend fun putProfileImage( + presignedUrl: String, + image: ByteArray, + ): Result } \ No newline at end of file From 5a547edcbf5030e18eb101d23984a8f5adcbc9fb Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:17:57 +0900 Subject: [PATCH 27/83] =?UTF-8?q?[feature/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20PresignedUrl=20presentation=20=EB=AA=A8=EB=93=88=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 --- .../home/ProfileImageUploadDialog.kt | 19 +++++++- .../home/viewmodel/ProfileEditViewModel.kt | 44 +++++++++++++++++++ presentation/src/main/res/values/strings.xml | 2 + 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt index a08137dc..13cfbd22 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.net.Uri import android.os.Bundle import android.view.View +import android.webkit.MimeTypeMap import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.activityViewModels @@ -69,11 +70,25 @@ class ProfileImageUploadDialog() : BindingBottomSheetDialog>>(UiState.Loading) val team = _team.asStateFlow() + private val _presignedUrl = MutableStateFlow>(UiState.Loading) + val presignedUrl = _presignedUrl.asStateFlow() + private val _nickName = MutableStateFlow("") val nickName = _nickName.asStateFlow() @@ -35,6 +40,7 @@ class ProfileEditViewModel @Inject constructor( val cheerTeam = _cheerTeam.asStateFlow() val changeEnabled = MutableStateFlow(false) + private var initialNickName: String = "" private var initialProfileImage: String = "" private var initialCheerTeam: Int = 0 @@ -73,6 +79,44 @@ class ProfileEditViewModel @Inject constructor( _profileImage.value = uri } + fun setProfileImagePresigned( + profileByteArray: ByteArray, + fileExtension: String, + memberId: Int, + ) { + viewModelScope.launch { + homeRepository.postProfileImagePresigned(fileExtension, memberId) + .onSuccess { presignedUrl -> + Timber.d("testSuccess = $presignedUrl") + _presignedUrl.value = UiState.Success(presignedUrl) + uploadProfileImage(profileByteArray) + } + .onFailure { + _presignedUrl.value = UiState.Failure(it.message ?: "실패") + Timber.e("testFail = 실패") + } + } + } + + fun uploadProfileImage(profileByteArray: ByteArray) { + //여기서 성공하면 _profileImage.value = string하기 + val currentState = presignedUrl.value + if (currentState is UiState.Success) { + viewModelScope.launch { + homeRepository.putProfileImage(currentState.data.presignedUrl, profileByteArray) + .onSuccess { + setProfileImage(currentState.data.presignedUrl) + Timber.d("test_UPLOAD_PROFILE_SUCCESS") + } + .onFailure { + Timber.d("test_UPLOAD_PROFILE_FAILURE : $it") + } + } + + } + } + + fun setClickedBaseballTeam(id: Int) { val currentState = team.value if (currentState is UiState.Success) { diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index f918a4a0..0937cca4 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -31,6 +31,8 @@ 선택한 사진\n용량이 너무 커요 5MB에 맞게 다시 선택해주세요 15MB에 맞게 다시 선택해주세요 + 선택한 사진\n확장자가 맞지 않아요 + jpg, jpeg, png 사진을 선택해주세요 확인 From 91e809a3e23086b4c45addd476303013c7be1ff5 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:22:38 +0900 Subject: [PATCH 28/83] =?UTF-8?q?[refactor/#29]=20request=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=ED=99=88=EC=97=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/model/request/{ => home}/RequestFileExtensionDto.kt | 2 +- .../data/model/request/{ => home}/RequestMySeatRecordDto.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename data/src/main/java/com/depromeet/data/model/request/{ => home}/RequestFileExtensionDto.kt (81%) rename data/src/main/java/com/depromeet/data/model/request/{ => home}/RequestMySeatRecordDto.kt (88%) diff --git a/data/src/main/java/com/depromeet/data/model/request/RequestFileExtensionDto.kt b/data/src/main/java/com/depromeet/data/model/request/home/RequestFileExtensionDto.kt similarity index 81% rename from data/src/main/java/com/depromeet/data/model/request/RequestFileExtensionDto.kt rename to data/src/main/java/com/depromeet/data/model/request/home/RequestFileExtensionDto.kt index f4a12ba8..8163165c 100644 --- a/data/src/main/java/com/depromeet/data/model/request/RequestFileExtensionDto.kt +++ b/data/src/main/java/com/depromeet/data/model/request/home/RequestFileExtensionDto.kt @@ -1,4 +1,4 @@ -package com.depromeet.data.model.request +package com.depromeet.data.model.request.home import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/data/src/main/java/com/depromeet/data/model/request/RequestMySeatRecordDto.kt b/data/src/main/java/com/depromeet/data/model/request/home/RequestMySeatRecordDto.kt similarity index 88% rename from data/src/main/java/com/depromeet/data/model/request/RequestMySeatRecordDto.kt rename to data/src/main/java/com/depromeet/data/model/request/home/RequestMySeatRecordDto.kt index 193e2027..528bfe37 100644 --- a/data/src/main/java/com/depromeet/data/model/request/RequestMySeatRecordDto.kt +++ b/data/src/main/java/com/depromeet/data/model/request/home/RequestMySeatRecordDto.kt @@ -1,4 +1,4 @@ -package com.depromeet.data.model.request +package com.depromeet.data.model.request.home import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable From 667dd2785f3d90ca346bfeff16bb54b5980c0274 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:54:40 +0900 Subject: [PATCH 29/83] =?UTF-8?q?[feature/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EC=8B=9C=20=EB=B7=B0=EA=B4=80=EB=A0=A8=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../depromeet/presentation/home/ProfileEditActivity.kt | 8 ++++++++ .../presentation/home/ProfileImageUploadDialog.kt | 1 + .../home/viewmodel/ProfileEditViewModel.kt | 10 ++-------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index e0790918..11ec9e67 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -119,6 +119,14 @@ class ProfileEditActivity : BaseActivity( transformations(CircleCropTransformation()) } } + viewModel.presignedUrl.asLiveData().observe(this) {state -> + when(state){ + is UiState.Success -> {} + is UiState.Failure -> {toast("이미지 업로드를 실패하였습니다. 다시 선택해주세요.")} + is UiState.Empty -> {toast("실패")} + is UiState.Loading -> {} + } + } } private fun observeChange() { diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt index 13cfbd22..7b9646f6 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt @@ -82,6 +82,7 @@ class ProfileImageUploadDialog() : BindingBottomSheetDialog - Timber.d("testSuccess = $presignedUrl") _presignedUrl.value = UiState.Success(presignedUrl) uploadProfileImage(profileByteArray) } .onFailure { _presignedUrl.value = UiState.Failure(it.message ?: "실패") - Timber.e("testFail = 실패") } } } fun uploadProfileImage(profileByteArray: ByteArray) { - //여기서 성공하면 _profileImage.value = string하기 val currentState = presignedUrl.value if (currentState is UiState.Success) { viewModelScope.launch { homeRepository.putProfileImage(currentState.data.presignedUrl, profileByteArray) .onSuccess { - setProfileImage(currentState.data.presignedUrl) - Timber.d("test_UPLOAD_PROFILE_SUCCESS") + } .onFailure { - Timber.d("test_UPLOAD_PROFILE_FAILURE : $it") + setProfileImage("") } } - } } From 05fe747ef54d8fe29913d0b2ab9124e2b6bd5909 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 17:50:15 +0900 Subject: [PATCH 30/83] =?UTF-8?q?[feature/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20data=20modul?= =?UTF-8?q?e=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/datasource/HomeDataSource.kt | 9 ++++++- .../datasource/remote/HomeDataSourceImpl.kt | 13 ++++++++-- .../com/depromeet/data/mapper/HomeMapper.kt | 4 +-- .../request/home/RequestProfileEditDto.kt | 23 ++++++++++++++++ .../response/home/ResponseProfileEditDto.kt | 26 +++++++++++++++++++ .../depromeet/data/remote/HomeApiService.kt | 10 ++++++- .../data/repository/HomeRepositoryImpl.kt | 14 ++++++++++ 7 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 data/src/main/java/com/depromeet/data/model/request/home/RequestProfileEditDto.kt create mode 100644 data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileEditDto.kt diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt index f7804536..72774b5e 100644 --- a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -1,9 +1,11 @@ package com.depromeet.data.datasource -import com.depromeet.data.model.request.RequestMySeatRecordDto +import com.depromeet.data.model.request.home.RequestMySeatRecordDto +import com.depromeet.data.model.request.home.RequestProfileEditDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto +import com.depromeet.data.model.response.home.ResponseProfileEditDto interface HomeDataSource { suspend fun getMySeatRecordData( @@ -21,4 +23,9 @@ interface HomeDataSource { presignedUrl: String, image: ByteArray, ) + + suspend fun putProfileEdit( + requestProfileEditDto: RequestProfileEditDto, + memberId: Int, + ) : ResponseProfileEditDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index cf1191c8..b953d4d8 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -1,11 +1,13 @@ package com.depromeet.data.datasource.remote import com.depromeet.data.datasource.HomeDataSource -import com.depromeet.data.model.request.RequestFileExtensionDto -import com.depromeet.data.model.request.RequestMySeatRecordDto +import com.depromeet.data.model.request.home.RequestFileExtensionDto +import com.depromeet.data.model.request.home.RequestMySeatRecordDto +import com.depromeet.data.model.request.home.RequestProfileEditDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto +import com.depromeet.data.model.response.home.ResponseProfileEditDto import com.depromeet.data.remote.HomeApiService import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody.Companion.toRequestBody @@ -41,4 +43,11 @@ class HomeDataSourceImpl @Inject constructor( val mediaType = "image/*".toMediaTypeOrNull() return homeApiService.putProfileImage(presignedUrl, image.toRequestBody(mediaType)) } + + override suspend fun putProfileEdit( + requestProfileEditDto: RequestProfileEditDto, + memberId: Int, + ): ResponseProfileEditDto { + return homeApiService.putProfileEdit(requestProfileEditDto, memberId) + } } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt index 1537580c..c4fd60e2 100644 --- a/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt +++ b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt @@ -1,6 +1,6 @@ package com.depromeet.data.mapper -import com.depromeet.data.model.request.RequestMySeatRecordDto +import com.depromeet.data.model.request.home.RequestMySeatRecordDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto @@ -76,4 +76,4 @@ fun ResponseBaseballTeamDto.toBaseballTeamResponse() = BaseballTeamResponse( /** PresignedUrl Mapper **/ fun ResponsePresignedUrlDto.toPresignedUrlResponse() = PresignedUrlResponse( presignedUrl = presignedUrl -) \ No newline at end of file +) diff --git a/data/src/main/java/com/depromeet/data/model/request/home/RequestProfileEditDto.kt b/data/src/main/java/com/depromeet/data/model/request/home/RequestProfileEditDto.kt new file mode 100644 index 00000000..21cdaa70 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/model/request/home/RequestProfileEditDto.kt @@ -0,0 +1,23 @@ +package com.depromeet.data.model.request.home + +import com.depromeet.domain.entity.request.home.ProfileEditRequest +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RequestProfileEditDto( + @SerialName("profileImage") + val profileImage: String? = null, + @SerialName("nickname") + val nickname: String? = null, + @SerialName("teamId") + val teamId: Int? = null, +) { + companion object { + fun ProfileEditRequest.toProfileEditRequestDto() = RequestProfileEditDto( + profileImage = url, + nickname = nickname, + teamId = teamId + ) + } +} \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileEditDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileEditDto.kt new file mode 100644 index 00000000..cf5e017b --- /dev/null +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileEditDto.kt @@ -0,0 +1,26 @@ +package com.depromeet.data.model.response.home + +import com.depromeet.domain.entity.response.home.ProfileEditResponse +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponseProfileEditDto( + @SerialName("id") + val id: Int, + @SerialName("nickname") + val nickname: String, + @SerialName("teamId") + val teamId: Int, +) { + companion object { + fun ResponseProfileEditDto.toProfileEditResponse(): ProfileEditResponse { + return ProfileEditResponse( + id = id, + nickname = nickname, + teamId = teamId + ) + } + } + +} \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index 55749137..1299596b 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -1,9 +1,11 @@ package com.depromeet.data.remote -import com.depromeet.data.model.request.RequestFileExtensionDto +import com.depromeet.data.model.request.home.RequestFileExtensionDto +import com.depromeet.data.model.request.home.RequestProfileEditDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto +import com.depromeet.data.model.response.home.ResponseProfileEditDto import okhttp3.RequestBody import retrofit2.http.Body import retrofit2.http.GET @@ -36,4 +38,10 @@ interface HomeApiService { @Url preSignedUrl: String, @Body image: RequestBody, ) + + @PUT("/api/v1/members/{memberId}") + suspend fun putProfileEdit( + @Body body: RequestProfileEditDto, + @Path("memberId") memberId: Int, + ) : ResponseProfileEditDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index 4187b6c1..3cb26e9a 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -5,10 +5,14 @@ import com.depromeet.data.mapper.toBaseballTeamResponse import com.depromeet.data.mapper.toMySeatRecordRequestDto import com.depromeet.data.mapper.toMySeatRecordResponse import com.depromeet.data.mapper.toPresignedUrlResponse +import com.depromeet.data.model.request.home.RequestProfileEditDto.Companion.toProfileEditRequestDto +import com.depromeet.data.model.response.home.ResponseProfileEditDto.Companion.toProfileEditResponse import com.depromeet.domain.entity.request.home.MySeatRecordRequest +import com.depromeet.domain.entity.request.home.ProfileEditRequest import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse +import com.depromeet.domain.entity.response.home.ProfileEditResponse import com.depromeet.domain.repository.HomeRepository import javax.inject.Inject @@ -43,4 +47,14 @@ class HomeRepositoryImpl @Inject constructor( homeDataSource.putProfileImage(presignedUrl, image) } } + + override suspend fun putProfileEdit( + profileEditRequest: ProfileEditRequest, + memberId: Int, + ): Result { + return runCatching { + homeDataSource.putProfileEdit(profileEditRequest.toProfileEditRequestDto(), memberId) + .toProfileEditResponse() + } + } } \ No newline at end of file From 047ac6d29ade54dcf7679f905ea615fdceeda1e5 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 17:50:31 +0900 Subject: [PATCH 31/83] =?UTF-8?q?[feature/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20domain=20mod?= =?UTF-8?q?ule=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/entity/request/home/ProfileEditRequest.kt | 7 +++++++ .../domain/entity/response/home/ProfileEditResponse.kt | 7 +++++++ .../java/com/depromeet/domain/repository/HomeRepository.kt | 7 +++++++ 3 files changed, 21 insertions(+) create mode 100644 domain/src/main/java/com/depromeet/domain/entity/request/home/ProfileEditRequest.kt create mode 100644 domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileEditResponse.kt diff --git a/domain/src/main/java/com/depromeet/domain/entity/request/home/ProfileEditRequest.kt b/domain/src/main/java/com/depromeet/domain/entity/request/home/ProfileEditRequest.kt new file mode 100644 index 00000000..4b514a80 --- /dev/null +++ b/domain/src/main/java/com/depromeet/domain/entity/request/home/ProfileEditRequest.kt @@ -0,0 +1,7 @@ +package com.depromeet.domain.entity.request.home + +data class ProfileEditRequest( + val url : String ?= null, + val nickname : String ?= null, + val teamId : Int ?= null, +) diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileEditResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileEditResponse.kt new file mode 100644 index 00000000..c746a840 --- /dev/null +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileEditResponse.kt @@ -0,0 +1,7 @@ +package com.depromeet.domain.entity.response.home + +data class ProfileEditResponse( + val id: Int, + val nickname: String = "", + val teamId: Int = 0, +) \ No newline at end of file diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt index 68421ffe..e886106f 100644 --- a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -1,9 +1,11 @@ package com.depromeet.domain.repository import com.depromeet.domain.entity.request.home.MySeatRecordRequest +import com.depromeet.domain.entity.request.home.ProfileEditRequest import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse +import com.depromeet.domain.entity.response.home.ProfileEditResponse interface HomeRepository { suspend fun getMySeatRecord( @@ -21,4 +23,9 @@ interface HomeRepository { presignedUrl: String, image: ByteArray, ): Result + + suspend fun putProfileEdit( + profileEditRequest: ProfileEditRequest, + memberId: Int + ) : Result } \ No newline at end of file From f564f38b0465b2e0ec10b967e83141f647dd78bb Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 17:50:48 +0900 Subject: [PATCH 32/83] =?UTF-8?q?[feature/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20presentation?= =?UTF-8?q?=20module=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/home/ProfileEditActivity.kt | 29 +++++++--- .../home/viewmodel/ProfileEditViewModel.kt | 54 ++++++++++++++++--- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index 11ec9e67..7b9e153b 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -51,7 +51,9 @@ class ProfileEditActivity : BaseActivity( private fun initEvent() { binding.ibProfileEditClose.setOnClickListener { finish() } - binding.tvProfileEditComplete.setOnClickListener { finish() } + binding.tvProfileEditComplete.setOnClickListener { + viewModel.uploadProfileEdit() + } navigateToPhotoPicker() onClickTeam() } @@ -119,12 +121,17 @@ class ProfileEditActivity : BaseActivity( transformations(CircleCropTransformation()) } } - viewModel.presignedUrl.asLiveData().observe(this) {state -> - when(state){ - is UiState.Success -> {} - is UiState.Failure -> {toast("이미지 업로드를 실패하였습니다. 다시 선택해주세요.")} - is UiState.Empty -> {toast("실패")} + viewModel.presignedUrl.asLiveData().observe(this) { state -> + when (state) { is UiState.Loading -> {} + is UiState.Success -> {} + is UiState.Failure -> { + toast("이미지 업로드를 실패하였습니다. 다시 선택해주세요.") + } + + is UiState.Empty -> { + toast("실패") + } } } } @@ -134,6 +141,16 @@ class ProfileEditActivity : BaseActivity( binding.tvProfileEditComplete.isEnabled = state } + + viewModel.profileEdit.asLiveData().observe(this) { state -> + when(state) { + is UiState.Success -> { finish() } + is UiState.Failure -> { toast("프로필 변경에 실패\n다시 시도바람") } + is UiState.Empty -> { toast("프로필 변경 실패\n다시 시도바람(빈값")} + is UiState.Loading -> {} + } + + } } private fun observeTeam() { diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt index 48874213..cc688658 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt @@ -1,10 +1,13 @@ package com.depromeet.presentation.home.viewmodel +import android.net.Uri import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.depromeet.core.state.UiState +import com.depromeet.domain.entity.request.home.ProfileEditRequest import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse +import com.depromeet.domain.entity.response.home.ProfileEditResponse import com.depromeet.domain.repository.HomeRepository import com.depromeet.presentation.extension.NickNameError import com.depromeet.presentation.extension.validateNickName @@ -13,6 +16,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch +import timber.log.Timber import javax.inject.Inject @HiltViewModel @@ -26,8 +30,11 @@ class ProfileEditViewModel @Inject constructor( private val _presignedUrl = MutableStateFlow>(UiState.Loading) val presignedUrl = _presignedUrl.asStateFlow() - private val _nickName = MutableStateFlow("") - val nickName = _nickName.asStateFlow() + private val _profileEdit = MutableStateFlow>(UiState.Loading) + val profileEdit = _profileEdit.asStateFlow() + + private val _nickname = MutableStateFlow("") + val nickname = _nickname.asStateFlow() private val _nickNameError = MutableStateFlow(NickNameError.NoError) val nickNameError = _nickNameError.asStateFlow() @@ -47,7 +54,7 @@ class ProfileEditViewModel @Inject constructor( init { viewModelScope.launch { combine( - nickName, + nickname, profileImage, cheerTeam, nickNameError @@ -99,7 +106,10 @@ class ProfileEditViewModel @Inject constructor( val currentState = presignedUrl.value if (currentState is UiState.Success) { viewModelScope.launch { - homeRepository.putProfileImage(currentState.data.presignedUrl, profileByteArray) + homeRepository.putProfileImage( + currentState.data.presignedUrl, + profileByteArray + ) .onSuccess { } @@ -110,6 +120,38 @@ class ProfileEditViewModel @Inject constructor( } } + fun uploadProfileEdit() { + viewModelScope.launch { + homeRepository.putProfileEdit( + ProfileEditRequest( + url = getPresignedUrlOrNull(), + nickname = nickname.value, + teamId = cheerTeam.value + ), memberId = 1 + /** memberId ->추후에 메인화면 api 나오면 연동해서 stateflow 업데이트*/ + ) + .onSuccess { + _profileEdit.value = UiState.Success(it) + Timber.d("test success -> $it") + } + .onFailure { + Timber.d("test fail -> $it") + } + } + } + + private fun getPresignedUrlOrNull(): String? { + val currentState = presignedUrl.value + return if (currentState is UiState.Success) { + removeQueryParameters(currentState.data.presignedUrl) + } else null + } + + private fun removeQueryParameters(url: String): String { + val uri = Uri.parse(url) + return uri.buildUpon().clearQuery().build().toString() + } + fun setClickedBaseballTeam(id: Int) { val currentState = team.value @@ -138,7 +180,7 @@ class ProfileEditViewModel @Inject constructor( initialProfileImage = image initialCheerTeam = cheerTeam - _nickName.value = name + _nickname.value = name _profileImage.value = image _cheerTeam.value = cheerTeam @@ -146,7 +188,7 @@ class ProfileEditViewModel @Inject constructor( } fun updateNickName(nickName: String) { - _nickName.value = nickName + _nickname.value = nickName _nickNameError.value = nickName.validateNickName() } } \ No newline at end of file From 5924c30dd2527cf5f72437584bbb2eb1b05617e3 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 18:45:03 +0900 Subject: [PATCH 33/83] =?UTF-8?q?[feature/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=ED=9B=84=20=EC=88=98=EC=A0=95=20=EC=99=84=EB=A3=8C=EB=A5=BC=20?= =?UTF-8?q?=EB=B0=94=EB=A1=9C=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=82=AC=ED=95=AD=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/viewmodel/ProfileEditViewModel.kt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt index cc688658..39cdb5eb 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt @@ -12,6 +12,7 @@ import com.depromeet.domain.repository.HomeRepository import com.depromeet.presentation.extension.NickNameError import com.depromeet.presentation.extension.validateNickName import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine @@ -46,6 +47,8 @@ class ProfileEditViewModel @Inject constructor( val cheerTeam = _cheerTeam.asStateFlow() val changeEnabled = MutableStateFlow(false) + private var profileImageJob: Job? = null + private var profilePresignedJob: Job? = null private var initialNickName: String = "" private var initialProfileImage: String = "" @@ -90,7 +93,7 @@ class ProfileEditViewModel @Inject constructor( fileExtension: String, memberId: Int, ) { - viewModelScope.launch { + profilePresignedJob = viewModelScope.launch { homeRepository.postProfileImagePresigned(fileExtension, memberId) .onSuccess { presignedUrl -> _presignedUrl.value = UiState.Success(presignedUrl) @@ -102,10 +105,10 @@ class ProfileEditViewModel @Inject constructor( } } - fun uploadProfileImage(profileByteArray: ByteArray) { + private fun uploadProfileImage(profileByteArray: ByteArray) { val currentState = presignedUrl.value if (currentState is UiState.Success) { - viewModelScope.launch { + profileImageJob = viewModelScope.launch { homeRepository.putProfileImage( currentState.data.presignedUrl, profileByteArray @@ -122,6 +125,11 @@ class ProfileEditViewModel @Inject constructor( fun uploadProfileEdit() { viewModelScope.launch { + if ((profileImageJob?.isActive == true) || (profilePresignedJob?.isActive == true)) { + profileImageJob?.join() + profilePresignedJob?.join() + } + homeRepository.putProfileEdit( ProfileEditRequest( url = getPresignedUrlOrNull(), From 36c56e22c4be0c976cf9571612e9e8201d99975a Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 19:33:22 +0900 Subject: [PATCH 34/83] =?UTF-8?q?[feature/#29]=20=EB=8B=89=EB=84=A4?= =?UTF-8?q?=EC=9E=84=20=EC=A4=91=EB=B3=B5=20API=20data=20module=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 --- .../java/com/depromeet/data/datasource/HomeDataSource.kt | 4 ++++ .../depromeet/data/datasource/remote/HomeDataSourceImpl.kt | 4 ++++ .../main/java/com/depromeet/data/remote/HomeApiService.kt | 7 ++++++- .../com/depromeet/data/repository/HomeRepositoryImpl.kt | 6 ++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt index 72774b5e..edf9929f 100644 --- a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -28,4 +28,8 @@ interface HomeDataSource { requestProfileEditDto: RequestProfileEditDto, memberId: Int, ) : ResponseProfileEditDto + + suspend fun getDuplicateNickname( + nickname : String + ) } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index b953d4d8..6d1204fc 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -50,4 +50,8 @@ class HomeDataSourceImpl @Inject constructor( ): ResponseProfileEditDto { return homeApiService.putProfileEdit(requestProfileEditDto, memberId) } + + override suspend fun getDuplicateNickname(nickname: String) { + return homeApiService.getDuplicateNickname(nickname) + } } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index 1299596b..12066d66 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -43,5 +43,10 @@ interface HomeApiService { suspend fun putProfileEdit( @Body body: RequestProfileEditDto, @Path("memberId") memberId: Int, - ) : ResponseProfileEditDto + ): ResponseProfileEditDto + + @GET("/api/v1/members/duplicatedNickname/{nickname}") + suspend fun getDuplicateNickname( + @Path("nickname") nickname: String, + ) } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index 3cb26e9a..b72436d0 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -57,4 +57,10 @@ class HomeRepositoryImpl @Inject constructor( .toProfileEditResponse() } } + + override suspend fun getDuplicateNickname(nickname: String): Result { + return runCatching { + homeDataSource.getDuplicateNickname(nickname) + } + } } \ No newline at end of file From 5036df04c3c9fc4cafdf3669ae797d02578fd96c Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 19:34:15 +0900 Subject: [PATCH 35/83] =?UTF-8?q?[feature/#29]=20=EB=8B=89=EB=84=A4?= =?UTF-8?q?=EC=9E=84=20=EC=A4=91=EB=B3=B5=20API=20domain,presentation=20mo?= =?UTF-8?q?dule=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/repository/HomeRepository.kt | 8 +++- .../presentation/extension/StringExt.kt | 2 - .../presentation/home/ProfileEditActivity.kt | 38 ++++++++++++++++-- .../home/viewmodel/ProfileEditViewModel.kt | 40 +++++++++++++++++-- 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt index e886106f..584b1752 100644 --- a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -26,6 +26,10 @@ interface HomeRepository { suspend fun putProfileEdit( profileEditRequest: ProfileEditRequest, - memberId: Int - ) : Result + memberId: Int, + ): Result + + suspend fun getDuplicateNickname( + nickname: String, + ): Result } \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt b/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt index 2e8a3035..c3843742 100644 --- a/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt +++ b/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt @@ -6,7 +6,6 @@ import java.time.format.TextStyle import java.util.Locale const val NICKNAME_PATTERN = "^[a-zA-Z0-9가-힣]+$" -const val TEST_DUPLICATE_NICKNAME = "안드로이드" //서버 연동되면 삭제예정 sealed class NickNameError { object NoError : NickNameError() @@ -20,7 +19,6 @@ fun String.validateNickName(): NickNameError { return when { this.length !in 2..10 -> NickNameError.LengthError !this.matches(Regex(NICKNAME_PATTERN)) -> NickNameError.InvalidCharacterError - this == TEST_DUPLICATE_NICKNAME -> NickNameError.DuplicateError else -> NickNameError.NoError } } diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index 7b9e153b..348812de 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -5,7 +5,10 @@ import android.text.Editable import android.view.View import androidx.activity.viewModels import androidx.core.widget.addTextChangedListener +import androidx.lifecycle.Lifecycle import androidx.lifecycle.asLiveData +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import coil.load import coil.transform.CircleCropTransformation import com.depromeet.core.base.BaseActivity @@ -18,7 +21,9 @@ import com.depromeet.presentation.extension.toast import com.depromeet.presentation.home.adapter.BaseballTeamAdapter import com.depromeet.presentation.home.adapter.GridSpacingItemDecoration import com.depromeet.presentation.home.viewmodel.ProfileEditViewModel +import com.depromeet.presentation.home.viewmodel.ProfileEvents import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch @AndroidEntryPoint class ProfileEditActivity : BaseActivity( @@ -59,6 +64,7 @@ class ProfileEditActivity : BaseActivity( } private fun initObserver() { + observeEvent() observeNickName() observeTeam() observeProfileImage() @@ -77,6 +83,21 @@ class ProfileEditActivity : BaseActivity( ) } + private fun observeEvent() { + lifecycleScope.launch { + lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.events.collect { event -> + when (event) { + is ProfileEvents.ShowSnackMessage -> { + toast(event.message) + } + } + } + } + + } + } + private fun observeNickName() { binding.etProfileEditNickname.addTextChangedListener { text: Editable? -> viewModel.updateNickName(text.toString()) @@ -143,10 +164,19 @@ class ProfileEditActivity : BaseActivity( } viewModel.profileEdit.asLiveData().observe(this) { state -> - when(state) { - is UiState.Success -> { finish() } - is UiState.Failure -> { toast("프로필 변경에 실패\n다시 시도바람") } - is UiState.Empty -> { toast("프로필 변경 실패\n다시 시도바람(빈값")} + when (state) { + is UiState.Success -> { + finish() + } + + is UiState.Failure -> { + toast("프로필 변경에 실패\n다시 시도바람") + } + + is UiState.Empty -> { + toast("프로필 변경 실패\n다시 시도바람(빈값") + } + is UiState.Loading -> {} } diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt index 39cdb5eb..bdf9f934 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt @@ -13,18 +13,34 @@ import com.depromeet.presentation.extension.NickNameError import com.depromeet.presentation.extension.validateNickName import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch -import timber.log.Timber import javax.inject.Inject +sealed class ProfileEvents { + data class ShowSnackMessage( + val message: String, + ) : ProfileEvents() +} + @HiltViewModel class ProfileEditViewModel @Inject constructor( private val homeRepository: HomeRepository, ) : ViewModel() { + private val _events = MutableSharedFlow( + replay = 0, + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + val events: SharedFlow = _events.asSharedFlow() + private val _team = MutableStateFlow>>(UiState.Loading) val team = _team.asStateFlow() @@ -117,7 +133,8 @@ class ProfileEditViewModel @Inject constructor( } .onFailure { - setProfileImage("") + _events.emit(ProfileEvents.ShowSnackMessage("프로필 이미지 업로드에 실패하였습니다\n다시 시도해주세요~")) + setProfileImage(initialProfileImage) } } } @@ -140,10 +157,9 @@ class ProfileEditViewModel @Inject constructor( ) .onSuccess { _profileEdit.value = UiState.Success(it) - Timber.d("test success -> $it") } .onFailure { - Timber.d("test fail -> $it") + _events.emit(ProfileEvents.ShowSnackMessage("프로필 업데이트에 실패하였습니다 다시 시도해주세요")) } } } @@ -198,5 +214,21 @@ class ProfileEditViewModel @Inject constructor( fun updateNickName(nickName: String) { _nickname.value = nickName _nickNameError.value = nickName.validateNickName() + + if (_nickNameError.value == NickNameError.NoError && initialNickName != nickname.value) { + checkNickNameAvailability(nickName) + } + } + + private fun checkNickNameAvailability(nickName: String) { + viewModelScope.launch { + homeRepository.getDuplicateNickname(nickName) + .onSuccess { + _nickNameError.value = NickNameError.NoError + } + .onFailure { + _nickNameError.value = NickNameError.DuplicateError + } + } } } \ No newline at end of file From 9c02f666f623e3738b453efbf107e076abae1235 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:15:55 +0900 Subject: [PATCH 36/83] =?UTF-8?q?[feature/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=EC=8B=9C=20=EA=B8=B0=EB=B3=B8=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/home/ProfileEditActivity.kt | 11 +++++++++-- .../presentation/home/ProfileImageUploadDialog.kt | 3 ++- .../home/viewmodel/ProfileEditViewModel.kt | 5 +++++ .../src/main/res/layout/activity_profile_edit.xml | 10 ++++++---- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index 348812de..01f4ba81 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -138,10 +138,17 @@ class ProfileEditActivity : BaseActivity( private fun observeProfileImage() { viewModel.profileImage.asLiveData().observe(this) { state -> - binding.ivProfileEditImage.load(state) { - transformations(CircleCropTransformation()) + with(binding.ivProfileEditImage) { + if (state.isEmpty()) { + setImageResource(R.drawable.ic_default_profile) + } else { + load(state) { + transformations(CircleCropTransformation()) + } + } } } + viewModel.presignedUrl.asLiveData().observe(this) { state -> when (state) { is UiState.Loading -> {} diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt index 7b9646f6..e3d2acd4 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt @@ -40,7 +40,8 @@ class ProfileImageUploadDialog() : BindingBottomSheetDialog + tools:ignore="contentDescription" /> + tools:ignore="contentDescription" + tools:src="@drawable/ic_default_profile" /> + tools:ignore="contentDescription" /> From fe90251bb5aa64ce1159e63f8cbd4744a95eca34 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:20:41 +0900 Subject: [PATCH 37/83] =?UTF-8?q?[feature/#29]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EA=B8=B0=EB=B3=B8=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/res/drawable/ic_default_profile.png | Bin 11337 -> 3131 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/presentation/src/main/res/drawable/ic_default_profile.png b/presentation/src/main/res/drawable/ic_default_profile.png index 3e3800f470e6d938e73afd03f5259dec6a07d1c0..f8a650b94cbfd638113e3c453fceb4f5585e4638 100644 GIT binary patch delta 3111 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 LNkvXXu0mjf9pVLO From 8bcdc8efe0eabfb9bc90ddecf552e47f6aa0603d Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 21:12:27 +0900 Subject: [PATCH 38/83] =?UTF-8?q?[fix/#29]=20=EC=95=BC=EA=B5=AC=20?= =?UTF-8?q?=ED=8C=80=20height=20=EC=88=98=EC=A0=95=20(=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=B0=80=EB=A6=BC,=20=EC=96=B4=EC=83=89=ED=95=9C?= =?UTF-8?q?=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=A0=9C=EA=B1=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- presentation/src/main/res/layout/item_baseball_team.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/presentation/src/main/res/layout/item_baseball_team.xml b/presentation/src/main/res/layout/item_baseball_team.xml index db744b88..17cb0f6b 100644 --- a/presentation/src/main/res/layout/item_baseball_team.xml +++ b/presentation/src/main/res/layout/item_baseball_team.xml @@ -11,8 +11,7 @@ Date: Fri, 19 Jul 2024 21:17:15 +0900 Subject: [PATCH 39/83] =?UTF-8?q?[fix/#29]=20=EC=9D=91=EC=9B=90=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=8C=80=20=EC=97=86=EC=9D=84=EB=95=8C=20null=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/home/viewmodel/ProfileEditViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt index dd385097..df70e6f4 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt @@ -154,7 +154,7 @@ class ProfileEditViewModel @Inject constructor( ProfileEditRequest( url = getPresignedUrlOrNull(), nickname = nickname.value, - teamId = cheerTeam.value + teamId = if(cheerTeam.value == 0) null else cheerTeam.value ), memberId = 1 /** memberId ->추후에 메인화면 api 나오면 연동해서 stateflow 업데이트*/ ) From 315b875e60d58f7d568d430de99d939e8acdf256 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 19 Jul 2024 22:12:43 +0900 Subject: [PATCH 40/83] =?UTF-8?q?[fix/#29]=20ProfileEditMockData.kt=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/mockdata/ProfileEditMockData.kt | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt diff --git a/presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt b/presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt deleted file mode 100644 index ece7d8a5..00000000 --- a/presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.depromeet.presentation.home.mockdata - -import android.os.Parcelable -import kotlinx.parcelize.Parcelize - -@Parcelize -data class TeamData( - val id: Int = 0, - val name: String = "", - val image: Int = 0, - val isClicked: Boolean = false, -) : Parcelable - - -//fun mockDataProfileEdit(): Flow = flow { -// -// val testData = mutableListOf() -// testData.add(TeamData(1, "삼성 라이온즈", R.drawable.ic_lg_team, true)) -// testData.add(TeamData(2, "안드 화이팅!!", R.drawable.ic_lg_team, false)) -// for (i in 3 until 20) { -// testData.add(TeamData(i, "LG 트윈스", R.drawable.ic_lg_team, false)) -// } -// -// emit(EditUiState("https://picsum.photos/600/400", "노균욱", testData)) -//} \ No newline at end of file From f9ee75989d3d77922e5b8b6eeab34cf208702502 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Sun, 21 Jul 2024 20:50:34 +0900 Subject: [PATCH 41/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=82=A0=EC=A7=9C=20=EC=A1=B0=ED=9A=8C=20data=20mo?= =?UTF-8?q?dule=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/datasource/HomeDataSource.kt | 7 ++-- .../datasource/remote/HomeDataSourceImpl.kt | 5 +++ .../response/home/ResponseReviewDateDto.kt | 32 +++++++++++++++++++ .../depromeet/data/remote/HomeApiService.kt | 4 +++ .../data/repository/HomeRepositoryImpl.kt | 8 +++++ 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 data/src/main/java/com/depromeet/data/model/response/home/ResponseReviewDateDto.kt diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt index edf9929f..934be688 100644 --- a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -6,6 +6,7 @@ import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.data.model.response.home.ResponseProfileEditDto +import com.depromeet.data.model.response.home.ResponseReviewDateDto interface HomeDataSource { suspend fun getMySeatRecordData( @@ -27,9 +28,11 @@ interface HomeDataSource { suspend fun putProfileEdit( requestProfileEditDto: RequestProfileEditDto, memberId: Int, - ) : ResponseProfileEditDto + ): ResponseProfileEditDto suspend fun getDuplicateNickname( - nickname : String + nickname: String, ) + + suspend fun getReviewDate(): ResponseReviewDateDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index 6d1204fc..8fd49b72 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -8,6 +8,7 @@ import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.data.model.response.home.ResponseProfileEditDto +import com.depromeet.data.model.response.home.ResponseReviewDateDto import com.depromeet.data.remote.HomeApiService import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody.Companion.toRequestBody @@ -54,4 +55,8 @@ class HomeDataSourceImpl @Inject constructor( override suspend fun getDuplicateNickname(nickname: String) { return homeApiService.getDuplicateNickname(nickname) } + + override suspend fun getReviewDate(): ResponseReviewDateDto { + return homeApiService.getReviewDate() + } } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseReviewDateDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseReviewDateDto.kt new file mode 100644 index 00000000..41bc4fe3 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseReviewDateDto.kt @@ -0,0 +1,32 @@ +package com.depromeet.data.model.response.home + +import com.depromeet.domain.entity.response.home.ReviewDateResponse +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponseReviewDateDto( + @SerialName("yearMonths") + val yearMonths: List, +) { + @Serializable + data class ResponseDateDto( + @SerialName("year") + val year: Int, + @SerialName("month") + val month: Int, + ) + + companion object { + fun ResponseReviewDateDto.toReviewDateResponse(): ReviewDateResponse { + val groupedByYear = this.yearMonths.groupBy { it.year } + val yearMonths = groupedByYear.map { (year, dates) -> + ReviewDateResponse.YearMonths( + year = year, + months = listOf(0) + dates.map { it.month }.sorted() + ) + }.sortedByDescending { it.year } + return ReviewDateResponse(yearMonths = yearMonths) + } + } +} diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index 12066d66..3b0e2be6 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -6,6 +6,7 @@ import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.data.model.response.home.ResponseProfileEditDto +import com.depromeet.data.model.response.home.ResponseReviewDateDto import okhttp3.RequestBody import retrofit2.http.Body import retrofit2.http.GET @@ -49,4 +50,7 @@ interface HomeApiService { suspend fun getDuplicateNickname( @Path("nickname") nickname: String, ) + + @GET("/api/v1/reviews/months") + suspend fun getReviewDate(): ResponseReviewDateDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index b72436d0..e2b919f3 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -7,12 +7,14 @@ import com.depromeet.data.mapper.toMySeatRecordResponse import com.depromeet.data.mapper.toPresignedUrlResponse import com.depromeet.data.model.request.home.RequestProfileEditDto.Companion.toProfileEditRequestDto import com.depromeet.data.model.response.home.ResponseProfileEditDto.Companion.toProfileEditResponse +import com.depromeet.data.model.response.home.ResponseReviewDateDto.Companion.toReviewDateResponse import com.depromeet.domain.entity.request.home.MySeatRecordRequest import com.depromeet.domain.entity.request.home.ProfileEditRequest import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse import com.depromeet.domain.entity.response.home.ProfileEditResponse +import com.depromeet.domain.entity.response.home.ReviewDateResponse import com.depromeet.domain.repository.HomeRepository import javax.inject.Inject @@ -63,4 +65,10 @@ class HomeRepositoryImpl @Inject constructor( homeDataSource.getDuplicateNickname(nickname) } } + + override suspend fun getReviewDate(): Result { + return runCatching { + homeDataSource.getReviewDate().toReviewDateResponse() + } + } } \ No newline at end of file From dcd8fcfb7453e161ae6ce21e080e0021eef999ad Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Sun, 21 Jul 2024 20:50:54 +0900 Subject: [PATCH 42/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=82=A0=EC=A7=9C=20=EC=A1=B0=ED=9A=8C=20domain=20?= =?UTF-8?q?module=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/entity/response/home/ReviewDateResponse.kt | 10 ++++++++++ .../com/depromeet/domain/repository/HomeRepository.kt | 3 +++ 2 files changed, 13 insertions(+) create mode 100644 domain/src/main/java/com/depromeet/domain/entity/response/home/ReviewDateResponse.kt diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/ReviewDateResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/ReviewDateResponse.kt new file mode 100644 index 00000000..f8de84f9 --- /dev/null +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/ReviewDateResponse.kt @@ -0,0 +1,10 @@ +package com.depromeet.domain.entity.response.home + +data class ReviewDateResponse( + val yearMonths: List = emptyList(), +) { + data class YearMonths( + val year: Int = 2024, + val months: List = emptyList(), + ) +} diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt index 584b1752..96b980ed 100644 --- a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -6,6 +6,7 @@ import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse import com.depromeet.domain.entity.response.home.ProfileEditResponse +import com.depromeet.domain.entity.response.home.ReviewDateResponse interface HomeRepository { suspend fun getMySeatRecord( @@ -32,4 +33,6 @@ interface HomeRepository { suspend fun getDuplicateNickname( nickname: String, ): Result + + suspend fun getReviewDate(): Result } \ No newline at end of file From 8d0ae1458b0318fefa7bb5864abcc7720b8558f3 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Sun, 21 Jul 2024 20:51:45 +0900 Subject: [PATCH 43/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=82=A0=EC=A7=9C=20=EC=A1=B0=ED=9A=8C=20presentat?= =?UTF-8?q?ion=20module=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/SeatRecordActivity.kt | 111 ++++++++++-------- .../seatrecord/adapter/DateMonthAdapter.kt | 8 +- .../seatrecord/mockdata/SeatRecordMockData.kt | 34 +----- .../seatrecord/uiMapper/HomeMapper.kt | 5 + .../viewmodel/SeatRecordViewModel.kt | 61 ++++++++-- 5 files changed, 125 insertions(+), 94 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 0e4325a0..f429f6ef 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -20,10 +20,9 @@ import com.depromeet.presentation.extension.toast import com.depromeet.presentation.seatrecord.adapter.DateMonthAdapter import com.depromeet.presentation.seatrecord.adapter.LinearSpacingItemDecoration import com.depromeet.presentation.seatrecord.adapter.MonthRecordAdapter -import com.depromeet.presentation.seatrecord.mockdata.MonthData import com.depromeet.presentation.seatrecord.mockdata.ProfileDetailData -import com.depromeet.presentation.seatrecord.mockdata.monthList import com.depromeet.presentation.seatrecord.uiMapper.MonthReviewData +import com.depromeet.presentation.seatrecord.uiMapper.MonthUiData import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel import dagger.hilt.android.AndroidEntryPoint import timber.log.Timber @@ -47,17 +46,14 @@ class SeatRecordActivity : BaseActivity( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - viewModel.getSeatRecords() initView() initEvent() initObserver() - - } private fun initView() { - initDateSpinner() initMonthAdapter() + viewModel.getReviewDate() } private fun initEvent() { @@ -75,17 +71,17 @@ class SeatRecordActivity : BaseActivity( } private fun initObserver() { - viewModel.selectedMonth.asLiveData().observe(this) { - val updatedMonthList = monthList.map { monthData -> - monthData.copy(isClicked = monthData.month == it) - } - dateMonthAdapter.submitList(updatedMonthList) + viewModel.selectedYear.asLiveData().observe(this) { selectedYear -> + viewModel.initMonths() + } + viewModel.months.asLiveData().observe(this) { + dateMonthAdapter.submitList(it) } viewModel.deleteClickedEvent.asLiveData().observe(this) { state -> if (state) moveConfirmationDialog() } - viewModel.uiState.asLiveData().observe(this) { state -> + viewModel.reviews.asLiveData().observe(this) { state -> when (state) { is UiState.Success -> { /*** setProfile() ->사용자 프로필 데이터 아직 서버 api명세서에 없음 */ @@ -105,6 +101,27 @@ class SeatRecordActivity : BaseActivity( } } } + + viewModel.date.asLiveData().observe(this) { state -> + when (state) { + is UiState.Success -> { + setReviewsVisibility(isExist = true) + val year = state.data.yearMonths.map { it.year } + initYearSpinner(year) + viewModel.getSeatRecords() + } + + is UiState.Empty -> { + setReviewsVisibility(isExist = false) + } + + is UiState.Loading -> {} + is UiState.Failure -> { + setReviewsVisibility(isExist = false) + } + + } + } } private fun setProfile(profileData: ProfileDetailData) { @@ -118,14 +135,14 @@ class SeatRecordActivity : BaseActivity( } } - private fun initDateSpinner() { - val year = listOf("2024년", "2023년", "2022년", "2021년") + private fun initYearSpinner(years: List) { + val yearList = years.map { "${it}년" } val adapter = SpotSpinner( this, R.layout.item_custom_month_spinner_view, R.layout.item_custom_month_spinner_dropdown, - year, + yearList, true, R.color.gray900 ) @@ -140,7 +157,7 @@ class SeatRecordActivity : BaseActivity( id: Long, ) { adapter.setSelectedItemPosition(position) - val selectedYear = year[position].filter { it.isDigit() }.toInt() + val selectedYear = yearList[position].filter { it.isDigit() }.toInt() viewModel.setSelectedYear(selectedYear) } @@ -160,17 +177,17 @@ class SeatRecordActivity : BaseActivity( ) dateMonthAdapter.itemMonthClickListener = object : DateMonthAdapter.OnItemMonthClickListener { - override fun onItemMonthClick(item: MonthData) { + override fun onItemMonthClick(item: MonthUiData) { val selectedMonth = item.month viewModel.setSelectedMonth(selectedMonth) } } } - private fun setReviewList(reviews: List) { - if (reviews.isEmpty()) { + private fun setReviewsVisibility(isExist: Boolean) { + if (!isExist) { with(binding) { - "${viewModel.selectedMonth.value}년".also { tvRecordYear.text = it } + "${viewModel.selectedYear.value}년".also { tvRecordYear.text = it } clRecordNone.visibility = View.VISIBLE clRecordStickyHeader.visibility = View.GONE rvRecordMonthDetail.visibility = View.GONE @@ -181,38 +198,40 @@ class SeatRecordActivity : BaseActivity( clRecordStickyHeader.visibility = View.VISIBLE rvRecordMonthDetail.visibility = View.VISIBLE - monthRecordAdapter = MonthRecordAdapter() - rvRecordMonthDetail.adapter = monthRecordAdapter ssvRecord.header = binding.clRecordStickyHeader } - val groupList = - reviews.groupBy { it.date.extractMonth(false) }.map { (month, reviews) -> - MonthReviewData(month, reviews) - } - monthRecordAdapter.submitList(groupList) - - monthRecordAdapter.itemRecordClickListener = - object : MonthRecordAdapter.OnItemRecordClickListener { - - override fun onItemRecordClick(item: MySeatRecordResponse.ReviewResponse) { - Intent( - this@SeatRecordActivity, - SeatDetailRecordActivity::class.java - ).apply { - putExtra(RECORD_ID, item.id) - putParcelableArrayListExtra(RECORD_LIST, viewModel.getUiReviewsData()) - }.let(::startActivity) - } + } + } - override fun onMoreRecordClick(reviewId: Int) { - viewModel.setEditReviewId(reviewId) - RecordEditDialog.newInstance(SEAT_RECORD_TAG) - .apply { show(supportFragmentManager, this.tag) } - } + private fun setReviewList(reviews: List) { + val groupList = + reviews.groupBy { it.date.extractMonth(false) }.map { (month, reviews) -> + MonthReviewData(month, reviews) + } + monthRecordAdapter = MonthRecordAdapter() + binding.rvRecordMonthDetail.adapter = monthRecordAdapter + monthRecordAdapter.submitList(groupList) + + monthRecordAdapter.itemRecordClickListener = + object : MonthRecordAdapter.OnItemRecordClickListener { + + override fun onItemRecordClick(item: MySeatRecordResponse.ReviewResponse) { + Intent( + this@SeatRecordActivity, + SeatDetailRecordActivity::class.java + ).apply { + putExtra(RECORD_ID, item.id) + putParcelableArrayListExtra(RECORD_LIST, viewModel.getUiReviewsData()) + }.let(::startActivity) + } + override fun onMoreRecordClick(reviewId: Int) { + viewModel.setEditReviewId(reviewId) + RecordEditDialog.newInstance(SEAT_RECORD_TAG) + .apply { show(supportFragmentManager, this.tag) } } - } + } } private fun moveConfirmationDialog() { diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DateMonthAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DateMonthAdapter.kt index df319165..13c363e3 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DateMonthAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DateMonthAdapter.kt @@ -9,17 +9,17 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ItemDateMonthBinding -import com.depromeet.presentation.seatrecord.mockdata.MonthData +import com.depromeet.presentation.seatrecord.uiMapper.MonthUiData import com.depromeet.presentation.util.ItemDiffCallback -class DateMonthAdapter : ListAdapter( +class DateMonthAdapter : ListAdapter( ItemDiffCallback( onItemsTheSame = { oldItem, newItem -> oldItem.month == newItem.month }, onContentsTheSame = { oldItem, newItem -> oldItem == newItem } ) ) { interface OnItemMonthClickListener { - fun onItemMonthClick(item: MonthData) + fun onItemMonthClick(item: MonthUiData) } var itemMonthClickListener: OnItemMonthClickListener? = null @@ -46,7 +46,7 @@ class DateMonthAdapter : ListAdapter( class DateMonthViewHolder( private val binding: ItemDateMonthBinding, ) : RecyclerView.ViewHolder(binding.root) { - fun bind(item: MonthData) { + fun bind(item: MonthUiData) { binding.tvMonth.text = when (item.month) { 0 -> "전체" else -> "${item.month}월" diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt index b485df6a..d4347edd 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt @@ -1,37 +1,9 @@ package com.depromeet.presentation.seatrecord.mockdata -import android.os.Parcelable -import com.depromeet.presentation.extension.extractMonth -import com.depromeet.presentation.viewfinder.sample.Keyword -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import kotlinx.parcelize.Parcelize - -data class MonthData( - val month: Int = 0, - var isClicked: Boolean = false, -) - -val monthList = listOf( - MonthData(0, true), - MonthData(1, false), - MonthData(2, false), - MonthData(3, false), - MonthData(4, false), - MonthData(5, false), - MonthData(6, false), - MonthData(7, false), - MonthData(8, false), - MonthData(9, false), - MonthData(10, false), - MonthData(11, false), - MonthData(12, false), -) - data class ProfileDetailData( - val nickName: String= "", - val profileImage: String ="", - val level: Int =0, + val nickName: String = "", + val profileImage: String = "", + val level: Int = 0, val titleName: String = "", val recordCount: Int = 0, ) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt index 8d4fa43c..0b6a70d0 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt @@ -13,6 +13,11 @@ data class MonthReviewData( val reviews: List, ) +data class MonthUiData( + val month: Int = 0, + var isClicked: Boolean = false, +) + @Parcelize data class ReviewUiData( val id: Int, diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index ce851683..f22ca948 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -5,7 +5,9 @@ import androidx.lifecycle.viewModelScope import com.depromeet.core.state.UiState import com.depromeet.domain.entity.request.home.MySeatRecordRequest import com.depromeet.domain.entity.response.home.MySeatRecordResponse +import com.depromeet.domain.entity.response.home.ReviewDateResponse import com.depromeet.domain.repository.HomeRepository +import com.depromeet.presentation.seatrecord.uiMapper.MonthUiData import com.depromeet.presentation.seatrecord.uiMapper.ReviewUiData import com.depromeet.presentation.seatrecord.uiMapper.toUiModel import dagger.hilt.android.lifecycle.HiltViewModel @@ -20,13 +22,17 @@ class SeatRecordViewModel @Inject constructor( ) : ViewModel() { - private val _uiState = MutableStateFlow>(UiState.Loading) - val uiState = _uiState.asStateFlow() + private val _reviews = MutableStateFlow>(UiState.Loading) + val reviews = _reviews.asStateFlow() - private val _selectedMonth = MutableStateFlow(0) - val selectedMonth = _selectedMonth.asStateFlow() + private val _date = MutableStateFlow>(UiState.Loading) + val date = _date.asStateFlow() - private val _selectedYear = MutableStateFlow(2024) + private val _months = + MutableStateFlow>(emptyList()) + val months = _months.asStateFlow() + + private val _selectedYear = MutableStateFlow(0) val selectedYear = _selectedYear.asStateFlow() private val _deleteClickedEvent = MutableStateFlow(false) @@ -35,9 +41,26 @@ class SeatRecordViewModel @Inject constructor( private val _editReviewId = MutableStateFlow(0) val editReviewId = _editReviewId.asStateFlow() + fun getReviewDate() { + viewModelScope.launch { + homeRepository.getReviewDate() + .onSuccess { data -> + if (data.yearMonths.isNotEmpty()) { + _date.value = UiState.Success(data) + _selectedYear.value = data.yearMonths[0].year + } else { + _date.value = UiState.Empty + } + } + .onFailure { e -> + _date.value = UiState.Failure(e.message ?: "실패") + } + } + } + fun getSeatRecords() { - val month = if (selectedMonth.value == 0) null else selectedMonth.value + val month = months.value.find { it.isClicked }?.takeIf { it.month != 0 }?.month viewModelScope.launch { homeRepository.getMySeatRecord( MySeatRecordRequest( @@ -45,20 +68,32 @@ class SeatRecordViewModel @Inject constructor( month ) ).onSuccess { data -> - _uiState.value = UiState.Success(data) + _reviews.value = UiState.Success(data) }.onFailure { - _uiState.value = UiState.Failure(it.message ?: "실패") + _reviews.value = UiState.Failure(it.message ?: "실패") } } } fun setSelectedYear(year: Int) { _selectedYear.value = year - getSeatRecords() + } + + fun initMonths() { + val currentState = date.value + if (currentState is UiState.Success) { + val selectedYearMonths = + currentState.data.yearMonths.first { it.year == selectedYear.value }.months + _months.value = selectedYearMonths.mapIndexed { index, month -> + MonthUiData(month = month, isClicked = index == 0) + } + } } fun setSelectedMonth(month: Int) { - _selectedMonth.value = month + _months.value = months.value.map { + it.copy(isClicked = it.month == month) + } getSeatRecords() } @@ -71,20 +106,20 @@ class SeatRecordViewModel @Inject constructor( } fun removeReviewData() { - val currentState = uiState.value + val currentState = reviews.value if (currentState is UiState.Success) { val updatedList = currentState.data.reviews.filter { review -> review.id != editReviewId.value } /** 여기서 서버에서 통신이 성공 -> uistate업로드 (api 명세 아직 없음)*/ - _uiState.value = UiState.Success(currentState.data.copy(reviews = updatedList)) + _reviews.value = UiState.Success(currentState.data.copy(reviews = updatedList)) _deleteClickedEvent.value = false } } fun getUiReviewsData(): ArrayList { - val currentState = uiState.value + val currentState = reviews.value return if (currentState is UiState.Success) { ArrayList(currentState.data.reviews.map { it.toUiModel() }) } else { From 8ca4118a5b20bfb83961e518ae229fa6abee8575 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Sun, 21 Jul 2024 20:56:31 +0900 Subject: [PATCH 44/83] =?UTF-8?q?[refactor/#29]=20=EC=8B=9C=EC=95=BC?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=95=A1=ED=8B=B0=EB=B9=84=ED=8B=B0=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=ED=99=94=20=EB=B0=8F=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/SeatRecordActivity.kt | 52 +++++++++------ .../seatrecord/mockdata/SeatRecordMockData.kt | 64 ------------------- 2 files changed, 31 insertions(+), 85 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index f429f6ef..cb408229 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -71,16 +71,41 @@ class SeatRecordActivity : BaseActivity( } private fun initObserver() { + observeDates() + observeReviews() + observeEvents() + } + + private fun observeDates() { viewModel.selectedYear.asLiveData().observe(this) { selectedYear -> viewModel.initMonths() } viewModel.months.asLiveData().observe(this) { dateMonthAdapter.submitList(it) } + viewModel.date.asLiveData().observe(this) { state -> + when (state) { + is UiState.Success -> { + setReviewsVisibility(isExist = true) + val year = state.data.yearMonths.map { it.year } + initYearSpinner(year) + viewModel.getSeatRecords() + } - viewModel.deleteClickedEvent.asLiveData().observe(this) { state -> - if (state) moveConfirmationDialog() + is UiState.Empty -> { + setReviewsVisibility(isExist = false) + } + + is UiState.Loading -> {} + is UiState.Failure -> { + setReviewsVisibility(isExist = false) + } + + } } + } + + private fun observeReviews() { viewModel.reviews.asLiveData().observe(this) { state -> when (state) { is UiState.Success -> { @@ -101,26 +126,11 @@ class SeatRecordActivity : BaseActivity( } } } + } - viewModel.date.asLiveData().observe(this) { state -> - when (state) { - is UiState.Success -> { - setReviewsVisibility(isExist = true) - val year = state.data.yearMonths.map { it.year } - initYearSpinner(year) - viewModel.getSeatRecords() - } - - is UiState.Empty -> { - setReviewsVisibility(isExist = false) - } - - is UiState.Loading -> {} - is UiState.Failure -> { - setReviewsVisibility(isExist = false) - } - - } + private fun observeEvents() { + viewModel.deleteClickedEvent.asLiveData().observe(this) { state -> + if (state) moveConfirmationDialog() } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt index d4347edd..fc4972f5 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt @@ -8,68 +8,4 @@ data class ProfileDetailData( val recordCount: Int = 0, ) -//data class RecordDetailMockData( -// val profileDetailData: ProfileDetailData = ProfileDetailData(), -// val reviews: List = emptyList(), -//) - -//@Parcelize -//data class ReviewMockData( -// val id: Int =0, -// val date: String ="", -// val image: String ="", -// val stadiumName: String ="", -// val blockName: String ="", -// val keyword: List = emptyList(), -//) : Parcelable -//data class MonthReviewData( -// val month: String, -// val reviews: List, -//) -// -//fun List.groupByMonth(): List { -// val groupedData = this.groupBy { it.date.extractMonth(false) } -// return groupedData.map { (month, reviews) -> -// MonthReviewData(month, reviews) -// } -//} -// -//fun makeSeatRecordData(): Flow = flow { -// emit( -// RecordDetailMockData( -// profileDetailData = ProfileDetailData( -// nickName = "노균욱", -// profileImage = "https://picsum.photos/600/400", -// level = 6, -// titleName = "전설의 직관러", -// recordCount = 37 -// ), -// reviews = makeRecordDetailData() -// ) -// ) -//} -// -// -//fun makeRecordDetailData(): List { -// val list = mutableListOf() -// for (i in 1..8) { -// list.add( -// ReviewMockData( -// id = i, -// date = "2024-0${i % 4 + 1}-12", -// image = "https://picsum.photos/600/400", -// stadiumName = "서울 잠실 야구장", -// blockName = "1루 네이비석 304블록", -// keyword = listOf( -// Keyword("🙍‍서서 응원하는 존", 44, 0), -// Keyword("☀️ 온종일 햇빛 존", 44, 1), -// Keyword("🙍‍서서 응원하는 존", 44, 1), -// Keyword("🙍‍서서 응원하는 존", 44, 0), -// Keyword("🙍‍서서 응원하는 존", 44, 0) -// ), -// ) -// ) -// } -// return list.sortedBy { it.date } -//} From 5507a4e80faff899e544972f82df7e9c8d75176d Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Sun, 21 Jul 2024 22:19:06 +0900 Subject: [PATCH 45/83] =?UTF-8?q?[fix/#29]=20=EB=A1=9C=EA=B7=B8=EC=9D=B8,?= =?UTF-8?q?=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=88=98=EC=A0=95=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EC=82=AC=EB=9D=BC=EC=A7=84=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EB=B3=B5=EA=B5=AC(=EB=A1=9C=EA=B7=B8=EC=9D=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/mockdata/ProfileEditMockData.kt | 34 +++++++++++++++++++ .../presentation/login/TeamSelectAdapter.kt | 25 +++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt diff --git a/presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt b/presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt new file mode 100644 index 00000000..2ef8b8fa --- /dev/null +++ b/presentation/src/main/java/com/depromeet/presentation/home/mockdata/ProfileEditMockData.kt @@ -0,0 +1,34 @@ +package com.depromeet.presentation.home.mockdata + +import android.os.Parcelable +import com.depromeet.presentation.R +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import kotlinx.parcelize.Parcelize + +@Parcelize +data class TeamData( + val id: Int = 0, + val name: String = "", + val image: Int = 0, + val isClicked: Boolean = false, +) : Parcelable + + +fun mockDataProfileEdit(): Flow = flow { + + val testData = mutableListOf() + testData.add(TeamData(1, "삼성 라이온즈", R.drawable.ic_lg_team, true)) + testData.add(TeamData(2, "안드 화이팅!!", R.drawable.ic_lg_team, false)) + for (i in 3 until 20) { + testData.add(TeamData(i, "LG 트윈스", R.drawable.ic_lg_team, false)) + } + + emit(EditUiState("https://picsum.photos/600/400", "노균욱", testData)) +} + +data class EditUiState( + val image: String = "", + val nickName: String = "", + val teamList: List = emptyList(), +) \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/login/TeamSelectAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/login/TeamSelectAdapter.kt index ca31e31d..7e30bab1 100644 --- a/presentation/src/main/java/com/depromeet/presentation/login/TeamSelectAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/login/TeamSelectAdapter.kt @@ -4,10 +4,10 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import coil.load import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ItemBaseballTeamBinding import com.depromeet.presentation.databinding.ItemSelectTeamBinding -import com.depromeet.presentation.home.adapter.ProfileEditTeamViewHolder import com.depromeet.presentation.home.mockdata.TeamData import com.depromeet.presentation.util.ItemDiffCallback @@ -81,4 +81,27 @@ class ButtonViewHolder( nextClick() } } +} + +class ProfileEditTeamViewHolder( + private val binding: ItemBaseballTeamBinding, +) : RecyclerView.ViewHolder(binding.root) { + fun bind(item: TeamData) { + with(binding) { + ivTeamImage.load(item.image) { + placeholder(R.drawable.ic_lg_team) + error(R.drawable.ic_x_close) + } + tvTeamName.text = item.name + updateSelectState(item.isClicked) + } + } + + private fun updateSelectState(isSelected: Boolean) { + val backgroundRes = when (isSelected) { + true -> R.drawable.rect_gray50_fill_gray900_line_10 + false -> R.drawable.rect_gray100_line_10 + } + binding.root.setBackgroundResource(backgroundRes) + } } \ No newline at end of file From 9739cae82bd30a32de544a7e675fceb0e8c00cb5 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Tue, 23 Jul 2024 23:37:31 +0900 Subject: [PATCH 46/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EC=B5=9C?= =?UTF-8?q?=EA=B7=BC=20=EC=8B=9C=EC=95=BC=20=EA=B8=B0=EB=A1=9D=20data,doma?= =?UTF-8?q?in=EB=AA=A8=EB=93=88=20=EA=B5=AC=ED=98=84=20(=EC=88=98=EC=A0=95?= =?UTF-8?q?=20=EC=98=88=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/depromeet/data/mapper/HomeMapper.kt | 51 ----- .../response/home/ResponseMySeatRecordDto.kt | 196 +++++++++++++----- .../data/repository/HomeRepositoryImpl.kt | 2 +- .../response/home/MySeatRecordResponse.kt | 25 ++- 4 files changed, 161 insertions(+), 113 deletions(-) diff --git a/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt index c4fd60e2..ca1bb103 100644 --- a/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt +++ b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt @@ -2,62 +2,11 @@ package com.depromeet.data.mapper import com.depromeet.data.model.request.home.RequestMySeatRecordDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto -import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.domain.entity.request.home.MySeatRecordRequest import com.depromeet.domain.entity.response.home.BaseballTeamResponse -import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse -fun ResponseMySeatRecordDto.toMySeatRecordResponse() = MySeatRecordResponse( - reviews = reviews.map { it.toReviewResponse() }, - totalCount = totalCount, - filteredCount = filteredCount, - offset = offset, - limit = limit, - hasMore = hasMore, - filter = filter.toFilterResponse() -) - -fun ResponseMySeatRecordDto.ResponseFilterDto.toFilterResponse() = - MySeatRecordResponse.FilterResponse( - stadiumId = stadiumId, - year = year, - month = month - ) - - -fun ResponseMySeatRecordDto.ResponseReviewDto.toReviewResponse() = - MySeatRecordResponse.ReviewResponse( - id = id, - stadiumId = stadiumId, - stadiumName = stadiumName, - blockId = blockId, - blockName = blockName, - seatId = seatId, - rowId = rowId, - seatNumber = seatNumber, - date = date, - content = content, - createdAt = createdAt, - updatedAt = updatedAt, - images = images.map { it.toReviewImageResponse() }, - keywords = keywords.map { it.toReviewKeywordResponse() } - ) - -fun ResponseMySeatRecordDto.ResponseReviewDto.ResponseReviewImageDto.toReviewImageResponse() = - MySeatRecordResponse.ReviewResponse.ReviewImageResponse( - id = id, - url = url - ) - -fun ResponseMySeatRecordDto.ResponseReviewDto.ResponseReviewKeywordDto.toReviewKeywordResponse() = - MySeatRecordResponse.ReviewResponse.ReviewKeywordResponse( - id = id, - content = content, - isPositive = isPositive - ) - fun MySeatRecordRequest.toMySeatRecordRequestDto() = RequestMySeatRecordDto( offset = offset, diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt index 4680c9b7..675045af 100644 --- a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt @@ -1,5 +1,6 @@ package com.depromeet.data.model.response.home +import com.depromeet.domain.entity.response.home.MySeatRecordResponse import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -7,59 +8,53 @@ import kotlinx.serialization.Serializable @Serializable data class ResponseMySeatRecordDto( @SerialName("reviews") - val reviews: List, - @SerialName("totalCount") - val totalCount: Int, - @SerialName("filteredCount") - val filteredCount: Int, - @SerialName("offset") - val offset: Int, - @SerialName("limit") - val limit: Int, - @SerialName("hasMore") - val hasMore: Boolean, - @SerialName("filter") - val filter: ResponseFilterDto, + val reviews: List, + @SerialName("totalElements") + val totalElements: Int, + @SerialName("totalPages") + val totalPages: Int, + @SerialName("number") + val number: Int, + @SerialName("size") + val size: Int, ) { + @Serializable + data class ResponseReviewWrapperDto( + @SerialName("baseReview") + val baseReview: ResponseReviewDto, + @SerialName("stadiumName") + val stadiumName: String, + @SerialName("sectionName") + val sectionName: String, + @SerialName("blockCode") + val blockCode: String, + ) + @Serializable data class ResponseReviewDto( @SerialName("id") val id: Int, - @SerialName("stadiumId") - val stadiumId: Int, - @SerialName("stadiumName") - val stadiumName: String, - @SerialName("blockId") - val blockId: Int, - @SerialName("blockName") - val blockName: String, - @SerialName("seatId") - val seatId: Int, - @SerialName("rowId") - val rowId: Int, - @SerialName("seatNumber") - val seatNumber: Int, - @SerialName("date") - val date: String, + @SerialName("member") + val member: ResponseMemberDto, + @SerialName("stadium") + val stadium: ResponseStadiumDto, + @SerialName("section") + val section: ResponseSectionDto, + @SerialName("block") + val block: ResponseBlockDto, + @SerialName("row") + val row: ResponseRowDto, + @SerialName("seat") + val seat: ResponseSeatDto, + @SerialName("dateTime") + val dateTime: String, @SerialName("content") val content: String, - @SerialName("createdAt") - val createdAt: String, - @SerialName("updatedAt") - val updatedAt: String, @SerialName("images") val images: List, @SerialName("keywords") val keywords: List, ) { - @Serializable - data class ResponseReviewImageDto( - @SerialName("id") - val id: Int, - @SerialName("url") - val url: String, - ) - @Serializable data class ResponseReviewKeywordDto( @SerialName("id") @@ -69,15 +64,120 @@ data class ResponseMySeatRecordDto( @SerialName("isPositive") val isPositive: Boolean, ) + + @Serializable + data class ResponseMemberDto( + @SerialName("profileImage") + val profileImage: String, + @SerialName("nickname") + val nickname: String, + @SerialName("level") + val level: Int, + ) + + @Serializable + data class ResponseStadiumDto( + @SerialName("id") + val id: Int, + @SerialName("name") + val name: String, + @SerialName("mainImage") + val mainImage: String, + @SerialName("seatingChartImage") + val seatingChartImage: String, + @SerialName("labeledSeatingChartImage") + val labeledSeatingChartImage: String, + @SerialName("isActive") + val isActive: Boolean, + ) + + @Serializable + data class ResponseSectionDto( + @SerialName("id") + val id: Int, + @SerialName("name") + val name: String, + @SerialName("alias") + val alias: String, + ) + + @Serializable + data class ResponseBlockDto( + @SerialName("id") + val id: Int, + @SerialName("code") + val code: String, + ) + + @Serializable + data class ResponseRowDto( + @SerialName("id") + val id: Int, + @SerialName("number") + val number: Int, + ) + + @Serializable + data class ResponseSeatDto( + @SerialName("id") + val id: Int, + @SerialName("seatNumber") + val seatNumber: Int, + ) } @Serializable - data class ResponseFilterDto( - @SerialName("stadiumId") - val stadiumId: Int, - @SerialName("year") - val year: Int, - @SerialName("month") - val month: Int, + data class ResponseReviewImageDto( + @SerialName("id") + val id: Int, + @SerialName("url") + val url: String, ) + + companion object { + fun ResponseMySeatRecordDto.toMySeatRecordResponse() = MySeatRecordResponse( + reviews = reviews.map { it.baseReview.toReviewResponse() }, + totalElements = totalElements, + totalPages = totalPages, + number = number, + size = size + ) + + private fun ResponseReviewDto.toReviewResponse() = MySeatRecordResponse.ReviewResponse( + id = id, + stadiumId = stadium.id, + stadiumName = stadium.name, + blockId = block.id, + blockName = block.code, + seatId = seat.id, + rowId = row.id, + rowNumber = row.number, + seatNumber = seat.seatNumber, + date = dateTime, + content = content, + member = member.toMemberResponse(), + images = images.map { it.toReviewImageResponse() }, + keywords = keywords.map { it.toReviewKeywordResponse() } + ) + + private fun ResponseReviewDto.ResponseMemberDto.toMemberResponse() = + MySeatRecordResponse.ReviewResponse.MemberResponse( + profileImage = profileImage, + nickname = nickname, + level = level + ) + + private fun ResponseReviewDto.ResponseReviewKeywordDto.toReviewKeywordResponse() = + MySeatRecordResponse.ReviewResponse.ReviewKeywordResponse( + id = id, + content = content, + isPositive = isPositive + ) + + private fun ResponseReviewImageDto.toReviewImageResponse() = + MySeatRecordResponse.ReviewResponse.ReviewImageResponse( + id = id, + url = url + ) + } } diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index e2b919f3..9b846b3a 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -3,9 +3,9 @@ package com.depromeet.data.repository import com.depromeet.data.datasource.HomeDataSource import com.depromeet.data.mapper.toBaseballTeamResponse import com.depromeet.data.mapper.toMySeatRecordRequestDto -import com.depromeet.data.mapper.toMySeatRecordResponse import com.depromeet.data.mapper.toPresignedUrlResponse import com.depromeet.data.model.request.home.RequestProfileEditDto.Companion.toProfileEditRequestDto +import com.depromeet.data.model.response.home.ResponseMySeatRecordDto.Companion.toMySeatRecordResponse import com.depromeet.data.model.response.home.ResponseProfileEditDto.Companion.toProfileEditResponse import com.depromeet.data.model.response.home.ResponseReviewDateDto.Companion.toReviewDateResponse import com.depromeet.domain.entity.request.home.MySeatRecordRequest diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt index 9d05bcb7..69bf2c94 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt @@ -2,12 +2,10 @@ package com.depromeet.domain.entity.response.home data class MySeatRecordResponse( val reviews: List = emptyList(), - val totalCount: Int = 0, - val filteredCount: Int = 0, - val offset: Int = 0, - val limit: Int = 0, - val hasMore: Boolean = false, - val filter: FilterResponse = FilterResponse(), + val totalElements : Int = 0, + val totalPages : Int = 0, + val number : Int = 0, + val size : Int = 0, ) { data class ReviewResponse( val id: Int, @@ -17,11 +15,11 @@ data class MySeatRecordResponse( val blockName: String = "", val seatId: Int = 0, val rowId: Int = 0, + val rowNumber : Int = 0, val seatNumber: Int = 0, val date: String = "", val content: String = "", - val createdAt: String = "", - val updatedAt: String = "", + val member : MemberResponse = MemberResponse(), val images: List = emptyList(), val keywords: List = emptyList(), ) { @@ -35,11 +33,12 @@ data class MySeatRecordResponse( val content: String = "", val isPositive: Boolean = false, ) + + data class MemberResponse( + val profileImage : String = "", + val nickname : String = "", + val level : Int = 0 + ) } - data class FilterResponse( - val stadiumId: Int = 0, - val year: Int = 0, - val month: Int = 0, - ) } From 17e30a23ad6f2265709d15102cab63d0b5d2ec6d Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Tue, 23 Jul 2024 23:53:59 +0900 Subject: [PATCH 47/83] =?UTF-8?q?[feature/#29]=20=ED=99=88=20=ED=94=BC?= =?UTF-8?q?=EB=93=9C=20=EC=9C=A0=EC=A0=80=20=EC=A0=95=EB=B3=B4=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20domain,data=20=EB=AA=A8=EB=93=88=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/datasource/HomeDataSource.kt | 3 +++ .../datasource/remote/HomeDataSourceImpl.kt | 5 ++++ .../model/response/home/ResponseProfileDto.kt | 26 +++++++++++++++++++ .../depromeet/data/remote/HomeApiService.kt | 4 +++ .../data/repository/HomeRepositoryImpl.kt | 8 ++++++ .../entity/response/home/ProfileResponse.kt | 8 ++++++ .../domain/repository/HomeRepository.kt | 3 +++ 7 files changed, 57 insertions(+) create mode 100644 data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt create mode 100644 domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt index 934be688..eb920798 100644 --- a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -6,6 +6,7 @@ import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.data.model.response.home.ResponseProfileEditDto +import com.depromeet.data.model.response.home.ResponseProfileDto import com.depromeet.data.model.response.home.ResponseReviewDateDto interface HomeDataSource { @@ -35,4 +36,6 @@ interface HomeDataSource { ) suspend fun getReviewDate(): ResponseReviewDateDto + + suspend fun getProfile() : ResponseProfileDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index 8fd49b72..9d6eb77b 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -7,6 +7,7 @@ import com.depromeet.data.model.request.home.RequestProfileEditDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto +import com.depromeet.data.model.response.home.ResponseProfileDto import com.depromeet.data.model.response.home.ResponseProfileEditDto import com.depromeet.data.model.response.home.ResponseReviewDateDto import com.depromeet.data.remote.HomeApiService @@ -59,4 +60,8 @@ class HomeDataSourceImpl @Inject constructor( override suspend fun getReviewDate(): ResponseReviewDateDto { return homeApiService.getReviewDate() } + + override suspend fun getProfile(): ResponseProfileDto { + return homeApiService.getProfileInfo() + } } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt new file mode 100644 index 00000000..f5fa2323 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt @@ -0,0 +1,26 @@ +package com.depromeet.data.model.response.home + +import com.depromeet.domain.entity.response.home.ProfileResponse +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponseProfileDto( + @SerialName("profileImageUrl") + val profileImageUrl: String, + @SerialName("nickname") + val nickname: String, + @SerialName("level") + val level: Int, + @SerialName("teamImageUrl") + val teamImageUrl: String, +) { + companion object { + fun ResponseProfileDto.toProfileResponse() = ProfileResponse( + profileImage = profileImageUrl, + nickname = nickname, + level = level, + teamImage = teamImageUrl + ) + } +} diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index 3b0e2be6..8e97cb7a 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -5,6 +5,7 @@ import com.depromeet.data.model.request.home.RequestProfileEditDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto +import com.depromeet.data.model.response.home.ResponseProfileDto import com.depromeet.data.model.response.home.ResponseProfileEditDto import com.depromeet.data.model.response.home.ResponseReviewDateDto import okhttp3.RequestBody @@ -53,4 +54,7 @@ interface HomeApiService { @GET("/api/v1/reviews/months") suspend fun getReviewDate(): ResponseReviewDateDto + + @GET("/api/v1/members/memberInfo") + suspend fun getProfileInfo(): ResponseProfileDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index 9b846b3a..62fb30fc 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -6,6 +6,7 @@ import com.depromeet.data.mapper.toMySeatRecordRequestDto import com.depromeet.data.mapper.toPresignedUrlResponse import com.depromeet.data.model.request.home.RequestProfileEditDto.Companion.toProfileEditRequestDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto.Companion.toMySeatRecordResponse +import com.depromeet.data.model.response.home.ResponseProfileDto.Companion.toProfileResponse import com.depromeet.data.model.response.home.ResponseProfileEditDto.Companion.toProfileEditResponse import com.depromeet.data.model.response.home.ResponseReviewDateDto.Companion.toReviewDateResponse import com.depromeet.domain.entity.request.home.MySeatRecordRequest @@ -14,6 +15,7 @@ import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse import com.depromeet.domain.entity.response.home.ProfileEditResponse +import com.depromeet.domain.entity.response.home.ProfileResponse import com.depromeet.domain.entity.response.home.ReviewDateResponse import com.depromeet.domain.repository.HomeRepository import javax.inject.Inject @@ -71,4 +73,10 @@ class HomeRepositoryImpl @Inject constructor( homeDataSource.getReviewDate().toReviewDateResponse() } } + + override suspend fun getProfile(): Result { + return kotlin.runCatching { + homeDataSource.getProfile().toProfileResponse() + } + } } \ No newline at end of file diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt new file mode 100644 index 00000000..dc5b18d6 --- /dev/null +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt @@ -0,0 +1,8 @@ +package com.depromeet.domain.entity.response.home + +data class ProfileResponse( + val profileImage : String = "", + val nickname :String = "", + val level : Int = 0, + val teamImage : String = "" +) \ No newline at end of file diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt index 96b980ed..9fd6f572 100644 --- a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -6,6 +6,7 @@ import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse import com.depromeet.domain.entity.response.home.ProfileEditResponse +import com.depromeet.domain.entity.response.home.ProfileResponse import com.depromeet.domain.entity.response.home.ReviewDateResponse interface HomeRepository { @@ -35,4 +36,6 @@ interface HomeRepository { ): Result suspend fun getReviewDate(): Result + + suspend fun getProfile() : Result } \ No newline at end of file From f922c0525b454f1d6c34a3fc7f1a108a40af2634 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 00:05:21 +0900 Subject: [PATCH 48/83] =?UTF-8?q?[feature/#29]=20=EC=B5=9C=EA=B7=BC=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0(=ED=99=88=20=ED=94=BC=EB=93=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C)=20domain,data=20=EB=AA=A8=EB=93=88=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/datasource/HomeDataSource.kt | 7 ++-- .../datasource/remote/HomeDataSourceImpl.kt | 5 +++ .../response/home/ResponseRecentReviewDto.kt | 32 +++++++++++++++++++ .../depromeet/data/remote/HomeApiService.kt | 4 +++ .../data/repository/HomeRepositoryImpl.kt | 10 +++++- .../response/home/RecentReviewResponse.kt | 10 ++++++ .../domain/repository/HomeRepository.kt | 5 ++- 7 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 data/src/main/java/com/depromeet/data/model/response/home/ResponseRecentReviewDto.kt create mode 100644 domain/src/main/java/com/depromeet/domain/entity/response/home/RecentReviewResponse.kt diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt index eb920798..eb35e8a7 100644 --- a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -5,8 +5,9 @@ import com.depromeet.data.model.request.home.RequestProfileEditDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto -import com.depromeet.data.model.response.home.ResponseProfileEditDto import com.depromeet.data.model.response.home.ResponseProfileDto +import com.depromeet.data.model.response.home.ResponseProfileEditDto +import com.depromeet.data.model.response.home.ResponseRecentReviewDto import com.depromeet.data.model.response.home.ResponseReviewDateDto interface HomeDataSource { @@ -37,5 +38,7 @@ interface HomeDataSource { suspend fun getReviewDate(): ResponseReviewDateDto - suspend fun getProfile() : ResponseProfileDto + suspend fun getProfile(): ResponseProfileDto + + suspend fun getRecentReview(): ResponseRecentReviewDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index 9d6eb77b..a7293776 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -9,6 +9,7 @@ import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.data.model.response.home.ResponseProfileDto import com.depromeet.data.model.response.home.ResponseProfileEditDto +import com.depromeet.data.model.response.home.ResponseRecentReviewDto import com.depromeet.data.model.response.home.ResponseReviewDateDto import com.depromeet.data.remote.HomeApiService import okhttp3.MediaType.Companion.toMediaTypeOrNull @@ -64,4 +65,8 @@ class HomeDataSourceImpl @Inject constructor( override suspend fun getProfile(): ResponseProfileDto { return homeApiService.getProfileInfo() } + + override suspend fun getRecentReview(): ResponseRecentReviewDto { + return homeApiService.getRecentReview() + } } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseRecentReviewDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseRecentReviewDto.kt new file mode 100644 index 00000000..f9feb152 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseRecentReviewDto.kt @@ -0,0 +1,32 @@ +package com.depromeet.data.model.response.home + +import com.depromeet.domain.entity.response.home.RecentReviewResponse +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponseRecentReviewDto( + @SerialName("totalReviewCount") + val totalReviewCount: Int, + @SerialName("stadiumName") + val stadiumName: String, + @SerialName("date") + val date: String, + @SerialName("reviewImages") + val reviewImages: List, + @SerialName("blockName") + val blockName: String, + @SerialName("seatNumber") + val seatNumber: Long, +) { + companion object { + fun ResponseRecentReviewDto.toRecentReviewResponse() = RecentReviewResponse( + totalReviewCount = totalReviewCount, + stadiumName = stadiumName, + date = date, + reviewImages = reviewImages, + blockName = blockName, + seatNumber = seatNumber + ) + } +} diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index 8e97cb7a..a05a339b 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -7,6 +7,7 @@ import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.data.model.response.home.ResponseProfileDto import com.depromeet.data.model.response.home.ResponseProfileEditDto +import com.depromeet.data.model.response.home.ResponseRecentReviewDto import com.depromeet.data.model.response.home.ResponseReviewDateDto import okhttp3.RequestBody import retrofit2.http.Body @@ -57,4 +58,7 @@ interface HomeApiService { @GET("/api/v1/members/memberInfo") suspend fun getProfileInfo(): ResponseProfileDto + + @GET("/api/v1/reviews/recentReview") + suspend fun getRecentReview(): ResponseRecentReviewDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index 62fb30fc..9a247d8c 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -8,6 +8,7 @@ import com.depromeet.data.model.request.home.RequestProfileEditDto.Companion.toP import com.depromeet.data.model.response.home.ResponseMySeatRecordDto.Companion.toMySeatRecordResponse import com.depromeet.data.model.response.home.ResponseProfileDto.Companion.toProfileResponse import com.depromeet.data.model.response.home.ResponseProfileEditDto.Companion.toProfileEditResponse +import com.depromeet.data.model.response.home.ResponseRecentReviewDto.Companion.toRecentReviewResponse import com.depromeet.data.model.response.home.ResponseReviewDateDto.Companion.toReviewDateResponse import com.depromeet.domain.entity.request.home.MySeatRecordRequest import com.depromeet.domain.entity.request.home.ProfileEditRequest @@ -16,6 +17,7 @@ import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse import com.depromeet.domain.entity.response.home.ProfileEditResponse import com.depromeet.domain.entity.response.home.ProfileResponse +import com.depromeet.domain.entity.response.home.RecentReviewResponse import com.depromeet.domain.entity.response.home.ReviewDateResponse import com.depromeet.domain.repository.HomeRepository import javax.inject.Inject @@ -75,8 +77,14 @@ class HomeRepositoryImpl @Inject constructor( } override suspend fun getProfile(): Result { - return kotlin.runCatching { + return runCatching { homeDataSource.getProfile().toProfileResponse() } } + + override suspend fun getRecentReview(): Result { + return runCatching { + homeDataSource.getRecentReview().toRecentReviewResponse() + } + } } \ No newline at end of file diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/RecentReviewResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/RecentReviewResponse.kt new file mode 100644 index 00000000..05cc53e4 --- /dev/null +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/RecentReviewResponse.kt @@ -0,0 +1,10 @@ +package com.depromeet.domain.entity.response.home + +data class RecentReviewResponse( + val totalReviewCount : Int = 0, + val stadiumName : String = "", + val date : String = "", + val reviewImages : List = emptyList(), + val blockName : String = "", + val seatNumber : Long = 0 +) diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt index 9fd6f572..6f9f0f13 100644 --- a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -7,6 +7,7 @@ import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse import com.depromeet.domain.entity.response.home.ProfileEditResponse import com.depromeet.domain.entity.response.home.ProfileResponse +import com.depromeet.domain.entity.response.home.RecentReviewResponse import com.depromeet.domain.entity.response.home.ReviewDateResponse interface HomeRepository { @@ -37,5 +38,7 @@ interface HomeRepository { suspend fun getReviewDate(): Result - suspend fun getProfile() : Result + suspend fun getProfile(): Result + + suspend fun getRecentReview(): Result } \ No newline at end of file From 0d6ad4b5598a72fdad3cd039949d4756428f711c Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 01:09:15 +0900 Subject: [PATCH 49/83] =?UTF-8?q?[fix/#29]=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=EB=8B=89=EB=84=A4=EC=9E=84=20enum?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20&=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85?= =?UTF-8?q?=20enum=20Duplicate=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/extension/StringExt.kt | 21 +++++++------------ .../presentation/home/ProfileEditActivity.kt | 16 +++++++------- .../home/viewmodel/ProfileEditViewModel.kt | 17 ++++++++------- .../login/ui/NicknameInputFragment.kt | 5 +++++ .../login/viewmodel/SignUpViewModel.kt | 3 ++- .../seatrecord/uiMapper/HomeMapper.kt | 4 ---- presentation/src/main/res/values/strings.xml | 1 + 7 files changed, 34 insertions(+), 33 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt b/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt index c3843742..2a249953 100644 --- a/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt +++ b/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt @@ -1,5 +1,6 @@ package com.depromeet.presentation.extension +import com.depromeet.presentation.login.viewmodel.NicknameInputState import java.time.LocalDate import java.time.format.DateTimeFormatter import java.time.format.TextStyle @@ -7,23 +8,17 @@ import java.util.Locale const val NICKNAME_PATTERN = "^[a-zA-Z0-9가-힣]+$" -sealed class NickNameError { - object NoError : NickNameError() - object LengthError : NickNameError() - object InvalidCharacterError : NickNameError() - object DuplicateError : NickNameError() -} - - -fun String.validateNickName(): NickNameError { +fun String.validateNickName(): NicknameInputState { return when { - this.length !in 2..10 -> NickNameError.LengthError - !this.matches(Regex(NICKNAME_PATTERN)) -> NickNameError.InvalidCharacterError - else -> NickNameError.NoError + this.length !in 2..10 -> NicknameInputState.INVALID_LENGTH + !this.matches(Regex(NICKNAME_PATTERN)) -> NicknameInputState.INVALID_CHARACTER + else -> NicknameInputState.VALID } } -/** ex) 2024-01-21 (서버 date형식 예정)*/ +/** ex) 2024-01-21 (서버 date형식 예정) + * TODO : CalenderUtil로 뺐음 추후에 삭제 해야함 + * */ fun String.extractDay(): String { val parts = this.split("-") return if (parts.size == 3) { diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index 01f4ba81..44675a8a 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -16,12 +16,12 @@ import com.depromeet.core.state.UiState import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ActivityProfileEditBinding -import com.depromeet.presentation.extension.NickNameError import com.depromeet.presentation.extension.toast import com.depromeet.presentation.home.adapter.BaseballTeamAdapter import com.depromeet.presentation.home.adapter.GridSpacingItemDecoration import com.depromeet.presentation.home.viewmodel.ProfileEditViewModel import com.depromeet.presentation.home.viewmodel.ProfileEvents +import com.depromeet.presentation.login.viewmodel.NicknameInputState import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -103,30 +103,32 @@ class ProfileEditActivity : BaseActivity( viewModel.updateNickName(text.toString()) } - viewModel.nickNameError.asLiveData().observe(this) { error -> - when (error) { - is NickNameError.NoError -> { + viewModel.nickNameError.asLiveData().observe(this) { state -> + when (state) { + NicknameInputState.EMPTY -> {} + + NicknameInputState.VALID -> { updateCompletionStatus( isError = false, getString(R.string.profile_edit_error_no) ) } - is NickNameError.LengthError -> { + NicknameInputState.INVALID_LENGTH -> { updateCompletionStatus( isError = true, getString(R.string.profile_edit_error_length) ) } - is NickNameError.InvalidCharacterError -> { + NicknameInputState.INVALID_CHARACTER -> { updateCompletionStatus( isError = true, getString(R.string.profile_edit_error_type) ) } - is NickNameError.DuplicateError -> { + NicknameInputState.DUPLICATE -> { updateCompletionStatus( isError = true, getString(R.string.profile_edit_error_duplicate) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt index df70e6f4..b312149e 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt @@ -9,8 +9,8 @@ import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse import com.depromeet.domain.entity.response.home.ProfileEditResponse import com.depromeet.domain.repository.HomeRepository -import com.depromeet.presentation.extension.NickNameError import com.depromeet.presentation.extension.validateNickName +import com.depromeet.presentation.login.viewmodel.NicknameInputState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job import kotlinx.coroutines.channels.BufferOverflow @@ -53,7 +53,7 @@ class ProfileEditViewModel @Inject constructor( private val _nickname = MutableStateFlow("") val nickname = _nickname.asStateFlow() - private val _nickNameError = MutableStateFlow(NickNameError.NoError) + private val _nickNameError = MutableStateFlow(NicknameInputState.VALID) val nickNameError = _nickNameError.asStateFlow() private val _profileImage = MutableStateFlow("") @@ -79,7 +79,7 @@ class ProfileEditViewModel @Inject constructor( nickNameError ) { nickName, profileImage, cheerTeam, nickNameError -> (nickName != initialNickName || profileImage != initialProfileImage - || cheerTeam != initialCheerTeam) && nickNameError == NickNameError.NoError + || cheerTeam != initialCheerTeam) && nickNameError == NicknameInputState.VALID }.collect { isChanged -> changeEnabled.value = isChanged } @@ -99,7 +99,8 @@ class ProfileEditViewModel @Inject constructor( } } } - fun deleteProfileImage(){ + + fun deleteProfileImage() { _profileImage.value = "" } @@ -154,7 +155,7 @@ class ProfileEditViewModel @Inject constructor( ProfileEditRequest( url = getPresignedUrlOrNull(), nickname = nickname.value, - teamId = if(cheerTeam.value == 0) null else cheerTeam.value + teamId = if (cheerTeam.value == 0) null else cheerTeam.value ), memberId = 1 /** memberId ->추후에 메인화면 api 나오면 연동해서 stateflow 업데이트*/ ) @@ -218,7 +219,7 @@ class ProfileEditViewModel @Inject constructor( _nickname.value = nickName _nickNameError.value = nickName.validateNickName() - if (_nickNameError.value == NickNameError.NoError && initialNickName != nickname.value) { + if (_nickNameError.value == NicknameInputState.VALID && initialNickName != nickname.value) { checkNickNameAvailability(nickName) } } @@ -227,10 +228,10 @@ class ProfileEditViewModel @Inject constructor( viewModelScope.launch { homeRepository.getDuplicateNickname(nickName) .onSuccess { - _nickNameError.value = NickNameError.NoError + _nickNameError.value = NicknameInputState.VALID } .onFailure { - _nickNameError.value = NickNameError.DuplicateError + _nickNameError.value = NicknameInputState.DUPLICATE } } } diff --git a/presentation/src/main/java/com/depromeet/presentation/login/ui/NicknameInputFragment.kt b/presentation/src/main/java/com/depromeet/presentation/login/ui/NicknameInputFragment.kt index a070a799..10f477f2 100644 --- a/presentation/src/main/java/com/depromeet/presentation/login/ui/NicknameInputFragment.kt +++ b/presentation/src/main/java/com/depromeet/presentation/login/ui/NicknameInputFragment.kt @@ -93,6 +93,11 @@ class NicknameInputFragment: BindingFragment( tvNicknameWarning.text = getString(R.string.profile_edit_error_type) updateButtonEnabled(false) } + NicknameInputState.DUPLICATE -> { + clNicknameInputWarning.visibility = View.VISIBLE + tvNicknameWarning.text = getString(R.string.profile_edit_error_duplicate) + updateButtonEnabled(false) + } } } } diff --git a/presentation/src/main/java/com/depromeet/presentation/login/viewmodel/SignUpViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/login/viewmodel/SignUpViewModel.kt index d6632f8a..193c7bb8 100644 --- a/presentation/src/main/java/com/depromeet/presentation/login/viewmodel/SignUpViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/login/viewmodel/SignUpViewModel.kt @@ -102,5 +102,6 @@ enum class NicknameInputState { EMPTY, VALID, INVALID_LENGTH, - INVALID_CHARACTER + INVALID_CHARACTER, + DUPLICATE } \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt index 0b6a70d0..f76863f5 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt @@ -30,8 +30,6 @@ data class ReviewUiData( val seatNumber: Int, val date: String, val content: String, - val createdAt: String, - val updatedAt: String, val images: List, val keywords: List, ) : Parcelable { @@ -79,8 +77,6 @@ fun MySeatRecordResponse.ReviewResponse.toUiModel(): ReviewUiData { seatNumber = seatNumber, date = date, content = content, - createdAt = createdAt, - updatedAt = updatedAt, images = images.map { it.toUiModel() }, keywords = keywords.map { it.toUiModel() } ) diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 0937cca4..6d75e952 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -25,6 +25,7 @@ 이미 사용중인 닉네임이에요. 닉네임은 알파벳 대소문자, 숫자, 한글만 입력 가능합니다. 닉네임은 최소 2글자에서 최대 10글자로 입력해 주세요. + 비어있습니다. 정상적으로 입력 완료! From c4bcf200c21f2a55b3370b5fdf680e285936f686 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 02:32:03 +0900 Subject: [PATCH 50/83] =?UTF-8?q?[feature/#29]=20=EC=B5=9C=EA=B7=BC=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0(=ED=99=88=20=ED=94=BC=EB=93=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C)=20presentation=EB=AA=A8=EB=93=88=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(=EC=8B=9C=EC=95=BC=20=EA=B8=B0=EB=A1=9D=20?= =?UTF-8?q?=EC=B6=94=ED=9B=84=20=ED=99=95=EC=9D=B8=20=EC=9A=94=EB=A7=9D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 아직 api 안나옴 --- .../presentation/home/HomeActivity.kt | 87 +++++++++++++++++++ .../home/viewmodel/HomeViewModel.kt | 47 ++++++++-- .../src/main/res/layout/activity_home.xml | 10 +-- presentation/src/main/res/values/strings.xml | 8 ++ 4 files changed, 140 insertions(+), 12 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt index f549b188..fe9fe8c0 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt @@ -7,9 +7,15 @@ import android.view.View import androidx.activity.viewModels import androidx.lifecycle.asLiveData import coil.load +import coil.transform.CircleCropTransformation import com.depromeet.core.base.BaseActivity +import com.depromeet.core.state.UiState +import com.depromeet.domain.entity.response.home.ProfileResponse +import com.depromeet.domain.entity.response.home.RecentReviewResponse +import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ActivityHomeBinding import com.depromeet.presentation.extension.loadAndClip +import com.depromeet.presentation.extension.toast import com.depromeet.presentation.home.viewmodel.HomeUiState import com.depromeet.presentation.home.viewmodel.HomeViewModel import com.depromeet.presentation.util.applyBoldAndSizeSpan @@ -45,9 +51,90 @@ class HomeActivity : BaseActivity( updateUi(state) } + viewModel.profile.asLiveData().observe(this) { state -> + when (state) { + is UiState.Success -> { + updateProfile(state.data) + } + + is UiState.Failure -> { + toast("실패") + } + + is UiState.Loading -> {} + is UiState.Empty -> {} + } + } + viewModel.recentReview.asLiveData().observe(this) { state -> + when (state) { + is UiState.Success -> { + updateRecentReview(state.data) + } + + is UiState.Failure -> { + toast("실패") + } + + is UiState.Loading -> {} + is UiState.Empty -> {} + } + } + viewModel.getInformation() } + private fun updateRecentReview(review: RecentReviewResponse) = with(binding) { + setSpannableString(viewModel.nickname.value, viewModel.reviewCount.value) + tvHomeRecentRecordName.text = review.stadiumName + tvHomeRecentRecordDate.text = review.date //TODO : 여기 바꿔야함 CALENDER UTIL로 + when (review.reviewImages.size) { + 0 -> { + tvHomeRecentRecordDate.visibility = View.GONE + tvHomeRecentRecordName.visibility = View.GONE + } + + 1 -> { + ivHomeRecentOneRecord1.loadAndClip(review.reviewImages[0]) + "${review.blockName}${review.seatNumber}".also { tvHomeRecentOneSection.text = it } + } + + 2 -> { + ivHomeRecentTwoRecord1.loadAndClip(review.reviewImages[0]) + ivHomeRecentTwoRecord2.loadAndClip(review.reviewImages[1]) + "${review.blockName}${review.seatNumber}".also { tvHomeRecentOneSection.text = it } + } + + 3 -> { + ivHomeRecentThreeRecord1.loadAndClip(review.reviewImages[0]) + ivHomeRecentThreeRecord2.loadAndClip(review.reviewImages[1]) + ivHomeRecentThreeRecord3.loadAndClip(review.reviewImages[2]) + "${review.blockName}${review.seatNumber}".also { tvHomeRecentOneSection.text = it } + } + else -> {} + } + } + + private fun updateProfile(profile: ProfileResponse) = with(binding) { + setSpannableString(viewModel.nickname.value, viewModel.reviewCount.value) + ivHomeProfile.load(profile.profileImage) { transformations(CircleCropTransformation()) } + "Lv.${profile.level} ${profile.level.levelToTitle()}".also { tvHomeLevel.text = it } + ivHomeCheerTeam.load(profile.teamImage) + + } + + /** 임시 처리 서버에서 내려주면 다시 바꿔주고 아니면 그대로 유지*/ + private fun Int.levelToTitle(): String { + return when (this) { + 1 -> getString(R.string.one_level_to_title) + 2 -> getString(R.string.two_level_to_title) + 3 -> getString(R.string.three_level_to_title) + 4 -> getString(R.string.four_level_to_title) + 5 -> getString(R.string.five_level_to_title) + 6 -> getString(R.string.six_level_to_title) + else -> getString(R.string.unknown_level_to_title) + } + } + private fun updateUi(state: HomeUiState) { with(binding) { diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt index 021edb72..9cea77ef 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt @@ -3,14 +3,17 @@ package com.depromeet.presentation.home.viewmodel import android.os.Parcelable import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.depromeet.core.state.UiState +import com.depromeet.domain.entity.response.home.ProfileResponse +import com.depromeet.domain.entity.response.home.RecentReviewResponse +import com.depromeet.domain.repository.HomeRepository import com.depromeet.presentation.home.mockdata.Profile import com.depromeet.presentation.home.mockdata.RecentSight -import com.depromeet.presentation.home.mockdata.mockDataProfile import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.async import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import javax.inject.Inject @@ -21,14 +24,44 @@ data class HomeUiState( ) : Parcelable @HiltViewModel -class HomeViewModel @Inject constructor() : ViewModel() { +class HomeViewModel @Inject constructor( + private val homeRepository: HomeRepository, +) : ViewModel() { private val _uiState = MutableStateFlow(HomeUiState()) val uiState = _uiState.asStateFlow() + private val _profile = MutableStateFlow>(UiState.Loading) + val profile = _profile.asStateFlow() + + private val _recentReview = MutableStateFlow>(UiState.Loading) + val recentReview = _recentReview.asStateFlow() + + val nickname = MutableStateFlow("") + val reviewCount = MutableStateFlow(0) + fun getInformation() { - mockDataProfile().onEach { - _uiState.value = it - }.launchIn(viewModelScope) + viewModelScope.launch { + val profileDeferred = async { + homeRepository.getProfile() + } + val reviewDeferred = async { + homeRepository.getRecentReview() + } + + val profileResult = profileDeferred.await() + profileResult.onSuccess { + _profile.value = UiState.Success(it) + }.onFailure { + _profile.value = UiState.Failure(it.message ?: "실패") + } + + val reviewResult = reviewDeferred.await() + reviewResult.onSuccess { + _recentReview.value = UiState.Success(it) + }.onFailure { + _recentReview.value = UiState.Failure(it.message ?: "실패") + } + } } } \ No newline at end of file diff --git a/presentation/src/main/res/layout/activity_home.xml b/presentation/src/main/res/layout/activity_home.xml index 3142084e..e09ec60b 100644 --- a/presentation/src/main/res/layout/activity_home.xml +++ b/presentation/src/main/res/layout/activity_home.xml @@ -100,13 +100,13 @@ 더보기 아직 작성한 시야 기록이 없어요. 시야 기록 남기기 + + 직관 첫 걸음 앨범에서 선택 @@ -58,6 +60,12 @@ 게시물 삭제시 복구가 불가능합니다 삭제하기 취소 + 경기장 탐험가 + 직관의 여유 + 응원 단장 + 야구정 VIP + 전설의 직관러 + 알 수 없음 \ No newline at end of file From 614979260f584090571fe2bbf673d283c33ad051 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 02:55:53 +0900 Subject: [PATCH 51/83] =?UTF-8?q?[feature/#29]=20calenderUtil=20=EB=82=A0?= =?UTF-8?q?=EC=A7=9C=20=EA=B4=80=EB=A0=A8=20=EC=B6=94=EA=B0=80=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/util/CalenderUtil.kt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt b/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt index 8b6ba296..e38ac87d 100644 --- a/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt +++ b/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt @@ -1,11 +1,15 @@ package com.depromeet.presentation.util import java.text.SimpleDateFormat +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter +import java.time.format.TextStyle import java.util.Calendar import java.util.Locale object CalendarUtil { + private const val ISO_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" private const val DATE_FORMAT = "yy.MM.dd" fun formatCalendarDate(calendar: Calendar): String { @@ -33,4 +37,30 @@ object CalendarUtil { fun getDay(calendar: Calendar): Int { return calendar.get(Calendar.DAY_OF_MONTH) } + + fun getMonthFromDateFormat(date: String): Int { + val formatter = DateTimeFormatter.ofPattern(ISO_DATE_FORMAT) + val parsedDate = LocalDateTime.parse(date, formatter) + return parsedDate.monthValue + } + + fun getDayOfMonthFromDateFormat(date: String): Int { + val formatter = DateTimeFormatter.ofPattern(ISO_DATE_FORMAT) + val parsedDate = LocalDateTime.parse(date, formatter) + return parsedDate.dayOfMonth + } + + fun getDayOfWeekFromDateFormat(date: String): String { + val formatter = DateTimeFormatter.ofPattern(ISO_DATE_FORMAT) + val parsedDate = LocalDateTime.parse(date, formatter) + return parsedDate.dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.KOREAN) + } + + fun getFormattedDate(date: String): String { + val formatter = DateTimeFormatter.ofPattern(ISO_DATE_FORMAT) + val parsedDate = LocalDateTime.parse(date, formatter) + val outputFormatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일", Locale.KOREAN) + return parsedDate.format(outputFormatter) + } + } From 3542daead0ed297c2f5877afcc1c4c8e600bce79 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 13:47:25 +0900 Subject: [PATCH 52/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=20=EA=B8=B0=EB=A1=9D=20=EA=B4=80=EB=A0=A8=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=20api=20=EC=88=98=EC=A0=95=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B8=ED=95=9C=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/home/ResponseMySeatRecordDto.kt | 29 ++++++++++++++++++- .../response/home/MySeatRecordResponse.kt | 27 +++++++++++------ .../seatrecord/SeatRecordActivity.kt | 13 +++++---- .../viewmodel/SeatRecordViewModel.kt | 8 ++--- .../presentation/util/CalenderUtil.kt | 6 ++++ 5 files changed, 63 insertions(+), 20 deletions(-) diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt index 675045af..f02080ce 100644 --- a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt @@ -7,6 +7,8 @@ import kotlinx.serialization.Serializable @Serializable data class ResponseMySeatRecordDto( + @SerialName("memberInfoOnMyReview") + val memberInfoOnMyReview: ResponseMemberDto, @SerialName("reviews") val reviews: List, @SerialName("totalElements") @@ -18,6 +20,21 @@ data class ResponseMySeatRecordDto( @SerialName("size") val size: Int, ) { + @Serializable + data class ResponseMemberDto( + @SerialName("userId") + val userId: Int, + @SerialName("profileImageUrl") + val profileImageUrl: String, + @SerialName("level") + val level: Int, + @SerialName("nickname") + val nickname: String, + @SerialName("reviewCount") + val reviewCount: Int, + ) + + @Serializable data class ResponseReviewWrapperDto( @SerialName("baseReview") @@ -136,13 +153,23 @@ data class ResponseMySeatRecordDto( companion object { fun ResponseMySeatRecordDto.toMySeatRecordResponse() = MySeatRecordResponse( + profile = memberInfoOnMyReview.toMyProfileResponse(), reviews = reviews.map { it.baseReview.toReviewResponse() }, totalElements = totalElements, totalPages = totalPages, number = number, - size = size + size = size, ) + private fun ResponseMemberDto.toMyProfileResponse() = + MySeatRecordResponse.MyProfileResponse( + userId = userId, + profileImage = profileImageUrl, + level = level, + nickname = nickname, + reviewCount = reviewCount + ) + private fun ResponseReviewDto.toReviewResponse() = MySeatRecordResponse.ReviewResponse( id = id, stadiumId = stadium.id, diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt index 69bf2c94..a5eb3bf6 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt @@ -1,12 +1,21 @@ package com.depromeet.domain.entity.response.home data class MySeatRecordResponse( + val profile: MyProfileResponse, val reviews: List = emptyList(), - val totalElements : Int = 0, - val totalPages : Int = 0, - val number : Int = 0, - val size : Int = 0, + val totalElements: Int = 0, + val totalPages: Int = 0, + val number: Int = 0, + val size: Int = 0, ) { + data class MyProfileResponse( + val userId: Int = 0, + val profileImage: String = "", + val level: Int = 0, + val nickname: String = "", + val reviewCount: Int = 0, + ) + data class ReviewResponse( val id: Int, val stadiumId: Int, @@ -15,11 +24,11 @@ data class MySeatRecordResponse( val blockName: String = "", val seatId: Int = 0, val rowId: Int = 0, - val rowNumber : Int = 0, + val rowNumber: Int = 0, val seatNumber: Int = 0, val date: String = "", val content: String = "", - val member : MemberResponse = MemberResponse(), + val member: MemberResponse = MemberResponse(), val images: List = emptyList(), val keywords: List = emptyList(), ) { @@ -35,9 +44,9 @@ data class MySeatRecordResponse( ) data class MemberResponse( - val profileImage : String = "", - val nickname : String = "", - val level : Int = 0 + val profileImage: String = "", + val nickname: String = "", + val level: Int = 0, ) } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index cb408229..3404793a 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -20,7 +20,6 @@ import com.depromeet.presentation.extension.toast import com.depromeet.presentation.seatrecord.adapter.DateMonthAdapter import com.depromeet.presentation.seatrecord.adapter.LinearSpacingItemDecoration import com.depromeet.presentation.seatrecord.adapter.MonthRecordAdapter -import com.depromeet.presentation.seatrecord.mockdata.ProfileDetailData import com.depromeet.presentation.seatrecord.uiMapper.MonthReviewData import com.depromeet.presentation.seatrecord.uiMapper.MonthUiData import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel @@ -94,6 +93,7 @@ class SeatRecordActivity : BaseActivity( is UiState.Empty -> { setReviewsVisibility(isExist = false) + viewModel.getSeatRecords() } is UiState.Loading -> {} @@ -134,12 +134,13 @@ class SeatRecordActivity : BaseActivity( } } - private fun setProfile(profileData: ProfileDetailData) { + private fun setProfile(data: MySeatRecordResponse.MyProfileResponse) { with(binding) { - "Lv.${profileData.level} ${profileData.titleName}".also { tvRecordLevel.text = it } - tvRecordNickname.text = profileData.nickName - tvRecordCount.text = profileData.recordCount.toString() - ivRecordProfile.load(profileData.profileImage) { + //TODO : 서버에서 칭호 넘겨주변 업데이트 해야함.. + "Lv.${data.level} 칭호".also { tvRecordLevel.text = it } + tvRecordNickname.text = data.nickname + tvRecordCount.text = data.reviewCount.toString() + ivRecordProfile.load(data.profileImage) { transformations(CircleCropTransformation()) } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index f22ca948..ce512af0 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -10,6 +10,7 @@ import com.depromeet.domain.repository.HomeRepository import com.depromeet.presentation.seatrecord.uiMapper.MonthUiData import com.depromeet.presentation.seatrecord.uiMapper.ReviewUiData import com.depromeet.presentation.seatrecord.uiMapper.toUiModel +import com.depromeet.presentation.util.CalendarUtil import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -21,7 +22,6 @@ class SeatRecordViewModel @Inject constructor( private val homeRepository: HomeRepository, ) : ViewModel() { - private val _reviews = MutableStateFlow>(UiState.Loading) val reviews = _reviews.asStateFlow() @@ -32,7 +32,7 @@ class SeatRecordViewModel @Inject constructor( MutableStateFlow>(emptyList()) val months = _months.asStateFlow() - private val _selectedYear = MutableStateFlow(0) + private val _selectedYear = MutableStateFlow(CalendarUtil.getCurrentYear()) val selectedYear = _selectedYear.asStateFlow() private val _deleteClickedEvent = MutableStateFlow(false) @@ -64,8 +64,8 @@ class SeatRecordViewModel @Inject constructor( viewModelScope.launch { homeRepository.getMySeatRecord( MySeatRecordRequest( - selectedYear.value, - month + year = selectedYear.value, + month = month ) ).onSuccess { data -> _reviews.value = UiState.Success(data) diff --git a/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt b/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt index e38ac87d..5df8a4f0 100644 --- a/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt +++ b/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt @@ -1,6 +1,7 @@ package com.depromeet.presentation.util import java.text.SimpleDateFormat +import java.time.LocalDate import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.time.format.TextStyle @@ -63,4 +64,9 @@ object CalendarUtil { return parsedDate.format(outputFormatter) } + fun getCurrentYear(): Int { + val today = LocalDate.now() + return today.year + } + } From 4d37731bb0d96edafe13e094d34b816c44f7eee4 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 13:55:59 +0900 Subject: [PATCH 53/83] =?UTF-8?q?[feature/#29]=20=ED=99=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EB=94=94=EC=9E=90=EC=9D=B8=EC=88=98=EC=A0=95,?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80,?= =?UTF-8?q?=20=EB=AA=A9=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?(API=EC=88=98=EC=A0=95=EC=98=88=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/response/home/ProfileResponse.kt | 1 + .../presentation/home/HomeActivity.kt | 77 ++++--------- .../home/mockdata/HomeMockData.kt | 101 ------------------ .../home/viewmodel/HomeViewModel.kt | 11 -- .../src/main/res/layout/activity_home.xml | 48 ++++++--- 5 files changed, 56 insertions(+), 182 deletions(-) delete mode 100644 presentation/src/main/java/com/depromeet/presentation/home/mockdata/HomeMockData.kt diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt index dc5b18d6..54de15e9 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt @@ -1,6 +1,7 @@ package com.depromeet.domain.entity.response.home data class ProfileResponse( + val teamId : Int = 0, // TODO : 서버에서 내려주는거 확인하고 투두 지우기 val profileImage : String = "", val nickname :String = "", val level : Int = 0, diff --git a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt index fe9fe8c0..52de5912 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt @@ -16,8 +16,8 @@ import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ActivityHomeBinding import com.depromeet.presentation.extension.loadAndClip import com.depromeet.presentation.extension.toast -import com.depromeet.presentation.home.viewmodel.HomeUiState import com.depromeet.presentation.home.viewmodel.HomeViewModel +import com.depromeet.presentation.seatrecord.SeatRecordActivity import com.depromeet.presentation.util.applyBoldAndSizeSpan import dagger.hilt.android.AndroidEntryPoint @@ -45,12 +45,9 @@ class HomeActivity : BaseActivity( super.onCreate(savedInstanceState) binding.ivHomeProfile.setOnClickListener { navigateToProfileEditActivity() } binding.ibHomeEdit.setOnClickListener { navigateToProfileEditActivity() } + binding.clHomeSightRecord.setOnClickListener { navigateToSeatRecordActivity() } binding.clMainSight.clipToOutline = true - viewModel.uiState.asLiveData().observe(this) { state -> - updateUi(state) - } - viewModel.profile.asLiveData().observe(this) { state -> when (state) { is UiState.Success -> { @@ -87,6 +84,11 @@ class HomeActivity : BaseActivity( setSpannableString(viewModel.nickname.value, viewModel.reviewCount.value) tvHomeRecentRecordName.text = review.stadiumName tvHomeRecentRecordDate.text = review.date //TODO : 여기 바꿔야함 CALENDER UTIL로 + + sightList.forEachIndexed { index, view -> + view.visibility = + if (index == review.reviewImages.size) View.VISIBLE else View.GONE + } when (review.reviewImages.size) { 0 -> { tvHomeRecentRecordDate.visibility = View.GONE @@ -110,6 +112,7 @@ class HomeActivity : BaseActivity( ivHomeRecentThreeRecord3.loadAndClip(review.reviewImages[2]) "${review.blockName}${review.seatNumber}".also { tvHomeRecentOneSection.text = it } } + else -> {} } } @@ -135,61 +138,19 @@ class HomeActivity : BaseActivity( } } + private fun navigateToProfileEditActivity() { + val currentState = viewModel.profile.value - private fun updateUi(state: HomeUiState) { - with(binding) { - val profile = state.profile - val recentSight = state.recentSight - - "Lv.${profile.level} ${profile.title}".also { tvHomeLevel.text = it } - setSpannableString(profile.nickName, profile.writeCount) - ivHomeCheerTeam.load(profile.teamImage) - tvHomeRecentRecordName.text = recentSight.location - tvHomeRecentRecordDate.text = recentSight.date - - - sightList.forEachIndexed { index, view -> - view.visibility = - if (index == recentSight.photoList.size) View.VISIBLE else View.GONE - } - - when (recentSight.photoList.size) { - 0 -> { - tvHomeRecentRecordDate.visibility = View.GONE - tvHomeRecentRecordName.visibility = View.GONE - } - - 1 -> { - ivHomeRecentOneRecord1.loadAndClip(recentSight.photoList[0]) - tvHomeRecentOneSection.text = recentSight.section - } - - 2 -> { - ivHomeRecentTwoRecord1.loadAndClip(recentSight.photoList[0]) - ivHomeRecentTwoRecord2.loadAndClip(recentSight.photoList[1]) - tvHomeRecentTwoSection.text = recentSight.section - } - - 3 -> { - ivHomeRecentThreeRecord1.loadAndClip(recentSight.photoList[0]) - ivHomeRecentThreeRecord2.loadAndClip(recentSight.photoList[1]) - ivHomeRecentThreeRecord3.loadAndClip(recentSight.photoList[2]) - tvHomeRecentThreeSection.text = recentSight.section - } - - else -> {} + if(currentState is UiState.Success){ + Intent(this, ProfileEditActivity::class.java).apply { + with(currentState.data) { + putExtra(PROFILE_NAME, this.nickname) + putExtra(PROFILE_IMAGE, this.profileImage) + putExtra(PROFILE_CHEER_TEAM, this.teamId) } + }.let(::startActivity) } - } - private fun navigateToProfileEditActivity() { - Intent(this, ProfileEditActivity::class.java).apply { - with(viewModel.uiState.value.profile) { - putExtra(PROFILE_NAME, this.nickName) - putExtra(PROFILE_IMAGE, this.image) - putExtra(PROFILE_CHEER_TEAM, this.teamId) - } - }.let(::startActivity) } private fun setSpannableString( @@ -210,4 +171,8 @@ class HomeActivity : BaseActivity( binding.tvHomeSightChance.text = spannableBuilder } + private fun navigateToSeatRecordActivity() { + Intent(this, SeatRecordActivity::class.java).apply { startActivity(this) } + } + } \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/home/mockdata/HomeMockData.kt b/presentation/src/main/java/com/depromeet/presentation/home/mockdata/HomeMockData.kt deleted file mode 100644 index 22ad8930..00000000 --- a/presentation/src/main/java/com/depromeet/presentation/home/mockdata/HomeMockData.kt +++ /dev/null @@ -1,101 +0,0 @@ -package com.depromeet.presentation.home.mockdata - -import android.os.Parcelable -import com.depromeet.presentation.home.viewmodel.HomeUiState -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import kotlinx.parcelize.Parcelize -import kotlin.random.Random - -/** - * 테스트용 - */ -@Parcelize -data class Profile( - val nickName: String = "", - val image : String = "", - val writeCount: Int = 0, - val level: Int = 0, - val title: String = "", - val teamImage: String = "", - val teamId : Int = 0 -) : Parcelable - -@Parcelize -data class RecentSight( - val location: String = "", - val date: String = "", - val section: String = "", - val photoList: List = emptyList(), -) : Parcelable - -data class LevelPolicy( - val name: String, - val minCount: Int, - val maxCount: Int, - val level: Int, -) - -/*** - * 화면 테스트용으로 랜덤하게 flow return - */ -fun mockDataProfile(): Flow = flow { - - /*** - * 추후 클라에서 처리할수도 있을지도..? 아닌가 - */ - val levelPolicies = listOf( - LevelPolicy("직관 첫 걸음", 0, 2, 1), - LevelPolicy("경기장 탐험가", 3, 6, 2), - LevelPolicy("직관의 여유", 7, 11, 3), - LevelPolicy("응원 단장", 12, 20, 4), - LevelPolicy("야구장 VIP", 21, 35, 5), - LevelPolicy("전설의 직관러", 36, Int.MAX_VALUE, 6) - ) - - fun getLevelByCount(count: Int): Pair { - val levelPolicy = levelPolicies.first { count in it.minCount..it.maxCount } - return Pair(levelPolicy.level, levelPolicy.name) - } - - - val profileList = listOf( - Profile("노균욱", "https://picsum.photos/600/400",23, 5, "야구장 VIP", "https://picsum.photos/600/400",1), - Profile("윤성식", "https://picsum.photos/600/400",12, 4, "응원 단장", "https://picsum.photos/600/400",1), - Profile("박민주", "https://picsum.photos/600/400",2, 2, "직관 첫 걸음", "https://picsum.photos/600/400",1), - Profile("조관희", "https://picsum.photos/600/400",7, 3, "직관의 여유", "https://picsum.photos/600/400",1), - ) - val recentSightList = listOf( - RecentSight("서울 잠실 야구장", "2024년 7월 20일", "3루 네이비석 3054블럭", emptyList()), - RecentSight( - "대전 한화 야구장", - "2024년 7월 12일", - "1루 블루석 124블럭", - listOf("https://picsum.photos/600/400") - ), - RecentSight( - "고척 스카이돔", "2024년 7월 05일", "3루 레드석 234블럭", listOf( - "https://picsum.photos/600/400", - "https://picsum.photos/600/400" - ) - ), - RecentSight( - "대구 삼성 파크", "2024년 6월 23일", "3루 베이지석 3451블럭", listOf( - "https://picsum.photos/600/400", - "https://picsum.photos/600/400", - "https://picsum.photos/600/400" - ) - ) - ) - delay(300) - val randomNumber = Random.nextInt(0, 4) - emit( - HomeUiState( - profileList[randomNumber], - recentSightList[randomNumber] - ) - ) -} - - diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt index 9cea77ef..aae0306b 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt @@ -1,35 +1,24 @@ package com.depromeet.presentation.home.viewmodel -import android.os.Parcelable import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.depromeet.core.state.UiState import com.depromeet.domain.entity.response.home.ProfileResponse import com.depromeet.domain.entity.response.home.RecentReviewResponse import com.depromeet.domain.repository.HomeRepository -import com.depromeet.presentation.home.mockdata.Profile -import com.depromeet.presentation.home.mockdata.RecentSight import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.async import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch -import kotlinx.parcelize.Parcelize import javax.inject.Inject -@Parcelize -data class HomeUiState( - val profile: Profile = Profile(), - val recentSight: RecentSight = RecentSight(), -) : Parcelable @HiltViewModel class HomeViewModel @Inject constructor( private val homeRepository: HomeRepository, ) : ViewModel() { - private val _uiState = MutableStateFlow(HomeUiState()) - val uiState = _uiState.asStateFlow() private val _profile = MutableStateFlow>(UiState.Loading) val profile = _profile.asStateFlow() diff --git a/presentation/src/main/res/layout/activity_home.xml b/presentation/src/main/res/layout/activity_home.xml index e09ec60b..77a0d35f 100644 --- a/presentation/src/main/res/layout/activity_home.xml +++ b/presentation/src/main/res/layout/activity_home.xml @@ -51,7 +51,8 @@ android:layout_marginTop="32dp" android:src="@drawable/ic_default_profile" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" + tools:ignore="contentDescription" /> + app:layout_constraintEnd_toEndOf="@id/iv_home_profile" + tools:ignore="contentDescription" /> + app:layout_constraintTop_toTopOf="parent" + tools:ignore="contentDescription" /> @@ -103,10 +106,11 @@ android:layout_width="114dp" android:layout_height="100dp" android:layout_marginEnd="20dp" - android:scaleType="fitXY" android:adjustViewBounds="true" + android:scaleType="fitXY" app:layout_constraintBottom_toBottomOf="@id/tv_home_sight_chance" app:layout_constraintEnd_toEndOf="parent" + tools:ignore="contentDescription" tools:src="@drawable/ic_lg_team" /> + app:layout_constraintTop_toTopOf="@id/tv_home_find_sight" + tools:ignore="contentDescription" /> + app:layout_constraintEnd_toEndOf="parent" + tools:ignore="contentDescription" /> @@ -203,7 +209,8 @@ android:src="@drawable/ic_chevron_right" app:layout_constraintBottom_toBottomOf="@id/tv_home_register_sight" app:layout_constraintStart_toEndOf="@id/tv_home_register_sight" - app:layout_constraintTop_toTopOf="@id/tv_home_register_sight" /> + app:layout_constraintTop_toTopOf="@id/tv_home_register_sight" + tools:ignore="contentDescription" /> + app:layout_constraintEnd_toEndOf="parent" + tools:ignore="contentDescription" /> @@ -253,7 +261,8 @@ android:src="@drawable/ic_chevron_right" app:layout_constraintBottom_toBottomOf="@id/tv_home_sight_record" app:layout_constraintStart_toEndOf="@id/tv_home_sight_record" - app:layout_constraintTop_toTopOf="@id/tv_home_sight_record" /> + app:layout_constraintTop_toTopOf="@id/tv_home_sight_record" + tools:ignore="contentDescription" /> @@ -335,7 +345,8 @@ android:src="@drawable/ic_folder_blank" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" + tools:ignore="contentDescription" /> @@ -390,6 +402,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" + tools:ignore="contentDescription" tools:src="@drawable/ic_stadium_test" /> @@ -430,6 +444,7 @@ app:layout_constraintEnd_toStartOf="@+id/iv_home_recent_two_record2" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" + tools:ignore="contentDescription" tools:src="@drawable/ic_stadium_test" /> + app:layout_constraintTop_toTopOf="parent" + tools:ignore="contentDescription" /> @@ -482,6 +499,7 @@ app:layout_constraintEnd_toStartOf="@+id/iv_home_recent_three_record2" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" + tools:ignore="contentDescription" tools:src="@drawable/ic_stadium_test" /> + app:layout_constraintTop_toTopOf="@id/iv_home_recent_three_record1" + tools:ignore="contentDescription" /> + app:layout_constraintTop_toBottomOf="@id/iv_home_recent_three_record2" + tools:ignore="contentDescription" /> From 4a76d22debae0fcb53914f4e3b3e80659bed45cf Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:20:19 +0900 Subject: [PATCH 54/83] =?UTF-8?q?[feature/#29]=20=ED=99=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20spannablestring=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/home/HomeActivity.kt | 18 ++++++++++++++---- .../home/viewmodel/HomeViewModel.kt | 2 ++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt index 52de5912..9c586ce7 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt @@ -43,11 +43,24 @@ class HomeActivity : BaseActivity( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + viewModel.getInformation() + initView() + initEvent() + initObserver() + + } + + private fun initView(){ + binding.clMainSight.clipToOutline = true + } + + private fun initEvent(){ binding.ivHomeProfile.setOnClickListener { navigateToProfileEditActivity() } binding.ibHomeEdit.setOnClickListener { navigateToProfileEditActivity() } binding.clHomeSightRecord.setOnClickListener { navigateToSeatRecordActivity() } - binding.clMainSight.clipToOutline = true + } + private fun initObserver() { viewModel.profile.asLiveData().observe(this) { state -> when (state) { is UiState.Success -> { @@ -76,8 +89,6 @@ class HomeActivity : BaseActivity( is UiState.Empty -> {} } } - - viewModel.getInformation() } private fun updateRecentReview(review: RecentReviewResponse) = with(binding) { @@ -118,7 +129,6 @@ class HomeActivity : BaseActivity( } private fun updateProfile(profile: ProfileResponse) = with(binding) { - setSpannableString(viewModel.nickname.value, viewModel.reviewCount.value) ivHomeProfile.load(profile.profileImage) { transformations(CircleCropTransformation()) } "Lv.${profile.level} ${profile.level.levelToTitle()}".also { tvHomeLevel.text = it } ivHomeCheerTeam.load(profile.teamImage) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt index aae0306b..1999dacf 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt @@ -41,6 +41,7 @@ class HomeViewModel @Inject constructor( val profileResult = profileDeferred.await() profileResult.onSuccess { _profile.value = UiState.Success(it) + nickname.value = it.nickname }.onFailure { _profile.value = UiState.Failure(it.message ?: "실패") } @@ -48,6 +49,7 @@ class HomeViewModel @Inject constructor( val reviewResult = reviewDeferred.await() reviewResult.onSuccess { _recentReview.value = UiState.Success(it) + reviewCount.value = it.totalReviewCount }.onFailure { _recentReview.value = UiState.Failure(it.message ?: "실패") } From e0e44bf0249161ec19b8dbeebebf1b99b9bcaf15 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:50:53 +0900 Subject: [PATCH 55/83] =?UTF-8?q?[fix/#29]=20=ED=99=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80,=20=ED=8C=80=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20null?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/response/home/ResponseProfileDto.kt | 12 ++++-- .../entity/response/home/ProfileResponse.kt | 1 + .../presentation/home/HomeActivity.kt | 41 ++++++++----------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt index f5fa2323..39ebcfca 100644 --- a/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt @@ -6,21 +6,25 @@ import kotlinx.serialization.Serializable @Serializable data class ResponseProfileDto( + //TODO : 서버에서 팀 아이디 받아와서 넘겨줘야함 @SerialName("profileImageUrl") - val profileImageUrl: String, + val profileImageUrl: String?, @SerialName("nickname") val nickname: String, @SerialName("level") val level: Int, + @SerialName("levelTitle") + val levelTitle: String, @SerialName("teamImageUrl") - val teamImageUrl: String, + val teamImageUrl: String?, ) { companion object { fun ResponseProfileDto.toProfileResponse() = ProfileResponse( - profileImage = profileImageUrl, + profileImage = profileImageUrl ?: "", nickname = nickname, level = level, - teamImage = teamImageUrl + levelTitle = levelTitle, + teamImage = teamImageUrl ?: "", ) } } diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt index 54de15e9..088eae2c 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt @@ -5,5 +5,6 @@ data class ProfileResponse( val profileImage : String = "", val nickname :String = "", val level : Int = 0, + val levelTitle : String = "", val teamImage : String = "" ) \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt index 9c586ce7..8e5dd99b 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt @@ -12,7 +12,6 @@ import com.depromeet.core.base.BaseActivity import com.depromeet.core.state.UiState import com.depromeet.domain.entity.response.home.ProfileResponse import com.depromeet.domain.entity.response.home.RecentReviewResponse -import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ActivityHomeBinding import com.depromeet.presentation.extension.loadAndClip import com.depromeet.presentation.extension.toast @@ -50,11 +49,11 @@ class HomeActivity : BaseActivity( } - private fun initView(){ + private fun initView() { binding.clMainSight.clipToOutline = true } - private fun initEvent(){ + private fun initEvent() { binding.ivHomeProfile.setOnClickListener { navigateToProfileEditActivity() } binding.ibHomeEdit.setOnClickListener { navigateToProfileEditActivity() } binding.clHomeSightRecord.setOnClickListener { navigateToSeatRecordActivity() } @@ -129,35 +128,29 @@ class HomeActivity : BaseActivity( } private fun updateProfile(profile: ProfileResponse) = with(binding) { - ivHomeProfile.load(profile.profileImage) { transformations(CircleCropTransformation()) } - "Lv.${profile.level} ${profile.level.levelToTitle()}".also { tvHomeLevel.text = it } + setSpannableString(viewModel.nickname.value, viewModel.reviewCount.value) + if (profile.profileImage.isEmpty()) { + ivHomeProfile.setImageResource(com.depromeet.presentation.R.drawable.ic_default_profile) + } else { + ivHomeProfile.load(profile.profileImage) { + transformations(CircleCropTransformation()) + } + } + "Lv.${profile.level} ${profile.levelTitle}".also { tvHomeLevel.text = it } ivHomeCheerTeam.load(profile.teamImage) } - /** 임시 처리 서버에서 내려주면 다시 바꿔주고 아니면 그대로 유지*/ - private fun Int.levelToTitle(): String { - return when (this) { - 1 -> getString(R.string.one_level_to_title) - 2 -> getString(R.string.two_level_to_title) - 3 -> getString(R.string.three_level_to_title) - 4 -> getString(R.string.four_level_to_title) - 5 -> getString(R.string.five_level_to_title) - 6 -> getString(R.string.six_level_to_title) - else -> getString(R.string.unknown_level_to_title) - } - } - private fun navigateToProfileEditActivity() { val currentState = viewModel.profile.value - if(currentState is UiState.Success){ + if (currentState is UiState.Success) { Intent(this, ProfileEditActivity::class.java).apply { - with(currentState.data) { - putExtra(PROFILE_NAME, this.nickname) - putExtra(PROFILE_IMAGE, this.profileImage) - putExtra(PROFILE_CHEER_TEAM, this.teamId) - } + with(currentState.data) { + putExtra(PROFILE_NAME, this.nickname) + putExtra(PROFILE_IMAGE, this.profileImage) + putExtra(PROFILE_CHEER_TEAM, this.teamId) + } }.let(::startActivity) } From 2fe8713c1c1b0449afa4f1154d2f61c324daa9c7 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:27:14 +0900 Subject: [PATCH 56/83] =?UTF-8?q?[fix/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=EA=B8=B0=EB=A1=9D=20API=EA=B4=80=EB=A0=A8=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/home/ResponseMySeatRecordDto.kt | 18 ++++++++++++++++++ .../viewmodel/SeatRecordViewModel.kt | 3 +++ 2 files changed, 21 insertions(+) diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt index f02080ce..ed9da037 100644 --- a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt @@ -19,6 +19,12 @@ data class ResponseMySeatRecordDto( val number: Int, @SerialName("size") val size: Int, + @SerialName("first") + val first: Boolean, + @SerialName("last") + val last: Boolean, + @SerialName("filter") + val filter: ResponseFilterDto, ) { @Serializable data class ResponseMemberDto( @@ -151,6 +157,18 @@ data class ResponseMySeatRecordDto( val url: String, ) + @Serializable + data class ResponseFilterDto( + @SerialName("rowNumber") + val rowNumber: Int, + @SerialName("seatNumber") + val seatNumber: Int, + @SerialName("year") + val year: Int, + @SerialName("month") + val month: Int, + ) + companion object { fun ResponseMySeatRecordDto.toMySeatRecordResponse() = MySeatRecordResponse( profile = memberInfoOnMyReview.toMyProfileResponse(), diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index ce512af0..1aa77287 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -15,6 +15,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +import timber.log.Timber import javax.inject.Inject @HiltViewModel @@ -68,8 +69,10 @@ class SeatRecordViewModel @Inject constructor( month = month ) ).onSuccess { data -> + Timber.d("GET_SEAT_RECORDS_TEST SUCCESS : $data") _reviews.value = UiState.Success(data) }.onFailure { + Timber.d("GET_SEAT_RECORDS_TEST FAIL : $it") _reviews.value = UiState.Failure(it.message ?: "실패") } } From 5e4c95f87735a93e01d215941f1b4c2bb18ee7db Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:36:10 +0900 Subject: [PATCH 57/83] =?UTF-8?q?[feature/#29]=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EB=A1=9C=EB=94=A9=20placeholder,error=20=EC=9E=84?= =?UTF-8?q?=EC=8B=9C=20=EC=82=AC=EC=A7=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/res/drawable/ic_image_error.png | Bin 0 -> 8311 bytes .../main/res/drawable/ic_image_placeholder.jpg | Bin 0 -> 3767 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 presentation/src/main/res/drawable/ic_image_error.png create mode 100644 presentation/src/main/res/drawable/ic_image_placeholder.jpg diff --git a/presentation/src/main/res/drawable/ic_image_error.png b/presentation/src/main/res/drawable/ic_image_error.png new file mode 100644 index 0000000000000000000000000000000000000000..2873ba6170718d9de8bcf9d69ee02542982effa0 GIT binary patch literal 8311 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 B=`;WU literal 0 HcmV?d00001 diff --git a/presentation/src/main/res/drawable/ic_image_placeholder.jpg b/presentation/src/main/res/drawable/ic_image_placeholder.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d4e09b35ccfc3f3e8a164e029698357407d6b1cd GIT binary patch literal 3767 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 Ub+YHX<+9u3zbO4jIpNTM0dYR1DgXcg literal 0 HcmV?d00001 From bbd1cfa856256f04bf5c8e5fc8779ab07c4aa8be Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:38:23 +0900 Subject: [PATCH 58/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=EA=B8=B0=EB=A1=9D=20API=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=97=90=20=EB=94=B0=EB=A5=B8=20data,domain,?= =?UTF-8?q?presentation=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datasource/remote/HomeDataSourceImpl.kt | 8 ++-- .../com/depromeet/data/mapper/HomeMapper.kt | 9 ---- .../request/home/RequestMySeatRecordDto.kt | 20 ++++++-- .../response/home/ResponseMySeatRecordDto.kt | 46 +++++++++---------- .../depromeet/data/remote/HomeApiService.kt | 4 +- .../data/repository/HomeRepositoryImpl.kt | 2 +- .../request/home/MySeatRecordRequest.kt | 4 +- .../response/home/MySeatRecordResponse.kt | 3 +- .../presentation/extension/ViewExt.kt | 8 +++- .../seatrecord/SeatRecordActivity.kt | 4 +- .../seatrecord/adapter/RecentRecordAdapter.kt | 14 ++++-- .../presentation/util/CalenderUtil.kt | 2 +- 12 files changed, 65 insertions(+), 59 deletions(-) diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index a7293776..06c6ba2b 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -21,10 +21,10 @@ class HomeDataSourceImpl @Inject constructor( ) : HomeDataSource { override suspend fun getMySeatRecordData(requestMySeatRecordDto: RequestMySeatRecordDto): ResponseMySeatRecordDto { return homeApiService.getMySeatRecord( - requestMySeatRecordDto.offset, - requestMySeatRecordDto.limit, - requestMySeatRecordDto.year, - requestMySeatRecordDto.month + page = requestMySeatRecordDto.page, + size = requestMySeatRecordDto.size, + year = requestMySeatRecordDto.year, + month = requestMySeatRecordDto.month ) } diff --git a/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt index ca1bb103..87014bcb 100644 --- a/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt +++ b/data/src/main/java/com/depromeet/data/mapper/HomeMapper.kt @@ -1,20 +1,11 @@ package com.depromeet.data.mapper -import com.depromeet.data.model.request.home.RequestMySeatRecordDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto -import com.depromeet.domain.entity.request.home.MySeatRecordRequest import com.depromeet.domain.entity.response.home.BaseballTeamResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse -fun MySeatRecordRequest.toMySeatRecordRequestDto() = RequestMySeatRecordDto( - offset = offset, - limit = limit, - year = year, - month = month -) - /** baseball team **/ fun ResponseBaseballTeamDto.toBaseballTeamResponse() = BaseballTeamResponse( id = id, diff --git a/data/src/main/java/com/depromeet/data/model/request/home/RequestMySeatRecordDto.kt b/data/src/main/java/com/depromeet/data/model/request/home/RequestMySeatRecordDto.kt index 528bfe37..3dc6e842 100644 --- a/data/src/main/java/com/depromeet/data/model/request/home/RequestMySeatRecordDto.kt +++ b/data/src/main/java/com/depromeet/data/model/request/home/RequestMySeatRecordDto.kt @@ -1,17 +1,27 @@ package com.depromeet.data.model.request.home +import com.depromeet.domain.entity.request.home.MySeatRecordRequest import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable data class RequestMySeatRecordDto( - @SerialName("offset") - val offset: Int? = null, - @SerialName("limit") - val limit: Int? = null, + @SerialName("page") + val page: Int? = null, + @SerialName("size") + val size: Int? = null, @SerialName("year") val year: Int? = null, @SerialName("month") val month: Int? = null, -) +) { + companion object { + fun MySeatRecordRequest.toMySeatRecordRequestDto() = RequestMySeatRecordDto( + page = page, + size = size, + year = year, + month = month + ) + } +} diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt index ed9da037..65689999 100644 --- a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt @@ -31,9 +31,11 @@ data class ResponseMySeatRecordDto( @SerialName("userId") val userId: Int, @SerialName("profileImageUrl") - val profileImageUrl: String, + val profileImageUrl: String?, @SerialName("level") val level: Int, + @SerialName("levelTitle") + val levelTitle: String, @SerialName("nickname") val nickname: String, @SerialName("reviewCount") @@ -91,7 +93,7 @@ data class ResponseMySeatRecordDto( @Serializable data class ResponseMemberDto( @SerialName("profileImage") - val profileImage: String, + val profileImage: String?, @SerialName("nickname") val nickname: String, @SerialName("level") @@ -104,14 +106,6 @@ data class ResponseMySeatRecordDto( val id: Int, @SerialName("name") val name: String, - @SerialName("mainImage") - val mainImage: String, - @SerialName("seatingChartImage") - val seatingChartImage: String, - @SerialName("labeledSeatingChartImage") - val labeledSeatingChartImage: String, - @SerialName("isActive") - val isActive: Boolean, ) @Serializable @@ -121,7 +115,7 @@ data class ResponseMySeatRecordDto( @SerialName("name") val name: String, @SerialName("alias") - val alias: String, + val alias: String?, ) @Serializable @@ -147,26 +141,27 @@ data class ResponseMySeatRecordDto( @SerialName("seatNumber") val seatNumber: Int, ) + + @Serializable + data class ResponseReviewImageDto( + @SerialName("id") + val id: Int, + @SerialName("url") + val url: String, + ) } - @Serializable - data class ResponseReviewImageDto( - @SerialName("id") - val id: Int, - @SerialName("url") - val url: String, - ) @Serializable data class ResponseFilterDto( @SerialName("rowNumber") - val rowNumber: Int, + val rowNumber: Int?, @SerialName("seatNumber") - val seatNumber: Int, + val seatNumber: Int?, @SerialName("year") - val year: Int, + val year: Int?, @SerialName("month") - val month: Int, + val month: Int?, ) companion object { @@ -182,8 +177,9 @@ data class ResponseMySeatRecordDto( private fun ResponseMemberDto.toMyProfileResponse() = MySeatRecordResponse.MyProfileResponse( userId = userId, - profileImage = profileImageUrl, + profileImage = profileImageUrl ?: "", level = level, + levelTitle = levelTitle, nickname = nickname, reviewCount = reviewCount ) @@ -207,7 +203,7 @@ data class ResponseMySeatRecordDto( private fun ResponseReviewDto.ResponseMemberDto.toMemberResponse() = MySeatRecordResponse.ReviewResponse.MemberResponse( - profileImage = profileImage, + profileImage = profileImage ?: "", nickname = nickname, level = level ) @@ -219,7 +215,7 @@ data class ResponseMySeatRecordDto( isPositive = isPositive ) - private fun ResponseReviewImageDto.toReviewImageResponse() = + private fun ResponseReviewDto.ResponseReviewImageDto.toReviewImageResponse() = MySeatRecordResponse.ReviewResponse.ReviewImageResponse( id = id, url = url diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index a05a339b..742a8f92 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -21,8 +21,8 @@ import retrofit2.http.Url interface HomeApiService { @GET("/api/v1/reviews") suspend fun getMySeatRecord( - @Query("offset") offset: Int?, - @Query("limit") limit: Int?, + @Query("page") page: Int?, + @Query("size") size: Int?, @Query("year") year: Int?, @Query("month") month: Int?, ): ResponseMySeatRecordDto diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index 9a247d8c..6dc83268 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -2,8 +2,8 @@ package com.depromeet.data.repository import com.depromeet.data.datasource.HomeDataSource import com.depromeet.data.mapper.toBaseballTeamResponse -import com.depromeet.data.mapper.toMySeatRecordRequestDto import com.depromeet.data.mapper.toPresignedUrlResponse +import com.depromeet.data.model.request.home.RequestMySeatRecordDto.Companion.toMySeatRecordRequestDto import com.depromeet.data.model.request.home.RequestProfileEditDto.Companion.toProfileEditRequestDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto.Companion.toMySeatRecordResponse import com.depromeet.data.model.response.home.ResponseProfileDto.Companion.toProfileResponse diff --git a/domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt b/domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt index 82ddf7d6..ad35190e 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt @@ -1,8 +1,8 @@ package com.depromeet.domain.entity.request.home data class MySeatRecordRequest( - val offset: Int ?= null, - val limit: Int ?= 50, + val page: Int ?= null, + val size: Int ?= 50, val year: Int ?= 2024, val month: Int ?= null, ) diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt index a5eb3bf6..31a23f5c 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt @@ -1,7 +1,7 @@ package com.depromeet.domain.entity.response.home data class MySeatRecordResponse( - val profile: MyProfileResponse, + val profile: MyProfileResponse = MyProfileResponse(), val reviews: List = emptyList(), val totalElements: Int = 0, val totalPages: Int = 0, @@ -12,6 +12,7 @@ data class MySeatRecordResponse( val userId: Int = 0, val profileImage: String = "", val level: Int = 0, + val levelTitle : String = "", val nickname: String = "", val reviewCount: Int = 0, ) diff --git a/presentation/src/main/java/com/depromeet/presentation/extension/ViewExt.kt b/presentation/src/main/java/com/depromeet/presentation/extension/ViewExt.kt index 58d1e66e..a98e45f9 100644 --- a/presentation/src/main/java/com/depromeet/presentation/extension/ViewExt.kt +++ b/presentation/src/main/java/com/depromeet/presentation/extension/ViewExt.kt @@ -4,6 +4,7 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import coil.load +import com.depromeet.presentation.R inline fun View.setOnSingleClickListener( delay: Long = 1000L, @@ -27,7 +28,10 @@ fun View.setMargins(left: Int, top: Int, right: Int, bottom: Int) { } } -fun ImageView.loadAndClip(imageUrl: String) { - this.load(imageUrl) +fun ImageView.loadAndClip(imageUrl: Any) { + this.load(imageUrl){ + placeholder(R.drawable.ic_image_placeholder) + error(R.drawable.ic_image_error) + } this.clipToOutline = true } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 3404793a..4c05bd95 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -109,7 +109,7 @@ class SeatRecordActivity : BaseActivity( viewModel.reviews.asLiveData().observe(this) { state -> when (state) { is UiState.Success -> { - /*** setProfile() ->사용자 프로필 데이터 아직 서버 api명세서에 없음 */ + setProfile(state.data.profile) setReviewList(state.data.reviews) } @@ -137,7 +137,7 @@ class SeatRecordActivity : BaseActivity( private fun setProfile(data: MySeatRecordResponse.MyProfileResponse) { with(binding) { //TODO : 서버에서 칭호 넘겨주변 업데이트 해야함.. - "Lv.${data.level} 칭호".also { tvRecordLevel.text = it } + "Lv.${data.level} ${data.levelTitle}".also { tvRecordLevel.text = it } tvRecordNickname.text = data.nickname tvRecordCount.text = data.reviewCount.toString() ivRecordProfile.load(data.profileImage) { diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt index da6b148f..5474ae06 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt @@ -7,11 +7,11 @@ import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.depromeet.domain.entity.response.home.MySeatRecordResponse +import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ItemRecentRecordBinding -import com.depromeet.presentation.extension.extractDay -import com.depromeet.presentation.extension.getDayOfWeek import com.depromeet.presentation.extension.loadAndClip import com.depromeet.presentation.seatrecord.uiMapper.toUiKeyword +import com.depromeet.presentation.util.CalendarUtil import com.depromeet.presentation.util.ItemDiffCallback import com.depromeet.presentation.viewfinder.compose.KeywordFlowRow @@ -63,9 +63,13 @@ class RecentRecordViewHolder( fun bind(item: MySeatRecordResponse.ReviewResponse) { with(binding) { - ivRecentImage.loadAndClip(item.images[0].url) - tvRecentDateDay.text = item.date.extractDay() - tvRecentDay.text = item.date.getDayOfWeek() + if (item.images.isNotEmpty()) { + ivRecentImage.loadAndClip(item.images[0].url) + } else { + ivRecentImage.loadAndClip(R.drawable.ic_image_placeholder) + } + tvRecentDateDay.text = CalendarUtil.getDayOfMonthFromDateFormat(item.date).toString() + tvRecentDay.text = CalendarUtil.getDayOfWeekFromDateFormat(item.date) tvRecentBlockName.text = item.blockName tvRecentStadiumName.text = item.stadiumName cvDetailKeyword.apply { diff --git a/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt b/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt index 5df8a4f0..b117e595 100644 --- a/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt +++ b/presentation/src/main/java/com/depromeet/presentation/util/CalenderUtil.kt @@ -10,7 +10,7 @@ import java.util.Locale object CalendarUtil { - private const val ISO_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" + private const val ISO_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss" private const val DATE_FORMAT = "yy.MM.dd" fun formatCalendarDate(calendar: Calendar): String { From 807cc1eca0bf881f041a3558741d98c164dec4b5 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 19:01:19 +0900 Subject: [PATCH 59/83] =?UTF-8?q?[fix/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=EA=B8=B0=EB=A1=9D=20=EC=B4=88=EA=B8=B0=20=EC=A7=84?= =?UTF-8?q?=EC=9E=85=EC=8B=9C=20=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EB=A1=9C?= =?UTF-8?q?=EB=94=A9=20=EC=95=88=EB=90=98=EB=8A=94=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95,=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/model/response/home/ResponseMySeatRecordDto.kt | 1 + .../domain/entity/response/home/MySeatRecordResponse.kt | 1 + .../depromeet/presentation/seatrecord/SeatRecordActivity.kt | 4 ++++ .../presentation/seatrecord/adapter/RecentRecordAdapter.kt | 2 +- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt index 65689999..83c6d265 100644 --- a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt @@ -196,6 +196,7 @@ data class ResponseMySeatRecordDto( seatNumber = seat.seatNumber, date = dateTime, content = content, + sectionName = section.name, member = member.toMemberResponse(), images = images.map { it.toReviewImageResponse() }, keywords = keywords.map { it.toReviewKeywordResponse() } diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt index 31a23f5c..bbe6852a 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt @@ -29,6 +29,7 @@ data class MySeatRecordResponse( val seatNumber: Int = 0, val date: String = "", val content: String = "", + val sectionName : String = "", val member: MemberResponse = MemberResponse(), val images: List = emptyList(), val keywords: List = emptyList(), diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 4c05bd95..3aa58179 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -142,11 +142,13 @@ class SeatRecordActivity : BaseActivity( tvRecordCount.text = data.reviewCount.toString() ivRecordProfile.load(data.profileImage) { transformations(CircleCropTransformation()) + error(R.drawable.ic_default_profile) } } } private fun initYearSpinner(years: List) { + viewModel.setSelectedYear(years[0]) val yearList = years.map { "${it}년" } val adapter = SpotSpinner( @@ -170,6 +172,7 @@ class SeatRecordActivity : BaseActivity( adapter.setSelectedItemPosition(position) val selectedYear = yearList[position].filter { it.isDigit() }.toInt() viewModel.setSelectedYear(selectedYear) + binding.ssvRecord.smoothScrollTo(0, 0) } override fun onNothingSelected(p0: AdapterView<*>?) {} @@ -191,6 +194,7 @@ class SeatRecordActivity : BaseActivity( override fun onItemMonthClick(item: MonthUiData) { val selectedMonth = item.month viewModel.setSelectedMonth(selectedMonth) + binding.ssvRecord.smoothScrollTo(0, 0) } } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt index 5474ae06..bc29ffe0 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/RecentRecordAdapter.kt @@ -70,7 +70,7 @@ class RecentRecordViewHolder( } tvRecentDateDay.text = CalendarUtil.getDayOfMonthFromDateFormat(item.date).toString() tvRecentDay.text = CalendarUtil.getDayOfWeekFromDateFormat(item.date) - tvRecentBlockName.text = item.blockName + "${item.sectionName} ${item.blockName}블록".also { tvRecentBlockName.text = it } tvRecentStadiumName.text = item.stadiumName cvDetailKeyword.apply { setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) From fdea35d8fce4ef386bf5f97b53093b3f61d02c80 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 19:33:56 +0900 Subject: [PATCH 60/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=20=EA=B8=B0=EB=A1=9D=20=EC=82=AD=EC=A0=9C=20API=20dat?= =?UTF-8?q?a=20=EB=AA=A8=EB=93=88=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../depromeet/data/datasource/HomeDataSource.kt | 5 +++++ .../datasource/remote/HomeDataSourceImpl.kt | 7 +++++++ .../response/home/ResponseDeleteReviewDto.kt | 17 +++++++++++++++++ .../com/depromeet/data/remote/HomeApiService.kt | 7 +++++++ .../data/repository/HomeRepositoryImpl.kt | 8 ++++++++ 5 files changed, 44 insertions(+) create mode 100644 data/src/main/java/com/depromeet/data/model/response/home/ResponseDeleteReviewDto.kt diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt index eb35e8a7..af711677 100644 --- a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -3,6 +3,7 @@ package com.depromeet.data.datasource import com.depromeet.data.model.request.home.RequestMySeatRecordDto import com.depromeet.data.model.request.home.RequestProfileEditDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto +import com.depromeet.data.model.response.home.ResponseDeleteReviewDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.data.model.response.home.ResponseProfileDto @@ -41,4 +42,8 @@ interface HomeDataSource { suspend fun getProfile(): ResponseProfileDto suspend fun getRecentReview(): ResponseRecentReviewDto + + suspend fun deleteReview( + reviewId : Int + ): ResponseDeleteReviewDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index 06c6ba2b..a93b4c83 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -5,6 +5,7 @@ import com.depromeet.data.model.request.home.RequestFileExtensionDto import com.depromeet.data.model.request.home.RequestMySeatRecordDto import com.depromeet.data.model.request.home.RequestProfileEditDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto +import com.depromeet.data.model.response.home.ResponseDeleteReviewDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.data.model.response.home.ResponseProfileDto @@ -69,4 +70,10 @@ class HomeDataSourceImpl @Inject constructor( override suspend fun getRecentReview(): ResponseRecentReviewDto { return homeApiService.getRecentReview() } + + override suspend fun deleteReview( + reviewId: Int, + ): ResponseDeleteReviewDto { + return homeApiService.deleteReview(reviewId) + } } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseDeleteReviewDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseDeleteReviewDto.kt new file mode 100644 index 00000000..dc4db421 --- /dev/null +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseDeleteReviewDto.kt @@ -0,0 +1,17 @@ +package com.depromeet.data.model.response.home + +import com.depromeet.domain.entity.response.home.DeleteReviewResponse +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponseDeleteReviewDto( + @SerialName("deleteReviewId") + val deleteReviewId: Int, +) { + companion object { + fun ResponseDeleteReviewDto.toDeleteReviewResponse() = DeleteReviewResponse( + reviewId = deleteReviewId + ) + } +} \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index 742a8f92..04028596 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -3,6 +3,7 @@ package com.depromeet.data.remote import com.depromeet.data.model.request.home.RequestFileExtensionDto import com.depromeet.data.model.request.home.RequestProfileEditDto import com.depromeet.data.model.response.home.ResponseBaseballTeamDto +import com.depromeet.data.model.response.home.ResponseDeleteReviewDto import com.depromeet.data.model.response.home.ResponseMySeatRecordDto import com.depromeet.data.model.response.home.ResponsePresignedUrlDto import com.depromeet.data.model.response.home.ResponseProfileDto @@ -11,6 +12,7 @@ import com.depromeet.data.model.response.home.ResponseRecentReviewDto import com.depromeet.data.model.response.home.ResponseReviewDateDto import okhttp3.RequestBody import retrofit2.http.Body +import retrofit2.http.DELETE import retrofit2.http.GET import retrofit2.http.POST import retrofit2.http.PUT @@ -61,4 +63,9 @@ interface HomeApiService { @GET("/api/v1/reviews/recentReview") suspend fun getRecentReview(): ResponseRecentReviewDto + + @DELETE("/api/v1/reviews/{reviewId}") + suspend fun deleteReview( + @Path("reviewId") reviewId: Int, + ): ResponseDeleteReviewDto } \ No newline at end of file diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index 6dc83268..f70fe182 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -5,6 +5,7 @@ import com.depromeet.data.mapper.toBaseballTeamResponse import com.depromeet.data.mapper.toPresignedUrlResponse import com.depromeet.data.model.request.home.RequestMySeatRecordDto.Companion.toMySeatRecordRequestDto import com.depromeet.data.model.request.home.RequestProfileEditDto.Companion.toProfileEditRequestDto +import com.depromeet.data.model.response.home.ResponseDeleteReviewDto.Companion.toDeleteReviewResponse import com.depromeet.data.model.response.home.ResponseMySeatRecordDto.Companion.toMySeatRecordResponse import com.depromeet.data.model.response.home.ResponseProfileDto.Companion.toProfileResponse import com.depromeet.data.model.response.home.ResponseProfileEditDto.Companion.toProfileEditResponse @@ -13,6 +14,7 @@ import com.depromeet.data.model.response.home.ResponseReviewDateDto.Companion.to import com.depromeet.domain.entity.request.home.MySeatRecordRequest import com.depromeet.domain.entity.request.home.ProfileEditRequest import com.depromeet.domain.entity.response.home.BaseballTeamResponse +import com.depromeet.domain.entity.response.home.DeleteReviewResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse import com.depromeet.domain.entity.response.home.ProfileEditResponse @@ -87,4 +89,10 @@ class HomeRepositoryImpl @Inject constructor( homeDataSource.getRecentReview().toRecentReviewResponse() } } + + override suspend fun deleteReview(reviewId: Int): Result { + return runCatching { + homeDataSource.deleteReview(reviewId).toDeleteReviewResponse() + } + } } \ No newline at end of file From 2f541012775a94a2e4980982876565579ccf917a Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 19:34:20 +0900 Subject: [PATCH 61/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=20=EA=B8=B0=EB=A1=9D=20=EC=82=AD=EC=A0=9C=20API=20dom?= =?UTF-8?q?ain=20=EB=AA=A8=EB=93=88=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/entity/response/home/DeleteReviewResponse.kt | 5 +++++ .../java/com/depromeet/domain/repository/HomeRepository.kt | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 domain/src/main/java/com/depromeet/domain/entity/response/home/DeleteReviewResponse.kt diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/DeleteReviewResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/DeleteReviewResponse.kt new file mode 100644 index 00000000..331bdc42 --- /dev/null +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/DeleteReviewResponse.kt @@ -0,0 +1,5 @@ +package com.depromeet.domain.entity.response.home + +data class DeleteReviewResponse( + val reviewId : Int +) diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt index 6f9f0f13..46b691a7 100644 --- a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -3,6 +3,7 @@ package com.depromeet.domain.repository import com.depromeet.domain.entity.request.home.MySeatRecordRequest import com.depromeet.domain.entity.request.home.ProfileEditRequest import com.depromeet.domain.entity.response.home.BaseballTeamResponse +import com.depromeet.domain.entity.response.home.DeleteReviewResponse import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.PresignedUrlResponse import com.depromeet.domain.entity.response.home.ProfileEditResponse @@ -41,4 +42,8 @@ interface HomeRepository { suspend fun getProfile(): Result suspend fun getRecentReview(): Result + + suspend fun deleteReview( + reviewId: Int, + ): Result } \ No newline at end of file From 404942c18b89492f142a563cb5e38638adfdd4c1 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 19:37:01 +0900 Subject: [PATCH 62/83] =?UTF-8?q?[feature/#29]=20=EB=82=B4=20=EC=8B=9C?= =?UTF-8?q?=EC=95=BC=20=EA=B8=B0=EB=A1=9D=20=EC=82=AD=EC=A0=9C=20API=20pre?= =?UTF-8?q?sentation=20=EB=AA=A8=EB=93=88=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/SeatRecordActivity.kt | 11 ++++++----- .../seatrecord/adapter/MonthRecordAdapter.kt | 2 +- .../seatrecord/mockdata/SeatRecordMockData.kt | 11 ----------- .../seatrecord/uiMapper/HomeMapper.kt | 2 +- .../seatrecord/viewmodel/SeatRecordViewModel.kt | 17 +++++++++++++---- 5 files changed, 21 insertions(+), 22 deletions(-) delete mode 100644 presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 3aa58179..8e3e668d 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -15,7 +15,6 @@ import com.depromeet.designsystem.extension.dpToPx import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ActivitySeatRecordBinding -import com.depromeet.presentation.extension.extractMonth import com.depromeet.presentation.extension.toast import com.depromeet.presentation.seatrecord.adapter.DateMonthAdapter import com.depromeet.presentation.seatrecord.adapter.LinearSpacingItemDecoration @@ -23,6 +22,7 @@ import com.depromeet.presentation.seatrecord.adapter.MonthRecordAdapter import com.depromeet.presentation.seatrecord.uiMapper.MonthReviewData import com.depromeet.presentation.seatrecord.uiMapper.MonthUiData import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel +import com.depromeet.presentation.util.CalendarUtil import dagger.hilt.android.AndroidEntryPoint import timber.log.Timber @@ -76,7 +76,7 @@ class SeatRecordActivity : BaseActivity( } private fun observeDates() { - viewModel.selectedYear.asLiveData().observe(this) { selectedYear -> + viewModel.selectedYear.asLiveData().observe(this) { viewModel.initMonths() } viewModel.months.asLiveData().observe(this) { @@ -220,9 +220,10 @@ class SeatRecordActivity : BaseActivity( private fun setReviewList(reviews: List) { val groupList = - reviews.groupBy { it.date.extractMonth(false) }.map { (month, reviews) -> - MonthReviewData(month, reviews) - } + reviews.groupBy { CalendarUtil.getMonthFromDateFormat(it.date) } + .map { (month, reviews) -> + MonthReviewData(month, reviews) + } monthRecordAdapter = MonthRecordAdapter() binding.rvRecordMonthDetail.adapter = monthRecordAdapter monthRecordAdapter.submitList(groupList) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt index ed35b799..90c6fef7 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/MonthRecordAdapter.kt @@ -14,7 +14,7 @@ class MonthRecordAdapter() : ListAdapter( ItemDiffCallback( onItemsTheSame = { oldItem, newItem -> oldItem.month == newItem.month }, - onContentsTheSame = { oldItem, newItem -> oldItem == newItem } + onContentsTheSame = { oldItem, newItem -> oldItem.reviews == newItem.reviews } ) ) { interface OnItemRecordClickListener { diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt deleted file mode 100644 index fc4972f5..00000000 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/mockdata/SeatRecordMockData.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.depromeet.presentation.seatrecord.mockdata - -data class ProfileDetailData( - val nickName: String = "", - val profileImage: String = "", - val level: Int = 0, - val titleName: String = "", - val recordCount: Int = 0, -) - - diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt index f76863f5..63aecf1b 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt @@ -9,7 +9,7 @@ import kotlinx.parcelize.Parcelize * 리팩토링 예정 */ data class MonthReviewData( - val month: String, + val month: Int, val reviews: List, ) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index 1aa77287..54886437 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -111,11 +111,20 @@ class SeatRecordViewModel @Inject constructor( fun removeReviewData() { val currentState = reviews.value if (currentState is UiState.Success) { - val updatedList = currentState.data.reviews.filter { review -> - review.id != editReviewId.value + viewModelScope.launch { + homeRepository.deleteReview(editReviewId.value) + .onSuccess { + if(it.reviewId == editReviewId.value){ + val updatedList = currentState.data.reviews.filter { review -> + review.id != editReviewId.value + } + _reviews.value = UiState.Success(currentState.data.copy(reviews = updatedList)) + } + } + .onFailure { + Timber.d("삭제 실패 : $it") + } } - /** 여기서 서버에서 통신이 성공 -> uistate업로드 (api 명세 아직 없음)*/ - _reviews.value = UiState.Success(currentState.data.copy(reviews = updatedList)) _deleteClickedEvent.value = false } From 11feb200d91f68f415a726edb2b9b7fdee64c329 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Wed, 24 Jul 2024 19:38:22 +0900 Subject: [PATCH 63/83] =?UTF-8?q?[refactor/#29]=20=EB=82=A0=EC=A7=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20stringextension=20=EC=82=AD=EC=A0=9C=20->?= =?UTF-8?q?=20CalenderUtil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/extension/StringExt.kt | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt b/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt index 2a249953..7ae0e581 100644 --- a/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt +++ b/presentation/src/main/java/com/depromeet/presentation/extension/StringExt.kt @@ -1,10 +1,6 @@ package com.depromeet.presentation.extension import com.depromeet.presentation.login.viewmodel.NicknameInputState -import java.time.LocalDate -import java.time.format.DateTimeFormatter -import java.time.format.TextStyle -import java.util.Locale const val NICKNAME_PATTERN = "^[a-zA-Z0-9가-힣]+$" @@ -14,39 +10,4 @@ fun String.validateNickName(): NicknameInputState { !this.matches(Regex(NICKNAME_PATTERN)) -> NicknameInputState.INVALID_CHARACTER else -> NicknameInputState.VALID } -} - -/** ex) 2024-01-21 (서버 date형식 예정) - * TODO : CalenderUtil로 뺐음 추후에 삭제 해야함 - * */ -fun String.extractDay(): String { - val parts = this.split("-") - return if (parts.size == 3) { - parts[2] - } else { - "" - } -} - -fun String.extractMonth(includeSuffixMonth: Boolean): String { - val parts = this.split("-") - if (parts.size == 3) { - val month = parts[1].toIntOrNull()?.toString() ?: return "" - return if (includeSuffixMonth) "${month}월" else month - } else if (this.length <= 2) { - return this.toIntOrNull()?.toString() ?: return "" - } - return "" -} - -//요일 확인 -fun String.getDayOfWeek(): String { - val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") - val date = LocalDate.parse(this, formatter) - return date.dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.KOREAN) -} - -fun String.getYearMonthDay(): String { - return LocalDate.parse(this, DateTimeFormatter.ISO_LOCAL_DATE) - .format(DateTimeFormatter.ofPattern("yyyy년 M월 d일")) } \ No newline at end of file From be20104634c514e22885cb1fc781b08d4f403c3b Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 25 Jul 2024 00:53:00 +0900 Subject: [PATCH 64/83] =?UTF-8?q?[fix/#29]=20=EB=82=A0=EC=A7=9C=EC=97=90?= =?UTF-8?q?=20=EB=94=B0=EB=A5=B8=20=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=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 --- .../seatrecord/SeatRecordActivity.kt | 29 +++++---- .../viewmodel/SeatRecordViewModel.kt | 8 +-- .../main/res/layout/activity_seat_record.xml | 60 +++++++++++-------- 3 files changed, 56 insertions(+), 41 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 8e3e668d..c204b37e 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -5,6 +5,7 @@ import android.os.Bundle import android.view.View import android.widget.AdapterView import androidx.activity.viewModels +import androidx.fragment.app.commit import androidx.lifecycle.asLiveData import coil.load import coil.transform.CircleCropTransformation @@ -81,6 +82,7 @@ class SeatRecordActivity : BaseActivity( } viewModel.months.asLiveData().observe(this) { dateMonthAdapter.submitList(it) + viewModel.getSeatRecords() } viewModel.date.asLiveData().observe(this) { state -> when (state) { @@ -88,12 +90,10 @@ class SeatRecordActivity : BaseActivity( setReviewsVisibility(isExist = true) val year = state.data.yearMonths.map { it.year } initYearSpinner(year) - viewModel.getSeatRecords() } is UiState.Empty -> { setReviewsVisibility(isExist = false) - viewModel.getSeatRecords() } is UiState.Loading -> {} @@ -136,7 +136,6 @@ class SeatRecordActivity : BaseActivity( private fun setProfile(data: MySeatRecordResponse.MyProfileResponse) { with(binding) { - //TODO : 서버에서 칭호 넘겨주변 업데이트 해야함.. "Lv.${data.level} ${data.levelTitle}".also { tvRecordLevel.text = it } tvRecordNickname.text = data.nickname tvRecordCount.text = data.reviewCount.toString() @@ -202,7 +201,7 @@ class SeatRecordActivity : BaseActivity( private fun setReviewsVisibility(isExist: Boolean) { if (!isExist) { with(binding) { - "${viewModel.selectedYear.value}년".also { tvRecordYear.text = it } + "${CalendarUtil.getCurrentYear()}년".also { tvRecordYear.text = it } clRecordNone.visibility = View.VISIBLE clRecordStickyHeader.visibility = View.GONE rvRecordMonthDetail.visibility = View.GONE @@ -232,13 +231,21 @@ class SeatRecordActivity : BaseActivity( object : MonthRecordAdapter.OnItemRecordClickListener { override fun onItemRecordClick(item: MySeatRecordResponse.ReviewResponse) { - Intent( - this@SeatRecordActivity, - SeatDetailRecordActivity::class.java - ).apply { - putExtra(RECORD_ID, item.id) - putParcelableArrayListExtra(RECORD_LIST, viewModel.getUiReviewsData()) - }.let(::startActivity) + + supportFragmentManager.commit { + replace( + R.id.fcv_record, + SeatDetailRecordFragment(), + SeatDetailRecordFragment.SEAT_RECORD_TAG + ) + } +// Intent( +// this@SeatRecordActivity, +// SeatDetailRecordActivity::class.java +// ).apply { +// putExtra(RECORD_ID, item.id) +// putParcelableArrayListExtra(RECORD_LIST, viewModel.getUiReviewsData()) +// }.let(::startActivity) } override fun onMoreRecordClick(reviewId: Int) { diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index 54886437..bb4b8f71 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -10,7 +10,6 @@ import com.depromeet.domain.repository.HomeRepository import com.depromeet.presentation.seatrecord.uiMapper.MonthUiData import com.depromeet.presentation.seatrecord.uiMapper.ReviewUiData import com.depromeet.presentation.seatrecord.uiMapper.toUiModel -import com.depromeet.presentation.util.CalendarUtil import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -33,7 +32,7 @@ class SeatRecordViewModel @Inject constructor( MutableStateFlow>(emptyList()) val months = _months.asStateFlow() - private val _selectedYear = MutableStateFlow(CalendarUtil.getCurrentYear()) + private val _selectedYear = MutableStateFlow(0) val selectedYear = _selectedYear.asStateFlow() private val _deleteClickedEvent = MutableStateFlow(false) @@ -114,11 +113,12 @@ class SeatRecordViewModel @Inject constructor( viewModelScope.launch { homeRepository.deleteReview(editReviewId.value) .onSuccess { - if(it.reviewId == editReviewId.value){ + if (it.reviewId == editReviewId.value) { val updatedList = currentState.data.reviews.filter { review -> review.id != editReviewId.value } - _reviews.value = UiState.Success(currentState.data.copy(reviews = updatedList)) + _reviews.value = + UiState.Success(currentState.data.copy(reviews = updatedList)) } } .onFailure { diff --git a/presentation/src/main/res/layout/activity_seat_record.xml b/presentation/src/main/res/layout/activity_seat_record.xml index 5cfbad17..927a75dd 100644 --- a/presentation/src/main/res/layout/activity_seat_record.xml +++ b/presentation/src/main/res/layout/activity_seat_record.xml @@ -40,33 +40,7 @@ app:menuIconColor="@color/gray900" app:navigationIcon="@drawable/ic_back" /> - - - + + + + + + \ No newline at end of file From 7293471392477a7c5332db00723c0501ac4b2144 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:16:20 +0900 Subject: [PATCH 65/83] =?UTF-8?q?[fix/#29]=20=EC=A2=8C=EC=84=9D=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EC=95=A1=ED=8B=B0=EB=B9=84=ED=8B=B0=20->?= =?UTF-8?q?=20=ED=94=84=EB=9E=98=EA=B7=B8=EB=A8=BC=ED=8A=B8=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 내 시야 좌석과 동일한 데이터들을 사용함 - 또한 삭제, 조회 등 동일하게 사용하여 activityviewmodel로 공유 --- .../seatrecord/ConfirmDeleteDialog.kt | 1 + .../seatrecord/RecordEditDialog.kt | 1 + .../seatrecord/SeatDetailRecordActivity.kt | 102 ------------------ .../seatrecord/SeatDetailRecordFragment.kt | 82 ++++++++++++++ .../seatrecord/adapter/DetailRecordAdapter.kt | 46 ++++---- .../layout/activity_seat_detail_record.xml | 3 +- 6 files changed, 114 insertions(+), 121 deletions(-) delete mode 100644 presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordActivity.kt create mode 100644 presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordFragment.kt diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt index 28f81d64..bb3c4e54 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt @@ -21,6 +21,7 @@ class ConfirmDeleteDialog : BindingDialogFragment( - ActivitySeatDetailRecordBinding::inflate -) { - companion object { - const val SEAT_DETAIL_TAG = "SEAT_DETAIL" - } - - private lateinit var detailRecordAdapter: DetailRecordAdapter - private val viewModel: SeatDetailViewModel by viewModels() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - initView() - initEvent() - initObserver() - - } - - private fun initView() { - setDetailRecordAdapter() - getDataExtra { id, reviews -> - val position = reviews.indexOfFirst { it.id == id } - if(position != -1){ - binding.rvDetailRecord.scrollToPosition(position) - } - viewModel.setReviewData(id, reviews) - } - - } - - private fun initEvent() { - with(binding) { - fabDetailUp.setOnClickListener { - rvDetailRecord.smoothScrollToPosition(0) - } - } - } - - private fun initObserver() { - - viewModel.uiState.asLiveData().observe(this) { - detailRecordAdapter.submitList(it) - } - - viewModel.deleteClickedEvent.asLiveData().observe(this) { state -> - if (state) moveConfirmationDialog() - } - } - - private fun setDetailRecordAdapter() { - detailRecordAdapter = DetailRecordAdapter() - binding.rvDetailRecord.adapter = detailRecordAdapter - - detailRecordAdapter.itemMoreClickListener = - object : DetailRecordAdapter.OnDetailItemClickListener { - override fun onItemMoreClickListener(item: ReviewUiData) { - viewModel.setEditReviewId(item.id) - RecordEditDialog.newInstance(SEAT_DETAIL_TAG) - .apply { show(supportFragmentManager, this.tag) } - } - } - } - - private fun moveConfirmationDialog() { - ConfirmDeleteDialog.newInstance(SEAT_DETAIL_TAG) - .apply { show(supportFragmentManager, this.tag) } - } - - @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.TIRAMISU, lambda = 0) - private fun getDataExtra(callback: (recordId: Int, recordList: ArrayList) -> Unit) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - callback( - intent?.getIntExtra(SeatRecordActivity.RECORD_ID, 0) ?: 0, - intent?.getParcelableArrayListExtra( - SeatRecordActivity.RECORD_LIST, - ReviewUiData::class.java - ) ?: arrayListOf() - ) - } else { - callback( - intent?.getIntExtra(SeatRecordActivity.RECORD_ID, 0) ?: 0, - intent?.getParcelableArrayListExtra(SeatRecordActivity.RECORD_LIST) ?: arrayListOf() - ) - } - } - -} \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordFragment.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordFragment.kt new file mode 100644 index 00000000..5cb8706e --- /dev/null +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordFragment.kt @@ -0,0 +1,82 @@ +package com.depromeet.presentation.seatrecord + +import android.os.Bundle +import android.view.View +import androidx.fragment.app.activityViewModels +import androidx.lifecycle.asLiveData +import com.depromeet.core.base.BindingFragment +import com.depromeet.core.state.UiState +import com.depromeet.domain.entity.response.home.MySeatRecordResponse +import com.depromeet.presentation.R +import com.depromeet.presentation.databinding.ActivitySeatDetailRecordBinding +import com.depromeet.presentation.seatrecord.adapter.TestDetailRecordAdapter +import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class SeatDetailRecordFragment : BindingFragment( + layoutResId = R.layout.activity_seat_detail_record, + bindingInflater = ActivitySeatDetailRecordBinding::inflate +) { + companion object { + const val SEAT_RECORD_TAG = "seatRecord" + } + + private val viewModel: SeatRecordViewModel by activityViewModels() + private lateinit var testDetailRecordAdapter: TestDetailRecordAdapter + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + initView() + initEvent() + initObserver() + + } + + private fun initView() { + setDetailRecordAdapter() + } + + private fun initEvent() { + with(binding) { + fabDetailUp.setOnClickListener { + rvDetailRecord.smoothScrollToPosition(0) + } + } + } + + private fun initObserver() { + viewModel.reviews.asLiveData().observe(viewLifecycleOwner) { state -> + if (state is UiState.Success) { + testDetailRecordAdapter.submitList(state.data.reviews) + } + } + + viewModel.deleteClickedEvent.asLiveData().observe(viewLifecycleOwner) { state -> + if (state) moveConfirmationDialog() + } + } + + private fun setDetailRecordAdapter() { + testDetailRecordAdapter = TestDetailRecordAdapter( + (viewModel.reviews.value as UiState.Success).data.profile + ) + + binding.rvDetailRecord.adapter = testDetailRecordAdapter + + testDetailRecordAdapter.itemMoreClickListener = + object : TestDetailRecordAdapter.OnDetailItemClickListener { + override fun onItemMoreClickListener(item: MySeatRecordResponse.ReviewResponse) { + viewModel.setEditReviewId(item.id) + RecordEditDialog.newInstance(SEAT_RECORD_TAG) + .show(parentFragmentManager, RecordEditDialog.TAG) + } + } + } + + private fun moveConfirmationDialog() { + ConfirmDeleteDialog.newInstance(SEAT_RECORD_TAG) + .show(parentFragmentManager, ConfirmDeleteDialog.TAG) + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DetailRecordAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DetailRecordAdapter.kt index de6d9ae1..1b3cf8c1 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DetailRecordAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/DetailRecordAdapter.kt @@ -8,21 +8,28 @@ import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 +import coil.load +import coil.transform.CircleCropTransformation +import com.depromeet.domain.entity.response.home.MySeatRecordResponse +import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ItemSeatReviewDetailBinding -import com.depromeet.presentation.seatrecord.uiMapper.ReviewUiData import com.depromeet.presentation.seatrecord.uiMapper.toUiKeyword +import com.depromeet.presentation.util.CalendarUtil import com.depromeet.presentation.util.ItemDiffCallback import com.depromeet.presentation.util.applyBoldSpan import com.depromeet.presentation.viewfinder.compose.KeywordFlowRow -class DetailRecordAdapter() : ListAdapter( - ItemDiffCallback( - onItemsTheSame = { oldItem, newItem -> oldItem.id == newItem.id }, - onContentsTheSame = { oldItem, newItem -> oldItem == newItem } - ) -) { +class TestDetailRecordAdapter( + private val myProfile: MySeatRecordResponse.MyProfileResponse, +) : + ListAdapter( + ItemDiffCallback( + onItemsTheSame = { oldItem, newItem -> oldItem.id == newItem.id }, + onContentsTheSame = { oldItem, newItem -> oldItem == newItem } + ) + ) { interface OnDetailItemClickListener { - fun onItemMoreClickListener(item: ReviewUiData) + fun onItemMoreClickListener(item: MySeatRecordResponse.ReviewResponse) } var itemMoreClickListener: OnDetailItemClickListener? = null @@ -39,7 +46,7 @@ class DetailRecordAdapter() : ListAdapter( } override fun onBindViewHolder(holder: ReviewDetailViewHolder, position: Int) { - holder.bind(getItem(position)) + holder.bind(getItem(position), myProfile) holder.binding.ivDetailMore.setOnClickListener { itemMoreClickListener?.onItemMoreClickListener(getItem(position)) } @@ -54,17 +61,20 @@ class ReviewDetailViewHolder( private const val MAX_VISIBLE_CHIPS = 3 } - fun bind(item: ReviewUiData) { + fun bind( + item: MySeatRecordResponse.ReviewResponse, + profile: MySeatRecordResponse.MyProfileResponse, + ) { with(binding) { - //TODO : 서버 데이터 바뀔거니 기억해두기 -// ivDetailProfileImage.load(item.profileImage) { -// transformations(CircleCropTransformation()) -// } -// tvDetailNickname.text = item.nickName -// "Lv.${item.level}".also { tvDetailLevel.text = it } + ivDetailProfileImage.load(profile.profileImage) { + transformations(CircleCropTransformation()) + error(R.drawable.ic_default_profile) + } + tvDetailNickname.text = profile.nickname + "Lv.${profile.level}".also { tvDetailLevel.text = it } tvDetailStadium.text = item.stadiumName - tvDetailBlock.text = item.blockName - tvDetailDate.text = item.date + "${item.sectionName} ${item.blockName}블록".also { tvDetailBlock.text = it } + tvDetailDate.text = CalendarUtil.getFormattedDate(item.date) tvDetailContent.text = item.content initImageViewPager(item.images.map { it.url }) cvDetailKeyword.apply { diff --git a/presentation/src/main/res/layout/activity_seat_detail_record.xml b/presentation/src/main/res/layout/activity_seat_detail_record.xml index a45b4491..2cb90480 100644 --- a/presentation/src/main/res/layout/activity_seat_detail_record.xml +++ b/presentation/src/main/res/layout/activity_seat_detail_record.xml @@ -3,7 +3,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:background="@color/white"> Date: Thu, 25 Jul 2024 13:53:51 +0900 Subject: [PATCH 66/83] =?UTF-8?q?[feature/#29]=20=EC=A2=8C=EC=84=9D?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EB=B7=B0=EB=AA=A8=EB=8D=B8=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C,=20=EC=82=AD=EC=A0=9C,=ED=99=95=EC=9D=B8=20=EB=8B=A4?= =?UTF-8?q?=EC=9D=B4=EC=96=BC=EB=A1=9C=EA=B7=B8=20=EB=8B=A8=EC=9D=BC=20?= =?UTF-8?q?=EB=B7=B0=EB=AA=A8=EB=8D=B8=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/ConfirmDeleteDialog.kt | 19 ++------ .../seatrecord/RecordEditDialog.kt | 18 ++------ .../seatrecord/SeatRecordActivity.kt | 11 +---- .../viewmodel/SeatDetailViewModel.kt | 44 ------------------- .../viewmodel/SeatRecordViewModel.kt | 14 ++---- 5 files changed, 12 insertions(+), 94 deletions(-) delete mode 100644 presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatDetailViewModel.kt diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt index bb3c4e54..4fde4c22 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt @@ -5,12 +5,10 @@ import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.View import android.view.WindowManager -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider +import androidx.fragment.app.activityViewModels import com.depromeet.core.base.BindingDialogFragment import com.depromeet.presentation.R import com.depromeet.presentation.databinding.FragmentConfirmDeleteDialogBinding -import com.depromeet.presentation.seatrecord.viewmodel.SeatDetailViewModel import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel import dagger.hilt.android.AndroidEntryPoint @@ -33,18 +31,12 @@ class ConfirmDeleteDialog : BindingDialogFragment ViewModelProvider(requireActivity())[SeatDetailViewModel::class.java] - SeatRecordActivity.SEAT_RECORD_TAG -> ViewModelProvider(requireActivity())[SeatRecordViewModel::class.java] - else -> throw IllegalArgumentException("알수 없는 뷰모델 태그") - } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -59,14 +51,11 @@ class ConfirmDeleteDialog : BindingDialogFragment (viewModel as SeatDetailViewModel).removeReviewData() - is SeatRecordViewModel -> (viewModel as SeatRecordViewModel).removeReviewData() - else -> throw IllegalArgumentException("알 수 없는 뷰모델") - } + viewModel.removeReviewData() dismiss() } binding.btConfirmCancel.setOnClickListener { + viewModel.cancelDeleteEvent() dismiss() } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt index e152e1a1..4d87551a 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt @@ -2,12 +2,10 @@ package com.depromeet.presentation.seatrecord import android.os.Bundle import android.view.View -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider +import androidx.fragment.app.activityViewModels import com.depromeet.core.base.BindingBottomSheetDialog import com.depromeet.presentation.R import com.depromeet.presentation.databinding.FragmentRecordEditBottomSheetBinding -import com.depromeet.presentation.seatrecord.viewmodel.SeatDetailViewModel import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel import dagger.hilt.android.AndroidEntryPoint @@ -30,19 +28,13 @@ class RecordEditDialog : BindingBottomSheetDialog ViewModelProvider(requireActivity())[SeatDetailViewModel::class.java] - SeatRecordActivity.SEAT_RECORD_TAG -> ViewModelProvider(requireActivity())[SeatRecordViewModel::class.java] - else -> throw IllegalArgumentException("알수 없는 뷰모델 태그") - } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -53,11 +45,7 @@ class RecordEditDialog : BindingBottomSheetDialog (viewModel as SeatDetailViewModel).setDeleteEvent() - is SeatRecordViewModel -> (viewModel as SeatRecordViewModel).setDeleteEvent() - else -> throw IllegalArgumentException("알 수 없는 뷰모델") - } + viewModel.setDeleteEvent() dismiss() } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index c204b37e..2f6488fd 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -1,6 +1,5 @@ package com.depromeet.presentation.seatrecord -import android.content.Intent import android.os.Bundle import android.view.View import android.widget.AdapterView @@ -33,8 +32,6 @@ class SeatRecordActivity : BaseActivity( ) { companion object { const val SEAT_RECORD_TAG = "seatRecord" - const val RECORD_ID = "record_id" - const val RECORD_LIST = "record_list" private const val START_SPACING_DP = 20 private const val BETWEEN_SPACING_DP = 8 } @@ -238,14 +235,8 @@ class SeatRecordActivity : BaseActivity( SeatDetailRecordFragment(), SeatDetailRecordFragment.SEAT_RECORD_TAG ) + addToBackStack(null) } -// Intent( -// this@SeatRecordActivity, -// SeatDetailRecordActivity::class.java -// ).apply { -// putExtra(RECORD_ID, item.id) -// putParcelableArrayListExtra(RECORD_LIST, viewModel.getUiReviewsData()) -// }.let(::startActivity) } override fun onMoreRecordClick(reviewId: Int) { diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatDetailViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatDetailViewModel.kt deleted file mode 100644 index 4ee0c692..00000000 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatDetailViewModel.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.depromeet.presentation.seatrecord.viewmodel - -import androidx.lifecycle.ViewModel -import com.depromeet.presentation.seatrecord.uiMapper.ReviewUiData -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import javax.inject.Inject - -@HiltViewModel -class SeatDetailViewModel @Inject constructor() : ViewModel() { - - private val _uiState = MutableStateFlow(emptyList()) - val uiState = _uiState.asStateFlow() - - private val _deleteClickedEvent = MutableStateFlow(false) - val deleteClickedEvent = _deleteClickedEvent.asStateFlow() - - private val _editReviewId = MutableStateFlow(0) - val editReviewId = _editReviewId.asStateFlow() - - fun setReviewData(id: Int, reviews: List) { - _uiState.value = reviews - } - - fun removeReviewData() { - val currentList = _uiState.value - val updatedList = currentList.filter { review -> - review.id != _editReviewId.value - } - - /** 투두 : 삭제 api 연동 **/ - _uiState.value = updatedList - _deleteClickedEvent.value = false - } - - fun setEditReviewId(id: Int) { - _editReviewId.value = id - } - - fun setDeleteEvent() { - _deleteClickedEvent.value = true - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index bb4b8f71..aeb21efa 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -8,8 +8,6 @@ import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.domain.entity.response.home.ReviewDateResponse import com.depromeet.domain.repository.HomeRepository import com.depromeet.presentation.seatrecord.uiMapper.MonthUiData -import com.depromeet.presentation.seatrecord.uiMapper.ReviewUiData -import com.depromeet.presentation.seatrecord.uiMapper.toUiModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -107,6 +105,10 @@ class SeatRecordViewModel @Inject constructor( _deleteClickedEvent.value = true } + fun cancelDeleteEvent() { + _deleteClickedEvent.value = false + } + fun removeReviewData() { val currentState = reviews.value if (currentState is UiState.Success) { @@ -130,12 +132,4 @@ class SeatRecordViewModel @Inject constructor( } - fun getUiReviewsData(): ArrayList { - val currentState = reviews.value - return if (currentState is UiState.Success) { - ArrayList(currentState.data.reviews.map { it.toUiModel() }) - } else { - arrayListOf() - } - } } \ No newline at end of file From 02363a9dec744f1e943f9cf923c5614b49395690 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:54:39 +0900 Subject: [PATCH 67/83] =?UTF-8?q?[refactor/#29]=20=EC=A2=8C=EC=84=9D=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EA=B4=80=EB=A0=A8=20=ED=95=84=EC=9A=94?= =?UTF-8?q?=EC=97=86=EB=8A=94=20mapper=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/uiMapper/HomeMapper.kt | 71 ------------------- 1 file changed, 71 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt index 63aecf1b..6e1d683e 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/uiMapper/HomeMapper.kt @@ -1,9 +1,7 @@ package com.depromeet.presentation.seatrecord.uiMapper -import android.os.Parcelable import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.presentation.viewfinder.sample.Keyword -import kotlinx.parcelize.Parcelize /** * 리팩토링 예정 @@ -18,35 +16,6 @@ data class MonthUiData( var isClicked: Boolean = false, ) -@Parcelize -data class ReviewUiData( - val id: Int, - val stadiumId: Int, - val stadiumName: String, - val blockId: Int, - val blockName: String, - val seatId: Int, - val rowId: Int, - val seatNumber: Int, - val date: String, - val content: String, - val images: List, - val keywords: List, -) : Parcelable { - @Parcelize - data class ReviewImageUiData( - val id: Int, - val url: String, - ) : Parcelable - - @Parcelize - data class ReviewKeywordUiData( - val id: Int, - val content: String, - val isPositive: Boolean, - ) : Parcelable -} - /** * 우선 Ui Mapper로 임시 처리 추후 관희 flowRow 변경 사항에 따라 수정 예정 */ @@ -56,43 +25,3 @@ fun MySeatRecordResponse.ReviewResponse.ReviewKeywordResponse.toUiKeyword() = type = if (isPositive) 1 else 0, like = 0 ) - -fun ReviewUiData.ReviewKeywordUiData.toUiKeyword() = - Keyword( - message = content, - type = if (isPositive) 1 else 0, - like = 0 - ) - - -fun MySeatRecordResponse.ReviewResponse.toUiModel(): ReviewUiData { - return ReviewUiData( - id = id, - stadiumId = stadiumId, - stadiumName = stadiumName, - blockId = blockId, - blockName = blockName, - seatId = seatId, - rowId = rowId, - seatNumber = seatNumber, - date = date, - content = content, - images = images.map { it.toUiModel() }, - keywords = keywords.map { it.toUiModel() } - ) -} - -fun MySeatRecordResponse.ReviewResponse.ReviewImageResponse.toUiModel(): ReviewUiData.ReviewImageUiData { - return ReviewUiData.ReviewImageUiData( - id = id, - url = url - ) -} - -fun MySeatRecordResponse.ReviewResponse.ReviewKeywordResponse.toUiModel(): ReviewUiData.ReviewKeywordUiData { - return ReviewUiData.ReviewKeywordUiData( - id = id, - content = content, - isPositive = isPositive - ) -} \ No newline at end of file From 5c8c52b30001c8d9e0bef4323935f75e38d96b5f Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 25 Jul 2024 14:10:32 +0900 Subject: [PATCH 68/83] =?UTF-8?q?[fix/#29]=20presignedurl,=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EC=88=98=EC=A0=95=20memberId=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C(=EC=84=9C=EB=B2=84=20=EB=B0=B0=ED=8F=AC=ED=9B=84=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/depromeet/data/datasource/HomeDataSource.kt | 2 -- .../depromeet/data/datasource/remote/HomeDataSourceImpl.kt | 6 ++---- .../main/java/com/depromeet/data/remote/HomeApiService.kt | 6 ++---- .../com/depromeet/data/repository/HomeRepositoryImpl.kt | 6 ++---- .../java/com/depromeet/domain/repository/HomeRepository.kt | 2 -- .../depromeet/presentation/home/ProfileImageUploadDialog.kt | 2 +- .../presentation/home/viewmodel/ProfileEditViewModel.kt | 6 ++---- 7 files changed, 9 insertions(+), 21 deletions(-) diff --git a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt index af711677..81707a21 100644 --- a/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt +++ b/data/src/main/java/com/depromeet/data/datasource/HomeDataSource.kt @@ -20,7 +20,6 @@ interface HomeDataSource { suspend fun postProfileImagePresigned( fileExtension: String, - memberId: Int, ): ResponsePresignedUrlDto suspend fun putProfileImage( @@ -30,7 +29,6 @@ interface HomeDataSource { suspend fun putProfileEdit( requestProfileEditDto: RequestProfileEditDto, - memberId: Int, ): ResponseProfileEditDto suspend fun getDuplicateNickname( diff --git a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt index a93b4c83..06b04e11 100644 --- a/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt +++ b/data/src/main/java/com/depromeet/data/datasource/remote/HomeDataSourceImpl.kt @@ -29,17 +29,16 @@ class HomeDataSourceImpl @Inject constructor( ) } + override suspend fun getBaseballTeamData(): List { return homeApiService.getBaseballTeam() } override suspend fun postProfileImagePresigned( fileExtension: String, - memberId: Int, ): ResponsePresignedUrlDto { return homeApiService.postProfileImagePresigned( RequestFileExtensionDto(fileExtension), - memberId ) } @@ -50,9 +49,8 @@ class HomeDataSourceImpl @Inject constructor( override suspend fun putProfileEdit( requestProfileEditDto: RequestProfileEditDto, - memberId: Int, ): ResponseProfileEditDto { - return homeApiService.putProfileEdit(requestProfileEditDto, memberId) + return homeApiService.putProfileEdit(requestProfileEditDto) } override suspend fun getDuplicateNickname(nickname: String) { diff --git a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt index 04028596..19b12fca 100644 --- a/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt +++ b/data/src/main/java/com/depromeet/data/remote/HomeApiService.kt @@ -32,10 +32,9 @@ interface HomeApiService { @GET("/api/v1/baseball-teams") suspend fun getBaseballTeam(): List - @POST("/api/v1/members/{memberId}/profile/images") + @POST("/api/v1/members/profile/images") suspend fun postProfileImagePresigned( @Body body: RequestFileExtensionDto, - @Path("memberId") memberId: Int, ): ResponsePresignedUrlDto @PUT @@ -44,10 +43,9 @@ interface HomeApiService { @Body image: RequestBody, ) - @PUT("/api/v1/members/{memberId}") + @PUT("/api/v1/members") suspend fun putProfileEdit( @Body body: RequestProfileEditDto, - @Path("memberId") memberId: Int, ): ResponseProfileEditDto @GET("/api/v1/members/duplicatedNickname/{nickname}") diff --git a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt index f70fe182..0cc6fd70 100644 --- a/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt +++ b/data/src/main/java/com/depromeet/data/repository/HomeRepositoryImpl.kt @@ -42,10 +42,9 @@ class HomeRepositoryImpl @Inject constructor( override suspend fun postProfileImagePresigned( fileExtension: String, - memberId: Int, ): Result { return runCatching { - homeDataSource.postProfileImagePresigned(fileExtension, memberId) + homeDataSource.postProfileImagePresigned(fileExtension) .toPresignedUrlResponse() } } @@ -58,10 +57,9 @@ class HomeRepositoryImpl @Inject constructor( override suspend fun putProfileEdit( profileEditRequest: ProfileEditRequest, - memberId: Int, ): Result { return runCatching { - homeDataSource.putProfileEdit(profileEditRequest.toProfileEditRequestDto(), memberId) + homeDataSource.putProfileEdit(profileEditRequest.toProfileEditRequestDto()) .toProfileEditResponse() } } diff --git a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt index 46b691a7..096a71a9 100644 --- a/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt +++ b/domain/src/main/java/com/depromeet/domain/repository/HomeRepository.kt @@ -20,7 +20,6 @@ interface HomeRepository { suspend fun postProfileImagePresigned( fileExtension: String, - memberId: Int, ): Result suspend fun putProfileImage( @@ -30,7 +29,6 @@ interface HomeRepository { suspend fun putProfileEdit( profileEditRequest: ProfileEditRequest, - memberId: Int, ): Result suspend fun getDuplicateNickname( diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt index e3d2acd4..bb5d4a74 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileImageUploadDialog.kt @@ -82,7 +82,7 @@ class ProfileImageUploadDialog() : BindingBottomSheetDialog _presignedUrl.value = UiState.Success(presignedUrl) uploadProfileImage(profileByteArray) @@ -156,8 +155,7 @@ class ProfileEditViewModel @Inject constructor( url = getPresignedUrlOrNull(), nickname = nickname.value, teamId = if (cheerTeam.value == 0) null else cheerTeam.value - ), memberId = 1 - /** memberId ->추후에 메인화면 api 나오면 연동해서 stateflow 업데이트*/ + ) ) .onSuccess { _profileEdit.value = UiState.Success(it) From 4396c9cb72785d30317821935351fbabc4ad83b3 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:33:14 +0900 Subject: [PATCH 69/83] =?UTF-8?q?[fix/#29]=20=ED=99=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EB=82=B4=20=EC=B5=9C=EA=B7=BC=20=EC=8B=9C=EC=95=BC?= =?UTF-8?q?=20=EB=82=B4=EC=97=AD=20API=20=EC=88=98=EC=A0=95=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/home/ResponseRecentReviewDto.kt | 197 ++++++++++++++++-- .../response/home/RecentReviewResponse.kt | 75 ++++++- .../presentation/home/HomeActivity.kt | 35 ++-- .../home/viewmodel/HomeViewModel.kt | 2 +- 4 files changed, 269 insertions(+), 40 deletions(-) diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseRecentReviewDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseRecentReviewDto.kt index f9feb152..7cfcfbc9 100644 --- a/data/src/main/java/com/depromeet/data/model/response/home/ResponseRecentReviewDto.kt +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseRecentReviewDto.kt @@ -6,27 +6,188 @@ import kotlinx.serialization.Serializable @Serializable data class ResponseRecentReviewDto( - @SerialName("totalReviewCount") - val totalReviewCount: Int, - @SerialName("stadiumName") - val stadiumName: String, - @SerialName("date") - val date: String, - @SerialName("reviewImages") - val reviewImages: List, - @SerialName("blockName") - val blockName: String, - @SerialName("seatNumber") - val seatNumber: Long, + @SerialName("review") + val review: ResponseReviewWrapperDto, + @SerialName("reviewCount") + val reviewCount: Int, ) { + @Serializable + data class ResponseReviewWrapperDto( + @SerialName("baseReview") + val baseReview: ResponseReviewDto, + @SerialName("stadiumName") + val stadiumName: String, + @SerialName("sectionName") + val sectionName: String, + @SerialName("blockCode") + val blockCode: String, + ) + + @Serializable + data class ResponseReviewDto( + @SerialName("id") + val id: Int, + @SerialName("member") + val member: ResponseMemberDto, + @SerialName("stadium") + val stadium: ResponseStadiumDto, + @SerialName("section") + val section: ResponseSectionDto, + @SerialName("block") + val block: ResponseBlockDto, + @SerialName("row") + val row: ResponseRowDto, + @SerialName("seat") + val seat: ResponseSeatDto, + @SerialName("dateTime") + val dateTime: String, + @SerialName("content") + val content: String, + @SerialName("images") + val images: List, + @SerialName("keywords") + val keywords: List, + ) + + @Serializable + data class ResponseMemberDto( + @SerialName("profileImage") + val profileImage: String?, + @SerialName("nickname") + val nickname: String, + @SerialName("level") + val level: Int, + ) + + @Serializable + data class ResponseStadiumDto( + @SerialName("id") + val id: Int, + @SerialName("name") + val name: String, + ) + + @Serializable + data class ResponseSectionDto( + @SerialName("id") + val id: Int, + @SerialName("name") + val name: String, + @SerialName("alias") + val alias: String?, + ) + + @Serializable + data class ResponseBlockDto( + @SerialName("id") + val id: Int, + @SerialName("code") + val code: String, + ) + + @Serializable + data class ResponseRowDto( + @SerialName("id") + val id: Int, + @SerialName("number") + val number: Int, + ) + + @Serializable + data class ResponseSeatDto( + @SerialName("id") + val id: Int, + @SerialName("seatNumber") + val seatNumber: Int, + ) + + @Serializable + data class ResponseImageDto( + @SerialName("id") + val id: Int, + @SerialName("url") + val url: String, + ) + + @Serializable + data class ResponseKeywordDto( + @SerialName("id") + val id: Int, + @SerialName("content") + val content: String, + @SerialName("isPositive") + val isPositive: Boolean, + ) + companion object { fun ResponseRecentReviewDto.toRecentReviewResponse() = RecentReviewResponse( - totalReviewCount = totalReviewCount, - stadiumName = stadiumName, - date = date, - reviewImages = reviewImages, - blockName = blockName, + review = review.toReviewWrapperResponse(), + reviewCount = reviewCount + ) + + fun ResponseReviewWrapperDto.toReviewWrapperResponse() = + RecentReviewResponse.ReviewWrapperResponse( + baseReview = baseReview.toReviewResponse(), + stadiumName = stadiumName, + sectionName = sectionName, + blockCode = blockCode + ) + + fun ResponseReviewDto.toReviewResponse() = RecentReviewResponse.ReviewResponse( + id = id, + member = member.toMemberResponse(), + stadium = stadium.toStadiumResponse(), + section = section.toSectionResponse(), + block = block.toBlockResponse(), + row = row.toRowResponse(), + seat = seat.toSeatResponse(), + dateTime = dateTime, + content = content, + images = images.map { it.toImageResponse() }, + keywords = keywords.map { it.toKeywordResponse() } + ) + + fun ResponseMemberDto.toMemberResponse() = RecentReviewResponse.MemberResponse( + profileImage = profileImage, + nickname = nickname, + level = level + ) + + fun ResponseStadiumDto.toStadiumResponse() = RecentReviewResponse.StadiumResponse( + id = id, + name = name + ) + + fun ResponseSectionDto.toSectionResponse() = RecentReviewResponse.SectionResponse( + id = id, + name = name, + alias = alias + ) + + fun ResponseBlockDto.toBlockResponse() = RecentReviewResponse.BlockResponse( + id = id, + code = code + ) + + fun ResponseRowDto.toRowResponse() = RecentReviewResponse.RowResponse( + id = id, + number = number + ) + + fun ResponseSeatDto.toSeatResponse() = RecentReviewResponse.SeatResponse( + id = id, seatNumber = seatNumber ) + + fun ResponseImageDto.toImageResponse() = RecentReviewResponse.ImageResponse( + id = id, + url = url + ) + + fun ResponseKeywordDto.toKeywordResponse() = RecentReviewResponse.KeywordResponse( + id = id, + content = content, + isPositive = isPositive + ) } -} +} \ No newline at end of file diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/RecentReviewResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/RecentReviewResponse.kt index 05cc53e4..3b715a81 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/response/home/RecentReviewResponse.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/RecentReviewResponse.kt @@ -1,10 +1,71 @@ package com.depromeet.domain.entity.response.home data class RecentReviewResponse( - val totalReviewCount : Int = 0, - val stadiumName : String = "", - val date : String = "", - val reviewImages : List = emptyList(), - val blockName : String = "", - val seatNumber : Long = 0 -) + val review: ReviewWrapperResponse, + val reviewCount: Int = 0, +) { + data class ReviewWrapperResponse( + val baseReview: ReviewResponse, + val stadiumName: String = "", + val sectionName: String = "", + val blockCode: String = "", + ) + + data class ReviewResponse( + val id: Int, + val member: MemberResponse = MemberResponse(), + val stadium: StadiumResponse, + val section: SectionResponse, + val block: BlockResponse, + val row: RowResponse, + val seat: SeatResponse, + val dateTime: String = "", + val content: String = "", + val images: List = emptyList(), + val keywords: List = emptyList(), + ) + + data class MemberResponse( + val profileImage: String? = "", + val nickname: String = "", + val level: Int = 0, + ) + + data class StadiumResponse( + val id: Int, + val name: String = "", + ) + + data class SectionResponse( + val id: Int, + val name: String = "", + val alias: String? = "", + ) + + data class BlockResponse( + val id: Int, + val code: String = "", + ) + + data class RowResponse( + val id: Int, + val number: Int = 0, + ) + + data class SeatResponse( + val id: Int, + val seatNumber: Int = 0, + ) + + data class ImageResponse( + val id: Int, + val url: String = "", + ) + + data class KeywordResponse( + val id: Int = 0, + val content: String = "", + val isPositive: Boolean = false, + ) + +} \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt index 8e5dd99b..ace33c10 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt @@ -17,6 +17,7 @@ import com.depromeet.presentation.extension.loadAndClip import com.depromeet.presentation.extension.toast import com.depromeet.presentation.home.viewmodel.HomeViewModel import com.depromeet.presentation.seatrecord.SeatRecordActivity +import com.depromeet.presentation.util.CalendarUtil import com.depromeet.presentation.util.applyBoldAndSizeSpan import dagger.hilt.android.AndroidEntryPoint @@ -90,37 +91,43 @@ class HomeActivity : BaseActivity( } } - private fun updateRecentReview(review: RecentReviewResponse) = with(binding) { + private fun updateRecentReview(data: RecentReviewResponse) = with(binding) { setSpannableString(viewModel.nickname.value, viewModel.reviewCount.value) - tvHomeRecentRecordName.text = review.stadiumName - tvHomeRecentRecordDate.text = review.date //TODO : 여기 바꿔야함 CALENDER UTIL로 + tvHomeRecentRecordName.text = data.review.stadiumName + tvHomeRecentRecordDate.text = CalendarUtil.getFormattedDate(data.review.baseReview.dateTime) sightList.forEachIndexed { index, view -> view.visibility = - if (index == review.reviewImages.size) View.VISIBLE else View.GONE + if (index == data.review.baseReview.images.size) View.VISIBLE else View.GONE } - when (review.reviewImages.size) { + when (data.review.baseReview.images.size) { 0 -> { tvHomeRecentRecordDate.visibility = View.GONE tvHomeRecentRecordName.visibility = View.GONE } 1 -> { - ivHomeRecentOneRecord1.loadAndClip(review.reviewImages[0]) - "${review.blockName}${review.seatNumber}".also { tvHomeRecentOneSection.text = it } + ivHomeRecentOneRecord1.loadAndClip(data.review.baseReview.images[0]) + "${data.review.sectionName} ${data.review.blockCode}블록".also { + tvHomeRecentOneSection.text = it + } } 2 -> { - ivHomeRecentTwoRecord1.loadAndClip(review.reviewImages[0]) - ivHomeRecentTwoRecord2.loadAndClip(review.reviewImages[1]) - "${review.blockName}${review.seatNumber}".also { tvHomeRecentOneSection.text = it } + ivHomeRecentTwoRecord1.loadAndClip(data.review.baseReview.images[0]) + ivHomeRecentTwoRecord2.loadAndClip(data.review.baseReview.images[1]) + "${data.review.sectionName} ${data.review.blockCode}블록".also { + tvHomeRecentOneSection.text = it + } } 3 -> { - ivHomeRecentThreeRecord1.loadAndClip(review.reviewImages[0]) - ivHomeRecentThreeRecord2.loadAndClip(review.reviewImages[1]) - ivHomeRecentThreeRecord3.loadAndClip(review.reviewImages[2]) - "${review.blockName}${review.seatNumber}".also { tvHomeRecentOneSection.text = it } + ivHomeRecentThreeRecord1.loadAndClip(data.review.baseReview.images[0]) + ivHomeRecentThreeRecord2.loadAndClip(data.review.baseReview.images[1]) + ivHomeRecentThreeRecord3.loadAndClip(data.review.baseReview.images[2]) + "${data.review.sectionName} ${data.review.blockCode}블록".also { + tvHomeRecentOneSection.text = it + } } else -> {} diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt index 1999dacf..4a9fdb36 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt @@ -49,7 +49,7 @@ class HomeViewModel @Inject constructor( val reviewResult = reviewDeferred.await() reviewResult.onSuccess { _recentReview.value = UiState.Success(it) - reviewCount.value = it.totalReviewCount + reviewCount.value = it.reviewCount }.onFailure { _recentReview.value = UiState.Failure(it.message ?: "실패") } From 28a9ebb9249490ef797b3c4e6c569b61e2d21c70 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:49:21 +0900 Subject: [PATCH 70/83] =?UTF-8?q?[feature/#29]=20=ED=99=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=95=A1=ED=8B=B0=EB=B9=84=ED=8B=B0=EA=B0=84=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=9D=B4=EB=8F=99=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/home/HomeActivity.kt | 63 +++++++++++++------ .../src/main/res/layout/activity_home.xml | 4 +- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt index ace33c10..b7d2e610 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt @@ -16,9 +16,11 @@ import com.depromeet.presentation.databinding.ActivityHomeBinding import com.depromeet.presentation.extension.loadAndClip import com.depromeet.presentation.extension.toast import com.depromeet.presentation.home.viewmodel.HomeViewModel +import com.depromeet.presentation.seatReview.ReviewActivity import com.depromeet.presentation.seatrecord.SeatRecordActivity import com.depromeet.presentation.util.CalendarUtil import com.depromeet.presentation.util.applyBoldAndSizeSpan +import com.depromeet.presentation.viewfinder.StadiumActivity import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -51,13 +53,26 @@ class HomeActivity : BaseActivity( } private fun initView() { - binding.clMainSight.clipToOutline = true + binding.clMainFindSight.clipToOutline = true } - private fun initEvent() { - binding.ivHomeProfile.setOnClickListener { navigateToProfileEditActivity() } - binding.ibHomeEdit.setOnClickListener { navigateToProfileEditActivity() } - binding.clHomeSightRecord.setOnClickListener { navigateToSeatRecordActivity() } + private fun initEvent() = with(binding) { + + /** 프로필 수정 */ + ivHomeProfile.setOnClickListener { navigateToProfileEditActivity() } + ibHomeEdit.setOnClickListener { navigateToProfileEditActivity() } + /** 내 시야 기록 */ + clHomeSightRecord.setOnClickListener { navigateToSeatRecordActivity() } + tvHomeMore.setOnClickListener { navigateToSeatRecordActivity() } + clHomeOneRecord.setOnClickListener { navigateToSeatRecordActivity() } + clHomeTwoRecord.setOnClickListener { navigateToSeatRecordActivity() } + clHomeThreeRecord.setOnClickListener { navigateToSeatRecordActivity() } + /** 시야후기 등록*/ + clHomeRegisterSight.setOnClickListener { navigateToReviewActivity() } + clHomeNoRecord.setOnClickListener { navigateToReviewActivity() } + /** 시야 찾기 */ + clMainFindSight.setOnClickListener { navigateToStadiumActivity() } + } private fun initObserver() { @@ -148,21 +163,6 @@ class HomeActivity : BaseActivity( } - private fun navigateToProfileEditActivity() { - val currentState = viewModel.profile.value - - if (currentState is UiState.Success) { - Intent(this, ProfileEditActivity::class.java).apply { - with(currentState.data) { - putExtra(PROFILE_NAME, this.nickname) - putExtra(PROFILE_IMAGE, this.profileImage) - putExtra(PROFILE_CHEER_TEAM, this.teamId) - } - }.let(::startActivity) - } - - } - private fun setSpannableString( nickName: String, writeCount: Int, @@ -181,8 +181,31 @@ class HomeActivity : BaseActivity( binding.tvHomeSightChance.text = spannableBuilder } + + private fun navigateToProfileEditActivity() { + val currentState = viewModel.profile.value + + if (currentState is UiState.Success) { + Intent(this, ProfileEditActivity::class.java).apply { + with(currentState.data) { + putExtra(PROFILE_NAME, this.nickname) + putExtra(PROFILE_IMAGE, this.profileImage) + putExtra(PROFILE_CHEER_TEAM, this.teamId) + } + }.let(::startActivity) + } + + } + private fun navigateToSeatRecordActivity() { Intent(this, SeatRecordActivity::class.java).apply { startActivity(this) } } + private fun navigateToReviewActivity() { + Intent(this, ReviewActivity::class.java).apply { startActivity(this) } + } + + private fun navigateToStadiumActivity() { + Intent(this, StadiumActivity::class.java).apply { startActivity(this) } + } } \ No newline at end of file diff --git a/presentation/src/main/res/layout/activity_home.xml b/presentation/src/main/res/layout/activity_home.xml index 77a0d35f..9265b00f 100644 --- a/presentation/src/main/res/layout/activity_home.xml +++ b/presentation/src/main/res/layout/activity_home.xml @@ -114,7 +114,7 @@ tools:src="@drawable/ic_lg_team" /> + app:layout_constraintTop_toBottomOf="@id/cl_main_find_sight"> Date: Thu, 25 Jul 2024 16:45:52 +0900 Subject: [PATCH 71/83] =?UTF-8?q?[fix/#29]=20=ED=99=88,=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=88=98=EC=A0=95,=EC=8B=9C=EC=95=BC=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seatrecord/adapter/SeatImageAdapter.kt | 5 ++--- .../src/main/res/layout/activity_home.xml | 12 +++++++--- .../main/res/layout/item_baseball_team.xml | 22 +++++++++++-------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/SeatImageAdapter.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/SeatImageAdapter.kt index db7abdf1..293d7eb7 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/SeatImageAdapter.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/adapter/SeatImageAdapter.kt @@ -5,9 +5,8 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import coil.load -import coil.size.Scale import com.depromeet.presentation.databinding.ItemSeatImageBinding +import com.depromeet.presentation.extension.loadAndClip import com.depromeet.presentation.util.ItemDiffCallback class SeatImageAdapter : ListAdapter( @@ -35,6 +34,6 @@ class SeatImageViewHolder( private val binding: ItemSeatImageBinding, ) : RecyclerView.ViewHolder(binding.root) { fun bind(item: String) { - binding.ivTest.load(item) { scale(Scale.FILL) } + binding.ivTest.loadAndClip(item) } } \ No newline at end of file diff --git a/presentation/src/main/res/layout/activity_home.xml b/presentation/src/main/res/layout/activity_home.xml index 9265b00f..288508dd 100644 --- a/presentation/src/main/res/layout/activity_home.xml +++ b/presentation/src/main/res/layout/activity_home.xml @@ -175,7 +175,7 @@ android:layout_height="wrap_content" android:layout_marginTop="24dp" android:background="@drawable/rect_white_fill_top20" - android:paddingBottom="80dp" + android:paddingBottom="60dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -183,11 +183,14 @@ @@ -235,12 +238,15 @@ + android:background="@drawable/rect_gray100_line_10"> From 73500c484b841d7864dab846ec3d5a0dd692e9c9 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 25 Jul 2024 18:45:30 +0900 Subject: [PATCH 72/83] =?UTF-8?q?[fix/#29]=20=EA=B3=B5=EC=9C=A0=20?= =?UTF-8?q?=EB=B7=B0=EB=AA=A8=EB=8D=B8=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20?= =?UTF-8?q?=EB=8B=A4=EC=9D=B4=EC=96=BC=EB=A1=9C=EA=B7=B8=20=EB=91=90?= =?UTF-8?q?=EA=B0=9C=20=EB=9C=A8=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/seatrecord/RecordEditDialog.kt | 10 +++++++++- .../seatrecord/SeatDetailRecordFragment.kt | 3 ++- .../seatrecord/SeatRecordActivity.kt | 3 ++- .../seatrecord/viewmodel/SeatRecordViewModel.kt | 16 +++++++++++----- .../src/main/res/layout/item_recent_record.xml | 5 ++--- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt index 4d87551a..49c387bd 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/RecordEditDialog.kt @@ -6,6 +6,7 @@ import androidx.fragment.app.activityViewModels import com.depromeet.core.base.BindingBottomSheetDialog import com.depromeet.presentation.R import com.depromeet.presentation.databinding.FragmentRecordEditBottomSheetBinding +import com.depromeet.presentation.seatrecord.viewmodel.DeleteUi import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel import dagger.hilt.android.AndroidEntryPoint @@ -29,6 +30,7 @@ class RecordEditDialog : BindingBottomSheetDialog - if (state) moveConfirmationDialog() + if (state == DeleteUi.SEAT_DETAIL) moveConfirmationDialog() } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 2f6488fd..b1736ac3 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -21,6 +21,7 @@ import com.depromeet.presentation.seatrecord.adapter.LinearSpacingItemDecoration import com.depromeet.presentation.seatrecord.adapter.MonthRecordAdapter import com.depromeet.presentation.seatrecord.uiMapper.MonthReviewData import com.depromeet.presentation.seatrecord.uiMapper.MonthUiData +import com.depromeet.presentation.seatrecord.viewmodel.DeleteUi import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel import com.depromeet.presentation.util.CalendarUtil import dagger.hilt.android.AndroidEntryPoint @@ -127,7 +128,7 @@ class SeatRecordActivity : BaseActivity( private fun observeEvents() { viewModel.deleteClickedEvent.asLiveData().observe(this) { state -> - if (state) moveConfirmationDialog() + if (state == DeleteUi.SEAT_RECORD) moveConfirmationDialog() } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index aeb21efa..a62b6f8d 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -33,7 +33,7 @@ class SeatRecordViewModel @Inject constructor( private val _selectedYear = MutableStateFlow(0) val selectedYear = _selectedYear.asStateFlow() - private val _deleteClickedEvent = MutableStateFlow(false) + private val _deleteClickedEvent = MutableStateFlow(DeleteUi.NONE) val deleteClickedEvent = _deleteClickedEvent.asStateFlow() private val _editReviewId = MutableStateFlow(0) @@ -101,12 +101,12 @@ class SeatRecordViewModel @Inject constructor( _editReviewId.value = id } - fun setDeleteEvent() { - _deleteClickedEvent.value = true + fun setDeleteEvent(deleteUi: DeleteUi) { + _deleteClickedEvent.value = deleteUi } fun cancelDeleteEvent() { - _deleteClickedEvent.value = false + _deleteClickedEvent.value = DeleteUi.NONE } fun removeReviewData() { @@ -127,9 +127,15 @@ class SeatRecordViewModel @Inject constructor( Timber.d("삭제 실패 : $it") } } - _deleteClickedEvent.value = false + _deleteClickedEvent.value = DeleteUi.NONE } } +} + +enum class DeleteUi { + NONE, + SEAT_RECORD, + SEAT_DETAIL } \ No newline at end of file diff --git a/presentation/src/main/res/layout/item_recent_record.xml b/presentation/src/main/res/layout/item_recent_record.xml index 1b999586..d6df2e99 100644 --- a/presentation/src/main/res/layout/item_recent_record.xml +++ b/presentation/src/main/res/layout/item_recent_record.xml @@ -14,17 +14,16 @@ android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - tools:text="12" /> + tools:text="1" /> From e6e97cb1d646fab4acd56d868cfebc4825efcc07 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 25 Jul 2024 20:41:30 +0900 Subject: [PATCH 73/83] =?UTF-8?q?[fix/#29]=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20response=20=ED=95=84=EB=93=9C=20=EA=B0=92?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/model/response/home/ResponseDeleteReviewDto.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseDeleteReviewDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseDeleteReviewDto.kt index dc4db421..c8a591d4 100644 --- a/data/src/main/java/com/depromeet/data/model/response/home/ResponseDeleteReviewDto.kt +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseDeleteReviewDto.kt @@ -6,7 +6,7 @@ import kotlinx.serialization.Serializable @Serializable data class ResponseDeleteReviewDto( - @SerialName("deleteReviewId") + @SerialName("deletedReviewId") val deleteReviewId: Int, ) { companion object { From d46df541627cfcafdc4a2ed0143000e2f918469d Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 25 Jul 2024 21:16:17 +0900 Subject: [PATCH 74/83] =?UTF-8?q?[fix/#29]=20S3=20URL=20=EB=B6=84=EA=B8=B0?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EB=B0=8F=20=EC=97=94=EB=93=9C=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20true=20=EC=9E=84=EC=8B=9C=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/intercepter/AuthInterceptor.kt | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/data/src/main/java/com/depromeet/data/intercepter/AuthInterceptor.kt b/data/src/main/java/com/depromeet/data/intercepter/AuthInterceptor.kt index 85c32d87..f7cd5e9c 100644 --- a/data/src/main/java/com/depromeet/data/intercepter/AuthInterceptor.kt +++ b/data/src/main/java/com/depromeet/data/intercepter/AuthInterceptor.kt @@ -2,7 +2,6 @@ package com.depromeet.data.intercepter import com.depromeet.domain.preference.SharedPreference import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.sync.Mutex import okhttp3.Interceptor import okhttp3.Request import okhttp3.Response @@ -17,7 +16,10 @@ class AuthInterceptor @Inject constructor( override fun intercept(chain: Interceptor.Chain): Response { val originalRequest = chain.request() - if (!shouldRequestAuthenticatedHeaders(originalRequest.url.encodedPath)) { + if (!shouldRequestAuthenticatedHeaders(originalRequest.url.encodedPath) || urlIsS3( + originalRequest.url.toString() + ) + ) { return chain.proceed(originalRequest) } @@ -36,13 +38,23 @@ class AuthInterceptor @Inject constructor( return response } + private fun urlIsS3(url: String): Boolean { + /** S3에서는 Authrization(accesstoken)을 포함시키면 안되기 때문에 넣어놨는데 추후 aws로 옮기면 다시 수정해야함!*/ + return url.contains("spot-image-bucket.kr.object.ncloudstorage.com") + } + + private fun shouldRequestAuthenticatedHeaders(encodedPath: String) = when (encodedPath) { - "/api/v1/members" -> false + "/api/v1/members" -> true // TODO : 프로필 수정과 URL이 겹쳐서 수정했습니다. "/api/v1/members/{accessToken}" -> false //TODO 추 후 변경 필요 else -> true } - private fun proceedWithAuthorizationHeader(chain: Interceptor.Chain, request: Request, token: String): Response { + private fun proceedWithAuthorizationHeader( + chain: Interceptor.Chain, + request: Request, + token: String, + ): Response { val newRequest = request.newBuilder() .addHeader("Authorization", token) .build() From a3732fe0ad5b52cebbee294a6d00ece1652b0ed5 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Thu, 25 Jul 2024 21:56:15 +0900 Subject: [PATCH 75/83] =?UTF-8?q?[fix/#29]=20=EB=82=B4=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20response=20teamId=20=EC=B6=94=EA=B0=80,=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=EC=88=98=EC=A0=95=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EC=B2=98=EB=A6=AC=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/model/response/home/ResponseProfileDto.kt | 4 +++- .../domain/entity/response/home/ProfileResponse.kt | 2 +- .../com/depromeet/presentation/home/ProfileEditActivity.kt | 2 ++ .../presentation/home/viewmodel/ProfileEditViewModel.kt | 6 ++++-- presentation/src/main/res/layout/activity_home.xml | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt index 39ebcfca..67d3e14f 100644 --- a/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseProfileDto.kt @@ -6,7 +6,8 @@ import kotlinx.serialization.Serializable @Serializable data class ResponseProfileDto( - //TODO : 서버에서 팀 아이디 받아와서 넘겨줘야함 + @SerialName("teamId") + val teamId : Int, @SerialName("profileImageUrl") val profileImageUrl: String?, @SerialName("nickname") @@ -20,6 +21,7 @@ data class ResponseProfileDto( ) { companion object { fun ResponseProfileDto.toProfileResponse() = ProfileResponse( + teamId = teamId, profileImage = profileImageUrl ?: "", nickname = nickname, level = level, diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt index 088eae2c..e48ff839 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/ProfileResponse.kt @@ -1,7 +1,7 @@ package com.depromeet.domain.entity.response.home data class ProfileResponse( - val teamId : Int = 0, // TODO : 서버에서 내려주는거 확인하고 투두 지우기 + val teamId : Int = 0, val profileImage : String = "", val nickname :String = "", val level : Int = 0, diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index 44675a8a..286e09be 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -24,6 +24,7 @@ import com.depromeet.presentation.home.viewmodel.ProfileEvents import com.depromeet.presentation.login.viewmodel.NicknameInputState import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch +import timber.log.Timber @AndroidEntryPoint class ProfileEditActivity : BaseActivity( @@ -49,6 +50,7 @@ class ProfileEditActivity : BaseActivity( private fun initView() { getDataExtra { name, image, cheerTeam -> viewModel.initProfile(name, image, cheerTeam) + Timber.d("test = $name /// $image /// $cheerTeam") binding.etProfileEditNickname.setText(name) } setCheerTeamList() diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt index a6f4e677..e9305fe1 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt @@ -166,11 +166,13 @@ class ProfileEditViewModel @Inject constructor( } } - private fun getPresignedUrlOrNull(): String? { + private fun getPresignedUrlOrNull(): String { val currentState = presignedUrl.value return if (currentState is UiState.Success) { removeQueryParameters(currentState.data.presignedUrl) - } else null + } else { + profileImage.value + } } private fun removeQueryParameters(url: String): String { diff --git a/presentation/src/main/res/layout/activity_home.xml b/presentation/src/main/res/layout/activity_home.xml index 288508dd..ea7e64ea 100644 --- a/presentation/src/main/res/layout/activity_home.xml +++ b/presentation/src/main/res/layout/activity_home.xml @@ -103,7 +103,7 @@ Date: Fri, 26 Jul 2024 00:13:50 +0900 Subject: [PATCH 76/83] =?UTF-8?q?[fix/#29]=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=84=A0=ED=83=9D=20=ED=9B=84=20=ED=99=88=ED=99=94=EB=A9=B4?= =?UTF-8?q?=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A0=84=EB=8B=AC,=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=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 --- .../request/home/RequestProfileEditDto.kt | 6 ++--- .../entity/request/home/ProfileEditRequest.kt | 6 ++--- .../presentation/home/HomeActivity.kt | 24 +++++++++++++++++-- .../presentation/home/ProfileEditActivity.kt | 20 +++++++++++++--- .../home/viewmodel/HomeViewModel.kt | 11 +++++++++ .../home/viewmodel/ProfileEditViewModel.kt | 15 +++++++----- 6 files changed, 65 insertions(+), 17 deletions(-) diff --git a/data/src/main/java/com/depromeet/data/model/request/home/RequestProfileEditDto.kt b/data/src/main/java/com/depromeet/data/model/request/home/RequestProfileEditDto.kt index 21cdaa70..5ce92741 100644 --- a/data/src/main/java/com/depromeet/data/model/request/home/RequestProfileEditDto.kt +++ b/data/src/main/java/com/depromeet/data/model/request/home/RequestProfileEditDto.kt @@ -15,9 +15,9 @@ data class RequestProfileEditDto( ) { companion object { fun ProfileEditRequest.toProfileEditRequestDto() = RequestProfileEditDto( - profileImage = url, - nickname = nickname, - teamId = teamId + profileImage = url.ifEmpty { null }, + nickname = nickname.ifEmpty { null }, + teamId = teamId.takeIf { it !=0 } ) } } \ No newline at end of file diff --git a/domain/src/main/java/com/depromeet/domain/entity/request/home/ProfileEditRequest.kt b/domain/src/main/java/com/depromeet/domain/entity/request/home/ProfileEditRequest.kt index 4b514a80..d574239f 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/request/home/ProfileEditRequest.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/request/home/ProfileEditRequest.kt @@ -1,7 +1,7 @@ package com.depromeet.domain.entity.request.home data class ProfileEditRequest( - val url : String ?= null, - val nickname : String ?= null, - val teamId : Int ?= null, + val url : String = "", + val nickname : String = "", + val teamId : Int = 0, ) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt index b7d2e610..75ae6f8d 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt @@ -1,9 +1,11 @@ package com.depromeet.presentation.home +import android.app.Activity import android.content.Intent import android.os.Bundle import android.text.SpannableStringBuilder import android.view.View +import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.lifecycle.asLiveData import coil.load @@ -43,6 +45,21 @@ class HomeActivity : BaseActivity( ) } + private val editProfileLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (result.resultCode == Activity.RESULT_OK) { + val data = result.data + val nickname = data?.getStringExtra(ProfileEditActivity.PROFILE_NAME) ?: "" + val profileImage = data?.getStringExtra(ProfileEditActivity.PROFILE_IMAGE) ?: "" + val teamId = data?.getIntExtra(ProfileEditActivity.PROFILE_CHEER_TEAM, 0) ?: 0 + val teamIdUrl = + data?.getStringExtra(ProfileEditActivity.PROFILE_CHEER_TEAM_URL) ?: "" + + viewModel.updateTest(nickname, profileImage, teamId, teamIdUrl) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) viewModel.getInformation() @@ -56,6 +73,7 @@ class HomeActivity : BaseActivity( binding.clMainFindSight.clipToOutline = true } + private fun initEvent() = with(binding) { /** 프로필 수정 */ @@ -185,14 +203,16 @@ class HomeActivity : BaseActivity( private fun navigateToProfileEditActivity() { val currentState = viewModel.profile.value + (Intent(this, ProfileEditActivity::class.java)) + if (currentState is UiState.Success) { - Intent(this, ProfileEditActivity::class.java).apply { + editProfileLauncher.launch(Intent(this, ProfileEditActivity::class.java).apply { with(currentState.data) { putExtra(PROFILE_NAME, this.nickname) putExtra(PROFILE_IMAGE, this.profileImage) putExtra(PROFILE_CHEER_TEAM, this.teamId) } - }.let(::startActivity) + }) } } diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index 286e09be..83b55b7e 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -1,5 +1,7 @@ package com.depromeet.presentation.home +import android.app.Activity +import android.content.Intent import android.os.Bundle import android.text.Editable import android.view.View @@ -24,7 +26,6 @@ import com.depromeet.presentation.home.viewmodel.ProfileEvents import com.depromeet.presentation.login.viewmodel.NicknameInputState import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch -import timber.log.Timber @AndroidEntryPoint class ProfileEditActivity : BaseActivity( @@ -33,6 +34,10 @@ class ProfileEditActivity : BaseActivity( companion object { private const val GRID_SPAN_COUNT = 2 private const val GRID_SPACING = 40 + const val PROFILE_NAME = "profile_name" + const val PROFILE_IMAGE = "profile_image" + const val PROFILE_CHEER_TEAM = "profile_cheer_team" + const val PROFILE_CHEER_TEAM_URL = "profile_cheer_team_url" } private lateinit var adapter: BaseballTeamAdapter @@ -50,7 +55,6 @@ class ProfileEditActivity : BaseActivity( private fun initView() { getDataExtra { name, image, cheerTeam -> viewModel.initProfile(name, image, cheerTeam) - Timber.d("test = $name /// $image /// $cheerTeam") binding.etProfileEditNickname.setText(name) } setCheerTeamList() @@ -73,6 +77,16 @@ class ProfileEditActivity : BaseActivity( observeChange() } + private fun saveProfile() { + val resultIntent = Intent().apply { + putExtra(PROFILE_NAME, viewModel.nickname.value) + putExtra(PROFILE_IMAGE, viewModel.getPresignedUrlOrProfileImage()) + putExtra(PROFILE_CHEER_TEAM, viewModel.cheerTeam.value) + putExtra(PROFILE_CHEER_TEAM_URL, viewModel.getTeamUrl()) + } + setResult(Activity.RESULT_OK, resultIntent) + finish() + } private fun setCheerTeamList() { adapter = BaseballTeamAdapter() @@ -177,7 +191,7 @@ class ProfileEditActivity : BaseActivity( viewModel.profileEdit.asLiveData().observe(this) { state -> when (state) { is UiState.Success -> { - finish() + saveProfile() } is UiState.Failure -> { diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt index 4a9fdb36..e5ca5ab9 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/HomeViewModel.kt @@ -55,4 +55,15 @@ class HomeViewModel @Inject constructor( } } } + + fun updateTest(name: String, image: String, cheerTeam: Int, cheerTeamUrl: String) { + _profile.value = UiState.Success( + (_profile.value as UiState.Success).data.copy( + nickname = name, + profileImage = image, + teamId = cheerTeam, + teamImage = cheerTeamUrl + ) + ) + } } \ No newline at end of file diff --git a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt index e9305fe1..a29555b5 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/viewmodel/ProfileEditViewModel.kt @@ -132,9 +132,7 @@ class ProfileEditViewModel @Inject constructor( currentState.data.presignedUrl, profileByteArray ) - .onSuccess { - - } + .onSuccess {} .onFailure { _events.emit(ProfileEvents.ShowSnackMessage("프로필 이미지 업로드에 실패하였습니다\n다시 시도해주세요~")) setProfileImage(initialProfileImage) @@ -152,9 +150,9 @@ class ProfileEditViewModel @Inject constructor( homeRepository.putProfileEdit( ProfileEditRequest( - url = getPresignedUrlOrNull(), + url = getPresignedUrlOrProfileImage(), nickname = nickname.value, - teamId = if (cheerTeam.value == 0) null else cheerTeam.value + teamId = cheerTeam.value ) ) .onSuccess { @@ -166,7 +164,7 @@ class ProfileEditViewModel @Inject constructor( } } - private fun getPresignedUrlOrNull(): String { + fun getPresignedUrlOrProfileImage(): String { val currentState = presignedUrl.value return if (currentState is UiState.Success) { removeQueryParameters(currentState.data.presignedUrl) @@ -175,6 +173,11 @@ class ProfileEditViewModel @Inject constructor( } } + fun getTeamUrl() : String { + if (cheerTeam.value == 0) return "" + return (team.value as UiState.Success).data.first { it.isClicked }.logo + } + private fun removeQueryParameters(url: String): String { val uri = Uri.parse(url) return uri.buildUpon().clearQuery().build().toString() From 91cec1bfc5a2bfab9b21a512576643dbd87409c6 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:21:00 +0900 Subject: [PATCH 77/83] =?UTF-8?q?[fix/#29]=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=20=EB=8B=A4=EC=9D=B4=EC=96=BC=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=20=EC=95=88=EB=9C=A8=EB=8A=94=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/seatrecord/ConfirmDeleteDialog.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt index 4fde4c22..4190d184 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/ConfirmDeleteDialog.kt @@ -1,5 +1,6 @@ package com.depromeet.presentation.seatrecord +import android.content.DialogInterface import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle @@ -61,5 +62,10 @@ class ConfirmDeleteDialog : BindingDialogFragment Date: Fri, 26 Jul 2024 00:44:53 +0900 Subject: [PATCH 78/83] =?UTF-8?q?[feature/#29]=20=ED=99=88=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=B7=B0=20=ED=81=B4=EB=A6=AD=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=EB=84=88=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../depromeet/presentation/home/HomeActivity.kt | 2 ++ .../seatrecord/SeatDetailRecordFragment.kt | 14 ++++++++++++++ .../presentation/seatrecord/SeatRecordActivity.kt | 9 +++++++++ 3 files changed, 25 insertions(+) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt index 75ae6f8d..98280b5a 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt @@ -91,6 +91,8 @@ class HomeActivity : BaseActivity( /** 시야 찾기 */ clMainFindSight.setOnClickListener { navigateToStadiumActivity() } + ibHomeSetting.setOnClickListener { /** 셋팅 이동 **/ } + } private fun initObserver() { diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordFragment.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordFragment.kt index a9572277..b55e8e7c 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordFragment.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatDetailRecordFragment.kt @@ -1,5 +1,6 @@ package com.depromeet.presentation.seatrecord +import android.content.Intent import android.os.Bundle import android.view.View import androidx.fragment.app.activityViewModels @@ -9,6 +10,7 @@ import com.depromeet.core.state.UiState import com.depromeet.domain.entity.response.home.MySeatRecordResponse import com.depromeet.presentation.R import com.depromeet.presentation.databinding.ActivitySeatDetailRecordBinding +import com.depromeet.presentation.seatReview.ReviewActivity import com.depromeet.presentation.seatrecord.adapter.TestDetailRecordAdapter import com.depromeet.presentation.seatrecord.viewmodel.DeleteUi import com.depromeet.presentation.seatrecord.viewmodel.SeatRecordViewModel @@ -44,6 +46,18 @@ class SeatDetailRecordFragment : BindingFragment( fabRecordUp.setOnClickListener { ssvRecord.smoothScrollTo(0, 0) } + fabRecordPlus.setOnClickListener { + Intent(this@SeatRecordActivity, ReviewActivity::class.java).apply { + startActivity( + this + ) + } + } } } From 3995550e0bc2b14a8e93a920a8053cc322fd6104 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:51:03 +0900 Subject: [PATCH 79/83] =?UTF-8?q?[fix/#29]=20=EC=9B=94=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=EC=8B=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=ED=98=B8=EC=B6=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/seatrecord/viewmodel/SeatRecordViewModel.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt index a62b6f8d..582ab9f5 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/viewmodel/SeatRecordViewModel.kt @@ -94,7 +94,6 @@ class SeatRecordViewModel @Inject constructor( _months.value = months.value.map { it.copy(isClicked = it.month == month) } - getSeatRecords() } fun setEditReviewId(id: Int) { From 9860b075b7b462bfc94ec70a4a318e6051452168 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:52:52 +0900 Subject: [PATCH 80/83] =?UTF-8?q?[feature/#29]=20data,domain=20=EB=82=B4?= =?UTF-8?q?=20=EC=8B=9C=EC=95=BC=EA=B8=B0=EB=A1=9D=20response=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/model/response/home/ResponseMySeatRecordDto.kt | 3 +++ .../domain/entity/request/home/MySeatRecordRequest.kt | 2 +- .../domain/entity/response/home/MySeatRecordResponse.kt | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt index 83c6d265..f3e8150b 100644 --- a/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt +++ b/data/src/main/java/com/depromeet/data/model/response/home/ResponseMySeatRecordDto.kt @@ -172,6 +172,9 @@ data class ResponseMySeatRecordDto( totalPages = totalPages, number = number, size = size, + first = first, + last = last, + isLoading = false ) private fun ResponseMemberDto.toMyProfileResponse() = diff --git a/domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt b/domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt index ad35190e..32f08859 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/request/home/MySeatRecordRequest.kt @@ -2,7 +2,7 @@ package com.depromeet.domain.entity.request.home data class MySeatRecordRequest( val page: Int ?= null, - val size: Int ?= 50, + val size: Int ?= 10, val year: Int ?= 2024, val month: Int ?= null, ) diff --git a/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt index bbe6852a..fa3ed706 100644 --- a/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt +++ b/domain/src/main/java/com/depromeet/domain/entity/response/home/MySeatRecordResponse.kt @@ -7,6 +7,9 @@ data class MySeatRecordResponse( val totalPages: Int = 0, val number: Int = 0, val size: Int = 0, + val first : Boolean = true, + val last : Boolean = true, + val isLoading : Boolean = true, ) { data class MyProfileResponse( val userId: Int = 0, From 430ef7cfd72dea2776214cab3e9356b1621ac087 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Fri, 26 Jul 2024 17:23:00 +0900 Subject: [PATCH 81/83] =?UTF-8?q?[fix/#29]=20=EB=B6=88=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20intent=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/depromeet/presentation/home/HomeActivity.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt index 98280b5a..172a6c69 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt @@ -204,9 +204,6 @@ class HomeActivity : BaseActivity( private fun navigateToProfileEditActivity() { val currentState = viewModel.profile.value - - (Intent(this, ProfileEditActivity::class.java)) - if (currentState is UiState.Success) { editProfileLauncher.launch(Intent(this, ProfileEditActivity::class.java).apply { with(currentState.data) { From 6b14819c39ccfa13c7f0fb53346cb57ffd702735 Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Sat, 27 Jul 2024 00:02:02 +0900 Subject: [PATCH 82/83] =?UTF-8?q?[fix/#29]=20S3=20url=20local=20properties?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/build.gradle.kts | 7 +++++++ .../java/com/depromeet/data/intercepter/AuthInterceptor.kt | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 048e2cf5..559e0061 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -1,3 +1,5 @@ +import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties + plugins { id("com.android.library") id("org.jetbrains.kotlin.android") @@ -14,6 +16,7 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") + buildConfigField("String", "S3_URL", getApiKey("s3.base.url")) } buildTypes { @@ -37,6 +40,10 @@ android { } } +fun getApiKey(propertyKey: String): String { + return gradleLocalProperties(rootDir).getProperty(propertyKey) +} + dependencies { implementation(project(":domain")) KotlinDependencies.run { diff --git a/data/src/main/java/com/depromeet/data/intercepter/AuthInterceptor.kt b/data/src/main/java/com/depromeet/data/intercepter/AuthInterceptor.kt index f7cd5e9c..e838eb02 100644 --- a/data/src/main/java/com/depromeet/data/intercepter/AuthInterceptor.kt +++ b/data/src/main/java/com/depromeet/data/intercepter/AuthInterceptor.kt @@ -1,5 +1,6 @@ package com.depromeet.data.intercepter +import com.depromeet.data.BuildConfig.S3_URL import com.depromeet.domain.preference.SharedPreference import kotlinx.coroutines.runBlocking import okhttp3.Interceptor @@ -39,8 +40,7 @@ class AuthInterceptor @Inject constructor( } private fun urlIsS3(url: String): Boolean { - /** S3에서는 Authrization(accesstoken)을 포함시키면 안되기 때문에 넣어놨는데 추후 aws로 옮기면 다시 수정해야함!*/ - return url.contains("spot-image-bucket.kr.object.ncloudstorage.com") + return url.contains(S3_URL) } From 9198c58570afb363a6870117cc062ea061a8b89f Mon Sep 17 00:00:00 2001 From: BENDENG1 <76191161+BENDENG1@users.noreply.github.com> Date: Sat, 27 Jul 2024 13:58:26 +0900 Subject: [PATCH 83/83] =?UTF-8?q?[refactor/#29]=20visibility=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20view=20import=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../depromeet/presentation/home/HomeActivity.kt | 8 +++++--- .../presentation/home/ProfileEditActivity.kt | 7 ++++--- .../presentation/seatrecord/SeatRecordActivity.kt | 14 ++++++++------ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt index 172a6c69..b4543d6d 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/HomeActivity.kt @@ -5,6 +5,8 @@ import android.content.Intent import android.os.Bundle import android.text.SpannableStringBuilder import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.lifecycle.asLiveData @@ -133,12 +135,12 @@ class HomeActivity : BaseActivity( sightList.forEachIndexed { index, view -> view.visibility = - if (index == data.review.baseReview.images.size) View.VISIBLE else View.GONE + if (index == data.review.baseReview.images.size) VISIBLE else GONE } when (data.review.baseReview.images.size) { 0 -> { - tvHomeRecentRecordDate.visibility = View.GONE - tvHomeRecentRecordName.visibility = View.GONE + tvHomeRecentRecordDate.visibility = GONE + tvHomeRecentRecordName.visibility = GONE } 1 -> { diff --git a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt index 83b55b7e..c284f7b5 100644 --- a/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/home/ProfileEditActivity.kt @@ -4,7 +4,8 @@ import android.app.Activity import android.content.Intent import android.os.Bundle import android.text.Editable -import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE import androidx.activity.viewModels import androidx.core.widget.addTextChangedListener import androidx.lifecycle.Lifecycle @@ -233,14 +234,14 @@ class ProfileEditActivity : BaseActivity( private fun updateCompletionStatus(isError: Boolean, error: String) = if (isError) { with(binding) { etProfileEditNickname.setBackgroundResource(R.drawable.rect_warning01red_line_6) - tvProfileEditNicknameError.visibility = View.VISIBLE + tvProfileEditNicknameError.visibility = VISIBLE tvProfileEditNicknameError.text = error } } else { with(binding) { etProfileEditNickname.setBackgroundResource(R.drawable.rect_gray100_line_6) - tvProfileEditNicknameError.visibility = View.GONE + tvProfileEditNicknameError.visibility = GONE tvProfileEditNicknameError.text = error } } diff --git a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt index 47c5e77a..780d8277 100644 --- a/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt +++ b/presentation/src/main/java/com/depromeet/presentation/seatrecord/SeatRecordActivity.kt @@ -3,6 +3,8 @@ package com.depromeet.presentation.seatrecord import android.content.Intent import android.os.Bundle import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE import android.widget.AdapterView import androidx.activity.viewModels import androidx.fragment.app.commit @@ -209,15 +211,15 @@ class SeatRecordActivity : BaseActivity( if (!isExist) { with(binding) { "${CalendarUtil.getCurrentYear()}년".also { tvRecordYear.text = it } - clRecordNone.visibility = View.VISIBLE - clRecordStickyHeader.visibility = View.GONE - rvRecordMonthDetail.visibility = View.GONE + clRecordNone.visibility = VISIBLE + clRecordStickyHeader.visibility = GONE + rvRecordMonthDetail.visibility = GONE } } else { with(binding) { - clRecordNone.visibility = View.GONE - clRecordStickyHeader.visibility = View.VISIBLE - rvRecordMonthDetail.visibility = View.VISIBLE + clRecordNone.visibility = GONE + clRecordStickyHeader.visibility = VISIBLE + rvRecordMonthDetail.visibility = VISIBLE ssvRecord.header = binding.clRecordStickyHeader }