Added more info about images in pickers

This commit is contained in:
T8RIN
2026-02-15 21:36:58 +03:00
parent 0fbc598aa0
commit dc28e8e677
14 changed files with 45 additions and 45 deletions

View File

@@ -44,7 +44,7 @@ import com.t8rin.imagetoolbox.core.domain.model.IntegerSize
import com.t8rin.imagetoolbox.core.domain.transformation.Transformation
import com.t8rin.imagetoolbox.core.domain.utils.runSuspendCatching
import com.t8rin.imagetoolbox.core.settings.domain.SettingsProvider
import com.t8rin.imagetoolbox.core.utils.getFilename
import com.t8rin.imagetoolbox.core.utils.filename
import com.t8rin.imagetoolbox.core.utils.tryRequireOriginal
import com.t8rin.logger.makeLog
import dagger.hilt.android.qualifiers.ApplicationContext
@@ -213,7 +213,7 @@ internal class AndroidImageGetter @Inject constructor(
}
override fun getExtension(uri: String): String? {
val filename = uri.toUri().getFilename(context) ?: ""
val filename = uri.toUri().filename(context) ?: ""
if (filename.endsWith(".qoi")) return "qoi"
if (filename.endsWith(".jxl")) return "jxl"
return if (ContentResolver.SCHEME_CONTENT == uri.toUri().scheme) {

View File

@@ -57,12 +57,12 @@ import com.t8rin.imagetoolbox.core.settings.domain.model.CopyToClipboardMode
import com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior
import com.t8rin.imagetoolbox.core.settings.domain.model.OneTimeSaveLocation
import com.t8rin.imagetoolbox.core.utils.fileSize
import com.t8rin.imagetoolbox.core.utils.getFilename
import com.t8rin.imagetoolbox.core.utils.filename
import com.t8rin.imagetoolbox.core.utils.getPath
import com.t8rin.imagetoolbox.core.utils.listFilesInDirectory
import com.t8rin.imagetoolbox.core.utils.listFilesInDirectoryProgressive
import com.t8rin.imagetoolbox.core.utils.toUiPath
import com.t8rin.imagetoolbox.core.utils.tryRequireOriginal
import com.t8rin.imagetoolbox.core.utils.uiPath
import com.t8rin.logger.makeLog
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.Flow
@@ -202,7 +202,7 @@ internal class AndroidFileController @Inject constructor(
return@withContext SaveResult.Success(
message = getString(
R.string.saved_to_original,
originalUri.getFilename(context).toString()
originalUri.filename(context).toString()
),
isOverwritten = true,
savingPath = savingPath
@@ -237,7 +237,7 @@ internal class AndroidFileController @Inject constructor(
Exception(
getString(
R.string.no_such_directory,
treeUri.toUri().toUiPath(treeUri)
treeUri.toUri().uiPath(treeUri)
)
)
)

View File

@@ -52,7 +52,7 @@ import com.t8rin.imagetoolbox.core.domain.saving.model.ImageSaveTarget
import com.t8rin.imagetoolbox.core.domain.utils.timestamp
import com.t8rin.imagetoolbox.core.settings.domain.SettingsManager
import com.t8rin.imagetoolbox.core.settings.domain.model.FilenameBehavior
import com.t8rin.imagetoolbox.core.utils.getFilename
import com.t8rin.imagetoolbox.core.utils.filename
import com.t8rin.logger.makeLog
import dagger.hilt.android.qualifiers.ApplicationContext
import java.util.Date
@@ -120,7 +120,7 @@ internal class AndroidFilenameCreator @Inject constructor(
val suffix = settingsState.filenameSuffix
val originalName = if (settingsState.addOriginalFilename && !isOriginalEmpty) {
saveTarget.originalUri.toUri().getFilename(context)
saveTarget.originalUri.toUri().filename(context)
?.substringBeforeLast('.').orEmpty()
} else ""
@@ -232,6 +232,6 @@ internal class AndroidFilenameCreator @Inject constructor(
length: Int
): String = "${randomStringGenerator.generate(length)}.${extension}"
override fun getFilename(uri: String): String = uri.toUri().getFilename(context) ?: ""
override fun getFilename(uri: String): String = uri.toUri().filename(context) ?: ""
}

View File

@@ -64,7 +64,7 @@ import com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionUtils.checkPerm
import com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionUtils.hasPermissionAllowed
import com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionUtils.setPermissionsAllowed
import com.t8rin.imagetoolbox.core.utils.appContext
import com.t8rin.imagetoolbox.core.utils.getFilename
import com.t8rin.imagetoolbox.core.utils.filename
import com.t8rin.logger.makeLog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -190,7 +190,7 @@ object ContextUtils {
fun rememberFilename(uri: Uri): String? {
return remember(uri) {
derivedStateOf {
uri.getFilename()
uri.filename()
}
}.value
}
@@ -456,7 +456,7 @@ object ContextUtils {
}
fun Uri.getExtension(): String? = runCatching {
val filename = getFilename().orEmpty()
val filename = filename().orEmpty()
if (filename.endsWith(".qoi")) return "qoi"
if (filename.endsWith(".jxl")) return "jxl"
return if (ContentResolver.SCHEME_CONTENT == scheme) {
@@ -508,7 +508,7 @@ object ContextUtils {
contentResolver.openInputStream(this@moveToCache)?.use { stream ->
val file = File(
cacheDir,
getFilename() ?: "cache_${Random.nextInt()}.tmp"
filename() ?: "cache_${Random.nextInt()}.tmp"
).apply { createNewFile() }
file.outputStream().use { stream.copyTo(it) }

View File

@@ -80,7 +80,7 @@ import com.t8rin.imagetoolbox.core.ui.widget.other.rememberRevealState
import com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem
import com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemDefaults
import com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch
import com.t8rin.imagetoolbox.core.utils.toUiPath
import com.t8rin.imagetoolbox.core.utils.uiPath
import kotlinx.coroutines.launch
@@ -170,7 +170,7 @@ fun OneTimeSaveLocationSelectionDialog(
val title by remember(item) {
derivedStateOf {
val default = essentials.getString(R.string.default_folder)
item?.uri?.toUri()?.toUiPath(default = default) ?: default
item?.uri?.toUri()?.uiPath(default = default) ?: default
}
}
val subtitle by remember(item) {

View File

@@ -66,9 +66,9 @@ import com.t8rin.imagetoolbox.core.ui.widget.modifier.container
import com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextField
import com.t8rin.imagetoolbox.core.ui.widget.text.RoundedTextFieldColors
import com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem
import com.t8rin.imagetoolbox.core.utils.addedTime
import com.t8rin.imagetoolbox.core.utils.dateAdded
import com.t8rin.imagetoolbox.core.utils.fileSize
import com.t8rin.imagetoolbox.core.utils.getFilename
import com.t8rin.imagetoolbox.core.utils.filename
import com.t8rin.imagetoolbox.core.utils.lastModified
import com.t8rin.imagetoolbox.core.utils.path
@@ -76,9 +76,9 @@ import com.t8rin.imagetoolbox.core.utils.path
fun MetadataPreviewButton(
uri: Uri?,
dateModified: (Uri) -> Long? = { it.lastModified() },
dateAdded: (Uri) -> Long? = { it.addedTime() },
dateAdded: (Uri) -> Long? = { it.dateAdded() },
path: (Uri) -> String? = { it.path() },
name: (Uri) -> String? = { it.getFilename() },
name: (Uri) -> String? = { it.filename() },
fileSize: (Uri) -> String? = { humanFileSize(it.fileSize() ?: 0L, 2) }
) {
AnimatedContent(

View File

@@ -44,7 +44,7 @@ import java.net.URLDecoder
import java.net.URLEncoder
import java.util.LinkedList
fun Uri?.toUiPath(
fun Uri?.uiPath(
default: String
): String = this?.let { uri ->
DocumentFile
@@ -118,11 +118,11 @@ fun Uri.path(): String? = tryExtractOriginal().run {
}
}
fun Uri.addedTime(): Long? = tryExtractOriginal().run {
fun Uri.dateAdded(): Long? = tryExtractOriginal().run {
getLongColumn(MediaStore.MediaColumns.DATE_ADDED)?.times(1000)
}
fun Uri.getFilename(
fun Uri.filename(
context: Context = appContext
): String? = tryExtractOriginal().run {
if (this.toString().startsWith("file:///")) {
@@ -221,23 +221,23 @@ fun String.encodeEscaped(): String {
}
fun Uri.isApng(): Boolean {
return getFilename().toString().endsWith(".png")
return filename().toString().endsWith(".png")
.or(appContext.contentResolver.getType(this)?.contains("png") == true)
.or(appContext.contentResolver.getType(this)?.contains("apng") == true)
}
fun Uri.isWebp(): Boolean {
return getFilename().toString().endsWith(".webp")
return filename().toString().endsWith(".webp")
.or(appContext.contentResolver.getType(this)?.contains("webp") == true)
}
fun Uri.isJxl(): Boolean {
return getFilename().toString().endsWith(".jxl")
return filename().toString().endsWith(".jxl")
.or(appContext.contentResolver.getType(this)?.contains("jxl") == true)
}
fun Uri.isGif(): Boolean {
return getFilename().toString().endsWith(".gif")
return filename().toString().endsWith(".gif")
.or(appContext.contentResolver.getType(this)?.contains("gif") == true)
}
@@ -253,7 +253,7 @@ fun Context.listFilesInDirectoryProgressive(
fun String?.getPath(
context: Context = appContext
) = this?.takeIf { it.isNotEmpty() }?.toUri().toUiPath(
) = this?.takeIf { it.isNotEmpty() }?.toUri().uiPath(
default = context.getString(R.string.default_folder)
)
@@ -332,7 +332,7 @@ private fun isDirectory(mimeType: String): Boolean {
private fun List<Uri>.sortedByExtension(
descending: Boolean = false
) = sortedByKey(descending) {
it.getFilename()?.substringAfterLast(
it.filename()?.substringAfterLast(
delimiter = '.',
missingDelimiterValue = ""
)?.lowercase()
@@ -345,7 +345,7 @@ private fun List<Uri>.sortedByDateModified(
private fun List<Uri>.sortedByName(
descending: Boolean = false
) = sortedByKey(descending) {
it.getFilename()
it.filename()
}
private fun List<Uri>.sortedBySize(
@@ -365,7 +365,7 @@ private fun List<Uri>.sortedByMimeType(
private fun List<Uri>.sortedByDateAdded(
descending: Boolean = false
) = sortedByKey(descending) {
it.addedTime()
it.dateAdded()
}
private fun Uri.getLongColumn(column: String): Long? =

View File

@@ -44,7 +44,7 @@ import com.t8rin.imagetoolbox.core.domain.saving.KeepAliveService
import com.t8rin.imagetoolbox.core.domain.saving.model.SaveResult
import com.t8rin.imagetoolbox.core.domain.saving.track
import com.t8rin.imagetoolbox.core.resources.R
import com.t8rin.imagetoolbox.core.utils.getFilename
import com.t8rin.imagetoolbox.core.utils.filename
import com.t8rin.imagetoolbox.feature.ai_tools.domain.AiProgressListener
import com.t8rin.imagetoolbox.feature.ai_tools.domain.AiToolsRepository
import com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralConstants
@@ -193,7 +193,7 @@ internal class AndroidAiToolsRepository @Inject constructor(
}
val modelName = possibleModel?.name
?: uri.toUri().getFilename().orEmpty().ifEmpty {
?: uri.toUri().filename().orEmpty().ifEmpty {
"imported_model_($modelChecksum).onnx"
}

View File

@@ -94,7 +94,7 @@ import com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem
import com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItemOverload
import com.t8rin.imagetoolbox.core.ui.widget.saver.OneTimeEffect
import com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem
import com.t8rin.imagetoolbox.core.utils.getFilename
import com.t8rin.imagetoolbox.core.utils.filename
import com.t8rin.imagetoolbox.feature.ai_tools.domain.model.NeuralModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -117,7 +117,7 @@ internal fun NeuralModelsColumn(
val listState = rememberLazyListState()
val filePicker = rememberFilePicker { uri: Uri ->
val name = uri.getFilename().orEmpty()
val name = uri.filename().orEmpty()
if (name.endsWith(".onnx") || name.endsWith(".ort")) {
onImportModel(uri) {
when (it) {

View File

@@ -29,7 +29,7 @@ import com.t8rin.imagetoolbox.core.domain.image.model.ImageFormat
import com.t8rin.imagetoolbox.core.domain.image.model.Quality
import com.t8rin.imagetoolbox.core.domain.resource.ResourceManager
import com.t8rin.imagetoolbox.core.resources.R
import com.t8rin.imagetoolbox.core.utils.getFilename
import com.t8rin.imagetoolbox.core.utils.filename
import com.t8rin.imagetoolbox.feature.audio_cover_extractor.domain.AudioCoverRetriever
import com.t8rin.imagetoolbox.feature.audio_cover_extractor.domain.model.AudioCoverResult
import dagger.hilt.android.qualifiers.ApplicationContext
@@ -71,7 +71,7 @@ internal class AndroidAudioCoverRetriever @Inject constructor(
data = pictureData,
originalSize = true
)?.let { bitmap ->
val originalName = audioUri.toUri().getFilename(context)?.substringBeforeLast('.')
val originalName = audioUri.toUri().filename(context)?.substringBeforeLast('.')
?: "AUDIO_${System.currentTimeMillis()}"
shareProvider.cacheData(

View File

@@ -33,7 +33,7 @@ import com.t8rin.imagetoolbox.core.domain.utils.smartJob
import com.t8rin.imagetoolbox.core.domain.utils.timestamp
import com.t8rin.imagetoolbox.core.ui.utils.BaseComponent
import com.t8rin.imagetoolbox.core.ui.utils.state.update
import com.t8rin.imagetoolbox.core.utils.getFilename
import com.t8rin.imagetoolbox.core.utils.filename
import com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.PaletteType
import com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model.NamedPalette
import com.t8rin.imagetoolbox.feature.palette_tools.presentation.components.model.PaletteFormatHelper
@@ -110,7 +110,7 @@ class PaletteToolsComponent @AssistedInject internal constructor(
withContext(defaultDispatcher) {
val data = fileController.readBytes(uri.toString())
val entries =
PaletteFormatHelper.entriesFor(uri.getFilename() ?: uri.toString())
PaletteFormatHelper.entriesFor(uri.filename() ?: uri.toString())
for (format in entries) {
format.getCoder().use { decode(data) }.onSuccess { palette ->

View File

@@ -57,7 +57,7 @@ import com.t8rin.imagetoolbox.core.settings.domain.model.ShapeType
import com.t8rin.imagetoolbox.core.settings.domain.model.SliderType
import com.t8rin.imagetoolbox.core.settings.domain.model.SnowfallMode
import com.t8rin.imagetoolbox.core.settings.domain.model.SwitchType
import com.t8rin.imagetoolbox.core.utils.getFilename
import com.t8rin.imagetoolbox.core.utils.filename
import com.t8rin.imagetoolbox.feature.settings.data.keys.ADD_ORIGINAL_NAME_TO_FILENAME
import com.t8rin.imagetoolbox.feature.settings.data.keys.ADD_PRESET_TO_FILENAME
import com.t8rin.imagetoolbox.feature.settings.data.keys.ADD_SCALE_MODE_TO_FILENAME
@@ -831,7 +831,7 @@ internal class AndroidSettingsManager @Inject constructor(
val font = context.contentResolver.openInputStream(uri.toUri())?.use {
it.buffered().readBytes()
} ?: ByteArray(0)
val filename = uri.toUri().getFilename(context) ?: "font${Random.nextInt()}.ttf"
val filename = uri.toUri().filename(context) ?: "font${Random.nextInt()}.ttf"
val directory = File(context.filesDir, "customFonts").apply {
mkdir()

View File

@@ -41,7 +41,7 @@ import com.t8rin.imagetoolbox.core.ui.utils.content_pickers.rememberFolderPicker
import com.t8rin.imagetoolbox.core.ui.utils.provider.SafeLocalContainerColor
import com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults
import com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem
import com.t8rin.imagetoolbox.core.utils.toUiPath
import com.t8rin.imagetoolbox.core.utils.uiPath
@Composable
fun SavingFolderSettingItemGroup(
@@ -85,7 +85,7 @@ fun SavingFolderSettingItemGroup(
launcher.pickFolder(currentFolderUri)
},
title = stringResource(R.string.custom),
subtitle = currentFolderUri.toUiPath(
subtitle = currentFolderUri.uiPath(
default = stringResource(R.string.unspecified)
),
containerColor = takeColorFromScheme {

View File

@@ -22,7 +22,7 @@ import androidx.core.net.toUri
import com.t8rin.imagetoolbox.core.data.utils.outputStream
import com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder
import com.t8rin.imagetoolbox.core.domain.image.ShareProvider
import com.t8rin.imagetoolbox.core.utils.getFilename
import com.t8rin.imagetoolbox.core.utils.filename
import com.t8rin.imagetoolbox.feature.zip.domain.ZipManager
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.withContext
@@ -48,7 +48,7 @@ internal class AndroidZipManager @Inject constructor(
withContext(ioDispatcher) {
context.contentResolver.openInputStream(file.toUri()).use { input ->
BufferedInputStream(input).use { origin ->
val entry = ZipEntry(file.toUri().getFilename(context))
val entry = ZipEntry(file.toUri().filename(context))
output.putNextEntry(entry)
origin.copyTo(output, 1024)
}
@@ -58,7 +58,7 @@ internal class AndroidZipManager @Inject constructor(
}
}
},
filename = files.firstOrNull()?.toUri()?.getFilename() ?: "temp.zip"
filename = files.firstOrNull()?.toUri()?.filename() ?: "temp.zip"
) ?: throw IllegalArgumentException("Cached to null file")
}