Skip to content

Commit 793189b

Browse files
committed
[BOOK-275] feat: 에러 핸들링 추가
1 parent 9434d5b commit 793189b

File tree

4 files changed

+53
-3
lines changed

4 files changed

+53
-3
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.ninecraft.booket.feature.record.ocr
2+
3+
import android.widget.Toast
4+
import androidx.compose.runtime.Composable
5+
import androidx.compose.ui.platform.LocalContext
6+
import com.skydoves.compose.effects.RememberedEffect
7+
8+
@Composable
9+
internal fun HandleOcrSideEffects(
10+
state: OcrUiState,
11+
) {
12+
val context = LocalContext.current
13+
14+
RememberedEffect(state.sideEffect) {
15+
when (state.sideEffect) {
16+
is OcrSideEffect.ShowToast -> {
17+
Toast.makeText(context, state.sideEffect.message, Toast.LENGTH_SHORT).show()
18+
}
19+
20+
null -> {}
21+
}
22+
}
23+
}

feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrPresenter.kt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.compose.runtime.getValue
66
import androidx.compose.runtime.mutableStateOf
77
import androidx.compose.runtime.rememberCoroutineScope
88
import androidx.compose.runtime.setValue
9+
import com.ninecraft.booket.core.common.utils.handleException
910
import com.ninecraft.booket.core.ocr.analyzer.CloudOcrRecognizer
1011
import com.ninecraft.booket.feature.screens.OcrScreen
1112
import com.orhanobut.logger.Logger
@@ -38,6 +39,7 @@ class OcrPresenter @AssistedInject constructor(
3839
var isTextDetectionFailed by rememberRetained { mutableStateOf(false) }
3940
var isRecaptureDialogVisible by rememberRetained { mutableStateOf(false) }
4041
var isLoading by rememberRetained { mutableStateOf(false) }
42+
var sideEffect by rememberRetained { mutableStateOf<OcrSideEffect?>(null) }
4143

4244
fun recognizeText(base64Image: String) {
4345
scope.launch {
@@ -61,9 +63,19 @@ class OcrPresenter @AssistedInject constructor(
6163
isTextDetectionFailed = true
6264
}
6365
}
64-
.onFailure {
66+
.onFailure { exception ->
6567
isTextDetectionFailed = true
66-
Logger.e("Cloud Vision API Error: ${it.message}")
68+
69+
val handleErrorMessage = { message: String ->
70+
Logger.e("Cloud Vision API Error: ${exception.message}")
71+
sideEffect = OcrSideEffect.ShowToast(message)
72+
}
73+
74+
handleException(
75+
exception = exception,
76+
onError = handleErrorMessage,
77+
onLoginRequired = {},
78+
)
6779
}
6880
} finally {
6981
isLoading = false
@@ -86,6 +98,8 @@ class OcrPresenter @AssistedInject constructor(
8698
}
8799

88100
is OcrUiEvent.OnCaptureButtonClick -> {
101+
isTextDetectionFailed = false
102+
89103
val base64Image = Base64.encodeToString(event.imageData, Base64.NO_WRAP)
90104
recognizeText(base64Image)
91105
}
@@ -128,6 +142,7 @@ class OcrPresenter @AssistedInject constructor(
128142
isTextDetectionFailed = isTextDetectionFailed,
129143
isRecaptureDialogVisible = isRecaptureDialogVisible,
130144
isLoading = isLoading,
145+
sideEffect = sideEffect,
131146
eventSink = ::handleEvent,
132147
)
133148
}

feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ internal fun OcrUi(
8181
state: OcrUiState,
8282
modifier: Modifier = Modifier,
8383
) {
84+
HandleOcrSideEffects(state = state)
85+
8486
when (state.currentUi) {
8587
OcrUi.CAMERA -> CameraPreview(state = state, modifier = modifier)
8688
OcrUi.RESULT -> TextScanResult(state = state, modifier = modifier)

feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUiState.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package com.ninecraft.booket.feature.record.ocr
22

3-
import androidx.camera.core.ImageProxy
3+
import androidx.compose.runtime.Immutable
44
import com.slack.circuit.runtime.CircuitUiEvent
55
import com.slack.circuit.runtime.CircuitUiState
66
import kotlinx.collections.immutable.ImmutableList
77
import kotlinx.collections.immutable.toPersistentList
8+
import java.util.UUID
89

910
data class OcrUiState(
1011
val currentUi: OcrUi = OcrUi.CAMERA,
@@ -14,9 +15,18 @@ data class OcrUiState(
1415
val isTextDetectionFailed: Boolean = false,
1516
val isRecaptureDialogVisible: Boolean = false,
1617
val isLoading: Boolean = false,
18+
val sideEffect: OcrSideEffect? = null,
1719
val eventSink: (OcrUiEvent) -> Unit,
1820
) : CircuitUiState
1921

22+
@Immutable
23+
sealed interface OcrSideEffect {
24+
data class ShowToast(
25+
val message: String,
26+
private val key: String = UUID.randomUUID().toString(),
27+
) : OcrSideEffect
28+
}
29+
2030
sealed interface OcrUiEvent : CircuitUiEvent {
2131
data object OnCloseClick : OcrUiEvent
2232
data object OnShowPermissionDialog : OcrUiEvent

0 commit comments

Comments
 (0)