mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 10:46:53 -04:00
Refined the BookItem
for better readability and maintainability.
* Created `ZimFileLanguageHeader` for showing the languages of ZIM files.
This commit is contained in:
parent
7cdcc0d021
commit
674ff5b24c
@ -18,7 +18,8 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.ui
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
@ -36,97 +37,129 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.extensions.faviconToPainter
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.BOOK_ICON_SIZE
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.EIGHT_DP
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.FIVE_DP
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.FOUR_DP
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.SIXTEEN_DP
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.TEN_DP
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
|
||||
|
||||
@Suppress("UnusedParameter", "LongMethod", "ComposableLambdaParameterNaming")
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun BookItem(
|
||||
bookOnDisk: BookOnDisk,
|
||||
onClick: (BookOnDisk) -> Unit,
|
||||
onLongClick: (BookOnDisk) -> Unit,
|
||||
onMultiSelect: (BookOnDisk) -> Unit,
|
||||
selectionMode: SelectionMode,
|
||||
isCheckboxVisible: Boolean = false,
|
||||
isChecked: Boolean = false,
|
||||
onCheckedChange: (Boolean) -> Unit = {},
|
||||
tags: @Composable () -> Unit = {}
|
||||
onClick: ((BookOnDisk) -> Unit)? = null,
|
||||
onLongClick: ((BookOnDisk) -> Unit)? = null,
|
||||
onMultiSelect: ((BookOnDisk) -> Unit)? = null,
|
||||
selectionMode: SelectionMode = SelectionMode.NORMAL,
|
||||
onCheckedChange: (Boolean) -> Unit = {}
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(dimensionResource(id = R.dimen.card_margin))
|
||||
.clickable { onClick(bookOnDisk) },
|
||||
.padding(FIVE_DP)
|
||||
.combinedClickable(
|
||||
onClick = {
|
||||
when (selectionMode) {
|
||||
SelectionMode.MULTI -> onMultiSelect?.invoke(bookOnDisk)
|
||||
SelectionMode.NORMAL -> onClick?.invoke(bookOnDisk)
|
||||
}
|
||||
},
|
||||
onLongClick = {
|
||||
if (selectionMode == SelectionMode.NORMAL) {
|
||||
onLongClick?.invoke(bookOnDisk)
|
||||
}
|
||||
}
|
||||
),
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
elevation = CardDefaults.elevatedCardElevation()
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(dimensionResource(id = R.dimen.activity_horizontal_margin))
|
||||
.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
if (isCheckboxVisible) {
|
||||
Checkbox(
|
||||
checked = isChecked,
|
||||
onCheckedChange = onCheckedChange,
|
||||
modifier = Modifier.padding(end = 10.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Icon(
|
||||
painter = bookOnDisk.book.faviconToPainter(),
|
||||
contentDescription = stringResource(R.string.fav_icon),
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.padding(end = 10.dp)
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = bookOnDisk.book.title,
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
Text(
|
||||
text = bookOnDisk.book.description.orEmpty(),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(top = 4.dp)
|
||||
) {
|
||||
Text(
|
||||
text = bookOnDisk.book.date,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = bookOnDisk.book.size,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = bookOnDisk.book.articleCount.orEmpty(),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
tags()
|
||||
}
|
||||
}
|
||||
BookContent(bookOnDisk, selectionMode, onCheckedChange)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BookContent(
|
||||
bookOnDisk: BookOnDisk,
|
||||
selectionMode: SelectionMode,
|
||||
onCheckedChange: (Boolean) -> Unit
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(SIXTEEN_DP).fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
if (selectionMode == SelectionMode.MULTI) {
|
||||
BookCheckbox(bookOnDisk, onCheckedChange)
|
||||
}
|
||||
BookIcon(bookOnDisk.book.faviconToPainter())
|
||||
BookDetails(Modifier.weight(1f), bookOnDisk)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BookCheckbox(bookOnDisk: BookOnDisk, onCheckedChange: (Boolean) -> Unit) {
|
||||
Checkbox(
|
||||
checked = bookOnDisk.isSelected,
|
||||
onCheckedChange = onCheckedChange,
|
||||
modifier = Modifier.padding(end = TEN_DP)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BookIcon(painter: Painter) {
|
||||
Icon(
|
||||
painter = painter,
|
||||
contentDescription = stringResource(R.string.fav_icon),
|
||||
modifier = Modifier
|
||||
.size(BOOK_ICON_SIZE)
|
||||
.padding(end = TEN_DP)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BookDetails(modifier: Modifier, bookOnDisk: BookOnDisk) {
|
||||
Column(modifier = modifier) {
|
||||
Text(
|
||||
text = bookOnDisk.book.title,
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
Text(
|
||||
text = bookOnDisk.book.description.orEmpty(),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(top = FOUR_DP)
|
||||
) {
|
||||
Text(
|
||||
text = bookOnDisk.book.date,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.width(EIGHT_DP))
|
||||
Text(
|
||||
text = bookOnDisk.book.size,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.width(EIGHT_DP))
|
||||
Text(
|
||||
text = bookOnDisk.book.articleCount.orEmpty(),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(FOUR_DP))
|
||||
TagsView(bookOnDisk.tags)
|
||||
}
|
||||
}
|
||||
|
@ -24,16 +24,16 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.EIGHT_DP
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.LanguageItem
|
||||
|
||||
@Composable
|
||||
fun LanguageHeader(languageItem: LanguageItem) {
|
||||
fun ZimFilesLanguageHeader(languageItem: LanguageItem) {
|
||||
Text(
|
||||
text = languageItem.text,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp)
|
||||
.padding(vertical = EIGHT_DP)
|
||||
)
|
||||
}
|
@ -24,6 +24,8 @@ import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.EncodeHintType
|
||||
import com.google.zxing.qrcode.QRCodeWriter
|
||||
import javax.inject.Inject
|
||||
import androidx.core.graphics.createBitmap
|
||||
import androidx.core.graphics.set
|
||||
|
||||
/**
|
||||
* Utility class to generate QR codes.
|
||||
@ -47,10 +49,10 @@ class GenerateQR @Inject constructor() {
|
||||
it[EncodeHintType.MARGIN] = 1
|
||||
}
|
||||
val bits = QRCodeWriter().encode(code, BarcodeFormat.QR_CODE, size, size, hints)
|
||||
return Bitmap.createBitmap(size, size, Bitmap.Config.RGB_565).also {
|
||||
return createBitmap(size, size, Bitmap.Config.RGB_565).also {
|
||||
for (x in 0 until size) {
|
||||
for (y in 0 until size) {
|
||||
it.setPixel(x, y, if (bits[x, y]) foregroundColor else backgroundColor)
|
||||
it[x, y] = if (bits[x, y]) foregroundColor else backgroundColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,4 +90,7 @@ object ComposeDimens {
|
||||
val MINIMUM_HEIGHT_OF_QR_CODE = 76.dp
|
||||
val MAXIMUM_HEIGHT_OF_QR_CODE = 128.dp
|
||||
val MINIMUM_HEIGHT_OF_BOOKS_LIST = 256.dp
|
||||
|
||||
// BookItem dimes
|
||||
val BOOK_ICON_SIZE = 40.dp
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user