From e4152c6a795bf311fa4500e69e2a955157ff66b5 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Thu, 14 Dec 2023 19:11:27 +0900 Subject: [PATCH 01/46] =?UTF-8?q?[FIX]=20#292=20CourseMain=20=EC=A7=84?= =?UTF-8?q?=EC=9E=85=EC=8B=9C,=20=ED=98=84=EC=9E=AC=20=EC=9C=84=EC=B9=98?= =?UTF-8?q?=20=EB=B2=84=ED=8A=BC=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20=EA=B6=8C?= =?UTF-8?q?=ED=95=9C=20=EC=9A=94=EC=B2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coursemain/CourseMainFragment.kt | 51 ++++++++++++++----- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt index e87a35111..770186c13 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt @@ -2,8 +2,11 @@ package com.runnect.runnect.presentation.coursemain import android.Manifest import android.content.Intent +import android.content.pm.PackageManager import android.os.Bundle import android.view.View +import android.widget.Toast +import androidx.core.content.ContextCompat import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices import com.gun0912.tedpermission.PermissionListener @@ -35,18 +38,17 @@ class CourseMainFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) init() - getCurrentLocation() + checkAndRequestLocationPermission() + initCurrentLocationButtonClickListener() drawCourseButton() } private fun init() { fusedLocation = LocationServices.getFusedLocationProviderClient(requireActivity()) - requestPermission() + initView() } private fun initView() { - - //MapFragment 추가 val fm = childFragmentManager val mapFragment = fm.findFragmentById(R.id.mapView) as MapFragment? ?: MapFragment.newInstance().also { @@ -57,9 +59,23 @@ class CourseMainFragment : } - private fun getCurrentLocation() { + private fun checkAndRequestLocationPermission() { + if (isLocationPermissionGranted()) { + if (!::naverMap.isInitialized) { + initView() + } + } else { + requestLocationPermission() + } + } + + private fun initCurrentLocationButtonClickListener() { binding.btnCurrentLocation.setOnClickListener { - cameraUpdate(currentLocation) + if (isLocationPermissionGranted()) { + cameraUpdate(currentLocation) + } else { + requestLocationPermission() + } } } @@ -103,23 +119,32 @@ class CourseMainFragment : locationOverlay.icon = OverlayImage.fromResource(R.drawable.current_location) } - private fun requestPermission() { + private fun isLocationPermissionGranted(): Boolean { + return ContextCompat.checkSelfPermission( + requireContext(), + Manifest.permission.ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED + } + + private fun requestLocationPermission() { TedPermission.create() .setPermissionListener(object : PermissionListener { - override fun onPermissionGranted() { //요청 승인 시 - initView() //지도 뷰 표시 + override fun onPermissionGranted() { + cameraUpdate(currentLocation) } - override fun onPermissionDenied(deniedPermissions: MutableList?) { //요청 거부 시 - naverMap.locationTrackingMode = LocationTrackingMode.None - onDestroy() //앱 종료 + override fun onPermissionDenied(deniedPermissions: MutableList?) { + Toast.makeText( + requireContext(), + "위치 권한이 거부되었습니다.", + Toast.LENGTH_SHORT + ).show() } }) .setRationaleTitle(PERMISSION_TITLE) .setRationaleMessage(PERMISSION_CONTENT) .setDeniedMessage(PERMISSION_GUIDE) .setPermissions( - Manifest.permission.POST_NOTIFICATIONS, // 러닝 시 notification icon 띄우기 Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION ) From ad6e59b5d449372cf94b9527e4877a69e31d47ec Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Thu, 14 Dec 2023 19:31:23 +0900 Subject: [PATCH 02/46] =?UTF-8?q?[MOD]=20#292=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/presentation/coursemain/CourseMainFragment.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt index 770186c13..6eb234136 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt @@ -39,13 +39,13 @@ class CourseMainFragment : super.onViewCreated(view, savedInstanceState) init() checkAndRequestLocationPermission() - initCurrentLocationButtonClickListener() - drawCourseButton() } private fun init() { fusedLocation = LocationServices.getFusedLocationProviderClient(requireActivity()) initView() + initCurrentLocationButtonClickListener() + initDrawCourseButtonClickListener() } private fun initView() { @@ -79,7 +79,7 @@ class CourseMainFragment : } } - private fun drawCourseButton() { + private fun initDrawCourseButtonClickListener() { binding.btnDraw.setOnClickListener { val intent = Intent(activity, SearchActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) From 216309ab8fc18d0a9a1767623302cc2d8566d65e Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Thu, 14 Dec 2023 20:17:53 +0900 Subject: [PATCH 03/46] =?UTF-8?q?[ADD]=20#292=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=EC=84=A4=EC=A0=95=20=ED=99=95=EC=9E=A5=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/util/extension/PermissionExt.kt | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt diff --git a/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt b/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt new file mode 100644 index 000000000..3479cb03e --- /dev/null +++ b/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt @@ -0,0 +1,35 @@ +package com.runnect.runnect.util.extension + +import android.Manifest +import android.content.Context +import android.widget.Toast +import com.gun0912.tedpermission.PermissionListener +import com.gun0912.tedpermission.normal.TedPermission +import com.runnect.runnect.presentation.coursemain.CourseMainFragment + +object PermissionUtil { + fun requestLocationPermission(context: Context, onPermissionGranted: () -> Unit) { + TedPermission.create() + .setPermissionListener(object : PermissionListener { + override fun onPermissionGranted() { + onPermissionGranted() + } + + override fun onPermissionDenied(deniedPermissions: MutableList?) { + Toast.makeText( + context, + "위치 권한이 거부되었습니다.", + Toast.LENGTH_SHORT + ).show() + } + }) + .setRationaleTitle(CourseMainFragment.PERMISSION_TITLE) + .setRationaleMessage(CourseMainFragment.PERMISSION_CONTENT) + .setDeniedMessage(CourseMainFragment.PERMISSION_GUIDE) + .setPermissions( + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION + ) + .check() + } +} \ No newline at end of file From 83d3d3107bfa16b5d4f8156090626ec2ca1c0db5 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Thu, 14 Dec 2023 20:19:21 +0900 Subject: [PATCH 04/46] =?UTF-8?q?[FEAT]=20#292=20=EC=BD=94=EC=8A=A4?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EA=B8=B0=20=ED=98=84=EC=9E=AC=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EC=8B=9C=EC=9E=91=20=EC=8B=9C=20=EA=B6=8C=ED=95=9C?= =?UTF-8?q?=20=EC=9A=94=EC=B2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/search/SearchActivity.kt | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt index 0dea2a8ca..f0f46839a 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt @@ -7,7 +7,6 @@ import android.os.Bundle import android.view.KeyEvent import android.view.MotionEvent import android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH -import android.view.inputmethod.InputMethodManager import android.widget.TextView import androidx.activity.viewModels import androidx.core.content.ContextCompat @@ -22,13 +21,14 @@ import com.runnect.runnect.presentation.draw.DrawActivity import com.runnect.runnect.presentation.search.adapter.SearchAdapter import com.runnect.runnect.presentation.state.UiState import com.runnect.runnect.util.callback.listener.OnSearchItemClick +import com.runnect.runnect.util.extension.PermissionUtil import com.runnect.runnect.util.extension.hideKeyboard import com.runnect.runnect.util.extension.showKeyboard import dagger.hilt.android.AndroidEntryPoint import timber.log.Timber @AndroidEntryPoint -class SearchActivity: BindingActivity(R.layout.activity_search), +class SearchActivity : BindingActivity(R.layout.activity_search), OnSearchItemClick { val viewModel: SearchViewModel by viewModels() private lateinit var searchAdapter: SearchAdapter @@ -159,7 +159,7 @@ class SearchActivity: BindingActivity(R.layout.activity_s override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean { if (actionId == IME_ACTION_SEARCH) { val keyword = binding.etSearch.text - if(!keyword.isNullOrBlank()){ + if (!keyword.isNullOrBlank()) { searchKeyword(keyword.toString()) hideKeyboard(binding.etSearch) } @@ -170,7 +170,9 @@ class SearchActivity: BindingActivity(R.layout.activity_s }) binding.cvStartCurrentLocation.setOnClickListener { - startCurrentLocation() + PermissionUtil.requestLocationPermission(this) { + startCurrentLocation() + } } binding.cvStartCustomLocation.setOnClickListener { @@ -178,13 +180,19 @@ class SearchActivity: BindingActivity(R.layout.activity_s } } + private fun startCurrentLocation() { startActivity( Intent(this, DrawActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) putExtra( EXTRA_SEARCH_RESULT, - SearchResultEntity(fullAddress = "", name = "", locationLatLng = null, mode = "currentLocation") + SearchResultEntity( + fullAddress = "", + name = "", + locationLatLng = null, + mode = "currentLocation" + ) ) } ) @@ -196,7 +204,12 @@ class SearchActivity: BindingActivity(R.layout.activity_s addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) putExtra( EXTRA_SEARCH_RESULT, - SearchResultEntity(fullAddress = "", name = "", locationLatLng = null, mode = "customLocation") + SearchResultEntity( + fullAddress = "", + name = "", + locationLatLng = null, + mode = "customLocation" + ) ) } ) From db64608039a70de8aa989a7feeae29f02b8336a1 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Thu, 14 Dec 2023 20:35:00 +0900 Subject: [PATCH 05/46] =?UTF-8?q?[FEAT]=20#292=20=EB=82=B4=20=EC=BD=94?= =?UTF-8?q?=EC=8A=A4=20=EC=8B=9C=EC=9E=91=20=EC=8B=9C=20=EA=B6=8C=ED=95=9C?= =?UTF-8?q?=20=EC=9A=94=EC=B2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mydrawdetail/MyDrawDetailActivity.kt | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt index 24c2eac70..1ea2e6edd 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt @@ -15,6 +15,7 @@ import com.runnect.runnect.data.dto.response.ResponseGetMyDrawDetail import com.runnect.runnect.databinding.ActivityMyDrawDetailBinding import com.runnect.runnect.presentation.MainActivity import com.runnect.runnect.presentation.countdown.CountDownActivity +import com.runnect.runnect.util.extension.PermissionUtil import com.runnect.runnect.util.extension.navigateToPreviousScreenWithAnimation import com.runnect.runnect.util.extension.setActivityDialog import dagger.hilt.android.AndroidEntryPoint @@ -40,7 +41,7 @@ class MyDrawDetailActivity : getMyDrawDetail() backButton() addObserver() - toCountDownButton() + initDrawButtonClickListener() deleteButton() } @@ -88,14 +89,21 @@ class MyDrawDetailActivity : viewModel.getMyDrawDetail(courseId = courseId) } - fun toCountDownButton() { + + private fun initDrawButtonClickListener() { binding.btnMyDrawDetailRun.setOnClickListener { - startActivity(Intent(this, CountDownActivity::class.java).apply { - putExtra(EXTRA_COURSE_DATA, viewModel.myDrawToRunData.value) - }) + PermissionUtil.requestLocationPermission(this) { + toCountDownButton() + } } } + private fun toCountDownButton() { + startActivity(Intent(this, CountDownActivity::class.java).apply { + putExtra(EXTRA_COURSE_DATA, viewModel.myDrawToRunData.value) + }) + } + fun addObserver() { observeGetResult() registerBackPressedCallback() @@ -158,7 +166,7 @@ class MyDrawDetailActivity : } } - fun deleteCourse() { + private fun deleteCourse() { viewModel.deleteMyDrawCourse(selectList) } From a45f39c92f81cefa8601399b976cda0881b72b5a Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 23 Dec 2023 14:34:03 +0900 Subject: [PATCH 06/46] =?UTF-8?q?[FIX]=20#300=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=EB=9F=AC=EB=8B=9D=20=EC=8B=9C=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EC=97=86=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20=ED=81=AC=EB=9E=98?= =?UTF-8?q?=EC=8B=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 커스텀모드에서는 departureLatLng 초기화해주는 부분이 없어서 UninitializedError 발생 --- .../com/runnect/runnect/presentation/draw/DrawActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt index 5af92a7c6..c456f4440 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt @@ -186,18 +186,18 @@ class DrawActivity : BindingActivity(R.layout.activity_draw private fun initCustomLocationMode() { isCustomLocationMode = true - with(binding) { customDepartureMarker.isVisible = true customDepartureInfoWindow.isVisible = true tvCustomDepartureGuideFrame.isVisible = true btnPreStart.setOnClickListener { + departureLatLng = getCenterPosition() isMarkerAvailable = true showDrawGuide() hideDeparture() showDrawCourse() - drawCourse(departureLatLng = getCenterPosition()) + drawCourse(departureLatLng = departureLatLng) hideFloatedDeparture() } } From 06ea7ba90281de382eeac5f432b219f8f1314f6f Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 23 Dec 2023 14:34:03 +0900 Subject: [PATCH 07/46] =?UTF-8?q?[FIX]=20#292=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=EB=9F=AC=EB=8B=9D=20=EC=8B=9C=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EC=97=86=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20=ED=81=AC=EB=9E=98?= =?UTF-8?q?=EC=8B=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 커스텀모드에서는 departureLatLng 초기화해주는 부분이 없어서 UninitializedError 발생 --- .../com/runnect/runnect/presentation/draw/DrawActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt index 5af92a7c6..c456f4440 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt @@ -186,18 +186,18 @@ class DrawActivity : BindingActivity(R.layout.activity_draw private fun initCustomLocationMode() { isCustomLocationMode = true - with(binding) { customDepartureMarker.isVisible = true customDepartureInfoWindow.isVisible = true tvCustomDepartureGuideFrame.isVisible = true btnPreStart.setOnClickListener { + departureLatLng = getCenterPosition() isMarkerAvailable = true showDrawGuide() hideDeparture() showDrawCourse() - drawCourse(departureLatLng = getCenterPosition()) + drawCourse(departureLatLng = departureLatLng) hideFloatedDeparture() } } From 3e35fbf00d594077aef8f8edb19fb095edfa4c8b Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Tue, 26 Dec 2023 19:39:09 +0900 Subject: [PATCH 08/46] =?UTF-8?q?[FEAT]=20#292=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EC=8B=9C=EC=9E=91=20=EC=8B=9C?= =?UTF-8?q?=20=EA=B6=8C=ED=95=9C=20=EC=9A=94=EC=B2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/runnect/presentation/draw/DrawActivity.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt index c456f4440..f4f084d3e 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt @@ -20,7 +20,6 @@ import androidx.lifecycle.lifecycleScope import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices import com.google.android.material.bottomsheet.BottomSheetDialog -import com.google.android.material.internal.ViewUtils.hideKeyboard import com.naver.maps.geometry.LatLng import com.naver.maps.geometry.LatLngBounds import com.naver.maps.map.CameraAnimation @@ -47,6 +46,7 @@ import com.runnect.runnect.presentation.countdown.CountDownActivity import com.runnect.runnect.presentation.state.UiState import com.runnect.runnect.util.DepartureSetMode import com.runnect.runnect.util.custom.dialog.RequireLoginDialogFragment +import com.runnect.runnect.util.extension.PermissionUtil import com.runnect.runnect.util.extension.hideKeyboard import com.runnect.runnect.util.extension.setActivityDialog import com.runnect.runnect.util.multipart.ContentUriRequestBody @@ -308,9 +308,11 @@ class DrawActivity : BindingActivity(R.layout.activity_draw bottomSheetDialog.setContentView(bottomSheetView) btnCreateCourse.setOnClickListener { - hideKeyboard(etCourseName) - bottomSheetDialog.dismiss() - createMBR() + PermissionUtil.requestLocationPermission(this) { + hideKeyboard(etCourseName) + bottomSheetDialog.dismiss() + createMBR() + } } return bottomSheetDialog From 53f1799e07349f1bbcadc0abde2b5ed7470726ce Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Tue, 26 Dec 2023 19:48:35 +0900 Subject: [PATCH 09/46] =?UTF-8?q?[MOD]=20#292=20courseMain=20=EC=97=90?= =?UTF-8?q?=EB=8F=84=20=EA=B6=8C=ED=95=9C=20=ED=99=95=EC=9D=B8=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=ED=95=A8=EC=88=98=20=EC=A0=81=EC=9A=A9=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coursemain/CourseMainFragment.kt | 37 ++++--------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt index 6eb234136..ea840e15f 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt @@ -5,12 +5,9 @@ import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.view.View -import android.widget.Toast import androidx.core.content.ContextCompat import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices -import com.gun0912.tedpermission.PermissionListener -import com.gun0912.tedpermission.normal.TedPermission import com.naver.maps.geometry.LatLng import com.naver.maps.map.CameraAnimation import com.naver.maps.map.CameraUpdate @@ -24,6 +21,7 @@ import com.runnect.runnect.R import com.runnect.runnect.binding.BindingFragment import com.runnect.runnect.databinding.FragmentCourseMainBinding import com.runnect.runnect.presentation.search.SearchActivity +import com.runnect.runnect.util.extension.PermissionUtil class CourseMainFragment : @@ -65,7 +63,9 @@ class CourseMainFragment : initView() } } else { - requestLocationPermission() + PermissionUtil.requestLocationPermission(requireContext()) { + cameraUpdate(currentLocation) + } } } @@ -74,7 +74,9 @@ class CourseMainFragment : if (isLocationPermissionGranted()) { cameraUpdate(currentLocation) } else { - requestLocationPermission() + PermissionUtil.requestLocationPermission(requireContext()) { + cameraUpdate(currentLocation) + } } } } @@ -126,31 +128,6 @@ class CourseMainFragment : ) == PackageManager.PERMISSION_GRANTED } - private fun requestLocationPermission() { - TedPermission.create() - .setPermissionListener(object : PermissionListener { - override fun onPermissionGranted() { - cameraUpdate(currentLocation) - } - - override fun onPermissionDenied(deniedPermissions: MutableList?) { - Toast.makeText( - requireContext(), - "위치 권한이 거부되었습니다.", - Toast.LENGTH_SHORT - ).show() - } - }) - .setRationaleTitle(PERMISSION_TITLE) - .setRationaleMessage(PERMISSION_CONTENT) - .setDeniedMessage(PERMISSION_GUIDE) - .setPermissions( - Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION - ) - .check() - } - private fun cameraUpdate(location: LatLng) { val cameraUpdate = CameraUpdate.scrollTo(LatLng(location.latitude, location.longitude)) .animate(CameraAnimation.Easing) From 648c0c155dc7038924903f114939f0973f5bb53c Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Tue, 26 Dec 2023 19:39:09 +0900 Subject: [PATCH 10/46] =?UTF-8?q?[FEAT]=20#292=20=EC=BD=94=EC=8A=A4=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EA=B6=8C?= =?UTF-8?q?=ED=95=9C=20=EC=9A=94=EC=B2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/runnect/presentation/draw/DrawActivity.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt index c456f4440..f4f084d3e 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt @@ -20,7 +20,6 @@ import androidx.lifecycle.lifecycleScope import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices import com.google.android.material.bottomsheet.BottomSheetDialog -import com.google.android.material.internal.ViewUtils.hideKeyboard import com.naver.maps.geometry.LatLng import com.naver.maps.geometry.LatLngBounds import com.naver.maps.map.CameraAnimation @@ -47,6 +46,7 @@ import com.runnect.runnect.presentation.countdown.CountDownActivity import com.runnect.runnect.presentation.state.UiState import com.runnect.runnect.util.DepartureSetMode import com.runnect.runnect.util.custom.dialog.RequireLoginDialogFragment +import com.runnect.runnect.util.extension.PermissionUtil import com.runnect.runnect.util.extension.hideKeyboard import com.runnect.runnect.util.extension.setActivityDialog import com.runnect.runnect.util.multipart.ContentUriRequestBody @@ -308,9 +308,11 @@ class DrawActivity : BindingActivity(R.layout.activity_draw bottomSheetDialog.setContentView(bottomSheetView) btnCreateCourse.setOnClickListener { - hideKeyboard(etCourseName) - bottomSheetDialog.dismiss() - createMBR() + PermissionUtil.requestLocationPermission(this) { + hideKeyboard(etCourseName) + bottomSheetDialog.dismiss() + createMBR() + } } return bottomSheetDialog From dd3bb06806f7aebb76318dbb1e214393ddf9ba0d Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Tue, 26 Dec 2023 19:48:35 +0900 Subject: [PATCH 11/46] =?UTF-8?q?[MOD]=20#292=20courseMain=20=EC=97=90?= =?UTF-8?q?=EB=8F=84=20=EA=B6=8C=ED=95=9C=20=ED=99=95=EC=9D=B8=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=ED=95=A8=EC=88=98=20=EC=A0=81=EC=9A=A9=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coursemain/CourseMainFragment.kt | 37 ++++--------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt index 6eb234136..ea840e15f 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt @@ -5,12 +5,9 @@ import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.view.View -import android.widget.Toast import androidx.core.content.ContextCompat import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices -import com.gun0912.tedpermission.PermissionListener -import com.gun0912.tedpermission.normal.TedPermission import com.naver.maps.geometry.LatLng import com.naver.maps.map.CameraAnimation import com.naver.maps.map.CameraUpdate @@ -24,6 +21,7 @@ import com.runnect.runnect.R import com.runnect.runnect.binding.BindingFragment import com.runnect.runnect.databinding.FragmentCourseMainBinding import com.runnect.runnect.presentation.search.SearchActivity +import com.runnect.runnect.util.extension.PermissionUtil class CourseMainFragment : @@ -65,7 +63,9 @@ class CourseMainFragment : initView() } } else { - requestLocationPermission() + PermissionUtil.requestLocationPermission(requireContext()) { + cameraUpdate(currentLocation) + } } } @@ -74,7 +74,9 @@ class CourseMainFragment : if (isLocationPermissionGranted()) { cameraUpdate(currentLocation) } else { - requestLocationPermission() + PermissionUtil.requestLocationPermission(requireContext()) { + cameraUpdate(currentLocation) + } } } } @@ -126,31 +128,6 @@ class CourseMainFragment : ) == PackageManager.PERMISSION_GRANTED } - private fun requestLocationPermission() { - TedPermission.create() - .setPermissionListener(object : PermissionListener { - override fun onPermissionGranted() { - cameraUpdate(currentLocation) - } - - override fun onPermissionDenied(deniedPermissions: MutableList?) { - Toast.makeText( - requireContext(), - "위치 권한이 거부되었습니다.", - Toast.LENGTH_SHORT - ).show() - } - }) - .setRationaleTitle(PERMISSION_TITLE) - .setRationaleMessage(PERMISSION_CONTENT) - .setDeniedMessage(PERMISSION_GUIDE) - .setPermissions( - Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION - ) - .check() - } - private fun cameraUpdate(location: LatLng) { val cameraUpdate = CameraUpdate.scrollTo(LatLng(location.latitude, location.longitude)) .animate(CameraAnimation.Easing) From 745f35ff4b5fe341e9bb0dee1b5e5550017488da Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Fri, 29 Dec 2023 15:01:25 +0900 Subject: [PATCH 12/46] =?UTF-8?q?[ADD]=20#303=20=EC=BD=94=EC=8A=A4=20?= =?UTF-8?q?=EB=94=94=ED=85=8C=EC=9D=BC=20Response=20=EC=97=90=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=EC=95=84=EC=9D=B4=EB=94=94=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/data/dto/response/ResponseGetCourseDetail.kt | 5 ++++- .../java/com/runnect/runnect/domain/entity/CourseDetail.kt | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetCourseDetail.kt b/app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetCourseDetail.kt index 3b651e654..822950893 100644 --- a/app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetCourseDetail.kt +++ b/app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetCourseDetail.kt @@ -21,7 +21,9 @@ data class ResponseGetCourseDetail( @SerialName("image") val image: String, @SerialName("isNowUser") - val isNowUser: Boolean + val isNowUser: Boolean, + @SerialName("id") + val id: Int ) @Serializable @@ -65,6 +67,7 @@ data class ResponseGetCourseDetail( level = user.level.toString(), nickname = user.nickname, isNowUser = user.isNowUser, + userId = user.id, id = publicCourse.id, courseId = publicCourse.courseId, departure = publicCourse.departure.region + ' ' + diff --git a/app/src/main/java/com/runnect/runnect/domain/entity/CourseDetail.kt b/app/src/main/java/com/runnect/runnect/domain/entity/CourseDetail.kt index ca0476e67..4fe5a6cb1 100644 --- a/app/src/main/java/com/runnect/runnect/domain/entity/CourseDetail.kt +++ b/app/src/main/java/com/runnect/runnect/domain/entity/CourseDetail.kt @@ -15,4 +15,5 @@ data class CourseDetail( val path: List>, val distance: String, val departure: String, + val userId: Int ) From 6ea1549eb7f56e0ca0317bf3a4bfaf4721a9119f Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Fri, 29 Dec 2023 15:02:26 +0900 Subject: [PATCH 13/46] =?UTF-8?q?[FEAT]=20#303=20CourseDetail=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=9C=A0=EC=A0=80=20Profile=EB=A1=9C=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=A0=84=ED=99=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 3 ++ .../detail/CourseDetailActivity.kt | 30 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0c0a6718e..337e58fb3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -134,6 +134,9 @@ + navigateToPreviousScreen() @@ -178,6 +192,7 @@ class CourseDetailActivity : initScrapButtonClickListener() initStartRunButtonClickListener() initEditFinishButtonClickListener() + initUserInfoClickListener() initShareButtonClickListener() initShowMoreButtonClickListener() @@ -215,6 +230,12 @@ class CourseDetailActivity : } } + private fun initUserInfoClickListener() { + binding.constCourseDetailUserInfo.setOnClickListener { + navigateToUserProfileWithBundle() + } + } + // todo: 함수를 더 작게 분리하는 게 좋을 거 같아요! @우남 private fun sendKakaoLink(title: String, desc: String, image: String) { // 메시지 템플릿 만들기 (피드형) @@ -600,6 +621,7 @@ class CourseDetailActivity : private const val EXTRA_COURSE_DATA = "CourseData" private const val EXTRA_FRAGMENT_REPLACEMENT_DIRECTION = "fragmentReplacementDirection" private const val EXTRA_FROM_COURSE_DETAIL = "fromCourseDetail" + private const val EXTRA_COURSE_USER_ID = "userId" private const val POPUP_MENU_X_OFFSET = 17 private const val POPUP_MENU_Y_OFFSET = -10 From 62c5ece86ae80c2ceab56e250c4811044b87d92b Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Fri, 29 Dec 2023 16:57:35 +0900 Subject: [PATCH 14/46] =?UTF-8?q?[FEAT]=20#303=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=ED=86=B5=EC=8B=A0=20serivce,=20datasource=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 --- .../runnect/data/service/UserService.kt | 6 ++++++ .../source/remote/RemoteUserDataSource.kt | 19 ++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/data/service/UserService.kt b/app/src/main/java/com/runnect/runnect/data/service/UserService.kt index 62fb27610..780a22bf9 100644 --- a/app/src/main/java/com/runnect/runnect/data/service/UserService.kt +++ b/app/src/main/java/com/runnect/runnect/data/service/UserService.kt @@ -48,4 +48,10 @@ interface UserService { @DELETE("api/user") suspend fun deleteUser(): ResponseDeleteUser + + // 유저 프로필 조회 + @GET("/api/user/{profileUserId}") + suspend fun getUserProfile( + @Path("profileUserId") userId: Int, + ): BaseResponse } \ No newline at end of file diff --git a/app/src/main/java/com/runnect/runnect/data/source/remote/RemoteUserDataSource.kt b/app/src/main/java/com/runnect/runnect/data/source/remote/RemoteUserDataSource.kt index 0964340c5..19d9b64e0 100644 --- a/app/src/main/java/com/runnect/runnect/data/source/remote/RemoteUserDataSource.kt +++ b/app/src/main/java/com/runnect/runnect/data/source/remote/RemoteUserDataSource.kt @@ -1,12 +1,21 @@ package com.runnect.runnect.data.source.remote -import com.runnect.runnect.data.service.UserService import com.runnect.runnect.data.dto.request.RequestDeleteHistory import com.runnect.runnect.data.dto.request.RequestDeleteUploadCourse import com.runnect.runnect.data.dto.request.RequestPatchHistoryTitle import com.runnect.runnect.data.dto.request.RequestPatchNickName -import com.runnect.runnect.data.dto.response.* +import com.runnect.runnect.data.dto.response.ResponseDeleteHistory +import com.runnect.runnect.data.dto.response.ResponseDeleteUploadCourse +import com.runnect.runnect.data.dto.response.ResponseDeleteUser +import com.runnect.runnect.data.dto.response.ResponseGetMyHistory +import com.runnect.runnect.data.dto.response.ResponseGetMyStamp +import com.runnect.runnect.data.dto.response.ResponseGetUser +import com.runnect.runnect.data.dto.response.ResponseGetUserProfile +import com.runnect.runnect.data.dto.response.ResponseGetUserUploadCourse +import com.runnect.runnect.data.dto.response.ResponsePatchHistoryTitle +import com.runnect.runnect.data.dto.response.ResponsePatchUserNickName import com.runnect.runnect.data.dto.response.base.BaseResponse +import com.runnect.runnect.data.service.UserService import javax.inject.Inject class RemoteUserDataSource @Inject constructor(private val userService: UserService) { @@ -16,7 +25,11 @@ class RemoteUserDataSource @Inject constructor(private val userService: UserServ suspend fun getMyStamp(): ResponseGetMyStamp = userService.getMyStamp() suspend fun getRecord(): ResponseGetMyHistory = userService.getRecord() - suspend fun getUserUploadCourse(): ResponseGetUserUploadCourse = userService.getUserUploadCourse() + suspend fun getUserUploadCourse(): ResponseGetUserUploadCourse = + userService.getUserUploadCourse() + + suspend fun getUserProfile(userId: Int): BaseResponse = + userService.getUserProfile(userId) suspend fun putDeleteUploadCourse( requestDeleteUploadCourse: RequestDeleteUploadCourse From 5380146cec058e3f2c95ce64b9a040e16201ddb7 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Fri, 29 Dec 2023 16:57:53 +0900 Subject: [PATCH 15/46] =?UTF-8?q?[FEAT]=20#303=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=ED=86=B5=EC=8B=A0=20repository=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/{ProfileCourseData.kt => UserProfileData.kt} | 12 ++++++++++-- .../runnect/data/repository/UserRepositoryImpl.kt | 8 +++++++- .../runnect/domain/repository/UserRepository.kt | 10 +++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) rename app/src/main/java/com/runnect/runnect/data/dto/{ProfileCourseData.kt => UserProfileData.kt} (58%) diff --git a/app/src/main/java/com/runnect/runnect/data/dto/ProfileCourseData.kt b/app/src/main/java/com/runnect/runnect/data/dto/UserProfileData.kt similarity index 58% rename from app/src/main/java/com/runnect/runnect/data/dto/ProfileCourseData.kt rename to app/src/main/java/com/runnect/runnect/data/dto/UserProfileData.kt index 8a96523ba..240281e11 100644 --- a/app/src/main/java/com/runnect/runnect/data/dto/ProfileCourseData.kt +++ b/app/src/main/java/com/runnect/runnect/data/dto/UserProfileData.kt @@ -1,12 +1,20 @@ package com.runnect.runnect.data.dto -data class ProfileCourseData( +data class UserProfileData( + val nickname: String, + val level: Int, + val levelPercent: Int, + val latestStamp: String, + val courseData: List +) + +data class UserCourseData( val publicCourseId: Int, val courseId: Int, val title: String, val image: String, val departure: DepartureData, - val scrapTF: Boolean + val scrapTF: Boolean, ) data class DepartureData( diff --git a/app/src/main/java/com/runnect/runnect/data/repository/UserRepositoryImpl.kt b/app/src/main/java/com/runnect/runnect/data/repository/UserRepositoryImpl.kt index 2b6350af5..b69c81244 100644 --- a/app/src/main/java/com/runnect/runnect/data/repository/UserRepositoryImpl.kt +++ b/app/src/main/java/com/runnect/runnect/data/repository/UserRepositoryImpl.kt @@ -1,6 +1,7 @@ package com.runnect.runnect.data.repository import com.runnect.runnect.data.dto.HistoryInfoDTO +import com.runnect.runnect.data.dto.UserProfileData import com.runnect.runnect.data.dto.UserUploadCourseDTO import com.runnect.runnect.data.dto.request.RequestDeleteHistory import com.runnect.runnect.data.dto.request.RequestDeleteUploadCourse @@ -9,9 +10,9 @@ import com.runnect.runnect.data.dto.request.RequestPatchNickName import com.runnect.runnect.data.dto.response.ResponseDeleteHistory import com.runnect.runnect.data.dto.response.ResponseDeleteUploadCourse import com.runnect.runnect.data.dto.response.ResponseDeleteUser +import com.runnect.runnect.data.dto.response.ResponseGetUser import com.runnect.runnect.data.dto.response.ResponsePatchHistoryTitle import com.runnect.runnect.data.dto.response.ResponsePatchUserNickName -import com.runnect.runnect.data.dto.response.ResponseGetUser import com.runnect.runnect.data.source.remote.RemoteUserDataSource import com.runnect.runnect.domain.repository.UserRepository import com.runnect.runnect.util.extension.toData @@ -36,6 +37,11 @@ class UserRepositoryImpl @Inject constructor(private val remoteUserDataSource: R .toMutableList() } + override suspend fun getUserProfile(userId: Int): Result = + runCatching { + remoteUserDataSource.getUserProfile(userId).data?.toUserProfile() + } + override suspend fun putDeleteUploadCourse( requestDeleteUploadCourse: RequestDeleteUploadCourse ): Result = runCatching { diff --git a/app/src/main/java/com/runnect/runnect/domain/repository/UserRepository.kt b/app/src/main/java/com/runnect/runnect/domain/repository/UserRepository.kt index 7f8f4db02..bf3c11ef5 100644 --- a/app/src/main/java/com/runnect/runnect/domain/repository/UserRepository.kt +++ b/app/src/main/java/com/runnect/runnect/domain/repository/UserRepository.kt @@ -1,12 +1,18 @@ package com.runnect.runnect.domain.repository import com.runnect.runnect.data.dto.HistoryInfoDTO +import com.runnect.runnect.data.dto.UserProfileData import com.runnect.runnect.data.dto.UserUploadCourseDTO import com.runnect.runnect.data.dto.request.RequestDeleteHistory import com.runnect.runnect.data.dto.request.RequestDeleteUploadCourse import com.runnect.runnect.data.dto.request.RequestPatchHistoryTitle import com.runnect.runnect.data.dto.request.RequestPatchNickName -import com.runnect.runnect.data.dto.response.* +import com.runnect.runnect.data.dto.response.ResponseDeleteHistory +import com.runnect.runnect.data.dto.response.ResponseDeleteUploadCourse +import com.runnect.runnect.data.dto.response.ResponseDeleteUser +import com.runnect.runnect.data.dto.response.ResponseGetUser +import com.runnect.runnect.data.dto.response.ResponsePatchHistoryTitle +import com.runnect.runnect.data.dto.response.ResponsePatchUserNickName interface UserRepository { suspend fun getUserInfo(): ResponseGetUser @@ -19,6 +25,8 @@ interface UserRepository { suspend fun getUserUploadCourse(): MutableList + suspend fun getUserProfile(userId: Int): Result + suspend fun putDeleteUploadCourse( requestDeleteUploadCourse: RequestDeleteUploadCourse ): Result From 000c41087fadb96feef3ac1bc9d6664553699c95 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Fri, 29 Dec 2023 16:58:27 +0900 Subject: [PATCH 16/46] =?UTF-8?q?[ADD]=20#303=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=ED=86=B5=EC=8B=A0=20Response=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/ResponseGetUserProfile.kt | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetUserProfile.kt diff --git a/app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetUserProfile.kt b/app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetUserProfile.kt new file mode 100644 index 000000000..1995da2cd --- /dev/null +++ b/app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetUserProfile.kt @@ -0,0 +1,88 @@ +package com.runnect.runnect.data.dto.response + +import com.runnect.runnect.data.dto.CourseData +import com.runnect.runnect.data.dto.DepartureData +import com.runnect.runnect.data.dto.UserCourseData +import com.runnect.runnect.data.dto.UserProfileData +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponseGetUserProfile( + @SerialName("user") + val user: User, + @SerialName("courses") + val courses: List +) { + @Serializable + data class User( + @SerialName("nickname") + val nickname: String, + @SerialName("level") + val level: Int, + @SerialName("levelPercent") + val levelPercent: Int, + @SerialName("latestStamp") + val latestStamp: String, + @SerialName("userId") + val userId: Int + ) + + @Serializable + data class CourseData( + @SerialName("publicCourseId") + val publicCourseId: Int, + @SerialName("courseId") + val courseId: Int, + @SerialName("title") + val title: String, + @SerialName("image") + val image: String, + @SerialName("departure") + val departure: Departure, + @SerialName("scrapTF") + val scrapTF: Boolean, + ) { + @Serializable + data class Departure( + @SerialName("region") + val region: String, + @SerialName("city") + val city: String, + @SerialName("town") + val town: String, + @SerialName("name") + val name: String?, + @SerialName("detail") + val detail: String? + ) + } + + fun toUserProfile(): UserProfileData { + val userCourseDataList: List = courses.map { course -> + UserCourseData( + publicCourseId = course.publicCourseId, + courseId = course.courseId, + title = course.title, + image = course.image, + departure = DepartureData( + region = course.departure.region, + city = course.departure.city, + town = course.departure.town, + detail = course.departure.detail, + name = course.departure.name ?: "" + ), + scrapTF = course.scrapTF + ) + } + + return UserProfileData( + nickname = user.nickname, + level = user.level, + levelPercent = user.levelPercent, + latestStamp = user.latestStamp, + courseData = userCourseDataList + ) + } + +} From da01b48114c35f9b89bbfb69669b15f8d6bc5903 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Fri, 29 Dec 2023 18:03:21 +0900 Subject: [PATCH 17/46] =?UTF-8?q?[FEAT]=20#303=20ViewModel=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=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 --- .../profile/ProfileCourseAdapter.kt | 10 +-- .../presentation/profile/ProfileViewModel.kt | 69 ++++++++++--------- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt index 11ddf62e4..059c3e46e 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt @@ -4,12 +4,12 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import com.runnect.runnect.data.dto.ProfileCourseData +import com.runnect.runnect.data.dto.UserCourseData import com.runnect.runnect.databinding.ItemProfileCourseBinding import com.runnect.runnect.util.callback.diff.ItemDiffCallback class ProfileCourseAdapter( -) : ListAdapter(diffUtil) { +) : ListAdapter(diffUtil) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UploadedCourseViewHolder { return UploadedCourseViewHolder( @@ -28,15 +28,15 @@ class ProfileCourseAdapter( class UploadedCourseViewHolder( private val binding: ItemProfileCourseBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(profileCourseData: ProfileCourseData) { + fun bind(userCourseData: UserCourseData) { with(binding) { - data = profileCourseData + data = userCourseData } } } companion object { - private val diffUtil = ItemDiffCallback( + private val diffUtil = ItemDiffCallback( onItemsTheSame = { old, new -> old.courseId == new.courseId }, onContentsTheSame = { old, new -> old == new } ) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt index e5667de47..8d58f7051 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt @@ -1,40 +1,45 @@ package com.runnect.runnect.presentation.profile +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import com.runnect.runnect.data.dto.DepartureData -import com.runnect.runnect.data.dto.ProfileCourseData +import androidx.lifecycle.viewModelScope +import com.runnect.runnect.data.dto.UserProfileData +import com.runnect.runnect.domain.repository.UserRepository +import com.runnect.runnect.presentation.state.UiStateV2 +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import timber.log.Timber +import javax.inject.Inject -class ProfileViewModel : ViewModel() { - val courseList: List = generateMockData() +@HiltViewModel +class ProfileViewModel @Inject constructor(private val userRepository: UserRepository) : + ViewModel() { - private fun generateMockData(): List { - val mockDataList = mutableListOf() - val mockData1 = ProfileCourseData( - publicCourseId = 1, - courseId = 101, - title = "제목 1", - image = "이미지 1", - departure = DepartureData( - region = "지역 1", - city = "도시 1", - town = "동네 1", - detail = null, - name = "출발지 1" - ), - scrapTF = true - ) - mockDataList.add(mockData1) - mockDataList.add(mockData1) - mockDataList.add(mockData1) - mockDataList.add(mockData1) - mockDataList.add(mockData1) - mockDataList.add(mockData1) - mockDataList.add(mockData1) - mockDataList.add(mockData1) - mockDataList.add(mockData1) - mockDataList.add(mockData1) - mockDataList.add(mockData1) - return mockDataList + private val _userProfileState = MutableLiveData>() + val userProfileState: LiveData> + get() = _userProfileState + + fun getUserProfile(userId: Int) { + viewModelScope.launch { + _userProfileState.value = UiStateV2.Loading + + userRepository.getUserProfile(userId = userId) + .onSuccess { profileData -> + if (profileData == null) { + _userProfileState.value = UiStateV2.Failure("PROFILE DATA IS NULL") + Timber.e("PROFILE DATA IS NULL") + return@launch + } + _userProfileState.value = UiStateV2.Success(profileData) + Timber.e("GET PROFILE DATA SUCCESS") + } + .onFailure { error -> + _userProfileState.value = UiStateV2.Failure(error.message.toString()) + Timber.e("GET PROFILE DATA FAILURE") + } + } } } + From 2d82d7adbfc9f067c9d04033201e7be2eeb4d3ab Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Fri, 29 Dec 2023 18:04:38 +0900 Subject: [PATCH 18/46] =?UTF-8?q?[FEAT]=20#303=20=EC=9D=B8=ED=85=90?= =?UTF-8?q?=ED=8A=B8=EB=A1=9C=20=EB=B0=9B=EC=9D=80=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EB=94=94=EB=A1=9C=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/profile/ProfileActivity.kt | 43 ++++++++++++++++++- .../main/res/layout/item_profile_course.xml | 2 +- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index 361bf01dd..3f3b648cd 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -5,23 +5,64 @@ import androidx.activity.viewModels import com.runnect.runnect.R import com.runnect.runnect.binding.BindingActivity import com.runnect.runnect.databinding.ActivityProfileBinding +import com.runnect.runnect.presentation.state.UiStateV2 import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class ProfileActivity : BindingActivity(R.layout.activity_profile) { private val viewModel: ProfileViewModel by viewModels() private lateinit var adapter: ProfileCourseAdapter + private var userId: Int = -1 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding.vm = viewModel binding.lifecycleOwner = this initAdapter() + getIntentExtra() + getUserProfile() + setupUserProfileGetStateObserver() + } + + private fun getIntentExtra() { + userId = intent.getIntExtra(EXTRA_COURSE_USER_ID, -1) } private fun initAdapter() { adapter = ProfileCourseAdapter().also { adapter -> binding.rvProfileUploadCourse.adapter = adapter - adapter.submitList(viewModel.courseList) } } + + + private fun getUserProfile() { + viewModel.getUserProfile(userId = userId) + } + + private fun setupUserProfileGetStateObserver() { + viewModel.userProfileState.observe(this) { state -> + when (state) { + is UiStateV2.Loading -> { + // 프로그레스바 + } + + is UiStateV2.Success -> { + binding.data = state.data + adapter.submitList(state.data.courseData) + } + + is UiStateV2.Failure -> { + + } + + else -> { + + } + } + + } + } + + companion object { + private const val EXTRA_COURSE_USER_ID = "userId" + } } \ No newline at end of file diff --git a/app/src/main/res/layout/item_profile_course.xml b/app/src/main/res/layout/item_profile_course.xml index b3572db42..45daaec59 100644 --- a/app/src/main/res/layout/item_profile_course.xml +++ b/app/src/main/res/layout/item_profile_course.xml @@ -7,7 +7,7 @@ + type="com.runnect.runnect.data.dto.UserCourseData" /> Date: Fri, 29 Dec 2023 18:08:01 +0900 Subject: [PATCH 19/46] =?UTF-8?q?[FEAT]=20#303=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=8A=A4=ED=83=AC=ED=94=84=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20bindingAdapter=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 setLocalImageByResourceId는 사용 시 따로 Extension을 이용해야해서 이를 모두 합친 bindingAdapter 함수 구현 --- .../runnect/util/binding/BindingAdapter.kt | 16 +++++++++++++++ app/src/main/res/layout/activity_profile.xml | 20 ++++++++++--------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/util/binding/BindingAdapter.kt b/app/src/main/java/com/runnect/runnect/util/binding/BindingAdapter.kt index 6f60357be..782755995 100644 --- a/app/src/main/java/com/runnect/runnect/util/binding/BindingAdapter.kt +++ b/app/src/main/java/com/runnect/runnect/util/binding/BindingAdapter.kt @@ -12,6 +12,22 @@ fun ImageView.setLocalImageByResourceId(resId: Int) { load(resId) } +@BindingAdapter("setStampImageByResourceId") +fun ImageView.setStampImageByResourceId(stampId: String?) { + val resNameParam = "mypage_img_stamp_" + val resType = "drawable" + val packageName = context.packageName + + var resName = "" + resName = if (stampId == "CSPR0") { + "${resNameParam}basic" + } else { + "${resNameParam}$stampId" + } + val resId = context.resources.getIdentifier(resName, resType, packageName) + setImageResource(resId) +} + @BindingAdapter("setImageUrl") fun ImageView.setImageUrl(url: String?) { if (url == null) return diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index 3d4185491..405f6e8a2 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -5,7 +5,9 @@ tools:context=".presentation.profile.ProfileActivity"> - + @@ -69,13 +71,13 @@ + setStampImageByResourceId="@{data.latestStamp}" /> + android:text="@{data.nickname}" /> + android:text="@{Integer.toString(data.level)}"/> + android:progress="@{data.levelPercent}" /> + android:text="@{Integer.toString(data.levelPercent)}" /> Date: Fri, 29 Dec 2023 23:12:36 +0900 Subject: [PATCH 20/46] =?UTF-8?q?[FEAT]=20#303=20=EB=A1=9C=EB=94=A9=20?= =?UTF-8?q?=EC=8B=9C=20=ED=94=84=EB=A1=9C=EA=B7=B8=EB=A0=88=EC=8A=A4?= =?UTF-8?q?=EB=B0=94=20=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/profile/ProfileActivity.kt | 14 ++++++++++- app/src/main/res/layout/activity_profile.xml | 25 +++++++++---------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index 3f3b648cd..48000f8c5 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -2,6 +2,7 @@ package com.runnect.runnect.presentation.profile import android.os.Bundle import androidx.activity.viewModels +import androidx.core.view.isVisible import com.runnect.runnect.R import com.runnect.runnect.binding.BindingActivity import com.runnect.runnect.databinding.ActivityProfileBinding @@ -42,10 +43,11 @@ class ProfileActivity : BindingActivity(R.layout.activit viewModel.userProfileState.observe(this) { state -> when (state) { is UiStateV2.Loading -> { - // 프로그레스바 + activateLoadingProgressBar() } is UiStateV2.Success -> { + deactivateLoadingProgressBar() binding.data = state.data adapter.submitList(state.data.courseData) } @@ -62,6 +64,16 @@ class ProfileActivity : BindingActivity(R.layout.activit } } + private fun activateLoadingProgressBar() { + binding.clProfile.isVisible = false + binding.pbProfileIntermediate.isVisible = true + } + + private fun deactivateLoadingProgressBar() { + binding.clProfile.isVisible = true + binding.pbProfileIntermediate.isVisible = false + } + companion object { private const val EXTRA_COURSE_USER_ID = "userId" } diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index 405f6e8a2..3b7c50212 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -15,6 +15,7 @@ @@ -50,6 +51,17 @@ + - Date: Fri, 29 Dec 2023 23:14:20 +0900 Subject: [PATCH 21/46] =?UTF-8?q?[CHORE]=20#303=20=EC=8B=A4=ED=8C=A8=20?= =?UTF-8?q?=EC=8B=9C=20=EC=8A=A4=EB=82=B5=EB=B0=94=20=EB=B3=B4=EC=97=AC?= =?UTF-8?q?=EC=A3=BC=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/runnect/presentation/profile/ProfileActivity.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index 48000f8c5..192537805 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -7,6 +7,7 @@ import com.runnect.runnect.R import com.runnect.runnect.binding.BindingActivity import com.runnect.runnect.databinding.ActivityProfileBinding import com.runnect.runnect.presentation.state.UiStateV2 +import com.runnect.runnect.util.extension.showSnackbar import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -53,7 +54,8 @@ class ProfileActivity : BindingActivity(R.layout.activit } is UiStateV2.Failure -> { - + deactivateLoadingProgressBar() + this.showSnackbar(binding.root, state.msg) } else -> { From a09a2cf6f15d2f88d7cbcbbcc16aaad49d1adca8 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Fri, 29 Dec 2023 23:31:26 +0900 Subject: [PATCH 22/46] =?UTF-8?q?[FEAT]=20#303=20=EB=B0=B1=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=A0=84=ED=99=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/presentation/detail/CourseDetailActivity.kt | 1 - .../runnect/runnect/presentation/profile/ProfileActivity.kt | 6 ++++++ app/src/main/res/layout/activity_profile.xml | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt index 995cb3a24..7e481550a 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt @@ -137,7 +137,6 @@ class CourseDetailActivity : private fun navigateToUserProfileWithBundle() { Intent(this@CourseDetailActivity, ProfileActivity::class.java).apply { putExtra(EXTRA_COURSE_USER_ID, courseDetail.userId) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) startActivity(this) } applyScreenExitAnimation() diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index 192537805..982d572f3 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -20,6 +20,7 @@ class ProfileActivity : BindingActivity(R.layout.activit binding.vm = viewModel binding.lifecycleOwner = this initAdapter() + initBackButtonClickListener() getIntentExtra() getUserProfile() setupUserProfileGetStateObserver() @@ -35,6 +36,11 @@ class ProfileActivity : BindingActivity(R.layout.activit } } + private fun initBackButtonClickListener() { + binding.ivProfileBack.setOnClickListener { + finish() + } + } private fun getUserProfile() { viewModel.getUserProfile(userId = userId) diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index 3b7c50212..55aa86c33 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -30,16 +30,20 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/M4" + app:contentInsetStart="0dp" app:layout_constraintTop_toTopOf="@id/cl_profile_toolbar"> Date: Sat, 30 Dec 2023 01:24:11 +0900 Subject: [PATCH 23/46] =?UTF-8?q?[FEAT]=20#303=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=ED=95=9C=20=EC=BD=94=EC=8A=A4=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=9E=A9=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/profile/ProfileActivity.kt | 11 +++++++- .../profile/ProfileCourseAdapter.kt | 18 ++++++++++-- .../presentation/profile/ProfileViewModel.kt | 28 ++++++++++++++++++- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index 982d572f3..b2bcf0008 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -31,11 +31,19 @@ class ProfileActivity : BindingActivity(R.layout.activit } private fun initAdapter() { - adapter = ProfileCourseAdapter().also { adapter -> + adapter = ProfileCourseAdapter( + onLikeButtonClick = { courseId, scrapTF -> + viewModel.postCourseScrap(courseId = courseId, scrapTF = scrapTF) + }, + onCourseItemClick = { courseId -> + // 코스 디테일로 이동 + } + ).also { adapter -> binding.rvProfileUploadCourse.adapter = adapter } } + private fun initBackButtonClickListener() { binding.ivProfileBack.setOnClickListener { finish() @@ -84,5 +92,6 @@ class ProfileActivity : BindingActivity(R.layout.activit companion object { private const val EXTRA_COURSE_USER_ID = "userId" + private const val EXTRA_PUBLIC_COURSE_ID = "publicCourseId" } } \ No newline at end of file diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt index 059c3e46e..8710a55eb 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt @@ -7,8 +7,11 @@ import androidx.recyclerview.widget.RecyclerView import com.runnect.runnect.data.dto.UserCourseData import com.runnect.runnect.databinding.ItemProfileCourseBinding import com.runnect.runnect.util.callback.diff.ItemDiffCallback +import com.runnect.runnect.util.extension.setOnSingleClickListener class ProfileCourseAdapter( + private val onLikeButtonClick: (Int, Boolean) -> Unit, + private val onCourseItemClick: (Int) -> Unit ) : ListAdapter(diffUtil) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UploadedCourseViewHolder { @@ -17,7 +20,9 @@ class ProfileCourseAdapter( LayoutInflater.from(parent.context), parent, false - ) + ), + onLikeButtonClick = onLikeButtonClick, + onCourseItemClick = onCourseItemClick ) } @@ -26,11 +31,20 @@ class ProfileCourseAdapter( } class UploadedCourseViewHolder( - private val binding: ItemProfileCourseBinding + private val binding: ItemProfileCourseBinding, + private val onLikeButtonClick: (Int, Boolean) -> Unit, + private val onCourseItemClick: (Int) -> Unit ) : RecyclerView.ViewHolder(binding.root) { fun bind(userCourseData: UserCourseData) { with(binding) { data = userCourseData + ivItemProfileCourseHeart.setOnSingleClickListener { + onLikeButtonClick(userCourseData.publicCourseId, !userCourseData.scrapTF) + } + + clItemProfileCourse.setOnSingleClickListener { + onCourseItemClick(userCourseData.courseId) + } } } } diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt index 8d58f7051..ef2a50153 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt @@ -5,6 +5,8 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.runnect.runnect.data.dto.UserProfileData +import com.runnect.runnect.data.dto.request.RequestPostCourseScrap +import com.runnect.runnect.domain.repository.CourseRepository import com.runnect.runnect.domain.repository.UserRepository import com.runnect.runnect.presentation.state.UiStateV2 import dagger.hilt.android.lifecycle.HiltViewModel @@ -13,9 +15,15 @@ import timber.log.Timber import javax.inject.Inject @HiltViewModel -class ProfileViewModel @Inject constructor(private val userRepository: UserRepository) : +class ProfileViewModel @Inject constructor( + private val userRepository: UserRepository, + private val courseRepository: CourseRepository +) : ViewModel() { + private val _courseScrapState = MutableLiveData>() + val courseScrapState: LiveData> + get() = _courseScrapState private val _userProfileState = MutableLiveData>() val userProfileState: LiveData> @@ -41,5 +49,23 @@ class ProfileViewModel @Inject constructor(private val userRepository: UserRepos } } } + + fun postCourseScrap(courseId: Int, scrapTF: Boolean) { + viewModelScope.launch { + _courseScrapState.value = UiStateV2.Loading + + courseRepository.postCourseScrap( + RequestPostCourseScrap( + publicCourseId = courseId, scrapTF = scrapTF.toString() + ) + ).onSuccess { response -> + Timber.e("POST COURSE SCRAP SUCCESS") + _courseScrapState.value = UiStateV2.Success(response) + }.onFailure { exception -> + Timber.e("POST COURSE SCRAP FAILURE") + _courseScrapState.value = UiStateV2.Failure(exception.message.toString()) + } + } + } } From fe859fc6c4379b8943f9052ab0243a7272f4603c Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 30 Dec 2023 01:26:52 +0900 Subject: [PATCH 24/46] =?UTF-8?q?[FEAT]=20#303=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=9E=A9=20=EC=84=B1=EA=B3=B5/=EC=B7=A8=EC=86=8C=20=EC=8B=9C,?= =?UTF-8?q?=20=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=A6=89=EC=8B=9C=20=EB=B3=80?= =?UTF-8?q?=EB=8F=99=20=EC=9E=88=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit courseId가 같을 시, 스크랩 여부를 반전하고 notifyItemChanged 를 통해 반영한다 --- .../runnect/runnect/data/dto/UserProfileData.kt | 2 +- .../presentation/profile/ProfileActivity.kt | 1 + .../presentation/profile/ProfileCourseAdapter.kt | 9 +++++++++ app/src/main/res/layout/item_profile_course.xml | 14 ++++++++------ 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/data/dto/UserProfileData.kt b/app/src/main/java/com/runnect/runnect/data/dto/UserProfileData.kt index 240281e11..91c8b9982 100644 --- a/app/src/main/java/com/runnect/runnect/data/dto/UserProfileData.kt +++ b/app/src/main/java/com/runnect/runnect/data/dto/UserProfileData.kt @@ -14,7 +14,7 @@ data class UserCourseData( val title: String, val image: String, val departure: DepartureData, - val scrapTF: Boolean, + var scrapTF: Boolean, ) data class DepartureData( diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index b2bcf0008..b4d4c73d8 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -34,6 +34,7 @@ class ProfileActivity : BindingActivity(R.layout.activit adapter = ProfileCourseAdapter( onLikeButtonClick = { courseId, scrapTF -> viewModel.postCourseScrap(courseId = courseId, scrapTF = scrapTF) + adapter.updateCourseItem(courseId = courseId, scrapTF = scrapTF) }, onCourseItemClick = { courseId -> // 코스 디테일로 이동 diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt index 8710a55eb..a990df6c6 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt @@ -49,6 +49,15 @@ class ProfileCourseAdapter( } } + fun updateCourseItem(courseId: Int, scrapTF: Boolean) { + currentList.forEachIndexed { index, userCourseData -> + if (userCourseData.publicCourseId == courseId) { + userCourseData.scrapTF = scrapTF + notifyItemChanged(index) + } + } + } + companion object { private val diffUtil = ItemDiffCallback( onItemsTheSame = { old, new -> old.courseId == new.courseId }, diff --git a/app/src/main/res/layout/item_profile_course.xml b/app/src/main/res/layout/item_profile_course.xml index 45daaec59..5f8b59c3b 100644 --- a/app/src/main/res/layout/item_profile_course.xml +++ b/app/src/main/res/layout/item_profile_course.xml @@ -11,6 +11,7 @@ @@ -19,15 +20,15 @@ android:layout_height="wrap_content" android:layout_marginHorizontal="3dp" android:layout_marginBottom="20dp" - app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:scale_base_height="154" app:scale_base_width="162"> Date: Sat, 30 Dec 2023 01:34:47 +0900 Subject: [PATCH 25/46] =?UTF-8?q?[FEAT]=20#303=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=ED=95=9C=20=EC=BD=94=EC=8A=A4=20=ED=81=B4=EB=A6=AD=20?= =?UTF-8?q?=EC=8B=9C=20=ED=95=B4=EB=8B=B9=20=EC=83=81=EC=84=B8=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/presentation/profile/ProfileActivity.kt | 12 +++++++++++- .../presentation/profile/ProfileCourseAdapter.kt | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index b4d4c73d8..683bc0a53 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -1,12 +1,15 @@ package com.runnect.runnect.presentation.profile +import android.content.Intent import android.os.Bundle import androidx.activity.viewModels import androidx.core.view.isVisible import com.runnect.runnect.R import com.runnect.runnect.binding.BindingActivity import com.runnect.runnect.databinding.ActivityProfileBinding +import com.runnect.runnect.presentation.detail.CourseDetailActivity import com.runnect.runnect.presentation.state.UiStateV2 +import com.runnect.runnect.util.extension.applyScreenExitAnimation import com.runnect.runnect.util.extension.showSnackbar import dagger.hilt.android.AndroidEntryPoint @@ -37,13 +40,20 @@ class ProfileActivity : BindingActivity(R.layout.activit adapter.updateCourseItem(courseId = courseId, scrapTF = scrapTF) }, onCourseItemClick = { courseId -> - // 코스 디테일로 이동 + navigateToCourseDetail(courseId) } ).also { adapter -> binding.rvProfileUploadCourse.adapter = adapter } } + private fun navigateToCourseDetail(courseId: Int) { + Intent(this@ProfileActivity, CourseDetailActivity::class.java).apply { + putExtra(EXTRA_PUBLIC_COURSE_ID, courseId) + startActivity(this) + } + applyScreenExitAnimation() + } private fun initBackButtonClickListener() { binding.ivProfileBack.setOnClickListener { diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt index a990df6c6..f9b9a4437 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt @@ -43,7 +43,7 @@ class ProfileCourseAdapter( } clItemProfileCourse.setOnSingleClickListener { - onCourseItemClick(userCourseData.courseId) + onCourseItemClick(userCourseData.publicCourseId) } } } From 9ab19a580da1d62e2899d129adc176162a8b18c3 Mon Sep 17 00:00:00 2001 From: unam Date: Mon, 1 Jan 2024 17:10:07 +0900 Subject: [PATCH 26/46] =?UTF-8?q?[FIX]=20#292=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=ED=97=88=EC=9A=A9=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/presentation/coursemain/CourseMainFragment.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt index ea840e15f..609eb938b 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt @@ -95,8 +95,10 @@ class CourseMainFragment : naverMap.minZoom = 10.0 map.locationSource = locationSource - map.locationTrackingMode = LocationTrackingMode.Follow //위치추적 모드 Follow + if(isLocationPermissionGranted()){ + map.locationTrackingMode = LocationTrackingMode.Follow //위치추적 모드 Follow + } //네이버 맵 sdk에 위치 정보 제공 locationSource = FusedLocationSource( From b88821521d2a224034865faa4f033c632bd8ab5a Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Thu, 4 Jan 2024 23:52:36 +0900 Subject: [PATCH 27/46] =?UTF-8?q?[MOD]=20#303=20Extra=20=EA=B0=92=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EA=B3=BC=20=EB=8F=99=EC=9D=BC=ED=95=98?= =?UTF-8?q?=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/runnect/presentation/detail/CourseDetailActivity.kt | 2 +- .../com/runnect/runnect/presentation/profile/ProfileActivity.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt index 7e481550a..ca5039924 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt @@ -620,7 +620,7 @@ class CourseDetailActivity : private const val EXTRA_COURSE_DATA = "CourseData" private const val EXTRA_FRAGMENT_REPLACEMENT_DIRECTION = "fragmentReplacementDirection" private const val EXTRA_FROM_COURSE_DETAIL = "fromCourseDetail" - private const val EXTRA_COURSE_USER_ID = "userId" + private const val EXTRA_COURSE_USER_ID = "courseUserId" private const val POPUP_MENU_X_OFFSET = 17 private const val POPUP_MENU_Y_OFFSET = -10 diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index 683bc0a53..920718964 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -102,7 +102,7 @@ class ProfileActivity : BindingActivity(R.layout.activit } companion object { - private const val EXTRA_COURSE_USER_ID = "userId" + private const val EXTRA_COURSE_USER_ID = "courseUserId" private const val EXTRA_PUBLIC_COURSE_ID = "publicCourseId" } } \ No newline at end of file From 72221d1658d8eb8850a3e10dd8b38bdd2c7b1cb5 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 6 Jan 2024 15:35:28 +0900 Subject: [PATCH 28/46] =?UTF-8?q?[ADD]=20#303=20CourseDetailActivity=20?= =?UTF-8?q?=EB=AC=B4=ED=95=9C=20=EC=83=9D=EC=84=B1=20=EB=B0=A9=EC=A7=80=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20IntentFlag=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/runnect/presentation/profile/ProfileActivity.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index 920718964..4c6c6bd6b 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -9,7 +9,7 @@ import com.runnect.runnect.binding.BindingActivity import com.runnect.runnect.databinding.ActivityProfileBinding import com.runnect.runnect.presentation.detail.CourseDetailActivity import com.runnect.runnect.presentation.state.UiStateV2 -import com.runnect.runnect.util.extension.applyScreenExitAnimation +import com.runnect.runnect.util.extension.applyScreenEnterAnimation import com.runnect.runnect.util.extension.showSnackbar import dagger.hilt.android.AndroidEntryPoint @@ -50,9 +50,10 @@ class ProfileActivity : BindingActivity(R.layout.activit private fun navigateToCourseDetail(courseId: Int) { Intent(this@ProfileActivity, CourseDetailActivity::class.java).apply { putExtra(EXTRA_PUBLIC_COURSE_ID, courseId) + addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) startActivity(this) } - applyScreenExitAnimation() + applyScreenEnterAnimation() } private fun initBackButtonClickListener() { From 4826f1b9818a06c30bf3bf57ad03b541c93f5f07 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 6 Jan 2024 15:39:31 +0900 Subject: [PATCH 29/46] =?UTF-8?q?[FEAT]=20#303=20onNewIntent=20=ED=99=9C?= =?UTF-8?q?=EC=9A=A9=ED=95=B4=20=EC=8A=A4=ED=83=9D=EC=97=90=20=EC=A1=B4?= =?UTF-8?q?=EC=9E=AC=ED=95=98=EB=8D=98=20=EC=95=A1=ED=8B=B0=EB=B9=84?= =?UTF-8?q?=ED=8B=B0=EC=9D=98=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20?= =?UTF-8?q?=EA=B0=B1=EC=8B=A0=ED=95=98=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EXTRA_PUBLIC_COURSE_ID 로 CourseDetail 다시 GET --- .../presentation/detail/CourseDetailActivity.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt index ca5039924..ebb4f7381 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt @@ -137,6 +137,7 @@ class CourseDetailActivity : private fun navigateToUserProfileWithBundle() { Intent(this@CourseDetailActivity, ProfileActivity::class.java).apply { putExtra(EXTRA_COURSE_USER_ID, courseDetail.userId) + addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) startActivity(this) } applyScreenExitAnimation() @@ -149,6 +150,16 @@ class CourseDetailActivity : } } + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + intent?.let { newIntent -> + newIntent.getCompatibleSerializableExtra(EXTRA_ROOT_SCREEN) + ?.let { rootScreen = it } + publicCourseId = newIntent.getIntExtra(EXTRA_PUBLIC_COURSE_ID, 0) + getCourseDetail() + } + } + private fun navigateToPreviousScreen() { if (isFromDeepLink) { navigateToMainScreenWithBundle() From feec2f03ce44d724e5cc38ba948786096000bccb Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 6 Jan 2024 15:42:11 +0900 Subject: [PATCH 30/46] =?UTF-8?q?[ADD]=20#303=20addListener(),=20addObserv?= =?UTF-8?q?er()=EB=A1=9C=20=ED=99=95=EC=9E=A5=EC=84=B1=20=EC=9E=88?= =?UTF-8?q?=EA=B2=8C=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/presentation/profile/ProfileActivity.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index 4c6c6bd6b..9a0c9162e 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -23,10 +23,10 @@ class ProfileActivity : BindingActivity(R.layout.activit binding.vm = viewModel binding.lifecycleOwner = this initAdapter() - initBackButtonClickListener() + addListener() + addObserver() getIntentExtra() getUserProfile() - setupUserProfileGetStateObserver() } private fun getIntentExtra() { @@ -47,6 +47,14 @@ class ProfileActivity : BindingActivity(R.layout.activit } } + private fun addListener() { + initBackButtonClickListener() + } + + private fun addObserver() { + setupUserProfileGetStateObserver() + } + private fun navigateToCourseDetail(courseId: Int) { Intent(this@ProfileActivity, CourseDetailActivity::class.java).apply { putExtra(EXTRA_PUBLIC_COURSE_ID, courseId) From b1f77697f6746f9b6045ac49827deebaae25176e Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 6 Jan 2024 15:44:06 +0900 Subject: [PATCH 31/46] =?UTF-8?q?[CHORE]=20#303=20Timber=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=20=EB=A9=94=EC=8B=9C=EC=A7=80=EC=9D=98=20=EB=A0=88?= =?UTF-8?q?=EB=B2=A8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/presentation/profile/ProfileViewModel.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt index ef2a50153..001f56a01 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt @@ -37,11 +37,11 @@ class ProfileViewModel @Inject constructor( .onSuccess { profileData -> if (profileData == null) { _userProfileState.value = UiStateV2.Failure("PROFILE DATA IS NULL") - Timber.e("PROFILE DATA IS NULL") + Timber.d("PROFILE DATA IS NULL") return@launch } _userProfileState.value = UiStateV2.Success(profileData) - Timber.e("GET PROFILE DATA SUCCESS") + Timber.d("GET PROFILE DATA SUCCESS") } .onFailure { error -> _userProfileState.value = UiStateV2.Failure(error.message.toString()) @@ -59,7 +59,7 @@ class ProfileViewModel @Inject constructor( publicCourseId = courseId, scrapTF = scrapTF.toString() ) ).onSuccess { response -> - Timber.e("POST COURSE SCRAP SUCCESS") + Timber.d("POST COURSE SCRAP SUCCESS") _courseScrapState.value = UiStateV2.Success(response) }.onFailure { exception -> Timber.e("POST COURSE SCRAP FAILURE") From b1a729c063fd3dfd6b36c921aefe0b8d639baa72 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 6 Jan 2024 15:46:43 +0900 Subject: [PATCH 32/46] =?UTF-8?q?[CHORE]=20#303=20=EC=A7=81=EA=B4=80?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=EC=9C=84=ED=95=9C=20onScrapButtonClick=20?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=EC=9D=98=20=EB=84=A4=EC=9D=B4=EB=B0=8D=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 --- .../runnect/presentation/profile/ProfileActivity.kt | 2 +- .../runnect/presentation/profile/ProfileCourseAdapter.kt | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index 9a0c9162e..dc5fbb0c9 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -35,7 +35,7 @@ class ProfileActivity : BindingActivity(R.layout.activit private fun initAdapter() { adapter = ProfileCourseAdapter( - onLikeButtonClick = { courseId, scrapTF -> + onScrapButtonClick = { courseId, scrapTF -> viewModel.postCourseScrap(courseId = courseId, scrapTF = scrapTF) adapter.updateCourseItem(courseId = courseId, scrapTF = scrapTF) }, diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt index f9b9a4437..bc06a43f5 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt @@ -10,7 +10,7 @@ import com.runnect.runnect.util.callback.diff.ItemDiffCallback import com.runnect.runnect.util.extension.setOnSingleClickListener class ProfileCourseAdapter( - private val onLikeButtonClick: (Int, Boolean) -> Unit, + private val onScrapButtonClick: (Int, Boolean) -> Unit, private val onCourseItemClick: (Int) -> Unit ) : ListAdapter(diffUtil) { @@ -21,7 +21,7 @@ class ProfileCourseAdapter( parent, false ), - onLikeButtonClick = onLikeButtonClick, + onScrapButtonClick = onScrapButtonClick, onCourseItemClick = onCourseItemClick ) } @@ -32,14 +32,14 @@ class ProfileCourseAdapter( class UploadedCourseViewHolder( private val binding: ItemProfileCourseBinding, - private val onLikeButtonClick: (Int, Boolean) -> Unit, + private val onScrapButtonClick: (Int, Boolean) -> Unit, private val onCourseItemClick: (Int) -> Unit ) : RecyclerView.ViewHolder(binding.root) { fun bind(userCourseData: UserCourseData) { with(binding) { data = userCourseData ivItemProfileCourseHeart.setOnSingleClickListener { - onLikeButtonClick(userCourseData.publicCourseId, !userCourseData.scrapTF) + onScrapButtonClick(userCourseData.publicCourseId, !userCourseData.scrapTF) } clItemProfileCourse.setOnSingleClickListener { From c80d446a0bb47fb43aa46d2cb8a3df81c889c5e3 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 6 Jan 2024 16:04:13 +0900 Subject: [PATCH 33/46] =?UTF-8?q?[CHORE]=20#303=20=EB=84=A4=EC=9D=B4?= =?UTF-8?q?=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 데이터 클래스의 이름엔 Data 제거 --- .../dto/response/ResponseGetUserProfile.kt | 19 +++++++++---------- .../data/repository/UserRepositoryImpl.kt | 4 ++-- .../entity/UserProfile.kt} | 12 ++++++------ .../domain/repository/UserRepository.kt | 4 ++-- .../profile/ProfileCourseAdapter.kt | 14 +++++++------- app/src/main/res/layout/activity_profile.xml | 2 +- .../main/res/layout/item_profile_course.xml | 2 +- 7 files changed, 28 insertions(+), 29 deletions(-) rename app/src/main/java/com/runnect/runnect/{data/dto/UserProfileData.kt => domain/entity/UserProfile.kt} (64%) diff --git a/app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetUserProfile.kt b/app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetUserProfile.kt index 1995da2cd..c61fff21e 100644 --- a/app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetUserProfile.kt +++ b/app/src/main/java/com/runnect/runnect/data/dto/response/ResponseGetUserProfile.kt @@ -1,9 +1,8 @@ package com.runnect.runnect.data.dto.response -import com.runnect.runnect.data.dto.CourseData -import com.runnect.runnect.data.dto.DepartureData -import com.runnect.runnect.data.dto.UserCourseData -import com.runnect.runnect.data.dto.UserProfileData +import com.runnect.runnect.domain.entity.Departure +import com.runnect.runnect.domain.entity.UserCourse +import com.runnect.runnect.domain.entity.UserProfile import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -58,14 +57,14 @@ data class ResponseGetUserProfile( ) } - fun toUserProfile(): UserProfileData { - val userCourseDataList: List = courses.map { course -> - UserCourseData( + fun toUserProfile(): UserProfile { + val userCourseLists: List = courses.map { course -> + UserCourse( publicCourseId = course.publicCourseId, courseId = course.courseId, title = course.title, image = course.image, - departure = DepartureData( + departure = Departure( region = course.departure.region, city = course.departure.city, town = course.departure.town, @@ -76,12 +75,12 @@ data class ResponseGetUserProfile( ) } - return UserProfileData( + return UserProfile( nickname = user.nickname, level = user.level, levelPercent = user.levelPercent, latestStamp = user.latestStamp, - courseData = userCourseDataList + courseData = userCourseLists ) } diff --git a/app/src/main/java/com/runnect/runnect/data/repository/UserRepositoryImpl.kt b/app/src/main/java/com/runnect/runnect/data/repository/UserRepositoryImpl.kt index b69c81244..8c0bf1081 100644 --- a/app/src/main/java/com/runnect/runnect/data/repository/UserRepositoryImpl.kt +++ b/app/src/main/java/com/runnect/runnect/data/repository/UserRepositoryImpl.kt @@ -1,7 +1,7 @@ package com.runnect.runnect.data.repository import com.runnect.runnect.data.dto.HistoryInfoDTO -import com.runnect.runnect.data.dto.UserProfileData +import com.runnect.runnect.domain.entity.UserProfile import com.runnect.runnect.data.dto.UserUploadCourseDTO import com.runnect.runnect.data.dto.request.RequestDeleteHistory import com.runnect.runnect.data.dto.request.RequestDeleteUploadCourse @@ -37,7 +37,7 @@ class UserRepositoryImpl @Inject constructor(private val remoteUserDataSource: R .toMutableList() } - override suspend fun getUserProfile(userId: Int): Result = + override suspend fun getUserProfile(userId: Int): Result = runCatching { remoteUserDataSource.getUserProfile(userId).data?.toUserProfile() } diff --git a/app/src/main/java/com/runnect/runnect/data/dto/UserProfileData.kt b/app/src/main/java/com/runnect/runnect/domain/entity/UserProfile.kt similarity index 64% rename from app/src/main/java/com/runnect/runnect/data/dto/UserProfileData.kt rename to app/src/main/java/com/runnect/runnect/domain/entity/UserProfile.kt index 91c8b9982..99276137e 100644 --- a/app/src/main/java/com/runnect/runnect/data/dto/UserProfileData.kt +++ b/app/src/main/java/com/runnect/runnect/domain/entity/UserProfile.kt @@ -1,23 +1,23 @@ -package com.runnect.runnect.data.dto +package com.runnect.runnect.domain.entity -data class UserProfileData( +data class UserProfile( val nickname: String, val level: Int, val levelPercent: Int, val latestStamp: String, - val courseData: List + val courseData: List ) -data class UserCourseData( +data class UserCourse( val publicCourseId: Int, val courseId: Int, val title: String, val image: String, - val departure: DepartureData, + val departure: Departure, var scrapTF: Boolean, ) -data class DepartureData( +data class Departure( val region: String, val city: String, val town: String, diff --git a/app/src/main/java/com/runnect/runnect/domain/repository/UserRepository.kt b/app/src/main/java/com/runnect/runnect/domain/repository/UserRepository.kt index bf3c11ef5..bb2713628 100644 --- a/app/src/main/java/com/runnect/runnect/domain/repository/UserRepository.kt +++ b/app/src/main/java/com/runnect/runnect/domain/repository/UserRepository.kt @@ -1,7 +1,7 @@ package com.runnect.runnect.domain.repository import com.runnect.runnect.data.dto.HistoryInfoDTO -import com.runnect.runnect.data.dto.UserProfileData +import com.runnect.runnect.domain.entity.UserProfile import com.runnect.runnect.data.dto.UserUploadCourseDTO import com.runnect.runnect.data.dto.request.RequestDeleteHistory import com.runnect.runnect.data.dto.request.RequestDeleteUploadCourse @@ -25,7 +25,7 @@ interface UserRepository { suspend fun getUserUploadCourse(): MutableList - suspend fun getUserProfile(userId: Int): Result + suspend fun getUserProfile(userId: Int): Result suspend fun putDeleteUploadCourse( requestDeleteUploadCourse: RequestDeleteUploadCourse diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt index bc06a43f5..8d4966a37 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileCourseAdapter.kt @@ -4,7 +4,7 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import com.runnect.runnect.data.dto.UserCourseData +import com.runnect.runnect.domain.entity.UserCourse import com.runnect.runnect.databinding.ItemProfileCourseBinding import com.runnect.runnect.util.callback.diff.ItemDiffCallback import com.runnect.runnect.util.extension.setOnSingleClickListener @@ -12,7 +12,7 @@ import com.runnect.runnect.util.extension.setOnSingleClickListener class ProfileCourseAdapter( private val onScrapButtonClick: (Int, Boolean) -> Unit, private val onCourseItemClick: (Int) -> Unit -) : ListAdapter(diffUtil) { +) : ListAdapter(diffUtil) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UploadedCourseViewHolder { return UploadedCourseViewHolder( @@ -35,15 +35,15 @@ class ProfileCourseAdapter( private val onScrapButtonClick: (Int, Boolean) -> Unit, private val onCourseItemClick: (Int) -> Unit ) : RecyclerView.ViewHolder(binding.root) { - fun bind(userCourseData: UserCourseData) { + fun bind(userCourse: UserCourse) { with(binding) { - data = userCourseData + data = userCourse ivItemProfileCourseHeart.setOnSingleClickListener { - onScrapButtonClick(userCourseData.publicCourseId, !userCourseData.scrapTF) + onScrapButtonClick(userCourse.publicCourseId, !userCourse.scrapTF) } clItemProfileCourse.setOnSingleClickListener { - onCourseItemClick(userCourseData.publicCourseId) + onCourseItemClick(userCourse.publicCourseId) } } } @@ -59,7 +59,7 @@ class ProfileCourseAdapter( } companion object { - private val diffUtil = ItemDiffCallback( + private val diffUtil = ItemDiffCallback( onItemsTheSame = { old, new -> old.courseId == new.courseId }, onContentsTheSame = { old, new -> old == new } ) diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index 55aa86c33..8054c619b 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -7,7 +7,7 @@ + type="com.runnect.runnect.domain.entity.UserProfile" /> diff --git a/app/src/main/res/layout/item_profile_course.xml b/app/src/main/res/layout/item_profile_course.xml index 5f8b59c3b..408b8a100 100644 --- a/app/src/main/res/layout/item_profile_course.xml +++ b/app/src/main/res/layout/item_profile_course.xml @@ -7,7 +7,7 @@ + type="com.runnect.runnect.domain.entity.UserCourse" /> Date: Sat, 6 Jan 2024 16:23:57 +0900 Subject: [PATCH 34/46] =?UTF-8?q?[FEAT]=20#303=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=9E=A9=20POST=20=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=EA=B4=80?= =?UTF-8?q?=EC=B0=B0=ED=95=B4=20=EB=B7=B0=EB=A5=BC=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8=ED=95=98=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 스크랩 버튼 클릭시 해당 코스의 정보를 뷰모델에 Pair로 저장 데이터 클래스의 이름엔 Data 제거 --- .../presentation/profile/ProfileActivity.kt | 43 +++++++++++++++---- .../presentation/profile/ProfileViewModel.kt | 15 +++++-- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index dc5fbb0c9..c92d55148 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -34,15 +34,12 @@ class ProfileActivity : BindingActivity(R.layout.activit } private fun initAdapter() { - adapter = ProfileCourseAdapter( - onScrapButtonClick = { courseId, scrapTF -> - viewModel.postCourseScrap(courseId = courseId, scrapTF = scrapTF) - adapter.updateCourseItem(courseId = courseId, scrapTF = scrapTF) - }, - onCourseItemClick = { courseId -> - navigateToCourseDetail(courseId) - } - ).also { adapter -> + adapter = ProfileCourseAdapter(onScrapButtonClick = { courseId, scrapTF -> + viewModel.postCourseScrap(courseId = courseId, scrapTF = scrapTF) + viewModel.saveScrapCourseData(courseId = courseId, scrapTF = scrapTF) + }, onCourseItemClick = { courseId -> + navigateToCourseDetail(courseId) + }).also { adapter -> binding.rvProfileUploadCourse.adapter = adapter } } @@ -53,6 +50,7 @@ class ProfileActivity : BindingActivity(R.layout.activit private fun addObserver() { setupUserProfileGetStateObserver() + setupCourseScrapPostStateObserver() } private fun navigateToCourseDetail(courseId: Int) { @@ -100,6 +98,33 @@ class ProfileActivity : BindingActivity(R.layout.activit } } + private fun setupCourseScrapPostStateObserver() { + viewModel.courseScrapState.observe(this) { state -> + when (state) { + is UiStateV2.Loading -> { + + } + + is UiStateV2.Success -> { + viewModel.scrapCourseData.value?.let { scrapCourseData -> + scrapCourseData.let { data -> + adapter.updateCourseItem(courseId = data.first, scrapTF = data.second) + } + } + } + + is UiStateV2.Failure -> { + this.showSnackbar(binding.root, state.msg) + } + + else -> { + + } + } + + } + } + private fun activateLoadingProgressBar() { binding.clProfile.isVisible = false binding.pbProfileIntermediate.isVisible = true diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt index 001f56a01..08a9721f4 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt @@ -4,8 +4,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.runnect.runnect.data.dto.UserProfileData import com.runnect.runnect.data.dto.request.RequestPostCourseScrap +import com.runnect.runnect.domain.entity.UserProfile import com.runnect.runnect.domain.repository.CourseRepository import com.runnect.runnect.domain.repository.UserRepository import com.runnect.runnect.presentation.state.UiStateV2 @@ -25,10 +25,19 @@ class ProfileViewModel @Inject constructor( val courseScrapState: LiveData> get() = _courseScrapState - private val _userProfileState = MutableLiveData>() - val userProfileState: LiveData> + private val _userProfileState = MutableLiveData>() + val userProfileState: LiveData> get() = _userProfileState + private val _scrapCourseData = MutableLiveData>() + + val scrapCourseData: LiveData> + get() = _scrapCourseData + + fun saveScrapCourseData(courseId: Int, scrapTF: Boolean) { + _scrapCourseData.value = Pair(courseId, scrapTF) + } + fun getUserProfile(userId: Int) { viewModelScope.launch { _userProfileState.value = UiStateV2.Loading From 9b0cd7ab6fb403a1c7364cc9efbffe6c166b263e Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 6 Jan 2024 16:40:54 +0900 Subject: [PATCH 35/46] =?UTF-8?q?[REFACTOR]=20#292=20departureLatLng?= =?UTF-8?q?=EA=B3=BC=20=EC=97=B0=EA=B4=80=EB=90=9C=20=EA=B5=AC=EB=AC=B8=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B0=B8=EC=A1=B0=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=84=EB=8B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/runnect/runnect/presentation/draw/DrawActivity.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt index f4f084d3e..ec811360c 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt @@ -192,12 +192,13 @@ class DrawActivity : BindingActivity(R.layout.activity_draw tvCustomDepartureGuideFrame.isVisible = true btnPreStart.setOnClickListener { - departureLatLng = getCenterPosition() isMarkerAvailable = true showDrawGuide() hideDeparture() showDrawCourse() - drawCourse(departureLatLng = departureLatLng) + getCenterPosition().apply { + departureLatLng = this + }.let(::drawCourse) hideFloatedDeparture() } } From 289ef2c29185c36086a01f81852c356a747dd7ce Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sun, 7 Jan 2024 11:32:25 +0900 Subject: [PATCH 36/46] =?UTF-8?q?[CHORE]=20#292=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EB=A6=AC?= =?UTF-8?q?=EC=86=8C=EC=8A=A4=20=EC=B6=94=EC=B6=9C=ED=95=B4=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 --- .../presentation/coursemain/CourseMainFragment.kt | 5 +---- .../com/runnect/runnect/util/extension/PermissionExt.kt | 9 +++++---- app/src/main/res/values/strings.xml | 6 ++++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt index 609eb938b..49adf7847 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt @@ -96,7 +96,7 @@ class CourseMainFragment : map.locationSource = locationSource - if(isLocationPermissionGranted()){ + if (isLocationPermissionGranted()) { map.locationTrackingMode = LocationTrackingMode.Follow //위치추적 모드 Follow } @@ -139,8 +139,5 @@ class CourseMainFragment : companion object { private const val LOCATION_PERMISSION_REQUEST_CODE = 1000 - const val PERMISSION_TITLE = "위치권한 요청" - const val PERMISSION_CONTENT = "코스의 출발지 설정과 러닝 트래킹을 위해 현재 위치 정보를 사용하도록 허용합니다." - const val PERMISSION_GUIDE = "권한을 허용해주세요. [설정] > [앱 및 알림] > [고급] > [앱 권한]" } } \ No newline at end of file diff --git a/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt b/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt index 3479cb03e..e65d731b9 100644 --- a/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt +++ b/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt @@ -5,6 +5,7 @@ import android.content.Context import android.widget.Toast import com.gun0912.tedpermission.PermissionListener import com.gun0912.tedpermission.normal.TedPermission +import com.runnect.runnect.R import com.runnect.runnect.presentation.coursemain.CourseMainFragment object PermissionUtil { @@ -18,14 +19,14 @@ object PermissionUtil { override fun onPermissionDenied(deniedPermissions: MutableList?) { Toast.makeText( context, - "위치 권한이 거부되었습니다.", + R.string.location_permission_denied, Toast.LENGTH_SHORT ).show() } }) - .setRationaleTitle(CourseMainFragment.PERMISSION_TITLE) - .setRationaleMessage(CourseMainFragment.PERMISSION_CONTENT) - .setDeniedMessage(CourseMainFragment.PERMISSION_GUIDE) + .setRationaleTitle(R.string.location_permission_title) + .setRationaleMessage(R.string.location_permission_content) + .setDeniedMessage(R.string.location_permission_guide) .setPermissions( Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8564f27dd..0fa72dbf1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -166,4 +166,10 @@ 나에게 최적화된 코스를 찾아보세요 최신순 스크랩순 + + + 위치 권한이 거부되었습니다. + 위치권한 요청 + 코스의 출발지 설정과 러닝 트래킹을 위해 현재 위치 정보를 사용하도록 허용합니다. + 권한을 허용해주세요. [설정] > [앱 및 알림] > [고급] > [앱 권한] \ No newline at end of file From c3bbadbb56622028d2dcc492d5764dcb8df0804c Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sun, 7 Jan 2024 12:54:07 +0900 Subject: [PATCH 37/46] =?UTF-8?q?[REFACTOR]=20#292=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=9C=A0=ED=8B=B8=20=ED=99=95=EC=9E=A5?= =?UTF-8?q?=EC=84=B1=20=EC=9E=88=EA=B2=8C=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 권한 거부 또한 고차함수로 만들어 커스텀 가능하게 변경 - PermissionType Enum 클래스 만들어 권한 타입 관리 - 권한 타입 별로 설정 메시지 띄우는 함수 추가 --- .../coursemain/CourseMainFragment.kt | 34 +++++++++--- .../runnect/presentation/draw/DrawActivity.kt | 21 ++++++-- .../mydrawdetail/MyDrawDetailActivity.kt | 17 +++++- .../presentation/search/SearchActivity.kt | 15 +++++- .../runnect/util/extension/PermissionExt.kt | 54 ++++++++++++++----- 5 files changed, 111 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt index 49adf7847..caf790938 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.view.View +import android.widget.Toast import androidx.core.content.ContextCompat import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices @@ -63,19 +64,26 @@ class CourseMainFragment : initView() } } else { - PermissionUtil.requestLocationPermission(requireContext()) { - cameraUpdate(currentLocation) + context?.let { + PermissionUtil.requestLocationPermission( + it, { cameraUpdate(currentLocation) }, + { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION + ) } } } + private fun initCurrentLocationButtonClickListener() { binding.btnCurrentLocation.setOnClickListener { if (isLocationPermissionGranted()) { cameraUpdate(currentLocation) } else { - PermissionUtil.requestLocationPermission(requireContext()) { - cameraUpdate(currentLocation) + context?.let { + PermissionUtil.requestLocationPermission( + it, { cameraUpdate(currentLocation) }, + { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION + ) } } } @@ -124,10 +132,12 @@ class CourseMainFragment : } private fun isLocationPermissionGranted(): Boolean { - return ContextCompat.checkSelfPermission( - requireContext(), - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED + return context?.let { + ContextCompat.checkSelfPermission( + it, + Manifest.permission.ACCESS_FINE_LOCATION + ) + } == PackageManager.PERMISSION_GRANTED } private fun cameraUpdate(location: LatLng) { @@ -137,6 +147,14 @@ class CourseMainFragment : } + private fun showPermissionDeniedToast() { + Toast.makeText( + context, + R.string.location_permission_denied, + Toast.LENGTH_SHORT + ).show() + } + companion object { private const val LOCATION_PERMISSION_REQUEST_CODE = 1000 } diff --git a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt index ec811360c..c4e1f13a1 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt @@ -309,16 +309,29 @@ class DrawActivity : BindingActivity(R.layout.activity_draw bottomSheetDialog.setContentView(bottomSheetView) btnCreateCourse.setOnClickListener { - PermissionUtil.requestLocationPermission(this) { - hideKeyboard(etCourseName) - bottomSheetDialog.dismiss() - createMBR() + this.let { + PermissionUtil.requestLocationPermission( + it, { + hideKeyboard(etCourseName) + bottomSheetDialog.dismiss() + createMBR() + }, + { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION + ) } } return bottomSheetDialog } + private fun showPermissionDeniedToast() { + Toast.makeText( + this, + R.string.location_permission_denied, + Toast.LENGTH_SHORT + ).show() + } + private fun activateDrawCourse() { binding.btnPreStart.setOnClickListener { isMarkerAvailable = true diff --git a/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt index 1ea2e6edd..778c2f7fa 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt @@ -3,6 +3,7 @@ package com.runnect.runnect.presentation.mydrawdetail import android.content.ContentValues import android.content.Intent import android.os.Bundle +import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.activity.viewModels import androidx.core.net.toUri @@ -92,12 +93,24 @@ class MyDrawDetailActivity : private fun initDrawButtonClickListener() { binding.btnMyDrawDetailRun.setOnClickListener { - PermissionUtil.requestLocationPermission(this) { - toCountDownButton() + + this.let { + PermissionUtil.requestLocationPermission( + it, { toCountDownButton() }, + { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION + ) } } } + private fun showPermissionDeniedToast() { + Toast.makeText( + this, + R.string.location_permission_denied, + Toast.LENGTH_SHORT + ).show() + } + private fun toCountDownButton() { startActivity(Intent(this, CountDownActivity::class.java).apply { putExtra(EXTRA_COURSE_DATA, viewModel.myDrawToRunData.value) diff --git a/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt index f0f46839a..9d033da2c 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt @@ -8,6 +8,7 @@ import android.view.KeyEvent import android.view.MotionEvent import android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH import android.widget.TextView +import android.widget.Toast import androidx.activity.viewModels import androidx.core.content.ContextCompat import androidx.core.view.isVisible @@ -170,8 +171,11 @@ class SearchActivity : BindingActivity(R.layout.activity_ }) binding.cvStartCurrentLocation.setOnClickListener { - PermissionUtil.requestLocationPermission(this) { - startCurrentLocation() + this.let { + PermissionUtil.requestLocationPermission( + it, { startCurrentLocation() }, + { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION + ) } } @@ -180,6 +184,13 @@ class SearchActivity : BindingActivity(R.layout.activity_ } } + private fun showPermissionDeniedToast() { + Toast.makeText( + this, + R.string.location_permission_denied, + Toast.LENGTH_SHORT + ).show() + } private fun startCurrentLocation() { startActivity( diff --git a/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt b/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt index e65d731b9..8c462892c 100644 --- a/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt +++ b/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt @@ -6,10 +6,15 @@ import android.widget.Toast import com.gun0912.tedpermission.PermissionListener import com.gun0912.tedpermission.normal.TedPermission import com.runnect.runnect.R -import com.runnect.runnect.presentation.coursemain.CourseMainFragment object PermissionUtil { - fun requestLocationPermission(context: Context, onPermissionGranted: () -> Unit) { + fun requestLocationPermission( + context: Context, + onPermissionGranted: () -> Unit, + onPermissionDenied: () -> Unit, + permissionType: PermissionType + ) { + val permission = setUpPermissionByType(permissionType) TedPermission.create() .setPermissionListener(object : PermissionListener { override fun onPermissionGranted() { @@ -17,20 +22,41 @@ object PermissionUtil { } override fun onPermissionDenied(deniedPermissions: MutableList?) { - Toast.makeText( - context, - R.string.location_permission_denied, - Toast.LENGTH_SHORT - ).show() + onPermissionDenied() } }) - .setRationaleTitle(R.string.location_permission_title) - .setRationaleMessage(R.string.location_permission_content) - .setDeniedMessage(R.string.location_permission_guide) - .setPermissions( - Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION - ) + .setRationaleTitle(permission.title) + .setRationaleMessage(permission.content) + .setDeniedMessage(permission.guide) + .setPermissions(*permission.permissions.toTypedArray()) .check() } + + enum class PermissionType { + LOCATION, + // 필요한 권한 있을 시 추가 + } + + data class PermissionInfo( + val permissions: List, + val title: Int, + val content: Int, + val guide: Int + ) + + private fun setUpPermissionByType(permissionType: PermissionType): PermissionInfo { + return when (permissionType) { + PermissionType.LOCATION -> { + PermissionInfo( + listOf( + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION + ), + R.string.location_permission_title, + R.string.location_permission_content, + R.string.location_permission_guide + ) + } + } + } } \ No newline at end of file From fe8fdcd48a73ad1195fde1509ef3a88318e0eb5f Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sun, 7 Jan 2024 12:56:19 +0900 Subject: [PATCH 38/46] =?UTF-8?q?[ADD]=20#292=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EA=B1=B0=EB=B6=80=20=EC=8B=9C=20=EA=B8=B0=EB=B3=B8=20=ED=86=A0?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=9D=84?= =?UTF-8?q?=EC=9B=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/runnect/runnect/util/extension/PermissionExt.kt | 8 +++++++- app/src/main/res/values/strings.xml | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt b/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt index 8c462892c..069465d03 100644 --- a/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt +++ b/app/src/main/java/com/runnect/runnect/util/extension/PermissionExt.kt @@ -11,7 +11,13 @@ object PermissionUtil { fun requestLocationPermission( context: Context, onPermissionGranted: () -> Unit, - onPermissionDenied: () -> Unit, + onPermissionDenied: () -> Unit = { + Toast.makeText( + context, + R.string.common_permission_denied, + Toast.LENGTH_SHORT + ).show() + }, permissionType: PermissionType ) { val permission = setUpPermissionByType(permissionType) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0fa72dbf1..1db596b9e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -167,6 +167,7 @@ 최신순 스크랩순 + 권한이 거부되었습니다. 위치 권한이 거부되었습니다. 위치권한 요청 From 49afa45a5ecf4f70a59db85488e43bfac1a649c5 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sun, 7 Jan 2024 13:00:12 +0900 Subject: [PATCH 39/46] =?UTF-8?q?[CHORE]=20#292=20=EC=BB=A8=EB=B2=A4?= =?UTF-8?q?=EC=85=98=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 동사 - 명사 순 --- .../runnect/presentation/coursemain/CourseMainFragment.kt | 8 ++++---- .../presentation/mydrawdetail/MyDrawDetailActivity.kt | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt index caf790938..e0418a935 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt @@ -66,7 +66,7 @@ class CourseMainFragment : } else { context?.let { PermissionUtil.requestLocationPermission( - it, { cameraUpdate(currentLocation) }, + it, { updateCamera(currentLocation) }, { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION ) } @@ -77,11 +77,11 @@ class CourseMainFragment : private fun initCurrentLocationButtonClickListener() { binding.btnCurrentLocation.setOnClickListener { if (isLocationPermissionGranted()) { - cameraUpdate(currentLocation) + updateCamera(currentLocation) } else { context?.let { PermissionUtil.requestLocationPermission( - it, { cameraUpdate(currentLocation) }, + it, { updateCamera(currentLocation) }, { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION ) } @@ -140,7 +140,7 @@ class CourseMainFragment : } == PackageManager.PERMISSION_GRANTED } - private fun cameraUpdate(location: LatLng) { + private fun updateCamera(location: LatLng) { val cameraUpdate = CameraUpdate.scrollTo(LatLng(location.latitude, location.longitude)) .animate(CameraAnimation.Easing) naverMap.moveCamera(cameraUpdate) diff --git a/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt index 778c2f7fa..116fed059 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt @@ -96,7 +96,7 @@ class MyDrawDetailActivity : this.let { PermissionUtil.requestLocationPermission( - it, { toCountDownButton() }, + it, { navigateToCountDown() }, { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION ) } @@ -111,7 +111,7 @@ class MyDrawDetailActivity : ).show() } - private fun toCountDownButton() { + private fun navigateToCountDown() { startActivity(Intent(this, CountDownActivity::class.java).apply { putExtra(EXTRA_COURSE_DATA, viewModel.myDrawToRunData.value) }) From cbc3f17f325a16c8972bbda0d92abf1248e87a16 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Mon, 8 Jan 2024 02:36:09 +0900 Subject: [PATCH 40/46] =?UTF-8?q?[FIX]=20#303=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EB=A7=88=EC=A7=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../res/layout/activity_course_detail.xml | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/app/src/main/res/layout/activity_course_detail.xml b/app/src/main/res/layout/activity_course_detail.xml index 98a48a8c1..32b5f29bb 100644 --- a/app/src/main/res/layout/activity_course_detail.xml +++ b/app/src/main/res/layout/activity_course_detail.xml @@ -178,7 +178,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="15dp" - android:layout_marginTop="14dp" + android:layout_marginTop="18dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tv_course_detail_title" app:srcCompat="@drawable/all_star" /> @@ -200,7 +200,7 @@ android:id="@+id/tv_course_detail_distance" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="34dp" + android:layout_marginStart="36dp" android:fontFamily="@font/pretendard_regular" android:text="@{courseDetail.distance}" android:textColor="@color/G1" @@ -227,7 +227,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="15dp" - android:layout_marginTop="8dp" + android:layout_marginTop="9dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/iv_course_detail_distance_indicator" app:srcCompat="@drawable/all_star" /> @@ -249,7 +249,7 @@ android:id="@+id/tv_course_detail_departure" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="23dp" + android:layout_marginStart="25dp" android:ellipsize="end" android:fontFamily="@font/pretendard_regular" android:maxLength="25" @@ -299,7 +299,7 @@ android:id="@+id/cl_course_detail_bottom_container" android:layout_width="0dp" android:layout_height="wrap_content" - android:paddingBottom="34dp" + android:layout_marginBottom="18dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"> @@ -308,8 +308,8 @@ android:id="@+id/iv_course_detail_scrap" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="26dp" - android:layout_marginTop="13dp" + android:layout_marginStart="16dp" + android:layout_marginTop="17dp" android:layout_marginEnd="17dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" @@ -319,11 +319,11 @@ android:id="@+id/tv_course_detail_scrap_count" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="10dp" + android:layout_marginTop="2dp" android:fontFamily="@font/pretendard_semibold" android:text="@{courseDetail.scrapCount}" android:textColor="@color/G2" - android:textSize="11sp" + android:textSize="10sp" app:layout_constraintEnd_toEndOf="@id/iv_course_detail_scrap" app:layout_constraintStart_toStartOf="@id/iv_course_detail_scrap" app:layout_constraintTop_toBottomOf="@id/iv_course_detail_scrap" @@ -332,9 +332,10 @@ Date: Mon, 8 Jan 2024 02:37:58 +0900 Subject: [PATCH 41/46] =?UTF-8?q?[MOD]=20#303=20exit=20->=20enter=EB=A1=9C?= =?UTF-8?q?=20=EC=A7=84=EC=9E=85=20=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/presentation/detail/CourseDetailActivity.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt index 13bc07958..59c90fde6 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt @@ -48,6 +48,7 @@ import com.runnect.runnect.util.custom.dialog.RequireLoginDialogFragment import com.runnect.runnect.util.custom.popup.PopupItem import com.runnect.runnect.util.custom.popup.RunnectPopupMenu import com.runnect.runnect.util.custom.toast.RunnectToast +import com.runnect.runnect.util.extension.applyScreenEnterAnimation import com.runnect.runnect.util.extension.applyScreenExitAnimation import com.runnect.runnect.util.extension.getCompatibleSerializableExtra import com.runnect.runnect.util.extension.getStampResId @@ -140,7 +141,7 @@ class CourseDetailActivity : addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) startActivity(this) } - applyScreenExitAnimation() + applyScreenEnterAnimation() } private fun handleBackButtonByCurrentScreenMode() { From ee5fd14a6242ad0ed6df4bdf9ab7f723462268f7 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Mon, 8 Jan 2024 02:47:49 +0900 Subject: [PATCH 42/46] =?UTF-8?q?[MOD]=20#292=20showToast=20Util=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/presentation/coursemain/CourseMainFragment.kt | 8 ++------ .../com/runnect/runnect/presentation/draw/DrawActivity.kt | 7 ++----- .../presentation/mydrawdetail/MyDrawDetailActivity.kt | 8 ++------ .../runnect/runnect/presentation/search/SearchActivity.kt | 8 ++------ 4 files changed, 8 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt index e0418a935..b42a16085 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt @@ -5,7 +5,6 @@ import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.view.View -import android.widget.Toast import androidx.core.content.ContextCompat import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices @@ -23,6 +22,7 @@ import com.runnect.runnect.binding.BindingFragment import com.runnect.runnect.databinding.FragmentCourseMainBinding import com.runnect.runnect.presentation.search.SearchActivity import com.runnect.runnect.util.extension.PermissionUtil +import com.runnect.runnect.util.extension.showToast class CourseMainFragment : @@ -148,11 +148,7 @@ class CourseMainFragment : } private fun showPermissionDeniedToast() { - Toast.makeText( - context, - R.string.location_permission_denied, - Toast.LENGTH_SHORT - ).show() + showToast(getString(R.string.location_permission_denied)) } companion object { diff --git a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt index c4e1f13a1..1dda08ace 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt @@ -49,6 +49,7 @@ import com.runnect.runnect.util.custom.dialog.RequireLoginDialogFragment import com.runnect.runnect.util.extension.PermissionUtil import com.runnect.runnect.util.extension.hideKeyboard import com.runnect.runnect.util.extension.setActivityDialog +import com.runnect.runnect.util.extension.showToast import com.runnect.runnect.util.multipart.ContentUriRequestBody import dagger.hilt.android.AndroidEntryPoint import kotlinx.android.synthetic.main.custom_dialog_make_course.view.btn_run @@ -325,11 +326,7 @@ class DrawActivity : BindingActivity(R.layout.activity_draw } private fun showPermissionDeniedToast() { - Toast.makeText( - this, - R.string.location_permission_denied, - Toast.LENGTH_SHORT - ).show() + showToast(getString(R.string.location_permission_denied)) } private fun activateDrawCourse() { diff --git a/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt index 116fed059..aeb1494e9 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt @@ -3,7 +3,6 @@ package com.runnect.runnect.presentation.mydrawdetail import android.content.ContentValues import android.content.Intent import android.os.Bundle -import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.activity.viewModels import androidx.core.net.toUri @@ -19,6 +18,7 @@ import com.runnect.runnect.presentation.countdown.CountDownActivity import com.runnect.runnect.util.extension.PermissionUtil import com.runnect.runnect.util.extension.navigateToPreviousScreenWithAnimation import com.runnect.runnect.util.extension.setActivityDialog +import com.runnect.runnect.util.extension.showToast import dagger.hilt.android.AndroidEntryPoint import kotlinx.android.synthetic.main.custom_dialog_delete.view.btn_delete_no import kotlinx.android.synthetic.main.custom_dialog_delete.view.btn_delete_yes @@ -104,11 +104,7 @@ class MyDrawDetailActivity : } private fun showPermissionDeniedToast() { - Toast.makeText( - this, - R.string.location_permission_denied, - Toast.LENGTH_SHORT - ).show() + showToast(getString(R.string.location_permission_denied)) } private fun navigateToCountDown() { diff --git a/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt index 9d033da2c..5fc459b5d 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt @@ -8,7 +8,6 @@ import android.view.KeyEvent import android.view.MotionEvent import android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH import android.widget.TextView -import android.widget.Toast import androidx.activity.viewModels import androidx.core.content.ContextCompat import androidx.core.view.isVisible @@ -25,6 +24,7 @@ import com.runnect.runnect.util.callback.listener.OnSearchItemClick import com.runnect.runnect.util.extension.PermissionUtil import com.runnect.runnect.util.extension.hideKeyboard import com.runnect.runnect.util.extension.showKeyboard +import com.runnect.runnect.util.extension.showToast import dagger.hilt.android.AndroidEntryPoint import timber.log.Timber @@ -185,11 +185,7 @@ class SearchActivity : BindingActivity(R.layout.activity_ } private fun showPermissionDeniedToast() { - Toast.makeText( - this, - R.string.location_permission_denied, - Toast.LENGTH_SHORT - ).show() + showToast(getString(R.string.location_permission_denied)) } private fun startCurrentLocation() { From 9797cdbd5e7d5f02c665bb5a9d1707e3ab527c9b Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Mon, 8 Jan 2024 02:52:49 +0900 Subject: [PATCH 43/46] =?UTF-8?q?[CHORE]=20#292=20named=20Argument=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/coursemain/CourseMainFragment.kt | 12 ++++++++---- .../runnect/presentation/draw/DrawActivity.kt | 6 ++++-- .../mydrawdetail/MyDrawDetailActivity.kt | 7 ++++--- .../runnect/presentation/search/SearchActivity.kt | 6 ++++-- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt index b42a16085..12b398503 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/coursemain/CourseMainFragment.kt @@ -66,8 +66,10 @@ class CourseMainFragment : } else { context?.let { PermissionUtil.requestLocationPermission( - it, { updateCamera(currentLocation) }, - { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION + context = it, + onPermissionGranted = { updateCamera(currentLocation) }, + onPermissionDenied = { showPermissionDeniedToast() }, + permissionType = PermissionUtil.PermissionType.LOCATION ) } } @@ -81,8 +83,10 @@ class CourseMainFragment : } else { context?.let { PermissionUtil.requestLocationPermission( - it, { updateCamera(currentLocation) }, - { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION + context = it, + onPermissionGranted = { updateCamera(currentLocation) }, + onPermissionDenied = { showPermissionDeniedToast() }, + permissionType = PermissionUtil.PermissionType.LOCATION ) } } diff --git a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt index 1dda08ace..64742a410 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt @@ -312,12 +312,14 @@ class DrawActivity : BindingActivity(R.layout.activity_draw btnCreateCourse.setOnClickListener { this.let { PermissionUtil.requestLocationPermission( - it, { + context = it, + onPermissionGranted = { hideKeyboard(etCourseName) bottomSheetDialog.dismiss() createMBR() }, - { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION + onPermissionDenied = { showPermissionDeniedToast() }, + permissionType = PermissionUtil.PermissionType.LOCATION ) } } diff --git a/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt index aeb1494e9..16344e6d2 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/mydrawdetail/MyDrawDetailActivity.kt @@ -93,11 +93,12 @@ class MyDrawDetailActivity : private fun initDrawButtonClickListener() { binding.btnMyDrawDetailRun.setOnClickListener { - this.let { PermissionUtil.requestLocationPermission( - it, { navigateToCountDown() }, - { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION + context = it, + onPermissionGranted = { navigateToCountDown() }, + onPermissionDenied = { showPermissionDeniedToast() }, + permissionType = PermissionUtil.PermissionType.LOCATION ) } } diff --git a/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt index 5fc459b5d..7b00996db 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/search/SearchActivity.kt @@ -173,8 +173,10 @@ class SearchActivity : BindingActivity(R.layout.activity_ binding.cvStartCurrentLocation.setOnClickListener { this.let { PermissionUtil.requestLocationPermission( - it, { startCurrentLocation() }, - { showPermissionDeniedToast() }, PermissionUtil.PermissionType.LOCATION + context = it, + onPermissionGranted = { startCurrentLocation() }, + onPermissionDenied = { showPermissionDeniedToast() }, + permissionType = PermissionUtil.PermissionType.LOCATION ) } } From e672516993d4b5c080a5124c90c9b8ae2509366a Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Tue, 9 Jan 2024 22:14:12 +0900 Subject: [PATCH 44/46] =?UTF-8?q?[ADD]=20#303=20response=20=EA=B0=92=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=9E=A9=20=EC=84=9C=EB=B2=84=ED=86=B5=EC=8B=A0=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runnect/data/dto/response/ResponsePostScrap.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 app/src/main/java/com/runnect/runnect/data/dto/response/ResponsePostScrap.kt diff --git a/app/src/main/java/com/runnect/runnect/data/dto/response/ResponsePostScrap.kt b/app/src/main/java/com/runnect/runnect/data/dto/response/ResponsePostScrap.kt new file mode 100644 index 000000000..cd5d3b0ae --- /dev/null +++ b/app/src/main/java/com/runnect/runnect/data/dto/response/ResponsePostScrap.kt @@ -0,0 +1,14 @@ +package com.runnect.runnect.data.dto.response + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponsePostScrap( + @SerialName("publicCourseId") + val publicCourseId: Long, + @SerialName("scrapCount") + val scrapCount: Long, + @SerialName("scrapTF") + val scrapTF: Boolean +) \ No newline at end of file From 52fd46cbb8e0f41ad03a7c5d42e98e89cae30838 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Tue, 9 Jan 2024 22:14:59 +0900 Subject: [PATCH 45/46] =?UTF-8?q?[MOD]=20#303=20response=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=9E=A9=20=EA=B8=B0=EC=A1=B4=20=EC=BD=94=EB=93=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 --- .../runnect/data/repository/CourseRepositoryImpl.kt | 3 ++- .../runnect/runnect/data/service/CourseService.kt | 6 +++--- .../data/source/remote/RemoteCourseDataSource.kt | 11 ++++++----- .../runnect/domain/repository/CourseRepository.kt | 13 +++++++++---- .../presentation/detail/CourseDetailViewModel.kt | 11 ++++++----- .../presentation/discover/DiscoverViewModel.kt | 5 +++-- 6 files changed, 29 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/data/repository/CourseRepositoryImpl.kt b/app/src/main/java/com/runnect/runnect/data/repository/CourseRepositoryImpl.kt index c8622db4c..540a03cd1 100644 --- a/app/src/main/java/com/runnect/runnect/data/repository/CourseRepositoryImpl.kt +++ b/app/src/main/java/com/runnect/runnect/data/repository/CourseRepositoryImpl.kt @@ -12,6 +12,7 @@ import com.runnect.runnect.data.dto.response.ResponsePostMyDrawCourse import com.runnect.runnect.data.dto.response.ResponsePostMyHistory import com.runnect.runnect.data.dto.response.ResponsePutMyDrawCourse import com.runnect.runnect.data.dto.response.ResponsePostDiscoverUpload +import com.runnect.runnect.data.dto.response.ResponsePostScrap import com.runnect.runnect.data.source.remote.RemoteCourseDataSource import com.runnect.runnect.domain.entity.DiscoverSearchCourse import com.runnect.runnect.domain.entity.DiscoverMultiViewItem.* @@ -100,7 +101,7 @@ class CourseRepositoryImpl @Inject constructor(private val remoteCourseDataSourc override suspend fun postCourseScrap( requestPostCourseScrap: RequestPostCourseScrap - ): Result = runCatching { + ): Result = runCatching { remoteCourseDataSource.postCourseScrap(requestPostCourseScrap = requestPostCourseScrap).data } } \ No newline at end of file diff --git a/app/src/main/java/com/runnect/runnect/data/service/CourseService.kt b/app/src/main/java/com/runnect/runnect/data/service/CourseService.kt index 64a8225ad..aa579c61b 100644 --- a/app/src/main/java/com/runnect/runnect/data/service/CourseService.kt +++ b/app/src/main/java/com/runnect/runnect/data/service/CourseService.kt @@ -1,10 +1,10 @@ package com.runnect.runnect.data.service +import com.runnect.runnect.data.dto.request.RequestPatchPublicCourse import com.runnect.runnect.data.dto.request.RequestPostCourseScrap +import com.runnect.runnect.data.dto.request.RequestPostPublicCourse import com.runnect.runnect.data.dto.request.RequestPostRunningHistory import com.runnect.runnect.data.dto.request.RequestPutMyDrawCourse -import com.runnect.runnect.data.dto.request.RequestPatchPublicCourse -import com.runnect.runnect.data.dto.request.RequestPostPublicCourse import com.runnect.runnect.data.dto.response.* import com.runnect.runnect.data.dto.response.base.BaseResponse import okhttp3.MultipartBody @@ -25,7 +25,7 @@ interface CourseService { @POST("/api/scrap") suspend fun postCourseScrap( @Body requestPostCourseScrap: RequestPostCourseScrap, - ): BaseResponse + ): BaseResponse @GET("/api/public-course/search?") suspend fun getCourseSearch( diff --git a/app/src/main/java/com/runnect/runnect/data/source/remote/RemoteCourseDataSource.kt b/app/src/main/java/com/runnect/runnect/data/source/remote/RemoteCourseDataSource.kt index fecd2ff75..ffb83942d 100644 --- a/app/src/main/java/com/runnect/runnect/data/source/remote/RemoteCourseDataSource.kt +++ b/app/src/main/java/com/runnect/runnect/data/source/remote/RemoteCourseDataSource.kt @@ -1,16 +1,17 @@ package com.runnect.runnect.data.source.remote -import com.runnect.runnect.data.service.CourseService +import com.runnect.runnect.data.dto.request.RequestPatchPublicCourse import com.runnect.runnect.data.dto.request.RequestPostCourseScrap +import com.runnect.runnect.data.dto.request.RequestPostPublicCourse import com.runnect.runnect.data.dto.request.RequestPostRunningHistory import com.runnect.runnect.data.dto.request.RequestPutMyDrawCourse -import com.runnect.runnect.data.dto.request.RequestPatchPublicCourse -import com.runnect.runnect.data.dto.request.RequestPostPublicCourse import com.runnect.runnect.data.dto.response.ResponseGetCourseDetail import com.runnect.runnect.data.dto.response.ResponseGetDiscoverMarathon -import com.runnect.runnect.data.dto.response.ResponsePatchPublicCourse import com.runnect.runnect.data.dto.response.ResponseGetDiscoverRecommend +import com.runnect.runnect.data.dto.response.ResponsePatchPublicCourse +import com.runnect.runnect.data.dto.response.ResponsePostScrap import com.runnect.runnect.data.dto.response.base.BaseResponse +import com.runnect.runnect.data.service.CourseService import okhttp3.MultipartBody import okhttp3.RequestBody import javax.inject.Inject @@ -27,7 +28,7 @@ class RemoteCourseDataSource @Inject constructor( ): BaseResponse = courseService.getRecommendCourse(pageNo = pageNo, ordering = ordering) - suspend fun postCourseScrap(requestPostCourseScrap: RequestPostCourseScrap): BaseResponse = + suspend fun postCourseScrap(requestPostCourseScrap: RequestPostCourseScrap): BaseResponse = courseService.postCourseScrap(requestPostCourseScrap) suspend fun getCourseSearch(keyword: String) = courseService.getCourseSearch(keyword) diff --git a/app/src/main/java/com/runnect/runnect/domain/repository/CourseRepository.kt b/app/src/main/java/com/runnect/runnect/domain/repository/CourseRepository.kt index 02665c5e1..ec56b0e9b 100644 --- a/app/src/main/java/com/runnect/runnect/domain/repository/CourseRepository.kt +++ b/app/src/main/java/com/runnect/runnect/domain/repository/CourseRepository.kt @@ -10,12 +10,13 @@ import com.runnect.runnect.data.dto.response.ResponseGetMyDrawDetail import com.runnect.runnect.data.dto.response.ResponsePostDiscoverUpload import com.runnect.runnect.data.dto.response.ResponsePostMyDrawCourse import com.runnect.runnect.data.dto.response.ResponsePostMyHistory +import com.runnect.runnect.data.dto.response.ResponsePostScrap import com.runnect.runnect.data.dto.response.ResponsePutMyDrawCourse import com.runnect.runnect.domain.entity.CourseDetail +import com.runnect.runnect.domain.entity.DiscoverMultiViewItem.MarathonCourse import com.runnect.runnect.domain.entity.DiscoverSearchCourse -import com.runnect.runnect.domain.entity.DiscoverMultiViewItem.* -import com.runnect.runnect.domain.entity.RecommendCoursePagingData import com.runnect.runnect.domain.entity.EditableCourseDetail +import com.runnect.runnect.domain.entity.RecommendCoursePagingData import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.Response @@ -23,7 +24,10 @@ import retrofit2.Response interface CourseRepository { suspend fun getMarathonCourse(): Result?> - suspend fun getRecommendCourse(pageNo: String, ordering: String): Result + suspend fun getRecommendCourse( + pageNo: String, + ordering: String + ): Result suspend fun getCourseSearch(keyword: String): Result?> @@ -40,6 +44,7 @@ interface CourseRepository { suspend fun uploadCourse( image: MultipartBody.Part, courseCreateRequestDto: RequestBody ): Response + suspend fun getCourseDetail(publicCourseId: Int): Result suspend fun patchPublicCourse( @@ -47,5 +52,5 @@ interface CourseRepository { requestPatchPublicCourse: RequestPatchPublicCourse ): Result - suspend fun postCourseScrap(requestPostCourseScrap: RequestPostCourseScrap): Result + suspend fun postCourseScrap(requestPostCourseScrap: RequestPostCourseScrap): Result } \ No newline at end of file diff --git a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailViewModel.kt b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailViewModel.kt index 400a5ca05..895cd711b 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailViewModel.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailViewModel.kt @@ -5,14 +5,15 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.map import androidx.lifecycle.viewModelScope -import com.runnect.runnect.data.dto.request.RequestPostCourseScrap import com.runnect.runnect.data.dto.request.RequestDeleteUploadCourse import com.runnect.runnect.data.dto.request.RequestPatchPublicCourse +import com.runnect.runnect.data.dto.request.RequestPostCourseScrap import com.runnect.runnect.data.dto.response.ResponseDeleteUploadCourse -import com.runnect.runnect.domain.repository.CourseRepository -import com.runnect.runnect.domain.repository.UserRepository +import com.runnect.runnect.data.dto.response.ResponsePostScrap import com.runnect.runnect.domain.entity.CourseDetail import com.runnect.runnect.domain.entity.EditableCourseDetail +import com.runnect.runnect.domain.repository.CourseRepository +import com.runnect.runnect.domain.repository.UserRepository import com.runnect.runnect.presentation.state.UiStateV2 import com.runnect.runnect.util.mode.ScreenMode import dagger.hilt.android.lifecycle.HiltViewModel @@ -37,8 +38,8 @@ class CourseDetailViewModel @Inject constructor( val courseDeleteState: LiveData> get() = _courseDeleteState - private var _courseScrapState = MutableLiveData>() - val courseScrapState: LiveData> + private var _courseScrapState = MutableLiveData>() + val courseScrapState: LiveData> get() = _courseScrapState // 플래그 변수 diff --git a/app/src/main/java/com/runnect/runnect/presentation/discover/DiscoverViewModel.kt b/app/src/main/java/com/runnect/runnect/presentation/discover/DiscoverViewModel.kt index f76fe6d8c..e6c5e129f 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/discover/DiscoverViewModel.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/discover/DiscoverViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.runnect.runnect.data.dto.request.RequestPostCourseScrap +import com.runnect.runnect.data.dto.response.ResponsePostScrap import com.runnect.runnect.domain.entity.DiscoverMultiViewItem import com.runnect.runnect.domain.entity.DiscoverMultiViewItem.* import com.runnect.runnect.domain.entity.DiscoverBanner @@ -39,8 +40,8 @@ class DiscoverViewModel @Inject constructor( val nextPageState: LiveData>> get() = _nextPageState - private val _courseScrapState = MutableLiveData>() - val courseScrapState: LiveData> + private val _courseScrapState = MutableLiveData>() + val courseScrapState: LiveData> get() = _courseScrapState private val _multiViewItems: MutableList> = mutableListOf() From 77db0a19dfd2c61a8da2516f2d1043724ec0d3d6 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Tue, 9 Jan 2024 22:15:40 +0900 Subject: [PATCH 46/46] =?UTF-8?q?[MOD]=20#303=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=8A=A4=ED=81=AC=EB=9E=A9=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/profile/ProfileActivity.kt | 10 +++++----- .../presentation/profile/ProfileViewModel.kt | 14 +++----------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt index c92d55148..21d30c6d7 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileActivity.kt @@ -36,7 +36,6 @@ class ProfileActivity : BindingActivity(R.layout.activit private fun initAdapter() { adapter = ProfileCourseAdapter(onScrapButtonClick = { courseId, scrapTF -> viewModel.postCourseScrap(courseId = courseId, scrapTF = scrapTF) - viewModel.saveScrapCourseData(courseId = courseId, scrapTF = scrapTF) }, onCourseItemClick = { courseId -> navigateToCourseDetail(courseId) }).also { adapter -> @@ -106,10 +105,11 @@ class ProfileActivity : BindingActivity(R.layout.activit } is UiStateV2.Success -> { - viewModel.scrapCourseData.value?.let { scrapCourseData -> - scrapCourseData.let { data -> - adapter.updateCourseItem(courseId = data.first, scrapTF = data.second) - } + state.data?.let { it -> + adapter.updateCourseItem( + courseId = it.publicCourseId.toInt(), + scrapTF = it.scrapTF + ) } } diff --git a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt index 08a9721f4..b518cc418 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/profile/ProfileViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.runnect.runnect.data.dto.request.RequestPostCourseScrap +import com.runnect.runnect.data.dto.response.ResponsePostScrap import com.runnect.runnect.domain.entity.UserProfile import com.runnect.runnect.domain.repository.CourseRepository import com.runnect.runnect.domain.repository.UserRepository @@ -21,22 +22,14 @@ class ProfileViewModel @Inject constructor( ) : ViewModel() { - private val _courseScrapState = MutableLiveData>() - val courseScrapState: LiveData> + private val _courseScrapState = MutableLiveData>() + val courseScrapState: LiveData> get() = _courseScrapState private val _userProfileState = MutableLiveData>() val userProfileState: LiveData> get() = _userProfileState - private val _scrapCourseData = MutableLiveData>() - - val scrapCourseData: LiveData> - get() = _scrapCourseData - - fun saveScrapCourseData(courseId: Int, scrapTF: Boolean) { - _scrapCourseData.value = Pair(courseId, scrapTF) - } fun getUserProfile(userId: Int) { viewModelScope.launch { @@ -62,7 +55,6 @@ class ProfileViewModel @Inject constructor( fun postCourseScrap(courseId: Int, scrapTF: Boolean) { viewModelScope.launch { _courseScrapState.value = UiStateV2.Loading - courseRepository.postCourseScrap( RequestPostCourseScrap( publicCourseId = courseId, scrapTF = scrapTF.toString()