Skip to content

Commit

Permalink
fix: #302
Browse files Browse the repository at this point in the history
Change-Id: I95a4dab6d04b5712c7308148f34288a9019df97a
  • Loading branch information
XayahSuSuSu committed Sep 8, 2024
1 parent 0d01e02 commit 8d72849
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 141 deletions.
127 changes: 25 additions & 102 deletions source/core/ui/src/main/kotlin/com/xayah/core/ui/component/Common.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.xayah.core.ui.component

import android.graphics.drawable.Drawable
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.ExperimentalLayoutApi
Expand All @@ -25,6 +23,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.Folder
import androidx.compose.material.icons.outlined.Shield
import androidx.compose.material.icons.rounded.MoreHoriz
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Checkbox
Expand All @@ -38,21 +37,14 @@ import androidx.compose.material3.VerticalDivider
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.xayah.core.model.database.MediaEntity
import com.xayah.core.model.database.PackageEntity
import com.xayah.core.model.util.formatSize
Expand All @@ -62,11 +54,6 @@ import com.xayah.core.ui.theme.value
import com.xayah.core.ui.theme.withState
import com.xayah.core.ui.token.AnimationTokens
import com.xayah.core.ui.token.SizeTokens
import com.xayah.core.util.PathUtil
import com.xayah.core.util.command.BaseUtil
import com.xayah.core.util.iconDir
import com.xayah.core.util.withIOContext
import kotlin.math.min

