Improve performance

This commit is contained in:
T8RIN
2025-05-06 22:33:56 +03:00
parent 99b0050cb0
commit 5ae0490230
23 changed files with 183 additions and 160 deletions

View File

@ -29,7 +29,7 @@ import ru.tech.imageresizershrinker.core.data.image.toMetadata
import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.image.clearAllAttributes
import ru.tech.imageresizershrinker.core.domain.image.copyTo
import ru.tech.imageresizershrinker.core.domain.utils.readableByteCount
import ru.tech.imageresizershrinker.core.domain.utils.humanFileSize
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import java.io.OutputStream
@ -103,7 +103,7 @@ internal fun Context.cacheSize(): String = runCatching {
externalCacheDirs?.forEach { file ->
size += file?.walkTopDown()?.sumOf { if (it.isFile) it.length() else 0 } ?: 0
}
readableByteCount(size)
humanFileSize(size)
}.getOrNull() ?: "0 B"

View File

@ -22,7 +22,7 @@ import java.text.StringCharacterIterator
import java.util.Locale
fun readableByteCount(bytes: Long): String {
fun humanFileSize(bytes: Long): String {
var tempBytes = bytes
if (-1024 < tempBytes && tempBytes < 1024) {
return "$tempBytes B"

View File

@ -37,8 +37,8 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ru.tech.imageresizershrinker.core.domain.remote.RemoteResourcesDownloadProgress
import ru.tech.imageresizershrinker.core.domain.utils.readableByteCount
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.rememberHumanFileSize
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.BasicEnhancedAlertDialog
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedAlertDialog
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedButton
@ -114,7 +114,7 @@ internal fun CubeLutDownloadDialog(
)
Spacer(Modifier.height(2.dp))
Text(
text = readableByteCount(cubeLutDownloadProgress?.currentTotalSize ?: 0),
text = rememberHumanFileSize(cubeLutDownloadProgress?.currentTotalSize ?: 0),
maxLines = 1,
textAlign = TextAlign.Center,
fontSize = 10.sp,

View File

@ -38,10 +38,14 @@ import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ErrorOutline
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.graphics.takeOrElse
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.Density
import androidx.core.app.ActivityCompat
import androidx.core.app.PendingIntentCompat
@ -180,7 +184,7 @@ object ContextUtils {
): Boolean = validInstallers.contains(getInstallerPackageName(packageName))
private fun Context.getInstallerPackageName(packageName: String): String? {
kotlin.runCatching {
runCatching {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
return packageManager.getInstallSourceInfo(packageName).installingPackageName
@Suppress("DEPRECATION")
@ -197,6 +201,28 @@ object ContextUtils {
DocumentFile.fromSingleUri(this, uri)?.name
}?.decodeEscaped()
@Composable
fun rememberFilename(uri: Uri): String? {
val context = LocalContext.current
return remember(context, uri) {
derivedStateOf {
context.getFilename(uri)
}
}.value
}
@Composable
fun rememberFileExtension(uri: Uri): String? {
val context = LocalContext.current
return remember(context, uri) {
derivedStateOf {
context.getExtension(uri)
}
}.value
}
fun Activity.parseImageFromIntent(
intent: Intent?,
onStart: () -> Unit,
@ -632,7 +658,7 @@ object ContextUtils {
startActivity(shareIntent)
}
private fun Context.getExtension(uri: Uri): String? {
fun Context.getExtension(uri: Uri): String? {
val filename = getFilename(uri) ?: ""
if (filename.endsWith(".qoi")) return "qoi"
if (filename.endsWith(".jxl")) return "jxl"

View File

@ -26,6 +26,7 @@ import android.os.Build.VERSION.SDK_INT
import android.provider.OpenableColumns
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.platform.LocalContext
@ -35,6 +36,7 @@ import androidx.core.graphics.scale
import androidx.core.text.isDigitsOnly
import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
import ru.tech.imageresizershrinker.core.domain.utils.humanFileSize
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getStringLocalized
import java.util.Locale
@ -228,7 +230,7 @@ object ImageUtils {
it in possibleConfigs
} ?: Bitmap.Config.ARGB_8888
fun Uri.fileSize(context: Context): Long? {
private fun Uri.fileSize(context: Context): Long? {
runCatching {
context.contentResolver
.query(this, null, null, null, null, null)
@ -244,6 +246,37 @@ object ImageUtils {
return null
}
@Composable
fun rememberFileSize(uri: Uri?): Long {
val context = LocalContext.current
return remember(uri, context) {
derivedStateOf {
uri?.fileSize(context) ?: 0L
}
}.value
}
@Composable
fun rememberHumanFileSize(uri: Uri): String {
val size = rememberFileSize(uri)
return remember(size, uri) {
derivedStateOf {
humanFileSize(size)
}
}.value
}
@Composable
fun rememberHumanFileSize(byteCount: Long): String {
return remember(byteCount) {
derivedStateOf {
humanFileSize(byteCount)
}
}.value
}
object Dimens {
const val MAX_IMAGE_SIZE = 8388607 * 16
}

View File

@ -214,3 +214,8 @@ fun Uri.isJxl(context: Context): Boolean {
return context.getFilename(this).toString().endsWith(".jxl")
.or(context.contentResolver.getType(this)?.contains("jxl") == true)
}
fun Uri.isGif(context: Context): Boolean {
return context.getFilename(this).toString().endsWith(".gif")
.or(context.contentResolver.getType(this)?.contains("gif") == true)
}

View File

@ -39,7 +39,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@ -50,7 +49,7 @@ import ru.tech.imageresizershrinker.core.resources.shapes.CloverShape
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.Picker
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberFilePicker
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberImagePicker
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.rememberFilename
import ru.tech.imageresizershrinker.core.ui.widget.dialogs.OneTimeImagePickingDialog
import ru.tech.imageresizershrinker.core.ui.widget.image.Picture
import ru.tech.imageresizershrinker.core.ui.widget.preferences.PreferenceItemOverload
@ -137,12 +136,10 @@ fun FileSelector(
) {
val pickFileLauncher = rememberFilePicker(onSuccess = onValueChange)
val context = LocalContext.current
PreferenceItemOverload(
title = title,
subtitle = if (subtitle == null && value != null) {
context.getFilename(value.toUri())
rememberFilename(value.toUri())
} else subtitle,
onClick = pickFileLauncher::pickFile,
autoShadowElevation = autoShadowElevation,

View File

@ -65,7 +65,6 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateListOf
@ -81,7 +80,6 @@ import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.IntOffset
@ -97,7 +95,7 @@ import ru.tech.imageresizershrinker.core.resources.icons.BrokenImageAlt
import ru.tech.imageresizershrinker.core.resources.icons.EditAlt
import ru.tech.imageresizershrinker.core.ui.theme.White
import ru.tech.imageresizershrinker.core.ui.theme.takeColorFromScheme
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.rememberFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.PredictiveBackObserver
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalScreenSize
@ -373,14 +371,8 @@ fun ImagePager(
}
)
}
val context = LocalContext.current
val selectedUriFilename by remember(selectedUri) {
derivedStateOf {
selectedUri?.let {
context.getFilename(it)
}
}
}
val selectedUriFilename = selectedUri?.let { rememberFilename(it) }
val showBottomHist = pagerState.currentPage !in imageErrorPages && moreThanOneUri
AnimatedVisibility(

View File

@ -69,7 +69,6 @@ import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.text.font.FontWeight
@ -83,7 +82,7 @@ import ru.tech.imageresizershrinker.core.domain.image.model.ImageFrames
import ru.tech.imageresizershrinker.core.resources.icons.BrokenImageAlt
import ru.tech.imageresizershrinker.core.ui.theme.White
import ru.tech.imageresizershrinker.core.ui.theme.takeColorFromScheme
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.rememberFileExtension
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalScreenSize
import ru.tech.imageresizershrinker.core.ui.widget.modifier.advancedShadow
import ru.tech.imageresizershrinker.core.ui.widget.modifier.dragHandler
@ -412,14 +411,7 @@ private fun ImageItem(
aboveImageContent(index)
if (showExtension) {
val context = LocalContext.current
val extension by remember(uri) {
derivedStateOf {
uri.toUri().let { uri ->
context.getFilename(uri)?.takeLastWhile { it != '.' }?.uppercase()
}
}
}
val extension = rememberFileExtension(uri.toUri())?.uppercase()
extension?.let {
Row(

View File

@ -41,7 +41,6 @@ import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@ -50,7 +49,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
@ -59,7 +57,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.ui.theme.takeColorFromScheme
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.rememberFilename
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.hapticsClickable
import ru.tech.imageresizershrinker.core.ui.widget.modifier.container
import ru.tech.imageresizershrinker.core.ui.widget.text.AutoSizeText
@ -94,8 +92,6 @@ fun UrisPreview(
showScrimForNonSuccess: Boolean = true,
filenameSource: (index: Int) -> Uri = { uris[it] }
) {
val context = LocalContext.current
BoxWithConstraints {
val size = uris.size + 1f
@ -192,11 +188,8 @@ fun UrisPreview(
),
)
}
val filename by remember(filenameSource, index) {
derivedStateOf {
context.getFilename(filenameSource(index))
}
}
val filename = rememberFilename(filenameSource(index))
filename?.let {
AutoSizeText(
text = it,

View File

@ -24,15 +24,18 @@ import androidx.compose.animation.togetherWith
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import ru.tech.imageresizershrinker.core.domain.utils.readableByteCount
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.ui.theme.Green
import ru.tech.imageresizershrinker.core.ui.theme.blend
import ru.tech.imageresizershrinker.core.ui.theme.takeColorFromScheme
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.rememberHumanFileSize
@Composable
fun <T : Any> TopAppBarTitle(
@ -64,12 +67,12 @@ fun <T : Any> TopAppBarTitle(
} else {
AnimatedContent(originalSize) { originalSize ->
val readableOriginal = if ((originalSize ?: 0) > 0) {
readableByteCount(originalSize ?: 0)
rememberHumanFileSize(originalSize ?: 0)
} else {
"? B"
}
val readableCompressed = if (size > 0) {
readableByteCount(size)
rememberHumanFileSize(size)
} else {
"(...)"
}
@ -83,21 +86,36 @@ fun <T : Any> TopAppBarTitle(
else -> Green
}
}
Text(
text = buildAnnotatedString {
val textStyle = LocalTextStyle.current
val sizeString = stringResource(R.string.size, readableCompressed)
val text by remember(
originalSize,
isSizesEqual,
sizeString,
readableOriginal,
readableCompressed,
textStyle
) {
derivedStateOf {
buildAnnotatedString {
append(
if (originalSize == null || isSizesEqual) {
stringResource(R.string.size, readableCompressed)
} else ""
if (originalSize == null || isSizesEqual) sizeString else ""
)
originalSize?.takeIf { !isSizesEqual }?.let {
append(readableOriginal)
append(" -> ")
withStyle(LocalTextStyle.current.toSpanStyle().copy(color)) {
withStyle(textStyle.toSpanStyle().copy(color)) {
append(readableCompressed)
}
}
}
}
}
Text(
text = text
)
}
}
@ -117,8 +135,8 @@ fun <T : Any> TopAppBarTitle(
Text(it)
}
} else {
val readableOriginal = readableByteCount(originalSize ?: 0)
val readableCompressed = readableByteCount(size)
val readableOriginal = rememberHumanFileSize(originalSize ?: 0)
val readableCompressed = rememberHumanFileSize(size)
val isSizesEqual =
size == originalSize || readableCompressed == readableOriginal
val color = takeColorFromScheme {
@ -128,21 +146,36 @@ fun <T : Any> TopAppBarTitle(
else -> Green
}
}
Text(
text = buildAnnotatedString {
val textStyle = LocalTextStyle.current
val sizeString = stringResource(R.string.size, readableCompressed)
val text by remember(
originalSize,
isSizesEqual,
sizeString,
readableOriginal,
readableCompressed,
textStyle
) {
derivedStateOf {
buildAnnotatedString {
append(
if (originalSize == null || isSizesEqual) {
stringResource(R.string.size, readableCompressed)
} else ""
if (originalSize == null || isSizesEqual) sizeString else ""
)
originalSize?.takeIf { !isSizesEqual }?.let {
append(readableOriginal)
append(" -> ")
withStyle(LocalTextStyle.current.toSpanStyle().copy(color)) {
withStyle(textStyle.toSpanStyle().copy(color)) {
append(readableCompressed)
}
}
}
}
}
Text(
text = text
)
}
}

View File

@ -17,22 +17,17 @@
package ru.tech.imageresizershrinker.core.ui.widget.utils
import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import android.webkit.MimeTypeMap
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.core.net.toUri
import ru.tech.imageresizershrinker.core.domain.model.ExtraDataType
import ru.tech.imageresizershrinker.core.settings.presentation.provider.LocalSettingsState
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getExtension
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
import java.util.Locale
@Composable
internal fun List<Uri>.screenList(
@ -46,7 +41,7 @@ internal fun List<Uri>.screenList(
): Boolean {
if (this == null) return false
val extension = context.getExtension(toString()) ?: return false
val extension = context.getExtension(this) ?: return false
return extensions.any(extension::contains)
}
@ -307,19 +302,3 @@ internal fun List<Uri>.screenList(
}
}
}
private fun Context.getExtension(
uri: String
): String? {
val filename = getFilename(uri.toUri()) ?: ""
if (filename.endsWith(".qoi")) return "qoi"
if (filename.endsWith(".jxl")) return "jxl"
return if (ContentResolver.SCHEME_CONTENT == uri.toUri().scheme) {
MimeTypeMap.getSingleton()
.getExtensionFromMimeType(
contentResolver.getType(uri.toUri())
)
} else {
MimeTypeMap.getFileExtensionFromUrl(uri).lowercase(Locale.getDefault())
}?.replace(".", "")
}

View File

@ -28,17 +28,15 @@ import androidx.compose.material.icons.outlined.FilePresent
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import ru.tech.imageresizershrinker.core.data.utils.fileSize
import ru.tech.imageresizershrinker.core.domain.utils.readableByteCount
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.resources.shapes.CloverShape
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.rememberFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.rememberHumanFileSize
import ru.tech.imageresizershrinker.core.ui.widget.preferences.PreferenceItemOverload
@Composable
@ -48,15 +46,9 @@ internal fun UriWithHashItem(
) {
val (uri, checksum) = uriWithHash
val context = LocalContext.current
val filename = rememberFilename(uri) ?: stringResource(R.string.filename)
val filename = remember {
context.getFilename(uri)
?: context.getString(R.string.filename)
}
val fileSize = remember {
readableByteCount(uri.fileSize(context) ?: 0L)
}
val fileSize = rememberHumanFileSize(uri)
Column(
modifier = Modifier.fillMaxWidth(),

View File

@ -53,22 +53,20 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ru.tech.imageresizershrinker.core.domain.model.CipherType
import ru.tech.imageresizershrinker.core.domain.utils.readableByteCount
import ru.tech.imageresizershrinker.core.domain.utils.toInt
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.settings.presentation.provider.LocalSettingsState
import ru.tech.imageresizershrinker.core.ui.theme.Green
import ru.tech.imageresizershrinker.core.ui.theme.outlineVariant
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberFileCreator
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.fileSize
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.rememberFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.rememberHumanFileSize
import ru.tech.imageresizershrinker.core.ui.utils.helper.isPortraitOrientationAsState
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
import ru.tech.imageresizershrinker.core.ui.widget.buttons.ToggleGroupButton
@ -86,7 +84,6 @@ import kotlin.random.Random
internal fun CipherControls(component: CipherComponent) {
val settingsState = LocalSettingsState.current
val isPortrait by isPortraitOrientationAsState()
val context = LocalContext.current
val essentials = rememberLocalEssentials()
val showConfetti: () -> Unit = essentials::showConfetti
@ -99,6 +96,10 @@ internal fun CipherControls(component: CipherComponent) {
}
)
val filename = component.uri?.let {
rememberFilename(it)
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
if (isPortrait) Spacer(Modifier.height(20.dp))
Row(
@ -140,9 +141,7 @@ internal fun CipherControls(component: CipherComponent) {
Spacer(Modifier.height(16.dp))
PreferenceItem(
modifier = Modifier,
title = component.uri?.let {
context.getFilename(it)
} ?: stringResource(R.string.something_went_wrong),
title = filename ?: stringResource(R.string.something_went_wrong),
onClick = null,
titleFontStyle = LocalTextStyle.current.copy(
lineHeight = 16.sp,
@ -151,9 +150,7 @@ internal fun CipherControls(component: CipherComponent) {
subtitle = component.uri?.let {
stringResource(
id = R.string.size,
readableByteCount(
it.fileSize(context) ?: 0L
)
rememberHumanFileSize(it)
)
},
startIcon = Icons.AutoMirrored.Rounded.InsertDriveFile
@ -245,15 +242,13 @@ internal fun CipherControls(component: CipherComponent) {
lineHeight = 14.sp,
modifier = Modifier.padding(vertical = 16.dp)
)
var name by rememberSaveable(component.byteArray) {
var name by rememberSaveable(component.byteArray, filename) {
mutableStateOf(
if (component.isEncrypt) {
"enc-"
} else {
"dec-"
} + (component.uri?.let {
context.getFilename(it)
} ?: Random.nextInt())
} + (filename ?: Random.nextInt())
)
}
RoundedTextField(

View File

@ -25,16 +25,15 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.rememberFilename
@Composable
internal fun BoxScope.CompareLabel(
@ -48,12 +47,9 @@ internal fun BoxScope.CompareLabel(
visible = enabled && uri != null,
modifier = modifier.align(alignment)
) {
val context = LocalContext.current
Text(
text = remember(uri) {
uri?.let { context.getFilename(it) }
?: context.getString(R.string.filename)
},
text = uri?.let { rememberFilename(it) }
?: stringResource(R.string.filename),
modifier = Modifier
.background(
color = MaterialTheme.colorScheme.scrim.copy(0.4f),

View File

@ -32,7 +32,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import ru.tech.imageresizershrinker.core.resources.R
@ -40,8 +39,8 @@ import ru.tech.imageresizershrinker.core.resources.icons.Exif
import ru.tech.imageresizershrinker.core.resources.icons.MiniEdit
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.Picker
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberImagePicker
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.fileSize
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.localizedName
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.rememberFileSize
import ru.tech.imageresizershrinker.core.ui.utils.helper.asClip
import ru.tech.imageresizershrinker.core.ui.utils.helper.isPortraitOrientationAsState
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalComponentActivity
@ -124,7 +123,7 @@ fun DeleteExifContent(
title = stringResource(R.string.delete_exif),
input = component.bitmap,
isLoading = component.isImageLoading,
size = component.selectedUri?.fileSize(LocalContext.current) ?: 0L
size = rememberFileSize(component.selectedUri)
)
},
onGoBack = {

View File

@ -36,7 +36,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import coil3.toBitmap
@ -46,7 +45,7 @@ import ru.tech.imageresizershrinker.core.resources.icons.Exif
import ru.tech.imageresizershrinker.core.resources.icons.MiniEdit
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.Picker
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberImagePicker
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.fileSize
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.rememberFileSize
import ru.tech.imageresizershrinker.core.ui.utils.helper.asClip
import ru.tech.imageresizershrinker.core.ui.utils.helper.isPortraitOrientationAsState
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalComponentActivity
@ -126,7 +125,7 @@ fun EditExifContent(
title = stringResource(R.string.edit_exif_screen),
input = component.uri.takeIf { it != Uri.EMPTY },
isLoading = component.isImageLoading,
size = component.uri.fileSize(LocalContext.current) ?: 0L
size = rememberFileSize(component.uri)
)
},
onGoBack = onBack,

View File

@ -17,7 +17,6 @@
package ru.tech.imageresizershrinker.feature.gif_tools.presentation
import android.content.Context
import android.net.Uri
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.layout.WindowInsets
@ -37,7 +36,7 @@ import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.Picker
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberFileCreator
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberFilePicker
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberImagePicker
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.isGif
import ru.tech.imageresizershrinker.core.ui.utils.helper.isPortraitOrientationAsState
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalComponentActivity
@ -310,11 +309,6 @@ fun GifToolsContent(
)
}
private fun Uri.isGif(context: Context): Boolean {
return context.getFilename(this).toString().endsWith(".gif")
.or(context.contentResolver.getType(this)?.contains("gif") == true)
}
private val GifToolsComponent.canSave: Boolean
get() = (gifFrames == ImageFrames.All)
.or(type is Screen.GifTools.Type.ImageToGif)

View File

@ -28,13 +28,12 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.Picker
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberImagePicker
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.fileSize
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.rememberFileSize
import ru.tech.imageresizershrinker.core.ui.utils.helper.asClip
import ru.tech.imageresizershrinker.core.ui.utils.helper.isPortraitOrientationAsState
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalComponentActivity
@ -128,7 +127,7 @@ fun LimitsResizeContent(
title = stringResource(R.string.limits_resize),
input = component.bitmap,
isLoading = component.isImageLoading,
size = component.selectedUri?.fileSize(LocalContext.current) ?: 0L
size = rememberFileSize(component.selectedUri)
)
},
onGoBack = onBack,

View File

@ -48,8 +48,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ru.tech.imageresizershrinker.core.domain.utils.readableByteCount
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.rememberHumanFileSize
import ru.tech.imageresizershrinker.core.ui.utils.helper.plus
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedIconButton
@ -159,9 +159,8 @@ fun MeshGradientsContent(
)
Spacer(Modifier.height(2.dp))
Text(
text = readableByteCount(
meshGradientDownloadProgress?.currentTotalSize
?: 0
text = rememberHumanFileSize(
meshGradientDownloadProgress?.currentTotalSize ?: 0
),
maxLines = 1,
textAlign = TextAlign.Center,

View File

@ -72,7 +72,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
@ -81,7 +80,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.ui.utils.animation.fancySlideTransition
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getFilename
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.rememberFilename
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalScreenSize
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedFloatingActionButton
@ -112,8 +111,6 @@ internal fun PdfToolsContentImpl(
val selectAllToggle = remember { mutableStateOf(false) }
val deselectAllToggle = remember { mutableStateOf(false) }
val context = LocalContext.current
Column(Modifier.fillMaxSize()) {
EnhancedTopAppBar(
type = EnhancedTopAppBarType.Large,
@ -126,7 +123,7 @@ internal fun PdfToolsContentImpl(
) { (pdfType, previewUri) ->
Text(
text = previewUri?.let {
context.getFilename(it)
rememberFilename(it)
} ?: stringResource(pdfType?.title ?: R.string.pdf_tools),
textAlign = TextAlign.Center
)

View File

@ -26,7 +26,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import ru.tech.imageresizershrinker.core.domain.utils.readableByteCount
import ru.tech.imageresizershrinker.core.domain.utils.humanFileSize
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
import ru.tech.imageresizershrinker.core.ui.widget.other.ToastDuration
@ -63,7 +63,7 @@ internal fun RecognizeTextDownloadDataDialog(component: RecognizeTextComponent)
?: RecognitionType.Standard,
languageCode = downloadDialogData.joinToString(separator = "+") { it.languageCode },
onProgress = { p, size ->
dataRemaining = readableByteCount(size)
dataRemaining = humanFileSize(size)
progress = p
},
onComplete = {

View File

@ -26,6 +26,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
@ -153,7 +154,9 @@ internal fun SettingItem(
Setting.ClearCache -> {
ClearCacheSettingItem(
value = component.getReadableCacheSize(),
value = remember {
component.getReadableCacheSize()
},
onClearCache = component::clearCache
)
}