Skip to content

Commit 8d6f61a

Browse files
authored
Merge pull request #125 from YAPP-Github/BOOK-244-fix/#123
fix: 도서 상세 UI 버그 수정
2 parents e5ad34d + 78c6c7d commit 8d6f61a

File tree

8 files changed

+94
-49
lines changed

8 files changed

+94
-49
lines changed

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import com.ninecraft.booket.core.data.api.repository.BookRepository
1515
import com.ninecraft.booket.core.data.api.repository.RecordRepository
1616
import com.ninecraft.booket.core.model.BookDetailModel
1717
import com.ninecraft.booket.core.model.EmotionModel
18+
import com.ninecraft.booket.core.model.PageInfoModel
1819
import com.ninecraft.booket.core.model.ReadingRecordModel
1920
import com.ninecraft.booket.core.ui.component.FooterState
2021
import com.ninecraft.booket.feature.screens.BookDetailScreen
@@ -34,9 +35,7 @@ import kotlinx.collections.immutable.ImmutableList
3435
import kotlinx.collections.immutable.persistentListOf
3536
import kotlinx.collections.immutable.toImmutableList
3637
import kotlinx.collections.immutable.toPersistentList
37-
import kotlinx.coroutines.CancellationException
3838
import kotlinx.coroutines.async
39-
import kotlinx.coroutines.coroutineScope
4039
import kotlinx.coroutines.launch
4140
import java.time.LocalDateTime
4241

@@ -66,20 +65,22 @@ class BookDetailPresenter @AssistedInject constructor(
6665
var bookDetail by rememberRetained { mutableStateOf(BookDetailModel()) }
6766
var seedsStates by rememberRetained { mutableStateOf<ImmutableList<EmotionModel>>(persistentListOf()) }
6867
var readingRecords by rememberRetained { mutableStateOf(persistentListOf<ReadingRecordModel>()) }
68+
var readingRecordsPageInfo by rememberRetained { mutableStateOf(PageInfoModel()) }
6969
var currentStartIndex by rememberRetained { mutableIntStateOf(START_INDEX) }
7070
var isLastPage by rememberRetained { mutableStateOf(false) }
7171
var currentBookStatus by rememberRetained { mutableStateOf(BookStatus.READING) }
72+
var selectedBookStatus by rememberRetained { mutableStateOf(BookStatus.READING) }
7273
var currentRecordSort by rememberRetained { mutableStateOf(RecordSort.PAGE_NUMBER_ASC) }
7374
var isBookUpdateBottomSheetVisible by rememberRetained { mutableStateOf(false) }
7475
var isRecordSortBottomSheetVisible by rememberRetained { mutableStateOf(false) }
7576
var sideEffect by rememberRetained { mutableStateOf<BookDetailSideEffect?>(null) }
7677

7778
@Suppress("TooGenericExceptionCaught")
78-
suspend fun initialLoad() {
79+
fun initialLoad() {
7980
uiState = UiState.Loading
8081

8182
try {
82-
coroutineScope {
83+
scope.launch {
8384
val bookDetailDef = async { bookRepository.getBookDetail(screen.isbn13).getOrThrow() }
8485
val seedsDef = async { bookRepository.getSeedsStats(screen.userBookId).getOrThrow() }
8586
val readingRecordsDef = async {
@@ -95,16 +96,17 @@ class BookDetailPresenter @AssistedInject constructor(
9596
val records = readingRecordsDef.await()
9697

9798
bookDetail = detail
99+
currentBookStatus = BookStatus.fromValue(detail.userBookStatus) ?: BookStatus.BEFORE_READING
100+
selectedBookStatus = currentBookStatus
98101
seedsStates = seeds.categories.toImmutableList()
99102
readingRecords = records.content.toPersistentList()
103+
readingRecordsPageInfo = records.page
100104

101105
isLastPage = records.content.size < PAGE_SIZE
102106
currentStartIndex = START_INDEX
103107

104108
uiState = UiState.Success
105109
}
106-
} catch (ce: CancellationException) {
107-
throw ce
108110
} catch (e: Throwable) {
109111
uiState = UiState.Error(e)
110112

@@ -211,11 +213,11 @@ class BookDetailPresenter @AssistedInject constructor(
211213
}
212214

213215
is BookDetailUiEvent.OnBookStatusItemSelected -> {
214-
currentBookStatus = event.bookStatus
216+
selectedBookStatus = event.bookStatus
215217
}
216218

217219
is BookDetailUiEvent.OnBookStatusUpdateButtonClick -> {
218-
upsertBook(screen.isbn13, currentBookStatus.value)
220+
upsertBook(screen.isbn13, selectedBookStatus.value)
219221
}
220222

221223
is BookDetailUiEvent.OnRecordSortBottomSheetDismiss -> {
@@ -252,9 +254,11 @@ class BookDetailPresenter @AssistedInject constructor(
252254
bookDetail = bookDetail,
253255
seedsStats = seedsStates,
254256
readingRecords = readingRecords,
257+
readingRecordsPageInfo = readingRecordsPageInfo,
255258
isBookUpdateBottomSheetVisible = isBookUpdateBottomSheetVisible,
256259
isRecordSortBottomSheetVisible = isRecordSortBottomSheetVisible,
257260
currentBookStatus = currentBookStatus,
261+
selectedBookStatus = selectedBookStatus,
258262
currentRecordSort = currentRecordSort,
259263
sideEffect = sideEffect,
260264
eventSink = ::handleEvent,

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import com.ninecraft.booket.core.designsystem.component.button.ReedButton
3737
import com.ninecraft.booket.core.designsystem.component.button.ReedButtonColorStyle
3838
import com.ninecraft.booket.core.designsystem.component.button.largeButtonStyle
3939
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
40+
import com.ninecraft.booket.core.model.BookDetailModel
4041
import com.ninecraft.booket.core.ui.ReedScaffold
4142
import com.ninecraft.booket.core.ui.component.InfinityLazyColumn
4243
import com.ninecraft.booket.core.ui.component.LoadStateFooter
@@ -95,6 +96,7 @@ internal fun BookDetailUi(
9596
},
9697
bookStatuses = BookStatus.entries.toTypedArray().toImmutableList(),
9798
currentBookStatus = state.currentBookStatus,
99+
selectedBookStatus = state.selectedBookStatus,
98100
onItemSelected = {
99101
state.eventSink(BookDetailUiEvent.OnBookStatusItemSelected(it))
100102
},
@@ -221,7 +223,7 @@ internal fun BookDetailContent(
221223
) {
222224
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing6))
223225
ReadingRecordsHeader(
224-
readingRecords = state.readingRecords,
226+
pageInfo = state.readingRecordsPageInfo,
225227
currentRecordSort = state.currentRecordSort,
226228
onReadingRecordClick = {
227229
state.eventSink(BookDetailUiEvent.OnRecordSortButtonClick)
@@ -297,6 +299,13 @@ private fun BookDetailPreview() {
297299
BookDetailUi(
298300
state = BookDetailUiState(
299301
uiState = UiState.Success,
302+
bookDetail = BookDetailModel(
303+
title = "데미안",
304+
author = "헤르만 헤세",
305+
publisher = "민음사",
306+
pubDate = "2023-01-01",
307+
coverImageUrl = "",
308+
),
300309
eventSink = {},
301310
),
302311
)

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
@@ -5,6 +5,7 @@ import com.ninecraft.booket.core.common.R
55
import com.ninecraft.booket.core.common.constants.BookStatus
66
import com.ninecraft.booket.core.model.BookDetailModel
77
import com.ninecraft.booket.core.model.EmotionModel
8+
import com.ninecraft.booket.core.model.PageInfoModel
89
import com.ninecraft.booket.core.model.ReadingRecordModel
910
import com.ninecraft.booket.core.ui.component.FooterState
1011
import com.slack.circuit.runtime.CircuitUiEvent
@@ -27,9 +28,11 @@ data class BookDetailUiState(
2728
val bookDetail: BookDetailModel = BookDetailModel(),
2829
val seedsStats: ImmutableList<EmotionModel> = persistentListOf(),
2930
val readingRecords: ImmutableList<ReadingRecordModel> = persistentListOf(),
31+
val readingRecordsPageInfo: PageInfoModel = PageInfoModel(),
3032
val currentStartIndex: Int = 1,
3133
val isLastPage: Boolean = false,
3234
val currentBookStatus: BookStatus = BookStatus.BEFORE_READING,
35+
val selectedBookStatus: BookStatus = BookStatus.BEFORE_READING,
3336
val currentRecordSort: RecordSort = RecordSort.PAGE_NUMBER_ASC,
3437
val isBookUpdateBottomSheetVisible: Boolean = false,
3538
val isRecordSortBottomSheetVisible: Boolean = false,
Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package com.ninecraft.booket.feature.detail.book.component
22

3+
import androidx.compose.foundation.border
4+
import androidx.compose.foundation.layout.BoxWithConstraints
35
import androidx.compose.foundation.layout.Column
46
import androidx.compose.foundation.layout.Row
57
import androidx.compose.foundation.layout.Spacer
68
import androidx.compose.foundation.layout.fillMaxWidth
79
import androidx.compose.foundation.layout.height
810
import androidx.compose.foundation.layout.padding
911
import androidx.compose.foundation.layout.width
12+
import androidx.compose.foundation.layout.widthIn
1013
import androidx.compose.foundation.shape.RoundedCornerShape
1114
import androidx.compose.material3.Text
1215
import androidx.compose.material3.VerticalDivider
@@ -18,6 +21,7 @@ import androidx.compose.ui.res.painterResource
1821
import androidx.compose.ui.text.style.TextOverflow
1922
import androidx.compose.ui.unit.dp
2023
import com.ninecraft.booket.core.common.extensions.formatPublishYear
24+
import com.ninecraft.booket.core.designsystem.ComponentPreview
2125
import com.ninecraft.booket.core.designsystem.component.NetworkImage
2226
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
2327
import com.ninecraft.booket.core.model.BookDetailModel
@@ -41,7 +45,12 @@ internal fun BookItem(
4145
.padding(end = ReedTheme.spacing.spacing4)
4246
.width(70.dp)
4347
.height(99.dp)
44-
.clip(RoundedCornerShape(size = ReedTheme.radius.xs)),
48+
.clip(RoundedCornerShape(size = ReedTheme.radius.xs))
49+
.border(
50+
width = 1.dp,
51+
color = ReedTheme.colors.borderPrimary,
52+
shape = RoundedCornerShape(ReedTheme.radius.xs),
53+
),
4554
placeholder = painterResource(designR.drawable.ic_placeholder),
4655
)
4756
Column(modifier = Modifier.weight(1f)) {
@@ -53,35 +62,38 @@ internal fun BookItem(
5362
style = ReedTheme.typography.headline1SemiBold,
5463
)
5564
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing2))
56-
Row(
57-
modifier = Modifier.fillMaxWidth(),
58-
verticalAlignment = Alignment.CenterVertically,
59-
) {
60-
Text(
61-
text = bookDetail.author,
62-
color = ReedTheme.colors.contentTertiary,
63-
overflow = TextOverflow.Ellipsis,
64-
maxLines = 1,
65-
style = ReedTheme.typography.label2Regular,
66-
modifier = Modifier.weight(0.7f, fill = false),
67-
)
68-
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
69-
VerticalDivider(
70-
modifier = Modifier.height(14.dp),
71-
thickness = 1.dp,
72-
color = ReedTheme.colors.contentTertiary,
73-
)
74-
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
75-
Text(
76-
text = bookDetail.publisher,
77-
color = ReedTheme.colors.contentTertiary,
78-
overflow = TextOverflow.Ellipsis,
79-
maxLines = 1,
80-
style = ReedTheme.typography.label2Regular,
81-
modifier = Modifier.weight(0.3f, fill = false),
82-
)
65+
BoxWithConstraints {
66+
val authorMaxWidth = maxWidth * 0.7f
67+
68+
Row(
69+
modifier = Modifier.fillMaxWidth(),
70+
verticalAlignment = Alignment.CenterVertically,
71+
) {
72+
Text(
73+
text = bookDetail.author,
74+
color = ReedTheme.colors.contentTertiary,
75+
overflow = TextOverflow.Ellipsis,
76+
maxLines = 1,
77+
style = ReedTheme.typography.label2Regular,
78+
modifier = Modifier.widthIn(max = authorMaxWidth),
79+
)
80+
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
81+
VerticalDivider(
82+
modifier = Modifier.height(14.dp),
83+
thickness = 1.dp,
84+
color = ReedTheme.colors.contentTertiary,
85+
)
86+
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
87+
Text(
88+
text = bookDetail.publisher,
89+
color = ReedTheme.colors.contentTertiary,
90+
overflow = TextOverflow.Ellipsis,
91+
maxLines = 1,
92+
style = ReedTheme.typography.label2Regular,
93+
modifier = Modifier.weight(1f, fill = false),
94+
)
95+
}
8396
}
84-
Spacer(Modifier.width(ReedTheme.spacing.spacing05))
8597
Text(
8698
text = bookDetail.pubDate.formatPublishYear(),
8799
color = ReedTheme.colors.contentTertiary,
@@ -92,3 +104,19 @@ internal fun BookItem(
92104
}
93105
}
94106
}
107+
108+
@ComponentPreview
109+
@Composable
110+
private fun BookItemPreview() {
111+
ReedTheme {
112+
BookItem(
113+
bookDetail = BookDetailModel(
114+
title = "데미안",
115+
author = "헤르만 헤세",
116+
publisher = "민음사",
117+
pubDate = "2023-01-01",
118+
coverImageUrl = "",
119+
),
120+
)
121+
}
122+
}

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ internal fun BookUpdateBottomSheet(
4848
onCloseButtonClick: () -> Unit,
4949
bookStatuses: ImmutableList<BookStatus>,
5050
currentBookStatus: BookStatus?,
51+
selectedBookStatus: BookStatus,
5152
onItemSelected: (BookStatus) -> Unit,
5253
onBookUpdateButtonClick: () -> Unit,
5354
modifier: Modifier = Modifier,
@@ -94,9 +95,9 @@ internal fun BookUpdateBottomSheet(
9495
bookStatuses.forEach { item ->
9596
BookStatusItem(
9697
item = item,
97-
selected = item == currentBookStatus,
98+
selected = item == selectedBookStatus,
9899
onClick = {
99-
if (item != currentBookStatus) {
100+
if (item != selectedBookStatus) {
100101
onItemSelected(item)
101102
}
102103
},
@@ -112,7 +113,7 @@ internal fun BookUpdateBottomSheet(
112113
sizeStyle = largeButtonStyle,
113114
colorStyle = ReedButtonColorStyle.PRIMARY,
114115
modifier = Modifier.fillMaxWidth(),
115-
enabled = currentBookStatus != null,
116+
enabled = currentBookStatus != selectedBookStatus,
116117
text = stringResource(R.string.book_update_ok),
117118
)
118119
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4))
@@ -167,6 +168,7 @@ private fun BookUpdateBottomSheetPreview() {
167168
onCloseButtonClick = {},
168169
bookStatuses = BookStatus.entries.toImmutableList(),
169170
currentBookStatus = null,
171+
selectedBookStatus = BookStatus.BEFORE_READING,
170172
onItemSelected = {},
171173
onBookUpdateButtonClick = {},
172174
)

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ internal fun CollectedSeeds(
6666
.padding(horizontal = ReedTheme.spacing.spacing4)
6767
.clip(RoundedCornerShape(ReedTheme.radius.sm))
6868
.background(ReedTheme.colors.basePrimary)
69-
.padding(ReedTheme.spacing.spacing3)
7069
.border(
7170
width = 1.dp,
72-
color = ReedTheme.colors.basePrimary,
71+
color = ReedTheme.colors.borderPrimary,
7372
shape = RoundedCornerShape(ReedTheme.radius.sm),
74-
),
73+
)
74+
.padding(ReedTheme.spacing.spacing3),
7575
) {
7676
EmotionAnalysisResultText(
7777
emotions = seedsStats,

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@ import androidx.compose.ui.graphics.vector.ImageVector
1515
import androidx.compose.ui.res.stringResource
1616
import androidx.compose.ui.res.vectorResource
1717
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
18-
import com.ninecraft.booket.core.model.ReadingRecordModel
18+
import com.ninecraft.booket.core.model.PageInfoModel
1919
import com.ninecraft.booket.feature.detail.R
2020
import com.ninecraft.booket.feature.detail.book.RecordSort
21-
import kotlinx.collections.immutable.ImmutableList
2221
import com.ninecraft.booket.core.designsystem.R as designR
2322

2423
@Composable
2524
internal fun ReadingRecordsHeader(
26-
readingRecords: ImmutableList<ReadingRecordModel>,
25+
pageInfo: PageInfoModel,
2726
currentRecordSort: RecordSort,
2827
onReadingRecordClick: () -> Unit,
2928
modifier: Modifier = Modifier,
@@ -41,7 +40,7 @@ internal fun ReadingRecordsHeader(
4140
)
4241
Spacer(modifier = Modifier.width(ReedTheme.spacing.spacing1))
4342
Text(
44-
text = "${readingRecords.size}",
43+
text = "${pageInfo.totalElements}",
4544
color = ReedTheme.colors.contentBrand,
4645
style = ReedTheme.typography.headline2SemiBold,
4746
)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ internal fun RecordItem(
8181
}
8282
Spacer(modifier = Modifier.weight(1f))
8383
Text(
84-
text = "${pageNumber}P",
84+
text = "${pageNumber}p",
8585
color = ReedTheme.colors.contentBrand,
8686
style = ReedTheme.typography.body2Medium,
8787
)

0 commit comments

Comments
 (0)