Fix lazy detail loading.
This commit is contained in:
parent
98f0e94766
commit
4f3fabc4d6
10 changed files with 106 additions and 107 deletions
|
|
@ -83,13 +83,13 @@ dependencies {
|
||||||
// Android core
|
// Android core
|
||||||
implementation 'androidx.core:core-ktx:1.7.0'
|
implementation 'androidx.core:core-ktx:1.7.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||||
implementation 'com.google.android.material:material:1.5.0'
|
implementation 'com.google.android.material:material:1.6.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
|
||||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.1"
|
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.1"
|
||||||
implementation 'androidx.activity:activity-compose:1.4.0'
|
implementation 'androidx.activity:activity-compose:1.4.0'
|
||||||
|
|
||||||
// Android Compose
|
// Android Compose
|
||||||
implementation "androidx.compose.ui:ui:1.2.0-alpha08"
|
implementation "androidx.compose.ui:ui:1.2.0-beta01"
|
||||||
implementation "androidx.compose.material:material:1.1.1"
|
implementation "androidx.compose.material:material:1.1.1"
|
||||||
implementation "androidx.compose.runtime:runtime-livedata:1.1.1"
|
implementation "androidx.compose.runtime:runtime-livedata:1.1.1"
|
||||||
implementation "androidx.compose.ui:ui-tooling-preview:1.1.1"
|
implementation "androidx.compose.ui:ui-tooling-preview:1.1.1"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.pixelized.biblib.ui.composable
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Cover(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
cover: CoverUio,
|
||||||
|
contentDescription: String? = null,
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
modifier = modifier,
|
||||||
|
painter = cover.painter,
|
||||||
|
contentScale = cover.contentScale,
|
||||||
|
colorFilter = cover.colorFilter,
|
||||||
|
contentDescription = contentDescription,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -46,7 +46,11 @@ fun ScreenNavHost(
|
||||||
fun NavHostController.navigateToHome() {
|
fun NavHostController.navigateToHome() {
|
||||||
navigate(Screen.Home.route) {
|
navigate(Screen.Home.route) {
|
||||||
launchSingleTop = true
|
launchSingleTop = true
|
||||||
popUpTo(0) { inclusive = true }
|
restoreState = true
|
||||||
|
popUpTo(0) {
|
||||||
|
saveState = true
|
||||||
|
inclusive = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,21 @@
|
||||||
package com.pixelized.biblib.ui.scaffold
|
package com.pixelized.biblib.ui.scaffold
|
||||||
|
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
import android.content.Context
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.BottomSheetScaffold
|
||||||
|
import androidx.compose.material.BottomSheetScaffoldState
|
||||||
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
|
import androidx.compose.material.rememberBottomSheetScaffoldState
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
import com.pixelized.biblib.R
|
||||||
|
import com.pixelized.biblib.ui.composable.StateUio
|
||||||
import com.pixelized.biblib.ui.screen.detail.BookDetailViewModel
|
import com.pixelized.biblib.ui.screen.detail.BookDetailViewModel
|
||||||
import com.pixelized.biblib.ui.screen.detail.DetailScreen
|
import com.pixelized.biblib.ui.screen.detail.DetailScreen
|
||||||
|
import com.pixelized.biblib.ui.screen.home.common.uio.BookUio
|
||||||
|
import com.pixelized.biblib.utils.extention.showToast
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
@ -15,7 +23,7 @@ val LocalBottomDetailController = staticCompositionLocalOf<BottomDetailStateCont
|
||||||
error("LocalBottomDetailController is not ready yet")
|
error("LocalBottomDetailController is not ready yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class, ExperimentalAnimationApi::class)
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomDetailScaffold(
|
fun BottomDetailScaffold(
|
||||||
bottomStateController: BottomDetailStateController = rememberBottomDetailStateController(),
|
bottomStateController: BottomDetailStateController = rememberBottomDetailStateController(),
|
||||||
|
|
@ -29,16 +37,8 @@ fun BottomDetailScaffold(
|
||||||
sheetPeekHeight = 0.dp,
|
sheetPeekHeight = 0.dp,
|
||||||
sheetGesturesEnabled = false,
|
sheetGesturesEnabled = false,
|
||||||
sheetContent = {
|
sheetContent = {
|
||||||
var detail by remember { bottomStateController.detail }
|
val detail by remember { bottomStateController.bookDetail }
|
||||||
val state = bottomStateController.scaffoldState.bottomSheetState
|
DetailScreen(detail = detail)
|
||||||
if (state.currentValue == BottomSheetValue.Collapsed) {
|
|
||||||
detail = null
|
|
||||||
}
|
|
||||||
detail?.let {
|
|
||||||
val viewModel: BookDetailViewModel = hiltViewModel()
|
|
||||||
viewModel.getDetail(id = it)
|
|
||||||
DetailScreen(viewModel)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
|
|
@ -48,35 +48,49 @@ fun BottomDetailScaffold(
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun rememberBottomDetailStateController(
|
fun rememberBottomDetailStateController(
|
||||||
|
viewModel: BookDetailViewModel = hiltViewModel(),
|
||||||
scope: CoroutineScope = rememberCoroutineScope(),
|
scope: CoroutineScope = rememberCoroutineScope(),
|
||||||
scaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(),
|
scaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(),
|
||||||
): BottomDetailStateController {
|
): BottomDetailStateController {
|
||||||
|
val context: Context = LocalContext.current
|
||||||
val controller = BottomDetailStateController(
|
val controller = BottomDetailStateController(
|
||||||
|
context = context,
|
||||||
|
viewModel = viewModel,
|
||||||
scope = scope,
|
scope = scope,
|
||||||
scaffoldState = scaffoldState
|
scaffoldState = scaffoldState
|
||||||
)
|
)
|
||||||
return remember(scope, scaffoldState) { controller }
|
return remember(scope, viewModel, scaffoldState) { controller }
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Stable
|
@Stable
|
||||||
class BottomDetailStateController constructor(
|
class BottomDetailStateController constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val viewModel: BookDetailViewModel,
|
||||||
private val scope: CoroutineScope,
|
private val scope: CoroutineScope,
|
||||||
val scaffoldState: BottomSheetScaffoldState,
|
val scaffoldState: BottomSheetScaffoldState,
|
||||||
) {
|
) {
|
||||||
val detail = mutableStateOf<Int?>(null)
|
var bookDetail = mutableStateOf<BookUio?>(null)
|
||||||
|
private set
|
||||||
|
|
||||||
fun expandBookDetail(bookId: Int) {
|
fun expandBookDetail(id: Int) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
detail.value = bookId
|
when (val book = viewModel.getDetail(id)) {
|
||||||
|
is StateUio.Failure -> {
|
||||||
|
context.showToast(message = context.getString(R.string.error_generic))
|
||||||
|
}
|
||||||
|
is StateUio.Success -> {
|
||||||
|
bookDetail.value = book.value
|
||||||
scaffoldState.bottomSheetState.expand()
|
scaffoldState.bottomSheetState.expand()
|
||||||
}
|
}
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun collapse() {
|
fun collapse() {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
scaffoldState.bottomSheetState.collapse()
|
scaffoldState.bottomSheetState.collapse()
|
||||||
detail.value = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,19 +2,13 @@ package com.pixelized.biblib.ui.screen.detail
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.runtime.State
|
|
||||||
import androidx.compose.runtime.derivedStateOf
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.lifecycle.SavedStateHandle
|
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import com.pixelized.biblib.R
|
import com.pixelized.biblib.R
|
||||||
import com.pixelized.biblib.model.book.Book
|
import com.pixelized.biblib.model.book.Book
|
||||||
import com.pixelized.biblib.network.client.IBibLibClient
|
import com.pixelized.biblib.network.client.IBibLibClient
|
||||||
import com.pixelized.biblib.network.factory.BookFactory
|
import com.pixelized.biblib.network.factory.BookFactory
|
||||||
import com.pixelized.biblib.ui.composable.StateUio
|
import com.pixelized.biblib.ui.composable.StateUio
|
||||||
import com.pixelized.biblib.ui.navigation.screen.Screen
|
|
||||||
import com.pixelized.biblib.ui.screen.home.common.uio.BookUio
|
import com.pixelized.biblib.ui.screen.home.common.uio.BookUio
|
||||||
import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio
|
import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio
|
||||||
import com.pixelized.biblib.ui.screen.home.common.viewModel.ACoverViewModel
|
import com.pixelized.biblib.ui.screen.home.common.viewModel.ACoverViewModel
|
||||||
|
|
@ -25,7 +19,7 @@ import com.pixelized.biblib.utils.extention.shortDate
|
||||||
import com.pixelized.biblib.utils.painterResource
|
import com.pixelized.biblib.utils.painterResource
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.withContext
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
@ -33,25 +27,17 @@ import javax.inject.Inject
|
||||||
class BookDetailViewModel @Inject constructor(
|
class BookDetailViewModel @Inject constructor(
|
||||||
application: Application,
|
application: Application,
|
||||||
bookCoverCache: BookCoverCache,
|
bookCoverCache: BookCoverCache,
|
||||||
savedStateHandle: SavedStateHandle,
|
|
||||||
private val client: IBibLibClient,
|
private val client: IBibLibClient,
|
||||||
) : ACoverViewModel(application, bookCoverCache) {
|
) : ACoverViewModel(application, bookCoverCache) {
|
||||||
|
|
||||||
private val _state = mutableStateOf<StateUio<BookUio>>(StateUio.Progress())
|
suspend fun getDetail(id: Int): StateUio<BookUio> {
|
||||||
val state: State<StateUio<BookUio>> get() = _state
|
return withContext(Dispatchers.IO) {
|
||||||
|
|
||||||
val book: State<BookUio?> = derivedStateOf {
|
|
||||||
state.value.let { if (it is StateUio.Success<BookUio>) it.value else null }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getDetail(id: Int) {
|
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
|
||||||
try {
|
try {
|
||||||
val book = getBookDetail(id = id)
|
val book = getBookDetail(id = id)
|
||||||
_state.value = StateUio.Success(book)
|
StateUio.Success(book)
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
Log.e("BookDetailViewModel", exception.message, exception)
|
Log.e("BookDetailViewModel", exception.message, exception)
|
||||||
_state.value = StateUio.Failure(exception)
|
StateUio.Failure(exception)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +69,7 @@ class BookDetailViewModel @Inject constructor(
|
||||||
date = releaseDate.shortDate(),
|
date = releaseDate.shortDate(),
|
||||||
series = series?.name,
|
series = series?.name,
|
||||||
description = synopsis ?: "",
|
description = synopsis ?: "",
|
||||||
cover = cover(
|
coverState = cover(
|
||||||
placeHolder = thumbnailCover,
|
placeHolder = thumbnailCover,
|
||||||
type = CoverUio.Type.DETAIL,
|
type = CoverUio.Type.DETAIL,
|
||||||
contentScale = ContentScale.FillHeight,
|
contentScale = ContentScale.FillHeight,
|
||||||
|
|
@ -91,7 +77,4 @@ class BookDetailViewModel @Inject constructor(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val SavedStateHandle.bookId: Int
|
|
||||||
get() = get<Int>(Screen.BookDetail.ARG_BOOK_ID) ?: error("")
|
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,6 @@ package com.pixelized.biblib.ui.screen.detail
|
||||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
|
import android.content.res.Configuration.UI_MODE_NIGHT_NO
|
||||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
|
@ -16,7 +15,6 @@ import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Download
|
import androidx.compose.material.icons.filled.Download
|
||||||
import androidx.compose.material.icons.filled.Send
|
import androidx.compose.material.icons.filled.Send
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
|
@ -30,8 +28,8 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.text.HtmlCompat
|
import androidx.core.text.HtmlCompat
|
||||||
import androidx.core.text.toSpannable
|
import androidx.core.text.toSpannable
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
|
||||||
import com.pixelized.biblib.R
|
import com.pixelized.biblib.R
|
||||||
|
import com.pixelized.biblib.ui.composable.Cover
|
||||||
import com.pixelized.biblib.ui.composable.SpannedText
|
import com.pixelized.biblib.ui.composable.SpannedText
|
||||||
import com.pixelized.biblib.ui.composable.animation.AnimatedDelayer
|
import com.pixelized.biblib.ui.composable.animation.AnimatedDelayer
|
||||||
import com.pixelized.biblib.ui.composable.animation.AnimatedOffset
|
import com.pixelized.biblib.ui.composable.animation.AnimatedOffset
|
||||||
|
|
@ -45,29 +43,27 @@ import com.pixelized.biblib.utils.extention.todo
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DetailScreen(
|
fun DetailScreen(
|
||||||
viewModel: BookDetailViewModel = hiltViewModel()
|
detail: BookUio? = null,
|
||||||
) {
|
) {
|
||||||
val bottomDetailState = LocalBottomDetailController.current
|
if (detail != null) {
|
||||||
|
|
||||||
Box {
|
|
||||||
val book by viewModel.book
|
|
||||||
book?.let {
|
|
||||||
DetailScreenContent(
|
DetailScreenContent(
|
||||||
book = it,
|
modifier = Modifier.fillMaxSize(),
|
||||||
onClose = {
|
book = detail,
|
||||||
bottomDetailState.collapse()
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
Box(modifier = Modifier.fillMaxSize())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val bottomDetailState = LocalBottomDetailController.current
|
||||||
|
BackHandler {
|
||||||
|
bottomDetailState.collapse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalAnimationApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DetailScreenContent(
|
private fun DetailScreenContent(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
book: BookUio,
|
book: BookUio,
|
||||||
onClose: () -> Unit = todo(),
|
|
||||||
onMobi: () -> Unit = todo(),
|
onMobi: () -> Unit = todo(),
|
||||||
onEpub: () -> Unit = todo(),
|
onEpub: () -> Unit = todo(),
|
||||||
onSend: () -> Unit = todo(),
|
onSend: () -> Unit = todo(),
|
||||||
|
|
@ -87,37 +83,16 @@ private fun DetailScreenContent(
|
||||||
.height(MaterialTheme.bibLib.dimen.detail.cover),
|
.height(MaterialTheme.bibLib.dimen.detail.cover),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
val cover by book.cover
|
val sizeModifier = if (book.cover.type == CoverUio.Type.PLACE_HOLDER) {
|
||||||
when (cover.type) {
|
Modifier.size(MaterialTheme.bibLib.dimen.detail.placeHolder)
|
||||||
CoverUio.Type.PLACE_HOLDER -> {
|
} else {
|
||||||
Image(
|
Modifier.fillMaxSize()
|
||||||
modifier = Modifier.size(MaterialTheme.bibLib.dimen.detail.placeHolder),
|
}
|
||||||
painter = cover.painter,
|
Cover(
|
||||||
contentScale = cover.contentScale,
|
modifier = sizeModifier,
|
||||||
colorFilter = cover.colorFilter,
|
cover = book.cover,
|
||||||
contentDescription = null,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CoverUio.Type.THUMBNAIL -> {
|
|
||||||
Image(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
painter = cover.painter,
|
|
||||||
contentScale = cover.contentScale,
|
|
||||||
colorFilter = cover.colorFilter,
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
CoverUio.Type.DETAIL -> {
|
|
||||||
Image(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
painter = cover.painter,
|
|
||||||
contentScale = cover.contentScale,
|
|
||||||
colorFilter = cover.colorFilter,
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row(modifier = Modifier.padding(vertical = MaterialTheme.bibLib.dimen.medium)) {
|
Row(modifier = Modifier.padding(vertical = MaterialTheme.bibLib.dimen.medium)) {
|
||||||
AnimatedOffset(
|
AnimatedOffset(
|
||||||
|
|
@ -195,7 +170,7 @@ private fun DetailScreenContent(
|
||||||
AnimatedOffset(modifier = Modifier.weight(1f)) {
|
AnimatedOffset(modifier = Modifier.weight(1f)) {
|
||||||
TitleLabel(
|
TitleLabel(
|
||||||
title = stringResource(id = R.string.detail_rating),
|
title = stringResource(id = R.string.detail_rating),
|
||||||
label = book.rating.toString(),
|
label = book.rating?.toString(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,15 +181,13 @@ private fun DetailScreenContent(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
book.date?.let {
|
|
||||||
AnimatedOffset(modifier = Modifier.weight(1f)) {
|
AnimatedOffset(modifier = Modifier.weight(1f)) {
|
||||||
TitleLabel(
|
TitleLabel(
|
||||||
title = stringResource(id = R.string.detail_release),
|
title = stringResource(id = R.string.detail_release),
|
||||||
label = it,
|
label = book.date ?: "-" ,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
AnimatedOffset(
|
AnimatedOffset(
|
||||||
modifier = Modifier.padding(bottom = MaterialTheme.bibLib.dimen.medium),
|
modifier = Modifier.padding(bottom = MaterialTheme.bibLib.dimen.medium),
|
||||||
|
|
@ -237,8 +210,6 @@ private fun DetailScreenContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BackHandler(onBack = onClose)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -288,7 +259,7 @@ private fun DetailScreenContentPreview() {
|
||||||
description = "En ce début de treizième millénaire, l'Empire n'a jamais été aussi puissant, aussi étendu à travers toute la galaxie. C'est dans sa capitale, Trantor, que l'éminent savant Hari Seldon invente la psychohistoire, une science nouvelle permettant de prédire l'avenir. Grâce à elle, Seldon prévoit l'effondrement de l'Empire d'ici cinq siècles, suivi d'une ère de ténèbres de trente mille ans. Réduire cette période à mille ans est peut-être possible, à condition de mener à terme son projet : la Fondation, chargée de rassembler toutes les connaissances humaines. Une entreprise visionnaire qui rencontre de nombreux et puissants détracteurs...",
|
description = "En ce début de treizième millénaire, l'Empire n'a jamais été aussi puissant, aussi étendu à travers toute la galaxie. C'est dans sa capitale, Trantor, que l'éminent savant Hari Seldon invente la psychohistoire, une science nouvelle permettant de prédire l'avenir. Grâce à elle, Seldon prévoit l'effondrement de l'Empire d'ici cinq siècles, suivi d'une ère de ténèbres de trente mille ans. Réduire cette période à mille ans est peut-être possible, à condition de mener à terme son projet : la Fondation, chargée de rassembler toutes les connaissances humaines. Une entreprise visionnaire qui rencontre de nombreux et puissants détracteurs...",
|
||||||
rating = 4.5f,
|
rating = 4.5f,
|
||||||
language = "Français",
|
language = "Français",
|
||||||
cover = cover,
|
coverState = cover,
|
||||||
)
|
)
|
||||||
BibLibTheme {
|
BibLibTheme {
|
||||||
DetailScreenContent(book = book)
|
DetailScreenContent(book = book)
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,10 @@ fun LazyBookThumbnailColumn(
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
state = state,
|
state = state,
|
||||||
) {
|
) {
|
||||||
items(books) { thumbnail ->
|
items(
|
||||||
|
items = books,
|
||||||
|
key = { it.id },
|
||||||
|
) { thumbnail ->
|
||||||
BookThumbnail(
|
BookThumbnail(
|
||||||
thumbnail = thumbnail,
|
thumbnail = thumbnail,
|
||||||
onClick = currentOnItemClick,
|
onClick = currentOnItemClick,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.pixelized.biblib.ui.screen.home.common.uio
|
package com.pixelized.biblib.ui.screen.home.common.uio
|
||||||
|
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
|
||||||
data class BookUio(
|
data class BookUio(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
|
|
@ -11,5 +12,7 @@ data class BookUio(
|
||||||
val date: String?,
|
val date: String?,
|
||||||
val series: String?,
|
val series: String?,
|
||||||
val description: String,
|
val description: String,
|
||||||
val cover: State<CoverUio>,
|
private val coverState: State<CoverUio>,
|
||||||
)
|
) {
|
||||||
|
val cover by coverState
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ fun BooksPage(
|
||||||
contentPadding = PaddingValues(all = MaterialTheme.bibLib.dimen.thumbnail.padding),
|
contentPadding = PaddingValues(all = MaterialTheme.bibLib.dimen.thumbnail.padding),
|
||||||
books = booksViewModel.books,
|
books = booksViewModel.books,
|
||||||
onItemClick = {
|
onItemClick = {
|
||||||
bottomDetailState.expandBookDetail(bookId = it.id)
|
bottomDetailState.expandBookDetail(id = it.id)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ fun NewsPage(
|
||||||
contentPadding = PaddingValues(all = MaterialTheme.bibLib.dimen.thumbnail.padding),
|
contentPadding = PaddingValues(all = MaterialTheme.bibLib.dimen.thumbnail.padding),
|
||||||
books = booksViewModel.news,
|
books = booksViewModel.news,
|
||||||
onItemClick = {
|
onItemClick = {
|
||||||
bottomDetail.expandBookDetail(bookId = it.id)
|
bottomDetail.expandBookDetail(id = it.id)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue