Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.ninecraft.booket.core.data.api.repository.BookRepository
import com.ninecraft.booket.core.data.api.repository.RecordRepository
import com.ninecraft.booket.core.model.BookDetailModel
import com.ninecraft.booket.core.model.EmotionModel
import com.ninecraft.booket.core.model.PageInfoModel
import com.ninecraft.booket.core.model.ReadingRecordModel
import com.ninecraft.booket.core.ui.component.FooterState
import com.ninecraft.booket.feature.screens.BookDetailScreen
Expand Down Expand Up @@ -66,9 +67,11 @@ class BookDetailPresenter @AssistedInject constructor(
var bookDetail by rememberRetained { mutableStateOf(BookDetailModel()) }
var seedsStates by rememberRetained { mutableStateOf<ImmutableList<EmotionModel>>(persistentListOf()) }
var readingRecords by rememberRetained { mutableStateOf(persistentListOf<ReadingRecordModel>()) }
var readingRecordsPageInfo by rememberRetained { mutableStateOf(PageInfoModel()) }
var currentStartIndex by rememberRetained { mutableIntStateOf(START_INDEX) }
Comment on lines +68 to 69
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

readingRecordsPageInfo 상태 도입: OK. 이후 페이지 로드/정렬 변경 시 최신화 필요

초기 로드에서만 설정되어 있어 추가 페이지 로드(loadMore)나 정렬 변경 시 totalElements 등 표시가 갱신되지 않을 수 있습니다. 아래 별도 코멘트에서 loadMore 분기 내 갱신을 제안합니다.


🏁 Script executed:

#!/bin/bash
echo "=== Context around readingRecordsPageInfo declaration ==="
sed -n '1,100p' feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailPresenter.kt

echo -e "\n=== loadMore occurrences ==="
rg -n "loadMore" feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailPresenter.kt

echo -e "\n=== readingRecordsPageInfo usages ==="
rg -n -C3 "readingRecordsPageInfo" feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailPresenter.kt

Length of output: 7418


🏁 Script executed:

#!/bin/bash
# Show loadMoreReadingRecords implementation for verification
sed -n '140,260p' feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailPresenter.kt

Length of output: 4648


loadMoreReadingRecords 함수에 페이지 정보 갱신 로직 추가 필요

loadMoreReadingRecords 호출 시 onSuccess 블록에서 readingRecordsPageInfo 를 업데이트하지 않아, totalElements 등 페이지 정보가 초기값에 고정됩니다. 아래 위치에 result.page 를 반영하는 코드를 추가해 주세요.

  • 파일: feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailPresenter.kt
  • 함수: loadMoreReadingRecords
  • onSuccess 블록 내

제안하는 수정 예시:

 recordRepository.getReadingRecords(
     userBookId = screen.userBookId,
     sort = currentRecordSort.value,
     page = startIndex,
     size = PAGE_SIZE,
 ).onSuccess { result ->
-    readingRecords = (readingRecords + result.content).toPersistentList()
+    readingRecords = (readingRecords + result.content).toPersistentList()
+    readingRecordsPageInfo = result.page
     currentStartIndex = startIndex
     isLastPage = result.content.size < PAGE_SIZE
     footerState = if (isLastPage) FooterState.End else FooterState.Idle
 }
🤖 Prompt for AI Agents
In
feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailPresenter.kt
around lines 70-71, the loadMoreReadingRecords function's onSuccess block does
not update the readingRecordsPageInfo with the latest page data, causing page
info like totalElements to remain at initial values. To fix this, add code
inside the onSuccess block of loadMoreReadingRecords to assign result.page to
readingRecordsPageInfo, ensuring the page information is refreshed correctly
after each successful load.

var isLastPage by rememberRetained { mutableStateOf(false) }
var currentBookStatus by rememberRetained { mutableStateOf(BookStatus.READING) }
var selectedBookStatus by rememberRetained { mutableStateOf(BookStatus.READING) }
var currentRecordSort by rememberRetained { mutableStateOf(RecordSort.PAGE_NUMBER_ASC) }
var isBookUpdateBottomSheetVisible by rememberRetained { mutableStateOf(false) }
var isRecordSortBottomSheetVisible by rememberRetained { mutableStateOf(false) }
Expand All @@ -95,8 +98,11 @@ class BookDetailPresenter @AssistedInject constructor(
val records = readingRecordsDef.await()

bookDetail = detail
currentBookStatus = BookStatus.fromValue(detail.userBookStatus) ?: BookStatus.BEFORE_READING
selectedBookStatus = currentBookStatus
seedsStates = seeds.categories.toImmutableList()
readingRecords = records.content.toPersistentList()
readingRecordsPageInfo = records.page

isLastPage = records.content.size < PAGE_SIZE
currentStartIndex = START_INDEX
Expand Down Expand Up @@ -211,11 +217,11 @@ class BookDetailPresenter @AssistedInject constructor(
}

is BookDetailUiEvent.OnBookStatusItemSelected -> {
currentBookStatus = event.bookStatus
selectedBookStatus = event.bookStatus
}

is BookDetailUiEvent.OnBookStatusUpdateButtonClick -> {
upsertBook(screen.isbn13, currentBookStatus.value)
upsertBook(screen.isbn13, selectedBookStatus.value)
}

is BookDetailUiEvent.OnRecordSortBottomSheetDismiss -> {
Expand Down Expand Up @@ -252,9 +258,11 @@ class BookDetailPresenter @AssistedInject constructor(
bookDetail = bookDetail,
seedsStats = seedsStates,
readingRecords = readingRecords,
readingRecordsPageInfo = readingRecordsPageInfo,
isBookUpdateBottomSheetVisible = isBookUpdateBottomSheetVisible,
isRecordSortBottomSheetVisible = isRecordSortBottomSheetVisible,
currentBookStatus = currentBookStatus,
selectedBookStatus = selectedBookStatus,
currentRecordSort = currentRecordSort,
sideEffect = sideEffect,
eventSink = ::handleEvent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import com.ninecraft.booket.core.designsystem.component.button.ReedButton
import com.ninecraft.booket.core.designsystem.component.button.ReedButtonColorStyle
import com.ninecraft.booket.core.designsystem.component.button.largeButtonStyle
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
import com.ninecraft.booket.core.model.BookDetailModel
import com.ninecraft.booket.core.ui.ReedScaffold
import com.ninecraft.booket.core.ui.component.InfinityLazyColumn
import com.ninecraft.booket.core.ui.component.LoadStateFooter
Expand Down Expand Up @@ -95,6 +96,7 @@ internal fun BookDetailUi(
},
bookStatuses = BookStatus.entries.toTypedArray().toImmutableList(),
currentBookStatus = state.currentBookStatus,
selectedBookStatus = state.selectedBookStatus,
onItemSelected = {
state.eventSink(BookDetailUiEvent.OnBookStatusItemSelected(it))
},
Expand Down Expand Up @@ -221,7 +223,7 @@ internal fun BookDetailContent(
) {
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing6))
ReadingRecordsHeader(
readingRecords = state.readingRecords,
pageInfo = state.readingRecordsPageInfo,
currentRecordSort = state.currentRecordSort,
onReadingRecordClick = {
state.eventSink(BookDetailUiEvent.OnRecordSortButtonClick)
Expand Down Expand Up @@ -297,6 +299,13 @@ private fun BookDetailPreview() {
BookDetailUi(
state = BookDetailUiState(
uiState = UiState.Success,
bookDetail = BookDetailModel(
title = "데미안",
author = "헤르만 헤세",
publisher = "민음사",
pubDate = "2023-01-01",
coverImageUrl = "",
),
eventSink = {},
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.ninecraft.booket.core.common.R
import com.ninecraft.booket.core.common.constants.BookStatus
import com.ninecraft.booket.core.model.BookDetailModel
import com.ninecraft.booket.core.model.EmotionModel
import com.ninecraft.booket.core.model.PageInfoModel
import com.ninecraft.booket.core.model.ReadingRecordModel
import com.ninecraft.booket.core.ui.component.FooterState
import com.slack.circuit.runtime.CircuitUiEvent
Expand All @@ -27,9 +28,11 @@ data class BookDetailUiState(
val bookDetail: BookDetailModel = BookDetailModel(),
val seedsStats: ImmutableList<EmotionModel> = persistentListOf(),
val readingRecords: ImmutableList<ReadingRecordModel> = persistentListOf(),
val readingRecordsPageInfo: PageInfoModel = PageInfoModel(),
val currentStartIndex: Int = 1,
val isLastPage: Boolean = false,
val currentBookStatus: BookStatus = BookStatus.BEFORE_READING,
val selectedBookStatus: BookStatus = BookStatus.BEFORE_READING,
val currentRecordSort: RecordSort = RecordSort.PAGE_NUMBER_ASC,
val isBookUpdateBottomSheetVisible: Boolean = false,
val isRecordSortBottomSheetVisible: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.ninecraft.booket.feature.detail.book.component

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.material3.VerticalDivider
Expand All @@ -18,6 +21,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.ninecraft.booket.core.common.extensions.formatPublishYear
import com.ninecraft.booket.core.designsystem.ComponentPreview
import com.ninecraft.booket.core.designsystem.component.NetworkImage
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
import com.ninecraft.booket.core.model.BookDetailModel
Expand All @@ -41,7 +45,12 @@ internal fun BookItem(
.padding(end = ReedTheme.spacing.spacing4)
.width(70.dp)
.height(99.dp)
.clip(RoundedCornerShape(size = ReedTheme.radius.xs)),
.clip(RoundedCornerShape(size = ReedTheme.radius.xs))
.border(
width = 1.dp,
color = ReedTheme.colors.borderPrimary,
shape = RoundedCornerShape(ReedTheme.radius.xs),
),
placeholder = painterResource(designR.drawable.ic_placeholder),
)
Column(modifier = Modifier.weight(1f)) {
Expand All @@ -53,35 +62,38 @@ internal fun BookItem(
style = ReedTheme.typography.headline1SemiBold,
)
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing2))
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = bookDetail.author,
color = ReedTheme.colors.contentTertiary,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = ReedTheme.typography.label2Regular,
modifier = Modifier.weight(0.7f, fill = false),
)
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
VerticalDivider(
modifier = Modifier.height(14.dp),
thickness = 1.dp,
color = ReedTheme.colors.contentTertiary,
)
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
Text(
text = bookDetail.publisher,
color = ReedTheme.colors.contentTertiary,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = ReedTheme.typography.label2Regular,
modifier = Modifier.weight(0.3f, fill = false),
)
BoxWithConstraints {
val authorMaxWidth = maxWidth * 0.7f

Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = bookDetail.author,
color = ReedTheme.colors.contentTertiary,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = ReedTheme.typography.label2Regular,
modifier = Modifier.widthIn(max = authorMaxWidth),
)
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
VerticalDivider(
modifier = Modifier.height(14.dp),
thickness = 1.dp,
color = ReedTheme.colors.contentTertiary,
)
Spacer(Modifier.width(ReedTheme.spacing.spacing1))
Text(
text = bookDetail.publisher,
color = ReedTheme.colors.contentTertiary,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = ReedTheme.typography.label2Regular,
modifier = Modifier.weight(1f, fill = false),
)
}
}
Spacer(Modifier.width(ReedTheme.spacing.spacing05))
Text(
text = bookDetail.pubDate.formatPublishYear(),
color = ReedTheme.colors.contentTertiary,
Expand All @@ -92,3 +104,19 @@ internal fun BookItem(
}
}
}

@ComponentPreview
@Composable
private fun BookItemPreview() {
ReedTheme {
BookItem(
bookDetail = BookDetailModel(
title = "데미안",
author = "헤르만 헤세",
publisher = "민음사",
pubDate = "2023-01-01",
coverImageUrl = "",
),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ internal fun BookUpdateBottomSheet(
onCloseButtonClick: () -> Unit,
bookStatuses: ImmutableList<BookStatus>,
currentBookStatus: BookStatus?,
selectedBookStatus: BookStatus,
onItemSelected: (BookStatus) -> Unit,
onBookUpdateButtonClick: () -> Unit,
modifier: Modifier = Modifier,
Expand Down Expand Up @@ -94,9 +95,9 @@ internal fun BookUpdateBottomSheet(
bookStatuses.forEach { item ->
BookStatusItem(
item = item,
selected = item == currentBookStatus,
selected = item == selectedBookStatus,
onClick = {
if (item != currentBookStatus) {
if (item != selectedBookStatus) {
onItemSelected(item)
}
},
Expand All @@ -112,7 +113,7 @@ internal fun BookUpdateBottomSheet(
sizeStyle = largeButtonStyle,
colorStyle = ReedButtonColorStyle.PRIMARY,
modifier = Modifier.fillMaxWidth(),
enabled = currentBookStatus != null,
enabled = currentBookStatus != selectedBookStatus,
text = stringResource(R.string.book_update_ok),
)
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4))
Expand Down Expand Up @@ -167,6 +168,7 @@ private fun BookUpdateBottomSheetPreview() {
onCloseButtonClick = {},
bookStatuses = BookStatus.entries.toImmutableList(),
currentBookStatus = null,
selectedBookStatus = BookStatus.BEFORE_READING,
onItemSelected = {},
onBookUpdateButtonClick = {},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ internal fun CollectedSeeds(
.padding(horizontal = ReedTheme.spacing.spacing4)
.clip(RoundedCornerShape(ReedTheme.radius.sm))
.background(ReedTheme.colors.basePrimary)
.padding(ReedTheme.spacing.spacing3)
.border(
width = 1.dp,
color = ReedTheme.colors.basePrimary,
color = ReedTheme.colors.borderPrimary,
shape = RoundedCornerShape(ReedTheme.radius.sm),
),
)
.padding(ReedTheme.spacing.spacing3),
) {
EmotionAnalysisResultText(
emotions = seedsStats,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
import com.ninecraft.booket.core.model.ReadingRecordModel
import com.ninecraft.booket.core.model.PageInfoModel
import com.ninecraft.booket.feature.detail.R
import com.ninecraft.booket.feature.detail.book.RecordSort
import kotlinx.collections.immutable.ImmutableList
import com.ninecraft.booket.core.designsystem.R as designR

@Composable
internal fun ReadingRecordsHeader(
readingRecords: ImmutableList<ReadingRecordModel>,
pageInfo: PageInfoModel,
currentRecordSort: RecordSort,
onReadingRecordClick: () -> Unit,
modifier: Modifier = Modifier,
Expand All @@ -41,7 +40,7 @@ internal fun ReadingRecordsHeader(
)
Spacer(modifier = Modifier.width(ReedTheme.spacing.spacing1))
Text(
text = "${readingRecords.size}",
text = "${pageInfo.totalElements}",
color = ReedTheme.colors.contentBrand,
style = ReedTheme.typography.headline2SemiBold,
)
Expand Down
Loading