Refactor the thumbnails.
This commit is contained in:
parent
f6496e485d
commit
35d27534df
15 changed files with 356 additions and 481 deletions
|
|
@ -2,6 +2,7 @@ package com.pixelized.biblib.ui.screen.home
|
|||
|
||||
import android.app.Application
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
|
|
@ -13,14 +14,11 @@ import com.pixelized.biblib.model.search.SortType
|
|||
import com.pixelized.biblib.model.search.SortValue
|
||||
import com.pixelized.biblib.repository.book.IBookRepository
|
||||
import com.pixelized.biblib.repository.search.ISearchRepository
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.LargeBookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.MicroBookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.SmallBookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.BookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.filter.FilterChipUio
|
||||
import com.pixelized.biblib.ui.screen.home.options.OptionsUio
|
||||
import com.pixelized.biblib.utils.extention.stringResource
|
||||
import com.pixelized.biblib.utils.extention.toLargeBookThumbnailUio
|
||||
import com.pixelized.biblib.utils.extention.toMicroThumbnailUio
|
||||
import com.pixelized.biblib.utils.extention.toSmallThumbnailUio
|
||||
import com.pixelized.biblib.utils.extention.toThumbnailUio
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -42,10 +40,19 @@ class BookSearchViewModel @Inject constructor(
|
|||
private val _updating = mutableStateOf(false)
|
||||
val updating: State<Boolean> = _updating
|
||||
|
||||
private val _display = mutableStateOf(HomeDisplay.MICRO)
|
||||
val display: State<HomeDisplay> = _display
|
||||
|
||||
val options = derivedStateOf {
|
||||
when(display.value) {
|
||||
HomeDisplay.MICRO -> OptionsUio(micro = true, small = false, large = false)
|
||||
HomeDisplay.SMALL -> OptionsUio(micro = false, small = true, large = false)
|
||||
HomeDisplay.GRID -> OptionsUio(micro = false, small = false, large = true)
|
||||
}
|
||||
}
|
||||
|
||||
private var searchSource: BookSearchSource? = null
|
||||
val microPaging: Flow<PagingData<MicroBookThumbnailUio>>
|
||||
val smallPaging: Flow<PagingData<SmallBookThumbnailUio>>
|
||||
val largePaging: Flow<PagingData<LargeBookThumbnailUio>>
|
||||
val paging: Flow<PagingData<BookThumbnailUio>>
|
||||
|
||||
private val _search = mutableStateOf<String?>(null)
|
||||
val search: State<String?> = _search
|
||||
|
|
@ -76,14 +83,8 @@ class BookSearchViewModel @Inject constructor(
|
|||
pagingSourceFactory = ::buildBookSource,
|
||||
).flow
|
||||
// keep transaction updated with the pager.
|
||||
microPaging = searchFlow
|
||||
.map { pagingData -> pagingData.map { it.toMicroThumbnailUio() } }
|
||||
.cachedIn(viewModelScope + Dispatchers.IO)
|
||||
smallPaging = searchFlow
|
||||
.map { pagingData -> pagingData.map { it.toSmallThumbnailUio() } }
|
||||
.cachedIn(viewModelScope + Dispatchers.IO)
|
||||
largePaging = searchFlow
|
||||
.map { pagingData -> pagingData.map { it.toLargeBookThumbnailUio() } }
|
||||
paging = searchFlow
|
||||
.map { pagingData -> pagingData.map { it.toThumbnailUio() } }
|
||||
.cachedIn(viewModelScope + Dispatchers.IO)
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +105,10 @@ class BookSearchViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun onDisplay(type: HomeDisplay) {
|
||||
_display.value = type
|
||||
}
|
||||
|
||||
fun source(clean: Boolean = false, block: SortAndFilterScope.() -> Unit) {
|
||||
val scope = if (clean) {
|
||||
SortAndFilterScope(
|
||||
|
|
|
|||
|
|
@ -2,11 +2,8 @@ package com.pixelized.biblib.ui.screen.home
|
|||
|
||||
import android.content.res.Configuration
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.*
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
|
|
@ -48,26 +45,29 @@ import com.pixelized.biblib.ui.composable.scaffold.*
|
|||
import com.pixelized.biblib.ui.navigation.LocalScreenNavHostController
|
||||
import com.pixelized.biblib.ui.navigation.navigateToProfile
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.*
|
||||
import com.pixelized.biblib.ui.screen.home.common.preview.thumbnailPreviewResources
|
||||
import com.pixelized.biblib.ui.screen.home.filter.FilterChip
|
||||
import com.pixelized.biblib.ui.screen.home.filter.FilterChipUio
|
||||
import com.pixelized.biblib.ui.screen.home.filter.filterPreview
|
||||
import com.pixelized.biblib.ui.screen.home.header.LazyGridCollapsingHeaderLayout
|
||||
import com.pixelized.biblib.ui.screen.home.options.Options
|
||||
import com.pixelized.biblib.ui.screen.home.options.OptionsUio
|
||||
import com.pixelized.biblib.ui.screen.home.options.OptionsViewModel
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
import com.pixelized.biblib.utils.extention.bibLib
|
||||
import com.pixelized.biblib.utils.extention.imeHeight
|
||||
import com.pixelized.biblib.utils.extention.navigationBarsHeight
|
||||
import com.skydoves.landscapist.glide.GlideImage
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Stable
|
||||
@Immutable
|
||||
sealed class HomeScreenErrorUio(
|
||||
@StringRes val message: Int,
|
||||
@StringRes val action: Int,
|
||||
) {
|
||||
@Stable
|
||||
@Immutable
|
||||
class LibraryUpdate(
|
||||
@StringRes message: Int,
|
||||
@StringRes action: Int,
|
||||
|
|
@ -77,12 +77,19 @@ sealed class HomeScreenErrorUio(
|
|||
)
|
||||
}
|
||||
|
||||
@Stable
|
||||
@Immutable
|
||||
enum class HomeDisplay {
|
||||
MICRO,
|
||||
SMALL,
|
||||
GRID,
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class, ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
fun HomeScreen(
|
||||
bookViewModel: BookSearchViewModel = hiltViewModel(),
|
||||
profileViewModel: HomeViewModel = hiltViewModel(),
|
||||
optionsViewModel: OptionsViewModel = hiltViewModel(),
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val navigation = LocalScreenNavHostController.current
|
||||
|
|
@ -137,7 +144,7 @@ fun HomeScreen(
|
|||
filterViewModel = bookViewModel,
|
||||
filterState = filterState,
|
||||
),
|
||||
options = optionsViewModel.options,
|
||||
options = bookViewModel.options,
|
||||
onUp = {
|
||||
scope.launch {
|
||||
launch { largeGridState.animateScrollToItem(index = 0) }
|
||||
|
|
@ -159,26 +166,21 @@ fun HomeScreen(
|
|||
}
|
||||
}
|
||||
},
|
||||
onMicro = optionsViewModel::onMicro,
|
||||
onSmall = optionsViewModel::onSmall,
|
||||
onLarge = optionsViewModel::onLarge,
|
||||
onDisplay = bookViewModel::onDisplay,
|
||||
isLoading = bookViewModel.updating,
|
||||
onPullToRefresh = {
|
||||
scope.launch {
|
||||
bookViewModel.updateLibrary()
|
||||
}
|
||||
},
|
||||
largeGridState = largeGridState,
|
||||
largeGrid = bookViewModel.largePaging,
|
||||
smallListState = smallListState,
|
||||
smallList = bookViewModel.smallPaging,
|
||||
microListState = microListState,
|
||||
microList = bookViewModel.microPaging,
|
||||
display = bookViewModel.display,
|
||||
gridState = largeGridState,
|
||||
items = bookViewModel.paging,
|
||||
onBook = {
|
||||
// close the keyboard.
|
||||
focus.clearFocus(force = true)
|
||||
keyboard?.hide()
|
||||
// opent the detail bottom sheet.
|
||||
// open the detail bottom sheet.
|
||||
scope.launch {
|
||||
detailState.expandBookDetail(id = it)
|
||||
}
|
||||
|
|
@ -295,17 +297,12 @@ private fun HomeScreenContent(
|
|||
options: State<OptionsUio>,
|
||||
onUp: () -> Unit,
|
||||
onSort: () -> Unit,
|
||||
onMicro: () -> Unit,
|
||||
onSmall: () -> Unit,
|
||||
onLarge: () -> Unit,
|
||||
onDisplay: (HomeDisplay) -> Unit,
|
||||
isLoading: State<Boolean>,
|
||||
onPullToRefresh: () -> Unit,
|
||||
largeGridState: LazyGridState,
|
||||
largeGrid: Flow<PagingData<LargeBookThumbnailUio>>,
|
||||
smallListState: LazyListState,
|
||||
smallList: Flow<PagingData<SmallBookThumbnailUio>>,
|
||||
microListState: LazyListState,
|
||||
microList: Flow<PagingData<MicroBookThumbnailUio>>,
|
||||
display: State<HomeDisplay>,
|
||||
gridState: LazyGridState,
|
||||
items: Flow<PagingData<BookThumbnailUio>>,
|
||||
onBook: (id: Int) -> Unit,
|
||||
) {
|
||||
val theme = MaterialTheme.bibLib
|
||||
|
|
@ -348,9 +345,9 @@ private fun HomeScreenContent(
|
|||
options = options.value,
|
||||
onUp = onUp,
|
||||
onSort = onSort,
|
||||
onMicro = onMicro,
|
||||
onSmall = onSmall,
|
||||
onLarge = onLarge,
|
||||
onMicro = { onDisplay(HomeDisplay.MICRO) },
|
||||
onSmall = { onDisplay(HomeDisplay.SMALL) },
|
||||
onLarge = { onDisplay(HomeDisplay.GRID) },
|
||||
)
|
||||
},
|
||||
loader = {
|
||||
|
|
@ -370,7 +367,7 @@ private fun HomeScreenContent(
|
|||
content = {
|
||||
val navigationBarsHeight = navigationBarsHeight()
|
||||
val imeHeight = imeHeight()
|
||||
val padding = remember(navigationBarsHeight, imeHeight) {
|
||||
val paddingValues = remember(navigationBarsHeight, imeHeight) {
|
||||
PaddingValues(
|
||||
start = theme.dimen.thumbnail.padding,
|
||||
end = theme.dimen.thumbnail.padding,
|
||||
|
|
@ -378,95 +375,18 @@ private fun HomeScreenContent(
|
|||
bottom = theme.dimen.thumbnail.padding + max(navigationBarsHeight, imeHeight)
|
||||
)
|
||||
}
|
||||
|
||||
SwipeRefresh(
|
||||
state = rememberSwipeRefreshState(isRefreshing = false),
|
||||
onRefresh = onPullToRefresh,
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = options.value.large,
|
||||
enter = fadeIn(animationSpec = tween(delayMillis = 150)),
|
||||
exit = fadeOut(animationSpec = tween()),
|
||||
) {
|
||||
val items = largeGrid.collectAsLazyPagingItems()
|
||||
LazyVerticalGrid(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
columns = GridCells.Fixed(2),
|
||||
contentPadding = padding,
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
space = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(
|
||||
space = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
state = largeGridState,
|
||||
) {
|
||||
items(
|
||||
count = items.itemCount,
|
||||
key = { items[it]?.id ?: it }
|
||||
) { index ->
|
||||
val item = items[index]
|
||||
LargeBookThumbnail(
|
||||
thumbnail = item,
|
||||
onClick = { onBook(it.id) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = options.value.small,
|
||||
enter = fadeIn(animationSpec = tween(delayMillis = 150)),
|
||||
exit = fadeOut(animationSpec = tween()),
|
||||
) {
|
||||
val items = smallList.collectAsLazyPagingItems()
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = padding,
|
||||
verticalArrangement = Arrangement.spacedBy(
|
||||
space = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
state = smallListState,
|
||||
) {
|
||||
items(
|
||||
count = items.itemCount,
|
||||
key = { items[it]?.id ?: it },
|
||||
) { index ->
|
||||
val item = items[index]
|
||||
SmallBookThumbnail(
|
||||
thumbnail = item,
|
||||
onClick = { onBook(it.id) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = options.value.micro,
|
||||
enter = fadeIn(animationSpec = tween(delayMillis = 150)),
|
||||
exit = fadeOut(animationSpec = tween()),
|
||||
) {
|
||||
val items = microList.collectAsLazyPagingItems()
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = padding,
|
||||
verticalArrangement = Arrangement.spacedBy(
|
||||
space = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
state = microListState,
|
||||
) {
|
||||
items(
|
||||
count = items.itemCount,
|
||||
key = { "microList-${items[it]?.id ?: it}" },
|
||||
) { index ->
|
||||
val item = items[index]
|
||||
MicroBookThumbnail(
|
||||
thumbnail = item,
|
||||
onClick = { onBook(it.id) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
BookList(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
display = display,
|
||||
items = items,
|
||||
paddingValues = paddingValues,
|
||||
state = gridState,
|
||||
onBook = onBook,
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
@ -586,6 +506,105 @@ private fun HomeToolbar(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BookList(
|
||||
modifier: Modifier = Modifier,
|
||||
display: State<HomeDisplay>,
|
||||
items: Flow<PagingData<BookThumbnailUio>>,
|
||||
paddingValues: PaddingValues,
|
||||
state: LazyGridState,
|
||||
onBook: (id: Int) -> Unit,
|
||||
) {
|
||||
val data = items.collectAsLazyPagingItems()
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = display.value == HomeDisplay.MICRO,
|
||||
enter = fadeIn(tween(durationMillis = 150)),
|
||||
exit = fadeOut(tween())
|
||||
) {
|
||||
LazyVerticalGrid(
|
||||
modifier = modifier,
|
||||
columns = GridCells.Fixed(1),
|
||||
contentPadding = paddingValues,
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
space = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(
|
||||
space = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
state = state,
|
||||
) {
|
||||
items(
|
||||
count = data.itemCount,
|
||||
key = { index -> data[index]?.id ?: index }
|
||||
) { index ->
|
||||
MicroBookThumbnail(
|
||||
thumbnail = data[index],
|
||||
onClick = { onBook(it.id) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = display.value == HomeDisplay.SMALL,
|
||||
enter = fadeIn(tween(durationMillis = 150)),
|
||||
exit = fadeOut(tween())
|
||||
) {
|
||||
LazyVerticalGrid(
|
||||
modifier = modifier,
|
||||
columns = GridCells.Fixed(1),
|
||||
contentPadding = paddingValues,
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
space = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(
|
||||
space = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
state = state,
|
||||
) {
|
||||
items(
|
||||
count = data.itemCount,
|
||||
key = { index -> data[index]?.id ?: index }
|
||||
) { index ->
|
||||
SmallBookThumbnail(
|
||||
thumbnail = data[index],
|
||||
onClick = { onBook(it.id) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = display.value == HomeDisplay.GRID,
|
||||
enter = fadeIn(tween(durationMillis = 150)),
|
||||
exit = fadeOut(tween())
|
||||
) {
|
||||
LazyVerticalGrid(
|
||||
modifier = modifier,
|
||||
columns = GridCells.Fixed(2),
|
||||
contentPadding = paddingValues,
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
space = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(
|
||||
space = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
state = state,
|
||||
) {
|
||||
items(
|
||||
count = data.itemCount,
|
||||
key = { index -> data[index]?.id ?: index }
|
||||
) { index ->
|
||||
LargeBookThumbnail(
|
||||
thumbnail = data[index],
|
||||
onClick = { onBook(it.id) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
private fun CollapseKeyboardOnScrollHandler(
|
||||
|
|
@ -627,17 +646,12 @@ private fun HomeScreenPreview() {
|
|||
options = options,
|
||||
onUp = { },
|
||||
onSort = { },
|
||||
onMicro = { },
|
||||
onSmall = { },
|
||||
onLarge = { },
|
||||
onDisplay = { },
|
||||
isLoading = remember { mutableStateOf(false) },
|
||||
onPullToRefresh = { },
|
||||
largeGridState = rememberLazyGridState(),
|
||||
largeGrid = emptyFlow(),
|
||||
smallListState = rememberLazyListState(),
|
||||
smallList = emptyFlow(),
|
||||
microListState = rememberLazyListState(),
|
||||
microList = emptyFlow(),
|
||||
display = remember { mutableStateOf(HomeDisplay.MICRO) },
|
||||
gridState = rememberLazyGridState(),
|
||||
items = thumbnailPreviewResources(),
|
||||
onBook = { },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package com.pixelized.biblib.ui.screen.home.common.item
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
||||
@Stable
|
||||
@Immutable
|
||||
data class BookThumbnailUio(
|
||||
val id: Int,
|
||||
val title: String,
|
||||
val series: String?,
|
||||
val genre: String?,
|
||||
val author: String?,
|
||||
val language: String?,
|
||||
val date: String?,
|
||||
val isNew: Boolean,
|
||||
val thumbnail: String,
|
||||
val cover: String,
|
||||
)
|
||||
|
||||
class BookThumbnailPreviewProvider : PreviewParameterProvider<BookThumbnailUio?> {
|
||||
override val values: Sequence<BookThumbnailUio?> = sequenceOf(
|
||||
BookThumbnailUio(
|
||||
id = 0,
|
||||
title = "Foundation",
|
||||
series = "Foundation - 1",
|
||||
genre = "Sci-Fi",
|
||||
author = "Asimov",
|
||||
language = "Français",
|
||||
date = "1951",
|
||||
isNew = true,
|
||||
thumbnail = "",
|
||||
cover = "",
|
||||
),
|
||||
null
|
||||
)
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -16,7 +15,6 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.biblib.R
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
|
|
@ -25,18 +23,11 @@ import com.pixelized.biblib.utils.extention.modifier.drawDiagonalLabel
|
|||
import com.pixelized.biblib.utils.extention.placeholder
|
||||
import com.skydoves.landscapist.glide.GlideImage
|
||||
|
||||
@Stable
|
||||
data class LargeBookThumbnailUio(
|
||||
val id: Int,
|
||||
val isNew: Boolean,
|
||||
val cover: String,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun LargeBookThumbnail(
|
||||
modifier: Modifier = Modifier,
|
||||
thumbnail: LargeBookThumbnailUio?,
|
||||
onClick: (LargeBookThumbnailUio) -> Unit,
|
||||
thumbnail: BookThumbnailUio?,
|
||||
onClick: (BookThumbnailUio) -> Unit,
|
||||
) {
|
||||
Card(
|
||||
modifier = modifier
|
||||
|
|
@ -61,8 +52,8 @@ fun LargeBookThumbnail(
|
|||
@Composable
|
||||
private fun LargeBookThumbnailContent(
|
||||
modifier: Modifier = Modifier,
|
||||
thumbnail: LargeBookThumbnailUio,
|
||||
onClick: (LargeBookThumbnailUio) -> Unit,
|
||||
thumbnail: BookThumbnailUio,
|
||||
onClick: (BookThumbnailUio) -> Unit,
|
||||
) {
|
||||
GlideImage(
|
||||
modifier = Modifier
|
||||
|
|
@ -116,7 +107,7 @@ private fun Modifier.isNew(
|
|||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun LargeBookThumbnailPreview(
|
||||
@PreviewParameter(LargeBookThumbnailPreviewProvider::class) preview: LargeBookThumbnailUio?,
|
||||
@PreviewParameter(BookThumbnailPreviewProvider::class) preview: BookThumbnailUio?,
|
||||
) {
|
||||
BibLibTheme {
|
||||
LargeBookThumbnail(
|
||||
|
|
@ -126,14 +117,3 @@ private fun LargeBookThumbnailPreview(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class LargeBookThumbnailPreviewProvider : PreviewParameterProvider<LargeBookThumbnailUio?> {
|
||||
override val values: Sequence<LargeBookThumbnailUio?> = sequenceOf(
|
||||
LargeBookThumbnailUio(
|
||||
id = 0,
|
||||
isNew = true,
|
||||
cover = "",
|
||||
),
|
||||
null
|
||||
)
|
||||
}
|
||||
|
|
@ -11,7 +11,6 @@ import androidx.compose.material.Card
|
|||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -20,6 +19,7 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.constraintlayout.compose.ConstraintLayout
|
||||
|
|
@ -31,21 +31,11 @@ import com.pixelized.biblib.utils.extention.modifier.drawDiagonalLabel
|
|||
import com.pixelized.biblib.utils.extention.placeholder
|
||||
import com.skydoves.landscapist.glide.GlideImage
|
||||
|
||||
@Stable
|
||||
data class MicroBookThumbnailUio(
|
||||
val id: Int,
|
||||
val cover: String,
|
||||
val title: String,
|
||||
val author: String,
|
||||
val series: String,
|
||||
val isNew: Boolean,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun MicroBookThumbnail(
|
||||
modifier: Modifier = Modifier,
|
||||
thumbnail: MicroBookThumbnailUio?,
|
||||
onClick: (MicroBookThumbnailUio) -> Unit,
|
||||
thumbnail: BookThumbnailUio?,
|
||||
onClick: (BookThumbnailUio) -> Unit,
|
||||
) {
|
||||
if (thumbnail != null) {
|
||||
MicroBookThumbnailContent(
|
||||
|
|
@ -63,8 +53,8 @@ fun MicroBookThumbnail(
|
|||
@Composable
|
||||
private fun MicroBookThumbnailContent(
|
||||
modifier: Modifier = Modifier,
|
||||
thumbnail: MicroBookThumbnailUio,
|
||||
onClick: (MicroBookThumbnailUio) -> Unit,
|
||||
thumbnail: BookThumbnailUio,
|
||||
onClick: (BookThumbnailUio) -> Unit,
|
||||
) {
|
||||
Card(
|
||||
modifier = modifier
|
||||
|
|
@ -89,7 +79,7 @@ private fun MicroBookThumbnailContent(
|
|||
.size(size = MaterialTheme.bibLib.dimen.thumbnail.micro)
|
||||
.isNew { thumbnail.isNew },
|
||||
previewPlaceholder = R.drawable.ic_fondation_thumbnail,
|
||||
imageModel = thumbnail.cover,
|
||||
imageModel = thumbnail.thumbnail,
|
||||
)
|
||||
|
||||
Text(
|
||||
|
|
@ -117,7 +107,7 @@ private fun MicroBookThumbnailContent(
|
|||
color = MaterialTheme.bibLib.colors.typography.light,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = thumbnail.author,
|
||||
text = thumbnail.author ?: "",
|
||||
)
|
||||
|
||||
Text(
|
||||
|
|
@ -131,7 +121,7 @@ private fun MicroBookThumbnailContent(
|
|||
color = MaterialTheme.bibLib.colors.typography.light,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = thumbnail.series,
|
||||
text = thumbnail.series ?: "",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -214,31 +204,14 @@ private fun Modifier.isNew(
|
|||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun MicroBookThumbnailPreview() {
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun MicroBookThumbnailPreview(
|
||||
@PreviewParameter(BookThumbnailPreviewProvider::class) preview: BookThumbnailUio?,
|
||||
) {
|
||||
BibLibTheme {
|
||||
MicroBookThumbnail(
|
||||
thumbnail = MicroBookThumbnailUio(
|
||||
id = 0,
|
||||
cover = "",
|
||||
title = "Foundation",
|
||||
author = "Asimov",
|
||||
series = "Foundation - 1",
|
||||
isNew = true,
|
||||
),
|
||||
onClick = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun MicroBookThumbnailEmptyPreview() {
|
||||
BibLibTheme {
|
||||
MicroBookThumbnail(
|
||||
thumbnail = null,
|
||||
thumbnail = preview,
|
||||
onClick = { },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import androidx.compose.material.Card
|
|||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -17,6 +16,7 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.constraintlayout.compose.ConstraintLayout
|
||||
import androidx.constraintlayout.compose.Dimension
|
||||
|
|
@ -27,22 +27,11 @@ import com.pixelized.biblib.utils.extention.modifier.drawDiagonalLabel
|
|||
import com.pixelized.biblib.utils.extention.placeholder
|
||||
import com.skydoves.landscapist.glide.GlideImage
|
||||
|
||||
@Stable
|
||||
data class SmallBookThumbnailUio(
|
||||
val id: Int,
|
||||
val genre: String,
|
||||
val title: String,
|
||||
val author: String,
|
||||
val date: String?,
|
||||
val isNew: Boolean,
|
||||
val cover: String,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun SmallBookThumbnail(
|
||||
modifier: Modifier = Modifier,
|
||||
thumbnail: SmallBookThumbnailUio?,
|
||||
onClick: (SmallBookThumbnailUio) -> Unit,
|
||||
thumbnail: BookThumbnailUio?,
|
||||
onClick: (BookThumbnailUio) -> Unit,
|
||||
) {
|
||||
if (thumbnail != null) {
|
||||
SmallBookThumbnailContent(
|
||||
|
|
@ -60,8 +49,8 @@ fun SmallBookThumbnail(
|
|||
@Composable
|
||||
private fun SmallBookThumbnailContent(
|
||||
modifier: Modifier = Modifier,
|
||||
thumbnail: SmallBookThumbnailUio,
|
||||
onClick: (SmallBookThumbnailUio) -> Unit,
|
||||
thumbnail: BookThumbnailUio,
|
||||
onClick: (BookThumbnailUio) -> Unit,
|
||||
) {
|
||||
Card(
|
||||
modifier = modifier
|
||||
|
|
@ -73,7 +62,7 @@ private fun SmallBookThumbnailContent(
|
|||
ConstraintLayout(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
val (cover, title, author, genre, date) = createRefs()
|
||||
val (cover, title, author, series, genre, date) = createRefs()
|
||||
|
||||
GlideImage(
|
||||
modifier = Modifier
|
||||
|
|
@ -86,7 +75,7 @@ private fun SmallBookThumbnailContent(
|
|||
.size(size = MaterialTheme.bibLib.dimen.thumbnail.cover)
|
||||
.isNew { thumbnail.isNew },
|
||||
previewPlaceholder = R.drawable.ic_fondation_thumbnail,
|
||||
imageModel = thumbnail.cover,
|
||||
imageModel = thumbnail.thumbnail,
|
||||
)
|
||||
|
||||
Text(
|
||||
|
|
@ -106,7 +95,7 @@ private fun SmallBookThumbnailContent(
|
|||
Text(
|
||||
modifier = Modifier.constrainAs(author) {
|
||||
top.linkTo(title.bottom, margin = 4.dp)
|
||||
bottom.linkTo(genre.top, margin = 4.dp)
|
||||
bottom.linkTo(series.top, margin = 4.dp)
|
||||
start.linkTo(cover.end, margin = 8.dp)
|
||||
end.linkTo(parent.end, margin = 8.dp)
|
||||
width = Dimension.fillToConstraints
|
||||
|
|
@ -116,7 +105,22 @@ private fun SmallBookThumbnailContent(
|
|||
color = MaterialTheme.bibLib.colors.typography.light,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
text = thumbnail.author
|
||||
text = thumbnail.author ?: ""
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.constrainAs(series) {
|
||||
top.linkTo(author.bottom, margin = 4.dp)
|
||||
bottom.linkTo(genre.top, margin = 4.dp)
|
||||
start.linkTo(cover.end, margin = 8.dp)
|
||||
end.linkTo(parent.end, margin = 8.dp)
|
||||
width = Dimension.fillToConstraints
|
||||
},
|
||||
style = MaterialTheme.typography.caption,
|
||||
color = MaterialTheme.bibLib.colors.typography.light,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
text = thumbnail.series ?: ""
|
||||
)
|
||||
|
||||
Text(
|
||||
|
|
@ -130,7 +134,7 @@ private fun SmallBookThumbnailContent(
|
|||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.caption,
|
||||
color = MaterialTheme.bibLib.colors.typography.light,
|
||||
text = thumbnail.genre
|
||||
text = thumbnail.genre ?: ""
|
||||
)
|
||||
|
||||
Text(
|
||||
|
|
@ -240,32 +244,14 @@ private fun Modifier.isNew(
|
|||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun SmallBookThumbnailPreview() {
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun SmallBookThumbnailPreview(
|
||||
@PreviewParameter(BookThumbnailPreviewProvider::class) preview: BookThumbnailUio?,
|
||||
) {
|
||||
BibLibTheme {
|
||||
SmallBookThumbnail(
|
||||
thumbnail = SmallBookThumbnailUio(
|
||||
id = 0,
|
||||
title = "Foundation",
|
||||
genre = "Sci-Fi",
|
||||
author = "Asimov",
|
||||
date = "1951",
|
||||
isNew = true,
|
||||
cover = "",
|
||||
),
|
||||
onClick = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun SmallBookThumbnailEmptyPreview() {
|
||||
BibLibTheme {
|
||||
SmallBookThumbnail(
|
||||
thumbnail = null,
|
||||
thumbnail = preview,
|
||||
onClick = { },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,192 +3,99 @@ package com.pixelized.biblib.ui.screen.home.common.preview
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.paging.PagingData
|
||||
import androidx.paging.compose.LazyPagingItems
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.LargeBookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.MicroBookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.SmallBookThumbnailUio
|
||||
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.BookThumbnailUio
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
||||
@Composable
|
||||
fun microBookThumbnailPreviewResources(): LazyPagingItems<MicroBookThumbnailUio> {
|
||||
fun thumbnailPreviewResources(): Flow<PagingData<BookThumbnailUio>> {
|
||||
val thumbnails = remember {
|
||||
|
||||
listOf(
|
||||
MicroBookThumbnailUio(
|
||||
BookThumbnailUio(
|
||||
id = 112,
|
||||
title = "Prélude à Fondation",
|
||||
author = "Asimov",
|
||||
series = "Foundation",
|
||||
genre = "SCI-FI",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/112.jpg",
|
||||
),
|
||||
MicroBookThumbnailUio(
|
||||
id = 78,
|
||||
title = "L'Aube de Fondation",
|
||||
author = "Asimov",
|
||||
series = "Foundation",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/78.jpg",
|
||||
),
|
||||
MicroBookThumbnailUio(
|
||||
id = 90,
|
||||
title = "Fondation",
|
||||
author = "Asimov",
|
||||
series = "Foundation",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/90.jpg",
|
||||
),
|
||||
MicroBookThumbnailUio(
|
||||
id = 184,
|
||||
title = "Fondation et Empire",
|
||||
author = "Asimov",
|
||||
series = "Foundation",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/184.jpg",
|
||||
),
|
||||
MicroBookThumbnailUio(
|
||||
id = 185,
|
||||
title = "Seconde Fondation",
|
||||
author = "Asimov",
|
||||
series = "Foundation",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/185.jpg",
|
||||
),
|
||||
MicroBookThumbnailUio(
|
||||
id = 119,
|
||||
title = "Fondation foudroyée",
|
||||
author = "Asimov",
|
||||
series = "Foundation",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/119.jpg",
|
||||
),
|
||||
MicroBookThumbnailUio(
|
||||
id = 163,
|
||||
title = "Terre et Fondation",
|
||||
author = "Asimov",
|
||||
series = "Foundation",
|
||||
isNew = true,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/163.jpg",
|
||||
),
|
||||
)
|
||||
}
|
||||
return flowOf(PagingData.from(thumbnails)).collectAsLazyPagingItems()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun smallBookThumbnailPreviewResources(): LazyPagingItems<SmallBookThumbnailUio> {
|
||||
val thumbnails = remember {
|
||||
listOf(
|
||||
SmallBookThumbnailUio(
|
||||
id = 112,
|
||||
title = "Prélude à Fondation",
|
||||
author = "Asimov",
|
||||
language = "Français",
|
||||
date = "1988",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/112.jpg",
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/90.jpg",
|
||||
thumbnail = "https://bib.bibulle.fr/api/book/thumbnail/112.jpg",
|
||||
),
|
||||
SmallBookThumbnailUio(
|
||||
BookThumbnailUio(
|
||||
id = 78,
|
||||
title = "L'Aube de Fondation",
|
||||
series = "Foundation",
|
||||
genre = "SCI-FI",
|
||||
author = "Asimov",
|
||||
language = "Français",
|
||||
date = "1993",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/78.jpg",
|
||||
),
|
||||
SmallBookThumbnailUio(
|
||||
id = 90,
|
||||
title = "Fondation",
|
||||
author = "Asimov",
|
||||
date = "1951",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/90.jpg",
|
||||
),
|
||||
SmallBookThumbnailUio(
|
||||
id = 184,
|
||||
title = "Fondation et Empire",
|
||||
author = "Asimov",
|
||||
date = "1952",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/184.jpg",
|
||||
),
|
||||
SmallBookThumbnailUio(
|
||||
id = 185,
|
||||
title = "Seconde Fondation",
|
||||
author = "Asimov",
|
||||
date = "1953",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/185.jpg",
|
||||
),
|
||||
SmallBookThumbnailUio(
|
||||
id = 119,
|
||||
title = "Fondation foudroyée",
|
||||
author = "Asimov",
|
||||
date = "1982",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/119.jpg",
|
||||
),
|
||||
SmallBookThumbnailUio(
|
||||
id = 163,
|
||||
title = "Terre et Fondation",
|
||||
author = "Asimov",
|
||||
date = "1986",
|
||||
genre = "Sci-Fi",
|
||||
isNew = true,
|
||||
cover = "https://bib.bibulle.fr/api/book/thumbnail/163.jpg",
|
||||
),
|
||||
)
|
||||
}
|
||||
return flowOf(PagingData.from(thumbnails)).collectAsLazyPagingItems()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun largeBookThumbnailPreviewResources(): LazyPagingItems<LargeBookThumbnailUio> {
|
||||
val thumbnails = remember {
|
||||
listOf(
|
||||
LargeBookThumbnailUio(
|
||||
id = 112,
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/112.jpg",
|
||||
),
|
||||
LargeBookThumbnailUio(
|
||||
id = 78,
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/78.jpg",
|
||||
),
|
||||
LargeBookThumbnailUio(
|
||||
id = 90,
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/90.jpg",
|
||||
thumbnail = "https://bib.bibulle.fr/api/book/thumbnail/78.jpg",
|
||||
),
|
||||
LargeBookThumbnailUio(
|
||||
BookThumbnailUio(
|
||||
id = 90,
|
||||
title = "Fondation",
|
||||
series = "Foundation",
|
||||
genre = "SCI-FI",
|
||||
author = "Asimov",
|
||||
language = "Français",
|
||||
date = "1951",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/90.jpg",
|
||||
thumbnail = "https://bib.bibulle.fr/api/book/thumbnail/90.jpg",
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 184,
|
||||
title = "Fondation et Empire",
|
||||
series = "Foundation",
|
||||
genre = "SCI-FI",
|
||||
author = "Asimov",
|
||||
language = "Français",
|
||||
date = "1952",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/184.jpg",
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/90.jpg",
|
||||
thumbnail = "https://bib.bibulle.fr/api/book/thumbnail/184.jpg",
|
||||
),
|
||||
LargeBookThumbnailUio(
|
||||
BookThumbnailUio(
|
||||
id = 185,
|
||||
title = "Seconde Fondation",
|
||||
series = "Foundation",
|
||||
genre = "SCI-FI",
|
||||
author = "Asimov",
|
||||
language = "Français",
|
||||
date = "1953",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/185.jpg",
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/90.jpg",
|
||||
thumbnail = "https://bib.bibulle.fr/api/book/thumbnail/185.jpg",
|
||||
),
|
||||
LargeBookThumbnailUio(
|
||||
BookThumbnailUio(
|
||||
id = 119,
|
||||
title = "Fondation foudroyée",
|
||||
series = "Foundation",
|
||||
genre = "SCI-FI",
|
||||
author = "Asimov",
|
||||
language = "Français",
|
||||
date = "1982",
|
||||
isNew = false,
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/119.jpg",
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/90.jpg",
|
||||
thumbnail = "https://bib.bibulle.fr/api/book/thumbnail/119.jpg",
|
||||
),
|
||||
LargeBookThumbnailUio(
|
||||
BookThumbnailUio(
|
||||
id = 163,
|
||||
title = "Terre et Fondation",
|
||||
series = "Foundation",
|
||||
genre = "SCI-FI",
|
||||
author = "Asimov",
|
||||
language = "Français",
|
||||
date = "1986",
|
||||
isNew = true,
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/163.jpg",
|
||||
cover = "https://bib.bibulle.fr/api/book/cover/90.jpg",
|
||||
thumbnail = "https://bib.bibulle.fr/api/book/thumbnail/163.jpg",
|
||||
),
|
||||
)
|
||||
}
|
||||
return flowOf(PagingData.from(thumbnails)).collectAsLazyPagingItems()
|
||||
return flowOf(PagingData.from(thumbnails))
|
||||
}
|
||||
|
|
@ -4,13 +4,12 @@ import android.content.Context
|
|||
import androidx.activity.compose.BackHandler
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.pixelized.biblib.R
|
||||
|
|
@ -69,6 +68,8 @@ fun DetailScreen(
|
|||
when (val detail = detailViewModel.detail.value) {
|
||||
null -> EmptyDetail()
|
||||
else -> {
|
||||
val bibLibUrl = stringResource(id = R.string.detail_open_on_biblib_url, detail.id)
|
||||
|
||||
ModalBottomSheetLayout(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
sheetState = emailSheetState,
|
||||
|
|
@ -92,10 +93,11 @@ fun DetailScreen(
|
|||
if (detailState.bottomSheetState.isVisible) {
|
||||
DetailScreenContent(
|
||||
book = detail,
|
||||
onOpenOnBibLib = {
|
||||
uriHandler.openUri(bibLibUrl)
|
||||
},
|
||||
onAuthor = { onAuthor(it.name, it.id) },
|
||||
onSeries = { onSeries(it.name, it.id) },
|
||||
onMobi = { },
|
||||
onEpub = { },
|
||||
onSend = {
|
||||
scope.launch {
|
||||
send(
|
||||
|
|
|
|||
|
|
@ -89,10 +89,9 @@ data class BookDetailUio(
|
|||
fun DetailScreenContent(
|
||||
modifier: Modifier = Modifier,
|
||||
book: BookDetailUio,
|
||||
onOpenOnBibLib: () -> Unit,
|
||||
onAuthor: (BookDetailUio.AuthorUio) -> Unit,
|
||||
onSeries: (BookDetailUio.SeriesUio) -> Unit,
|
||||
onMobi: () -> Unit,
|
||||
onEpub: () -> Unit,
|
||||
onSend: () -> Unit,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
|
|
@ -110,16 +109,29 @@ fun DetailScreenContent(
|
|||
.systemBarsPadding(),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
GlideImage(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp)
|
||||
.height(MaterialTheme.bibLib.dimen.detail.cover),
|
||||
previewPlaceholder = R.drawable.ic_fondatoin_cover,
|
||||
circularReveal = CircularReveal(duration = 1000),
|
||||
contentScale = ContentScale.FillHeight,
|
||||
imageModel = book.cover,
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
GlideImage(
|
||||
modifier = Modifier.height(MaterialTheme.bibLib.dimen.detail.cover),
|
||||
previewPlaceholder = R.drawable.ic_fondatoin_cover,
|
||||
circularReveal = CircularReveal(duration = 1000),
|
||||
contentScale = ContentScale.FillHeight,
|
||||
imageModel = book.cover,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.clickable(onClick = onOpenOnBibLib)
|
||||
.padding(
|
||||
horizontal = 8.dp,
|
||||
vertical = 2.dp,
|
||||
),
|
||||
style = MaterialTheme.bibLib.typography.base.caption,
|
||||
color = MaterialTheme.bibLib.colors.typography.emphasis,
|
||||
text = stringResource(id = R.string.detail_open_on_biblib)
|
||||
)
|
||||
}
|
||||
|
||||
AnimatedOffset {
|
||||
Column(
|
||||
|
|
@ -263,10 +275,9 @@ private fun DetailScreenContentPreview() {
|
|||
.verticalScroll(state = rememberScrollState())
|
||||
.padding(all = 16.dp),
|
||||
book = BookDetailUio.preview(),
|
||||
onOpenOnBibLib = { },
|
||||
onAuthor = { },
|
||||
onSeries = { },
|
||||
onMobi = { },
|
||||
onEpub = { },
|
||||
onSend = { },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import com.pixelized.biblib.utils.extention.bibLib
|
|||
@Stable
|
||||
@Immutable
|
||||
data class OptionsUio(
|
||||
val sorting: Boolean,
|
||||
val sorting: Boolean = false,
|
||||
val micro: Boolean,
|
||||
val small: Boolean,
|
||||
val large: Boolean,
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
package com.pixelized.biblib.ui.screen.home.options
|
||||
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class OptionsViewModel @Inject constructor() : ViewModel() {
|
||||
private val _options = mutableStateOf(
|
||||
OptionsUio(sorting = false, micro = true, small = false, large = false)
|
||||
)
|
||||
val options: State<OptionsUio> = _options
|
||||
|
||||
fun onMicro() {
|
||||
_options.value = OptionsUio(false, true, false, false)
|
||||
}
|
||||
|
||||
fun onSmall() {
|
||||
_options.value = OptionsUio(false, false, true, false)
|
||||
}
|
||||
|
||||
fun onLarge() {
|
||||
_options.value = OptionsUio(false, false, false, true)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,9 +4,7 @@ import androidx.annotation.StringDef
|
|||
import com.pixelized.biblib.model.book.Book
|
||||
import com.pixelized.biblib.model.book.Series
|
||||
import com.pixelized.biblib.network.client.IBibLibClient
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.LargeBookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.MicroBookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.SmallBookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.common.item.BookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.detail.BookDetailUio
|
||||
|
||||
|
||||
|
|
@ -17,34 +15,19 @@ import com.pixelized.biblib.ui.screen.home.detail.BookDetailUio
|
|||
)
|
||||
annotation class CoverUrl
|
||||
|
||||
fun Book.toMicroThumbnailUio(
|
||||
@CoverUrl coverBaseUrl: String = IBibLibClient.THUMBNAIL_URL
|
||||
) = MicroBookThumbnailUio(
|
||||
fun Book.toThumbnailUio(
|
||||
@CoverUrl coverBaseUrl: String = IBibLibClient.COVER_URL,
|
||||
@CoverUrl thumbnailBaseUrl: String = IBibLibClient.THUMBNAIL_URL
|
||||
) = BookThumbnailUio(
|
||||
id = id,
|
||||
cover = "${coverBaseUrl}/$id.jpg",
|
||||
title = title,
|
||||
author = author.joinToString { it.name },
|
||||
series = series?.let { toLabel(it) } ?: "",
|
||||
isNew = isNew,
|
||||
)
|
||||
|
||||
fun Book.toSmallThumbnailUio(
|
||||
@CoverUrl coverBaseUrl: String = IBibLibClient.THUMBNAIL_URL
|
||||
) = SmallBookThumbnailUio(
|
||||
id = id,
|
||||
genre = genre?.joinToString { it.name } ?: "",
|
||||
title = title,
|
||||
author = author.joinToString { it.name },
|
||||
date = releaseDate.longDate(),
|
||||
isNew = isNew,
|
||||
cover = "${coverBaseUrl}/$id.jpg",
|
||||
)
|
||||
|
||||
fun Book.toLargeBookThumbnailUio(
|
||||
@CoverUrl coverBaseUrl: String = IBibLibClient.COVER_URL
|
||||
) = LargeBookThumbnailUio(
|
||||
id = id,
|
||||
language = language?.displayLanguage?.capitalize() ?: "",
|
||||
date = releaseDate.year(),
|
||||
isNew = isNew,
|
||||
thumbnail = "${thumbnailBaseUrl}/$id.jpg",
|
||||
cover = "${coverBaseUrl}/$id.jpg",
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import java.text.Format
|
|||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
fun Date.longDate(
|
||||
fun Date.year(
|
||||
default: String? = null,
|
||||
formatter: Format = SimpleDateFormat("MMMM yyyy", Locale.getDefault()),
|
||||
formatter: Format = SimpleDateFormat("yyyy", Locale.getDefault()),
|
||||
): String? = format(
|
||||
default = default,
|
||||
formatter = formatter
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
<string name="authentication_password">Mot de passe</string>
|
||||
<string name="authentication_credential_remember">Mémoriser mes identifiants</string>
|
||||
|
||||
<string name="detail_open_on_biblib">ouvrir sur bib.bibulle.fr</string>
|
||||
<string name="detail_rating">Note</string>
|
||||
<string name="detail_language">Langue</string>
|
||||
<string name="detail_release">Publication</string>
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@
|
|||
|
||||
<string name="list_is_new" translatable="false">New</string>
|
||||
|
||||
<string name="detail_open_on_biblib">open on bib.bibulle.fr</string>
|
||||
<string name="detail_open_on_biblib_url" translatable="false">https://bib.bibulle.fr/book/%1$s</string>
|
||||
<string name="detail_rating">Rating</string>
|
||||
<string name="detail_language">Language</string>
|
||||
<string name="detail_release">Release</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue