mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-09 07:16:04 -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
|
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.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@ -36,97 +37,129 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
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.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import org.kiwix.kiwixmobile.core.R
|
import org.kiwix.kiwixmobile.core.R
|
||||||
import org.kiwix.kiwixmobile.core.extensions.faviconToPainter
|
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.SelectionMode
|
||||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
|
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
|
||||||
|
|
||||||
@Suppress("UnusedParameter", "LongMethod", "ComposableLambdaParameterNaming")
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun BookItem(
|
fun BookItem(
|
||||||
bookOnDisk: BookOnDisk,
|
bookOnDisk: BookOnDisk,
|
||||||
onClick: (BookOnDisk) -> Unit,
|
onClick: ((BookOnDisk) -> Unit)? = null,
|
||||||
onLongClick: (BookOnDisk) -> Unit,
|
onLongClick: ((BookOnDisk) -> Unit)? = null,
|
||||||
onMultiSelect: (BookOnDisk) -> Unit,
|
onMultiSelect: ((BookOnDisk) -> Unit)? = null,
|
||||||
selectionMode: SelectionMode,
|
selectionMode: SelectionMode = SelectionMode.NORMAL,
|
||||||
isCheckboxVisible: Boolean = false,
|
onCheckedChange: (Boolean) -> Unit = {}
|
||||||
isChecked: Boolean = false,
|
|
||||||
onCheckedChange: (Boolean) -> Unit = {},
|
|
||||||
tags: @Composable () -> Unit = {}
|
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(dimensionResource(id = R.dimen.card_margin))
|
.padding(FIVE_DP)
|
||||||
.clickable { onClick(bookOnDisk) },
|
.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,
|
shape = MaterialTheme.shapes.medium,
|
||||||
elevation = CardDefaults.elevatedCardElevation()
|
elevation = CardDefaults.elevatedCardElevation()
|
||||||
) {
|
) {
|
||||||
Row(
|
BookContent(bookOnDisk, selectionMode, onCheckedChange)
|
||||||
modifier = Modifier
|
}
|
||||||
.padding(dimensionResource(id = R.dimen.activity_horizontal_margin))
|
}
|
||||||
.fillMaxWidth(),
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
@Composable
|
||||||
) {
|
private fun BookContent(
|
||||||
if (isCheckboxVisible) {
|
bookOnDisk: BookOnDisk,
|
||||||
Checkbox(
|
selectionMode: SelectionMode,
|
||||||
checked = isChecked,
|
onCheckedChange: (Boolean) -> Unit
|
||||||
onCheckedChange = onCheckedChange,
|
) {
|
||||||
modifier = Modifier.padding(end = 10.dp)
|
Row(
|
||||||
)
|
modifier = Modifier.padding(SIXTEEN_DP).fillMaxWidth(),
|
||||||
}
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
Icon(
|
if (selectionMode == SelectionMode.MULTI) {
|
||||||
painter = bookOnDisk.book.faviconToPainter(),
|
BookCheckbox(bookOnDisk, onCheckedChange)
|
||||||
contentDescription = stringResource(R.string.fav_icon),
|
}
|
||||||
modifier = Modifier
|
BookIcon(bookOnDisk.book.faviconToPainter())
|
||||||
.size(40.dp)
|
BookDetails(Modifier.weight(1f), bookOnDisk)
|
||||||
.padding(end = 10.dp)
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
Column(
|
@Composable
|
||||||
modifier = Modifier.weight(1f)
|
private fun BookCheckbox(bookOnDisk: BookOnDisk, onCheckedChange: (Boolean) -> Unit) {
|
||||||
) {
|
Checkbox(
|
||||||
Text(
|
checked = bookOnDisk.isSelected,
|
||||||
text = bookOnDisk.book.title,
|
onCheckedChange = onCheckedChange,
|
||||||
style = MaterialTheme.typography.titleMedium
|
modifier = Modifier.padding(end = TEN_DP)
|
||||||
)
|
)
|
||||||
Text(
|
}
|
||||||
text = bookOnDisk.book.description.orEmpty(),
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
@Composable
|
||||||
maxLines = 2,
|
fun BookIcon(painter: Painter) {
|
||||||
overflow = TextOverflow.Ellipsis,
|
Icon(
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
painter = painter,
|
||||||
)
|
contentDescription = stringResource(R.string.fav_icon),
|
||||||
Row(
|
modifier = Modifier
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
.size(BOOK_ICON_SIZE)
|
||||||
modifier = Modifier.padding(top = 4.dp)
|
.padding(end = TEN_DP)
|
||||||
) {
|
)
|
||||||
Text(
|
}
|
||||||
text = bookOnDisk.book.date,
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
@Composable
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
private fun BookDetails(modifier: Modifier, bookOnDisk: BookOnDisk) {
|
||||||
)
|
Column(modifier = modifier) {
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
Text(
|
||||||
Text(
|
text = bookOnDisk.book.title,
|
||||||
text = bookOnDisk.book.size,
|
style = MaterialTheme.typography.titleMedium
|
||||||
style = MaterialTheme.typography.bodySmall,
|
)
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
Text(
|
||||||
)
|
text = bookOnDisk.book.description.orEmpty(),
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
Text(
|
maxLines = 2,
|
||||||
text = bookOnDisk.book.articleCount.orEmpty(),
|
overflow = TextOverflow.Ellipsis,
|
||||||
style = MaterialTheme.typography.bodySmall,
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
)
|
||||||
)
|
Row(
|
||||||
}
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
modifier = Modifier.padding(top = FOUR_DP)
|
||||||
tags()
|
) {
|
||||||
}
|
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.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
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
|
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.LanguageItem
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LanguageHeader(languageItem: LanguageItem) {
|
fun ZimFilesLanguageHeader(languageItem: LanguageItem) {
|
||||||
Text(
|
Text(
|
||||||
text = languageItem.text,
|
text = languageItem.text,
|
||||||
style = MaterialTheme.typography.titleMedium,
|
style = MaterialTheme.typography.titleMedium,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.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.EncodeHintType
|
||||||
import com.google.zxing.qrcode.QRCodeWriter
|
import com.google.zxing.qrcode.QRCodeWriter
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import androidx.core.graphics.createBitmap
|
||||||
|
import androidx.core.graphics.set
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to generate QR codes.
|
* Utility class to generate QR codes.
|
||||||
@ -47,10 +49,10 @@ class GenerateQR @Inject constructor() {
|
|||||||
it[EncodeHintType.MARGIN] = 1
|
it[EncodeHintType.MARGIN] = 1
|
||||||
}
|
}
|
||||||
val bits = QRCodeWriter().encode(code, BarcodeFormat.QR_CODE, size, size, hints)
|
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 (x in 0 until size) {
|
||||||
for (y 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 MINIMUM_HEIGHT_OF_QR_CODE = 76.dp
|
||||||
val MAXIMUM_HEIGHT_OF_QR_CODE = 128.dp
|
val MAXIMUM_HEIGHT_OF_QR_CODE = 128.dp
|
||||||
val MINIMUM_HEIGHT_OF_BOOKS_LIST = 256.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