Skip to content

Commit 599e0f0

Browse files
authored
Merge pull request #153 from YAPP-Github/BOOK-272-feature/#148
feat: 등록 도서 삭제 기능 구현
2 parents 1e15367 + 7c0c118 commit 599e0f0

File tree

26 files changed

+263
-34
lines changed

26 files changed

+263
-34
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.ninecraft.booket.core.common.constants
22

3+
import androidx.annotation.StringRes
4+
35
data class ErrorDialogSpec(
46
val message: String,
5-
val buttonLabelResId: Int,
7+
@StringRes val buttonLabelResId: Int,
68
val action: () -> Unit,
79
)

core/data/api/src/main/kotlin/com/ninecraft/booket/core/data/api/repository/BookRepository.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ interface BookRepository {
1717
start: Int,
1818
): Result<BookSearchModel>
1919

20-
suspend fun removeBookRecentSearch(query: String)
20+
suspend fun deleteBookRecentSearch(query: String)
2121

2222
suspend fun getBookDetail(isbn13: String): Result<BookDetailModel>
2323

@@ -38,9 +38,11 @@ interface BookRepository {
3838
size: Int,
3939
): Result<LibraryModel>
4040

41-
suspend fun removeLibraryRecentSearch(query: String)
41+
suspend fun deleteLibraryRecentSearch(query: String)
4242

4343
suspend fun getHome(): Result<HomeModel>
4444

4545
suspend fun getSeedsStats(userBookId: String): Result<SeedModel>
46+
47+
suspend fun deleteBook(userBookId: String): Result<Unit>
4648
}

core/data/impl/src/main/kotlin/com/ninecraft/booket/core/data/impl/repository/DefaultBookRepository.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ internal class DefaultBookRepository @Inject constructor(
3030
result
3131
}
3232

