BookInfoScreen: Cover Reset feature.
This commit is contained in:
parent
809ecb38c7
commit
45c1bd2b80
13 changed files with 235 additions and 37 deletions
|
|
@ -16,6 +16,10 @@ class FileParserImpl @Inject constructor(
|
||||||
private val fb2FileParser: Fb2FileParser
|
private val fb2FileParser: Fb2FileParser
|
||||||
) : FileParser {
|
) : FileParser {
|
||||||
override suspend fun parse(file: File): Pair<Book, CoverImage?>? {
|
override suspend fun parse(file: File): Pair<Book, CoverImage?>? {
|
||||||
|
if (!file.exists()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
val fileFormat = ".${file.name.substringAfterLast(".")}".lowercase().trim()
|
val fileFormat = ".${file.name.substringAfterLast(".")}".lowercase().trim()
|
||||||
|
|
||||||
if (fileFormat == ".pdf") {
|
if (fileFormat == ".pdf") {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,12 @@ class TextParserImpl @Inject constructor(
|
||||||
private val fb2TextParser: Fb2TextParser
|
private val fb2TextParser: Fb2TextParser
|
||||||
) : TextParser {
|
) : TextParser {
|
||||||
override suspend fun parse(file: File): Resource<List<String>> {
|
override suspend fun parse(file: File): Resource<List<String>> {
|
||||||
|
if (!file.exists()) {
|
||||||
|
return Resource.Error(
|
||||||
|
UIText.StringResource(R.string.error_something_went_wrong_with_file)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
val fileFormat = ".${file.name.substringAfterLast(".")}".lowercase().trim()
|
val fileFormat = ".${file.name.substringAfterLast(".")}".lowercase().trim()
|
||||||
|
|
||||||
if (fileFormat == ".pdf") {
|
if (fileFormat == ".pdf") {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,10 @@ package ua.acclorite.book_story.data.repository
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
|
import android.provider.MediaStore
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
import com.google.mlkit.common.model.DownloadConditions
|
import com.google.mlkit.common.model.DownloadConditions
|
||||||
|
|
@ -46,6 +48,7 @@ import ua.acclorite.book_story.domain.util.LanguageCode
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.util.UIText
|
||||||
import ua.acclorite.book_story.presentation.data.MainState
|
import ua.acclorite.book_story.presentation.data.MainState
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
@ -417,6 +420,46 @@ class BookRepositoryImpl @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun canResetCover(bookId: Int): Boolean {
|
||||||
|
val book = database.findBookById(bookId)
|
||||||
|
|
||||||
|
val defaultCoverUncompressed = fileParser.parse(File(book.filePath))?.second
|
||||||
|
?: return false
|
||||||
|
|
||||||
|
if (book.image == null) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
val stream = ByteArrayOutputStream()
|
||||||
|
defaultCoverUncompressed.copy(Bitmap.Config.RGB_565, false).compress(
|
||||||
|
Bitmap.CompressFormat.WEBP,
|
||||||
|
20,
|
||||||
|
stream
|
||||||
|
)
|
||||||
|
val byteArray = stream.toByteArray()
|
||||||
|
val defaultCover = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
|
||||||
|
|
||||||
|
val currentCover = MediaStore.Images.Media.getBitmap(
|
||||||
|
application.contentResolver,
|
||||||
|
Uri.parse(book.image)
|
||||||
|
)
|
||||||
|
|
||||||
|
return !defaultCover.sameAs(currentCover)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun resetCoverImage(bookId: Int): Boolean {
|
||||||
|
if (!canResetCover(bookId)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val book = database.findBookById(bookId)
|
||||||
|
val defaultCover = fileParser.parse(File(book.filePath))?.second
|
||||||
|
?: return false
|
||||||
|
updateCoverImageOfBook(bookMapper.toBook(book), defaultCover)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun <T> retrieveDataFromDataStore(
|
override suspend fun <T> retrieveDataFromDataStore(
|
||||||
key: Preferences.Key<T>,
|
key: Preferences.Key<T>,
|
||||||
defaultValue: T
|
defaultValue: T
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,12 @@ interface BookRepository {
|
||||||
books: List<Book>
|
books: List<Book>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
suspend fun canResetCover(
|
||||||
|
bookId: Int
|
||||||
|
): Boolean
|
||||||
|
|
||||||
|
suspend fun resetCoverImage(bookId: Int): Boolean
|
||||||
|
|
||||||
|
|
||||||
suspend fun <T> retrieveDataFromDataStore(
|
suspend fun <T> retrieveDataFromDataStore(
|
||||||
key: Preferences.Key<T>,
|
key: Preferences.Key<T>,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package ua.acclorite.book_story.domain.use_case
|
||||||
|
|
||||||
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class CanResetCover @Inject constructor(
|
||||||
|
private val repository: BookRepository
|
||||||
|
) {
|
||||||
|
|
||||||
|
suspend fun execute(bookId: Int): Boolean {
|
||||||
|
return repository.canResetCover(bookId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package ua.acclorite.book_story.domain.use_case
|
||||||
|
|
||||||
|
import ua.acclorite.book_story.domain.repository.BookRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ResetCoverImage @Inject constructor(
|
||||||
|
private val repository: BookRepository
|
||||||
|
) {
|
||||||
|
|
||||||
|
suspend fun execute(bookId: Int): Boolean {
|
||||||
|
return repository.resetCoverImage(bookId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,10 +7,13 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.HideImage
|
import androidx.compose.material.icons.filled.HideImage
|
||||||
import androidx.compose.material.icons.filled.ImageSearch
|
import androidx.compose.material.icons.filled.ImageSearch
|
||||||
|
import androidx.compose.material.icons.filled.Restore
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
|
@ -62,48 +65,86 @@ fun BookInfoChangeCoverBottomSheet(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
onEvent(BookInfoEvent.OnCheckCoverReset)
|
||||||
|
}
|
||||||
|
|
||||||
CustomBottomSheet(
|
CustomBottomSheet(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onDismissRequest = {
|
onDismissRequest = {
|
||||||
onEvent(BookInfoEvent.OnShowHideChangeCoverBottomSheet)
|
onEvent(BookInfoEvent.OnShowHideChangeCoverBottomSheet)
|
||||||
}
|
}
|
||||||
) { padding ->
|
) { padding ->
|
||||||
BookInfoChangeCoverBottomSheetItem(
|
LazyColumn(Modifier.fillMaxWidth()) {
|
||||||
icon = Icons.Default.ImageSearch,
|
if (state.value.canResetCover) {
|
||||||
text = stringResource(id = R.string.change_cover),
|
item {
|
||||||
description = stringResource(id = R.string.change_cover_desc)
|
BookInfoChangeCoverBottomSheetItem(
|
||||||
) {
|
icon = Icons.Default.Restore,
|
||||||
photoPicker.launch(
|
text = stringResource(id = R.string.reset_cover),
|
||||||
PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)
|
description = stringResource(id = R.string.reset_cover_desc)
|
||||||
)
|
) {
|
||||||
}
|
onEvent(
|
||||||
|
BookInfoEvent.OnResetCoverImage(
|
||||||
|
refreshList = {
|
||||||
|
onLibraryUpdateEvent(LibraryEvent.OnUpdateBook(it))
|
||||||
|
onHistoryUpdateEvent(HistoryEvent.OnUpdateBook(it))
|
||||||
|
},
|
||||||
|
showResult = {
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
it.asString(context),
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (state.value.book.coverImage != null) {
|
item {
|
||||||
BookInfoChangeCoverBottomSheetItem(
|
BookInfoChangeCoverBottomSheetItem(
|
||||||
icon = Icons.Default.HideImage,
|
icon = Icons.Default.ImageSearch,
|
||||||
text = stringResource(id = R.string.delete_cover),
|
text = stringResource(id = R.string.change_cover),
|
||||||
description = stringResource(id = R.string.delete_cover_desc)
|
description = stringResource(id = R.string.change_cover_desc)
|
||||||
) {
|
) {
|
||||||
onEvent(
|
photoPicker.launch(
|
||||||
BookInfoEvent.OnDeleteCover(
|
PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)
|
||||||
refreshList = {
|
)
|
||||||
onLibraryUpdateEvent(LibraryEvent.OnUpdateBook(it))
|
}
|
||||||
onHistoryUpdateEvent(HistoryEvent.OnUpdateBook(it))
|
}
|
||||||
}
|
|
||||||
|
if (state.value.book.coverImage != null) {
|
||||||
|
item {
|
||||||
|
BookInfoChangeCoverBottomSheetItem(
|
||||||
|
icon = Icons.Default.HideImage,
|
||||||
|
text = stringResource(id = R.string.delete_cover),
|
||||||
|
description = stringResource(id = R.string.delete_cover_desc)
|
||||||
|
) {
|
||||||
|
onEvent(
|
||||||
|
BookInfoEvent.OnDeleteCover(
|
||||||
|
refreshList = {
|
||||||
|
onLibraryUpdateEvent(LibraryEvent.OnUpdateBook(it))
|
||||||
|
onHistoryUpdateEvent(HistoryEvent.OnUpdateBook(it))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
context.getString(R.string.cover_image_deleted),
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
Spacer(
|
||||||
|
modifier = Modifier.height(
|
||||||
|
8.dp + padding
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
Toast.makeText(
|
|
||||||
context,
|
|
||||||
context.getString(R.string.cover_image_deleted),
|
|
||||||
Toast.LENGTH_LONG
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(
|
|
||||||
modifier = Modifier.height(
|
|
||||||
8.dp + padding
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.lazy.LazyItemScope
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
|
@ -22,9 +23,15 @@ import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change cover bottom sheet item.
|
* Change cover bottom sheet item.
|
||||||
|
*
|
||||||
|
* @param icon Icon.
|
||||||
|
* @param text Text.
|
||||||
|
* @param description Description of the item.
|
||||||
|
* @param verticalPadding Vertical item padding.
|
||||||
|
* @param onClick OnClick callback.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun BookInfoChangeCoverBottomSheetItem(
|
fun LazyItemScope.BookInfoChangeCoverBottomSheetItem(
|
||||||
icon: ImageVector,
|
icon: ImageVector,
|
||||||
text: String,
|
text: String,
|
||||||
description: String,
|
description: String,
|
||||||
|
|
@ -33,6 +40,7 @@ fun BookInfoChangeCoverBottomSheetItem(
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.animateItem()
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clickable {
|
.clickable {
|
||||||
onClick()
|
onClick()
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import androidx.compose.ui.focus.FocusRequester
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.model.Book
|
||||||
import ua.acclorite.book_story.domain.model.Category
|
import ua.acclorite.book_story.domain.model.Category
|
||||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||||
|
import ua.acclorite.book_story.domain.util.UIText
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
sealed class BookInfoEvent {
|
sealed class BookInfoEvent {
|
||||||
|
|
@ -17,6 +18,11 @@ sealed class BookInfoEvent {
|
||||||
data class OnChangeCover(val uri: Uri, val context: Context, val refreshList: (Book) -> Unit) :
|
data class OnChangeCover(val uri: Uri, val context: Context, val refreshList: (Book) -> Unit) :
|
||||||
BookInfoEvent()
|
BookInfoEvent()
|
||||||
|
|
||||||
|
data object OnCheckCoverReset : BookInfoEvent()
|
||||||
|
data class OnResetCoverImage(
|
||||||
|
val refreshList: (Book) -> Unit,
|
||||||
|
val showResult: (UIText) -> Unit
|
||||||
|
) : BookInfoEvent()
|
||||||
data object OnShowHideEditTitle : BookInfoEvent()
|
data object OnShowHideEditTitle : BookInfoEvent()
|
||||||
data class OnRequestFocus(val focusRequester: FocusRequester) : BookInfoEvent()
|
data class OnRequestFocus(val focusRequester: FocusRequester) : BookInfoEvent()
|
||||||
data class OnTitleValueChange(val value: String) : BookInfoEvent()
|
data class OnTitleValueChange(val value: String) : BookInfoEvent()
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ data class BookInfoState(
|
||||||
val titleValue: String = "",
|
val titleValue: String = "",
|
||||||
|
|
||||||
val showChangeCoverBottomSheet: Boolean = false,
|
val showChangeCoverBottomSheet: Boolean = false,
|
||||||
|
val canResetCover: Boolean = false,
|
||||||
|
|
||||||
val showDetailsBottomSheet: Boolean = false,
|
val showDetailsBottomSheet: Boolean = false,
|
||||||
|
|
||||||
val showDeleteDialog: Boolean = false,
|
val showDeleteDialog: Boolean = false,
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,18 @@ import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.Category
|
import ua.acclorite.book_story.domain.model.Category
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.model.History
|
||||||
import ua.acclorite.book_story.domain.model.NullableBook
|
import ua.acclorite.book_story.domain.model.NullableBook
|
||||||
|
import ua.acclorite.book_story.domain.use_case.CanResetCover
|
||||||
import ua.acclorite.book_story.domain.use_case.DeleteBooks
|
import ua.acclorite.book_story.domain.use_case.DeleteBooks
|
||||||
import ua.acclorite.book_story.domain.use_case.GetBookById
|
import ua.acclorite.book_story.domain.use_case.GetBookById
|
||||||
import ua.acclorite.book_story.domain.use_case.GetBookFromFile
|
import ua.acclorite.book_story.domain.use_case.GetBookFromFile
|
||||||
import ua.acclorite.book_story.domain.use_case.GetText
|
import ua.acclorite.book_story.domain.use_case.GetText
|
||||||
import ua.acclorite.book_story.domain.use_case.InsertHistory
|
import ua.acclorite.book_story.domain.use_case.InsertHistory
|
||||||
|
import ua.acclorite.book_story.domain.use_case.ResetCoverImage
|
||||||
import ua.acclorite.book_story.domain.use_case.UpdateBookWithText
|
import ua.acclorite.book_story.domain.use_case.UpdateBookWithText
|
||||||
import ua.acclorite.book_story.domain.use_case.UpdateBooks
|
import ua.acclorite.book_story.domain.use_case.UpdateBooks
|
||||||
import ua.acclorite.book_story.domain.use_case.UpdateCoverImageOfBook
|
import ua.acclorite.book_story.domain.use_case.UpdateCoverImageOfBook
|
||||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||||
|
import ua.acclorite.book_story.domain.util.UIText
|
||||||
import ua.acclorite.book_story.presentation.data.Screen
|
import ua.acclorite.book_story.presentation.data.Screen
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
@ -45,7 +48,9 @@ class BookInfoViewModel @Inject constructor(
|
||||||
private val deleteBooks: DeleteBooks,
|
private val deleteBooks: DeleteBooks,
|
||||||
private val getBookFromFile: GetBookFromFile,
|
private val getBookFromFile: GetBookFromFile,
|
||||||
private val getBookById: GetBookById,
|
private val getBookById: GetBookById,
|
||||||
private val getText: GetText
|
private val getText: GetText,
|
||||||
|
private val canResetCover: CanResetCover,
|
||||||
|
private val resetCoverImage: ResetCoverImage,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val _state = MutableStateFlow(BookInfoState())
|
private val _state = MutableStateFlow(BookInfoState())
|
||||||
|
|
@ -83,7 +88,8 @@ class BookInfoViewModel @Inject constructor(
|
||||||
book = it.book.copy(
|
book = it.book.copy(
|
||||||
coverImage = newCoverImage
|
coverImage = newCoverImage
|
||||||
),
|
),
|
||||||
showChangeCoverBottomSheet = false
|
showChangeCoverBottomSheet = false,
|
||||||
|
canResetCover = canResetCover.execute(bookId = it.book.id)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
event.refreshList(_state.value.book)
|
event.refreshList(_state.value.book)
|
||||||
|
|
@ -105,13 +111,52 @@ class BookInfoViewModel @Inject constructor(
|
||||||
book = it.book.copy(
|
book = it.book.copy(
|
||||||
coverImage = null
|
coverImage = null
|
||||||
),
|
),
|
||||||
showChangeCoverBottomSheet = false
|
showChangeCoverBottomSheet = false,
|
||||||
|
canResetCover = canResetCover.execute(bookId = it.book.id)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
event.refreshList(_state.value.book)
|
event.refreshList(_state.value.book)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is BookInfoEvent.OnCheckCoverReset -> {
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
_state.update {
|
||||||
|
it.copy(
|
||||||
|
canResetCover = canResetCover.execute(_state.value.book.id)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is BookInfoEvent.OnResetCoverImage -> {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val result = resetCoverImage.execute(_state.value.book.id)
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
event.showResult(UIText.StringResource(R.string.error_could_not_reset_cover))
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
|
||||||
|
val book = getBookById.execute(_state.value.book.id)
|
||||||
|
|
||||||
|
if (book == null) {
|
||||||
|
event.showResult(UIText.StringResource(R.string.error_something_went_wrong))
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
|
||||||
|
_state.update {
|
||||||
|
it.copy(
|
||||||
|
book = book,
|
||||||
|
showChangeCoverBottomSheet = false,
|
||||||
|
canResetCover = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
event.showResult(UIText.StringResource(R.string.cover_reset))
|
||||||
|
event.refreshList(_state.value.book)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
is BookInfoEvent.OnShowHideEditTitle -> {
|
is BookInfoEvent.OnShowHideEditTitle -> {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
val shouldHide = _state.value.editTitle
|
val shouldHide = _state.value.editTitle
|
||||||
|
|
@ -662,7 +707,10 @@ class BookInfoViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
_state.update {
|
_state.update {
|
||||||
BookInfoState(book = book)
|
BookInfoState(
|
||||||
|
book = book,
|
||||||
|
canResetCover = canResetCover.execute(screen.bookId)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@
|
||||||
<string name="error_wrong_language">Не можна вибрати цю мову.</string>
|
<string name="error_wrong_language">Не можна вибрати цю мову.</string>
|
||||||
<string name="error_could_not_download_language">Не вдалося завантажити мову.</string>
|
<string name="error_could_not_download_language">Не вдалося завантажити мову.</string>
|
||||||
<string name="error_could_not_download_languages">Не вдалося завантажити мови.</string>
|
<string name="error_could_not_download_languages">Не вдалося завантажити мови.</string>
|
||||||
|
<string name="error_could_not_reset_cover">Не вдалося скинути обкладинку.</string>
|
||||||
|
|
||||||
<!-- Is Empty messages -->
|
<!-- Is Empty messages -->
|
||||||
<string name="browse_empty">
|
<string name="browse_empty">
|
||||||
|
|
@ -186,6 +187,8 @@
|
||||||
<string name="read_more">Вам потрібно читати більше!</string>
|
<string name="read_more">Вам потрібно читати більше!</string>
|
||||||
<string name="read_keep">Так тримати!</string>
|
<string name="read_keep">Так тримати!</string>
|
||||||
<string name="read_done">Браво, ви повністю прочитали цю книгу!</string>
|
<string name="read_done">Браво, ви повністю прочитали цю книгу!</string>
|
||||||
|
<string name="reset_cover">Скинути обкладинку</string>
|
||||||
|
<string name="reset_cover_desc">Скиніть обкладинку книги до стандартної</string>
|
||||||
<string name="change_cover">Змінити обкладинку</string>
|
<string name="change_cover">Змінити обкладинку</string>
|
||||||
<string name="change_cover_desc">Виберіть нову обкладинку з ваших фото</string>
|
<string name="change_cover_desc">Виберіть нову обкладинку з ваших фото</string>
|
||||||
<string name="delete_cover">Видалити обкладинку</string>
|
<string name="delete_cover">Видалити обкладинку</string>
|
||||||
|
|
@ -294,6 +297,7 @@
|
||||||
<string name="translator_canceling">Переклад відміняється. Будь ласка, зачекайте.</string>
|
<string name="translator_canceling">Переклад відміняється. Будь ласка, зачекайте.</string>
|
||||||
<string name="translator_text_canceling">Перекладений текст відміняється. Будь ласка, зачекайте.</string>
|
<string name="translator_text_canceling">Перекладений текст відміняється. Будь ласка, зачекайте.</string>
|
||||||
<string name="translator_starting">Переклад скоро почнеться. Будь ласка, зачекайте.</string>
|
<string name="translator_starting">Переклад скоро почнеться. Будь ласка, зачекайте.</string>
|
||||||
|
<string name="cover_reset">Обкладинка була успішно скинута.</string>
|
||||||
|
|
||||||
<!-- Snackbar messages -->
|
<!-- Snackbar messages -->
|
||||||
<string name="history_element_deleted">Елемент історії був успішно видалений.</string>
|
<string name="history_element_deleted">Елемент історії був успішно видалений.</string>
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@
|
||||||
<string name="error_wrong_language">Cannot select this language.</string>
|
<string name="error_wrong_language">Cannot select this language.</string>
|
||||||
<string name="error_could_not_download_language">Could not download language.</string>
|
<string name="error_could_not_download_language">Could not download language.</string>
|
||||||
<string name="error_could_not_download_languages">Could not download languages.</string>
|
<string name="error_could_not_download_languages">Could not download languages.</string>
|
||||||
|
<string name="error_could_not_reset_cover">Could not reset cover image.</string>
|
||||||
|
|
||||||
<!-- Is Empty messages -->
|
<!-- Is Empty messages -->
|
||||||
<string name="browse_empty">
|
<string name="browse_empty">
|
||||||
|
|
@ -204,6 +205,8 @@
|
||||||
<string name="read_more">You need to read more!</string>
|
<string name="read_more">You need to read more!</string>
|
||||||
<string name="read_keep">Keep it up!</string>
|
<string name="read_keep">Keep it up!</string>
|
||||||
<string name="read_done">Well done, you have read the whole book!</string>
|
<string name="read_done">Well done, you have read the whole book!</string>
|
||||||
|
<string name="reset_cover">Reset cover image</string>
|
||||||
|
<string name="reset_cover_desc">Reset cover image of the book to the default</string>
|
||||||
<string name="change_cover">Change cover image</string>
|
<string name="change_cover">Change cover image</string>
|
||||||
<string name="change_cover_desc">Choose new cover from your photos</string>
|
<string name="change_cover_desc">Choose new cover from your photos</string>
|
||||||
<string name="delete_cover">Delete cover image</string>
|
<string name="delete_cover">Delete cover image</string>
|
||||||
|
|
@ -314,6 +317,7 @@
|
||||||
<string name="translator_canceling">Translation is canceling. Please wait.</string>
|
<string name="translator_canceling">Translation is canceling. Please wait.</string>
|
||||||
<string name="translator_text_canceling">Translated text is canceling. Please wait.</string>
|
<string name="translator_text_canceling">Translated text is canceling. Please wait.</string>
|
||||||
<string name="translator_starting">Translation will start soon. Please wait.</string>
|
<string name="translator_starting">Translation will start soon. Please wait.</string>
|
||||||
|
<string name="cover_reset">Cover image was successfully reset.</string>
|
||||||
|
|
||||||
<!-- Snackbar messages -->
|
<!-- Snackbar messages -->
|
||||||
<string name="history_element_deleted">History element was successfully deleted.</string>
|
<string name="history_element_deleted">History element was successfully deleted.</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue