From 278ca7552db600c23507a37d0979859d76a3bd52 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 08:06:51 +0900 Subject: [PATCH 01/25] [CHORE/#394] version update 1.3.3 -> 1.3.4 --- .../terning/data/mypage/datasource/MyPageDataSource.kt | 5 +++++ .../data/mypage/datasourceimpl/MyPageDataSourceImpl.kt | 4 ++++ .../data/mypage/dto/request/AlarmStatusRequestDto.kt | 10 ++++++++++ .../terning/data/mypage/mapper/AlarmStatusMapper.kt | 9 +++++++++ .../data/mypage/repositoryimpl/MyPageRepositoryImpl.kt | 7 +++++++ .../com/terning/data/mypage/service/MyPageService.kt | 6 ++++++ .../com/terning/domain/mypage/entity/AlarmStatus.kt | 5 +++++ .../domain/mypage/repository/MyPageRepository.kt | 5 +++++ 8 files changed, 51 insertions(+) create mode 100644 data/mypage/src/main/java/com/terning/data/mypage/dto/request/AlarmStatusRequestDto.kt create mode 100644 data/mypage/src/main/java/com/terning/data/mypage/mapper/AlarmStatusMapper.kt create mode 100644 domain/mypage/src/main/java/com/terning/domain/mypage/entity/AlarmStatus.kt diff --git a/data/mypage/src/main/java/com/terning/data/mypage/datasource/MyPageDataSource.kt b/data/mypage/src/main/java/com/terning/data/mypage/datasource/MyPageDataSource.kt index 82733b8f2..0aca8338a 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/datasource/MyPageDataSource.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/datasource/MyPageDataSource.kt @@ -2,6 +2,7 @@ package com.terning.data.mypage.datasource import com.terning.core.network.BaseResponse import com.terning.core.network.NonDataBaseResponse +import com.terning.data.mypage.dto.request.AlarmStatusRequestDto import com.terning.data.mypage.dto.request.MyPageProfileEditRequestDto import com.terning.data.mypage.dto.response.MyPageResponseDto @@ -15,4 +16,8 @@ interface MyPageDataSource { suspend fun editProfile( request: MyPageProfileEditRequestDto ): NonDataBaseResponse + + suspend fun updateAlarmState( + request : AlarmStatusRequestDto + ) : NonDataBaseResponse } \ No newline at end of file diff --git a/data/mypage/src/main/java/com/terning/data/mypage/datasourceimpl/MyPageDataSourceImpl.kt b/data/mypage/src/main/java/com/terning/data/mypage/datasourceimpl/MyPageDataSourceImpl.kt index a8c1fe64b..e1d237cf3 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/datasourceimpl/MyPageDataSourceImpl.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/datasourceimpl/MyPageDataSourceImpl.kt @@ -3,6 +3,7 @@ package com.terning.data.mypage.datasourceimpl import com.terning.core.network.BaseResponse import com.terning.core.network.NonDataBaseResponse import com.terning.data.mypage.datasource.MyPageDataSource +import com.terning.data.mypage.dto.request.AlarmStatusRequestDto import com.terning.data.mypage.dto.request.MyPageProfileEditRequestDto import com.terning.data.mypage.dto.response.MyPageResponseDto import com.terning.data.mypage.service.MyPageService @@ -20,4 +21,7 @@ class MyPageDataSourceImpl @Inject constructor( override suspend fun editProfile( request: MyPageProfileEditRequestDto ): NonDataBaseResponse = myPageService.editProfile(request) + + override suspend fun updateAlarmState(request: AlarmStatusRequestDto): NonDataBaseResponse = + myPageService.patchAlarmStatus(request) } \ No newline at end of file diff --git a/data/mypage/src/main/java/com/terning/data/mypage/dto/request/AlarmStatusRequestDto.kt b/data/mypage/src/main/java/com/terning/data/mypage/dto/request/AlarmStatusRequestDto.kt new file mode 100644 index 000000000..fa6505df3 --- /dev/null +++ b/data/mypage/src/main/java/com/terning/data/mypage/dto/request/AlarmStatusRequestDto.kt @@ -0,0 +1,10 @@ +package com.terning.data.mypage.dto.request + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class AlarmStatusRequestDto( + @SerialName("newStatus") + val newStatus: String +) \ No newline at end of file diff --git a/data/mypage/src/main/java/com/terning/data/mypage/mapper/AlarmStatusMapper.kt b/data/mypage/src/main/java/com/terning/data/mypage/mapper/AlarmStatusMapper.kt new file mode 100644 index 000000000..8997e6d97 --- /dev/null +++ b/data/mypage/src/main/java/com/terning/data/mypage/mapper/AlarmStatusMapper.kt @@ -0,0 +1,9 @@ +package com.terning.data.mypage.mapper + +import com.terning.data.mypage.dto.request.AlarmStatusRequestDto +import com.terning.domain.mypage.entity.AlarmStatus + +fun AlarmStatus.toAlarmStatusRequestDto(): AlarmStatusRequestDto = + AlarmStatusRequestDto( + newStatus = newStatus + ) \ No newline at end of file diff --git a/data/mypage/src/main/java/com/terning/data/mypage/repositoryimpl/MyPageRepositoryImpl.kt b/data/mypage/src/main/java/com/terning/data/mypage/repositoryimpl/MyPageRepositoryImpl.kt index dbff41328..ea0714abd 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/repositoryimpl/MyPageRepositoryImpl.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/repositoryimpl/MyPageRepositoryImpl.kt @@ -1,8 +1,10 @@ package com.terning.data.mypage.repositoryimpl import com.terning.data.mypage.datasource.MyPageDataSource +import com.terning.data.mypage.mapper.toAlarmStatusRequestDto import com.terning.data.mypage.mapper.toMyPageProfile import com.terning.data.mypage.mapper.toMyPageProfileEditRequestDto +import com.terning.domain.mypage.entity.AlarmStatus import com.terning.domain.mypage.entity.MyPageProfile import com.terning.domain.mypage.entity.MyPageProfileEdit import com.terning.domain.mypage.repository.MyPageRepository @@ -34,4 +36,9 @@ class MyPageRepositoryImpl @Inject constructor( request.toMyPageProfileEditRequestDto() ) } + + override suspend fun updateAlarmState(request: AlarmStatus): Result = + runCatching { + myPageDataSource.updateAlarmState(request.toAlarmStatusRequestDto()) + } } \ No newline at end of file diff --git a/data/mypage/src/main/java/com/terning/data/mypage/service/MyPageService.kt b/data/mypage/src/main/java/com/terning/data/mypage/service/MyPageService.kt index ece71a44c..443174518 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/service/MyPageService.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/service/MyPageService.kt @@ -2,6 +2,7 @@ package com.terning.data.mypage.service import com.terning.core.network.BaseResponse import com.terning.core.network.NonDataBaseResponse +import com.terning.data.mypage.dto.request.AlarmStatusRequestDto import com.terning.data.mypage.dto.request.MyPageProfileEditRequestDto import com.terning.data.mypage.dto.response.MyPageResponseDto import retrofit2.http.Body @@ -24,4 +25,9 @@ interface MyPageService { suspend fun editProfile( @Body body: MyPageProfileEditRequestDto ): NonDataBaseResponse + + @PATCH("api/v1/push-status") + suspend fun patchAlarmStatus( + @Body body: AlarmStatusRequestDto + ): NonDataBaseResponse } \ No newline at end of file diff --git a/domain/mypage/src/main/java/com/terning/domain/mypage/entity/AlarmStatus.kt b/domain/mypage/src/main/java/com/terning/domain/mypage/entity/AlarmStatus.kt new file mode 100644 index 000000000..99650be79 --- /dev/null +++ b/domain/mypage/src/main/java/com/terning/domain/mypage/entity/AlarmStatus.kt @@ -0,0 +1,5 @@ +package com.terning.domain.mypage.entity + +data class AlarmStatus( + val newStatus: String +) \ No newline at end of file diff --git a/domain/mypage/src/main/java/com/terning/domain/mypage/repository/MyPageRepository.kt b/domain/mypage/src/main/java/com/terning/domain/mypage/repository/MyPageRepository.kt index e9478f285..4097c183b 100644 --- a/domain/mypage/src/main/java/com/terning/domain/mypage/repository/MyPageRepository.kt +++ b/domain/mypage/src/main/java/com/terning/domain/mypage/repository/MyPageRepository.kt @@ -1,5 +1,6 @@ package com.terning.domain.mypage.repository +import com.terning.domain.mypage.entity.AlarmStatus import com.terning.domain.mypage.entity.MyPageProfile import com.terning.domain.mypage.entity.MyPageProfileEdit @@ -13,4 +14,8 @@ interface MyPageRepository { suspend fun editProfile( request: MyPageProfileEdit ): Result + + suspend fun updateAlarmState( + request: AlarmStatus + ): Result } \ No newline at end of file From b9d71556095ee1673d33f632cf279ee862fd8ba2 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 08:09:09 +0900 Subject: [PATCH 02/25] =?UTF-8?q?[FEAT/#396]=20=ED=91=B8=EC=8B=9C=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EC=83=81=ED=83=9C=EB=B3=80=EA=B2=BD=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/terning/data/mypage/datasource/MyPageDataSource.kt | 2 +- .../terning/data/mypage/datasourceimpl/MyPageDataSourceImpl.kt | 2 +- .../terning/data/mypage/dto/request/AlarmStatusRequestDto.kt | 2 +- .../java/com/terning/data/mypage/mapper/AlarmStatusMapper.kt | 2 +- .../terning/data/mypage/repositoryimpl/MyPageRepositoryImpl.kt | 2 +- .../main/java/com/terning/domain/mypage/entity/AlarmStatus.kt | 2 +- .../com/terning/domain/mypage/repository/MyPageRepository.kt | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/data/mypage/src/main/java/com/terning/data/mypage/datasource/MyPageDataSource.kt b/data/mypage/src/main/java/com/terning/data/mypage/datasource/MyPageDataSource.kt index 0aca8338a..bbbb4dfef 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/datasource/MyPageDataSource.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/datasource/MyPageDataSource.kt @@ -20,4 +20,4 @@ interface MyPageDataSource { suspend fun updateAlarmState( request : AlarmStatusRequestDto ) : NonDataBaseResponse -} \ No newline at end of file +} diff --git a/data/mypage/src/main/java/com/terning/data/mypage/datasourceimpl/MyPageDataSourceImpl.kt b/data/mypage/src/main/java/com/terning/data/mypage/datasourceimpl/MyPageDataSourceImpl.kt index e1d237cf3..dbf576030 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/datasourceimpl/MyPageDataSourceImpl.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/datasourceimpl/MyPageDataSourceImpl.kt @@ -24,4 +24,4 @@ class MyPageDataSourceImpl @Inject constructor( override suspend fun updateAlarmState(request: AlarmStatusRequestDto): NonDataBaseResponse = myPageService.patchAlarmStatus(request) -} \ No newline at end of file +} diff --git a/data/mypage/src/main/java/com/terning/data/mypage/dto/request/AlarmStatusRequestDto.kt b/data/mypage/src/main/java/com/terning/data/mypage/dto/request/AlarmStatusRequestDto.kt index fa6505df3..4df436809 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/dto/request/AlarmStatusRequestDto.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/dto/request/AlarmStatusRequestDto.kt @@ -7,4 +7,4 @@ import kotlinx.serialization.Serializable data class AlarmStatusRequestDto( @SerialName("newStatus") val newStatus: String -) \ No newline at end of file +) diff --git a/data/mypage/src/main/java/com/terning/data/mypage/mapper/AlarmStatusMapper.kt b/data/mypage/src/main/java/com/terning/data/mypage/mapper/AlarmStatusMapper.kt index 8997e6d97..7f81d4dc2 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/mapper/AlarmStatusMapper.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/mapper/AlarmStatusMapper.kt @@ -6,4 +6,4 @@ import com.terning.domain.mypage.entity.AlarmStatus fun AlarmStatus.toAlarmStatusRequestDto(): AlarmStatusRequestDto = AlarmStatusRequestDto( newStatus = newStatus - ) \ No newline at end of file + ) diff --git a/data/mypage/src/main/java/com/terning/data/mypage/repositoryimpl/MyPageRepositoryImpl.kt b/data/mypage/src/main/java/com/terning/data/mypage/repositoryimpl/MyPageRepositoryImpl.kt index ea0714abd..ee8eae27c 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/repositoryimpl/MyPageRepositoryImpl.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/repositoryimpl/MyPageRepositoryImpl.kt @@ -41,4 +41,4 @@ class MyPageRepositoryImpl @Inject constructor( runCatching { myPageDataSource.updateAlarmState(request.toAlarmStatusRequestDto()) } -} \ No newline at end of file +} diff --git a/domain/mypage/src/main/java/com/terning/domain/mypage/entity/AlarmStatus.kt b/domain/mypage/src/main/java/com/terning/domain/mypage/entity/AlarmStatus.kt index 99650be79..b4e414ebd 100644 --- a/domain/mypage/src/main/java/com/terning/domain/mypage/entity/AlarmStatus.kt +++ b/domain/mypage/src/main/java/com/terning/domain/mypage/entity/AlarmStatus.kt @@ -2,4 +2,4 @@ package com.terning.domain.mypage.entity data class AlarmStatus( val newStatus: String -) \ No newline at end of file +) diff --git a/domain/mypage/src/main/java/com/terning/domain/mypage/repository/MyPageRepository.kt b/domain/mypage/src/main/java/com/terning/domain/mypage/repository/MyPageRepository.kt index 4097c183b..a7b5657aa 100644 --- a/domain/mypage/src/main/java/com/terning/domain/mypage/repository/MyPageRepository.kt +++ b/domain/mypage/src/main/java/com/terning/domain/mypage/repository/MyPageRepository.kt @@ -18,4 +18,4 @@ interface MyPageRepository { suspend fun updateAlarmState( request: AlarmStatus ): Result -} \ No newline at end of file +} From df037634a7dc260d413a4389ec6a57d90babe450 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 08:22:35 +0900 Subject: [PATCH 03/25] =?UTF-8?q?[FEAT/#396]=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=20API=20=EC=9D=91=EB=8B=B5=EA=B0=92=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../terning/data/mypage/dto/response/MyPageResponseDto.kt | 6 ++++-- .../java/com/terning/data/mypage/mapper/MyPageMapper.kt | 3 ++- .../java/com/terning/domain/mypage/entity/MyPageProfile.kt | 5 +++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/data/mypage/src/main/java/com/terning/data/mypage/dto/response/MyPageResponseDto.kt b/data/mypage/src/main/java/com/terning/data/mypage/dto/response/MyPageResponseDto.kt index 0cca39b7f..c99bbeffc 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/dto/response/MyPageResponseDto.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/dto/response/MyPageResponseDto.kt @@ -10,5 +10,7 @@ data class MyPageResponseDto( @SerialName("profileImage") val profileImage: String, @SerialName("authType") - val authType: String -) \ No newline at end of file + val authType: String, + @SerialName("pushStatus") + val pushStatus: String +) diff --git a/data/mypage/src/main/java/com/terning/data/mypage/mapper/MyPageMapper.kt b/data/mypage/src/main/java/com/terning/data/mypage/mapper/MyPageMapper.kt index 3a46f7104..4c78fa07a 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/mapper/MyPageMapper.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/mapper/MyPageMapper.kt @@ -7,5 +7,6 @@ fun MyPageResponseDto.toMyPageProfile() = MyPageProfile( name = name, profileImage = profileImage, - authType = authType + authType = authType, + pushStatus = pushStatus ) diff --git a/domain/mypage/src/main/java/com/terning/domain/mypage/entity/MyPageProfile.kt b/domain/mypage/src/main/java/com/terning/domain/mypage/entity/MyPageProfile.kt index afff9a0fb..cc724b0b5 100644 --- a/domain/mypage/src/main/java/com/terning/domain/mypage/entity/MyPageProfile.kt +++ b/domain/mypage/src/main/java/com/terning/domain/mypage/entity/MyPageProfile.kt @@ -3,5 +3,6 @@ package com.terning.domain.mypage.entity data class MyPageProfile( val name: String, val profileImage: String, - val authType: String -) \ No newline at end of file + val authType: String, + val pushStatus: String +) From 7bfd4c5c84f5e1c106b8e89416c223f500670816 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 08:34:40 +0900 Subject: [PATCH 04/25] =?UTF-8?q?[FEAT/#396]=20AlarmType=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/terning/core/designsystem/type/AlarmType.kt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 core/designsystem/src/main/java/com/terning/core/designsystem/type/AlarmType.kt diff --git a/core/designsystem/src/main/java/com/terning/core/designsystem/type/AlarmType.kt b/core/designsystem/src/main/java/com/terning/core/designsystem/type/AlarmType.kt new file mode 100644 index 000000000..70106d955 --- /dev/null +++ b/core/designsystem/src/main/java/com/terning/core/designsystem/type/AlarmType.kt @@ -0,0 +1,6 @@ +package com.terning.core.designsystem.type + +enum class AlarmType(val value: String) { + ENABLED("ENABLED"), + DISABLED("DISABLED") +} From 0e09c2895e912d929ca5623856a72182da5e7c7a Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 08:35:11 +0900 Subject: [PATCH 05/25] =?UTF-8?q?[FEAT/#396]=20Home=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=97=90=20=EC=95=8C=EB=A6=BC=20=EC=83=81=ED=83=9C=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=ED=86=B5=EC=8B=A0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/terning/feature/home/HomeViewModel.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt b/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt index 6b1fa6375..c77f40a76 100644 --- a/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt +++ b/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt @@ -6,12 +6,15 @@ import androidx.paging.PagingData import androidx.paging.cachedIn import androidx.paging.map import com.terning.core.designsystem.state.UiState +import com.terning.core.designsystem.type.AlarmType.DISABLED +import com.terning.core.designsystem.type.AlarmType.ENABLED import com.terning.core.designsystem.type.SortBy import com.terning.domain.home.entity.ChangeFilteringRequestModel import com.terning.domain.home.entity.FcmToken import com.terning.domain.home.entity.HomeRecommendIntern import com.terning.domain.home.entity.HomeRecommendedIntern import com.terning.domain.home.repository.HomeRepository +import com.terning.domain.mypage.entity.AlarmStatus import com.terning.domain.mypage.repository.MyPageRepository import com.terning.domain.user.repository.UserRepository import dagger.hilt.android.lifecycle.HiltViewModel @@ -219,7 +222,11 @@ class HomeViewModel @Inject constructor( } fun updateAlarmAvailability(availability: Boolean) { - userRepository.setAlarmAvailable(availability) + // userRepository.setAlarmAvailable(availability) todo: 삭제 + viewModelScope.launch { + if (availability) myPageRepository.updateAlarmState(AlarmStatus(ENABLED.value)) + else myPageRepository.updateAlarmState(AlarmStatus(DISABLED.value)) + } } fun updatePermissionRequested(requested: Boolean) { From fce4cfb858699eb02ef02d5f0f5c7b69cdfb0e11 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 08:37:01 +0900 Subject: [PATCH 06/25] =?UTF-8?q?[FEAT/#396]=20Mypage=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=97=90=20=EC=95=8C=EB=A6=BC=20=EC=83=81=ED=83=9C=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=ED=86=B5=EC=8B=A0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../terning/feature/mypage/mypage/MyPageViewModel.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt index 598a644c2..8bca46d9d 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt @@ -4,6 +4,9 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.kakao.sdk.user.UserApiClient import com.terning.core.designsystem.state.UiState +import com.terning.core.designsystem.type.AlarmType.DISABLED +import com.terning.core.designsystem.type.AlarmType.ENABLED +import com.terning.domain.mypage.entity.AlarmStatus import com.terning.domain.mypage.repository.MyPageRepository import com.terning.domain.user.repository.UserRepository import dagger.hilt.android.lifecycle.HiltViewModel @@ -84,7 +87,7 @@ class MyPageViewModel @Inject constructor( isGetSuccess = UiState.Success(true), name = response.name, profileImage = response.profileImage, - authType = response.authType + authType = response.authType // todo: 여기서 응답값에 대한 분기처리 ) }.onFailure { _sideEffects.emit(MyPageSideEffect.ShowToast(DesignSystemR.string.server_failure)) @@ -133,7 +136,11 @@ class MyPageViewModel @Inject constructor( viewModelScope.launch { _sideEffects.emit(MyPageSideEffect.NavigateToProfileEdit) } fun updateAlarmAvailability(availability: Boolean) { - userRepository.setAlarmAvailable(availability) + // userRepository.setAlarmAvailable(availability) todo: 삭제 + viewModelScope.launch { + if (availability) myPageRepository.updateAlarmState(AlarmStatus(ENABLED.value)) + else myPageRepository.updateAlarmState(AlarmStatus(DISABLED.value)) + } } fun getAlarmAvailability(): Boolean = userRepository.getAlarmAvailable() From e95fb65cf403b007db09ac449398ea861a4273c1 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 09:21:55 +0900 Subject: [PATCH 07/25] =?UTF-8?q?[FEAT/#396]=20FirebaseMessaging=20?= =?UTF-8?q?=EB=A1=9C=EC=BB=AC=20->=20=EC=84=9C=EB=B2=84DB=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=9C=BC=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 --- core/firebase/build.gradle.kts | 2 +- .../messageservice/TerningMessagingService.kt | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/core/firebase/build.gradle.kts b/core/firebase/build.gradle.kts index ef446c83d..bdd628cef 100644 --- a/core/firebase/build.gradle.kts +++ b/core/firebase/build.gradle.kts @@ -15,7 +15,7 @@ dependencies { implementation(projects.core.analytics) // domain - implementation(projects.domain.user) + implementation(projects.domain.mypage) // timber implementation(libs.timber) diff --git a/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt b/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt index 8c9a7493c..0241d3992 100644 --- a/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt +++ b/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt @@ -16,12 +16,14 @@ import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import com.terning.core.analytics.AmplitudeTracker import com.terning.core.analytics.EventType +import com.terning.core.designsystem.type.AlarmType import com.terning.core.designsystem.type.DeeplinkType import com.terning.core.designsystem.util.DeeplinkDefaults import com.terning.core.firebase.R -import com.terning.domain.user.repository.UserRepository +import com.terning.domain.mypage.repository.MyPageRepository import com.terning.navigator.NavigatorProvider import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.runBlocking import timber.log.Timber import java.util.Random import javax.inject.Inject @@ -30,7 +32,7 @@ import javax.inject.Inject class TerningMessagingService : FirebaseMessagingService() { @Inject - lateinit var userRepository: UserRepository + lateinit var myPageRepository: MyPageRepository @Inject lateinit var navigatorProvider: NavigatorProvider @@ -76,7 +78,13 @@ class TerningMessagingService : FirebaseMessagingService() { type: String?, imageUrl: String? ) { - if (title.isNullOrEmpty() || !userRepository.getAlarmAvailable()) return + if (title.isNullOrEmpty()) return + + val isAlarmAvailable: Boolean = runBlocking { + myPageRepository.getProfile().getOrNull()?.pushStatus == AlarmType.ENABLED.value + } + + if (!isAlarmAvailable) return amplitudeTracker.track( type = EventType.PUSH_NOTIFICATION, From ea565ff87c4f9ed021d14467eff778c2accc558f Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 10:25:05 +0900 Subject: [PATCH 08/25] =?UTF-8?q?[FEAT/#396]=20FirebaseMessaging=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/firebase/build.gradle.kts | 2 +- .../messageservice/TerningMessagingService.kt | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/core/firebase/build.gradle.kts b/core/firebase/build.gradle.kts index bdd628cef..ef446c83d 100644 --- a/core/firebase/build.gradle.kts +++ b/core/firebase/build.gradle.kts @@ -15,7 +15,7 @@ dependencies { implementation(projects.core.analytics) // domain - implementation(projects.domain.mypage) + implementation(projects.domain.user) // timber implementation(libs.timber) diff --git a/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt b/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt index 0241d3992..8c9a7493c 100644 --- a/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt +++ b/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt @@ -16,14 +16,12 @@ import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import com.terning.core.analytics.AmplitudeTracker import com.terning.core.analytics.EventType -import com.terning.core.designsystem.type.AlarmType import com.terning.core.designsystem.type.DeeplinkType import com.terning.core.designsystem.util.DeeplinkDefaults import com.terning.core.firebase.R -import com.terning.domain.mypage.repository.MyPageRepository +import com.terning.domain.user.repository.UserRepository import com.terning.navigator.NavigatorProvider import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.runBlocking import timber.log.Timber import java.util.Random import javax.inject.Inject @@ -32,7 +30,7 @@ import javax.inject.Inject class TerningMessagingService : FirebaseMessagingService() { @Inject - lateinit var myPageRepository: MyPageRepository + lateinit var userRepository: UserRepository @Inject lateinit var navigatorProvider: NavigatorProvider @@ -78,13 +76,7 @@ class TerningMessagingService : FirebaseMessagingService() { type: String?, imageUrl: String? ) { - if (title.isNullOrEmpty()) return - - val isAlarmAvailable: Boolean = runBlocking { - myPageRepository.getProfile().getOrNull()?.pushStatus == AlarmType.ENABLED.value - } - - if (!isAlarmAvailable) return + if (title.isNullOrEmpty() || !userRepository.getAlarmAvailable()) return amplitudeTracker.track( type = EventType.PUSH_NOTIFICATION, From f641f5a95df7ab5a6b70e5d9a07451d8377cde1a Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 10:25:44 +0900 Subject: [PATCH 09/25] =?UTF-8?q?[FEAT/#396]=20Home=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=BB=AC=EB=A1=9C=EB=8F=84=20=ED=86=B5=EC=8B=A0?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/terning/feature/home/HomeViewModel.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt b/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt index c77f40a76..a2a65f9e3 100644 --- a/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt +++ b/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt @@ -222,7 +222,8 @@ class HomeViewModel @Inject constructor( } fun updateAlarmAvailability(availability: Boolean) { - // userRepository.setAlarmAvailable(availability) todo: 삭제 + userRepository.setAlarmAvailable(availability) + viewModelScope.launch { if (availability) myPageRepository.updateAlarmState(AlarmStatus(ENABLED.value)) else myPageRepository.updateAlarmState(AlarmStatus(DISABLED.value)) From 5eb3c086c4ea4594a3868e6fdfebd4b685ae161d Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 10:27:30 +0900 Subject: [PATCH 10/25] =?UTF-8?q?[FEAT/#396]=20Mypage=20Optimistic=20UI=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 --- .../feature/mypage/mypage/MyPageRoute.kt | 10 ++++-- .../feature/mypage/mypage/MyPageState.kt | 6 ++-- .../feature/mypage/mypage/MyPageViewModel.kt | 35 ++++++++++++++----- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt index c80f7b245..38d58febf 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt @@ -94,8 +94,12 @@ fun MyPageRoute( rememberPermissionState(permission = notificationPermission) var isChecked by remember { mutableStateOf( - if (!permissionState.status.isGranted) false - else viewModel.getAlarmAvailability() + if (!permissionState.status.isGranted) { + viewModel.updateAlarmAvailability(false) + false + } else { + viewModel.getAlarmAvailability() + } ) } val notificationSettingsLauncher = @@ -116,7 +120,7 @@ fun MyPageRoute( } } - LaunchedEffect(key1 = true) { + LaunchedEffect(Unit) { viewModel.getProfile() } diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt index ea480f8bc..bd6ddd8d4 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt @@ -1,6 +1,7 @@ package com.terning.feature.mypage.mypage import com.terning.core.designsystem.state.UiState +import com.terning.core.designsystem.type.AlarmType.DISABLED data class MyPageState( val isGetSuccess: UiState = UiState.Loading, @@ -13,5 +14,6 @@ data class MyPageState( val showPersonal: Boolean = false, val showLogoutBottomSheet: Boolean = false, val showQuitBottomSheet: Boolean = false, - val showAlarmDialog: Boolean = false -) \ No newline at end of file + val showAlarmDialog: Boolean = false, + val pushStatus: String = DISABLED.value, +) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt index 8bca46d9d..ecc35dd44 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt @@ -83,12 +83,15 @@ class MyPageViewModel @Inject constructor( viewModelScope.launch { myPageRepository.getProfile() .onSuccess { response -> - _state.value = _state.value.copy( - isGetSuccess = UiState.Success(true), - name = response.name, - profileImage = response.profileImage, - authType = response.authType // todo: 여기서 응답값에 대한 분기처리 - ) + _state.update { currentState -> + currentState.copy( + isGetSuccess = UiState.Success(true), + name = response.name, + profileImage = response.profileImage, + authType = response.authType, + pushStatus = response.pushStatus + ) + } }.onFailure { _sideEffects.emit(MyPageSideEffect.ShowToast(DesignSystemR.string.server_failure)) _state.value = _state.value.copy(isGetSuccess = UiState.Failure(it.toString())) @@ -136,10 +139,24 @@ class MyPageViewModel @Inject constructor( viewModelScope.launch { _sideEffects.emit(MyPageSideEffect.NavigateToProfileEdit) } fun updateAlarmAvailability(availability: Boolean) { - // userRepository.setAlarmAvailable(availability) todo: 삭제 + val previousPushStatus = _state.value.pushStatus + val optimisticPushStatus = if (availability) ENABLED.value else DISABLED.value + + _state.update { it.copy(pushStatus = optimisticPushStatus) } + viewModelScope.launch { - if (availability) myPageRepository.updateAlarmState(AlarmStatus(ENABLED.value)) - else myPageRepository.updateAlarmState(AlarmStatus(DISABLED.value)) + userRepository.setAlarmAvailable(availability) + + val result = if (availability) { + myPageRepository.updateAlarmState(AlarmStatus(ENABLED.value)) + } else { + myPageRepository.updateAlarmState(AlarmStatus(DISABLED.value)) + } + + result.onFailure { + _state.update { it.copy(pushStatus = previousPushStatus) } + _sideEffects.emit(MyPageSideEffect.ShowToast(DesignSystemR.string.server_failure)) + } } } From 031018589058f1e73c18a8fec8853e62829d148c Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 11:36:57 +0900 Subject: [PATCH 11/25] =?UTF-8?q?[FEAT/#396]=20groupBy=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=ED=95=A8=EC=88=98=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/designsystem/extension/FlowExt.kt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt diff --git a/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt b/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt new file mode 100644 index 000000000..932927815 --- /dev/null +++ b/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt @@ -0,0 +1,23 @@ +package com.terning.core.designsystem.extension + +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.SendChannel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.consumeAsFlow +import kotlinx.coroutines.flow.flow + +fun Flow.groupBy(getKey: (T) -> K): Flow>> = flow { + val storage = mutableMapOf>() + + collect { t -> + val key = getKey(t) + val channel = storage.getOrPut(key) { + Channel(capacity = Channel.BUFFERED).also { + emit(key to it.consumeAsFlow()) + } + } + channel.send(t) + } + + storage.values.forEach { it.close() } +} \ No newline at end of file From 3332ac3e350dbc74ebce9c2511d006807fc55ecb Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 11:39:34 +0900 Subject: [PATCH 12/25] =?UTF-8?q?[FEAT/#396]=20AlarmInfo=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/terning/feature/mypage/mypage/AlarmInfo.kt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 feature/mypage/src/main/java/com/terning/feature/mypage/mypage/AlarmInfo.kt diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/AlarmInfo.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/AlarmInfo.kt new file mode 100644 index 000000000..5042a3054 --- /dev/null +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/AlarmInfo.kt @@ -0,0 +1,6 @@ +package com.terning.feature.mypage.mypage + +data class AlarmInfo( + val id: String, + val isAlarmAvailable: Boolean +) From defb28c9163826b26373ee489e9beda4c72ddf86 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 11:43:52 +0900 Subject: [PATCH 13/25] =?UTF-8?q?[FEAT/#396]=20debounceFlow=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/mypage/mypage/MyPageViewModel.kt | 56 +++++++++++++------ 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt index ecc35dd44..ef79eaebb 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt @@ -3,6 +3,7 @@ package com.terning.feature.mypage.mypage import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.kakao.sdk.user.UserApiClient +import com.terning.core.designsystem.extension.groupBy import com.terning.core.designsystem.state.UiState import com.terning.core.designsystem.type.AlarmType.DISABLED import com.terning.core.designsystem.type.AlarmType.ENABLED @@ -10,17 +11,22 @@ import com.terning.domain.mypage.entity.AlarmStatus import com.terning.domain.mypage.repository.MyPageRepository import com.terning.domain.user.repository.UserRepository import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.flatMapMerge import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import javax.inject.Inject import com.terning.core.designsystem.R as DesignSystemR +@OptIn(FlowPreview::class, ExperimentalCoroutinesApi::class) @HiltViewModel class MyPageViewModel @Inject constructor( private val myPageRepository: MyPageRepository, @@ -33,6 +39,35 @@ class MyPageViewModel @Inject constructor( private val _sideEffects = MutableSharedFlow() val sideEffects: SharedFlow get() = _sideEffects.asSharedFlow() + private val debounceFlow = MutableSharedFlow() + + private val lastSuccessfulAlarmStatus = mutableMapOf() + + init { + viewModelScope.launch { + debounceFlow + .groupBy { it.id } + .flatMapMerge { (_, flow) -> flow.debounce(300L) } + .collect { info -> + val result = myPageRepository.updateAlarmState( + AlarmStatus(if (info.isAlarmAvailable) ENABLED.value else DISABLED.value) + ) + + if (result.isSuccess) { + lastSuccessfulAlarmStatus[info.id] = info.isAlarmAvailable + } else { + val previous = lastSuccessfulAlarmStatus[info.id] ?: !info.isAlarmAvailable + _state.update { + it.copy(pushStatus = if (previous) ENABLED.value else DISABLED.value) + } + userRepository.setAlarmAvailable(previous) + + _sideEffects.emit(MyPageSideEffect.ShowToast(DesignSystemR.string.server_failure)) + } + } + } + } + fun logoutKakao() { UserApiClient.instance.logout { error -> if (error == null) { @@ -139,24 +174,14 @@ class MyPageViewModel @Inject constructor( viewModelScope.launch { _sideEffects.emit(MyPageSideEffect.NavigateToProfileEdit) } fun updateAlarmAvailability(availability: Boolean) { - val previousPushStatus = _state.value.pushStatus - val optimisticPushStatus = if (availability) ENABLED.value else DISABLED.value + _state.update { state -> + state.copy(pushStatus = if (availability) ENABLED.value else DISABLED.value) + } - _state.update { it.copy(pushStatus = optimisticPushStatus) } + userRepository.setAlarmAvailable(availability) viewModelScope.launch { - userRepository.setAlarmAvailable(availability) - - val result = if (availability) { - myPageRepository.updateAlarmState(AlarmStatus(ENABLED.value)) - } else { - myPageRepository.updateAlarmState(AlarmStatus(DISABLED.value)) - } - - result.onFailure { - _state.update { it.copy(pushStatus = previousPushStatus) } - _sideEffects.emit(MyPageSideEffect.ShowToast(DesignSystemR.string.server_failure)) - } + debounceFlow.emit(AlarmInfo(id = "user", isAlarmAvailable = availability)) } } @@ -169,5 +194,4 @@ class MyPageViewModel @Inject constructor( ) } } - } \ No newline at end of file From 97c5c7a1ac87b54935fa863ff2d9e80b54f66e61 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 12:14:12 +0900 Subject: [PATCH 14/25] =?UTF-8?q?[FEAT/#396]=20=EB=94=94=EB=B0=94=EC=9A=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../terning/feature/mypage/mypage/MyPageViewModel.kt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt index ef79eaebb..aa870248c 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt @@ -47,7 +47,7 @@ class MyPageViewModel @Inject constructor( viewModelScope.launch { debounceFlow .groupBy { it.id } - .flatMapMerge { (_, flow) -> flow.debounce(300L) } + .flatMapMerge { (_, flow) -> flow.debounce(DEBOUNCE_DURATION) } .collect { info -> val result = myPageRepository.updateAlarmState( AlarmStatus(if (info.isAlarmAvailable) ENABLED.value else DISABLED.value) @@ -181,7 +181,7 @@ class MyPageViewModel @Inject constructor( userRepository.setAlarmAvailable(availability) viewModelScope.launch { - debounceFlow.emit(AlarmInfo(id = "user", isAlarmAvailable = availability)) + debounceFlow.emit(AlarmInfo(id = DEBOUNCE_KEY, isAlarmAvailable = availability)) } } @@ -194,4 +194,9 @@ class MyPageViewModel @Inject constructor( ) } } -} \ No newline at end of file + + companion object { + private const val DEBOUNCE_DURATION = 300L + private const val DEBOUNCE_KEY = "NOTIFICATION" + } +} From c134828882913396d5f3e54303c27e7fbf7fd841 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 13:44:05 +0900 Subject: [PATCH 15/25] =?UTF-8?q?[CHORE/#396]=20currentState=20=EB=84=A4?= =?UTF-8?q?=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 --- .../com/terning/feature/mypage/mypage/MyPageViewModel.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt index aa870248c..60aece214 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt @@ -57,8 +57,8 @@ class MyPageViewModel @Inject constructor( lastSuccessfulAlarmStatus[info.id] = info.isAlarmAvailable } else { val previous = lastSuccessfulAlarmStatus[info.id] ?: !info.isAlarmAvailable - _state.update { - it.copy(pushStatus = if (previous) ENABLED.value else DISABLED.value) + _state.update { currentState -> + currentState.copy(pushStatus = if (previous) ENABLED.value else DISABLED.value) } userRepository.setAlarmAvailable(previous) @@ -174,8 +174,8 @@ class MyPageViewModel @Inject constructor( viewModelScope.launch { _sideEffects.emit(MyPageSideEffect.NavigateToProfileEdit) } fun updateAlarmAvailability(availability: Boolean) { - _state.update { state -> - state.copy(pushStatus = if (availability) ENABLED.value else DISABLED.value) + _state.update { currentState -> + currentState.copy(pushStatus = if (availability) ENABLED.value else DISABLED.value) } userRepository.setAlarmAvailable(availability) From 8a86ca76541936c9db167a2b91a0f8b43342e692 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 13:47:56 +0900 Subject: [PATCH 16/25] =?UTF-8?q?[CHORE/#396]=20AlarmInfo=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=EC=A0=9C=EC=96=B4=EC=9E=90=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=ED=8C=8C=EC=9D=BC=20=EC=9C=84=EC=B9=98=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/terning/feature/mypage/mypage/AlarmInfo.kt | 6 ------ .../com/terning/feature/mypage/mypage/MyPageViewModel.kt | 1 + .../com/terning/feature/mypage/mypage/model/AlarmInfo.kt | 6 ++++++ 3 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 feature/mypage/src/main/java/com/terning/feature/mypage/mypage/AlarmInfo.kt create mode 100644 feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/AlarmInfo.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/AlarmInfo.kt deleted file mode 100644 index 5042a3054..000000000 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/AlarmInfo.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.terning.feature.mypage.mypage - -data class AlarmInfo( - val id: String, - val isAlarmAvailable: Boolean -) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt index 60aece214..8998ebd0d 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt @@ -10,6 +10,7 @@ import com.terning.core.designsystem.type.AlarmType.ENABLED import com.terning.domain.mypage.entity.AlarmStatus import com.terning.domain.mypage.repository.MyPageRepository import com.terning.domain.user.repository.UserRepository +import com.terning.feature.mypage.mypage.model.AlarmInfo import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt new file mode 100644 index 000000000..b0c23351b --- /dev/null +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt @@ -0,0 +1,6 @@ +package com.terning.feature.mypage.mypage.model + +internal data class AlarmInfo( + val id: String, + val isAlarmAvailable: Boolean +) From ab3725128f6c7c8551785fef65c0a4b1edc80ab3 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 14:34:33 +0900 Subject: [PATCH 17/25] =?UTF-8?q?[CHORE/#396]=20alarmStatus=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=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 --- .../java/com/terning/data/mypage/mapper/MyPageMapper.kt | 2 +- .../java/com/terning/domain/mypage/entity/MyPageProfile.kt | 2 +- .../java/com/terning/feature/mypage/mypage/MyPageState.kt | 2 +- .../com/terning/feature/mypage/mypage/MyPageViewModel.kt | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/data/mypage/src/main/java/com/terning/data/mypage/mapper/MyPageMapper.kt b/data/mypage/src/main/java/com/terning/data/mypage/mapper/MyPageMapper.kt index 4c78fa07a..9868c8211 100644 --- a/data/mypage/src/main/java/com/terning/data/mypage/mapper/MyPageMapper.kt +++ b/data/mypage/src/main/java/com/terning/data/mypage/mapper/MyPageMapper.kt @@ -8,5 +8,5 @@ fun MyPageResponseDto.toMyPageProfile() = name = name, profileImage = profileImage, authType = authType, - pushStatus = pushStatus + alarmStatus = pushStatus ) diff --git a/domain/mypage/src/main/java/com/terning/domain/mypage/entity/MyPageProfile.kt b/domain/mypage/src/main/java/com/terning/domain/mypage/entity/MyPageProfile.kt index cc724b0b5..85ed630ec 100644 --- a/domain/mypage/src/main/java/com/terning/domain/mypage/entity/MyPageProfile.kt +++ b/domain/mypage/src/main/java/com/terning/domain/mypage/entity/MyPageProfile.kt @@ -4,5 +4,5 @@ data class MyPageProfile( val name: String, val profileImage: String, val authType: String, - val pushStatus: String + val alarmStatus: String ) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt index bd6ddd8d4..56e49fc44 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt @@ -15,5 +15,5 @@ data class MyPageState( val showLogoutBottomSheet: Boolean = false, val showQuitBottomSheet: Boolean = false, val showAlarmDialog: Boolean = false, - val pushStatus: String = DISABLED.value, + val alarmStatus: String = DISABLED.value, ) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt index 8998ebd0d..40068cbcd 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt @@ -59,7 +59,7 @@ class MyPageViewModel @Inject constructor( } else { val previous = lastSuccessfulAlarmStatus[info.id] ?: !info.isAlarmAvailable _state.update { currentState -> - currentState.copy(pushStatus = if (previous) ENABLED.value else DISABLED.value) + currentState.copy(alarmStatus = if (previous) ENABLED.value else DISABLED.value) } userRepository.setAlarmAvailable(previous) @@ -125,7 +125,7 @@ class MyPageViewModel @Inject constructor( name = response.name, profileImage = response.profileImage, authType = response.authType, - pushStatus = response.pushStatus + alarmStatus = response.alarmStatus ) } }.onFailure { @@ -176,7 +176,7 @@ class MyPageViewModel @Inject constructor( fun updateAlarmAvailability(availability: Boolean) { _state.update { currentState -> - currentState.copy(pushStatus = if (availability) ENABLED.value else DISABLED.value) + currentState.copy(alarmStatus = if (availability) ENABLED.value else DISABLED.value) } userRepository.setAlarmAvailable(availability) From d6d92750688cadbc764cb1fa14911a02773f3ea2 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 14:40:17 +0900 Subject: [PATCH 18/25] =?UTF-8?q?[CHORE/#396]=20onSuccess=20/=20onFailure?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/terning/feature/mypage/mypage/MyPageViewModel.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt index 40068cbcd..807c3c14e 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt @@ -50,13 +50,11 @@ class MyPageViewModel @Inject constructor( .groupBy { it.id } .flatMapMerge { (_, flow) -> flow.debounce(DEBOUNCE_DURATION) } .collect { info -> - val result = myPageRepository.updateAlarmState( + myPageRepository.updateAlarmState( AlarmStatus(if (info.isAlarmAvailable) ENABLED.value else DISABLED.value) - ) - - if (result.isSuccess) { + ).onSuccess { lastSuccessfulAlarmStatus[info.id] = info.isAlarmAvailable - } else { + }.onFailure { val previous = lastSuccessfulAlarmStatus[info.id] ?: !info.isAlarmAvailable _state.update { currentState -> currentState.copy(alarmStatus = if (previous) ENABLED.value else DISABLED.value) From fa9dde307334ba8bca5c636360ddae74b5076544 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 15:20:26 +0900 Subject: [PATCH 19/25] =?UTF-8?q?[CHORE/#396]=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/designsystem/extension/FlowExt.kt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt b/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt index 932927815..981c7b437 100644 --- a/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt +++ b/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt @@ -8,16 +8,17 @@ import kotlinx.coroutines.flow.flow fun Flow.groupBy(getKey: (T) -> K): Flow>> = flow { val storage = mutableMapOf>() - - collect { t -> - val key = getKey(t) - val channel = storage.getOrPut(key) { - Channel(capacity = Channel.BUFFERED).also { - emit(key to it.consumeAsFlow()) + try { + collect { t -> + val key = getKey(t) + val channel = storage.getOrPut(key) { + Channel(capacity = Channel.BUFFERED).also { + emit(key to it.consumeAsFlow()) + } } + channel.send(t) } - channel.send(t) + } finally { + storage.values.forEach { it.close() } } - - storage.values.forEach { it.close() } } \ No newline at end of file From 8bfb7aa8e79b0c9baca67f3654238c561ffe5c62 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 15:41:06 +0900 Subject: [PATCH 20/25] =?UTF-8?q?[CHORE/#396]=20DisposableEffect=20?= =?UTF-8?q?=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/terning/feature/mypage/mypage/MyPageRoute.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt index 38d58febf..14a811b6e 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt @@ -110,11 +110,9 @@ fun MyPageRoute( viewModel.updateAlarmAvailability(isGranted) } - LaunchedEffect(Unit) { + DisposableEffect(lifecycleOwner) { systemUiController.setStatusBarColor(color = Back) - } - DisposableEffect(lifecycleOwner) { onDispose { systemUiController.setStatusBarColor(color = White) } From a42ed2aaab0ac4f7a918ca40240e081cc85eecb6 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 17:06:41 +0900 Subject: [PATCH 21/25] =?UTF-8?q?[CHORE/#396]=20=EC=95=88=EC=93=B0?= =?UTF-8?q?=EC=9D=B4=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/designsystem/extension/FlowExt.kt | 24 ------------------- .../feature/mypage/mypage/model/AlarmInfo.kt | 6 ----- 2 files changed, 30 deletions(-) delete mode 100644 core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt delete mode 100644 feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt diff --git a/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt b/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt deleted file mode 100644 index 981c7b437..000000000 --- a/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.terning.core.designsystem.extension - -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.channels.SendChannel -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.consumeAsFlow -import kotlinx.coroutines.flow.flow - -fun Flow.groupBy(getKey: (T) -> K): Flow>> = flow { - val storage = mutableMapOf>() - try { - collect { t -> - val key = getKey(t) - val channel = storage.getOrPut(key) { - Channel(capacity = Channel.BUFFERED).also { - emit(key to it.consumeAsFlow()) - } - } - channel.send(t) - } - } finally { - storage.values.forEach { it.close() } - } -} \ No newline at end of file diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt deleted file mode 100644 index b0c23351b..000000000 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.terning.feature.mypage.mypage.model - -internal data class AlarmInfo( - val id: String, - val isAlarmAvailable: Boolean -) From 93e4e377cac6610212cd417feb85ed1f3de02dda Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 17:07:03 +0900 Subject: [PATCH 22/25] =?UTF-8?q?[CHORE/#396]=20groupBy=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=ED=95=A8=EC=88=98=20=EC=97=86=EC=9D=B4=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 --- .../feature/mypage/mypage/MyPageViewModel.kt | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt index 807c3c14e..965bfc9e5 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt @@ -3,14 +3,12 @@ package com.terning.feature.mypage.mypage import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.kakao.sdk.user.UserApiClient -import com.terning.core.designsystem.extension.groupBy import com.terning.core.designsystem.state.UiState import com.terning.core.designsystem.type.AlarmType.DISABLED import com.terning.core.designsystem.type.AlarmType.ENABLED import com.terning.domain.mypage.entity.AlarmStatus import com.terning.domain.mypage.repository.MyPageRepository import com.terning.domain.user.repository.UserRepository -import com.terning.feature.mypage.mypage.model.AlarmInfo import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview @@ -21,7 +19,6 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.debounce -import kotlinx.coroutines.flow.flatMapMerge import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import javax.inject.Inject @@ -40,22 +37,25 @@ class MyPageViewModel @Inject constructor( private val _sideEffects = MutableSharedFlow() val sideEffects: SharedFlow get() = _sideEffects.asSharedFlow() - private val debounceFlow = MutableSharedFlow() + private val debounceFlow = MutableSharedFlow() - private val lastSuccessfulAlarmStatus = mutableMapOf() + private var lastSuccessfulAlarmStatus: Boolean? = null init { + handleDebouncedAlarm() + } + + private fun handleDebouncedAlarm() { viewModelScope.launch { debounceFlow - .groupBy { it.id } - .flatMapMerge { (_, flow) -> flow.debounce(DEBOUNCE_DURATION) } - .collect { info -> + .debounce(DEBOUNCE_DURATION) + .collect { isEnabled -> myPageRepository.updateAlarmState( - AlarmStatus(if (info.isAlarmAvailable) ENABLED.value else DISABLED.value) + AlarmStatus(if (isEnabled) ENABLED.value else DISABLED.value) ).onSuccess { - lastSuccessfulAlarmStatus[info.id] = info.isAlarmAvailable + lastSuccessfulAlarmStatus = isEnabled }.onFailure { - val previous = lastSuccessfulAlarmStatus[info.id] ?: !info.isAlarmAvailable + val previous = lastSuccessfulAlarmStatus ?: !isEnabled _state.update { currentState -> currentState.copy(alarmStatus = if (previous) ENABLED.value else DISABLED.value) } @@ -180,7 +180,7 @@ class MyPageViewModel @Inject constructor( userRepository.setAlarmAvailable(availability) viewModelScope.launch { - debounceFlow.emit(AlarmInfo(id = DEBOUNCE_KEY, isAlarmAvailable = availability)) + debounceFlow.emit(availability) } } @@ -196,6 +196,5 @@ class MyPageViewModel @Inject constructor( companion object { private const val DEBOUNCE_DURATION = 300L - private const val DEBOUNCE_KEY = "NOTIFICATION" } } From b81f23f7fb3e0fd4be8f5f578859b8a345066be2 Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 17:34:38 +0900 Subject: [PATCH 23/25] =?UTF-8?q?[CHORE/#396]=20=ED=83=88=ED=87=B4=20?= =?UTF-8?q?=EB=91=90=20=EB=B2=88=20=ED=95=9C=20=EC=9C=A0=EC=A0=80=EB=8A=94?= =?UTF-8?q?=20=EC=9E=90=EB=8F=99=20disabled=20=EB=90=98=EA=B2=8C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/src/main/java/com/terning/feature/home/HomeRoute.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt b/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt index fe9a6b202..7ee68e6bc 100644 --- a/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt +++ b/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt @@ -104,6 +104,8 @@ fun HomeRoute( viewModel.updateAlarmAvailability(isGranted) viewModel.updatePermissionRequested(true) } + } else { + viewModel.updateAlarmAvailability(false) } } From 05886e78fd8d0b3c10d03709b7fcf29c0a08351e Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 18:00:33 +0900 Subject: [PATCH 24/25] =?UTF-8?q?[FIX/#396]=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=EC=9D=98=20=EC=95=8C=EB=A6=BC=20=ED=99=9C?= =?UTF-8?q?=EC=84=B1=ED=99=94=20=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=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 --- .../home/src/main/java/com/terning/feature/home/HomeRoute.kt | 3 ++- .../src/main/java/com/terning/feature/home/HomeViewModel.kt | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt b/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt index 7ee68e6bc..e97aedf66 100644 --- a/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt +++ b/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt @@ -105,7 +105,8 @@ fun HomeRoute( viewModel.updatePermissionRequested(true) } } else { - viewModel.updateAlarmAvailability(false) + val isAlarmAvailable = viewModel.getAlarmAvailability() + viewModel.updateAlarmAvailability(isAlarmAvailable) } } diff --git a/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt b/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt index a2a65f9e3..00fbe574d 100644 --- a/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt +++ b/feature/home/src/main/java/com/terning/feature/home/HomeViewModel.kt @@ -252,4 +252,6 @@ class HomeViewModel @Inject constructor( ).onFailure(Timber::e) } } + + fun getAlarmAvailability(): Boolean = userRepository.getAlarmAvailable() } \ No newline at end of file From da0c9218586a974a2fc92fca91d3b1d6a9b175fe Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Sat, 17 May 2025 18:16:30 +0900 Subject: [PATCH 25/25] =?UTF-8?q?[FIX/#396]=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=9B=90=EC=83=81=20=EB=B3=B5=EA=B5=AC=20=EB=B0=8F=20=ED=81=90?= =?UTF-8?q?=EC=97=90=EC=9D=B4=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/designsystem/extension/FlowExt.kt | 24 +++++++++++++++++++ .../com/terning/feature/home/HomeRoute.kt | 3 ++- .../feature/mypage/mypage/MyPageViewModel.kt | 24 ++++++++++++------- .../feature/mypage/mypage/model/AlarmInfo.kt | 6 +++++ 4 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt create mode 100644 feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt diff --git a/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt b/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt new file mode 100644 index 000000000..981c7b437 --- /dev/null +++ b/core/designsystem/src/main/java/com/terning/core/designsystem/extension/FlowExt.kt @@ -0,0 +1,24 @@ +package com.terning.core.designsystem.extension + +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.SendChannel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.consumeAsFlow +import kotlinx.coroutines.flow.flow + +fun Flow.groupBy(getKey: (T) -> K): Flow>> = flow { + val storage = mutableMapOf>() + try { + collect { t -> + val key = getKey(t) + val channel = storage.getOrPut(key) { + Channel(capacity = Channel.BUFFERED).also { + emit(key to it.consumeAsFlow()) + } + } + channel.send(t) + } + } finally { + storage.values.forEach { it.close() } + } +} \ No newline at end of file diff --git a/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt b/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt index e97aedf66..2f3472383 100644 --- a/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt +++ b/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt @@ -104,7 +104,8 @@ fun HomeRoute( viewModel.updateAlarmAvailability(isGranted) viewModel.updatePermissionRequested(true) } - } else { + } + else { val isAlarmAvailable = viewModel.getAlarmAvailability() viewModel.updateAlarmAvailability(isAlarmAvailable) } diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt index 965bfc9e5..5ec56d298 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt @@ -3,12 +3,14 @@ package com.terning.feature.mypage.mypage import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.kakao.sdk.user.UserApiClient +import com.terning.core.designsystem.extension.groupBy import com.terning.core.designsystem.state.UiState import com.terning.core.designsystem.type.AlarmType.DISABLED import com.terning.core.designsystem.type.AlarmType.ENABLED import com.terning.domain.mypage.entity.AlarmStatus import com.terning.domain.mypage.repository.MyPageRepository import com.terning.domain.user.repository.UserRepository +import com.terning.feature.mypage.mypage.model.AlarmInfo import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview @@ -19,6 +21,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.flatMapMerge import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import javax.inject.Inject @@ -37,9 +40,9 @@ class MyPageViewModel @Inject constructor( private val _sideEffects = MutableSharedFlow() val sideEffects: SharedFlow get() = _sideEffects.asSharedFlow() - private val debounceFlow = MutableSharedFlow() + private val debounceFlow = MutableSharedFlow() - private var lastSuccessfulAlarmStatus: Boolean? = null + private val lastSuccessfulAlarmStatus = mutableMapOf() init { handleDebouncedAlarm() @@ -48,14 +51,15 @@ class MyPageViewModel @Inject constructor( private fun handleDebouncedAlarm() { viewModelScope.launch { debounceFlow - .debounce(DEBOUNCE_DURATION) - .collect { isEnabled -> + .groupBy { it.id } + .flatMapMerge { (_, flow) -> flow.debounce(DEBOUNCE_DURATION) } + .collect { info -> myPageRepository.updateAlarmState( - AlarmStatus(if (isEnabled) ENABLED.value else DISABLED.value) + AlarmStatus(if (info.isAlarmAvailable) ENABLED.value else DISABLED.value) ).onSuccess { - lastSuccessfulAlarmStatus = isEnabled + lastSuccessfulAlarmStatus[info.id] = info.isAlarmAvailable }.onFailure { - val previous = lastSuccessfulAlarmStatus ?: !isEnabled + val previous = lastSuccessfulAlarmStatus[info.id] ?: !info.isAlarmAvailable _state.update { currentState -> currentState.copy(alarmStatus = if (previous) ENABLED.value else DISABLED.value) } @@ -128,7 +132,8 @@ class MyPageViewModel @Inject constructor( } }.onFailure { _sideEffects.emit(MyPageSideEffect.ShowToast(DesignSystemR.string.server_failure)) - _state.value = _state.value.copy(isGetSuccess = UiState.Failure(it.toString())) + _state.value = + _state.value.copy(isGetSuccess = UiState.Failure(it.toString())) } } } @@ -180,7 +185,7 @@ class MyPageViewModel @Inject constructor( userRepository.setAlarmAvailable(availability) viewModelScope.launch { - debounceFlow.emit(availability) + debounceFlow.emit(AlarmInfo(id = DEBOUNCE_KEY, isAlarmAvailable = availability)) } } @@ -196,5 +201,6 @@ class MyPageViewModel @Inject constructor( companion object { private const val DEBOUNCE_DURATION = 300L + private const val DEBOUNCE_KEY = "NOTIFICATION" } } diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt new file mode 100644 index 000000000..e9a7b8a80 --- /dev/null +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/model/AlarmInfo.kt @@ -0,0 +1,6 @@ +package com.terning.feature.mypage.mypage.model + +internal data class AlarmInfo( + val id: String, + val isAlarmAvailable: Boolean +) \ No newline at end of file