What's new UI/UX modification.
This commit is contained in:
parent
0506953d34
commit
142957d490
12 changed files with 433 additions and 244 deletions
|
|
@ -1,10 +1,7 @@
|
|||
package com.pixelized.biblib.ui.screen.home
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.ScrollableTabRow
|
||||
import androidx.compose.material.Tab
|
||||
|
|
@ -20,6 +17,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||
import com.google.accompanist.pager.HorizontalPager
|
||||
import com.google.accompanist.pager.PagerState
|
||||
import com.google.accompanist.pager.rememberPagerState
|
||||
import com.pixelized.biblib.ui.composable.Search
|
||||
import com.pixelized.biblib.ui.scaffold.BottomDetailScaffold
|
||||
|
|
@ -32,6 +30,7 @@ import com.pixelized.biblib.ui.screen.home.page.news.NewsPage
|
|||
import com.pixelized.biblib.ui.screen.profile.ProfileScreen
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
import com.pixelized.biblib.utils.extention.bibLib
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
|
|
@ -96,24 +95,22 @@ fun HomeScreen(
|
|||
fun HomeScreenContent(
|
||||
pages: List<Page> = Page.all
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val pagerState = rememberPagerState()
|
||||
val scope: CoroutineScope = rememberCoroutineScope()
|
||||
val pagerState: PagerState = rememberPagerState()
|
||||
|
||||
Column {
|
||||
Column(modifier = Modifier.navigationBarsPadding()) {
|
||||
ScrollableTabRow(
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
edgePadding = MaterialTheme.bibLib.dimen.dp16,
|
||||
) {
|
||||
// Add tabs for all of our pages
|
||||
pages.forEachIndexed { index, page ->
|
||||
Tab(
|
||||
text = { Text(text = stringResource(id = page.label)) },
|
||||
selected = pagerState.currentPage == index,
|
||||
text = { Text(text = stringResource(id = page.label)) },
|
||||
onClick = { scope.launch { pagerState.animateScrollToPage(index) } },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
count = pages.size
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
package com.pixelized.biblib.ui.screen.home.common.composable
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.expandVertically
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.sizeIn
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.CloudOff
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.pixelized.biblib.R
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
import com.pixelized.biblib.utils.extention.bibLib
|
||||
|
||||
@Composable
|
||||
fun ConnectivityHeader(
|
||||
modifier: Modifier = Modifier,
|
||||
isNetworkAvailable: () -> State<Boolean>
|
||||
) {
|
||||
val showHideHeader by isNetworkAvailable()
|
||||
AnimatedVisibility(
|
||||
visible = showHideHeader.not(),
|
||||
enter = expandVertically(),
|
||||
exit = shrinkVertically(),
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.background(color = MaterialTheme.colors.error)
|
||||
.fillMaxWidth()
|
||||
.sizeIn(minHeight = ButtonDefaults.MinHeight)
|
||||
.padding(
|
||||
horizontal = MaterialTheme.bibLib.dimen.thumbnail.padding,
|
||||
vertical = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.padding(end = MaterialTheme.bibLib.dimen.dp8),
|
||||
imageVector = Icons.Default.CloudOff,
|
||||
tint = MaterialTheme.colors.onError,
|
||||
contentDescription = null
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.caption,
|
||||
color = MaterialTheme.colors.onError,
|
||||
text = stringResource(id = R.string.error_offline),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun ConnectivityHeaderPreview() {
|
||||
BibLibTheme {
|
||||
val isNetworkAvailable = remember { mutableStateOf(false) }
|
||||
ConnectivityHeader(
|
||||
isNetworkAvailable = { isNetworkAvailable }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
package com.pixelized.biblib.ui.screen.home.common.composable
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.expandVertically
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.CloudOff
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.paging.PagingData
|
||||
import androidx.paging.compose.LazyPagingItems
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import androidx.paging.compose.items
|
||||
import com.pixelized.biblib.R
|
||||
import com.pixelized.biblib.ui.screen.home.common.uio.BookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
import com.pixelized.biblib.utils.extention.bibLib
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun LazyBookThumbnailColumn(
|
||||
modifier: Modifier = Modifier,
|
||||
verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(MaterialTheme.bibLib.dimen.dp16),
|
||||
contentPadding: PaddingValues = PaddingValues(),
|
||||
state: LazyListState = rememberLazyListState(),
|
||||
isNetworkAvailable: () -> State<Boolean>,
|
||||
books: LazyPagingItems<BookThumbnailUio>,
|
||||
onItemClick: (BookThumbnailUio) -> Unit = {},
|
||||
) {
|
||||
val currentOnItemClick by rememberUpdatedState(newValue = onItemClick)
|
||||
LazyColumn(
|
||||
modifier = modifier,
|
||||
verticalArrangement = verticalArrangement,
|
||||
contentPadding = contentPadding,
|
||||
state = state,
|
||||
) {
|
||||
stickyHeader {
|
||||
ConnectivityHeader(
|
||||
isNetworkAvailable = isNetworkAvailable,
|
||||
)
|
||||
}
|
||||
items(
|
||||
items = books,
|
||||
key = { it.id },
|
||||
) { thumbnail ->
|
||||
BookThumbnail(
|
||||
modifier = Modifier.padding(horizontal = MaterialTheme.bibLib.dimen.thumbnail.padding),
|
||||
thumbnail = thumbnail,
|
||||
onClick = currentOnItemClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ConnectivityHeader(
|
||||
modifier : Modifier = Modifier,
|
||||
isNetworkAvailable: () -> State<Boolean>
|
||||
) {
|
||||
val showHideHeader by isNetworkAvailable()
|
||||
AnimatedVisibility(
|
||||
visible = showHideHeader.not(),
|
||||
enter = expandVertically(),
|
||||
exit = shrinkVertically(),
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.background(color = MaterialTheme.colors.error)
|
||||
.fillMaxWidth()
|
||||
.sizeIn(minHeight = ButtonDefaults.MinHeight)
|
||||
.padding(
|
||||
horizontal = MaterialTheme.bibLib.dimen.thumbnail.padding,
|
||||
vertical = MaterialTheme.bibLib.dimen.thumbnail.arrangement,
|
||||
),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.padding(end = MaterialTheme.bibLib.dimen.dp8),
|
||||
imageVector = Icons.Default.CloudOff,
|
||||
tint = MaterialTheme.colors.onError,
|
||||
contentDescription = null
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.caption,
|
||||
color = MaterialTheme.colors.onError,
|
||||
text = stringResource(id = R.string.error_offline),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun LazyBookThumbnailColumnPreview() {
|
||||
val isNetworkAvailable = remember { mutableStateOf(false) }
|
||||
BibLibTheme {
|
||||
LazyBookThumbnailColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
isNetworkAvailable = { isNetworkAvailable },
|
||||
books = previewResources(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun previewResources(): LazyPagingItems<BookThumbnailUio> {
|
||||
val cover = CoverUio(
|
||||
type = CoverUio.Type.PLACE_HOLDER,
|
||||
painter = painterResource(id = R.drawable.ic_baseline_auto_stories_24),
|
||||
contentScale = ContentScale.None,
|
||||
)
|
||||
val thumbnails = listOf(
|
||||
BookThumbnailUio(
|
||||
id = 112,
|
||||
title = "Prélude à Fondation",
|
||||
author = "Asimov",
|
||||
date = "1988",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 78,
|
||||
title = "L'Aube de Fondation",
|
||||
author = "Asimov",
|
||||
date = "1993",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 90,
|
||||
title = "Fondation",
|
||||
author = "Asimov",
|
||||
date = "1951",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 184,
|
||||
title = "Fondation et Empire",
|
||||
author = "Asimov",
|
||||
date = "1952",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 185,
|
||||
title = "Seconde Fondation",
|
||||
author = "Asimov",
|
||||
date = "1953",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 119,
|
||||
title = "Fondation foudroyée",
|
||||
author = "Asimov",
|
||||
date = "1982",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 163,
|
||||
title = "Terre et Fondation",
|
||||
author = "Asimov",
|
||||
date = "1986",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
)
|
||||
return flowOf(PagingData.from(thumbnails)).collectAsLazyPagingItems()
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package com.pixelized.biblib.ui.screen.home.common.composable
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.paging.PagingData
|
||||
import androidx.paging.compose.LazyPagingItems
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.pixelized.biblib.R
|
||||
import com.pixelized.biblib.ui.screen.home.common.uio.BookThumbnailUio
|
||||
|
||||
import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
||||
@Composable
|
||||
fun bookPreviewResources(): LazyPagingItems<BookThumbnailUio> {
|
||||
val cover = CoverUio(
|
||||
type = CoverUio.Type.PLACE_HOLDER,
|
||||
painter = painterResource(id = R.drawable.ic_baseline_auto_stories_24),
|
||||
contentScale = ContentScale.None,
|
||||
)
|
||||
val thumbnails = listOf(
|
||||
BookThumbnailUio(
|
||||
id = 112,
|
||||
title = "Prélude à Fondation",
|
||||
author = "Asimov",
|
||||
date = "1988",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 78,
|
||||
title = "L'Aube de Fondation",
|
||||
author = "Asimov",
|
||||
date = "1993",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 90,
|
||||
title = "Fondation",
|
||||
author = "Asimov",
|
||||
date = "1951",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 184,
|
||||
title = "Fondation et Empire",
|
||||
author = "Asimov",
|
||||
date = "1952",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 185,
|
||||
title = "Seconde Fondation",
|
||||
author = "Asimov",
|
||||
date = "1953",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 119,
|
||||
title = "Fondation foudroyée",
|
||||
author = "Asimov",
|
||||
date = "1982",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
BookThumbnailUio(
|
||||
id = 163,
|
||||
title = "Terre et Fondation",
|
||||
author = "Asimov",
|
||||
date = "1986",
|
||||
genre = "Sci-Fi",
|
||||
isNew = false,
|
||||
cover = remember { mutableStateOf(cover) },
|
||||
),
|
||||
)
|
||||
return flowOf(PagingData.from(thumbnails)).collectAsLazyPagingItems()
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.pixelized.biblib.ui.screen.home.common.composable
|
||||
package com.pixelized.biblib.ui.screen.home.page.books
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.*
|
||||
|
|
@ -1,41 +1,86 @@
|
|||
package com.pixelized.biblib.ui.screen.home.page.books
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.paging.compose.LazyPagingItems
|
||||
import androidx.paging.compose.items
|
||||
import com.pixelized.biblib.ui.scaffold.LocalBottomDetailState
|
||||
import com.pixelized.biblib.ui.screen.connectivity.ConnectivityViewModel
|
||||
import com.pixelized.biblib.ui.screen.home.common.composable.LazyBookThumbnailColumn
|
||||
import com.pixelized.biblib.ui.screen.home.page.news.NewsPage
|
||||
import com.pixelized.biblib.ui.screen.home.common.composable.ConnectivityHeader
|
||||
import com.pixelized.biblib.ui.screen.home.common.composable.bookPreviewResources
|
||||
import com.pixelized.biblib.ui.screen.home.common.uio.BookThumbnailUio
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
import com.pixelized.biblib.utils.extention.bibLib
|
||||
|
||||
|
||||
@Composable
|
||||
fun BooksPage(
|
||||
connectivityViewModel: ConnectivityViewModel = hiltViewModel(),
|
||||
booksViewModel: BooksViewModel = hiltViewModel()
|
||||
newsViewModel: BooksViewModel = hiltViewModel()
|
||||
) {
|
||||
val books = newsViewModel.books
|
||||
|
||||
BooksPageContent(
|
||||
isNetworkAvailable = { connectivityViewModel.isNetworkAvailable },
|
||||
books = books,
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
private fun BooksPageContent(
|
||||
isNetworkAvailable: () -> State<Boolean>,
|
||||
books: LazyPagingItems<BookThumbnailUio>,
|
||||
) {
|
||||
val bottomDetailState = LocalBottomDetailState.current
|
||||
|
||||
LazyBookThumbnailColumn(
|
||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.bibLib.dimen.thumbnail.arrangement),
|
||||
isNetworkAvailable = { connectivityViewModel.isNetworkAvailable },
|
||||
books = booksViewModel.books,
|
||||
onItemClick = {
|
||||
bottomDetailState.expandBookDetail(id = it.id)
|
||||
},
|
||||
)
|
||||
Column {
|
||||
ConnectivityHeader(
|
||||
isNetworkAvailable = isNetworkAvailable,
|
||||
)
|
||||
LazyColumn(
|
||||
contentPadding = PaddingValues(vertical = MaterialTheme.bibLib.dimen.thumbnail.padding),
|
||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.bibLib.dimen.thumbnail.arrangement),
|
||||
) {
|
||||
items(
|
||||
items = books,
|
||||
key = { it.id },
|
||||
) { thumbnail ->
|
||||
BookThumbnail(
|
||||
modifier = Modifier.padding(horizontal = MaterialTheme.bibLib.dimen.thumbnail.padding),
|
||||
thumbnail = thumbnail,
|
||||
onClick = {
|
||||
bottomDetailState.expandBookDetail(id = it.id)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun BooksPagePreview() {
|
||||
val isNetworkAvailable = remember { mutableStateOf(false) }
|
||||
BibLibTheme {
|
||||
Column {
|
||||
NewsPage()
|
||||
BooksPageContent(
|
||||
isNetworkAvailable = { isNetworkAvailable },
|
||||
books = bookPreviewResources()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
package com.pixelized.biblib.ui.screen.home.page.news
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.biblib.R
|
||||
import com.pixelized.biblib.ui.screen.home.common.uio.BookThumbnailUio
|
||||
import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
import com.pixelized.biblib.utils.extention.bibLib
|
||||
|
||||
@Composable
|
||||
fun NewThumbnail(
|
||||
modifier: Modifier = Modifier,
|
||||
thumbnail: BookThumbnailUio?,
|
||||
onClick: (BookThumbnailUio) -> Unit = { },
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.clickable { thumbnail?.let(onClick) }
|
||||
) {
|
||||
thumbnail?.cover?.let { it ->
|
||||
Cover(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(MaterialTheme.bibLib.shape.base.medium)
|
||||
.aspectRatio(64f / 102f),
|
||||
image = it,
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
style = MaterialTheme.typography.body1,
|
||||
color = MaterialTheme.colors.onSurface,
|
||||
text = thumbnail?.title ?: "",
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
Text(
|
||||
style = MaterialTheme.typography.caption,
|
||||
color = MaterialTheme.colors.onSurface,
|
||||
text = thumbnail?.author ?: ""
|
||||
)
|
||||
|
||||
Text(
|
||||
style = MaterialTheme.typography.caption,
|
||||
color = MaterialTheme.colors.onSurface,
|
||||
text = thumbnail?.date ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalAnimationApi::class)
|
||||
@Composable
|
||||
private fun Cover(
|
||||
modifier: Modifier = Modifier,
|
||||
image: State<CoverUio>
|
||||
) {
|
||||
val cover by image
|
||||
AnimatedContent(
|
||||
targetState = cover.painter,
|
||||
transitionSpec = { fadeIn() with fadeOut() }
|
||||
) {
|
||||
Image(
|
||||
modifier = modifier,
|
||||
alignment = Alignment.Center,
|
||||
contentScale = cover.contentScale,
|
||||
colorFilter = cover.colorFilter,
|
||||
painter = cover.painter,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun BookThumbnailPreview() {
|
||||
val painter = painterResource(id = R.drawable.ic_baseline_auto_stories_24)
|
||||
val thumbnail = BookThumbnailUio(
|
||||
id = 0,
|
||||
genre = "Sci-Fi",
|
||||
title = "Foundation",
|
||||
author = "Asimov",
|
||||
date = "1951",
|
||||
isNew = false,
|
||||
cover = remember {
|
||||
mutableStateOf(
|
||||
CoverUio(
|
||||
type = CoverUio.Type.PLACE_HOLDER,
|
||||
contentScale = ContentScale.None,
|
||||
painter = painter,
|
||||
)
|
||||
)
|
||||
},
|
||||
)
|
||||
BibLibTheme {
|
||||
NewThumbnail(
|
||||
modifier = Modifier.width(200.dp),
|
||||
thumbnail = thumbnail,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.pixelized.biblib.ui.screen.home.page.news
|
|||
|
||||
import android.app.Application
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
|
|
@ -41,14 +42,8 @@ class NewsBookViewModel @Inject constructor(
|
|||
|
||||
val news @Composable get() = newsSource.collectAsLazyPagingItems()
|
||||
|
||||
private fun Book.toThumbnail() = BookThumbnailUio(
|
||||
id = id,
|
||||
genre = genre?.joinToString { it.name } ?: "",
|
||||
title = title,
|
||||
author = author.joinToString { it.name },
|
||||
date = releaseDate.longDate(),
|
||||
isNew = isNew,
|
||||
cover = cover(
|
||||
private fun Book.toThumbnail() : BookThumbnailUio{
|
||||
val thumbnail by cover(
|
||||
placeHolder = CoverUio(
|
||||
type = CoverUio.Type.PLACE_HOLDER,
|
||||
contentScale = ContentScale.None,
|
||||
|
|
@ -57,5 +52,18 @@ class NewsBookViewModel @Inject constructor(
|
|||
type = CoverUio.Type.THUMBNAIL,
|
||||
url = URL("${IBibLibClient.THUMBNAIL_URL}/$id.jpg"),
|
||||
)
|
||||
)
|
||||
return BookThumbnailUio(
|
||||
id = id,
|
||||
genre = genre?.joinToString { it.name } ?: "",
|
||||
title = title,
|
||||
author = author.joinToString { it.name },
|
||||
date = releaseDate.longDate(),
|
||||
isNew = isNew,
|
||||
cover = cover(
|
||||
placeHolder = thumbnail,
|
||||
type = CoverUio.Type.DETAIL,
|
||||
url = URL("${IBibLibClient.COVER_URL}/$id.jpg"),
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +1,93 @@
|
|||
package com.pixelized.biblib.ui.screen.home.page.news
|
||||
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyItemScope
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.paging.compose.LazyPagingItems
|
||||
import androidx.paging.compose.items
|
||||
import com.pixelized.biblib.ui.scaffold.BottomDetailState
|
||||
import com.pixelized.biblib.ui.scaffold.LocalBottomDetailState
|
||||
import com.pixelized.biblib.ui.screen.connectivity.ConnectivityViewModel
|
||||
import com.pixelized.biblib.ui.screen.home.common.composable.LazyBookThumbnailColumn
|
||||
import com.pixelized.biblib.ui.screen.home.common.composable.ConnectivityHeader
|
||||
import com.pixelized.biblib.ui.screen.home.common.composable.bookPreviewResources
|
||||
import com.pixelized.biblib.ui.screen.home.common.uio.BookThumbnailUio
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
import com.pixelized.biblib.utils.extention.bibLib
|
||||
import java.util.*
|
||||
|
||||
@Composable
|
||||
fun NewsPage(
|
||||
connectivityViewModel: ConnectivityViewModel = hiltViewModel(),
|
||||
booksViewModel: NewsBookViewModel = hiltViewModel()
|
||||
) {
|
||||
val bottomDetail = LocalBottomDetailState.current
|
||||
val books = booksViewModel.news
|
||||
|
||||
LazyBookThumbnailColumn(
|
||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.bibLib.dimen.thumbnail.arrangement),
|
||||
NewsPageContent(
|
||||
isNetworkAvailable = { connectivityViewModel.isNetworkAvailable },
|
||||
books = booksViewModel.news,
|
||||
onItemClick = {
|
||||
bottomDetail.expandBookDetail(id = it.id)
|
||||
},
|
||||
books = books,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun NewPagePreview() {
|
||||
BibLibTheme {
|
||||
Column {
|
||||
NewsPage()
|
||||
private fun NewsPageContent(
|
||||
isNetworkAvailable: () -> State<Boolean>,
|
||||
books: LazyPagingItems<BookThumbnailUio>,
|
||||
) {
|
||||
val bottomDetailState: BottomDetailState = LocalBottomDetailState.current
|
||||
|
||||
Column {
|
||||
ConnectivityHeader(
|
||||
isNetworkAvailable = isNetworkAvailable,
|
||||
)
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(2),
|
||||
contentPadding = PaddingValues(all = MaterialTheme.bibLib.dimen.thumbnail.padding),
|
||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.bibLib.dimen.thumbnail.arrangement),
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.bibLib.dimen.thumbnail.arrangement)
|
||||
) {
|
||||
items(
|
||||
count = books.itemCount
|
||||
) { index ->
|
||||
NewThumbnail(
|
||||
thumbnail = books[index],
|
||||
onClick = {
|
||||
bottomDetailState.expandBookDetail(id = it.id)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_NO)
|
||||
@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_YES)
|
||||
private fun NewPagePreview() {
|
||||
val isNetworkAvailable = remember { mutableStateOf(false) }
|
||||
BibLibTheme {
|
||||
Column {
|
||||
NewsPageContent(
|
||||
isNetworkAvailable = { isNetworkAvailable },
|
||||
books = bookPreviewResources()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ data class BibLibDimen(
|
|||
@Immutable
|
||||
data class BookThumbnail(
|
||||
val padding: Dp = 16.dp,
|
||||
val arrangement: Dp = 8.dp,
|
||||
val arrangement: Dp = 16.dp,
|
||||
val cover: DpSize = DpSize(64.dp, 102.dp), // ratio 1.6
|
||||
val corner: Dp = 8.dp,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
<!-- Bottom bar -->
|
||||
|
||||
<string name="menu_new">Nouveautés</string>
|
||||
<string name="menu_book">Library</string>
|
||||
<string name="menu_book">Librarie</string>
|
||||
<string name="menu_series">Séries</string>
|
||||
<string name="menu_author">Auteurs</string>
|
||||
<string name="menu_tag">Étiquettes</string>
|
||||
<string name="menu_tag">Genres</string>
|
||||
|
||||
<!-- Dialogs -->
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<string name="menu_book">Library</string>
|
||||
<string name="menu_series">Series</string>
|
||||
<string name="menu_author">Authors</string>
|
||||
<string name="menu_tag">Tags</string>
|
||||
<string name="menu_tag">Genres</string>
|
||||
|
||||
<!-- Dialogs -->
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue