mirror of
https://github.com/T8RIN/ImageToolbox.git
synced 2025-05-17 13:35:58 +08:00
Improve coroutines work
This commit is contained in:
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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()) }
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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(),
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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()) {
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 =
|
||||
|
@ -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(
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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 = {
|
||||
|
@ -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,
|
||||
|
@ -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 }
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()) }
|
||||
|
@ -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(
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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(),
|
||||
|
@ -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(
|
||||
|
Reference in New Issue
Block a user