Add back the detail page linked to the API.
This commit is contained in:
parent
d2acbf8d18
commit
90d6c4bd65
6 changed files with 53 additions and 10 deletions
|
|
@ -12,6 +12,8 @@ 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.livedata.observeAsState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
|
@ -23,16 +25,30 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.pixelized.biblib.R
|
import com.pixelized.biblib.R
|
||||||
import com.pixelized.biblib.ui.composable.items.Image
|
import com.pixelized.biblib.ui.composable.items.Image
|
||||||
import com.pixelized.biblib.ui.data.BookUio
|
import com.pixelized.biblib.ui.data.BookUio
|
||||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||||
import com.pixelized.biblib.ui.theme.Teal200
|
import com.pixelized.biblib.ui.theme.Teal200
|
||||||
|
import com.pixelized.biblib.ui.viewmodel.book.BooksViewModel
|
||||||
|
import com.pixelized.biblib.ui.viewmodel.book.IBooksViewModel
|
||||||
import com.pixelized.biblib.utils.BitmapCache
|
import com.pixelized.biblib.utils.BitmapCache
|
||||||
import com.pixelized.biblib.utils.injection.Bob
|
import com.pixelized.biblib.utils.injection.Bob
|
||||||
import com.pixelized.biblib.utils.mock.BookMock
|
import com.pixelized.biblib.utils.mock.BookMock
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DetailPageComposable(
|
||||||
|
booksViewModel: IBooksViewModel = viewModel<BooksViewModel>(),
|
||||||
|
bookId: Int
|
||||||
|
) {
|
||||||
|
val book by booksViewModel.getBookDetail(bookId).observeAsState()
|
||||||
|
book?.let {
|
||||||
|
DetailPageComposable(book = it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DetailPageComposable(book: BookUio) {
|
fun DetailPageComposable(book: BookUio) {
|
||||||
val typography = MaterialTheme.typography
|
val typography = MaterialTheme.typography
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package com.pixelized.biblib.ui.composable.pages
|
package com.pixelized.biblib.ui.composable.pages
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
|
@ -18,7 +17,7 @@ import com.pixelized.biblib.ui.data.BookThumbnailUio
|
||||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||||
import com.pixelized.biblib.ui.viewmodel.book.IBooksViewModel
|
import com.pixelized.biblib.ui.viewmodel.book.IBooksViewModel
|
||||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel
|
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel
|
||||||
|
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Navigable.Page
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -35,7 +34,8 @@ fun HomePageComposable(
|
||||||
navigationViewModel: INavigationViewModel,
|
navigationViewModel: INavigationViewModel,
|
||||||
booksViewModel: IBooksViewModel
|
booksViewModel: IBooksViewModel
|
||||||
) {
|
) {
|
||||||
val lazyBooks: LazyPagingItems<BookThumbnailUio> = booksViewModel.books.collectAsLazyPagingItems()
|
val lazyBooks: LazyPagingItems<BookThumbnailUio> =
|
||||||
|
booksViewModel.books.collectAsLazyPagingItems()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = PaddingValues(16.dp),
|
contentPadding = PaddingValues(16.dp),
|
||||||
|
|
@ -48,9 +48,7 @@ fun HomePageComposable(
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.wrapContentHeight(),
|
.wrapContentHeight(),
|
||||||
) { item ->
|
) { item ->
|
||||||
// TODO:
|
navigationViewModel.navigateTo(Page.Detail(item.id))
|
||||||
// val bookMock = BookMock().let { it.books[item.id] ?: it.book }
|
|
||||||
// navigation.navigateTo(INavigation.Page.Detail(bookMock))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ fun MainScreenComposable(
|
||||||
val page by navigationViewModel.page.observeAsState()
|
val page by navigationViewModel.page.observeAsState()
|
||||||
|
|
||||||
LaunchedEffect(key1 = "MainScreen", block = {
|
LaunchedEffect(key1 = "MainScreen", block = {
|
||||||
navigationViewModel.navigateTo(Page.HomePage)
|
navigationViewModel.navigateTo(Page.HomePage, true)
|
||||||
})
|
})
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
|
|
@ -76,10 +76,10 @@ fun MainScreenComposable(
|
||||||
enter = slideInHorizontally(initialOffsetX = { width -> width }),
|
enter = slideInHorizontally(initialOffsetX = { width -> width }),
|
||||||
exit = slideOutHorizontally(targetOffsetX = { width -> width }),
|
exit = slideOutHorizontally(targetOffsetX = { width -> width }),
|
||||||
) {
|
) {
|
||||||
// small trick to display the detail page during animation exit.
|
// Small trick to display the detail page during animation exit.
|
||||||
var currentPage by remember { mutableStateOf<Page.Detail?>(null) }
|
var currentPage by remember { mutableStateOf<Page.Detail?>(null) }
|
||||||
currentPage = page as? Page.Detail ?: currentPage
|
currentPage = page as? Page.Detail ?: currentPage
|
||||||
currentPage?.let { DetailPageComposable(it.book) }
|
currentPage?.let { DetailPageComposable(booksViewModel, it.bookId) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,12 @@ import com.pixelized.biblib.network.factory.BookFactory
|
||||||
import com.pixelized.biblib.repository.apiCache.IAPICacheRepository
|
import com.pixelized.biblib.repository.apiCache.IAPICacheRepository
|
||||||
import com.pixelized.biblib.repository.book.IBookRepository
|
import com.pixelized.biblib.repository.book.IBookRepository
|
||||||
import com.pixelized.biblib.ui.data.BookThumbnailUio
|
import com.pixelized.biblib.ui.data.BookThumbnailUio
|
||||||
|
import com.pixelized.biblib.ui.data.BookUio
|
||||||
import com.pixelized.biblib.utils.injection.inject
|
import com.pixelized.biblib.utils.injection.inject
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class BooksViewModel : ViewModel(), IBooksViewModel {
|
class BooksViewModel : ViewModel(), IBooksViewModel {
|
||||||
private val bookRepository: IBookRepository by inject()
|
private val bookRepository: IBookRepository by inject()
|
||||||
|
|
@ -51,6 +53,17 @@ class BooksViewModel : ViewModel(), IBooksViewModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getBookDetail(id: Int): LiveData<BookUio> {
|
||||||
|
val data = MutableLiveData<BookUio>()
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
val factory = BookFactory()
|
||||||
|
val response = client.service.detail(id)
|
||||||
|
val book = factory.fromDetailResponseToBook(response)
|
||||||
|
data.postValue(book.toUio())
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun loadNewBooks(): Boolean {
|
private suspend fun loadNewBooks(): Boolean {
|
||||||
val cached = apiCache.new
|
val cached = apiCache.new
|
||||||
val updated = client.service.new()
|
val updated = client.service.new()
|
||||||
|
|
@ -79,4 +92,16 @@ class BooksViewModel : ViewModel(), IBooksViewModel {
|
||||||
date = releaseDate.toString(),
|
date = releaseDate.toString(),
|
||||||
series = series?.name,
|
series = series?.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun Book.toUio() = BookUio(
|
||||||
|
id = id,
|
||||||
|
title = title,
|
||||||
|
author = author.joinToString { it.name },
|
||||||
|
genre = genre?.joinToString { it.name } ?: "",
|
||||||
|
rating = rating?.toFloat() ?: 0.0f,
|
||||||
|
language = language?.code?.let { Locale(it).language } ?: "",
|
||||||
|
date = releaseDate.toString(),
|
||||||
|
series = series?.name,
|
||||||
|
description = synopsis ?: "",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.paging.PagingData
|
import androidx.paging.PagingData
|
||||||
import com.pixelized.biblib.ui.data.BookThumbnailUio
|
import com.pixelized.biblib.ui.data.BookThumbnailUio
|
||||||
|
import com.pixelized.biblib.ui.data.BookUio
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
|
||||||
|
|
@ -14,6 +15,8 @@ interface IBooksViewModel {
|
||||||
|
|
||||||
fun updateBooks()
|
fun updateBooks()
|
||||||
|
|
||||||
|
fun getBookDetail(id: Int): LiveData<BookUio>
|
||||||
|
|
||||||
sealed class State {
|
sealed class State {
|
||||||
object Initial : State()
|
object Initial : State()
|
||||||
object Loading : State()
|
object Loading : State()
|
||||||
|
|
@ -28,5 +31,6 @@ interface IBooksViewModel {
|
||||||
get() = flowOf()
|
get() = flowOf()
|
||||||
|
|
||||||
override fun updateBooks() = Unit
|
override fun updateBooks() = Unit
|
||||||
|
override fun getBookDetail(id: Int) = MutableLiveData<BookUio>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -20,7 +20,7 @@ interface INavigationViewModel {
|
||||||
|
|
||||||
sealed class Page : Navigable() {
|
sealed class Page : Navigable() {
|
||||||
object HomePage : Page()
|
object HomePage : Page()
|
||||||
data class Detail(val book: BookUio) : Page()
|
data class Detail(val bookId: Int) : Page()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue