Skip to content

Commit da0c921

Browse files
committed
[FIX/#396] 코드 원상 복구 및 큐에이 해결
1 parent 05886e7 commit da0c921

4 files changed

Lines changed: 47 additions & 10 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.terning.core.designsystem.extension
2+
3+
import kotlinx.coroutines.channels.Channel
4+
import kotlinx.coroutines.channels.SendChannel
5+
import kotlinx.coroutines.flow.Flow
6+
import kotlinx.coroutines.flow.consumeAsFlow
7+
import kotlinx.coroutines.flow.flow
8+
9+
fun <T, K> Flow<T>.groupBy(getKey: (T) -> K): Flow<Pair<K, Flow<T>>> = flow {
10+
val storage = mutableMapOf<K, SendChannel<T>>()
11+
try {
12+
collect { t ->
13+
val key = getKey(t)
14+
val channel = storage.getOrPut(key) {
15+
Channel<T>(capacity = Channel.BUFFERED).also {
16+
emit(key to it.consumeAsFlow())
17+
}
18+
}
19+
channel.send(t)
20+
}
21+
} finally {
22+
storage.values.forEach { it.close() }
23+
}
24+
}

feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ fun HomeRoute(
104104
viewModel.updateAlarmAvailability(isGranted)
105105
viewModel.updatePermissionRequested(true)
106106
}
107-
} else {
107+
}
108+
else {
108109
val isAlarmAvailable = viewModel.getAlarmAvailability()
109110
viewModel.updateAlarmAvailability(isAlarmAvailable)
110111
}

feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ package com.terning.feature.mypage.mypage
33
import androidx.lifecycle.ViewModel
44
import androidx.lifecycle.viewModelScope
55
import com.kakao.sdk.user.UserApiClient
6+
import com.terning.core.designsystem.extension.groupBy
67
import com.terning.core.designsystem.state.UiState
78
import com.terning.core.designsystem.type.AlarmType.DISABLED
89
import com.terning.core.designsystem.type.AlarmType.ENABLED
910
import com.terning.domain.mypage.entity.AlarmStatus
1011
import com.terning.domain.mypage.repository.MyPageRepository
1112
import com.terning.domain.user.repository.UserRepository
13+
import com.terning.feature.mypage.mypage.model.AlarmInfo
1214
import dagger.hilt.android.lifecycle.HiltViewModel
1315
import kotlinx.coroutines.ExperimentalCoroutinesApi
1416
import kotlinx.coroutines.FlowPreview
@@ -19,6 +21,7 @@ import kotlinx.coroutines.flow.StateFlow
1921
import kotlinx.coroutines.flow.asSharedFlow
2022
import kotlinx.coroutines.flow.asStateFlow
2123
import kotlinx.coroutines.flow.debounce
24+
import kotlinx.coroutines.flow.flatMapMerge
2225
import kotlinx.coroutines.flow.update
2326
import kotlinx.coroutines.launch
2427
import javax.inject.Inject
@@ -37,9 +40,9 @@ class MyPageViewModel @Inject constructor(
3740
private val _sideEffects = MutableSharedFlow<MyPageSideEffect>()
3841
val sideEffects: SharedFlow<MyPageSideEffect> get() = _sideEffects.asSharedFlow()
3942

40-
private val debounceFlow = MutableSharedFlow<Boolean>()
43+
private val debounceFlow = MutableSharedFlow<AlarmInfo>()
4144

42-
private var lastSuccessfulAlarmStatus: Boolean? = null
45+
private val lastSuccessfulAlarmStatus = mutableMapOf<String, Boolean>()
4346

4447
init {
4548
handleDebouncedAlarm()
@@ -48,14 +51,15 @@ class MyPageViewModel @Inject constructor(
4851
private fun handleDebouncedAlarm() {
4952
viewModelScope.launch {
5053
debounceFlow
51-
.debounce(DEBOUNCE_DURATION)
52-
.collect { isEnabled ->
54+
.groupBy { it.id }
55+
.flatMapMerge { (_, flow) -> flow.debounce(DEBOUNCE_DURATION) }
56+
.collect { info ->
5357
myPageRepository.updateAlarmState(
54-
AlarmStatus(if (isEnabled) ENABLED.value else DISABLED.value)
58+
AlarmStatus(if (info.isAlarmAvailable) ENABLED.value else DISABLED.value)
5559
).onSuccess {
56-
lastSuccessfulAlarmStatus = isEnabled
60+
lastSuccessfulAlarmStatus[info.id] = info.isAlarmAvailable
5761
}.onFailure {
58-
val previous = lastSuccessfulAlarmStatus ?: !isEnabled
62+
val previous = lastSuccessfulAlarmStatus[info.id] ?: !info.isAlarmAvailable
5963
_state.update { currentState ->
6064
currentState.copy(alarmStatus = if (previous) ENABLED.value else DISABLED.value)
6165
}
@@ -128,7 +132,8 @@ class MyPageViewModel @Inject constructor(
128132
}
129133
}.onFailure {
130134
_sideEffects.emit(MyPageSideEffect.ShowToast(DesignSystemR.string.server_failure))
131-
_state.value = _state.value.copy(isGetSuccess = UiState.Failure(it.toString()))
135+
_state.value =
136+
_state.value.copy(isGetSuccess = UiState.Failure(it.toString()))
132137
}
133138
}
134139
}
@@ -180,7 +185,7 @@ class MyPageViewModel @Inject constructor(
180185
userRepository.setAlarmAvailable(availability)
181186

182187
viewModelScope.launch {
183-
debounceFlow.emit(availability)
188+
debounceFlow.emit(AlarmInfo(id = DEBOUNCE_KEY, isAlarmAvailable = availability))
184189
}
185190
}
186191

@@ -196,5 +201,6 @@ class MyPageViewModel @Inject constructor(
196201

197202
companion object {
198203
private const val DEBOUNCE_DURATION = 300L
204+
private const val DEBOUNCE_KEY = "NOTIFICATION"
199205
}
200206
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.terning.feature.mypage.mypage.model
2+
3+
internal data class AlarmInfo(
4+
val id: String,
5+
val isAlarmAvailable: Boolean
6+
)

0 commit comments

Comments
 (0)