diff --git a/apps/vbox/client/shared/src/androidMain/kotlin/ru/shadowsparky/vbox/shared/domain/ActivityInfo.kt b/apps/vbox/client/shared/src/androidMain/kotlin/ru/shadowsparky/vbox/shared/domain/ActivityInfo.kt deleted file mode 100644 index 6550726..0000000 --- a/apps/vbox/client/shared/src/androidMain/kotlin/ru/shadowsparky/vbox/shared/domain/ActivityInfo.kt +++ /dev/null @@ -1,7 +0,0 @@ -package ru.shadowsparky.vbox.shared.domain - -import kotlinx.coroutines.flow.StateFlow - -interface ActivityInfo { - val isActiveFlow: StateFlow -} diff --git a/apps/vbox/client/shared/src/commonMain/kotlin/ru/shadowsparky/vbox/shared/data/VBoxUpdateFetcher.kt b/apps/vbox/client/shared/src/commonMain/kotlin/ru/shadowsparky/vbox/shared/data/VBoxUpdateFetcher.kt new file mode 100644 index 0000000..c527a13 --- /dev/null +++ b/apps/vbox/client/shared/src/commonMain/kotlin/ru/shadowsparky/vbox/shared/data/VBoxUpdateFetcher.kt @@ -0,0 +1,27 @@ +package ru.shadowsparky.vbox.shared.data + +import io.ktor.client.HttpClient +import org.koin.core.annotation.Factory +import ru.shadowsparky.domain.AppConfig +import ru.shadowsparky.updater.domain.UpdateFetcher +import ru.shadowsparky.updater.domain.UpdateInfo +import ru.shadowsparky.vbox.shared.domain.DYNAMIC_PREFIX +import ru.shadowsparky.vbox.shared.domain.ServerConfigurationRepository +import ru.shadowsparky.vbox.shared.domain.getServerConfiguration + +@Factory +class VBoxUpdateFetcher( + private val httpClient: HttpClient, + private val serverConfigurationProvider: ServerConfigurationRepository, + private val appConfig: AppConfig +) : UpdateFetcher { + override suspend fun fetch(): UpdateInfo { + return httpClient.get( + "$DYNAMIC_PREFIX/checkUpdates", + mapOf( + "versionCode" to appConfig.versionCode.toString() + ), + serverConfigurationProvider.getServerConfiguration() + ) + } +} diff --git a/apps/vbox/client/shared/src/commonMain/kotlin/ru/shadowsparky/vbox/shared/presentation/settings/SettingsComponent.kt b/apps/vbox/client/shared/src/commonMain/kotlin/ru/shadowsparky/vbox/shared/presentation/settings/SettingsComponent.kt index a51ad8f..cb32f7e 100644 --- a/apps/vbox/client/shared/src/commonMain/kotlin/ru/shadowsparky/vbox/shared/presentation/settings/SettingsComponent.kt +++ b/apps/vbox/client/shared/src/commonMain/kotlin/ru/shadowsparky/vbox/shared/presentation/settings/SettingsComponent.kt @@ -39,7 +39,7 @@ class SettingsComponent( val showOffline: () -> Unit, val showTags: () -> Unit ) : ComponentContext by context { - private val updateComponent = updateComponentFactory.create(childContext("UpdateComponent")) + val updateComponent = updateComponentFactory.create(childContext("UpdateComponent")) val hasUpdateSupport = updateComponent.hasSupport diff --git a/apps/vbox/client/shared/src/commonMain/kotlin/ru/shadowsparky/vbox/shared/presentation/settings/SettingsScreen.kt b/apps/vbox/client/shared/src/commonMain/kotlin/ru/shadowsparky/vbox/shared/presentation/settings/SettingsScreen.kt index 1336c83..396e8ce 100644 --- a/apps/vbox/client/shared/src/commonMain/kotlin/ru/shadowsparky/vbox/shared/presentation/settings/SettingsScreen.kt +++ b/apps/vbox/client/shared/src/commonMain/kotlin/ru/shadowsparky/vbox/shared/presentation/settings/SettingsScreen.kt @@ -27,6 +27,7 @@ import ru.shadowsparky.ui.applyBlurSource import ru.shadowsparky.ui.components.ExpressiveLazyColumn import ru.shadowsparky.ui.components.SwitchPreference import ru.shadowsparky.ui.components.TextPreference +import ru.shadowsparky.updater.presentation.UpdateBottomSheet @Composable fun SettingsContent(comp: SettingsComponent, paddingValues: PaddingValues) { @@ -73,7 +74,7 @@ fun SettingsContent(comp: SettingsComponent, paddingValues: PaddingValues) { modifier = Modifier.clickable { comp.showTags() } ) } - if (comp.hasUpdateSupport) { + if (comp.updateComponent.hasSupport) { item { TextPreference( text = stringResource(Res.string.check_for_updates), @@ -115,6 +116,7 @@ fun SettingsContent(comp: SettingsComponent, paddingValues: PaddingValues) { } } ) + UpdateBottomSheet(comp.updateComponent) LaunchedEffect(null) { withFrameNanos {} requester.requestFocus() diff --git a/libs/base/src/commonMain/kotlin/ru/shadowsparky/data/KeyValueStorageImpl.kt b/libs/base/src/commonMain/kotlin/ru/shadowsparky/data/KeyValueStorageImpl.kt index c6383a5..401d6f6 100644 --- a/libs/base/src/commonMain/kotlin/ru/shadowsparky/data/KeyValueStorageImpl.kt +++ b/libs/base/src/commonMain/kotlin/ru/shadowsparky/data/KeyValueStorageImpl.kt @@ -5,6 +5,7 @@ import com.russhwolf.settings.Settings import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import ru.shadowsparky.domain.DispatcherProvider @@ -27,7 +28,7 @@ class SettingsKeyValueStorage( } override fun get(key: String): Flow { - return impl.get(key) + return impl.get(key).flowOn(dispatcherProvider.io) } override suspend fun remove(key: String) = withContext(dispatcherProvider.io) { diff --git a/libs/updater/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateBottomSheet.kt b/libs/updater/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateBottomSheet.kt index 9a0c47f..c786506 100644 --- a/libs/updater/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateBottomSheet.kt +++ b/libs/updater/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateBottomSheet.kt @@ -18,11 +18,11 @@ import androidx.compose.animation.AnimatedContent import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button -import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme @@ -38,6 +38,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.arkivanov.decompose.extensions.compose.subscribeAsState import org.jetbrains.compose.resources.stringResource +import ru.shadowsparky.ui.components.Loading import ru.shadowsparky.updater.domain.UpdateState @OptIn(ExperimentalMaterial3Api::class) @@ -54,11 +55,15 @@ fun UpdateBottomSheet( val isVisible = remember(state) { state !is UpdateState.Idle && state !is UpdateState.UpToDate } if (isVisible) { - ModalBottomSheet(onDismissRequest = {}, sheetState = sheetState, modifier = modifier) { + ModalBottomSheet( + onDismissRequest = { component.reset() }, + sheetState = sheetState, + modifier = modifier + ) { AnimatedContent( targetState = state, label = "UpdateStateAnimation", - modifier = Modifier.fillMaxWidth().padding(start = 16.dp, end = 16.dp, bottom = 32.dp) + modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp) ) { currentState -> when (currentState) { is UpdateState.Checking -> UpdateCheckingContent() @@ -90,11 +95,8 @@ fun UpdateBottomSheet( } @Composable -private fun UpdateCheckingContent(modifier: Modifier = Modifier) { - Column( - modifier = modifier.fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally - ) { CircularProgressIndicator() } +private fun UpdateCheckingContent() { + Loading(Modifier.fillMaxSize()) } @Composable diff --git a/libs/updater/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateComponent.kt b/libs/updater/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateComponent.kt index 0bc9570..83b6001 100644 --- a/libs/updater/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateComponent.kt +++ b/libs/updater/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateComponent.kt @@ -65,6 +65,10 @@ class UpdateComponent( fun installApk(path: String) { scope.launch { interactor.installApk(path) } } + + fun reset() { + _state.value = UpdateState.Idle + } } @Factory