Skip to content

Commit 0d8086c

Browse files
Show the Book Progress in the overview (#3170)
1 parent b296b0c commit 0d8086c

File tree

2 files changed

+150
-65
lines changed

2 files changed

+150
-65
lines changed

features/bookOverview/src/main/kotlin/voice/features/bookOverview/views/GridBooks.kt

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,39 @@
11
package voice.features.bookOverview.views
22

3+
import androidx.compose.foundation.background
34
import androidx.compose.foundation.combinedClickable
45
import androidx.compose.foundation.layout.Arrangement
6+
import androidx.compose.foundation.layout.Box
57
import androidx.compose.foundation.layout.Column
68
import androidx.compose.foundation.layout.PaddingValues
9+
import androidx.compose.foundation.layout.Row
710
import androidx.compose.foundation.layout.Spacer
811
import androidx.compose.foundation.layout.WindowInsets
912
import androidx.compose.foundation.layout.aspectRatio
13+
import androidx.compose.foundation.layout.fillMaxSize
1014
import androidx.compose.foundation.layout.fillMaxWidth
15+
import androidx.compose.foundation.layout.height
1116
import androidx.compose.foundation.layout.padding
1217
import androidx.compose.foundation.layout.systemBars
1318
import androidx.compose.foundation.layout.windowInsetsBottomHeight
1419
import androidx.compose.foundation.lazy.grid.GridCells
1520
import androidx.compose.foundation.lazy.grid.GridItemSpan
1621
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
1722
import androidx.compose.foundation.lazy.grid.items
18-
import androidx.compose.foundation.shape.RoundedCornerShape
19-
import androidx.compose.material3.Card
23+
import androidx.compose.material3.ElevatedCard
2024
import androidx.compose.material3.LinearProgressIndicator
2125
import androidx.compose.material3.MaterialTheme
2226
import androidx.compose.material3.Text
2327
import androidx.compose.runtime.Composable
28+
import androidx.compose.ui.Alignment
2429
import androidx.compose.ui.Modifier
2530
import androidx.compose.ui.draw.clip
2631
import androidx.compose.ui.layout.ContentScale
2732
import androidx.compose.ui.platform.LocalDensity
2833
import androidx.compose.ui.platform.LocalResources
2934
import androidx.compose.ui.res.painterResource
35+
import androidx.compose.ui.text.style.TextOverflow
36+
import androidx.compose.ui.tooling.preview.Preview
3037
import androidx.compose.ui.unit.dp
3138
import coil.compose.AsyncImage
3239
import kotlinx.collections.immutable.ImmutableMap
@@ -96,45 +103,68 @@ internal fun GridBook(
96103
onBookClick: (BookId) -> Unit,
97104
onBookLongClick: (BookId) -> Unit,
98105
) {
99-
Card(
106+
ElevatedCard(
107+
shape = MaterialTheme.shapes.extraLarge,
100108
modifier = Modifier
101109
.fillMaxWidth()
102110
.combinedClickable(
103-
onClick = {
104-
onBookClick(book.id)
105-
},
106-
onLongClick = {
107-
onBookLongClick(book.id)
108-
},
111+
onClick = { onBookClick(book.id) },
112+
onLongClick = { onBookLongClick(book.id) },
109113
),
110114
) {
111-
Column {
112-
AsyncImage(
115+
Column(
116+
modifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 12.dp),
117+
) {
118+
Box(
113119
modifier = Modifier
114-
.aspectRatio(4F / 3F)
115-
.padding(start = 8.dp, end = 8.dp, top = 8.dp)
116-
.clip(RoundedCornerShape(8.dp)),
117-
contentScale = ContentScale.Crop,
118-
model = book.cover?.file,
119-
placeholder = painterResource(id = UiR.drawable.album_art),
120-
error = painterResource(id = UiR.drawable.album_art),
121-
contentDescription = null,
122-
)
120+
.fillMaxWidth()
121+
.aspectRatio(4f / 3f)
122+
.clip(MaterialTheme.shapes.large)
123+
.background(MaterialTheme.colorScheme.surfaceVariant),
124+
contentAlignment = Alignment.Center,
125+
) {
126+
AsyncImage(
127+
modifier = Modifier.fillMaxSize(),
128+
contentScale = ContentScale.Crop,
129+
model = book.cover?.file,
130+
placeholder = painterResource(id = UiR.drawable.album_art),
131+
error = painterResource(id = UiR.drawable.album_art),
132+
contentDescription = null,
133+
)
134+
}
135+
136+
Spacer(Modifier.height(4.dp))
137+
123138
Text(
124-
modifier = Modifier.padding(start = 8.dp, end = 8.dp, top = 8.dp),
125139
text = book.name,
140+
style = MaterialTheme.typography.titleMedium,
141+
color = MaterialTheme.colorScheme.onSurface,
126142
maxLines = 3,
127-
style = MaterialTheme.typography.bodyMedium,
128-
)
129-
Text(
130-
modifier = Modifier.padding(start = 8.dp, end = 8.dp, bottom = 8.dp),
131-
text = book.remainingTime,
132-
style = MaterialTheme.typography.bodySmall,
143+
overflow = TextOverflow.Ellipsis,
133144
)
134145

135-
if (book.progress > 0F) {
146+
Row(
147+
modifier = Modifier.fillMaxWidth(),
148+
horizontalArrangement = Arrangement.SpaceBetween,
149+
verticalAlignment = Alignment.CenterVertically,
150+
) {
151+
Text(
152+
text = book.remainingTime,
153+
style = MaterialTheme.typography.labelMedium,
154+
color = MaterialTheme.colorScheme.onSurfaceVariant,
155+
)
156+
if (book.progress > 0f) {
157+
Text(
158+
text = "${(book.progress * 100).toInt()}%",
159+
style = MaterialTheme.typography.labelMedium,
160+
color = MaterialTheme.colorScheme.onSurfaceVariant,
161+
)
162+
}
163+
}
164+
165+
Spacer(Modifier.height(8.dp))
166+
if (book.progress > 0.05f) {
136167
LinearProgressIndicator(
137-
modifier = Modifier.fillMaxWidth(),
138168
progress = { book.progress },
139169
)
140170
}
@@ -152,3 +182,15 @@ internal fun gridColumnCount(): Int {
152182
val columns = (widthPx / desiredPx).roundToInt()
153183
return columns.coerceAtLeast(2)
154184
}
185+
186+
@Composable
187+
@Preview(widthDp = 200)
188+
private fun GridBookPreviewWithProgress() {
189+
GridBook(BookOverviewPreviewParameterProvider().book().copy(progress = 0.66f), {}, {})
190+
}
191+
192+
@Composable
193+
@Preview(widthDp = 200)
194+
private fun GridBookPreviewWithoutProgress() {
195+
GridBook(BookOverviewPreviewParameterProvider().book().copy(progress = 0f), {}, {})
196+
}

features/bookOverview/src/main/kotlin/voice/features/bookOverview/views/ListBooks.kt

Lines changed: 79 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,27 @@ import androidx.compose.foundation.layout.Row
99
import androidx.compose.foundation.layout.Spacer
1010
import androidx.compose.foundation.layout.WindowInsets
1111
import androidx.compose.foundation.layout.fillMaxWidth
12+
import androidx.compose.foundation.layout.height
1213
import androidx.compose.foundation.layout.padding
1314
import androidx.compose.foundation.layout.size
1415
import androidx.compose.foundation.layout.systemBars
1516
import androidx.compose.foundation.layout.windowInsetsBottomHeight
1617
import androidx.compose.foundation.lazy.LazyColumn
1718
import androidx.compose.foundation.lazy.items
1819
import androidx.compose.foundation.shape.RoundedCornerShape
19-
import androidx.compose.material3.Card
20+
import androidx.compose.material3.ElevatedCard
2021
import androidx.compose.material3.LinearProgressIndicator
2122
import androidx.compose.material3.MaterialTheme
2223
import androidx.compose.material3.Text
2324
import androidx.compose.runtime.Composable
2425
import androidx.compose.ui.Alignment
2526
import androidx.compose.ui.Modifier
2627
import androidx.compose.ui.draw.clip
28+
import androidx.compose.ui.layout.ContentScale
2729
import androidx.compose.ui.res.painterResource
2830
import androidx.compose.ui.text.intl.LocaleList
2931
import androidx.compose.ui.text.toUpperCase
32+
import androidx.compose.ui.tooling.preview.Preview
3033
import androidx.compose.ui.unit.dp
3134
import coil.compose.AsyncImage
3235
import kotlinx.collections.immutable.ImmutableMap
@@ -92,65 +95,105 @@ internal fun ListBookRow(
9295
onBookLongClick: (BookId) -> Unit,
9396
modifier: Modifier = Modifier,
9497
) {
95-
Card(
98+
ElevatedCard(
99+
shape = MaterialTheme.shapes.extraLarge,
96100
modifier = modifier
97101
.fillMaxWidth()
98102
.combinedClickable(
99-
onClick = {
100-
onBookClick(book.id)
101-
},
102-
onLongClick = {
103-
onBookLongClick(book.id)
104-
},
103+
onClick = { onBookClick(book.id) },
104+
onLongClick = { onBookLongClick(book.id) },
105105
),
106-
content = {
107-
Column {
108-
Row {
109-
CoverImage(book.cover)
110-
Column(
111-
Modifier
112-
.padding(start = 8.dp, end = 8.dp, top = 8.dp, bottom = 8.dp)
113-
.align(Alignment.CenterVertically),
114-
) {
115-
if (book.author != null) {
116-
Text(
117-
text = book.author.toUpperCase(LocaleList.current),
118-
style = MaterialTheme.typography.labelSmall,
119-
maxLines = 1,
120-
)
121-
}
106+
) {
107+
Column(Modifier.padding()) {
108+
Row(verticalAlignment = Alignment.CenterVertically) {
109+
CoverImage(book.cover)
110+
111+
Column(
112+
Modifier
113+
.padding(start = 12.dp)
114+
.weight(1f),
115+
) {
116+
if (book.author != null) {
122117
Text(
123-
text = book.name,
124-
style = MaterialTheme.typography.bodyMedium,
118+
text = book.author.toUpperCase(LocaleList.current),
119+
style = MaterialTheme.typography.labelSmall,
120+
color = MaterialTheme.colorScheme.onSurfaceVariant,
121+
maxLines = 1,
125122
)
123+
}
124+
125+
Text(
126+
text = book.name,
127+
style = MaterialTheme.typography.titleSmall,
128+
color = MaterialTheme.colorScheme.onSurface,
129+
maxLines = 2,
130+
)
131+
132+
Row(
133+
modifier = Modifier.fillMaxWidth().padding(end = 12.dp),
134+
verticalAlignment = Alignment.CenterVertically,
135+
horizontalArrangement = Arrangement.SpaceBetween,
136+
) {
126137
Text(
127138
text = book.remainingTime,
128-
style = MaterialTheme.typography.bodySmall,
139+
style = MaterialTheme.typography.labelMedium,
140+
color = MaterialTheme.colorScheme.onSurfaceVariant,
141+
maxLines = 1,
129142
)
143+
144+
if (book.progress > 0f) {
145+
Text(
146+
text = "${(book.progress * 100).toInt()}%",
147+
style = MaterialTheme.typography.labelMedium,
148+
color = MaterialTheme.colorScheme.onSurfaceVariant,
149+
maxLines = 1,
150+
)
151+
}
130152
}
131153
}
154+
}
132155

133-
if (book.progress > 0.05) {
134-
LinearProgressIndicator(
135-
modifier = Modifier.fillMaxWidth(),
136-
progress = { book.progress },
137-
)
138-
}
156+
if (book.progress > 0.05f) {
157+
Spacer(Modifier.size(0.dp))
158+
LinearProgressIndicator(
159+
progress = { book.progress },
160+
modifier = Modifier
161+
.fillMaxWidth()
162+
.clip(MaterialTheme.shapes.small)
163+
.height(4.dp),
164+
color = MaterialTheme.colorScheme.primary,
165+
trackColor = MaterialTheme.colorScheme.surfaceVariant,
166+
)
139167
}
140-
},
141-
)
168+
}
169+
}
142170
}
143171

144172
@Composable
145173
private fun CoverImage(cover: ImmutableFile?) {
174+
val startPadding = 16.dp
175+
val endPadding = 16.dp
146176
AsyncImage(
147177
modifier = Modifier
148178
.padding(top = 8.dp, start = 8.dp, bottom = 8.dp)
149179
.size(76.dp)
150-
.clip(RoundedCornerShape(8.dp)),
180+
.clip(RoundedCornerShape(topStart = startPadding, bottomStart = startPadding, topEnd = endPadding, bottomEnd = endPadding)),
151181
model = cover?.file,
152182
placeholder = painterResource(id = UiR.drawable.album_art),
153183
error = painterResource(id = UiR.drawable.album_art),
184+
contentScale = ContentScale.Crop,
154185
contentDescription = null,
155186
)
156187
}
188+
189+
@Composable
190+
@Preview
191+
private fun ListBookRowPreviewWithProgress() {
192+
ListBookRow(BookOverviewPreviewParameterProvider().book().copy(progress = 0.6f), {}, {})
193+
}
194+
195+
@Composable
196+
@Preview
197+
private fun ListBookRowPreviewWithoutProgress() {
198+
ListBookRow(BookOverviewPreviewParameterProvider().book().copy(progress = 0f), {}, {})
199+
}

0 commit comments

Comments
 (0)