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.Send
 | 
			
		||||
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.Modifier
 | 
			
		||||
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.tooling.preview.Preview
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import androidx.lifecycle.viewmodel.compose.viewModel
 | 
			
		||||
import com.pixelized.biblib.R
 | 
			
		||||
import com.pixelized.biblib.ui.composable.items.Image
 | 
			
		||||
import com.pixelized.biblib.ui.data.BookUio
 | 
			
		||||
import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
			
		||||
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.injection.Bob
 | 
			
		||||
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
 | 
			
		||||
fun DetailPageComposable(book: BookUio) {
 | 
			
		||||
    val typography = MaterialTheme.typography
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,5 @@
 | 
			
		|||
package com.pixelized.biblib.ui.composable.pages
 | 
			
		||||
 | 
			
		||||
import android.util.Log
 | 
			
		||||
import androidx.compose.foundation.layout.Arrangement
 | 
			
		||||
import androidx.compose.foundation.layout.PaddingValues
 | 
			
		||||
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.viewmodel.book.IBooksViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel
 | 
			
		||||
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Navigable.Page
 | 
			
		||||
 | 
			
		||||
@Preview
 | 
			
		||||
@Composable
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +34,8 @@ fun HomePageComposable(
 | 
			
		|||
    navigationViewModel: INavigationViewModel,
 | 
			
		||||
    booksViewModel: IBooksViewModel
 | 
			
		||||
) {
 | 
			
		||||
    val lazyBooks: LazyPagingItems<BookThumbnailUio> = booksViewModel.books.collectAsLazyPagingItems()
 | 
			
		||||
    val lazyBooks: LazyPagingItems<BookThumbnailUio> =
 | 
			
		||||
        booksViewModel.books.collectAsLazyPagingItems()
 | 
			
		||||
 | 
			
		||||
    LazyColumn(
 | 
			
		||||
        contentPadding = PaddingValues(16.dp),
 | 
			
		||||
| 
						 | 
				
			
			@ -48,9 +48,7 @@ fun HomePageComposable(
 | 
			
		|||
                    .fillMaxWidth()
 | 
			
		||||
                    .wrapContentHeight(),
 | 
			
		||||
            ) { item ->
 | 
			
		||||
                // TODO:
 | 
			
		||||
//                val bookMock = BookMock().let { it.books[item.id] ?: it.book }
 | 
			
		||||
//                navigation.navigateTo(INavigation.Page.Detail(bookMock))
 | 
			
		||||
                navigationViewModel.navigateTo(Page.Detail(item.id))
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ fun MainScreenComposable(
 | 
			
		|||
    val page by navigationViewModel.page.observeAsState()
 | 
			
		||||
 | 
			
		||||
    LaunchedEffect(key1 = "MainScreen", block = {
 | 
			
		||||
        navigationViewModel.navigateTo(Page.HomePage)
 | 
			
		||||
        navigationViewModel.navigateTo(Page.HomePage, true)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    Scaffold(
 | 
			
		||||
| 
						 | 
				
			
			@ -76,10 +76,10 @@ fun MainScreenComposable(
 | 
			
		|||
            enter = slideInHorizontally(initialOffsetX = { 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) }
 | 
			
		||||
            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.book.IBookRepository
 | 
			
		||||
import com.pixelized.biblib.ui.data.BookThumbnailUio
 | 
			
		||||
import com.pixelized.biblib.ui.data.BookUio
 | 
			
		||||
import com.pixelized.biblib.utils.injection.inject
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.flow.Flow
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import java.util.*
 | 
			
		||||
 | 
			
		||||
class BooksViewModel : ViewModel(), IBooksViewModel {
 | 
			
		||||
    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 {
 | 
			
		||||
        val cached = apiCache.new
 | 
			
		||||
        val updated = client.service.new()
 | 
			
		||||
| 
						 | 
				
			
			@ -79,4 +92,16 @@ class BooksViewModel : ViewModel(), IBooksViewModel {
 | 
			
		|||
        date = releaseDate.toString(),
 | 
			
		||||
        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.paging.PagingData
 | 
			
		||||
import com.pixelized.biblib.ui.data.BookThumbnailUio
 | 
			
		||||
import com.pixelized.biblib.ui.data.BookUio
 | 
			
		||||
import kotlinx.coroutines.flow.Flow
 | 
			
		||||
import kotlinx.coroutines.flow.flowOf
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +15,8 @@ interface IBooksViewModel {
 | 
			
		|||
 | 
			
		||||
    fun updateBooks()
 | 
			
		||||
 | 
			
		||||
    fun getBookDetail(id: Int): LiveData<BookUio>
 | 
			
		||||
 | 
			
		||||
    sealed class State {
 | 
			
		||||
        object Initial : State()
 | 
			
		||||
        object Loading : State()
 | 
			
		||||
| 
						 | 
				
			
			@ -28,5 +31,6 @@ interface IBooksViewModel {
 | 
			
		|||
            get() = flowOf()
 | 
			
		||||
 | 
			
		||||
        override fun updateBooks() = Unit
 | 
			
		||||
        override fun getBookDetail(id: Int) = MutableLiveData<BookUio>()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +20,7 @@ interface INavigationViewModel {
 | 
			
		|||
 | 
			
		||||
        sealed class Page : Navigable() {
 | 
			
		||||
            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