Skip to content

Commit ea76358

Browse files
committed
[BOOK-212] feat: 도서 상세 조회 API 연동 WIP
1 parent 3887f73 commit ea76358

File tree

12 files changed

+166
-101
lines changed

12 files changed

+166
-101
lines changed

core/model/src/main/kotlin/com/ninecraft/booket/core/model/BookDetailModel.kt

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@ import androidx.compose.runtime.Stable
44

55
@Stable
66
data class BookDetailModel(
7-
val version: String,
8-
val title: String,
9-
val link: String,
10-
val author: String,
11-
val pubDate: String,
12-
val description: String,
13-
val isbn: String,
14-
val isbn13: String,
15-
val itemId: Long,
16-
val priceSales: Double,
17-
val priceStandard: Double,
18-
val mallType: String,
19-
val stockStatus: String,
20-
val mileage: Int,
21-
val cover: String,
22-
val categoryId: Int,
23-
val categoryName: String,
24-
val publisher: String,
7+
val version: String = "",
8+
val title: String = "",
9+
val link: String = "",
10+
val author: String = "",
11+
val pubDate: String = "",
12+
val description: String = "",
13+
val isbn: String = "",
14+
val isbn13: String = "",
15+
val itemId: Long = 0L,
16+
val priceSales: Double = 0.0,
17+
val priceStandard: Double = 0.0,
18+
val mallType: String = "",
19+
val stockStatus: String = "",
20+
val mileage: Int = 0,
21+
val cover: String = "",
22+
val categoryId: Int = 0,
23+
val categoryName: String = "",
24+
val publisher: String = "",
2525
)

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

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package com.ninecraft.booket.feature.detail.book
22

33
import androidx.compose.runtime.Composable
4+
import androidx.compose.runtime.LaunchedEffect
45
import androidx.compose.runtime.getValue
56
import androidx.compose.runtime.mutableStateOf
67
import androidx.compose.runtime.rememberCoroutineScope
78
import androidx.compose.runtime.setValue
89
import com.ninecraft.booket.core.common.constants.BookStatus
910
import com.ninecraft.booket.core.common.utils.handleException
1011
import com.ninecraft.booket.core.data.api.repository.BookRepository
12+
import com.ninecraft.booket.core.model.BookDetailModel
1113
import com.ninecraft.booket.feature.screens.BookDetailScreen
1214
import com.ninecraft.booket.feature.screens.LoginScreen
1315
import com.ninecraft.booket.feature.screens.RecordDetailScreen
@@ -33,17 +35,47 @@ class BookDetailPresenter @AssistedInject constructor(
3335
override fun present(): BookDetailUiState {
3436
val scope = rememberCoroutineScope()
3537

38+
var isLoading by rememberRetained { mutableStateOf(false) }
39+
var bookDetail by rememberRetained { mutableStateOf(BookDetailModel()) }
3640
var isBookUpdateBottomSheetVisible by rememberRetained { mutableStateOf(false) }
3741
var isRecordSortBottomSheetVisible by rememberRetained { mutableStateOf(false) }
3842
var currentBookStatus by rememberRetained { mutableStateOf(BookStatus.READING) }
3943
var currentRecordSort by rememberRetained { mutableStateOf(RecordSort.PAGE_ASCENDING) }
4044
var sideEffect by rememberRetained { mutableStateOf<BookDetailSideEffect?>(null) }
4145

46+
fun getBookDetail() {
47+
scope.launch {
48+
try {
49+
isLoading = true
50+
repository.getBookDetail(screen.bookId)
51+
.onSuccess { result ->
52+
bookDetail = result
53+
}
54+
.onFailure { exception ->
55+
val handleErrorMessage = { message: String ->
56+
Logger.e(message)
57+
sideEffect = BookDetailSideEffect.ShowToast(message)
58+
}
59+
60+
handleException(
61+
exception = exception,
62+
onError = handleErrorMessage,
63+
onLoginRequired = {
64+
navigator.resetRoot(LoginScreen)
65+
},
66+
)
67+
}
68+
} finally {
69+
isLoading = false
70+
}
71+
}
72+
}
73+
4274
fun upsertBook(bookIsbn: String, bookStatus: String) {
4375
scope.launch {
4476
repository.upsertBook(bookIsbn, bookStatus)
4577
.onSuccess {
46-
sideEffect = BookDetailSideEffect.ShowToast("성공")
78+
isBookUpdateBottomSheetVisible = false
4779
}
4880
.onFailure { exception ->
4981
val handleErrorMessage = { message: String ->
@@ -62,6 +94,10 @@ class BookDetailPresenter @AssistedInject constructor(
6294
}
6395
}
6496

97+
LaunchedEffect(screen.bookId) {
98+
getBookDetail()
99+
}
100+
65101
fun handleEvent(event: BookDetailUiEvent) {
66102
when (event) {
67103
is BookDetailUiEvent.InitSideEffect -> {
@@ -93,7 +129,7 @@ class BookDetailPresenter @AssistedInject constructor(
93129
}
94130

95131
is BookDetailUiEvent.OnBookStatusUpdateButtonClick -> {
96-
upsertBook(screen.isbn, currentBookStatus.value)
132+
upsertBook(screen.bookId, currentBookStatus.value)
97133
}
98134

99135
is BookDetailUiEvent.OnRecordSortBottomSheetDismiss -> {
@@ -112,6 +148,8 @@ class BookDetailPresenter @AssistedInject constructor(
112148
}
113149

114150
return BookDetailUiState(
151+
isLoading = isLoading,
152+
bookDetail = bookDetail,
115153
isBookUpdateBottomSheetVisible = isBookUpdateBottomSheetVisible,
116154
isRecordSortBottomSheetVisible = isRecordSortBottomSheetVisible,
117155
currentBookStatus = currentBookStatus,

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

Lines changed: 2 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,26 @@ import androidx.compose.foundation.layout.size
1111
import androidx.compose.foundation.layout.width
1212
import androidx.compose.foundation.layout.widthIn
1313
import androidx.compose.foundation.rememberScrollState
14-
import androidx.compose.foundation.shape.RoundedCornerShape
1514
import androidx.compose.foundation.verticalScroll
1615
import androidx.compose.material3.ExperimentalMaterial3Api
1716
import androidx.compose.material3.Icon
18-
import androidx.compose.material3.Text
19-
import androidx.compose.material3.VerticalDivider
2017
import androidx.compose.material3.rememberModalBottomSheetState
2118
import androidx.compose.runtime.Composable
2219
import androidx.compose.runtime.rememberCoroutineScope
23-
import androidx.compose.ui.Alignment
2420
import androidx.compose.ui.Modifier
25-
import androidx.compose.ui.draw.clip
2621
import androidx.compose.ui.graphics.vector.ImageVector
27-
import androidx.compose.ui.res.painterResource
2822
import androidx.compose.ui.res.vectorResource
29-
import androidx.compose.ui.text.style.TextOverflow
3023
import androidx.compose.ui.unit.dp
3124
import com.ninecraft.booket.core.common.constants.BookStatus
3225
import com.ninecraft.booket.core.designsystem.ComponentPreview
33-
import com.ninecraft.booket.core.designsystem.component.NetworkImage
3426
import com.ninecraft.booket.core.designsystem.component.ReedDivider
3527
import com.ninecraft.booket.core.designsystem.component.button.ReedButton
3628
import com.ninecraft.booket.core.designsystem.component.button.ReedButtonColorStyle
3729
import com.ninecraft.booket.core.designsystem.component.button.largeButtonStyle
3830
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
3931
import com.ninecraft.booket.core.ui.component.ReedBackTopAppBar
4032
import com.ninecraft.booket.core.ui.component.ReedFullScreen
33+
import com.ninecraft.booket.feature.detail.book.component.BookItem
4134
import com.ninecraft.booket.feature.detail.book.component.BookUpdateBottomSheet
4235
import com.ninecraft.booket.feature.detail.book.component.CollectedSeed
4336
import com.ninecraft.booket.feature.detail.book.component.RecordSortBottomSheet
@@ -129,68 +122,7 @@ internal fun BookDetailContent(
129122
.fillMaxSize()
130123
.verticalScroll(rememberScrollState()),
131124
) {
132-
Row(
133-
modifier = modifier
134-
.fillMaxWidth()
135-
.padding(horizontal = ReedTheme.spacing.spacing5),
136-
) {
137-
NetworkImage(
138-
imageUrl = "",
139-
contentDescription = "Book CoverImage",
140-
modifier = Modifier
141-
.padding(end = ReedTheme.spacing.spacing4)
142-
.width(70.dp)
143-
.height(99.dp)
144-
.clip(RoundedCornerShape(size = ReedTheme.radius.xs)),
145-
placeholder = painterResource(designR.drawable.ic_placeholder),
146-
)
147-
Column(modifier = Modifier.weight(1f)) {
148-
Text(
149-
text = "여름은 오래 그곳에 남아",
150-
color = ReedTheme.colors.contentPrimary,
151-
overflow = TextOverflow.Ellipsis,
152-
maxLines = 2,
153-
style = ReedTheme.typography.headline1SemiBold,
154-
)
155-
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing2))
156-
Row(
157-
modifier = Modifier.fillMaxWidth(),
158-
verticalAlignment = Alignment.CenterVertically,
159-
) {
160-
Text(
161-
text = "미쓰이에 마사시",
162-
color = ReedTheme.colors.contentTertiary,
163-
overflow = TextOverflow.Ellipsis,
164-
maxLines = 1,
165-
style = ReedTheme.typography.label2Regular,
166-
modifier = Modifier.weight(0.7f, fill = false),
167-
)
168-
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
169-
VerticalDivider(
170-
modifier = Modifier.height(14.dp),
171-
thickness = 1.dp,
172-
color = ReedTheme.colors.contentTertiary,
173-
)
174-
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
175-
Text(
176-
text = "비채",
177-
color = ReedTheme.colors.contentTertiary,
178-
overflow = TextOverflow.Ellipsis,
179-
maxLines = 1,
180-
style = ReedTheme.typography.label2Regular,
181-
modifier = Modifier.weight(0.3f, fill = false),
182-
)
183-
}
184-
Spacer(Modifier.width(ReedTheme.spacing.spacing05))
185-
Text(
186-
text = "2024년",
187-
color = ReedTheme.colors.contentTertiary,
188-
overflow = TextOverflow.Ellipsis,
189-
maxLines = 1,
190-
style = ReedTheme.typography.label2Regular,
191-
)
192-
}
193-
}
125+
BookItem(bookDetail = state.bookDetail)
194126
Spacer(Modifier.height(ReedTheme.spacing.spacing3))
195127
Spacer(Modifier.height(ReedTheme.spacing.spacing4))
196128
Row(

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.ninecraft.booket.feature.detail.book
33
import androidx.compose.runtime.Immutable
44
import com.ninecraft.booket.core.common.R
55
import com.ninecraft.booket.core.common.constants.BookStatus
6+
import com.ninecraft.booket.core.model.BookDetailModel
67
import com.ninecraft.booket.core.model.Emotion
78
import com.ninecraft.booket.core.model.EmotionModel
89
import com.ninecraft.booket.core.model.RecordRegisterModel
@@ -13,6 +14,8 @@ import kotlinx.collections.immutable.persistentListOf
1314
import java.util.UUID
1415

1516
data class BookDetailUiState(
17+
val isLoading: Boolean = false,
18+
val bookDetail: BookDetailModel = BookDetailModel(),
1619
val isBookUpdateBottomSheetVisible: Boolean = false,
1720
val isRecordSortBottomSheetVisible: Boolean = false,
1821
val emotionList: ImmutableList<EmotionModel> = persistentListOf(
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.ninecraft.booket.feature.detail.book.component
2+
3+
import androidx.compose.foundation.layout.Column
4+
import androidx.compose.foundation.layout.Row
5+
import androidx.compose.foundation.layout.Spacer
6+
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.height
8+
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.foundation.layout.width
10+
import androidx.compose.foundation.shape.RoundedCornerShape
11+
import androidx.compose.material3.Text
12+
import androidx.compose.material3.VerticalDivider
13+
import androidx.compose.runtime.Composable
14+
import androidx.compose.ui.Alignment
15+
import androidx.compose.ui.Modifier
16+
import androidx.compose.ui.draw.clip
17+
import androidx.compose.ui.res.painterResource
18+
import androidx.compose.ui.text.style.TextOverflow
19+
import androidx.compose.ui.unit.dp
20+
import com.ninecraft.booket.core.designsystem.component.NetworkImage
21+
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
22+
import com.ninecraft.booket.core.model.BookDetailModel
23+
import com.ninecraft.booket.core.designsystem.R as designR
24+
25+
@Composable
26+
internal fun BookItem(
27+
bookDetail: BookDetailModel,
28+
modifier: Modifier = Modifier,
29+
) {
30+
Row(
31+
modifier = modifier
32+
.fillMaxWidth()
33+
.padding(horizontal = ReedTheme.spacing.spacing5),
34+
) {
35+
NetworkImage(
36+
imageUrl = bookDetail.cover,
37+
contentDescription = "Book CoverImage",
38+
modifier = Modifier
39+
.padding(end = ReedTheme.spacing.spacing4)
40+
.width(70.dp)
41+
.height(99.dp)
42+
.clip(RoundedCornerShape(size = ReedTheme.radius.xs)),
43+
placeholder = painterResource(designR.drawable.ic_placeholder),
44+
)
45+
Column(modifier = Modifier.weight(1f)) {
46+
Text(
47+
text = "여름은 오래 그곳에 남아",
48+
color = ReedTheme.colors.contentPrimary,
49+
overflow = TextOverflow.Ellipsis,
50+
maxLines = 2,
51+
style = ReedTheme.typography.headline1SemiBold,
52+
)
53+
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing2))
54+
Row(
55+
modifier = Modifier.fillMaxWidth(),
56+
verticalAlignment = Alignment.CenterVertically,
57+
) {
58+
Text(
59+
text = "미쓰이에 마사시",
60+
color = ReedTheme.colors.contentTertiary,
61+
overflow = TextOverflow.Ellipsis,
62+
maxLines = 1,
63+
style = ReedTheme.typography.label2Regular,
64+
modifier = Modifier.weight(0.7f, fill = false),
65+
)
66+
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
67+
VerticalDivider(
68+
modifier = Modifier.height(14.dp),
69+
thickness = 1.dp,
70+
color = ReedTheme.colors.contentTertiary,
71+
)
72+
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
73+
Text(
74+
text = "비채",
75+
color = ReedTheme.colors.contentTertiary,
76+
overflow = TextOverflow.Ellipsis,
77+
maxLines = 1,
78+
style = ReedTheme.typography.label2Regular,
79+
modifier = Modifier.weight(0.3f, fill = false),
80+
)
81+
}
82+
Spacer(Modifier.width(ReedTheme.spacing.spacing05))
83+
Text(
84+
text = "2024년",
85+
color = ReedTheme.colors.contentTertiary,
86+
overflow = TextOverflow.Ellipsis,
87+
maxLines = 1,
88+
style = ReedTheme.typography.label2Regular,
89+
)
90+
}
91+
}
92+
}

feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomePresenter.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class HomePresenter @AssistedInject constructor(
6161
}
6262
}
6363

64+
LaunchedEffect(true) {
65+
getHome()
66+
}
67+
6468
fun handleEvent(event: HomeUiEvent) {
6569
when (event) {
6670
is HomeUiEvent.OnSettingsClick -> {
@@ -76,15 +80,11 @@ class HomePresenter @AssistedInject constructor(
7680
}
7781

7882
is HomeUiEvent.OnBookDetailClick -> {
79-
navigator.goTo(BookDetailScreen(""))
83+
navigator.goTo(BookDetailScreen(event.userBookId))
8084
}
8185
}
8286
}
8387

84-
LaunchedEffect(true) {
85-
getHome()
86-
}
87-
8888
return HomeUiState(
8989
recentBooks = recentBooks,
9090
eventSink = ::handleEvent,

feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ internal fun HomeContent(
119119
BookCard(
120120
recentBookInfo = state.recentBooks[page],
121121
onBookDetailClick = {
122-
state.eventSink(HomeUiEvent.OnBookDetailClick)
122+
state.eventSink(HomeUiEvent.OnBookDetailClick(state.recentBooks[page].userBookId))
123123
},
124124
onRecordButtonClick = {
125125
state.eventSink(HomeUiEvent.OnRecordButtonClick(state.recentBooks[page].userBookId))

feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUiState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ sealed interface HomeUiEvent : CircuitUiEvent {
2626
data object OnSettingsClick : HomeUiEvent
2727
data object OnBookRegisterClick : HomeUiEvent
2828
data class OnRecordButtonClick(val userBookId: String) : HomeUiEvent
29-
data object OnBookDetailClick : HomeUiEvent
29+
data class OnBookDetailClick(val userBookId: String) : HomeUiEvent
3030
}

0 commit comments

Comments
 (0)