Add the send to kindle feature.
This commit is contained in:
		
							parent
							
								
									3c75c7a990
								
							
						
					
					
						commit
						f14c2258f6
					
				
					 8 changed files with 103 additions and 18 deletions
				
			
		| 
						 | 
					@ -38,7 +38,10 @@ fun DetailBottomSheet(
 | 
				
			||||||
            scrimColor = ShadowPalette.scrim,
 | 
					            scrimColor = ShadowPalette.scrim,
 | 
				
			||||||
            sheetState = bottomDetailState.bottomSheetState,
 | 
					            sheetState = bottomDetailState.bottomSheetState,
 | 
				
			||||||
            sheetContent = {
 | 
					            sheetContent = {
 | 
				
			||||||
                DetailScreen(detail = bottomDetailState.bookDetail)
 | 
					                DetailScreen(
 | 
				
			||||||
 | 
					                    viewModel = bottomDetailState.viewModel,
 | 
				
			||||||
 | 
					                    detail = bottomDetailState.bookDetail,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            content = content,
 | 
					            content = content,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -77,8 +80,8 @@ fun rememberDetailBottomSheetState(
 | 
				
			||||||
@Stable
 | 
					@Stable
 | 
				
			||||||
class DetailBottomSheetState constructor(
 | 
					class DetailBottomSheetState constructor(
 | 
				
			||||||
    private val context: Context,
 | 
					    private val context: Context,
 | 
				
			||||||
    private val viewModel: BookDetailViewModel,
 | 
					 | 
				
			||||||
    private val scope: CoroutineScope,
 | 
					    private val scope: CoroutineScope,
 | 
				
			||||||
 | 
					    val viewModel: BookDetailViewModel,
 | 
				
			||||||
    val bottomSheetState: ModalBottomSheetState,
 | 
					    val bottomSheetState: ModalBottomSheetState,
 | 
				
			||||||
    bookDetail: MutableState<BookDetailUio?>,
 | 
					    bookDetail: MutableState<BookDetailUio?>,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,10 @@ class BookDetailViewModel @Inject constructor(
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    suspend fun send(bookId: Int, mail: String) {
 | 
				
			||||||
 | 
					        client.service.send(bookId = bookId, mail = mail)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private suspend fun getBookDetail(id: Int): BookDetailUio {
 | 
					    private suspend fun getBookDetail(id: Int): BookDetailUio {
 | 
				
			||||||
        val factory = BookFactory()
 | 
					        val factory = BookFactory()
 | 
				
			||||||
        val response = client.service.detail(id)
 | 
					        val response = client.service.detail(id)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@ import androidx.compose.runtime.*
 | 
				
			||||||
import androidx.compose.ui.Alignment
 | 
					import androidx.compose.ui.Alignment
 | 
				
			||||||
import androidx.compose.ui.Modifier
 | 
					import androidx.compose.ui.Modifier
 | 
				
			||||||
import androidx.compose.ui.layout.ContentScale
 | 
					import androidx.compose.ui.layout.ContentScale
 | 
				
			||||||
 | 
					import androidx.compose.ui.platform.LocalContext
 | 
				
			||||||
import androidx.compose.ui.res.stringResource
 | 
					import androidx.compose.ui.res.stringResource
 | 
				
			||||||
import androidx.compose.ui.text.font.FontWeight
 | 
					import androidx.compose.ui.text.font.FontWeight
 | 
				
			||||||
import androidx.compose.ui.text.style.TextAlign
 | 
					import androidx.compose.ui.text.style.TextAlign
 | 
				
			||||||
| 
						 | 
					@ -41,12 +42,14 @@ import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
				
			||||||
import com.pixelized.biblib.ui.theme.color.ShadowPalette
 | 
					import com.pixelized.biblib.ui.theme.color.ShadowPalette
 | 
				
			||||||
import com.pixelized.biblib.utils.extention.bibLib
 | 
					import com.pixelized.biblib.utils.extention.bibLib
 | 
				
			||||||
import com.pixelized.biblib.utils.extention.default
 | 
					import com.pixelized.biblib.utils.extention.default
 | 
				
			||||||
 | 
					import com.pixelized.biblib.utils.extention.showToast
 | 
				
			||||||
import com.skydoves.landscapist.CircularReveal
 | 
					import com.skydoves.landscapist.CircularReveal
 | 
				
			||||||
import com.skydoves.landscapist.glide.GlideImage
 | 
					import com.skydoves.landscapist.glide.GlideImage
 | 
				
			||||||
import kotlinx.coroutines.launch
 | 
					import kotlinx.coroutines.launch
 | 
				
			||||||
import java.io.Serializable
 | 
					import java.io.Serializable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Stable
 | 
					@Stable
 | 
				
			||||||
 | 
					@Immutable
 | 
				
			||||||
data class BookDetailUio(
 | 
					data class BookDetailUio(
 | 
				
			||||||
    val id: Int,
 | 
					    val id: Int,
 | 
				
			||||||
    val title: String,
 | 
					    val title: String,
 | 
				
			||||||
| 
						 | 
					@ -64,8 +67,10 @@ data class BookDetailUio(
 | 
				
			||||||
fun DetailScreen(
 | 
					fun DetailScreen(
 | 
				
			||||||
    detailState: DetailBottomSheetState = LocalDetailBottomSheetState.current,
 | 
					    detailState: DetailBottomSheetState = LocalDetailBottomSheetState.current,
 | 
				
			||||||
    profileViewModel: ProfileViewModel = hiltViewModel(),
 | 
					    profileViewModel: ProfileViewModel = hiltViewModel(),
 | 
				
			||||||
 | 
					    viewModel: BookDetailViewModel = hiltViewModel(),
 | 
				
			||||||
    detail: BookDetailUio? = null,
 | 
					    detail: BookDetailUio? = null,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
 | 
					    val context = LocalContext.current
 | 
				
			||||||
    val scope = rememberCoroutineScope()
 | 
					    val scope = rememberCoroutineScope()
 | 
				
			||||||
    val sheet = rememberModalBottomSheetState(
 | 
					    val sheet = rememberModalBottomSheetState(
 | 
				
			||||||
        initialValue = ModalBottomSheetValue.Hidden,
 | 
					        initialValue = ModalBottomSheetValue.Hidden,
 | 
				
			||||||
| 
						 | 
					@ -82,13 +87,20 @@ fun DetailScreen(
 | 
				
			||||||
                    .heightIn(min = 1.dp)
 | 
					                    .heightIn(min = 1.dp)
 | 
				
			||||||
                    .animateContentSize()
 | 
					                    .animateContentSize()
 | 
				
			||||||
            ) {
 | 
					            ) {
 | 
				
			||||||
                val user by derivedStateOf { profileViewModel.user }
 | 
					                val user = profileViewModel.user
 | 
				
			||||||
                if (user.isSuccessful()) {
 | 
					                if (user.isSuccessful()) {
 | 
				
			||||||
                    DetailScreenSendContent(
 | 
					                    DetailScreenSendContent(
 | 
				
			||||||
                        modifier = Modifier
 | 
					                        modifier = Modifier
 | 
				
			||||||
                            .navigationBarsPadding()
 | 
					                            .navigationBarsPadding()
 | 
				
			||||||
                            .padding(bottom = MaterialTheme.bibLib.dimen.dp16),
 | 
					                            .padding(bottom = MaterialTheme.bibLib.dimen.dp16),
 | 
				
			||||||
                        emails = (user as StateUio.Success<UserUio>).value.amazonEmails,
 | 
					                        emails = user.value.amazonEmails,
 | 
				
			||||||
 | 
					                        onEmail = { mail ->
 | 
				
			||||||
 | 
					                            detail?.id?.let { bookId ->
 | 
				
			||||||
 | 
					                                scope.launch {
 | 
				
			||||||
 | 
					                                    viewModel.send(bookId = bookId, mail = mail)
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -99,7 +111,28 @@ fun DetailScreen(
 | 
				
			||||||
                    DetailScreenContent(
 | 
					                    DetailScreenContent(
 | 
				
			||||||
                        modifier = Modifier.fillMaxSize(),
 | 
					                        modifier = Modifier.fillMaxSize(),
 | 
				
			||||||
                        book = detail,
 | 
					                        book = detail,
 | 
				
			||||||
                        onSend = { scope.launch { sheet.show() } }
 | 
					                        onSend = {
 | 
				
			||||||
 | 
					                            // check
 | 
				
			||||||
 | 
					                            val user = profileViewModel.user
 | 
				
			||||||
 | 
					                            if (user.isSuccessful()) {
 | 
				
			||||||
 | 
					                                val mails = user.value.amazonEmails
 | 
				
			||||||
 | 
					                                when {
 | 
				
			||||||
 | 
					                                    mails.isEmpty() -> {
 | 
				
			||||||
 | 
					                                        context.showToast(context.getString(R.string.error_no_amazon_email),)
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                    mails.size == 1 -> {
 | 
				
			||||||
 | 
					                                        scope.launch {
 | 
				
			||||||
 | 
					                                            viewModel.send(bookId = detail.id, mail = mails.first())
 | 
				
			||||||
 | 
					                                        }
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                    else -> {
 | 
				
			||||||
 | 
					                                        scope.launch { sheet.show() }
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                // TODO()
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    Box(modifier = Modifier.fillMaxSize())
 | 
					                    Box(modifier = Modifier.fillMaxSize())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,29 +5,19 @@ import android.content.res.Configuration.UI_MODE_NIGHT_YES
 | 
				
			||||||
import androidx.compose.animation.core.Spring
 | 
					import androidx.compose.animation.core.Spring
 | 
				
			||||||
import androidx.compose.animation.core.animateFloatAsState
 | 
					import androidx.compose.animation.core.animateFloatAsState
 | 
				
			||||||
import androidx.compose.animation.core.spring
 | 
					import androidx.compose.animation.core.spring
 | 
				
			||||||
import androidx.compose.foundation.horizontalScroll
 | 
					 | 
				
			||||||
import androidx.compose.foundation.layout.*
 | 
					import androidx.compose.foundation.layout.*
 | 
				
			||||||
import androidx.compose.foundation.lazy.LazyColumn
 | 
					import androidx.compose.foundation.lazy.LazyColumn
 | 
				
			||||||
import androidx.compose.foundation.rememberScrollState
 | 
					 | 
				
			||||||
import androidx.compose.material.*
 | 
					import androidx.compose.material.*
 | 
				
			||||||
import androidx.compose.material.icons.Icons
 | 
					 | 
				
			||||||
import androidx.compose.material.icons.filled.ArrowDropDown
 | 
					 | 
				
			||||||
import androidx.compose.runtime.Composable
 | 
					import androidx.compose.runtime.Composable
 | 
				
			||||||
import androidx.compose.runtime.derivedStateOf
 | 
					 | 
				
			||||||
import androidx.compose.runtime.getValue
 | 
					import androidx.compose.runtime.getValue
 | 
				
			||||||
import androidx.compose.runtime.remember
 | 
					 | 
				
			||||||
import androidx.compose.ui.Alignment
 | 
					 | 
				
			||||||
import androidx.compose.ui.ExperimentalComposeUiApi
 | 
					import androidx.compose.ui.ExperimentalComposeUiApi
 | 
				
			||||||
import androidx.compose.ui.Modifier
 | 
					import androidx.compose.ui.Modifier
 | 
				
			||||||
import androidx.compose.ui.draw.alpha
 | 
					import androidx.compose.ui.draw.alpha
 | 
				
			||||||
import androidx.compose.ui.graphics.Color
 | 
					import androidx.compose.ui.graphics.Color
 | 
				
			||||||
import androidx.compose.ui.platform.LocalFocusManager
 | 
					import androidx.compose.ui.platform.LocalFocusManager
 | 
				
			||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
 | 
					import androidx.compose.ui.platform.LocalSoftwareKeyboardController
 | 
				
			||||||
import androidx.compose.ui.res.stringResource
 | 
					 | 
				
			||||||
import androidx.compose.ui.tooling.preview.Preview
 | 
					import androidx.compose.ui.tooling.preview.Preview
 | 
				
			||||||
import androidx.paging.LoadState
 | 
					 | 
				
			||||||
import androidx.paging.PagingData
 | 
					import androidx.paging.PagingData
 | 
				
			||||||
import androidx.paging.compose.LazyPagingItems
 | 
					 | 
				
			||||||
import androidx.paging.compose.collectAsLazyPagingItems
 | 
					import androidx.paging.compose.collectAsLazyPagingItems
 | 
				
			||||||
import androidx.paging.compose.items
 | 
					import androidx.paging.compose.items
 | 
				
			||||||
import com.pixelized.biblib.ui.scaffold.LocalCategorySearchBottomSheetState
 | 
					import com.pixelized.biblib.ui.scaffold.LocalCategorySearchBottomSheetState
 | 
				
			||||||
| 
						 | 
					@ -36,8 +26,8 @@ import com.pixelized.biblib.ui.scaffold.LocalSearchViewModel
 | 
				
			||||||
import com.pixelized.biblib.ui.scaffold.SearchFilter
 | 
					import com.pixelized.biblib.ui.scaffold.SearchFilter
 | 
				
			||||||
import com.pixelized.biblib.ui.screen.home.common.item.MicroBookThumbnail
 | 
					import com.pixelized.biblib.ui.screen.home.common.item.MicroBookThumbnail
 | 
				
			||||||
import com.pixelized.biblib.ui.screen.home.common.item.MicroBookThumbnailUio
 | 
					import com.pixelized.biblib.ui.screen.home.common.item.MicroBookThumbnailUio
 | 
				
			||||||
import com.pixelized.biblib.ui.screen.home.common.item.SmallBookThumbnail
 | 
					import com.pixelized.biblib.ui.screen.home.page.search.item.SearchFilter
 | 
				
			||||||
import com.pixelized.biblib.ui.screen.home.common.item.SmallBookThumbnailUio
 | 
					import com.pixelized.biblib.ui.screen.home.page.search.item.rememberSearchFilter
 | 
				
			||||||
import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
					import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
				
			||||||
import com.pixelized.biblib.utils.extention.bibLib
 | 
					import com.pixelized.biblib.utils.extention.bibLib
 | 
				
			||||||
import com.pixelized.biblib.utils.extention.default
 | 
					import com.pixelized.biblib.utils.extention.default
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
package com.pixelized.biblib.ui.screen.home.page.search
 | 
					package com.pixelized.biblib.ui.screen.home.page.search.item
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import android.content.res.Configuration
 | 
					import android.content.res.Configuration
 | 
				
			||||||
import androidx.compose.foundation.horizontalScroll
 | 
					import androidx.compose.foundation.horizontalScroll
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@ import androidx.compose.ui.res.stringResource
 | 
				
			||||||
import androidx.compose.ui.tooling.preview.Preview
 | 
					import androidx.compose.ui.tooling.preview.Preview
 | 
				
			||||||
import com.pixelized.biblib.ui.scaffold.LocalSearchViewModel
 | 
					import com.pixelized.biblib.ui.scaffold.LocalSearchViewModel
 | 
				
			||||||
import com.pixelized.biblib.ui.scaffold.SearchFilter
 | 
					import com.pixelized.biblib.ui.scaffold.SearchFilter
 | 
				
			||||||
 | 
					import com.pixelized.biblib.ui.screen.home.page.search.SearchViewModel
 | 
				
			||||||
import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
					import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
				
			||||||
import com.pixelized.biblib.utils.extention.bibLib
 | 
					import com.pixelized.biblib.utils.extention.bibLib
 | 
				
			||||||
import com.pixelized.biblib.utils.extention.default
 | 
					import com.pixelized.biblib.utils.extention.default
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,52 @@
 | 
				
			||||||
 | 
					package com.pixelized.biblib.ui.screen.home.page.search.item
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.content.res.Configuration
 | 
				
			||||||
 | 
					import androidx.compose.foundation.layout.Row
 | 
				
			||||||
 | 
					import androidx.compose.foundation.layout.padding
 | 
				
			||||||
 | 
					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.History
 | 
				
			||||||
 | 
					import androidx.compose.runtime.Composable
 | 
				
			||||||
 | 
					import androidx.compose.ui.Modifier
 | 
				
			||||||
 | 
					import androidx.compose.ui.tooling.preview.Preview
 | 
				
			||||||
 | 
					import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
				
			||||||
 | 
					import com.pixelized.biblib.utils.extention.bibLib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Composable
 | 
				
			||||||
 | 
					fun SearchHistory() {
 | 
				
			||||||
 | 
					    SearchHistoryContent(
 | 
				
			||||||
 | 
					        label = ""
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Composable
 | 
				
			||||||
 | 
					private fun SearchHistoryContent(
 | 
				
			||||||
 | 
					    modifier: Modifier = Modifier,
 | 
				
			||||||
 | 
					    label : String,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    Row(
 | 
				
			||||||
 | 
					        modifier = modifier.padding(all = MaterialTheme.bibLib.dimen.dp16)
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        Icon(
 | 
				
			||||||
 | 
					            modifier = Modifier.padding(end = MaterialTheme.bibLib.dimen.dp8),
 | 
				
			||||||
 | 
					            imageVector = Icons.Default.History,
 | 
				
			||||||
 | 
					            contentDescription = null,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        Text(
 | 
				
			||||||
 | 
					            color = MaterialTheme.bibLib.colors.typography.medium,
 | 
				
			||||||
 | 
					            style = MaterialTheme.typography.body1,
 | 
				
			||||||
 | 
					            text = label,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Composable
 | 
				
			||||||
 | 
					@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
 | 
				
			||||||
 | 
					@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
 | 
				
			||||||
 | 
					private fun SearchHistoryContentPreview() {
 | 
				
			||||||
 | 
					    BibLibTheme {
 | 
				
			||||||
 | 
					        SearchHistoryContentPreview()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@
 | 
				
			||||||
    <string name="error_authentication">Oups, la connection a échoué !</string>
 | 
					    <string name="error_authentication">Oups, la connection a échoué !</string>
 | 
				
			||||||
    <string name="error_book">Oups! le téléchargement de la librairy à échoué !</string>
 | 
					    <string name="error_book">Oups! le téléchargement de la librairy à échoué !</string>
 | 
				
			||||||
    <string name="error_offline">Vous êtes hors ligne.</string>
 | 
					    <string name="error_offline">Vous êtes hors ligne.</string>
 | 
				
			||||||
 | 
					    <string name="error_no_amazon_email">Vous n\'avez aucun mail lié à votre compte. Merci de vous rendre sur https://bib.bibulle.fr/ et d\'éditez voter profile pour en ajouter un.</string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <string name="loading_authentication">Ouverture de BibLibrary.</string>
 | 
					    <string name="loading_authentication">Ouverture de BibLibrary.</string>
 | 
				
			||||||
    <string name="loading_book">Téléchargement de BibLibrary.</string>
 | 
					    <string name="loading_book">Téléchargement de BibLibrary.</string>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,6 +26,7 @@
 | 
				
			||||||
    <string name="error_authentication">Oops, connection failed!</string>
 | 
					    <string name="error_authentication">Oops, connection failed!</string>
 | 
				
			||||||
    <string name="error_book">Oops! library download failed!</string>
 | 
					    <string name="error_book">Oops! library download failed!</string>
 | 
				
			||||||
    <string name="error_offline">You are offline.</string>
 | 
					    <string name="error_offline">You are offline.</string>
 | 
				
			||||||
 | 
					    <string name="error_no_amazon_email">You have no email linked to your account. Please go to https://bib.bibulle.fr/ and edit your profile to add one.</string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <string name="loading_authentication">Opening the BibLibrary.</string>
 | 
					    <string name="loading_authentication">Opening the BibLibrary.</string>
 | 
				
			||||||
    <string name="loading_book">Downloading the BibLibrary.</string>
 | 
					    <string name="loading_book">Downloading the BibLibrary.</string>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue