update configurations screen
This commit is contained in:
parent
4477180d2d
commit
db0f2b44c9
|
@ -10,6 +10,7 @@ import com.vanced.manager.core.installer.impl.VancedInstaller
|
||||||
import com.vanced.manager.repository.DataRepository
|
import com.vanced.manager.repository.DataRepository
|
||||||
import com.vanced.manager.repository.MainRepository
|
import com.vanced.manager.repository.MainRepository
|
||||||
import com.vanced.manager.repository.MirrorRepository
|
import com.vanced.manager.repository.MirrorRepository
|
||||||
|
import com.vanced.manager.ui.viewmodel.ConfigurationViewModel
|
||||||
import com.vanced.manager.ui.viewmodel.InstallViewModel
|
import com.vanced.manager.ui.viewmodel.InstallViewModel
|
||||||
import com.vanced.manager.ui.viewmodel.MainViewModel
|
import com.vanced.manager.ui.viewmodel.MainViewModel
|
||||||
import org.koin.android.ext.koin.androidApplication
|
import org.koin.android.ext.koin.androidApplication
|
||||||
|
@ -34,6 +35,11 @@ val viewModelModule = module {
|
||||||
microgInstaller: MicrogInstaller,
|
microgInstaller: MicrogInstaller,
|
||||||
) = InstallViewModel(vancedDownloader, musicDownloader, microgDownloader, vancedInstaller, musicInstaller, microgInstaller)
|
) = InstallViewModel(vancedDownloader, musicDownloader, microgDownloader, vancedInstaller, musicInstaller, microgInstaller)
|
||||||
|
|
||||||
|
fun provideConfigurationViewModel(): ConfigurationViewModel {
|
||||||
|
return ConfigurationViewModel()
|
||||||
|
}
|
||||||
|
|
||||||
viewModel { provideMainViewModel(get(), get(), androidApplication()) }
|
viewModel { provideMainViewModel(get(), get(), androidApplication()) }
|
||||||
viewModel { provideInstallViewModel(get(), get(), get(), get(), get(), get()) }
|
viewModel { provideInstallViewModel(get(), get(), get(), get(), get(), get()) }
|
||||||
|
viewModel { provideConfigurationViewModel() }
|
||||||
}
|
}
|
|
@ -1,29 +1,29 @@
|
||||||
package com.vanced.manager.domain.model
|
package com.vanced.manager.domain.model
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
sealed class InstallationOption(
|
sealed class InstallationOption : Parcelable {
|
||||||
@StringRes val itemTitleId: Int,
|
|
||||||
) : Parcelable {
|
abstract val titleId: Int
|
||||||
|
abstract val items: List<InstallationOptionItem>
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class MultiSelect(
|
data class MultiSelect(
|
||||||
@StringRes val titleId: Int,
|
override val titleId: Int,
|
||||||
val items: List<InstallationOptionItem>,
|
override val items: List<InstallationOptionItem>,
|
||||||
val getOption: () -> Set<String>,
|
val getOption: () -> Set<String>,
|
||||||
val addOption: (String) -> Unit,
|
val addOption: (String) -> Unit,
|
||||||
val removeOption: (String) -> Unit
|
val removeOption: (String) -> Unit
|
||||||
) : InstallationOption(titleId)
|
) : InstallationOption()
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class SingleSelect(
|
data class SingleSelect(
|
||||||
@StringRes val titleId: Int,
|
override val titleId: Int,
|
||||||
val items: List<InstallationOptionItem>,
|
override val items: List<InstallationOptionItem>,
|
||||||
val getOption: () -> String,
|
val getOption: () -> String,
|
||||||
val setOption: (String) -> Unit,
|
val setOption: (String) -> Unit,
|
||||||
) : InstallationOption(titleId)
|
) : InstallationOption()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ class MainActivity : ComponentActivity() {
|
||||||
onAppInstallPress = { appName, appVersions, installationOptions ->
|
onAppInstallPress = { appName, appVersions, installationOptions ->
|
||||||
if (installationOptions != null) {
|
if (installationOptions != null) {
|
||||||
backStack.push(
|
backStack.push(
|
||||||
Screen.InstallPreferences(
|
Screen.Configuration(
|
||||||
appName,
|
appName,
|
||||||
appVersions,
|
appVersions,
|
||||||
installationOptions
|
installationOptions
|
||||||
|
@ -118,13 +118,13 @@ class MainActivity : ComponentActivity() {
|
||||||
is Screen.Logs -> {
|
is Screen.Logs -> {
|
||||||
|
|
||||||
}
|
}
|
||||||
is Screen.InstallPreferences -> {
|
is Screen.Configuration -> {
|
||||||
InstallPreferencesScreen(
|
ConfigurationScreen(
|
||||||
installationOptions = screen.appInstallationOptions,
|
installationOptions = screen.appInstallationOptions,
|
||||||
onToolbarBackButtonClick = {
|
onToolbarBackButtonClick = {
|
||||||
backStack.pop()
|
backStack.pop()
|
||||||
},
|
},
|
||||||
onDoneClick = {
|
onFinishClick = {
|
||||||
backStack.push(
|
backStack.push(
|
||||||
Screen.Install(
|
Screen.Install(
|
||||||
screen.appName,
|
screen.appName,
|
||||||
|
|
|
@ -0,0 +1,259 @@
|
||||||
|
package com.vanced.manager.ui.screens
|
||||||
|
|
||||||
|
import androidx.compose.animation.*
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
|
import androidx.compose.material.ListItem
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.rounded.ArrowBackIosNew
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.vanced.manager.R
|
||||||
|
import com.vanced.manager.domain.model.InstallationOption
|
||||||
|
import com.vanced.manager.ui.component.card.ManagerTonalCard
|
||||||
|
import com.vanced.manager.ui.component.text.ManagerText
|
||||||
|
import com.vanced.manager.ui.component.topappbar.ManagerTopAppBar
|
||||||
|
import com.vanced.manager.ui.resources.managerString
|
||||||
|
import com.vanced.manager.ui.theme.LargeShape
|
||||||
|
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
||||||
|
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
||||||
|
import com.vanced.manager.ui.viewmodel.ConfigurationViewModel
|
||||||
|
import com.vanced.manager.ui.widget.layout.managerCategory
|
||||||
|
import org.koin.androidx.compose.getViewModel
|
||||||
|
|
||||||
|
@ExperimentalFoundationApi
|
||||||
|
@ExperimentalAnimationApi
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun ConfigurationScreen(
|
||||||
|
installationOptions: List<InstallationOption>,
|
||||||
|
onToolbarBackButtonClick: () -> Unit,
|
||||||
|
onFinishClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
val viewModel: ConfigurationViewModel = getViewModel()
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
ManagerTopAppBar(
|
||||||
|
title = managerString(R.string.toolbar_installation_preferences),
|
||||||
|
navigationIcon = {
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
onToolbarBackButtonClick()
|
||||||
|
viewModel.reset()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.ArrowBackIosNew,
|
||||||
|
contentDescription = "Back"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
bottomBar = {
|
||||||
|
ConfigurationButtons(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(
|
||||||
|
horizontal = DefaultContentPaddingHorizontal,
|
||||||
|
vertical = DefaultContentPaddingVertical
|
||||||
|
),
|
||||||
|
lastIndex = installationOptions.lastIndex,
|
||||||
|
currentIndex = viewModel.currentIndex,
|
||||||
|
onBackClick = {
|
||||||
|
viewModel.back()
|
||||||
|
},
|
||||||
|
onNextClick = {
|
||||||
|
viewModel.next()
|
||||||
|
},
|
||||||
|
onFinishClick = {
|
||||||
|
onFinishClick()
|
||||||
|
viewModel.reset()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
ConfigurationBody(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues),
|
||||||
|
currentIndex = viewModel.currentIndex,
|
||||||
|
installationOptions = installationOptions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalAnimationApi::class, ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
private fun ConfigurationBody(
|
||||||
|
currentIndex: Int,
|
||||||
|
installationOptions: List<InstallationOption>,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
AnimatedContent(
|
||||||
|
modifier = modifier,
|
||||||
|
targetState = currentIndex,
|
||||||
|
transitionSpec = {
|
||||||
|
slideAnimationSpec(
|
||||||
|
if (targetState > initialState) {
|
||||||
|
AnimatedContentScope.SlideDirection.Start
|
||||||
|
} else {
|
||||||
|
AnimatedContentScope.SlideDirection.End
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { optionIndex ->
|
||||||
|
val installationOption = installationOptions[optionIndex]
|
||||||
|
val categoryName = managerString(installationOption.titleId)
|
||||||
|
LazyColumn {
|
||||||
|
when (installationOption) {
|
||||||
|
is InstallationOption.SingleSelect -> {
|
||||||
|
managerCategory(
|
||||||
|
categoryName = categoryName,
|
||||||
|
items = installationOption.items
|
||||||
|
) { item ->
|
||||||
|
val preference = installationOption.getOption()
|
||||||
|
ConfigurationItem(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(),
|
||||||
|
text = item.displayText(item.key),
|
||||||
|
onClick = {
|
||||||
|
installationOption.setOption(item.key)
|
||||||
|
},
|
||||||
|
trailing = {
|
||||||
|
RadioButton(
|
||||||
|
selected = preference == item.key,
|
||||||
|
onClick = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is InstallationOption.MultiSelect -> {
|
||||||
|
managerCategory(
|
||||||
|
categoryName = categoryName,
|
||||||
|
items = installationOption.items
|
||||||
|
) { item ->
|
||||||
|
val preference = installationOption.getOption()
|
||||||
|
ConfigurationItem(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(),
|
||||||
|
text = item.displayText(item.key),
|
||||||
|
onClick = {
|
||||||
|
if (preference.contains(item.key)) {
|
||||||
|
installationOption.removeOption(item.key)
|
||||||
|
} else {
|
||||||
|
installationOption.addOption(item.key)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trailing = {
|
||||||
|
Checkbox(
|
||||||
|
checked = preference.contains(item.key),
|
||||||
|
onCheckedChange = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalAnimationApi::class)
|
||||||
|
@Composable
|
||||||
|
private fun ConfigurationButtons(
|
||||||
|
currentIndex: Int,
|
||||||
|
lastIndex: Int,
|
||||||
|
onBackClick: () -> Unit,
|
||||||
|
onNextClick: () -> Unit,
|
||||||
|
onFinishClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Row(modifier = modifier) {
|
||||||
|
AnimatedVisibility(
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentWidth(Alignment.Start)
|
||||||
|
.weight(1f),
|
||||||
|
visible = currentIndex > 0) {
|
||||||
|
TextButton(onClick = onBackClick) {
|
||||||
|
ManagerText(text = "Back")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AnimatedContent(
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentWidth(Alignment.End)
|
||||||
|
.weight(1f),
|
||||||
|
targetState = currentIndex == lastIndex,
|
||||||
|
transitionSpec = {
|
||||||
|
slideAnimationSpec(
|
||||||
|
if (initialState && !targetState) {
|
||||||
|
AnimatedContentScope.SlideDirection.Up
|
||||||
|
} else {
|
||||||
|
AnimatedContentScope.SlideDirection.Down
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { isLastIndex ->
|
||||||
|
if (isLastIndex) {
|
||||||
|
ElevatedButton(onClick = onFinishClick) {
|
||||||
|
ManagerText(text = "Finish")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
OutlinedButton(onClick = onNextClick) {
|
||||||
|
ManagerText(text = "Next")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
|
@Composable
|
||||||
|
private fun ConfigurationItem(
|
||||||
|
text: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
trailing: @Composable () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
ManagerTonalCard(
|
||||||
|
modifier = modifier
|
||||||
|
.padding(
|
||||||
|
start = 6.dp,
|
||||||
|
end = 6.dp,
|
||||||
|
bottom = 8.dp
|
||||||
|
),
|
||||||
|
shape = LargeShape,
|
||||||
|
onClick = onClick
|
||||||
|
) {
|
||||||
|
ListItem(
|
||||||
|
text = {
|
||||||
|
ManagerText(
|
||||||
|
text = text,
|
||||||
|
textStyle = MaterialTheme.typography.titleSmall
|
||||||
|
)
|
||||||
|
},
|
||||||
|
trailing = trailing,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalAnimationApi
|
||||||
|
private fun <S> AnimatedContentScope<S>.slideAnimationSpec(
|
||||||
|
slideDirection: AnimatedContentScope.SlideDirection
|
||||||
|
) = slideIntoContainer(
|
||||||
|
towards = slideDirection,
|
||||||
|
animationSpec = tween(400)
|
||||||
|
) + fadeIn(
|
||||||
|
animationSpec = tween(400)
|
||||||
|
) with slideOutOfContainer(
|
||||||
|
towards = slideDirection,
|
||||||
|
animationSpec = tween(400)
|
||||||
|
) + fadeOut(
|
||||||
|
animationSpec = tween(400)
|
||||||
|
)
|
|
@ -1,225 +0,0 @@
|
||||||
package com.vanced.manager.ui.screens
|
|
||||||
|
|
||||||
import androidx.compose.animation.*
|
|
||||||
import androidx.compose.animation.core.tween
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.rounded.ArrowBackIosNew
|
|
||||||
import androidx.compose.material.icons.rounded.Done
|
|
||||||
import androidx.compose.material.icons.rounded.NavigateBefore
|
|
||||||
import androidx.compose.material.icons.rounded.NavigateNext
|
|
||||||
import androidx.compose.material3.*
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.domain.model.InstallationOption
|
|
||||||
import com.vanced.manager.ui.component.card.ManagerTonalCard
|
|
||||||
import com.vanced.manager.ui.component.layout.ManagerLazyColumn
|
|
||||||
import com.vanced.manager.ui.component.layout.ManagerScaffold
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
import com.vanced.manager.ui.component.topappbar.ManagerTopAppBar
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
import com.vanced.manager.ui.theme.LargeShape
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
|
||||||
import com.vanced.manager.ui.widget.list.CheckboxItem
|
|
||||||
import com.vanced.manager.ui.widget.list.RadiobuttonItem
|
|
||||||
|
|
||||||
@ExperimentalFoundationApi
|
|
||||||
@ExperimentalAnimationApi
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun InstallPreferencesScreen(
|
|
||||||
installationOptions: List<InstallationOption>,
|
|
||||||
onToolbarBackButtonClick: () -> Unit,
|
|
||||||
onDoneClick: () -> Unit,
|
|
||||||
) {
|
|
||||||
var currentOptionIndex by rememberSaveable { mutableStateOf(0) }
|
|
||||||
|
|
||||||
ManagerScaffold(
|
|
||||||
topBar = {
|
|
||||||
ManagerTopAppBar(
|
|
||||||
title = managerString(R.string.toolbar_installation_preferences),
|
|
||||||
navigationIcon = {
|
|
||||||
IconButton(
|
|
||||||
onClick = onToolbarBackButtonClick
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.ArrowBackIosNew,
|
|
||||||
contentDescription = "Back"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
) { paddingValues ->
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(paddingValues),
|
|
||||||
) {
|
|
||||||
AnimatedContent(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(
|
|
||||||
horizontal = DefaultContentPaddingHorizontal,
|
|
||||||
vertical = DefaultContentPaddingVertical
|
|
||||||
)
|
|
||||||
.weight(1f),
|
|
||||||
targetState = currentOptionIndex,
|
|
||||||
transitionSpec = {
|
|
||||||
getSlideAnimationSpec(
|
|
||||||
if (targetState > initialState) {
|
|
||||||
AnimatedContentScope.SlideDirection.Start
|
|
||||||
} else {
|
|
||||||
AnimatedContentScope.SlideDirection.End
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { optionIndex ->
|
|
||||||
val installationOption = installationOptions[optionIndex]
|
|
||||||
ManagerTonalCard(
|
|
||||||
modifier = Modifier
|
|
||||||
.wrapContentHeight(
|
|
||||||
align = Alignment.Top
|
|
||||||
),
|
|
||||||
shape = LargeShape
|
|
||||||
) {
|
|
||||||
Column {
|
|
||||||
ManagerText(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(
|
|
||||||
horizontal = DefaultContentPaddingHorizontal,
|
|
||||||
vertical = DefaultContentPaddingVertical
|
|
||||||
),
|
|
||||||
text = managerString(installationOption.itemTitleId),
|
|
||||||
textStyle = MaterialTheme.typography.titleLarge,
|
|
||||||
)
|
|
||||||
ManagerLazyColumn(
|
|
||||||
contentPadding = PaddingValues(
|
|
||||||
start = 4.dp,
|
|
||||||
end = 4.dp,
|
|
||||||
bottom = DefaultContentPaddingVertical
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
when (installationOption) {
|
|
||||||
is InstallationOption.MultiSelect -> {
|
|
||||||
items(installationOption.items) { item ->
|
|
||||||
val preference = installationOption.getOption()
|
|
||||||
CheckboxItem(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = item.displayText(item.key),
|
|
||||||
checked = preference.contains(item.key),
|
|
||||||
onCheckedChange = {
|
|
||||||
if (it) {
|
|
||||||
installationOption.addOption(item.key)
|
|
||||||
} else {
|
|
||||||
installationOption.removeOption(item.key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is InstallationOption.SingleSelect -> {
|
|
||||||
items(installationOption.items) { item ->
|
|
||||||
val preference = installationOption.getOption()
|
|
||||||
RadiobuttonItem(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = item.displayText(item.key),
|
|
||||||
selected = preference == item.key,
|
|
||||||
onClick = {
|
|
||||||
installationOption.setOption(item.key)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(
|
|
||||||
horizontal = DefaultContentPaddingHorizontal,
|
|
||||||
vertical = DefaultContentPaddingVertical
|
|
||||||
),
|
|
||||||
) {
|
|
||||||
AnimatedVisibility(
|
|
||||||
visible = currentOptionIndex > 0
|
|
||||||
) {
|
|
||||||
FloatingActionButton(
|
|
||||||
onClick = {
|
|
||||||
currentOptionIndex--
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.NavigateBefore,
|
|
||||||
contentDescription = "Back"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
|
||||||
AnimatedContent(
|
|
||||||
targetState = currentOptionIndex == installationOptions.lastIndex,
|
|
||||||
transitionSpec = {
|
|
||||||
|
|
||||||
getSlideAnimationSpec(
|
|
||||||
if (initialState && !targetState) {
|
|
||||||
AnimatedContentScope.SlideDirection.Up
|
|
||||||
} else {
|
|
||||||
AnimatedContentScope.SlideDirection.Down
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { lastIndex ->
|
|
||||||
if (lastIndex) {
|
|
||||||
FloatingActionButton(
|
|
||||||
onClick = onDoneClick
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.Done,
|
|
||||||
contentDescription = "Done"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FloatingActionButton(
|
|
||||||
onClick = {
|
|
||||||
currentOptionIndex++
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.NavigateNext,
|
|
||||||
contentDescription = "Next"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExperimentalAnimationApi
|
|
||||||
private fun <S> AnimatedContentScope<S>.getSlideAnimationSpec(
|
|
||||||
slideDirection: AnimatedContentScope.SlideDirection
|
|
||||||
) = slideIntoContainer(
|
|
||||||
towards = slideDirection,
|
|
||||||
animationSpec = tween(400)
|
|
||||||
) + fadeIn(
|
|
||||||
animationSpec = tween(400)
|
|
||||||
) with slideOutOfContainer(
|
|
||||||
towards = slideDirection,
|
|
||||||
animationSpec = tween(400)
|
|
||||||
) + fadeOut(
|
|
||||||
animationSpec = tween(400)
|
|
||||||
)
|
|
|
@ -28,7 +28,7 @@ sealed class Screen(
|
||||||
displayName = R.string.toolbar_logs,
|
displayName = R.string.toolbar_logs,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class InstallPreferences(
|
data class Configuration(
|
||||||
val appName: String,
|
val appName: String,
|
||||||
val appVersions: List<String>?,
|
val appVersions: List<String>?,
|
||||||
val appInstallationOptions: List<InstallationOption>
|
val appInstallationOptions: List<InstallationOption>
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.vanced.manager.ui.viewmodel
|
||||||
|
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
|
||||||
|
class ConfigurationViewModel : ViewModel() {
|
||||||
|
|
||||||
|
var currentIndex by mutableStateOf(0)
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun next() {
|
||||||
|
currentIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
fun back() {
|
||||||
|
currentIndex--
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
|
currentIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package com.vanced.manager.ui.widget.list
|
package com.vanced.manager.ui.widget.list
|
||||||
|
|
||||||
import androidx.compose.material3.Checkbox
|
import androidx.compose.material3.Checkbox
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -9,6 +10,7 @@ import com.vanced.manager.ui.component.list.ManagerSelectableListItem
|
||||||
import com.vanced.manager.ui.component.modifier.managerClickable
|
import com.vanced.manager.ui.component.modifier.managerClickable
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
import com.vanced.manager.ui.component.text.ManagerText
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CheckboxItem(
|
fun CheckboxItem(
|
||||||
text: String,
|
text: String,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.vanced.manager.ui.widget.list
|
package com.vanced.manager.ui.widget.list
|
||||||
|
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.RadioButton
|
import androidx.compose.material3.RadioButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
@ -9,6 +10,7 @@ import com.vanced.manager.ui.component.list.ManagerSelectableListItem
|
||||||
import com.vanced.manager.ui.component.modifier.managerClickable
|
import com.vanced.manager.ui.component.modifier.managerClickable
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
import com.vanced.manager.ui.component.text.ManagerText
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun RadiobuttonItem(
|
fun RadiobuttonItem(
|
||||||
text: String,
|
text: String,
|
||||||
|
|
Loading…
Reference in New Issue