diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c3f89fb99d..3b41260eb6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.11.4 + +* `Coroutines`: + * `Compose`: + * Add extension `StateFlow#asMutableComposeListState` and `StateFlow#asComposeList` + * Add extension `StateFlow#asMutableComposeState`/`StateFlow#asComposeState` + ## 0.11.3 * `Ktor`: diff --git a/coroutines/compose/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/compose/FlowAsListState.kt b/coroutines/compose/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/compose/FlowAsListState.kt new file mode 100644 index 00000000000..3ce3e860eac --- /dev/null +++ b/coroutines/compose/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/compose/FlowAsListState.kt @@ -0,0 +1,26 @@ +package dev.inmo.micro_utils.coroutines.compose + +import androidx.compose.runtime.* +import androidx.compose.runtime.snapshots.SnapshotStateList +import dev.inmo.micro_utils.common.applyDiff +import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.StateFlow + +@Suppress("NOTHING_TO_INLINE") +inline fun Flow>.asMutableComposeListState( + scope: CoroutineScope +): SnapshotStateList { + val state = mutableStateListOf() + subscribeSafelyWithoutExceptions(scope) { + state.applyDiff(it) + } + return state +} + +@Suppress("NOTHING_TO_INLINE") +inline fun Flow>.asComposeList( + scope: CoroutineScope +): List = asMutableComposeListState(scope) + diff --git a/coroutines/compose/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/compose/FlowAsState.kt b/coroutines/compose/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/compose/FlowAsState.kt new file mode 100644 index 00000000000..334c5dcb6ea --- /dev/null +++ b/coroutines/compose/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/compose/FlowAsState.kt @@ -0,0 +1,35 @@ +package dev.inmo.micro_utils.coroutines.compose + +import androidx.compose.runtime.* +import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.StateFlow + +fun Flow.asMutableComposeState( + initial: T, + scope: CoroutineScope +): MutableState { + val state = mutableStateOf(initial) + subscribeSafelyWithoutExceptions(scope) { state.value = it } + return state +} + +@Suppress("NOTHING_TO_INLINE") +inline fun StateFlow.asMutableComposeState( + scope: CoroutineScope +): MutableState = asMutableComposeState(value, scope) + +fun Flow.asComposeState( + initial: T, + scope: CoroutineScope +): State { + val state = asMutableComposeState(initial, scope) + return derivedStateOf { state.value } +} + +@Suppress("NOTHING_TO_INLINE") +inline fun StateFlow.asComposeState( + scope: CoroutineScope +): State = asComposeState(value, scope) + diff --git a/coroutines/compose/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/compose/FlowToState.kt b/coroutines/compose/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/compose/FlowToMutableState.kt similarity index 100% rename from coroutines/compose/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/compose/FlowToState.kt rename to coroutines/compose/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/compose/FlowToMutableState.kt diff --git a/gradle.properties b/gradle.properties index 8ff6592186e..27e35f6180e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,5 +14,5 @@ crypto_js_version=4.1.1 # Project data group=dev.inmo -version=0.11.3 -android_code_version=127 +version=0.11.4 +android_code_version=128 diff --git a/ktor/client/src/jsMain/kotlin/dev/inmo/micro_utils/ktor/client/ActualTemporalUpload.kt b/ktor/client/src/jsMain/kotlin/dev/inmo/micro_utils/ktor/client/ActualTemporalUpload.kt index 0824c19c516..33c8a4910f5 100644 --- a/ktor/client/src/jsMain/kotlin/dev/inmo/micro_utils/ktor/client/ActualTemporalUpload.kt +++ b/ktor/client/src/jsMain/kotlin/dev/inmo/micro_utils/ktor/client/ActualTemporalUpload.kt @@ -4,7 +4,10 @@ import dev.inmo.micro_utils.common.MPPFile import dev.inmo.micro_utils.ktor.common.TemporalFileId import io.ktor.client.HttpClient import kotlinx.coroutines.* +import org.w3c.dom.mediasource.ENDED +import org.w3c.dom.mediasource.ReadyState import org.w3c.xhr.* +import org.w3c.xhr.XMLHttpRequest.Companion.DONE suspend fun tempUpload( fullTempUploadDraftPath: String, @@ -12,7 +15,7 @@ suspend fun tempUpload( onUpload: (Long, Long) -> Unit ): TemporalFileId { val formData = FormData() - val answer = CompletableDeferred() + val answer = CompletableDeferred(currentCoroutineContext().job) formData.append( "data", @@ -37,17 +40,15 @@ suspend fun tempUpload( request.open("POST", fullTempUploadDraftPath, true) request.send(formData) - val handle = currentCoroutineContext().job.invokeOnCompletion { + answer.invokeOnCompletion { runCatching { - request.abort() + if (request.readyState != DONE) { + request.abort() + } } } - return runCatching { - answer.await() - }.also { - handle.dispose() - }.getOrThrow() + return answer.await() }