33-
override suspend fun removeBookRecentSearch(query: String) {
34-
bookRecentSearchDataSource.removeRecentSearch(query)
33+
override suspend fun deleteBookRecentSearch(query: String) {
34+
bookRecentSearchDataSource.deleteRecentSearch(query)
3535
}
3636

3737
override suspend fun getBookDetail(isbn13: String) = runSuspendCatching {
@@ -53,8 +53,8 @@ internal class DefaultBookRepository @Inject constructor(
5353
result
5454
}
5555

56-
override suspend fun removeLibraryRecentSearch(query: String) {
57-
libraryRecentSearchDataSource.removeRecentSearch(query)
56+
override suspend fun deleteLibraryRecentSearch(query: String) {
57+
libraryRecentSearchDataSource.deleteRecentSearch(query)
5858
}
5959

6060
override suspend fun getHome() = runSuspendCatching {
@@ -64,4 +64,8 @@ internal class DefaultBookRepository @Inject constructor(
6464
override suspend fun getSeedsStats(userBookId: String) = runSuspendCatching {
6565
service.getSeedsStats(userBookId).toModel()
6666
}
67+
68+
override suspend fun deleteBook(userBookId: String) = runSuspendCatching {
69+
service.deleteBook(userBookId)
70+
}
6771
}

core/datastore/api/src/main/kotlin/com/ninecraft/booket/core/datastore/api/datasource/RecentSearchDataSource.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ import kotlinx.coroutines.flow.Flow
55
interface RecentSearchDataSource {
66
val recentSearches: Flow<List<String>>
77
suspend fun addRecentSearch(query: String)
8-
suspend fun removeRecentSearch(query: String)
8+
suspend fun deleteRecentSearch(query: String)
99
suspend fun clearRecentSearches()
1010
}

core/datastore/impl/src/main/kotlin/com/ninecraft/booket/core/datastore/impl/datasource/DefaultBookRecentSearchDataSource.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class DefaultBookRecentSearchDataSource @Inject constructor(
6767
}
6868

6969
@Suppress("TooGenericExceptionCaught")
70-
override suspend fun removeRecentSearch(query: String) {
70+
override suspend fun deleteRecentSearch(query: String) {
7171
dataStore.edit { prefs ->
7272
val currentSearches = prefs[BOOK_RECENT_SEARCHES]?.let { jsonString ->
7373
try {

core/datastore/impl/src/main/kotlin/com/ninecraft/booket/core/datastore/impl/datasource/DefaultLibraryRecentSearchDataSource.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class DefaultLibraryRecentSearchDataSource @Inject constructor(
6767
}
6868

6969
@Suppress("TooGenericExceptionCaught")
70-
override suspend fun removeRecentSearch(query: String) {
70+
override suspend fun deleteRecentSearch(query: String) {
7171
dataStore.edit { prefs ->
7272
val currentSearches = prefs[LIBRARY_RECENT_SEARCHES]?.let { jsonString ->
7373
try {
@@ -76,7 +76,7 @@ class DefaultLibraryRecentSearchDataSource @Inject constructor(
7676
Logger.e(e, "Failed to deserialize recent searches for removal")
7777
mutableListOf()
7878
} catch (e: Exception) {
79-
Logger.e(e, "Unexpected error while removing recent search")
79+
Logger.e(e, "Unexpected error while deleting recent search")
8080
mutableListOf()
8181
}
8282
} ?: mutableListOf()

core/network/src/main/kotlin/com/ninecraft/booket/core/network/TokenInterceptor.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import okhttp3.Response
77
import javax.inject.Inject
88

99
internal class TokenInterceptor @Inject constructor(
10-
@Suppress("unused")
1110
private val tokenDataSource: TokenDataSource,
1211
) : Interceptor {
1312

core/network/src/main/kotlin/com/ninecraft/booket/core/network/service/ReedService.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ interface ReedService {
8080
@Query("sort") sort: String = "CREATED_DATE_DESC",
8181
): LibraryResponse
8282

83+
@DELETE("api/v1/books/my-library/{userBookId}")
84+
suspend fun deleteBook(
85+
@Path("userBookId") userBookId: String,
86+
)
87+
8388
// Reading-records endpoints (auth required)
8489
@POST("api/v1/reading-records/{userBookId}")
8590
suspend fun postRecord(

core/ui/src/main/kotlin/com/ninecraft/booket/core/ui/component/InfinityLazyColumn.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ fun InfinityLazyColumn(
7272
@SuppressLint("ComposableNaming")
7373
@Composable
7474
private fun LazyListState.onLoadMore(
75-
limitCount: Int = 6,
75+
limitCount: Int = LIMIT_COUNT,
7676
loadOnBottom: Boolean = true,
7777
action: () -> Unit,
7878
) {

feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailPresenter.kt

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class BookDetailPresenter @AssistedInject constructor(
7878
var isRecordSortBottomSheetVisible by rememberRetained { mutableStateOf(false) }
7979
var isRecordMenuBottomSheetVisible by rememberRetained { mutableStateOf(false) }
8080
var isRecordDeleteDialogVisible by rememberRetained { mutableStateOf(false) }
81+
var isDetailMenuBottomSheetVisible by rememberRetained { mutableStateOf(false) }
82+
var isBookDeleteDialogVisible by rememberRetained { mutableStateOf(false) }
8183
var sideEffect by rememberRetained { mutableStateOf<BookDetailSideEffect?>(null) }
8284

8385
@Suppress("TooGenericExceptionCaught")
@@ -212,6 +214,29 @@ class BookDetailPresenter @AssistedInject constructor(
212214
}
213215
}
214216

217+
fun deleteBook(userBookId: String, onSuccess: () -> Unit) {
218+
scope.launch {
219+
bookRepository.deleteBook(userBookId = userBookId)
220+
.onSuccess {
221+
onSuccess()
222+
}
223+
.onFailure { exception ->
224+
val handleErrorMessage = { message: String ->
225+
Logger.e(message)
226+
sideEffect = BookDetailSideEffect.ShowToast(message)
227+
}
228+
229+
handleException(
230+
exception = exception,
231+
onError = handleErrorMessage,
232+
onLoginRequired = {
233+
navigator.resetRoot(LoginScreen)
234+
},
235+
)
236+
}
237+
}
238+
}
239+
215240
LaunchedEffect(Unit) {
216241
initialLoad()
217242
}
@@ -297,7 +322,7 @@ class BookDetailPresenter @AssistedInject constructor(
297322
isRecordDeleteDialogVisible = true
298323
}
299324

300-
is BookDetailUiEvent.OnDelete -> {
325+
is BookDetailUiEvent.OnDeleteRecord -> {
301326
isRecordDeleteDialogVisible = false
302327
deleteRecord(
303328
readingRecordId = selectedRecordInfo.id,
@@ -313,6 +338,33 @@ class BookDetailPresenter @AssistedInject constructor(
313338
navigator.goTo(RecordDetailScreen(event.recordId))
314339
}
315340

341+
is BookDetailUiEvent.OnDetailMenuClick -> {
342+
isDetailMenuBottomSheetVisible = true
343+
}
344+
345+
is BookDetailUiEvent.OnDetailMenuBottomSheetDismiss -> {
346+
isDetailMenuBottomSheetVisible = false
347+
}
348+
349+
is BookDetailUiEvent.OnDeleteBookClick -> {
350+
isDetailMenuBottomSheetVisible = false
351+
isBookDeleteDialogVisible = true
352+
}
353+
354+
is BookDetailUiEvent.OnDeleteDialogDismiss -> {
355+
isBookDeleteDialogVisible = false
356+
}
357+
358+
is BookDetailUiEvent.OnDeleteBook -> {
359+
isBookDeleteDialogVisible = false
360+
deleteBook(
361+
userBookId = screen.userBookId,
362+
onSuccess = {
363+
navigator.pop()
364+
},
365+
)
366+
}
367+
316368
is BookDetailUiEvent.OnLoadMore -> {
317369
if (uiState != UiState.Loading && footerState !is FooterState.Loading && !isLastPage) {
318370
loadMoreReadingRecords(startIndex = currentStartIndex + 1)
@@ -342,6 +394,8 @@ class BookDetailPresenter @AssistedInject constructor(
342394
selectedRecordInfo = selectedRecordInfo,
343395
isRecordMenuBottomSheetVisible = isRecordMenuBottomSheetVisible,
344396
isRecordDeleteDialogVisible = isRecordDeleteDialogVisible,
397+
isDetailMenuBottomSheetVisible = isDetailMenuBottomSheetVisible,
398+
isBookDeleteDialogVisible = isBookDeleteDialogVisible,
345399
sideEffect = sideEffect,
346400
eventSink = ::handleEvent,
347401
)

0 commit comments

Comments
 (0)