impl VBoxUpdateFetcher
This commit is contained in:
-7
@@ -1,7 +0,0 @@
|
|||||||
package ru.shadowsparky.vbox.shared.domain
|
|
||||||
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
|
|
||||||
interface ActivityInfo {
|
|
||||||
val isActiveFlow: StateFlow<Boolean>
|
|
||||||
}
|
|
||||||
+27
@@ -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<UpdateInfo>(
|
||||||
|
"$DYNAMIC_PREFIX/checkUpdates",
|
||||||
|
mapOf(
|
||||||
|
"versionCode" to appConfig.versionCode.toString()
|
||||||
|
),
|
||||||
|
serverConfigurationProvider.getServerConfiguration()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -39,7 +39,7 @@ class SettingsComponent(
|
|||||||
val showOffline: () -> Unit,
|
val showOffline: () -> Unit,
|
||||||
val showTags: () -> Unit
|
val showTags: () -> Unit
|
||||||
) : ComponentContext by context {
|
) : ComponentContext by context {
|
||||||
private val updateComponent = updateComponentFactory.create(childContext("UpdateComponent"))
|
val updateComponent = updateComponentFactory.create(childContext("UpdateComponent"))
|
||||||
|
|
||||||
val hasUpdateSupport = updateComponent.hasSupport
|
val hasUpdateSupport = updateComponent.hasSupport
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -27,6 +27,7 @@ import ru.shadowsparky.ui.applyBlurSource
|
|||||||
import ru.shadowsparky.ui.components.ExpressiveLazyColumn
|
import ru.shadowsparky.ui.components.ExpressiveLazyColumn
|
||||||
import ru.shadowsparky.ui.components.SwitchPreference
|
import ru.shadowsparky.ui.components.SwitchPreference
|
||||||
import ru.shadowsparky.ui.components.TextPreference
|
import ru.shadowsparky.ui.components.TextPreference
|
||||||
|
import ru.shadowsparky.updater.presentation.UpdateBottomSheet
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsContent(comp: SettingsComponent, paddingValues: PaddingValues) {
|
fun SettingsContent(comp: SettingsComponent, paddingValues: PaddingValues) {
|
||||||
@@ -73,7 +74,7 @@ fun SettingsContent(comp: SettingsComponent, paddingValues: PaddingValues) {
|
|||||||
modifier = Modifier.clickable { comp.showTags() }
|
modifier = Modifier.clickable { comp.showTags() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (comp.hasUpdateSupport) {
|
if (comp.updateComponent.hasSupport) {
|
||||||
item {
|
item {
|
||||||
TextPreference(
|
TextPreference(
|
||||||
text = stringResource(Res.string.check_for_updates),
|
text = stringResource(Res.string.check_for_updates),
|
||||||
@@ -115,6 +116,7 @@ fun SettingsContent(comp: SettingsComponent, paddingValues: PaddingValues) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
UpdateBottomSheet(comp.updateComponent)
|
||||||
LaunchedEffect(null) {
|
LaunchedEffect(null) {
|
||||||
withFrameNanos {}
|
withFrameNanos {}
|
||||||
requester.requestFocus()
|
requester.requestFocus()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.russhwolf.settings.Settings
|
|||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.callbackFlow
|
import kotlinx.coroutines.flow.callbackFlow
|
||||||
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.shadowsparky.domain.DispatcherProvider
|
import ru.shadowsparky.domain.DispatcherProvider
|
||||||
@@ -27,7 +28,7 @@ class SettingsKeyValueStorage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun get(key: String): Flow<String?> {
|
override fun get(key: String): Flow<String?> {
|
||||||
return impl.get(key)
|
return impl.get(key).flowOn(dispatcherProvider.io)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun remove(key: String) = withContext(dispatcherProvider.io) {
|
override suspend fun remove(key: String) = withContext(dispatcherProvider.io) {
|
||||||
|
|||||||
+10
-8
@@ -18,11 +18,11 @@ import androidx.compose.animation.AnimatedContent
|
|||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.LinearProgressIndicator
|
import androidx.compose.material3.LinearProgressIndicator
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@@ -38,6 +38,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||||
import org.jetbrains.compose.resources.stringResource
|
import org.jetbrains.compose.resources.stringResource
|
||||||
|
import ru.shadowsparky.ui.components.Loading
|
||||||
import ru.shadowsparky.updater.domain.UpdateState
|
import ru.shadowsparky.updater.domain.UpdateState
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@@ -54,11 +55,15 @@ fun UpdateBottomSheet(
|
|||||||
val isVisible = remember(state) { state !is UpdateState.Idle && state !is UpdateState.UpToDate }
|
val isVisible = remember(state) { state !is UpdateState.Idle && state !is UpdateState.UpToDate }
|
||||||
|
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
ModalBottomSheet(onDismissRequest = {}, sheetState = sheetState, modifier = modifier) {
|
ModalBottomSheet(
|
||||||
|
onDismissRequest = { component.reset() },
|
||||||
|
sheetState = sheetState,
|
||||||
|
modifier = modifier
|
||||||
|
) {
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = state,
|
targetState = state,
|
||||||
label = "UpdateStateAnimation",
|
label = "UpdateStateAnimation",
|
||||||
modifier = Modifier.fillMaxWidth().padding(start = 16.dp, end = 16.dp, bottom = 32.dp)
|
modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp)
|
||||||
) { currentState ->
|
) { currentState ->
|
||||||
when (currentState) {
|
when (currentState) {
|
||||||
is UpdateState.Checking -> UpdateCheckingContent()
|
is UpdateState.Checking -> UpdateCheckingContent()
|
||||||
@@ -90,11 +95,8 @@ fun UpdateBottomSheet(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun UpdateCheckingContent(modifier: Modifier = Modifier) {
|
private fun UpdateCheckingContent() {
|
||||||
Column(
|
Loading(Modifier.fillMaxSize())
|
||||||
modifier = modifier.fillMaxWidth(),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
|
||||||
) { CircularProgressIndicator() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
+4
@@ -65,6 +65,10 @@ class UpdateComponent(
|
|||||||
fun installApk(path: String) {
|
fun installApk(path: String) {
|
||||||
scope.launch { interactor.installApk(path) }
|
scope.launch { interactor.installApk(path) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
|
_state.value = UpdateState.Idle
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Factory
|
@Factory
|
||||||
|
|||||||
Reference in New Issue
Block a user