diff --git a/app/src/main/java/com/pixelized/biblib/ui/composable/StateUioHandler.kt b/app/src/main/java/com/pixelized/biblib/ui/composable/StateUioHandler.kt index a61cd79..df64129 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/composable/StateUioHandler.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/composable/StateUioHandler.kt @@ -15,6 +15,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.window.Dialog import com.pixelized.biblib.ui.composable.dialog.ErrorCard import com.pixelized.biblib.ui.composable.dialog.LoadingCard +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract sealed class StateUio { class Progress(val progress: Float? = null) : StateUio() @@ -22,6 +24,14 @@ sealed class StateUio { class Success(val value: T) : StateUio() } +@OptIn(ExperimentalContracts::class) +fun StateUio.isSuccessful(): Boolean { + contract { + returns(true) implies (this@isSuccessful is StateUio.Success) + } + return this is StateUio.Success +} + @OptIn(ExperimentalAnimationApi::class) @Composable fun StateUioHandler( diff --git a/app/src/main/java/com/pixelized/biblib/ui/scaffold/BottomDetailScaffold.kt b/app/src/main/java/com/pixelized/biblib/ui/scaffold/BottomDetailScaffold.kt index 847c3c4..2279a69 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/scaffold/BottomDetailScaffold.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/scaffold/BottomDetailScaffold.kt @@ -20,7 +20,7 @@ import com.pixelized.biblib.utils.extention.showToast import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -val LocalBottomDetailController = staticCompositionLocalOf { +val LocalBottomDetailState = staticCompositionLocalOf { error("LocalBottomDetailController is not ready yet") } @@ -31,7 +31,7 @@ fun BottomDetailScaffold( content: @Composable () -> Unit, ) { CompositionLocalProvider( - LocalBottomDetailController provides bottomDetailState + LocalBottomDetailState provides bottomDetailState ) { ModalBottomSheetLayout( scrimColor = Color.Black.copy(alpha = 0.37f), @@ -89,7 +89,6 @@ class BottomDetailState constructor( } is StateUio.Success -> { bookDetail.value = book.value -// bottomSheetState.animateTo(ModalBottomSheetValue.Expanded) bottomSheetState.show() } else -> Unit diff --git a/app/src/main/java/com/pixelized/biblib/ui/screen/detail/DetailScreen.kt b/app/src/main/java/com/pixelized/biblib/ui/screen/detail/DetailScreen.kt index 3f95540..996b73d 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/screen/detail/DetailScreen.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/screen/detail/DetailScreen.kt @@ -2,21 +2,21 @@ package com.pixelized.biblib.ui.screen.detail import android.content.res.Configuration.UI_MODE_NIGHT_NO import android.content.res.Configuration.UI_MODE_NIGHT_YES +import androidx.activity.compose.BackHandler +import androidx.compose.animation.animateContentSize import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material.Button -import androidx.compose.material.Icon -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text +import androidx.compose.material.* 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.mutableStateOf -import androidx.compose.runtime.remember +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -26,28 +26,76 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.text.HtmlCompat import androidx.core.text.toSpannable +import androidx.hilt.navigation.compose.hiltViewModel import com.pixelized.biblib.R import com.pixelized.biblib.ui.composable.Cover import com.pixelized.biblib.ui.composable.SpannedText +import com.pixelized.biblib.ui.composable.StateUio import com.pixelized.biblib.ui.composable.animation.AnimatedDelayer import com.pixelized.biblib.ui.composable.animation.AnimatedOffset +import com.pixelized.biblib.ui.composable.isSuccessful +import com.pixelized.biblib.ui.scaffold.BottomDetailState +import com.pixelized.biblib.ui.scaffold.LocalBottomDetailState import com.pixelized.biblib.ui.screen.home.common.uio.BookUio import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio +import com.pixelized.biblib.ui.screen.profile.ProfileViewModel +import com.pixelized.biblib.ui.screen.profile.UserUio import com.pixelized.biblib.ui.theme.BibLibTheme import com.pixelized.biblib.utils.extention.bibLib import com.pixelized.biblib.utils.extention.todo +import kotlinx.coroutines.launch +@OptIn(ExperimentalMaterialApi::class) @Composable fun DetailScreen( + detailState: BottomDetailState = LocalBottomDetailState.current, + profileViewModel: ProfileViewModel = hiltViewModel(), detail: BookUio? = null, ) { - if (detail != null) { - DetailScreenContent( - modifier = Modifier.fillMaxSize(), - book = detail, - ) - } else { - Box(modifier = Modifier.fillMaxSize()) + val scope = rememberCoroutineScope() + val sheet = rememberModalBottomSheetState( + initialValue = ModalBottomSheetValue.Hidden, + skipHalfExpanded = true, + ) + + ModalBottomSheetLayout( + sheetState = sheet, + scrimColor = Color.Black.copy(alpha = 0.37f), + sheetContent = { + Box( + modifier = Modifier + .fillMaxWidth() + .heightIn(min = 1.dp) + .animateContentSize() + ) { + val user by derivedStateOf { profileViewModel.user } + if (user.isSuccessful()) { + DetailScreenSendContent( + modifier = Modifier.navigationBarsPadding(), + emails = (user as StateUio.Success).value.amazonEmails, + ) + } + } + }, + content = { + if (detailState.bottomSheetState.isVisible) { + if (detail != null) { + DetailScreenContent( + modifier = Modifier.fillMaxSize(), + book = detail, + onSend = { scope.launch { sheet.show() } } + ) + } else { + Box(modifier = Modifier.fillMaxSize()) + } + } else { + LaunchedEffect(key1 = "email bottom sheet close") { sheet.hide() } + } + }, + ) + + BackHandler(enabled = sheet.isVisible) { + scope.launch { sheet.hide() } } } @@ -61,7 +109,6 @@ private fun DetailScreenContent( ) { AnimatedDelayer( targetState = book, - delay = 300, ) { Column( modifier = Modifier @@ -230,6 +277,44 @@ private fun TitleLabel( } } +@Composable +private fun DetailScreenSendContent( + modifier: Modifier = Modifier, + emails: List, +) { + Column( + modifier = modifier.fillMaxWidth(), + ) { + Text( + modifier = Modifier.padding( + vertical = MaterialTheme.bibLib.dimen.dp8, + horizontal = MaterialTheme.bibLib.dimen.dp16, + ), + color = MaterialTheme.colors.primary, + style = MaterialTheme.typography.caption, + text = "Send this eBook to:", + ) + + LazyColumn { + items(items = emails) { + Box( + modifier = Modifier + .height(height = MaterialTheme.bibLib.dimen.dp48) + .fillMaxWidth(), + contentAlignment = Alignment.CenterStart + ) { + Text( + modifier = Modifier.padding(horizontal = MaterialTheme.bibLib.dimen.dp16), + style = MaterialTheme.typography.body1, + color = MaterialTheme.colors.onSurface, + text = it + ) + } + } + } + } +} + @Composable @Preview(showBackground = true, uiMode = UI_MODE_NIGHT_NO) @Preview(showBackground = true, uiMode = UI_MODE_NIGHT_YES) @@ -258,4 +343,18 @@ private fun DetailScreenContentPreview() { BibLibTheme { DetailScreenContent(book = book) } +} + +@Composable +@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_NO) +@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_YES) +private fun DetailScreenSendPreview() { + BibLibTheme { + DetailScreenSendContent( + emails = listOf( + "R.Giskard.Reventlov.Kindle@gmailcom", + "R.Daneel.Olivaw.Kindle@gmailcom", + ), + ) + } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/biblib/ui/screen/home/page/books/BooksPage.kt b/app/src/main/java/com/pixelized/biblib/ui/screen/home/page/books/BooksPage.kt index 98c8932..094e811 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/screen/home/page/books/BooksPage.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/screen/home/page/books/BooksPage.kt @@ -6,7 +6,7 @@ import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel -import com.pixelized.biblib.ui.scaffold.LocalBottomDetailController +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 @@ -18,7 +18,7 @@ fun BooksPage( connectivityViewModel: ConnectivityViewModel = hiltViewModel(), booksViewModel: BooksViewModel = hiltViewModel() ) { - val bottomDetailState = LocalBottomDetailController.current + val bottomDetailState = LocalBottomDetailState.current LazyBookThumbnailColumn( verticalArrangement = Arrangement.spacedBy(MaterialTheme.bibLib.dimen.thumbnail.arrangement), diff --git a/app/src/main/java/com/pixelized/biblib/ui/screen/home/page/news/NewsPage.kt b/app/src/main/java/com/pixelized/biblib/ui/screen/home/page/news/NewsPage.kt index 8295ba2..1275dc9 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/screen/home/page/news/NewsPage.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/screen/home/page/news/NewsPage.kt @@ -6,7 +6,7 @@ import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel -import com.pixelized.biblib.ui.scaffold.LocalBottomDetailController +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.theme.BibLibTheme @@ -17,7 +17,7 @@ fun NewsPage( connectivityViewModel: ConnectivityViewModel = hiltViewModel(), booksViewModel: NewsBookViewModel = hiltViewModel() ) { - val bottomDetail = LocalBottomDetailController.current + val bottomDetail = LocalBottomDetailState.current LazyBookThumbnailColumn( verticalArrangement = Arrangement.spacedBy(MaterialTheme.bibLib.dimen.thumbnail.arrangement), diff --git a/app/src/main/java/com/pixelized/biblib/ui/theme/dimen/BibLibDimen.kt b/app/src/main/java/com/pixelized/biblib/ui/theme/dimen/BibLibDimen.kt index 00d4221..0118e19 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/theme/dimen/BibLibDimen.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/theme/dimen/BibLibDimen.kt @@ -14,6 +14,7 @@ data class BibLibDimen( val dp8: Dp = 8.dp, val dp16: Dp = 16.dp, val dp32: Dp = 32.dp, + val dp48: Dp = 48.dp, val dp64: Dp = 64.dp, val dialog: Dialog = Dialog(), val thumbnail: BookThumbnail = BookThumbnail(),