Improve coroutines work

This commit is contained in:
T8RIN
2025-02-08 02:45:12 +03:00
parent 98deaf3d6a
commit a4bbe13384
55 changed files with 200 additions and 157 deletions

View File

@ -48,6 +48,7 @@ import ru.tech.imageresizershrinker.core.domain.image.model.ImageFormat
import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.model.IntegerSize
import ru.tech.imageresizershrinker.core.domain.transformation.Transformation
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.settings.domain.SettingsProvider
import ru.tech.imageresizershrinker.core.settings.domain.model.SettingsState
import java.util.Locale
@ -227,7 +228,7 @@ internal class AndroidImageGetter @Inject constructor(
.decoderFactory(UpscaleSvgDecoder.Factory())
.build()
runCatching {
runSuspendCatching {
imageLoader.execute(request).image?.toBitmap()
}.onFailure(onFailure).getOrNull()
}

View File

@ -40,6 +40,7 @@ import ru.tech.imageresizershrinker.core.domain.image.model.ResizeAnchor
import ru.tech.imageresizershrinker.core.domain.image.model.ResizeType
import ru.tech.imageresizershrinker.core.domain.image.model.ScaleColorSpace
import ru.tech.imageresizershrinker.core.domain.model.IntegerSize
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.filters.domain.FilterProvider
import ru.tech.imageresizershrinker.core.filters.domain.model.Filter
import ru.tech.imageresizershrinker.core.filters.domain.model.createFilter
@ -493,7 +494,7 @@ internal class AndroidImageScaler @Inject constructor(
ResizeAnchor.Height -> scaleByHeight()
ResizeAnchor.Default -> {
runCatching {
runSuspendCatching {
if (image.height >= image.width) {
val aspectRatio = image.aspectRatio
val targetWidth = (max * aspectRatio).toInt()

View File

@ -40,6 +40,7 @@ import ru.tech.imageresizershrinker.core.domain.saving.FilenameCreator
import ru.tech.imageresizershrinker.core.domain.saving.io.Writeable
import ru.tech.imageresizershrinker.core.domain.saving.io.use
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.resources.R
import java.io.File
import javax.inject.Inject
@ -79,7 +80,7 @@ internal class AndroidShareProvider @Inject constructor(
imageInfo: ImageInfo,
filename: String?
): String? = withContext(ioDispatcher) {
runCatching {
runSuspendCatching {
val saveTarget = ImageSaveTarget<ExifInterface>(
imageInfo = imageInfo,
originalUri = imageInfo.originalUri ?: "share",
@ -121,7 +122,7 @@ internal class AndroidShareProvider @Inject constructor(
onComplete: () -> Unit
) {
withContext(defaultDispatcher) {
runCatching {
runSuspendCatching {
shareUriImpl(
uri = uri,
type = type
@ -221,7 +222,7 @@ internal class AndroidShareProvider @Inject constructor(
): String? = withContext(ioDispatcher) {
val imagesFolder = File(context.cacheDir, "files")
runCatching {
runSuspendCatching {
imagesFolder.mkdirs()
val file = File(imagesFolder, filename)
FileWriteable(file).use {

View File

@ -28,6 +28,7 @@ import ru.tech.imageresizershrinker.core.domain.remote.RemoteResource
import ru.tech.imageresizershrinker.core.domain.remote.RemoteResources
import ru.tech.imageresizershrinker.core.domain.remote.RemoteResourcesDownloadProgress
import ru.tech.imageresizershrinker.core.domain.remote.RemoteResourcesStore
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
@ -71,7 +72,7 @@ internal class AndroidRemoteResourcesStore @Inject constructor(
onFailure: (Throwable) -> Unit,
downloadOnlyNewData: Boolean
): RemoteResources? = withContext(defaultDispatcher) {
runCatching {
runSuspendCatching {
val connection = URL(getResourcesLink(name)).openConnection() as HttpURLConnection
connection.apply {
@ -153,7 +154,7 @@ internal class AndroidRemoteResourcesStore @Inject constructor(
var count: Int
var downloaded = 0
val isSuccess = runCatching {
val isSuccess = runSuspendCatching {
BufferedInputStream(conn).use { input ->
FileOutputStream(outFile).use { output ->
withContext(ioDispatcher) {
@ -219,7 +220,7 @@ internal class AndroidRemoteResourcesStore @Inject constructor(
override suspend fun getResourceLinks(
name: String
): RemoteResources? = withContext(defaultDispatcher) {
runCatching {
runSuspendCatching {
val connection = URL(getResourcesLink(name)).openConnection() as HttpURLConnection
connection.apply {

View File

@ -55,6 +55,7 @@ import ru.tech.imageresizershrinker.core.domain.saving.io.use
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveTarget
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.settings.domain.SettingsManager
import ru.tech.imageresizershrinker.core.settings.domain.model.CopyToClipboardMode
@ -112,7 +113,7 @@ internal class AndroidFileController @Inject constructor(
val savingPath = oneTimeSaveLocationUri?.getPath(context) ?: defaultSavingPath
runCatching {
runSuspendCatching {
if (settingsState.copyToClipboardMode is CopyToClipboardMode.Enabled) {
val clipboardManager = context.getSystemService<ClipboardManager>()
@ -327,8 +328,8 @@ internal class AndroidFileController @Inject constructor(
override suspend fun writeBytes(
uri: String,
block: suspend (Writeable) -> Unit,
): SaveResult {
runCatching {
): SaveResult = withContext(ioDispatcher) {
runSuspendCatching {
context.openWriteableStream(
uri = uri.toUri(),
onFailure = { throw it }
@ -336,15 +337,15 @@ internal class AndroidFileController @Inject constructor(
StreamWriteable(stream).use { block(it) }
}
}.onSuccess {
return SaveResult.Success(
return@withContext SaveResult.Success(
message = null,
savingPath = ""
)
}.onFailure {
return SaveResult.Error.Exception(it)
return@withContext SaveResult.Error.Exception(it)
}
return SaveResult.Error.Exception(IllegalStateException())
return@withContext SaveResult.Error.Exception(IllegalStateException())
}
override suspend fun <O : Any> saveObject(

View File

@ -28,6 +28,7 @@ import androidx.exifinterface.media.ExifInterface
import kotlinx.coroutines.coroutineScope
import ru.tech.imageresizershrinker.core.domain.image.model.MetadataTag
import ru.tech.imageresizershrinker.core.domain.utils.readableByteCount
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import java.io.OutputStream
import kotlin.io.use
@ -44,7 +45,7 @@ suspend fun Context.copyMetadata(
fileUri: Uri?,
keepMetadata: Boolean,
originalUri: Uri
) = runCatching {
) = runSuspendCatching {
if (initialExif != null) {
getFileDescriptorFor(fileUri)?.use {
val ex = ExifInterface(it.fileDescriptor)

View File

@ -18,6 +18,9 @@
package ru.tech.imageresizershrinker.core.domain.utils
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.ensureActive
inline fun <reified T> T?.notNullAnd(
predicate: (T) -> Boolean
@ -39,4 +42,16 @@ inline fun <reified T, reified R> T.safeCast(): R? = this as? R
inline operator fun CharSequence.times(
count: Int
): CharSequence = repeat(count.coerceAtLeast(0))
): CharSequence = repeat(count.coerceAtLeast(0))
suspend inline fun <T, R> T.runSuspendCatching(block: T.() -> R): Result<R> {
currentCoroutineContext().ensureActive()
return try {
Result.success(block())
} catch (e: Throwable) {
currentCoroutineContext().ensureActive()
Result.failure(e)
}
}

View File

@ -247,7 +247,7 @@ class AddFiltersSheetComponent @AssistedInject internal constructor(
fileUri: Uri,
onResult: (SaveResult) -> Unit
) {
componentScope.launch(ioDispatcher) {
componentScope.launch {
fileController.writeBytes(
uri = fileUri.toString(),
block = { it.writeBytes(content.toByteArray()) }

View File

@ -44,6 +44,7 @@ import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.image.model.Quality
import ru.tech.imageresizershrinker.core.domain.image.model.ResizeType
import ru.tech.imageresizershrinker.core.domain.model.IntegerSize
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.feature.apng_tools.domain.ApngConverter
import ru.tech.imageresizershrinker.feature.apng_tools.domain.ApngParams
import java.io.ByteArrayOutputStream
@ -145,7 +146,7 @@ internal class AndroidApngConverter @Inject constructor(
) = withContext(defaultDispatcher) {
apngUris.forEach { uri ->
uri.bytes?.let { apngData ->
runCatching {
runSuspendCatching {
JxlCoder.Convenience.apng2JXL(
apngData = apngData,
quality = quality.qualityValue,

View File

@ -146,7 +146,7 @@ class ApngToolsComponent @AssistedInject internal constructor(
Screen.ApngTools.Type.ApngToImage(uri)
}
updateApngFrames(ImageFrames.All)
collectionJob = componentScope.launch(defaultDispatcher) {
collectionJob = componentScope.launch {
_isLoading.update { true }
_isLoadingApngImages.update { true }
apngConverter.extractFramesFromApng(
@ -192,7 +192,7 @@ class ApngToolsComponent @AssistedInject internal constructor(
uri: Uri,
onResult: (SaveResult) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
apngData?.let { byteArray ->
fileController.writeBytes(
@ -212,7 +212,7 @@ class ApngToolsComponent @AssistedInject internal constructor(
) {
_isSaving.value = false
savingJob?.cancel()
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_left.value = 1
_done.value = 0
@ -423,7 +423,7 @@ class ApngToolsComponent @AssistedInject internal constructor(
) {
_isSaving.value = false
savingJob?.cancel()
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_left.value = 1
_done.value = 0

View File

@ -184,7 +184,7 @@ class Base64ToolsComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (result: SaveResult) -> Unit,
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.update { true }
uri?.let { imageGetter.getImage(it) }?.let { image ->
val imageInfo = ImageInfo(

View File

@ -19,8 +19,10 @@
package ru.tech.imageresizershrinker.feature.cipher.data
import kotlinx.coroutines.withContext
import ru.tech.imageresizershrinker.core.data.saving.io.StringReadable
import ru.tech.imageresizershrinker.core.data.utils.computeBytesFromReadable
import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
import ru.tech.imageresizershrinker.core.domain.model.CipherType
import ru.tech.imageresizershrinker.core.domain.model.HashingType
import ru.tech.imageresizershrinker.feature.cipher.domain.CryptographyManager
@ -35,7 +37,9 @@ import javax.crypto.spec.PBEParameterSpec
import javax.crypto.spec.SecretKeySpec
import javax.inject.Inject
internal class AndroidCryptographyManager @Inject constructor() : CryptographyManager {
internal class AndroidCryptographyManager @Inject constructor(
private val dispatchersHolder: DispatchersHolder
) : CryptographyManager, DispatchersHolder by dispatchersHolder {
private val CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
@ -65,7 +69,7 @@ internal class AndroidCryptographyManager @Inject constructor() : CryptographyMa
data: ByteArray,
key: String,
type: CipherType
): ByteArray {
): ByteArray = withContext(defaultDispatcher) {
val cipher = type.toCipher(
keySpec = createKey(
password = key,
@ -74,14 +78,14 @@ internal class AndroidCryptographyManager @Inject constructor() : CryptographyMa
isEncrypt = false
)
return cipher.doOrThrow(data)
cipher.doOrThrow(data)
}
override suspend fun encrypt(
data: ByteArray,
key: String,
type: CipherType
): ByteArray {
): ByteArray = withContext(defaultDispatcher) {
val cipher = type.toCipher(
keySpec = createKey(
password = key,
@ -90,7 +94,7 @@ internal class AndroidCryptographyManager @Inject constructor() : CryptographyMa
isEncrypt = true
)
return cipher.doOrThrow(data)
cipher.doOrThrow(data)
}
private fun Cipher.init(

View File

@ -32,6 +32,7 @@ import ru.tech.imageresizershrinker.core.domain.image.ShareProvider
import ru.tech.imageresizershrinker.core.domain.model.CipherType
import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.domain.utils.smartJob
import ru.tech.imageresizershrinker.core.ui.utils.BaseComponent
import ru.tech.imageresizershrinker.core.ui.utils.state.update
@ -87,29 +88,30 @@ class CipherComponent @AssistedInject internal constructor(
onFileRequest: suspend (Uri) -> ByteArray?,
onComplete: (Throwable?) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
if (_uri.value == null) {
val uri = uri
if (uri == null) {
onComplete(null)
return@launch
}
val file = onFileRequest(_uri.value!!)
runCatching {
if (isEncrypt) {
_byteArray.value = file?.let {
cryptographyManager.encrypt(
data = it,
key = key,
type = cipherType
)
}
} else {
_byteArray.value = file?.let {
cryptographyManager.decrypt(
data = it,
key = key,
type = cipherType
)
runSuspendCatching {
_byteArray.update {
onFileRequest(uri)?.let { file ->
if (isEncrypt) {
cryptographyManager.encrypt(
data = file,
key = key,
type = cipherType
)
} else {
cryptographyManager.decrypt(
data = file,
key = key,
type = cipherType
)
}
}
}
}.exceptionOrNull().let(onComplete)
@ -141,7 +143,7 @@ class CipherComponent @AssistedInject internal constructor(
uri: Uri,
onResult: (SaveResult) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
byteArray?.let { byteArray ->
fileController.writeBytes(

View File

@ -140,7 +140,7 @@ class CollageMakerComponent @AssistedInject internal constructor(
_isSaving.update { true }
_collageCreationTrigger.update { true }
requestedOperation = {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
collageBitmap?.let { image ->
_isSaving.update { true }
val imageInfo = ImageInfo(

View File

@ -88,7 +88,7 @@ class CompareComponent @AssistedInject internal constructor(
if (it == 90f) 0f
else 90f
}
componentScope.launch(defaultDispatcher) {
componentScope.launch {
_bitmapData.value?.let { (f, s) ->
if (f != null && s != null) {
_isImageLoading.value = true
@ -118,7 +118,7 @@ class CompareComponent @AssistedInject internal constructor(
}
fun swap() {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
_isImageLoading.value = true
_bitmapData.value = _bitmapData.value?.run { second to first }
_isImageLoading.value = false
@ -130,7 +130,7 @@ class CompareComponent @AssistedInject internal constructor(
onFailure: () -> Unit,
onSuccess: () -> Unit
) {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
val data = getBitmapByUri(uris.first) to getBitmapByUri(uris.second)
if (data.first == null || data.second == null) onFailure()
else {
@ -153,7 +153,7 @@ class CompareComponent @AssistedInject internal constructor(
imageFormat: ImageFormat,
onComplete: () -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isImageLoading.value = true
getOverlappedImage(percent)?.let {
shareProvider.shareImage(
@ -176,7 +176,7 @@ class CompareComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (saveResult: SaveResult) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isImageLoading.value = true
getOverlappedImage(percent)?.let { localBitmap ->
onComplete(

View File

@ -141,7 +141,7 @@ class CropComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (saveResult: SaveResult) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
bitmap?.let { localBitmap ->
val byteArray = imageCompressor.compressAndTransform(

View File

@ -40,6 +40,7 @@ import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.FilenameCreator
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.domain.utils.smartJob
import ru.tech.imageresizershrinker.core.ui.utils.BaseComponent
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
@ -102,7 +103,7 @@ class DeleteExifComponent @AssistedInject internal constructor(
}
fun updateUrisSilently(removedUri: Uri) {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
_uris.value = uris
if (_selectedUri.value == removedUri) {
val index = uris?.indexOf(removedUri) ?: -1
@ -145,12 +146,12 @@ class DeleteExifComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onResult: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
val results = mutableListOf<SaveResult>()
_done.value = 0
uris?.forEach { uri ->
runCatching {
runSuspendCatching {
imageGetter.getImage(uri.toString())
}.getOrNull()?.let {
val metadata: ExifInterface? = if (selectedTags.isNotEmpty()) {
@ -189,7 +190,7 @@ class DeleteExifComponent @AssistedInject internal constructor(
fun updateSelectedUri(
uri: Uri,
onFailure: (Throwable) -> Unit = {}
) = componentScope.launch(defaultDispatcher) {
) = componentScope.launch {
_isImageLoading.value = true
_selectedUri.value = uri
imageGetter.getImageAsync(

View File

@ -42,6 +42,7 @@ import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.saving.model.onSuccess
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.domain.utils.smartJob
import ru.tech.imageresizershrinker.core.ui.utils.BaseComponent
import ru.tech.imageresizershrinker.core.ui.utils.helper.ScanResult
@ -108,12 +109,12 @@ class DocumentScannerComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
val results = mutableListOf<SaveResult>()
_done.value = 0
uris.forEach { uri ->
runCatching {
runSuspendCatching {
imageGetter.getImage(uri.toString())?.image
}.getOrNull()?.let { bitmap ->
val imageInfo = ImageInfo(
@ -154,7 +155,7 @@ class DocumentScannerComponent @AssistedInject internal constructor(
uri: Uri,
onResult: (SaveResult) -> Unit
) {
savingJob = componentScope.launch(ioDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
getPdfUri()?.let { pdfUri ->
fileController.writeBytes(
@ -200,7 +201,7 @@ class DocumentScannerComponent @AssistedInject internal constructor(
_done.update { 0 }
_left.update { 0 }
runCatching {
runSuspendCatching {
shareProvider.shareUri(
uri = pdfUri.toString(),
onComplete = onComplete

View File

@ -191,7 +191,7 @@ class DrawComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (saveResult: SaveResult) -> Unit,
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
getDrawingBitmap()?.let { localBitmap ->
onComplete(

View File

@ -38,6 +38,7 @@ import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.FilenameCreator
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.domain.utils.smartJob
import ru.tech.imageresizershrinker.core.ui.utils.BaseComponent
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
@ -82,9 +83,9 @@ class EditExifComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (result: SaveResult) -> Unit,
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.update { true }
runCatching {
runSuspendCatching {
imageGetter.getImage(uri.toString())
}.getOrNull()?.let {
val result = fileController.save(

View File

@ -178,7 +178,7 @@ class EraseBackgroundComponent @AssistedInject internal constructor(
) {
_isSaving.value = false
savingJob?.cancel()
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
getErasedBitmap(true)?.let { localBitmap ->
onComplete(
@ -303,7 +303,7 @@ class EraseBackgroundComponent @AssistedInject internal constructor(
onSuccess: () -> Unit,
onFailure: (Throwable) -> Unit,
) {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
getErasedBitmap(false)?.let { bitmap1 ->
_isErasingBG.value = true
autoBackgroundRemover.removeBackgroundFromImage(

View File

@ -37,6 +37,7 @@ import ru.tech.imageresizershrinker.core.domain.image.model.ImageFormat
import ru.tech.imageresizershrinker.core.domain.image.model.Quality
import ru.tech.imageresizershrinker.core.domain.model.ImageModel
import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.filters.domain.FavoriteFiltersInteractor
import ru.tech.imageresizershrinker.core.filters.domain.model.Filter
import ru.tech.imageresizershrinker.core.filters.domain.model.TemplateFilter
@ -90,9 +91,9 @@ internal class AndroidFavoriteFiltersInteractor @Inject constructor(
onSuccess: suspend (filterName: String, filtersCount: Int) -> Unit,
onFailure: suspend () -> Unit,
) {
runCatching {
runSuspendCatching {
if (isValidTemplateFilter(string)) {
runCatching {
runSuspendCatching {
string.removePrefix(LINK_HEADER).toTemplateFiltersList(context).firstOrNull()
}.getOrNull()?.let {
addTemplateFilter(it)

View File

@ -48,6 +48,7 @@ import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.saving.model.onSuccess
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.domain.utils.smartJob
import ru.tech.imageresizershrinker.core.filters.domain.FilterProvider
import ru.tech.imageresizershrinker.core.filters.presentation.model.UiFilter
@ -217,7 +218,7 @@ class FiltersComponent @AssistedInject internal constructor(
}
fun updateUrisSilently(removedUri: Uri) {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
val state = _basicFilterState.value
if (state.selectedUri == removedUri) {
val index = state.uris?.indexOf(removedUri) ?: -1
@ -260,13 +261,13 @@ class FiltersComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onResult: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
val results = mutableListOf<SaveResult>()
_done.value = 0
_left.value = _basicFilterState.value.uris?.size ?: 1
_basicFilterState.value.uris?.forEach { uri ->
runCatching {
runSuspendCatching {
imageGetter.getImageWithTransformations(
uri = uri.toString(),
transformations = _basicFilterState.value.filters.map {
@ -310,7 +311,7 @@ class FiltersComponent @AssistedInject internal constructor(
onFailure: (Throwable) -> Unit = {}
) {
runCatching {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
_isImageLoading.update { true }
val req = imageGetter.getImage(uri = uri.toString())
val tempBitmap = req?.image
@ -475,7 +476,7 @@ class FiltersComponent @AssistedInject internal constructor(
private fun updatePreview() {
_bitmap.value?.let { bitmap ->
filterJob = componentScope.launch(defaultDispatcher) {
filterJob = componentScope.launch {
delay(200L)
_isImageLoading.value = true
when (filterType) {
@ -554,7 +555,7 @@ class FiltersComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (saveResult: SaveResult) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_done.value = 0
_left.value = maskingFilterState.masks.size

View File

@ -30,7 +30,6 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.Job
import kotlinx.coroutines.withContext
import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
import ru.tech.imageresizershrinker.core.domain.image.ImageCompressor
import ru.tech.imageresizershrinker.core.domain.image.ImageGetter
@ -48,6 +47,7 @@ import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.saving.model.onSuccess
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.domain.utils.smartJob
import ru.tech.imageresizershrinker.core.ui.transformation.ImageInfoTransformation
import ru.tech.imageresizershrinker.core.ui.utils.BaseComponent
@ -138,7 +138,7 @@ class FormatConversionComponent @AssistedInject internal constructor(
removedUri: Uri,
onFailure: (Throwable) -> Unit
) {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
_uris.value = uris
if (_selectedUri.value == removedUri) {
val index = uris?.indexOf(removedUri) ?: -1
@ -172,17 +172,13 @@ class FormatConversionComponent @AssistedInject internal constructor(
private suspend fun updatePreview(
bitmap: Bitmap
): Bitmap? = withContext(defaultDispatcher) {
imageInfo.run {
imagePreviewCreator.createPreview(
image = bitmap,
imageInfo = this,
onGetByteCount = { size ->
_imageInfo.update { it.copy(sizeInBytes = size) }
}
)
): Bitmap? = imagePreviewCreator.createPreview(
image = bitmap,
imageInfo = imageInfo,
onGetByteCount = { size ->
_imageInfo.update { it.copy(sizeInBytes = size) }
}
}
)
private fun resetValues() {
_imageInfo.value = ImageInfo(
@ -252,12 +248,12 @@ class FormatConversionComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
val results = mutableListOf<SaveResult>()
_done.value = 0
uris?.forEach { uri ->
runCatching {
runSuspendCatching {
imageGetter.getImage(uri.toString())?.image
}.getOrNull()?.let { bitmap ->
imageInfo.copy(
@ -302,8 +298,8 @@ class FormatConversionComponent @AssistedInject internal constructor(
onFailure: (Throwable) -> Unit = {}
) {
_selectedUri.value = uri
componentScope.launch(defaultDispatcher) {
runCatching {
componentScope.launch {
runSuspendCatching {
_isImageLoading.update { true }
val bitmap = imageGetter.getImage(
uri = uri.toString(),

View File

@ -48,6 +48,7 @@ import ru.tech.imageresizershrinker.core.domain.image.model.ImageFormat
import ru.tech.imageresizershrinker.core.domain.image.model.ImageFrames
import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.image.model.Quality
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.feature.gif_tools.domain.GifConverter
import ru.tech.imageresizershrinker.feature.gif_tools.domain.GifParams
import java.io.ByteArrayOutputStream
@ -185,7 +186,7 @@ internal class AndroidGifConverter @Inject constructor(
) = withContext(defaultDispatcher) {
gifUris.forEach { uri ->
uri.bytes?.let { gifData ->
runCatching {
runSuspendCatching {
JxlCoder.Convenience.gif2JXL(
gifData = gifData,
quality = quality.qualityValue,
@ -212,7 +213,7 @@ internal class AndroidGifConverter @Inject constructor(
backgroundColor = Color.Transparent.toArgb()
)
runCatching {
runSuspendCatching {
encoder
.loadGif(uri.file)
.encode()

View File

@ -152,7 +152,7 @@ class GifToolsComponent @AssistedInject internal constructor(
}
updateGifFrames(ImageFrames.All)
collectionJob = componentScope.launch(defaultDispatcher) {
collectionJob = componentScope.launch {
_isLoading.update { true }
_isLoadingGifImages.update { true }
gifConverter.extractFramesFromGif(
@ -201,7 +201,7 @@ class GifToolsComponent @AssistedInject internal constructor(
uri: Uri,
onResult: (SaveResult) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
gifData?.let { byteArray ->
fileController.writeBytes(
@ -219,7 +219,7 @@ class GifToolsComponent @AssistedInject internal constructor(
onGifSaveResult: (filename: String) -> Unit,
onResult: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_left.value = 1
_done.value = 0
@ -467,7 +467,7 @@ class GifToolsComponent @AssistedInject internal constructor(
}
fun performSharing(onComplete: () -> Unit) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_left.value = 1
_done.value = 0

View File

@ -159,7 +159,7 @@ class GradientMakerComponent @AssistedInject internal constructor(
onStandaloneGradientSaveResult: (SaveResult) -> Unit,
onResult: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_left.value = -1
_isSaving.value = true
if (uris.isEmpty()) {
@ -398,7 +398,7 @@ class GradientMakerComponent @AssistedInject internal constructor(
fun updateUrisSilently(
removedUri: Uri
) = componentScope.launch(defaultDispatcher) {
) = componentScope.launch {
if (selectedUri == removedUri) {
val index = uris.indexOf(removedUri)
if (index == 0) {

View File

@ -77,7 +77,7 @@ class ImagePreviewComponent @AssistedInject internal constructor(
fun shareImages(
uriList: List<Uri>?,
onComplete: () -> Unit
) = componentScope.launch(defaultDispatcher) {
) = componentScope.launch {
uris?.let {
shareProvider.shareUris(
if (uriList.isNullOrEmpty()) {

View File

@ -112,7 +112,7 @@ class ImageSplitterComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
val results = mutableListOf<SaveResult>()
_done.value = 0

View File

@ -134,7 +134,7 @@ class ImageStackingComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (result: SaveResult) -> Unit,
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_done.value = 0
imageStacker.stackImages(

View File

@ -147,7 +147,7 @@ class ImageStitchingComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (result: SaveResult) -> Unit,
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_done.value = 0
imageCombiner.combineImages(

View File

@ -47,6 +47,7 @@ import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.image.model.Quality
import ru.tech.imageresizershrinker.core.domain.image.model.ResizeType
import ru.tech.imageresizershrinker.core.domain.model.IntegerSize
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.feature.jxl_tools.domain.AnimatedJxlParams
import ru.tech.imageresizershrinker.feature.jxl_tools.domain.JxlConverter
import javax.inject.Inject
@ -66,7 +67,7 @@ internal class AndroidJxlConverter @Inject constructor(
onProgress: suspend (String, ByteArray) -> Unit
) = withContext(defaultDispatcher) {
jpegUris.forEach { uri ->
runCatching {
runSuspendCatching {
uri.jxl?.let { onProgress(uri, it) }
}.onFailure(onFailure)
}
@ -78,7 +79,7 @@ internal class AndroidJxlConverter @Inject constructor(
onProgress: suspend (String, ByteArray) -> Unit
) = withContext(defaultDispatcher) {
jxlUris.forEach { uri ->
runCatching {
runSuspendCatching {
uri.jpeg?.let { onProgress(uri, it) }
}.onFailure(onFailure)
}
@ -97,7 +98,7 @@ internal class AndroidJxlConverter @Inject constructor(
return@withContext null
}
runCatching {
runSuspendCatching {
val size = params.size ?: imageGetter.getImage(data = imageUris[0])!!.run {
IntegerSize(width, height)
}

View File

@ -147,7 +147,7 @@ class JxlToolsComponent @AssistedInject internal constructor(
Screen.JxlTools.Type.JxlToImage(uri)
}
updateJxlFrames(ImageFrames.All)
collectionJob = componentScope.launch(defaultDispatcher) {
collectionJob = componentScope.launch {
_isLoading.update { true }
_isLoadingJxlImages.update { true }
jxlConverter.extractFramesFromJxl(
@ -176,7 +176,7 @@ class JxlToolsComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onResult: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_left.value = 1
_done.value = 0
@ -382,7 +382,7 @@ class JxlToolsComponent @AssistedInject internal constructor(
onFailure: (Throwable) -> Unit,
onComplete: () -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_left.value = 1
_done.value = 0

View File

@ -44,6 +44,7 @@ import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.saving.model.onSuccess
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.domain.utils.smartJob
import ru.tech.imageresizershrinker.core.ui.utils.BaseComponent
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
@ -136,7 +137,7 @@ class LimitsResizeComponent @AssistedInject internal constructor(
}
fun updateUrisSilently(removedUri: Uri) {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
_uris.value = uris
if (_selectedUri.value == removedUri) {
val index = uris?.indexOf(removedUri) ?: -1
@ -186,12 +187,12 @@ class LimitsResizeComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onResult: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
val results = mutableListOf<SaveResult>()
_done.value = 0
uris?.forEach { uri ->
runCatching {
runSuspendCatching {
imageGetter.getImage(uri.toString())?.image
}.getOrNull()?.let { bitmap ->
imageScaler.scaleImage(
@ -236,10 +237,10 @@ class LimitsResizeComponent @AssistedInject internal constructor(
fun updateSelectedUri(
uri: Uri,
onFailure: (Throwable) -> Unit = {}
onFailure: (Throwable) -> Unit = {} //TODO: Remove unnecessary callbacks
) {
runCatching {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
_isImageLoading.value = true
updateBitmap(imageGetter.getImage(uri.toString())?.image)
_selectedUri.value = uri

View File

@ -29,6 +29,7 @@ import ru.tech.imageresizershrinker.core.domain.image.ImageGetter
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider
import ru.tech.imageresizershrinker.core.domain.image.model.ImageFormat
import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.feature.load_net_image.domain.HtmlImageParser
import java.net.UnknownHostException
@ -53,7 +54,7 @@ internal class AndroidHtmlImageParser @Inject constructor(
val baseImage = loadImage(realUrl)
val parsedImages = if (realUrl.isNotEmpty()) {
runCatching {
runSuspendCatching {
val parsed = Jsoup
.connect(realUrl)
.userAgent(USER_AGENT)

View File

@ -174,7 +174,7 @@ class LoadNetImageComponent @AssistedInject internal constructor(
) {
_isSaving.value = false
savingJob?.cancel()
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
val positions =

View File

@ -199,7 +199,7 @@ class MarkupLayersComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (saveResult: SaveResult) -> Unit,
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
getDrawingBitmap()?.let { localBitmap ->
onComplete(

View File

@ -28,6 +28,7 @@ import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.feature.media_picker.data.utils.Query
import ru.tech.imageresizershrinker.feature.media_picker.data.utils.contentFlowObserver
import ru.tech.imageresizershrinker.feature.media_picker.data.utils.getAlbums
@ -170,7 +171,7 @@ internal class AndroidMediaRetriever @Inject constructor(
uris = uris,
coroutineContext = ioDispatcher
).map {
runCatching {
runSuspendCatching {
dataBody.invoke(contentResolver)
}
}.conflate()
@ -181,7 +182,7 @@ internal class AndroidMediaRetriever @Inject constructor(
uris = uris,
coroutineContext = ioDispatcher
).map {
runCatching {
runSuspendCatching {
dataBody.invoke(contentResolver)
}
}.conflate()

View File

@ -105,7 +105,7 @@ class MediaPickerComponent @AssistedInject internal constructor(
private var albumJob: Job? by smartJob()
private fun getAlbums(allowedMedia: AllowedMedia) {
albumJob = componentScope.launch(defaultDispatcher) {
albumJob = componentScope.launch {
mediaRetriever.getAlbumsWithType(allowedMedia)
.flowOn(defaultDispatcher)
.collectLatest { result ->
@ -135,7 +135,7 @@ class MediaPickerComponent @AssistedInject internal constructor(
albumId: Long,
allowedMedia: AllowedMedia
) {
mediaGettingJob = componentScope.launch(defaultDispatcher) {
mediaGettingJob = componentScope.launch {
_mediaState.emit(mediaState.value.copy(isLoading = true))
mediaRetriever.mediaFlowWithType(albumId, allowedMedia)
.flowOn(defaultDispatcher)

View File

@ -79,7 +79,7 @@ class MeshGradientsComponent @AssistedInject constructor(
fun shareImages(
uriList: List<Uri>,
onComplete: () -> Unit
) = componentScope.launch(defaultDispatcher) {
) = componentScope.launch {
shareProvider.shareImages(
uris = uriList.map { it.toString() },
imageLoader = {

View File

@ -89,7 +89,7 @@ class NoiseGenerationComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (result: SaveResult) -> Unit,
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.update { true }
noiseGenerator.generateNoise(
width = noiseSize.width,

View File

@ -40,6 +40,7 @@ import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.saving.model.onSuccess
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.domain.utils.smartJob
import ru.tech.imageresizershrinker.core.ui.utils.BaseComponent
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
@ -111,7 +112,7 @@ class PdfToolsComponent @AssistedInject internal constructor(
uri: Uri,
onResult: (SaveResult) -> Unit
) {
savingJob = componentScope.launch(ioDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_byteArray.value?.let { byteArray ->
fileController.writeBytes(
@ -395,7 +396,7 @@ class PdfToolsComponent @AssistedInject internal constructor(
private fun checkForOOM() {
val preset = _presetSelected.value
presetSelectionJob = componentScope.launch {
runCatching {
runSuspendCatching {
_pdfToImageState.value?.let { (uri, _, selectedPages) ->
val pagesSize = pdfManager.getPdfPageSizes(uri.toString())
.filterIndexed { index, _ -> index in selectedPages }

View File

@ -31,6 +31,7 @@ import dagger.assisted.AssistedInject
import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
import ru.tech.imageresizershrinker.core.domain.image.ImageGetter
import ru.tech.imageresizershrinker.core.domain.image.ImageScaler
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.ui.utils.BaseComponent
class PickColorFromImageComponent @AssistedInject internal constructor(
@ -68,7 +69,7 @@ class PickColorFromImageComponent @AssistedInject internal constructor(
) {
_uri.value = uri
componentScope.launch {
runCatching {
runSuspendCatching {
updateBitmap(
imageGetter.getImage(
data = uri,

View File

@ -457,7 +457,7 @@ class RecognizeTextComponent @AssistedInject internal constructor(
uri: Uri,
onResult: (SaveResult) -> Unit
) {
languagesJob = componentScope.launch(ioDispatcher) {
languagesJob = componentScope.launch {
_isExporting.value = true
imageTextReader.exportLanguagesToZip()?.let { zipUri ->
fileController.writeBytes(
@ -490,7 +490,7 @@ class RecognizeTextComponent @AssistedInject internal constructor(
onSuccess: () -> Unit,
onFailure: (Throwable) -> Unit
) {
languagesJob = componentScope.launch(ioDispatcher) {
languagesJob = componentScope.launch {
_isExporting.value = true
imageTextReader.importLanguagesFromUri(uri.toString())
.onSuccess {

View File

@ -51,6 +51,7 @@ import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.saving.model.onSuccess
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.domain.utils.smartJob
import ru.tech.imageresizershrinker.core.settings.domain.SettingsProvider
import ru.tech.imageresizershrinker.core.ui.transformation.ImageInfoTransformation
@ -162,7 +163,7 @@ class ResizeAndConvertComponent @AssistedInject internal constructor(
}
fun updateUrisSilently(removedUri: Uri) {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
_uris.update { uris }
if (_selectedUri.value == removedUri) {
val index = uris?.indexOf(removedUri) ?: -1
@ -381,12 +382,12 @@ class ResizeAndConvertComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.update { true }
val results = mutableListOf<SaveResult>()
_done.update { 0 }
uris?.forEach { uri ->
runCatching {
runSuspendCatching {
imageGetter.getImage(uri.toString())?.image
}.getOrNull()?.let { bitmap ->
imageInfo.copy(
@ -432,7 +433,7 @@ class ResizeAndConvertComponent @AssistedInject internal constructor(
) {
runCatching {
_selectedUri.update { uri }
componentScope.launch(defaultDispatcher) {
componentScope.launch {
_isImageLoading.update { true }
val bitmap = imageGetter.getImage(
uri = uri.toString(),

View File

@ -23,6 +23,7 @@ import androidx.datastore.preferences.core.PreferencesSerializer
import kotlinx.coroutines.coroutineScope
import okio.buffer
import okio.source
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.resources.R
import java.io.ByteArrayInputStream
import java.io.File
@ -33,7 +34,7 @@ internal suspend fun Context.restoreDatastore(
onFailure: (Throwable) -> Unit,
onSuccess: suspend () -> Unit
) = coroutineScope {
runCatching {
runSuspendCatching {
contentResolver.openInputStream(backupUri)?.use { input ->
val bytes = input.readBytes()
restoreDatastore(
@ -54,10 +55,11 @@ internal suspend fun Context.restoreDatastore(
onFailure: (Throwable) -> Unit,
onSuccess: suspend () -> Unit
) = coroutineScope {
runCatching {
try {
runSuspendCatching {
runSuspendCatching {
PreferencesSerializer.readFrom(ByteArrayInputStream(backupData).source().buffer())
} catch (_: Throwable) {
}.onFailure {
onFailure(Throwable(getString(R.string.corrupted_file_or_not_a_backup)))
return@coroutineScope
}

View File

@ -325,7 +325,7 @@ class SettingsComponent @AssistedInject internal constructor(
uri: Uri,
onResult: (SaveResult) -> Unit,
) {
componentScope.launch(ioDispatcher) {
componentScope.launch {
fileController.writeBytes(
uri = uri.toString(),
block = { it.writeBytes(settingsManager.createBackupFile()) }
@ -337,7 +337,7 @@ class SettingsComponent @AssistedInject internal constructor(
uri: Uri,
onResult: (SaveResult) -> Unit,
) {
componentScope.launch(ioDispatcher) {
componentScope.launch {
fileController.writeBytes(
uri = uri.toString(),
block = { it.writeBytes(settingsManager.createCustomFontsExport()) }

View File

@ -249,7 +249,7 @@ class SingleEditComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onComplete: (result: SaveResult) -> Unit,
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.update { true }
bitmap?.let { bitmap ->
onComplete(

View File

@ -30,6 +30,7 @@ import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
import ru.tech.imageresizershrinker.core.domain.image.ImageGetter
import ru.tech.imageresizershrinker.core.domain.model.IntegerSize
import ru.tech.imageresizershrinker.core.domain.saving.RandomStringGenerator
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.feature.svg_maker.domain.SvgManager
import ru.tech.imageresizershrinker.feature.svg_maker.domain.SvgParams
import java.io.File
@ -50,7 +51,7 @@ internal class AndroidSvgManager @Inject constructor(
onProgress: suspend (originalUri: String, data: ByteArray) -> Unit
) = withContext(defaultDispatcher) {
imageUris.forEach { uri ->
runCatching {
runSuspendCatching {
val folder = File(context.cacheDir, "svg").apply { mkdirs() }
val file = File(folder, "${randomStringGenerator.generate(10)}.svg")

View File

@ -87,7 +87,7 @@ class SvgMakerComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onResult: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
val results = mutableListOf<SaveResult>()
_isSaving.value = true

View File

@ -142,7 +142,7 @@ class WatermarkingComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onResult: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_left.value = -1
_isSaving.value = true
val results = mutableListOf<SaveResult>()
@ -283,7 +283,7 @@ class WatermarkingComponent @AssistedInject internal constructor(
}
fun updateUrisSilently(removedUri: Uri) {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
if (selectedUri == removedUri) {
val index = uris.indexOf(removedUri)
if (index == 0) {

View File

@ -133,7 +133,7 @@ class WebpToolsComponent @AssistedInject internal constructor(
Screen.WebpTools.Type.WebpToImage(uri)
}
updateWebpFrames(ImageFrames.All)
collectionJob = componentScope.launch(defaultDispatcher) {
collectionJob = componentScope.launch {
_isLoading.update { true }
_isLoadingWebpImages.update { true }
webpConverter.extractFramesFromWebp(
@ -179,7 +179,7 @@ class WebpToolsComponent @AssistedInject internal constructor(
uri: Uri,
onResult: (SaveResult) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
webpData?.let { byteArray ->
fileController.writeBytes(
@ -199,7 +199,7 @@ class WebpToolsComponent @AssistedInject internal constructor(
) {
_isSaving.value = false
savingJob?.cancel()
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_left.value = 1
_done.value = 0
@ -353,7 +353,7 @@ class WebpToolsComponent @AssistedInject internal constructor(
) {
_isSaving.value = false
savingJob?.cancel()
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_left.value = 1
_done.value = 0

View File

@ -28,6 +28,7 @@ import ru.tech.imageresizershrinker.core.domain.image.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.image.model.ImageScaleMode
import ru.tech.imageresizershrinker.core.domain.image.model.Quality
import ru.tech.imageresizershrinker.core.domain.model.IntegerSize
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.feature.weight_resize.domain.WeightImageScaler
import javax.inject.Inject
import kotlin.math.roundToInt
@ -46,7 +47,7 @@ internal class AndroidWeightImageScaler @Inject constructor(
imageScaleMode: ImageScaleMode,
maxBytes: Long
): Pair<ByteArray, ImageInfo>? = withContext(defaultDispatcher) {
runCatching {
runSuspendCatching {
val initialSize = imageCompressor.calculateImageSize(
image = image,
imageInfo = ImageInfo(

View File

@ -45,6 +45,7 @@ import ru.tech.imageresizershrinker.core.domain.saving.FilenameCreator
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.saving.model.onSuccess
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.domain.utils.smartJob
import ru.tech.imageresizershrinker.core.ui.utils.BaseComponent
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
@ -159,7 +160,7 @@ class WeightResizeComponent @AssistedInject internal constructor(
}
fun updateUrisSilently(removedUri: Uri) {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
_uris.value = uris
if (_selectedUri.value == removedUri) {
val index = uris?.indexOf(removedUri) ?: -1
@ -205,15 +206,15 @@ class WeightResizeComponent @AssistedInject internal constructor(
oneTimeSaveLocationUri: String?,
onResult: (List<SaveResult>) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
val results = mutableListOf<SaveResult>()
_done.value = 0
uris?.forEach { uri ->
runCatching {
runSuspendCatching {
imageGetter.getImage(uri.toString())
}.getOrNull()?.image?.let { bitmap ->
runCatching {
runSuspendCatching {
if (handMode) {
imageScaler.scaleByMaxBytes(
image = bitmap,
@ -261,7 +262,7 @@ class WeightResizeComponent @AssistedInject internal constructor(
onFailure: (Throwable) -> Unit = {}
) {
runCatching {
componentScope.launch(defaultDispatcher) {
componentScope.launch {
updateBitmap(
imageGetter.getImage(
uri = uri.toString(),

View File

@ -32,6 +32,7 @@ import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider
import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
import ru.tech.imageresizershrinker.core.domain.utils.smartJob
import ru.tech.imageresizershrinker.core.ui.utils.BaseComponent
import ru.tech.imageresizershrinker.core.ui.utils.state.update
@ -80,12 +81,12 @@ class ZipComponent @AssistedInject internal constructor(
fun startCompression(
onFailure: (Throwable) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
if (uris.isEmpty()) {
return@launch
}
runCatching {
runSuspendCatching {
_done.update { 0 }
_left.update { uris.size }
_byteArray.value = zipManager.zip(
@ -107,7 +108,7 @@ class ZipComponent @AssistedInject internal constructor(
uri: Uri,
onResult: (SaveResult) -> Unit
) {
savingJob = componentScope.launch(defaultDispatcher) {
savingJob = componentScope.launch {
_isSaving.value = true
_byteArray.value?.let { byteArray ->
fileController.writeBytes(