@ExperimentalMaterial3Api
@Composable
Expand Down Expand Up @@ -138,98 +125,34 @@ fun PackageIcons(
packages: List<PackageEntity>,
maxDisplayNum: Int = 6,
size: Dp = SizeTokens.Level24,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
onClick: () -> Unit,
) {
val context = LocalContext.current
var icons by remember { mutableStateOf(listOf<Drawable?>()) }
LaunchedEffect(packages) {
// Read icon from cached internal dir.
withIOContext {
val tmp = mutableListOf<Drawable?>()
for (i in 0 until min(maxDisplayNum, packages.size)) {
tmp.add(BaseUtil.readIcon(context, "${context.iconDir()}/${PathUtil.getPackageIconRelativePath(packages[i].packageName)}"))
}
icons = tmp
}
}

Row(modifier = modifier, horizontalArrangement = Arrangement.spacedBy(-SizeTokens.Level4)) {
for ((index, icon) in icons.withIndex()) {
if (index == icons.size - 1) break
if (icon == null) {
Surface(
modifier = Modifier.size(size),
shape = ClippedCircleShape,
color = ThemedColorSchemeKeyTokens.PrimaryContainer.value,
onClick = onClick,
indication = null,
interactionSource = interactionSource
) {
Box(contentAlignment = Alignment.Center) {
LabelMediumText(
text = "${packages.getOrNull(index)?.packageInfo?.label?.firstOrNull() ?: ""}",
color = ThemedColorSchemeKeyTokens.OnPrimaryContainer.value
)
}
}
} else {
AsyncImage(
modifier = Modifier
.size(size)
.clip(ClippedCircleShape),
model = ImageRequest.Builder(context)
.data(icon)
.crossfade(true)
.build(),
contentDescription = null
)
}
for (index in 0 until packages.size) {
if (index == packages.size - 1) break
PackageIconImage(
packageName = packages[index].packageName,
inCircleShape = true,
fromLocal = true,
size = size,
shape = ClippedCircleShape,
)
}

if (packages.size <= maxDisplayNum && icons.isNotEmpty()) {
val last = icons.last()
if (last == null) {
Surface(
modifier = Modifier.size(size),
shape = CircleShape,
color = ThemedColorSchemeKeyTokens.PrimaryContainer.value,
onClick = onClick,
indication = null,
interactionSource = interactionSource
) {
Box(contentAlignment = Alignment.Center) {
LabelMediumText(
text = "${packages.getOrNull(icons.lastIndex)?.packageInfo?.label?.firstOrNull() ?: ""}",
color = ThemedColorSchemeKeyTokens.OnPrimaryContainer.value
)
}
}
} else {
AsyncImage(
modifier = Modifier
.size(size)
.clip(CircleShape),
model = ImageRequest.Builder(context)
.data(last)
.crossfade(true)
.build(),
contentDescription = null
)
}
} else if (packages.size - maxDisplayNum > 0) {
Surface(
modifier = Modifier.size(size),
shape = CircleShape,
color = ThemedColorSchemeKeyTokens.PrimaryContainer.value,
onClick = onClick,
indication = null,
interactionSource = interactionSource
) {
Box(contentAlignment = Alignment.Center) {
LabelMediumText(text = "+${packages.size - maxDisplayNum + 1}", color = ThemedColorSchemeKeyTokens.OnPrimaryContainer.value)
}
}
// Last item
if (packages.size <= maxDisplayNum && packages.isNotEmpty()) {
PackageIconImage(
packageName = packages.last().packageName,
inCircleShape = true,
fromLocal = true,
size = size,
)
} else if (packages.size > maxDisplayNum) {
PackageIconImage(
icon = Icons.Rounded.MoreHoriz,
packageName = "",
inCircleShape = true,
size = size,
)
}
}
}
Expand Down
73 changes: 39 additions & 34 deletions source/core/ui/src/main/kotlin/com/xayah/core/ui/component/Image.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.xayah.core.ui.component

import android.graphics.Bitmap
import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
Expand All @@ -25,12 +26,15 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.core.graphics.drawable.toBitmap
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.xayah.core.ui.R
Expand All @@ -46,7 +50,7 @@ import kotlin.math.sqrt

@ExperimentalFoundationApi
@Composable
fun PackageIconImage(icon: ImageVector? = null, packageName: String, inCircleShape: Boolean = false, fromLocal: Boolean = false, size: Dp = SizeTokens.Level32) {
fun PackageIconImage(icon: ImageVector? = null, packageName: String, shape: Shape? = null, inCircleShape: Boolean = false, fromLocal: Boolean = false, size: Dp = SizeTokens.Level32) {
val context = LocalContext.current
val scope = rememberCoroutineScope()
var iconForeground by remember(packageName, icon) { mutableStateOf<Drawable?>(null) }
Expand Down Expand Up @@ -85,40 +89,41 @@ fun PackageIconImage(icon: ImageVector? = null, packageName: String, inCircleSha
}
}

Box(contentAlignment = Alignment.Center) {
if (inCircleShape)
AsyncImage(
modifier = Modifier
.size(size)
.clip(CircleShape)
.scale(1.4f)
.background(ThemedColorSchemeKeyTokens.PrimaryContainer.value),
model = ImageRequest.Builder(context)
.data(iconBackground)
.crossfade(true)
.build(),
contentDescription = null
)
if (icon != null) {
Icon(
imageVector = icon,
modifier = Modifier
.size(sizeForeground),
contentDescription = null,
tint = ThemedColorSchemeKeyTokens.Primary.value
)
} else {
AsyncImage(
modifier = Modifier
.size(sizeForeground),
model = ImageRequest.Builder(context)
.data(iconForeground)
.crossfade(true)
.build(),
contentDescription = null,
)
Box(modifier = if (shape != null) Modifier.clip(shape) else Modifier, contentAlignment = Alignment.Center) {
with(LocalDensity.current) {
if (inCircleShape)
AsyncImage(
modifier = Modifier
.size(size)
.clip(CircleShape)
.scale(1.4f)
.background(ThemedColorSchemeKeyTokens.PrimaryContainer.value),
model = ImageRequest.Builder(context)
.data(iconBackground?.toBitmap(sizeForeground.roundToPx(), sizeForeground.roundToPx(), Bitmap.Config.ARGB_8888))
.crossfade(true)
.build(),
contentDescription = null
)
if (icon != null) {
Icon(
imageVector = icon,
modifier = Modifier
.size(sizeForeground),
contentDescription = null,
tint = ThemedColorSchemeKeyTokens.Primary.value
)
} else {
AsyncImage(
modifier = Modifier
.size(sizeForeground),
model = ImageRequest.Builder(context)
.data(iconForeground?.toBitmap(sizeForeground.roundToPx(), sizeForeground.roundToPx(), Bitmap.Config.ARGB_8888))
.crossfade(true)
.build(),
contentDescription = null,
)
}
}

}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ fun LabelMediumText(
textAlign: TextAlign? = null,
fontWeight: FontWeight? = null,
textDecoration: TextDecoration? = null,
overflow: TextOverflow = TextOverflow.Ellipsis,
maxLines: Int = Int.MAX_VALUE,
enabled: Boolean = true,
) {
Text(
Expand All @@ -210,6 +212,8 @@ fun LabelMediumText(
textAlign = textAlign,
fontWeight = fontWeight,
textDecoration = textDecoration,
overflow = overflow,
maxLines = maxLines,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ fun PagePackagesBackupProcessingSetup(localNavController: NavHostController, vie
leadingIcon = ImageVector.vectorResource(id = R.drawable.ic_rounded_apps),
interactionSource = interactionSource,
content = {
PackageIcons(modifier = Modifier.paddingTop(SizeTokens.Level8), packages = packages, interactionSource = interactionSource) {}
PackageIcons(modifier = Modifier.paddingTop(SizeTokens.Level8), packages = packages)
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fun PagePackagesRestoreProcessingSetup(localNavController: NavHostController, vi
leadingIcon = ImageVector.vectorResource(id = R.drawable.ic_rounded_apps),
interactionSource = interactionSource,
content = {
PackageIcons(modifier = Modifier.paddingTop(SizeTokens.Level8), packages = packages, interactionSource = interactionSource) {}
PackageIcons(modifier = Modifier.paddingTop(SizeTokens.Level8), packages = packages)
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,7 @@ fun PageRestore() {
interactionSource = appsInteractionSource,
content = if (uiState.packages.isEmpty()) null else {
{
PackageIcons(modifier = Modifier.paddingTop(SizeTokens.Level8), packages = uiState.packages, interactionSource = appsInteractionSource) {
viewModel.emitIntentOnIO(IndexUiIntent.ToAppList(navController))
}
PackageIcons(modifier = Modifier.paddingTop(SizeTokens.Level8), packages = uiState.packages)
}
}
) {
Expand Down

0 comments on commit 8d72849

Please sign in to comment.