diff --git a/core/common/src/main/kotlin/com/ninecraft/booket/core/common/constants/ErrorDialogSpec.kt b/core/common/src/main/kotlin/com/ninecraft/booket/core/common/constants/ErrorDialogSpec.kt
index a6cefa89..33ce49ec 100644
--- a/core/common/src/main/kotlin/com/ninecraft/booket/core/common/constants/ErrorDialogSpec.kt
+++ b/core/common/src/main/kotlin/com/ninecraft/booket/core/common/constants/ErrorDialogSpec.kt
@@ -2,6 +2,6 @@ package com.ninecraft.booket.core.common.constants
data class ErrorDialogSpec(
val message: String,
- val buttonLabel: String,
+ val buttonLabelResId: Int,
val action: () -> Unit,
)
diff --git a/core/common/src/main/kotlin/com/ninecraft/booket/core/common/utils/HandleException.kt b/core/common/src/main/kotlin/com/ninecraft/booket/core/common/utils/HandleException.kt
index 0920c555..fb2850a2 100644
--- a/core/common/src/main/kotlin/com/ninecraft/booket/core/common/utils/HandleException.kt
+++ b/core/common/src/main/kotlin/com/ninecraft/booket/core/common/utils/HandleException.kt
@@ -1,5 +1,7 @@
package com.ninecraft.booket.core.common.utils
+import androidx.annotation.StringRes
+import com.ninecraft.booket.core.common.R
import com.ninecraft.booket.core.common.constants.ErrorDialogSpec
import com.ninecraft.booket.core.common.constants.ErrorScope
import com.ninecraft.booket.core.common.event.ErrorEvent
@@ -46,11 +48,13 @@ fun handleException(
fun postErrorDialog(
errorScope: ErrorScope,
exception: Throwable,
+ @StringRes buttonLabelResId: Int = R.string.confirm,
action: () -> Unit = {},
) {
val spec = buildDialog(
scope = errorScope,
exception = exception,
+ buttonLabelResId = buttonLabelResId,
action = action,
)
@@ -60,6 +64,7 @@ fun postErrorDialog(
private fun buildDialog(
scope: ErrorScope,
exception: Throwable,
+ @StringRes buttonLabelResId: Int,
action: () -> Unit,
): ErrorDialogSpec {
val message = when {
@@ -92,7 +97,7 @@ private fun buildDialog(
}
}
- return ErrorDialogSpec(message = message, buttonLabel = "확인", action = action)
+ return ErrorDialogSpec(message = message, buttonLabelResId = buttonLabelResId, action = action)
}
@Suppress("TooGenericExceptionCaught")
diff --git a/core/common/src/main/res/values/strings.xml b/core/common/src/main/res/values/strings.xml
index 71ff450b..45506ca4 100644
--- a/core/common/src/main/res/values/strings.xml
+++ b/core/common/src/main/res/values/strings.xml
@@ -5,4 +5,5 @@
독서 완료
페이지순
최신 등록순
+ 확인
diff --git a/core/model/src/main/kotlin/com/ninecraft/booket/core/model/BookUpsertModel.kt b/core/model/src/main/kotlin/com/ninecraft/booket/core/model/BookUpsertModel.kt
index 40843cef..617f1d11 100644
--- a/core/model/src/main/kotlin/com/ninecraft/booket/core/model/BookUpsertModel.kt
+++ b/core/model/src/main/kotlin/com/ninecraft/booket/core/model/BookUpsertModel.kt
@@ -1,8 +1,5 @@
package com.ninecraft.booket.core.model
-import androidx.compose.runtime.Stable
-
-@Stable
data class BookUpsertModel(
val userBookId: String,
val userId: String,
diff --git a/core/model/src/main/kotlin/com/ninecraft/booket/core/model/ReadingRecordsModel.kt b/core/model/src/main/kotlin/com/ninecraft/booket/core/model/ReadingRecordsModel.kt
index f60f2dee..1c6356e1 100644
--- a/core/model/src/main/kotlin/com/ninecraft/booket/core/model/ReadingRecordsModel.kt
+++ b/core/model/src/main/kotlin/com/ninecraft/booket/core/model/ReadingRecordsModel.kt
@@ -1,5 +1,7 @@
package com.ninecraft.booket.core.model
+import androidx.compose.runtime.Stable
+
data class ReadingRecordsModel(
val lastPage: Boolean = true,
val totalResults: Int = 0,
@@ -8,6 +10,7 @@ data class ReadingRecordsModel(
val readingRecords: List = emptyList(),
)
+@Stable
data class ReadingRecordModel(
val id: String = "",
val userBookId: String = "",
diff --git a/core/ui/src/main/kotlin/com/ninecraft/booket/core/ui/ReedScaffold.kt b/core/ui/src/main/kotlin/com/ninecraft/booket/core/ui/ReedScaffold.kt
index 3e4f4edd..be8a59c2 100644
--- a/core/ui/src/main/kotlin/com/ninecraft/booket/core/ui/ReedScaffold.kt
+++ b/core/ui/src/main/kotlin/com/ninecraft/booket/core/ui/ReedScaffold.kt
@@ -22,13 +22,13 @@ fun ReedScaffold(
content: @Composable (PaddingValues) -> Unit,
) {
Scaffold(
+ modifier = modifier.keyboardHide(),
topBar = topBar,
bottomBar = bottomBar,
snackbarHost = snackbarHost,
floatingActionButton = floatingActionButton,
containerColor = containerColor,
contentWindowInsets = contentWindowInsets,
- modifier = modifier.keyboardHide(),
) { innerPadding ->
content(innerPadding)
}
diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt
index 4ee9010b..93ad9fcc 100644
--- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt
+++ b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt
@@ -11,6 +11,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.stringResource
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import com.ninecraft.booket.core.common.constants.ErrorDialogSpec
import com.ninecraft.booket.core.common.event.ErrorEvent
@@ -70,7 +71,8 @@ class MainActivity : ComponentActivity() {
dialogSpec.value?.let { spec ->
ReedDialog(
description = spec.message,
- confirmButtonText = spec.buttonLabel,
+ confirmButtonText = stringResource(spec.buttonLabelResId),
+
onConfirmRequest = {
spec.action()
dialogSpec.value = null
diff --git a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt
index fa7031e8..242b1c84 100644
--- a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt
+++ b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt
@@ -56,7 +56,7 @@ internal fun RecordRegisterUi(
)
RecordProgressBar(
currentStep = state.currentStep,
- modifier = modifier.padding(horizontal = ReedTheme.spacing.spacing5),
+ modifier = Modifier.padding(horizontal = ReedTheme.spacing.spacing5),
)
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing10))
when (state.currentStep) {
diff --git a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt
index 62efcce8..677465fc 100644
--- a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt
+++ b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt
@@ -158,7 +158,7 @@ class BookSearchPresenter @AssistedInject constructor(
}
is BookSearchUiEvent.OnSearchClick -> {
- val query = event.text.trim()
+ val query = event.query.trim()
if (query.isNotEmpty()) {
searchBooks(query = query, startIndex = START_INDEX)
}
diff --git a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt
index 28b8ea15..42d48337 100644
--- a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt
+++ b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt
@@ -93,13 +93,13 @@ internal fun SearchContent(
ReedTextField(
queryState = state.queryState,
queryHintRes = designR.string.search_book_hint,
- onSearch = { text ->
- state.eventSink(BookSearchUiEvent.OnSearchClick(text))
+ onSearch = { query ->
+ state.eventSink(BookSearchUiEvent.OnSearchClick(query))
},
onClear = {
state.eventSink(BookSearchUiEvent.OnClearClick)
},
- modifier = modifier.padding(horizontal = ReedTheme.spacing.spacing5),
+ modifier = Modifier.padding(horizontal = ReedTheme.spacing.spacing5),
borderStroke = BorderStroke(width = 1.dp, color = ReedTheme.colors.borderBrand),
searchIconTint = ReedTheme.colors.contentBrand,
)
diff --git a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUiState.kt b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUiState.kt
index 3f534a38..edb48186 100644
--- a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUiState.kt
+++ b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUiState.kt
@@ -48,7 +48,7 @@ sealed interface BookSearchUiEvent : CircuitUiEvent {
data object OnBackClick : BookSearchUiEvent
data class OnRecentSearchClick(val query: String) : BookSearchUiEvent
data class OnRecentSearchRemoveClick(val query: String) : BookSearchUiEvent
- data class OnSearchClick(val text: String) : BookSearchUiEvent
+ data class OnSearchClick(val query: String) : BookSearchUiEvent
data object OnClearClick : BookSearchUiEvent
data class OnBookClick(val isbn13: String) : BookSearchUiEvent
data object OnLoadMore : BookSearchUiEvent
diff --git a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt
index b40cb66e..9634eb60 100644
--- a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt
+++ b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt
@@ -75,13 +75,13 @@ internal fun LibrarySearchContent(
ReedTextField(
queryState = state.queryState,
queryHintRes = R.string.library_search_hint,
- onSearch = { text ->
- state.eventSink(LibrarySearchUiEvent.OnSearchClick(text))
+ onSearch = { query ->
+ state.eventSink(LibrarySearchUiEvent.OnSearchClick(query))
},
onClear = {
state.eventSink(LibrarySearchUiEvent.OnClearClick)
},
- modifier = modifier.padding(horizontal = ReedTheme.spacing.spacing5),
+ modifier = Modifier.padding(horizontal = ReedTheme.spacing.spacing5),
backgroundColor = ReedTheme.colors.baseSecondary,
borderStroke = null,
)
diff --git a/feature/settings/src/main/assets/oss_licenses.json b/feature/settings/src/main/assets/oss_licenses.json
index 71d1421f..ce75a00b 100644
--- a/feature/settings/src/main/assets/oss_licenses.json
+++ b/feature/settings/src/main/assets/oss_licenses.json
@@ -44,6 +44,56 @@
"license": "Apache License 2.0",
"url": "https://github.com/coil-kt/coil"
},
+ {
+ "name": "Landscapist",
+ "license": "Apache License 2.0",
+ "url": "https://github.com/skydoves/landscapist"
+ },
+ {
+ "name": "Google Analytics",
+ "license": "Apache License 2.0",
+ "url": "https://firebase.google.com/docs/analytics"
+ },
+ {
+ "name": "Firebase Crashlytics",
+ "license": "Apache License 2.0",
+ "url": "https://firebase.google.com/docs/crashlytics"
+ },
+ {
+ "name": "ML Kit Text Recognition",
+ "license": "Apache License 2.0",
+ "url": "https://developers.google.com/ml-kit/vision/text-recognition"
+ },
+ {
+ "name": "Compose System UI Controller",
+ "license": "MIT License",
+ "url": "https://github.com/taehwandev/ComposeExtensions"
+ },
+ {
+ "name": "Compose Keyboard State",
+ "license": "MIT License",
+ "url": "https://github.com/taehwandev/ComposeExtensions"
+ },
+ {
+ "name": "Lottie Compose",
+ "license": "Apache License 2.0",
+ "url": "https://github.com/airbnb/lottie-android"
+ },
+ {
+ "name": "Kakao SDK",
+ "license": "Apache License 2.0",
+ "url": "https://developers.kakao.com/docs/latest/ko/android/getting-started"
+ },
+ {
+ "name": "Kotlinx Collections Immutable",
+ "license": "Apache License 2.0",
+ "url": "https://github.com/Kotlin/kotlinx.collections.immutable"
+ },
+ {
+ "name": "Compose Shadow",
+ "license": "MIT License",
+ "url": "https://github.com/adamglin0/compose-shadow"
+ },
{
"name": "Detekt",
"license": "Apache License 2.0",
diff --git a/feature/splash/src/main/kotlin/com/ninecraft/booket/splash/SplashPresenter.kt b/feature/splash/src/main/kotlin/com/ninecraft/booket/splash/SplashPresenter.kt
index ef79f06f..b8715ef5 100644
--- a/feature/splash/src/main/kotlin/com/ninecraft/booket/splash/SplashPresenter.kt
+++ b/feature/splash/src/main/kotlin/com/ninecraft/booket/splash/SplashPresenter.kt
@@ -6,10 +6,13 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
+import com.ninecraft.booket.core.common.constants.ErrorScope
+import com.ninecraft.booket.core.common.utils.postErrorDialog
import com.ninecraft.booket.core.data.api.repository.AuthRepository
import com.ninecraft.booket.core.data.api.repository.UserRepository
import com.ninecraft.booket.core.model.AutoLoginState
import com.ninecraft.booket.core.model.OnboardingState
+import com.ninecraft.booket.core.ui.R
import com.ninecraft.booket.feature.screens.HomeScreen
import com.ninecraft.booket.feature.screens.LoginScreen
import com.ninecraft.booket.feature.screens.OnboardingScreen
@@ -50,8 +53,13 @@ class SplashPresenter @AssistedInject constructor(
navigator.resetRoot(LoginScreen)
}
}
- .onFailure {
- navigator.resetRoot(LoginScreen)
+ .onFailure { exception ->
+ postErrorDialog(
+ errorScope = ErrorScope.GLOBAL,
+ exception = exception,
+ buttonLabelResId = R.string.retry,
+ action = { checkTermsAgreement() },
+ )
}
}
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 96ee3042..896dd695 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -123,7 +123,6 @@ landscapist-placeholder = { group = "com.github.skydoves", name = "landscapist-p
kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }
-kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinx-datetime" }
kotlinx-collections-immutable = { group = "org.jetbrains.kotlinx", name = "kotlinx-collections-immutable", version.ref = "kotlinx-collections-immutable" }
circuit-foundation = { group = "com.slack.circuit", name = "circuit-foundation", version.ref = "circuit" }