Add format selection on book send.
This commit is contained in:
parent
1401c7159c
commit
3e234cc37d
9 changed files with 286 additions and 140 deletions
|
|
@ -25,7 +25,7 @@ interface IBibLibWebServiceAPI {
|
||||||
suspend fun detail(@Path("id") bookId: Int): BookDetailResponse
|
suspend fun detail(@Path("id") bookId: Int): BookDetailResponse
|
||||||
|
|
||||||
@GET("book/{id}/send/kindle")
|
@GET("book/{id}/send/kindle")
|
||||||
suspend fun send(@Path("id") bookId: Int, @Query("mail") mail: String): LinkedTreeMap<String, Any>
|
suspend fun send(@Path("id") bookId: Int, @Query("mail") mail: String, @Query("format") format: String): LinkedTreeMap<String, Any>
|
||||||
|
|
||||||
@GET("series")
|
@GET("series")
|
||||||
suspend fun series(): SeriesListResponse
|
suspend fun series(): SeriesListResponse
|
||||||
|
|
|
||||||
|
|
@ -46,16 +46,16 @@ class BookDetailViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun send(bookId: Int, email: String) {
|
suspend fun send(bookId: Int, email: String, format: String) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val data = client.service.send(bookId = bookId, mail = email)
|
val data = client.service.send(bookId = bookId, mail = email, format = format)
|
||||||
_sendStatus.emit(true)
|
_sendStatus.emit(true)
|
||||||
Log.d("send", data.toString())
|
Log.d("send", data.toString())
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
Log.d("send", exception.message, exception)
|
Log.d("send", exception.message, exception)
|
||||||
_sendStatus.emit(false)
|
_sendStatus.emit(false)
|
||||||
_error.emit(toSendBookUio(bookId = bookId, mail = email))
|
_error.emit(toSendBookUio(bookId = bookId, mail = email, format))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,10 +77,15 @@ class BookDetailViewModel @Inject constructor(
|
||||||
bookId = bookId,
|
bookId = bookId,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun toSendBookUio(bookId: Int, mail: String) = BookDetailUioErrorUio.SendBookInput(
|
private fun toSendBookUio(
|
||||||
|
bookId: Int,
|
||||||
|
mail: String,
|
||||||
|
format: String
|
||||||
|
) = BookDetailUioErrorUio.SendBookInput(
|
||||||
message = stringResource(R.string.error_send_book_message),
|
message = stringResource(R.string.error_send_book_message),
|
||||||
action = stringResource(R.string.error_send_book_action),
|
action = stringResource(R.string.error_send_book_action),
|
||||||
bookId = bookId,
|
bookId = bookId,
|
||||||
mail = mail,
|
mail = mail,
|
||||||
|
format = format,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.pixelized.biblib.ui.screen.home.detail
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.pixelized.biblib.network.client.IBibLibClient
|
||||||
|
import com.pixelized.biblib.network.factory.UserFactory
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class BookOptionViewModel @Inject constructor(
|
||||||
|
private val client: IBibLibClient,
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
var emails by mutableStateOf(listOf<OptionUio>())
|
||||||
|
private set
|
||||||
|
|
||||||
|
var formats by mutableStateOf(listOf(OptionUio(Format.EPUB, true), OptionUio(Format.MOBI)))
|
||||||
|
private set
|
||||||
|
|
||||||
|
init {
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
val factory = UserFactory()
|
||||||
|
val response = client.service.user()
|
||||||
|
val data = factory.fromUserResponseToUser(response)
|
||||||
|
|
||||||
|
emails = data.amazonEmails.mapIndexed { index, mail ->
|
||||||
|
OptionUio(value = mail, selected = index == 0)
|
||||||
|
}
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Log.e("AccountViewModel", exception.message, exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectMail(mail: String) {
|
||||||
|
emails = emails.map {
|
||||||
|
it.copy(selected = it.value == mail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectFormat(@Format format: String) {
|
||||||
|
formats = formats.map {
|
||||||
|
it.copy(selected = it.value == format)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,10 +16,11 @@ class ConfirmDialogViewModel @Inject constructor(
|
||||||
var dialog by mutableStateOf<ConfirmDialogUio?>(null)
|
var dialog by mutableStateOf<ConfirmDialogUio?>(null)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun show(bookId: Int, email: String) {
|
fun show(bookId: Int, email: String, @Format format: String) {
|
||||||
this.dialog = ConfirmDialogUio(
|
this.dialog = ConfirmDialogUio(
|
||||||
bookId = bookId,
|
bookId = bookId,
|
||||||
email = email,
|
email = email,
|
||||||
|
format = format,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.pixelized.biblib.ui.screen.home.detail
|
package com.pixelized.biblib.ui.screen.home.detail
|
||||||
|
|
||||||
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
|
@ -18,6 +19,7 @@ import com.pixelized.biblib.ui.screen.home.page.profile.ProfileViewModel
|
||||||
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.showToast
|
import com.pixelized.biblib.utils.extention.showToast
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
|
|
@ -70,6 +72,7 @@ sealed class BookDetailUioErrorUio(
|
||||||
action: String?,
|
action: String?,
|
||||||
val bookId: Int,
|
val bookId: Int,
|
||||||
val mail: String,
|
val mail: String,
|
||||||
|
val format: String,
|
||||||
) : BookDetailUioErrorUio(message, action)
|
) : BookDetailUioErrorUio(message, action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,13 +103,12 @@ fun DetailScreen(
|
||||||
sheetState = emailSheetState,
|
sheetState = emailSheetState,
|
||||||
scrimColor = ShadowPalette.scrim,
|
scrimColor = ShadowPalette.scrim,
|
||||||
sheetContent = {
|
sheetContent = {
|
||||||
DetailScreenEmailList(
|
DetailScreenSendOption(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.navigationBarsPadding()
|
.navigationBarsPadding()
|
||||||
.padding(bottom = MaterialTheme.bibLib.dimen.dp16),
|
.padding(bottom = MaterialTheme.bibLib.dimen.dp16),
|
||||||
profileViewModel = profileViewModel,
|
onSend = { mail, format ->
|
||||||
onEmail = { mail ->
|
confirmViewModel.show(bookId = detail.id, email = mail, format = format)
|
||||||
confirmViewModel.show(bookId = detail.id, email = mail)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -132,7 +134,8 @@ fun DetailScreen(
|
||||||
mails.size == 1 -> {
|
mails.size == 1 -> {
|
||||||
confirmViewModel.show(
|
confirmViewModel.show(
|
||||||
bookId = detail.id,
|
bookId = detail.id,
|
||||||
email = mails.first()
|
email = mails.first(),
|
||||||
|
format = Format.EPUB,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|
@ -153,11 +156,11 @@ fun DetailScreen(
|
||||||
ConfirmDialog(
|
ConfirmDialog(
|
||||||
modifier = Modifier.padding(all = MaterialTheme.bibLib.dimen.dp32),
|
modifier = Modifier.padding(all = MaterialTheme.bibLib.dimen.dp32),
|
||||||
confirmViewModel = confirmViewModel,
|
confirmViewModel = confirmViewModel,
|
||||||
onConfirm = { id, email ->
|
onConfirm = { id, email, format ->
|
||||||
scope.launch {
|
scope.launch {
|
||||||
confirmViewModel.hide()
|
confirmViewModel.hide()
|
||||||
emailSheetState.hide()
|
emailSheetState.hide()
|
||||||
detailViewModel.send(bookId = id, email = email)
|
detailViewModel.send(bookId = id, email = email, format = format)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onDismiss = { confirmViewModel.hide() },
|
onDismiss = { confirmViewModel.hide() },
|
||||||
|
|
@ -176,20 +179,34 @@ fun DetailScreen(
|
||||||
)
|
)
|
||||||
if (result == SnackbarResult.ActionPerformed) {
|
if (result == SnackbarResult.ActionPerformed) {
|
||||||
when (it) {
|
when (it) {
|
||||||
is BookDetailUioErrorUio.GetDetailInput -> {
|
is BookDetailUioErrorUio.GetDetailInput -> detailViewModel.getDetail(
|
||||||
detailViewModel.getDetail(id = it.bookId)
|
id = it.bookId
|
||||||
}
|
)
|
||||||
is BookDetailUioErrorUio.SendBookInput -> {
|
is BookDetailUioErrorUio.SendBookInput -> detailViewModel.send(
|
||||||
detailViewModel.send(bookId = it.bookId, email = it.mail)
|
bookId = it.bookId,
|
||||||
}
|
email = it.mail,
|
||||||
|
format = it.format,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(key1 = "") {
|
||||||
|
detailViewModel.sendStatus.collect {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LaunchedEffect(key1 = bookId) {
|
LaunchedEffect(key1 = bookId) {
|
||||||
bookId?.let { detailViewModel.getDetail(it) }
|
bookId?.let { detailViewModel.getDetail(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BackHandler(emailSheetState.isVisible || emailSheetState.isAnimationRunning) {
|
||||||
|
scope.launch {
|
||||||
|
emailSheetState.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.pixelized.biblib.ui.screen.home.detail
|
package com.pixelized.biblib.ui.screen.home.detail
|
||||||
|
|
||||||
|
import android.content.Context.*
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
|
import androidx.annotation.StringDef
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
|
|
@ -26,17 +28,29 @@ import com.pixelized.biblib.utils.extention.default
|
||||||
import com.pixelized.biblib.utils.extention.highlight
|
import com.pixelized.biblib.utils.extention.highlight
|
||||||
import com.pixelized.biblib.utils.extention.stringRegex
|
import com.pixelized.biblib.utils.extention.stringRegex
|
||||||
|
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
@StringDef(Format.EPUB, Format.MOBI)
|
||||||
|
annotation class Format {
|
||||||
|
companion object {
|
||||||
|
const val EPUB = "epub"
|
||||||
|
const val MOBI = "mobi"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
@Immutable
|
@Immutable
|
||||||
data class ConfirmDialogUio(
|
data class ConfirmDialogUio(
|
||||||
val bookId: Int,
|
val bookId: Int,
|
||||||
val email: String,
|
val email: String,
|
||||||
|
@Format val format: String,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
fun preview() = ConfirmDialogUio(
|
fun preview() = ConfirmDialogUio(
|
||||||
bookId = 90,
|
bookId = 90,
|
||||||
email = "R.Daneel.Olivaw.Kindle@gmail.com",
|
email = "R.Daneel.Olivaw.Kindle@gmail.com",
|
||||||
|
format = Format.EPUB,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -45,7 +59,7 @@ data class ConfirmDialogUio(
|
||||||
fun ConfirmDialog(
|
fun ConfirmDialog(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
confirmViewModel: ConfirmDialogViewModel,
|
confirmViewModel: ConfirmDialogViewModel,
|
||||||
onConfirm: (bookId: Int, mail: String) -> Unit = { _, _ -> },
|
onConfirm: (bookId: Int, mail: String, format: String) -> Unit = { _, _, _ -> },
|
||||||
onHelp: (url: String) -> Unit = default<String>(),
|
onHelp: (url: String) -> Unit = default<String>(),
|
||||||
onDismiss: () -> Unit
|
onDismiss: () -> Unit
|
||||||
) {
|
) {
|
||||||
|
|
@ -67,7 +81,7 @@ fun ConfirmDialog(
|
||||||
uio: ConfirmDialogUio,
|
uio: ConfirmDialogUio,
|
||||||
onDismissRequest: () -> Unit = default(),
|
onDismissRequest: () -> Unit = default(),
|
||||||
onHelp: (url: String) -> Unit = default<String>(),
|
onHelp: (url: String) -> Unit = default<String>(),
|
||||||
onConfirm: (bookId: Int, mail: String) -> Unit = { _, _ -> },
|
onConfirm: (bookId: Int, mail: String, format: String) -> Unit = { _, _, _ -> },
|
||||||
) {
|
) {
|
||||||
Dialog(
|
Dialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
|
|
@ -89,7 +103,7 @@ fun ConfirmDialogContent(
|
||||||
uio: ConfirmDialogUio,
|
uio: ConfirmDialogUio,
|
||||||
onDismissRequest: () -> Unit = default(),
|
onDismissRequest: () -> Unit = default(),
|
||||||
onHelp: (url: String) -> Unit = default<String>(),
|
onHelp: (url: String) -> Unit = default<String>(),
|
||||||
onConfirm: (bookId: Int, mail: String) -> Unit = { _, _ -> },
|
onConfirm: (bookId: Int, mail: String, format: String) -> Unit = { _, _, _ -> },
|
||||||
) {
|
) {
|
||||||
val amazonHelpUri = stringResource(R.string.detail_send_confirm_help_url)
|
val amazonHelpUri = stringResource(R.string.detail_send_confirm_help_url)
|
||||||
|
|
||||||
|
|
@ -142,15 +156,15 @@ fun ConfirmDialogContent(
|
||||||
onClick = onDismissRequest,
|
onClick = onDismissRequest,
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.detail_send_confirm_confirm_action)
|
text = stringResource(R.string.detail_send_confirm_cancel_action)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Button(
|
Button(
|
||||||
colors = ButtonDefaults.buttonColors(),
|
colors = ButtonDefaults.buttonColors(),
|
||||||
onClick = { onConfirm(uio.bookId, uio.email) }
|
onClick = { onConfirm(uio.bookId, uio.email, uio.format) }
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.detail_send_confirm_cancel_action)
|
text = stringResource(R.string.detail_send_confirm_confirm_action)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,114 +0,0 @@
|
||||||
package com.pixelized.biblib.ui.screen.home.detail
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.animation.animateContentSize
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
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.NavigateNext
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
|
||||||
import com.pixelized.biblib.ui.composable.isSuccessful
|
|
||||||
import com.pixelized.biblib.ui.screen.home.page.profile.ProfileViewModel
|
|
||||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
|
||||||
import com.pixelized.biblib.utils.extention.bibLib
|
|
||||||
import com.pixelized.biblib.utils.extention.default
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun DetailScreenEmailList(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
profileViewModel: ProfileViewModel,
|
|
||||||
onEmail: (email: String) -> Unit = default<String>(),
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.heightIn(min = 1.dp)
|
|
||||||
.animateContentSize()
|
|
||||||
) {
|
|
||||||
val user = profileViewModel.user
|
|
||||||
if (user.isSuccessful()) {
|
|
||||||
DetailScreenEmailList(
|
|
||||||
modifier = modifier,
|
|
||||||
emails = user.value.amazonEmails,
|
|
||||||
onEmail = onEmail,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun DetailScreenEmailList(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
emails: List<String>,
|
|
||||||
onEmail: (email: String) -> Unit = default<String>(),
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier.fillMaxWidth(),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(top = MaterialTheme.bibLib.dimen.dp8)
|
|
||||||
.padding(horizontal = MaterialTheme.bibLib.dimen.dp16),
|
|
||||||
color = MaterialTheme.colors.primary,
|
|
||||||
style = MaterialTheme.typography.caption,
|
|
||||||
text = "Send this eBook to:",
|
|
||||||
)
|
|
||||||
|
|
||||||
LazyColumn {
|
|
||||||
items(items = emails) { email ->
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.clickable(onClick = { onEmail(email) })
|
|
||||||
.height(height = MaterialTheme.bibLib.dimen.dp52)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(
|
|
||||||
start = MaterialTheme.bibLib.dimen.dp16,
|
|
||||||
end = MaterialTheme.bibLib.dimen.dp8,
|
|
||||||
)
|
|
||||||
.weight(1f),
|
|
||||||
style = MaterialTheme.typography.body1,
|
|
||||||
color = MaterialTheme.colors.onSurface,
|
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
text = email
|
|
||||||
)
|
|
||||||
|
|
||||||
Icon(
|
|
||||||
modifier = Modifier.padding(end = MaterialTheme.bibLib.dimen.dp16),
|
|
||||||
imageVector = Icons.Default.NavigateNext,
|
|
||||||
contentDescription = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
|
|
||||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
private fun DetailScreenEmailListPreview() {
|
|
||||||
BibLibTheme {
|
|
||||||
DetailScreenEmailList(
|
|
||||||
emails = listOf(
|
|
||||||
"R.Giskard.Reventlov.Kindle@gmail.com",
|
|
||||||
"R.Daneel.Olivaw.Kindle@gmail.com",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,166 @@
|
||||||
|
package com.pixelized.biblib.ui.screen.home.detail
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.Button
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.RadioButton
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import androidx.compose.runtime.Stable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
import com.pixelized.biblib.R
|
||||||
|
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||||
|
import com.pixelized.biblib.utils.extention.bibLib
|
||||||
|
import com.pixelized.biblib.utils.extention.capitalize
|
||||||
|
|
||||||
|
@Stable
|
||||||
|
@Immutable
|
||||||
|
data class OptionUio(
|
||||||
|
val value: String,
|
||||||
|
val selected: Boolean = false,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DetailScreenSendOption(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
optionViewModel: BookOptionViewModel = hiltViewModel(),
|
||||||
|
onSend: (email: String, format: String) -> Unit = { _, _ -> },
|
||||||
|
) {
|
||||||
|
DetailScreenSendOption(
|
||||||
|
modifier = modifier,
|
||||||
|
emails = optionViewModel.emails,
|
||||||
|
formats = optionViewModel.formats,
|
||||||
|
onEmail = { optionViewModel.selectMail(it.value) },
|
||||||
|
onFormat = { optionViewModel.selectFormat(it.value) },
|
||||||
|
onSend = onSend,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DetailScreenSendOption(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
emails: List<OptionUio>,
|
||||||
|
formats: List<OptionUio>,
|
||||||
|
onEmail: (OptionUio) -> Unit = { },
|
||||||
|
onFormat: (OptionUio) -> Unit = { },
|
||||||
|
onSend: (email: String, format: String) -> Unit = { _, _ -> },
|
||||||
|
) {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = modifier.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(vertical = MaterialTheme.bibLib.dimen.dp8)
|
||||||
|
.padding(horizontal = MaterialTheme.bibLib.dimen.dp16),
|
||||||
|
color = MaterialTheme.colors.primary,
|
||||||
|
style = MaterialTheme.typography.caption,
|
||||||
|
text = stringResource(id = R.string.detail_option_mail),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
items(items = emails) { email ->
|
||||||
|
OptionItem(
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable { onEmail(email) }
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(all = MaterialTheme.bibLib.dimen.dp16),
|
||||||
|
uio = email,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(vertical = MaterialTheme.bibLib.dimen.dp8)
|
||||||
|
.padding(horizontal = MaterialTheme.bibLib.dimen.dp16),
|
||||||
|
color = MaterialTheme.colors.primary,
|
||||||
|
style = MaterialTheme.typography.caption,
|
||||||
|
text = stringResource(id = R.string.detail_option_mail),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
items(items = formats) { format ->
|
||||||
|
OptionItem(
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable { onFormat(format) }
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(all = MaterialTheme.bibLib.dimen.dp16),
|
||||||
|
uio = format,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Button(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = MaterialTheme.bibLib.dimen.dp16),
|
||||||
|
onClick = {
|
||||||
|
val format = formats.first { it.selected }
|
||||||
|
val email = emails.first { it.selected }
|
||||||
|
onSend(email.value, format.value)
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = R.string.detail_option_action)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun OptionItem(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
uio: OptionUio,
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = modifier,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
RadioButton(
|
||||||
|
selected = uio.selected,
|
||||||
|
onClick = null,
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(
|
||||||
|
start = MaterialTheme.bibLib.dimen.dp16,
|
||||||
|
end = MaterialTheme.bibLib.dimen.dp8,
|
||||||
|
)
|
||||||
|
.weight(1f),
|
||||||
|
style = MaterialTheme.typography.body1,
|
||||||
|
color = MaterialTheme.colors.onSurface,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
text = uio.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||||
|
private fun DetailScreenEmailListPreview() {
|
||||||
|
BibLibTheme {
|
||||||
|
DetailScreenSendOption(
|
||||||
|
emails = listOf(
|
||||||
|
OptionUio("R.Giskard.Reventlov.Kindle@gmail.com", selected = true),
|
||||||
|
OptionUio("R.Daneel.Olivaw.Kindle@gmail.com"),
|
||||||
|
),
|
||||||
|
formats = listOf(
|
||||||
|
OptionUio(Format.EPUB.capitalize(), selected = true),
|
||||||
|
OptionUio(Format.MOBI.capitalize()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -59,7 +59,10 @@
|
||||||
<string name="detail_release">Release</string>
|
<string name="detail_release">Release</string>
|
||||||
<string name="detail_genre">Genre</string>
|
<string name="detail_genre">Genre</string>
|
||||||
<string name="detail_series">Series</string>
|
<string name="detail_series">Series</string>
|
||||||
<string name="detail_emails_title">Send this eBook to:</string>
|
|
||||||
|
<string name="detail_option_mail">Send this eBook to:</string>
|
||||||
|
<string name="detail_option_format">Use this format:</string>
|
||||||
|
<string name="detail_option_action">Confirm</string>
|
||||||
|
|
||||||
<string name="detail_send_confirm_title">Send to your Kindle</string>
|
<string name="detail_send_confirm_title">Send to your Kindle</string>
|
||||||
<string name="detail_send_confirm_description">Make sure your Kindle has an internet connection, that %1$s is an approved expeditor and that the following email address is correctly set up on your Amazon Account.</string>
|
<string name="detail_send_confirm_description">Make sure your Kindle has an internet connection, that %1$s is an approved expeditor and that the following email address is correctly set up on your Amazon Account.</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue