mirror of
https://github.com/T8RIN/ImageToolbox.git
synced 2025-08-05 23:34:15 +08:00
Improve performance
This commit is contained in:
@ -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.Metadata
|
||||||
import ru.tech.imageresizershrinker.core.domain.image.clearAllAttributes
|
import ru.tech.imageresizershrinker.core.domain.image.clearAllAttributes
|
||||||
import ru.tech.imageresizershrinker.core.domain.image.copyTo
|
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 ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ internal fun Context.cacheSize(): String = runCatching {
|
|||||||
externalCacheDirs?.forEach { file ->
|
externalCacheDirs?.forEach { file ->
|
||||||
size += file?.walkTopDown()?.sumOf { if (it.isFile) it.length() else 0 } ?: 0
|
size += file?.walkTopDown()?.sumOf { if (it.isFile) it.length() else 0 } ?: 0
|
||||||
}
|
}
|
||||||
readableByteCount(size)
|
humanFileSize(size)
|
||||||
}.getOrNull() ?: "0 B"
|
}.getOrNull() ?: "0 B"
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import java.text.StringCharacterIterator
|
|||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
|
|
||||||
fun readableByteCount(bytes: Long): String {
|
fun humanFileSize(bytes: Long): String {
|
||||||
var tempBytes = bytes
|
var tempBytes = bytes
|
||||||
if (-1024 < tempBytes && tempBytes < 1024) {
|
if (-1024 < tempBytes && tempBytes < 1024) {
|
||||||
return "$tempBytes B"
|
return "$tempBytes B"
|
||||||
|
@ -37,8 +37,8 @@ import androidx.compose.ui.text.style.TextAlign
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ru.tech.imageresizershrinker.core.domain.remote.RemoteResourcesDownloadProgress
|
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.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.BasicEnhancedAlertDialog
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedAlertDialog
|
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedAlertDialog
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedButton
|
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedButton
|
||||||
@ -114,7 +114,7 @@ internal fun CubeLutDownloadDialog(
|
|||||||
)
|
)
|
||||||
Spacer(Modifier.height(2.dp))
|
Spacer(Modifier.height(2.dp))
|
||||||
Text(
|
Text(
|
||||||
text = readableByteCount(cubeLutDownloadProgress?.currentTotalSize ?: 0),
|
text = rememberHumanFileSize(cubeLutDownloadProgress?.currentTotalSize ?: 0),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
fontSize = 10.sp,
|
fontSize = 10.sp,
|
||||||
|
@ -38,10 +38,14 @@ import androidx.annotation.StringRes
|
|||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.ErrorOutline
|
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.Color
|
||||||
import androidx.compose.ui.graphics.asAndroidBitmap
|
import androidx.compose.ui.graphics.asAndroidBitmap
|
||||||
import androidx.compose.ui.graphics.takeOrElse
|
import androidx.compose.ui.graphics.takeOrElse
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.Density
|
import androidx.compose.ui.unit.Density
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.app.PendingIntentCompat
|
import androidx.core.app.PendingIntentCompat
|
||||||
@ -180,7 +184,7 @@ object ContextUtils {
|
|||||||
): Boolean = validInstallers.contains(getInstallerPackageName(packageName))
|
): Boolean = validInstallers.contains(getInstallerPackageName(packageName))
|
||||||
|
|
||||||
private fun Context.getInstallerPackageName(packageName: String): String? {
|
private fun Context.getInstallerPackageName(packageName: String): String? {
|
||||||
kotlin.runCatching {
|
runCatching {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
|
||||||
return packageManager.getInstallSourceInfo(packageName).installingPackageName
|
return packageManager.getInstallSourceInfo(packageName).installingPackageName
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
@ -197,6 +201,28 @@ object ContextUtils {
|
|||||||
DocumentFile.fromSingleUri(this, uri)?.name
|
DocumentFile.fromSingleUri(this, uri)?.name
|
||||||
}?.decodeEscaped()
|
}?.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(
|
fun Activity.parseImageFromIntent(
|
||||||
intent: Intent?,
|
intent: Intent?,
|
||||||
onStart: () -> Unit,
|
onStart: () -> Unit,
|
||||||
@ -632,7 +658,7 @@ object ContextUtils {
|
|||||||
startActivity(shareIntent)
|
startActivity(shareIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Context.getExtension(uri: Uri): String? {
|
fun Context.getExtension(uri: Uri): String? {
|
||||||
val filename = getFilename(uri) ?: ""
|
val filename = getFilename(uri) ?: ""
|
||||||
if (filename.endsWith(".qoi")) return "qoi"
|
if (filename.endsWith(".qoi")) return "qoi"
|
||||||
if (filename.endsWith(".jxl")) return "jxl"
|
if (filename.endsWith(".jxl")) return "jxl"
|
||||||
|
@ -26,6 +26,7 @@ import android.os.Build.VERSION.SDK_INT
|
|||||||
import android.provider.OpenableColumns
|
import android.provider.OpenableColumns
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
@ -35,6 +36,7 @@ import androidx.core.graphics.scale
|
|||||||
import androidx.core.text.isDigitsOnly
|
import androidx.core.text.isDigitsOnly
|
||||||
import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
|
import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
|
||||||
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
|
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.resources.R
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getStringLocalized
|
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getStringLocalized
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@ -228,7 +230,7 @@ object ImageUtils {
|
|||||||
it in possibleConfigs
|
it in possibleConfigs
|
||||||
} ?: Bitmap.Config.ARGB_8888
|
} ?: Bitmap.Config.ARGB_8888
|
||||||
|
|
||||||
fun Uri.fileSize(context: Context): Long? {
|
private fun Uri.fileSize(context: Context): Long? {
|
||||||
runCatching {
|
runCatching {
|
||||||
context.contentResolver
|
context.contentResolver
|
||||||
.query(this, null, null, null, null, null)
|
.query(this, null, null, null, null, null)
|
||||||
@ -244,6 +246,37 @@ object ImageUtils {
|
|||||||
return null
|
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 {
|
object Dimens {
|
||||||
const val MAX_IMAGE_SIZE = 8388607 * 16
|
const val MAX_IMAGE_SIZE = 8388607 * 16
|
||||||
}
|
}
|
||||||
|
@ -214,3 +214,8 @@ fun Uri.isJxl(context: Context): Boolean {
|
|||||||
return context.getFilename(this).toString().endsWith(".jxl")
|
return context.getFilename(this).toString().endsWith(".jxl")
|
||||||
.or(context.contentResolver.getType(this)?.contains("jxl") == true)
|
.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)
|
||||||
|
}
|
@ -39,7 +39,6 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.graphics.Shape
|
import androidx.compose.ui.graphics.Shape
|
||||||
import androidx.compose.ui.graphics.compositeOver
|
import androidx.compose.ui.graphics.compositeOver
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
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.Picker
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberFilePicker
|
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.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.dialogs.OneTimeImagePickingDialog
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.image.Picture
|
import ru.tech.imageresizershrinker.core.ui.widget.image.Picture
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.preferences.PreferenceItemOverload
|
import ru.tech.imageresizershrinker.core.ui.widget.preferences.PreferenceItemOverload
|
||||||
@ -137,12 +136,10 @@ fun FileSelector(
|
|||||||
) {
|
) {
|
||||||
val pickFileLauncher = rememberFilePicker(onSuccess = onValueChange)
|
val pickFileLauncher = rememberFilePicker(onSuccess = onValueChange)
|
||||||
|
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
PreferenceItemOverload(
|
PreferenceItemOverload(
|
||||||
title = title,
|
title = title,
|
||||||
subtitle = if (subtitle == null && value != null) {
|
subtitle = if (subtitle == null && value != null) {
|
||||||
context.getFilename(value.toUri())
|
rememberFilename(value.toUri())
|
||||||
} else subtitle,
|
} else subtitle,
|
||||||
onClick = pickFileLauncher::pickFile,
|
onClick = pickFileLauncher::pickFile,
|
||||||
autoShadowElevation = autoShadowElevation,
|
autoShadowElevation = autoShadowElevation,
|
||||||
|
@ -65,7 +65,6 @@ 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.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.derivedStateOf
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableFloatStateOf
|
import androidx.compose.runtime.mutableFloatStateOf
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
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.compositeOver
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.IntOffset
|
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.resources.icons.EditAlt
|
||||||
import ru.tech.imageresizershrinker.core.ui.theme.White
|
import ru.tech.imageresizershrinker.core.ui.theme.White
|
||||||
import ru.tech.imageresizershrinker.core.ui.theme.takeColorFromScheme
|
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.helper.PredictiveBackObserver
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
|
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalScreenSize
|
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalScreenSize
|
||||||
@ -373,14 +371,8 @@ fun ImagePager(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val context = LocalContext.current
|
|
||||||
val selectedUriFilename by remember(selectedUri) {
|
val selectedUriFilename = selectedUri?.let { rememberFilename(it) }
|
||||||
derivedStateOf {
|
|
||||||
selectedUri?.let {
|
|
||||||
context.getFilename(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val showBottomHist = pagerState.currentPage !in imageErrorPages && moreThanOneUri
|
val showBottomHist = pagerState.currentPage !in imageErrorPages && moreThanOneUri
|
||||||
|
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
|
@ -69,7 +69,6 @@ import androidx.compose.ui.graphics.RectangleShape
|
|||||||
import androidx.compose.ui.graphics.compositeOver
|
import androidx.compose.ui.graphics.compositeOver
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.layout.layout
|
import androidx.compose.ui.layout.layout
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
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.resources.icons.BrokenImageAlt
|
||||||
import ru.tech.imageresizershrinker.core.ui.theme.White
|
import ru.tech.imageresizershrinker.core.ui.theme.White
|
||||||
import ru.tech.imageresizershrinker.core.ui.theme.takeColorFromScheme
|
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.utils.provider.LocalScreenSize
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.modifier.advancedShadow
|
import ru.tech.imageresizershrinker.core.ui.widget.modifier.advancedShadow
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.modifier.dragHandler
|
import ru.tech.imageresizershrinker.core.ui.widget.modifier.dragHandler
|
||||||
@ -412,14 +411,7 @@ private fun ImageItem(
|
|||||||
aboveImageContent(index)
|
aboveImageContent(index)
|
||||||
|
|
||||||
if (showExtension) {
|
if (showExtension) {
|
||||||
val context = LocalContext.current
|
val extension = rememberFileExtension(uri.toUri())?.uppercase()
|
||||||
val extension by remember(uri) {
|
|
||||||
derivedStateOf {
|
|
||||||
uri.toUri().let { uri ->
|
|
||||||
context.getFilename(uri)?.takeLastWhile { it != '.' }?.uppercase()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension?.let {
|
extension?.let {
|
||||||
Row(
|
Row(
|
||||||
|
@ -41,7 +41,6 @@ import androidx.compose.material3.LocalTextStyle
|
|||||||
import androidx.compose.material3.MaterialTheme
|
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.runtime.derivedStateOf
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -50,7 +49,6 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
@ -59,7 +57,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ru.tech.imageresizershrinker.core.resources.R
|
import ru.tech.imageresizershrinker.core.resources.R
|
||||||
import ru.tech.imageresizershrinker.core.ui.theme.takeColorFromScheme
|
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.enhanced.hapticsClickable
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.modifier.container
|
import ru.tech.imageresizershrinker.core.ui.widget.modifier.container
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.text.AutoSizeText
|
import ru.tech.imageresizershrinker.core.ui.widget.text.AutoSizeText
|
||||||
@ -94,8 +92,6 @@ fun UrisPreview(
|
|||||||
showScrimForNonSuccess: Boolean = true,
|
showScrimForNonSuccess: Boolean = true,
|
||||||
filenameSource: (index: Int) -> Uri = { uris[it] }
|
filenameSource: (index: Int) -> Uri = { uris[it] }
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
BoxWithConstraints {
|
BoxWithConstraints {
|
||||||
val size = uris.size + 1f
|
val size = uris.size + 1f
|
||||||
|
|
||||||
@ -192,11 +188,8 @@ fun UrisPreview(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val filename by remember(filenameSource, index) {
|
val filename = rememberFilename(filenameSource(index))
|
||||||
derivedStateOf {
|
|
||||||
context.getFilename(filenameSource(index))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filename?.let {
|
filename?.let {
|
||||||
AutoSizeText(
|
AutoSizeText(
|
||||||
text = it,
|
text = it,
|
||||||
|
@ -24,15 +24,18 @@ import androidx.compose.animation.togetherWith
|
|||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
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.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import androidx.compose.ui.text.withStyle
|
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.resources.R
|
||||||
import ru.tech.imageresizershrinker.core.ui.theme.Green
|
import ru.tech.imageresizershrinker.core.ui.theme.Green
|
||||||
import ru.tech.imageresizershrinker.core.ui.theme.blend
|
import ru.tech.imageresizershrinker.core.ui.theme.blend
|
||||||
import ru.tech.imageresizershrinker.core.ui.theme.takeColorFromScheme
|
import ru.tech.imageresizershrinker.core.ui.theme.takeColorFromScheme
|
||||||
|
import ru.tech.imageresizershrinker.core.ui.utils.helper.ImageUtils.rememberHumanFileSize
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun <T : Any> TopAppBarTitle(
|
fun <T : Any> TopAppBarTitle(
|
||||||
@ -64,12 +67,12 @@ fun <T : Any> TopAppBarTitle(
|
|||||||
} else {
|
} else {
|
||||||
AnimatedContent(originalSize) { originalSize ->
|
AnimatedContent(originalSize) { originalSize ->
|
||||||
val readableOriginal = if ((originalSize ?: 0) > 0) {
|
val readableOriginal = if ((originalSize ?: 0) > 0) {
|
||||||
readableByteCount(originalSize ?: 0)
|
rememberHumanFileSize(originalSize ?: 0)
|
||||||
} else {
|
} else {
|
||||||
"? B"
|
"? B"
|
||||||
}
|
}
|
||||||
val readableCompressed = if (size > 0) {
|
val readableCompressed = if (size > 0) {
|
||||||
readableByteCount(size)
|
rememberHumanFileSize(size)
|
||||||
} else {
|
} else {
|
||||||
"(...)"
|
"(...)"
|
||||||
}
|
}
|
||||||
@ -83,21 +86,36 @@ fun <T : Any> TopAppBarTitle(
|
|||||||
else -> Green
|
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(
|
append(
|
||||||
if (originalSize == null || isSizesEqual) {
|
if (originalSize == null || isSizesEqual) sizeString else ""
|
||||||
stringResource(R.string.size, readableCompressed)
|
|
||||||
} else ""
|
|
||||||
)
|
)
|
||||||
originalSize?.takeIf { !isSizesEqual }?.let {
|
originalSize?.takeIf { !isSizesEqual }?.let {
|
||||||
append(readableOriginal)
|
append(readableOriginal)
|
||||||
append(" -> ")
|
append(" -> ")
|
||||||
withStyle(LocalTextStyle.current.toSpanStyle().copy(color)) {
|
withStyle(textStyle.toSpanStyle().copy(color)) {
|
||||||
append(readableCompressed)
|
append(readableCompressed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = text
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,8 +135,8 @@ fun <T : Any> TopAppBarTitle(
|
|||||||
Text(it)
|
Text(it)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val readableOriginal = readableByteCount(originalSize ?: 0)
|
val readableOriginal = rememberHumanFileSize(originalSize ?: 0)
|
||||||
val readableCompressed = readableByteCount(size)
|
val readableCompressed = rememberHumanFileSize(size)
|
||||||
val isSizesEqual =
|
val isSizesEqual =
|
||||||
size == originalSize || readableCompressed == readableOriginal
|
size == originalSize || readableCompressed == readableOriginal
|
||||||
val color = takeColorFromScheme {
|
val color = takeColorFromScheme {
|
||||||
@ -128,21 +146,36 @@ fun <T : Any> TopAppBarTitle(
|
|||||||
else -> Green
|
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(
|
append(
|
||||||
if (originalSize == null || isSizesEqual) {
|
if (originalSize == null || isSizesEqual) sizeString else ""
|
||||||
stringResource(R.string.size, readableCompressed)
|
|
||||||
} else ""
|
|
||||||
)
|
)
|
||||||
originalSize?.takeIf { !isSizesEqual }?.let {
|
originalSize?.takeIf { !isSizesEqual }?.let {
|
||||||
append(readableOriginal)
|
append(readableOriginal)
|
||||||
append(" -> ")
|
append(" -> ")
|
||||||
withStyle(LocalTextStyle.current.toSpanStyle().copy(color)) {
|
withStyle(textStyle.toSpanStyle().copy(color)) {
|
||||||
append(readableCompressed)
|
append(readableCompressed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = text
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,22 +17,17 @@
|
|||||||
|
|
||||||
package ru.tech.imageresizershrinker.core.ui.widget.utils
|
package ru.tech.imageresizershrinker.core.ui.widget.utils
|
||||||
|
|
||||||
import android.content.ContentResolver
|
|
||||||
import android.content.Context
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.webkit.MimeTypeMap
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.core.net.toUri
|
|
||||||
import ru.tech.imageresizershrinker.core.domain.model.ExtraDataType
|
import ru.tech.imageresizershrinker.core.domain.model.ExtraDataType
|
||||||
import ru.tech.imageresizershrinker.core.settings.presentation.provider.LocalSettingsState
|
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 ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun List<Uri>.screenList(
|
internal fun List<Uri>.screenList(
|
||||||
@ -46,7 +41,7 @@ internal fun List<Uri>.screenList(
|
|||||||
): Boolean {
|
): Boolean {
|
||||||
if (this == null) return false
|
if (this == null) return false
|
||||||
|
|
||||||
val extension = context.getExtension(toString()) ?: return false
|
val extension = context.getExtension(this) ?: return false
|
||||||
|
|
||||||
return extensions.any(extension::contains)
|
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(".", "")
|
|
||||||
}
|
|
@ -28,17 +28,15 @@ import androidx.compose.material.icons.outlined.FilePresent
|
|||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
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 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.R
|
||||||
import ru.tech.imageresizershrinker.core.resources.shapes.CloverShape
|
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
|
import ru.tech.imageresizershrinker.core.ui.widget.preferences.PreferenceItemOverload
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -48,15 +46,9 @@ internal fun UriWithHashItem(
|
|||||||
) {
|
) {
|
||||||
val (uri, checksum) = uriWithHash
|
val (uri, checksum) = uriWithHash
|
||||||
|
|
||||||
val context = LocalContext.current
|
val filename = rememberFilename(uri) ?: stringResource(R.string.filename)
|
||||||
|
|
||||||
val filename = remember {
|
val fileSize = rememberHumanFileSize(uri)
|
||||||
context.getFilename(uri)
|
|
||||||
?: context.getString(R.string.filename)
|
|
||||||
}
|
|
||||||
val fileSize = remember {
|
|
||||||
readableByteCount(uri.fileSize(context) ?: 0L)
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
@ -53,22 +53,20 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ru.tech.imageresizershrinker.core.domain.model.CipherType
|
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.domain.utils.toInt
|
||||||
import ru.tech.imageresizershrinker.core.resources.R
|
import ru.tech.imageresizershrinker.core.resources.R
|
||||||
import ru.tech.imageresizershrinker.core.settings.presentation.provider.LocalSettingsState
|
import ru.tech.imageresizershrinker.core.settings.presentation.provider.LocalSettingsState
|
||||||
import ru.tech.imageresizershrinker.core.ui.theme.Green
|
import ru.tech.imageresizershrinker.core.ui.theme.Green
|
||||||
import ru.tech.imageresizershrinker.core.ui.theme.outlineVariant
|
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.content_pickers.rememberFileCreator
|
||||||
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.fileSize
|
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.helper.isPortraitOrientationAsState
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
|
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.buttons.ToggleGroupButton
|
import ru.tech.imageresizershrinker.core.ui.widget.buttons.ToggleGroupButton
|
||||||
@ -86,7 +84,6 @@ import kotlin.random.Random
|
|||||||
internal fun CipherControls(component: CipherComponent) {
|
internal fun CipherControls(component: CipherComponent) {
|
||||||
val settingsState = LocalSettingsState.current
|
val settingsState = LocalSettingsState.current
|
||||||
val isPortrait by isPortraitOrientationAsState()
|
val isPortrait by isPortraitOrientationAsState()
|
||||||
val context = LocalContext.current
|
|
||||||
val essentials = rememberLocalEssentials()
|
val essentials = rememberLocalEssentials()
|
||||||
val showConfetti: () -> Unit = essentials::showConfetti
|
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) {
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
if (isPortrait) Spacer(Modifier.height(20.dp))
|
if (isPortrait) Spacer(Modifier.height(20.dp))
|
||||||
Row(
|
Row(
|
||||||
@ -140,9 +141,7 @@ internal fun CipherControls(component: CipherComponent) {
|
|||||||
Spacer(Modifier.height(16.dp))
|
Spacer(Modifier.height(16.dp))
|
||||||
PreferenceItem(
|
PreferenceItem(
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
title = component.uri?.let {
|
title = filename ?: stringResource(R.string.something_went_wrong),
|
||||||
context.getFilename(it)
|
|
||||||
} ?: stringResource(R.string.something_went_wrong),
|
|
||||||
onClick = null,
|
onClick = null,
|
||||||
titleFontStyle = LocalTextStyle.current.copy(
|
titleFontStyle = LocalTextStyle.current.copy(
|
||||||
lineHeight = 16.sp,
|
lineHeight = 16.sp,
|
||||||
@ -151,9 +150,7 @@ internal fun CipherControls(component: CipherComponent) {
|
|||||||
subtitle = component.uri?.let {
|
subtitle = component.uri?.let {
|
||||||
stringResource(
|
stringResource(
|
||||||
id = R.string.size,
|
id = R.string.size,
|
||||||
readableByteCount(
|
rememberHumanFileSize(it)
|
||||||
it.fileSize(context) ?: 0L
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
startIcon = Icons.AutoMirrored.Rounded.InsertDriveFile
|
startIcon = Icons.AutoMirrored.Rounded.InsertDriveFile
|
||||||
@ -245,15 +242,13 @@ internal fun CipherControls(component: CipherComponent) {
|
|||||||
lineHeight = 14.sp,
|
lineHeight = 14.sp,
|
||||||
modifier = Modifier.padding(vertical = 16.dp)
|
modifier = Modifier.padding(vertical = 16.dp)
|
||||||
)
|
)
|
||||||
var name by rememberSaveable(component.byteArray) {
|
var name by rememberSaveable(component.byteArray, filename) {
|
||||||
mutableStateOf(
|
mutableStateOf(
|
||||||
if (component.isEncrypt) {
|
if (component.isEncrypt) {
|
||||||
"enc-"
|
"enc-"
|
||||||
} else {
|
} else {
|
||||||
"dec-"
|
"dec-"
|
||||||
} + (component.uri?.let {
|
} + (filename ?: Random.nextInt())
|
||||||
context.getFilename(it)
|
|
||||||
} ?: Random.nextInt())
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
RoundedTextField(
|
RoundedTextField(
|
||||||
|
@ -25,16 +25,15 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.material3.MaterialTheme
|
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.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.Shape
|
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.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ru.tech.imageresizershrinker.core.resources.R
|
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
|
@Composable
|
||||||
internal fun BoxScope.CompareLabel(
|
internal fun BoxScope.CompareLabel(
|
||||||
@ -48,12 +47,9 @@ internal fun BoxScope.CompareLabel(
|
|||||||
visible = enabled && uri != null,
|
visible = enabled && uri != null,
|
||||||
modifier = modifier.align(alignment)
|
modifier = modifier.align(alignment)
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
|
||||||
Text(
|
Text(
|
||||||
text = remember(uri) {
|
text = uri?.let { rememberFilename(it) }
|
||||||
uri?.let { context.getFilename(it) }
|
?: stringResource(R.string.filename),
|
||||||
?: context.getString(R.string.filename)
|
|
||||||
},
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(
|
.background(
|
||||||
color = MaterialTheme.colorScheme.scrim.copy(0.4f),
|
color = MaterialTheme.colorScheme.scrim.copy(0.4f),
|
||||||
|
@ -32,7 +32,6 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ru.tech.imageresizershrinker.core.resources.R
|
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.resources.icons.MiniEdit
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.Picker
|
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.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.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.asClip
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.helper.isPortraitOrientationAsState
|
import ru.tech.imageresizershrinker.core.ui.utils.helper.isPortraitOrientationAsState
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalComponentActivity
|
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalComponentActivity
|
||||||
@ -124,7 +123,7 @@ fun DeleteExifContent(
|
|||||||
title = stringResource(R.string.delete_exif),
|
title = stringResource(R.string.delete_exif),
|
||||||
input = component.bitmap,
|
input = component.bitmap,
|
||||||
isLoading = component.isImageLoading,
|
isLoading = component.isImageLoading,
|
||||||
size = component.selectedUri?.fileSize(LocalContext.current) ?: 0L
|
size = rememberFileSize(component.selectedUri)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onGoBack = {
|
onGoBack = {
|
||||||
|
@ -36,7 +36,6 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import coil3.toBitmap
|
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.resources.icons.MiniEdit
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.Picker
|
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.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.asClip
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.helper.isPortraitOrientationAsState
|
import ru.tech.imageresizershrinker.core.ui.utils.helper.isPortraitOrientationAsState
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalComponentActivity
|
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalComponentActivity
|
||||||
@ -126,7 +125,7 @@ fun EditExifContent(
|
|||||||
title = stringResource(R.string.edit_exif_screen),
|
title = stringResource(R.string.edit_exif_screen),
|
||||||
input = component.uri.takeIf { it != Uri.EMPTY },
|
input = component.uri.takeIf { it != Uri.EMPTY },
|
||||||
isLoading = component.isImageLoading,
|
isLoading = component.isImageLoading,
|
||||||
size = component.uri.fileSize(LocalContext.current) ?: 0L
|
size = rememberFileSize(component.uri)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onGoBack = onBack,
|
onGoBack = onBack,
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package ru.tech.imageresizershrinker.feature.gif_tools.presentation
|
package ru.tech.imageresizershrinker.feature.gif_tools.presentation
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
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.rememberFileCreator
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberFilePicker
|
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.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.helper.isPortraitOrientationAsState
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
|
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalComponentActivity
|
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
|
private val GifToolsComponent.canSave: Boolean
|
||||||
get() = (gifFrames == ImageFrames.All)
|
get() = (gifFrames == ImageFrames.All)
|
||||||
.or(type is Screen.GifTools.Type.ImageToGif)
|
.or(type is Screen.GifTools.Type.ImageToGif)
|
||||||
|
@ -28,13 +28,12 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ru.tech.imageresizershrinker.core.resources.R
|
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.Picker
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.content_pickers.rememberImagePicker
|
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.asClip
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.helper.isPortraitOrientationAsState
|
import ru.tech.imageresizershrinker.core.ui.utils.helper.isPortraitOrientationAsState
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalComponentActivity
|
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalComponentActivity
|
||||||
@ -128,7 +127,7 @@ fun LimitsResizeContent(
|
|||||||
title = stringResource(R.string.limits_resize),
|
title = stringResource(R.string.limits_resize),
|
||||||
input = component.bitmap,
|
input = component.bitmap,
|
||||||
isLoading = component.isImageLoading,
|
isLoading = component.isImageLoading,
|
||||||
size = component.selectedUri?.fileSize(LocalContext.current) ?: 0L
|
size = rememberFileSize(component.selectedUri)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onGoBack = onBack,
|
onGoBack = onBack,
|
||||||
|
@ -48,8 +48,8 @@ import androidx.compose.ui.text.font.FontWeight
|
|||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
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.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.helper.plus
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
|
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedIconButton
|
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedIconButton
|
||||||
@ -159,9 +159,8 @@ fun MeshGradientsContent(
|
|||||||
)
|
)
|
||||||
Spacer(Modifier.height(2.dp))
|
Spacer(Modifier.height(2.dp))
|
||||||
Text(
|
Text(
|
||||||
text = readableByteCount(
|
text = rememberHumanFileSize(
|
||||||
meshGradientDownloadProgress?.currentTotalSize
|
meshGradientDownloadProgress?.currentTotalSize ?: 0
|
||||||
?: 0
|
|
||||||
),
|
),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
|
@ -72,7 +72,6 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clipToBounds
|
import androidx.compose.ui.draw.clipToBounds
|
||||||
import androidx.compose.ui.graphics.RectangleShape
|
import androidx.compose.ui.graphics.RectangleShape
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
@ -81,7 +80,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ru.tech.imageresizershrinker.core.resources.R
|
import ru.tech.imageresizershrinker.core.resources.R
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.animation.fancySlideTransition
|
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.navigation.Screen
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalScreenSize
|
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalScreenSize
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedFloatingActionButton
|
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedFloatingActionButton
|
||||||
@ -112,8 +111,6 @@ internal fun PdfToolsContentImpl(
|
|||||||
val selectAllToggle = remember { mutableStateOf(false) }
|
val selectAllToggle = remember { mutableStateOf(false) }
|
||||||
val deselectAllToggle = remember { mutableStateOf(false) }
|
val deselectAllToggle = remember { mutableStateOf(false) }
|
||||||
|
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
Column(Modifier.fillMaxSize()) {
|
Column(Modifier.fillMaxSize()) {
|
||||||
EnhancedTopAppBar(
|
EnhancedTopAppBar(
|
||||||
type = EnhancedTopAppBarType.Large,
|
type = EnhancedTopAppBarType.Large,
|
||||||
@ -126,7 +123,7 @@ internal fun PdfToolsContentImpl(
|
|||||||
) { (pdfType, previewUri) ->
|
) { (pdfType, previewUri) ->
|
||||||
Text(
|
Text(
|
||||||
text = previewUri?.let {
|
text = previewUri?.let {
|
||||||
context.getFilename(it)
|
rememberFilename(it)
|
||||||
} ?: stringResource(pdfType?.title ?: R.string.pdf_tools),
|
} ?: stringResource(pdfType?.title ?: R.string.pdf_tools),
|
||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
)
|
)
|
||||||
|
@ -26,7 +26,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.platform.LocalContext
|
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.resources.R
|
||||||
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
|
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
|
||||||
import ru.tech.imageresizershrinker.core.ui.widget.other.ToastDuration
|
import ru.tech.imageresizershrinker.core.ui.widget.other.ToastDuration
|
||||||
@ -63,7 +63,7 @@ internal fun RecognizeTextDownloadDataDialog(component: RecognizeTextComponent)
|
|||||||
?: RecognitionType.Standard,
|
?: RecognitionType.Standard,
|
||||||
languageCode = downloadDialogData.joinToString(separator = "+") { it.languageCode },
|
languageCode = downloadDialogData.joinToString(separator = "+") { it.languageCode },
|
||||||
onProgress = { p, size ->
|
onProgress = { p, size ->
|
||||||
dataRemaining = readableByteCount(size)
|
dataRemaining = humanFileSize(size)
|
||||||
progress = p
|
progress = p
|
||||||
},
|
},
|
||||||
onComplete = {
|
onComplete = {
|
||||||
|
@ -26,6 +26,7 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
@ -153,7 +154,9 @@ internal fun SettingItem(
|
|||||||
|
|
||||||
Setting.ClearCache -> {
|
Setting.ClearCache -> {
|
||||||
ClearCacheSettingItem(
|
ClearCacheSettingItem(
|
||||||
value = component.getReadableCacheSize(),
|
value = remember {
|
||||||
|
component.getReadableCacheSize()
|
||||||
|
},
|
||||||
onClearCache = component::clearCache
|
onClearCache = component::clearCache
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user