refactor ui components
This commit is contained in:
parent
5cf2cd1cbe
commit
9d73cae456
|
@ -1,3 +1,6 @@
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application")
|
id("com.android.application")
|
||||||
kotlin("android")
|
kotlin("android")
|
||||||
|
@ -57,13 +60,21 @@ android {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
|
||||||
|
tasks.withType<KotlinCompile>().configureEach {
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "11"
|
jvmTarget = "11"
|
||||||
freeCompilerArgs = freeCompilerArgs + "-Xopt-in=kotlin.RequiresOptIn"
|
optIn("androidx.compose.material3.ExperimentalMaterial3Api")
|
||||||
|
optIn("androidx.compose.animation.ExperimentalAnimationApi")
|
||||||
|
optIn("androidx.compose.foundation.ExperimentalFoundationApi")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun KotlinJvmOptions.optIn(library: String) {
|
||||||
|
freeCompilerArgs = freeCompilerArgs +
|
||||||
|
"-opt-in=$library"
|
||||||
|
}
|
||||||
|
|
||||||
val languages: String get() {
|
val languages: String get() {
|
||||||
val langs = arrayListOf("en", "bn_BD", "bn_IN", "pa_IN", "pa_PK", "pt_BR", "pt_PT", "zh_CN", "zh_TW")
|
val langs = arrayListOf("en", "bn_BD", "bn_IN", "pa_IN", "pa_PK", "pt_BR", "pt_PT", "zh_CN", "zh_TW")
|
||||||
val exceptions = arrayOf("bn", "pa", "pt", "zh")
|
val exceptions = arrayOf("bn", "pa", "pt", "zh")
|
||||||
|
|
|
@ -7,9 +7,7 @@ import android.content.IntentFilter
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.SideEffect
|
import androidx.compose.runtime.SideEffect
|
||||||
import com.github.zsoltk.compose.backpress.BackPressHandler
|
import com.github.zsoltk.compose.backpress.BackPressHandler
|
||||||
|
@ -18,11 +16,11 @@ import com.github.zsoltk.compose.router.Router
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.vanced.manager.core.installer.service.AppInstallService
|
import com.vanced.manager.core.installer.service.AppInstallService
|
||||||
import com.vanced.manager.core.installer.service.AppUninstallService
|
import com.vanced.manager.core.installer.service.AppUninstallService
|
||||||
import com.vanced.manager.ui.component.color.managerSurfaceColor
|
import com.vanced.manager.ui.screen.*
|
||||||
import com.vanced.manager.ui.screens.*
|
|
||||||
import com.vanced.manager.ui.theme.ManagerTheme
|
import com.vanced.manager.ui.theme.ManagerTheme
|
||||||
import com.vanced.manager.ui.theme.isDark
|
import com.vanced.manager.ui.theme.isDark
|
||||||
import com.vanced.manager.ui.util.Screen
|
import com.vanced.manager.ui.util.Screen
|
||||||
|
import com.vanced.manager.ui.util.animated
|
||||||
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.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
@ -52,17 +50,12 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(
|
|
||||||
ExperimentalAnimationApi::class,
|
|
||||||
ExperimentalMaterial3Api::class,
|
|
||||||
ExperimentalFoundationApi::class,
|
|
||||||
)
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
mainViewModel.fetch()
|
mainViewModel.fetch()
|
||||||
setContent {
|
setContent {
|
||||||
ManagerTheme {
|
ManagerTheme {
|
||||||
val surfaceColor = managerSurfaceColor()
|
val surfaceColor = MaterialTheme.colorScheme.surface.animated
|
||||||
|
|
||||||
val isDark = isDark()
|
val isDark = isDark()
|
||||||
|
|
||||||
|
@ -81,12 +74,12 @@ class MainActivity : ComponentActivity() {
|
||||||
Router<Screen>("VancedManager", Screen.Home) { backStack ->
|
Router<Screen>("VancedManager", Screen.Home) { backStack ->
|
||||||
when (val screen = backStack.last()) {
|
when (val screen = backStack.last()) {
|
||||||
is Screen.Home -> {
|
is Screen.Home -> {
|
||||||
HomeLayout(
|
HomeScreen(
|
||||||
viewModel = mainViewModel,
|
viewModel = mainViewModel,
|
||||||
onToolbarScreenSelected = {
|
onToolbarScreenSelected = {
|
||||||
backStack.push(it)
|
backStack.push(it)
|
||||||
},
|
},
|
||||||
onAppInstallPress = { appName, appVersions, installationOptions ->
|
onAppDownloadClick = { appName, appVersions, installationOptions ->
|
||||||
if (installationOptions != null) {
|
if (installationOptions != null) {
|
||||||
backStack.push(
|
backStack.push(
|
||||||
Screen.Configuration(
|
Screen.Configuration(
|
||||||
|
@ -98,18 +91,24 @@ class MainActivity : ComponentActivity() {
|
||||||
} else {
|
} else {
|
||||||
backStack.push(Screen.Install(appName, appVersions))
|
backStack.push(Screen.Install(appName, appVersions))
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onAppLaunchClick = { appName, packageName ->
|
||||||
|
mainViewModel.launchApp(appName, packageName)
|
||||||
|
},
|
||||||
|
onAppUninstallClick = { packageName ->
|
||||||
|
mainViewModel.uninstallApp(packageName)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is Screen.Settings -> {
|
is Screen.Settings -> {
|
||||||
SettingsLayout(
|
SettingsScreen(
|
||||||
onToolbarBackButtonClick = {
|
onToolbarBackButtonClick = {
|
||||||
backStack.pop()
|
backStack.pop()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is Screen.About -> {
|
is Screen.About -> {
|
||||||
AboutLayout(
|
AboutScreen(
|
||||||
onToolbarBackButtonClick = {
|
onToolbarBackButtonClick = {
|
||||||
backStack.pop()
|
backStack.pop()
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.RowScope
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Shape
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerButton(
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||||
|
elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),
|
||||||
|
shape: Shape = RoundedCornerShape(20.0.dp),
|
||||||
|
border: BorderStroke? = null,
|
||||||
|
colors: ButtonColors = ButtonDefaults.buttonColors(),
|
||||||
|
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
|
||||||
|
content: @Composable RowScope.() -> Unit
|
||||||
|
) {
|
||||||
|
Button(
|
||||||
|
onClick,
|
||||||
|
modifier,
|
||||||
|
enabled,
|
||||||
|
interactionSource,
|
||||||
|
elevation,
|
||||||
|
shape,
|
||||||
|
border,
|
||||||
|
colors,
|
||||||
|
contentPadding,
|
||||||
|
content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerElevatedButton(
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||||
|
elevation: ButtonElevation? = ButtonDefaults.elevatedButtonElevation(),
|
||||||
|
shape: Shape = RoundedCornerShape(20.0.dp),
|
||||||
|
border: BorderStroke? = null,
|
||||||
|
colors: ButtonColors = ButtonDefaults.elevatedButtonColors(),
|
||||||
|
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
|
||||||
|
content: @Composable RowScope.() -> Unit
|
||||||
|
) {
|
||||||
|
ElevatedButton(
|
||||||
|
onClick,
|
||||||
|
modifier,
|
||||||
|
enabled,
|
||||||
|
interactionSource,
|
||||||
|
elevation,
|
||||||
|
shape,
|
||||||
|
border,
|
||||||
|
colors,
|
||||||
|
contentPadding,
|
||||||
|
content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerFilledTonalButton(
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||||
|
elevation: ButtonElevation? = ButtonDefaults.filledTonalButtonElevation(),
|
||||||
|
shape: Shape = RoundedCornerShape(20.0.dp),
|
||||||
|
border: BorderStroke? = null,
|
||||||
|
colors: ButtonColors = ButtonDefaults.filledTonalButtonColors(),
|
||||||
|
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
|
||||||
|
content: @Composable RowScope.() -> Unit
|
||||||
|
) {
|
||||||
|
FilledTonalButton(
|
||||||
|
onClick,
|
||||||
|
modifier,
|
||||||
|
enabled,
|
||||||
|
interactionSource,
|
||||||
|
elevation,
|
||||||
|
shape,
|
||||||
|
border,
|
||||||
|
colors,
|
||||||
|
contentPadding,
|
||||||
|
content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerOutlinedButton(
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||||
|
elevation: ButtonElevation? = null,
|
||||||
|
shape: Shape = RoundedCornerShape(20.0.dp),
|
||||||
|
border: BorderStroke? = ButtonDefaults.outlinedButtonBorder,
|
||||||
|
colors: ButtonColors = ButtonDefaults.outlinedButtonColors(),
|
||||||
|
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
|
||||||
|
content: @Composable RowScope.() -> Unit
|
||||||
|
) {
|
||||||
|
Button(
|
||||||
|
onClick,
|
||||||
|
modifier,
|
||||||
|
enabled,
|
||||||
|
interactionSource,
|
||||||
|
elevation,
|
||||||
|
shape,
|
||||||
|
border,
|
||||||
|
colors,
|
||||||
|
contentPadding,
|
||||||
|
content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerTextButton(
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||||
|
elevation: ButtonElevation? = null,
|
||||||
|
shape: Shape = RoundedCornerShape(20.0.dp),
|
||||||
|
border: BorderStroke? = null,
|
||||||
|
colors: ButtonColors = ButtonDefaults.textButtonColors(),
|
||||||
|
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
|
||||||
|
content: @Composable RowScope.() -> Unit
|
||||||
|
) {
|
||||||
|
TextButton(
|
||||||
|
onClick,
|
||||||
|
modifier,
|
||||||
|
enabled,
|
||||||
|
interactionSource,
|
||||||
|
elevation,
|
||||||
|
shape,
|
||||||
|
border,
|
||||||
|
colors,
|
||||||
|
contentPadding,
|
||||||
|
content
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.Shape
|
||||||
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
import com.vanced.manager.ui.util.animated
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerCard(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
onClick: (() -> Unit)? = null,
|
||||||
|
shape: Shape = MediumShape,
|
||||||
|
containerColor: Color = MaterialTheme.colorScheme.surface,
|
||||||
|
contentColor: Color = contentColorFor(containerColor),
|
||||||
|
elevation: CardElevation = CardDefaults.cardElevation(),
|
||||||
|
content: @Composable ColumnScope.() -> Unit,
|
||||||
|
) {
|
||||||
|
if (onClick != null) {
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
Card(
|
||||||
|
modifier = modifier
|
||||||
|
.clickable(
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
indication = null,
|
||||||
|
onClick = onClick
|
||||||
|
),
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
shape = shape,
|
||||||
|
containerColor = containerColor.animated,
|
||||||
|
contentColor = contentColor.animated,
|
||||||
|
elevation = elevation,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Card(
|
||||||
|
modifier = modifier,
|
||||||
|
shape = shape,
|
||||||
|
containerColor = containerColor.animated,
|
||||||
|
contentColor = contentColor.animated,
|
||||||
|
elevation = elevation,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Composable
|
||||||
|
fun ManagerElevatedCard(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
onClick: (() -> Unit)? = null,
|
||||||
|
shape: Shape = MediumShape,
|
||||||
|
containerColor: Color = MaterialTheme.colorScheme.surface,
|
||||||
|
contentColor: Color = contentColorFor(containerColor),
|
||||||
|
elevation: CardElevation = CardDefaults.elevatedCardElevation(),
|
||||||
|
content: @Composable ColumnScope.() -> Unit,
|
||||||
|
) {
|
||||||
|
if (onClick != null) {
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
ElevatedCard(
|
||||||
|
modifier = modifier
|
||||||
|
.clickable(
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
indication = null,
|
||||||
|
onClick = onClick
|
||||||
|
),
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
shape = shape,
|
||||||
|
containerColor = containerColor.animated,
|
||||||
|
contentColor = contentColor.animated,
|
||||||
|
elevation = elevation,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ElevatedCard(
|
||||||
|
modifier = modifier,
|
||||||
|
shape = shape,
|
||||||
|
containerColor = containerColor.animated,
|
||||||
|
contentColor = contentColor.animated,
|
||||||
|
elevation = elevation,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Composable
|
||||||
|
fun ManagerOutlinedCard(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
onClick: (() -> Unit)? = null,
|
||||||
|
shape: Shape = MediumShape,
|
||||||
|
containerColor: Color = MaterialTheme.colorScheme.surface,
|
||||||
|
contentColor: Color = contentColorFor(containerColor),
|
||||||
|
elevation: CardElevation = CardDefaults.outlinedCardElevation(),
|
||||||
|
content: @Composable ColumnScope.() -> Unit,
|
||||||
|
) {
|
||||||
|
if (onClick != null) {
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
OutlinedCard(
|
||||||
|
modifier = modifier
|
||||||
|
.clickable(
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
indication = null,
|
||||||
|
onClick = onClick
|
||||||
|
),
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
shape = shape,
|
||||||
|
containerColor = containerColor.animated,
|
||||||
|
contentColor = contentColor.animated,
|
||||||
|
elevation = elevation,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
OutlinedCard(
|
||||||
|
modifier = modifier,
|
||||||
|
shape = shape,
|
||||||
|
containerColor = containerColor.animated,
|
||||||
|
contentColor = contentColor.animated,
|
||||||
|
elevation = elevation,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,10 @@
|
||||||
package com.vanced.manager.ui.component.dialog
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
import com.vanced.manager.ui.theme.LargeShape
|
import com.vanced.manager.ui.theme.LargeShape
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -23,7 +21,6 @@ fun ManagerDialog(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
title = {
|
title = {
|
||||||
ManagerText(
|
ManagerText(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = title,
|
text = title,
|
||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
)
|
)
|
|
@ -1,4 +1,4 @@
|
||||||
package com.vanced.manager.ui.component.menu
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
import androidx.compose.animation.core.MutableTransitionState
|
import androidx.compose.animation.core.MutableTransitionState
|
||||||
|
@ -9,24 +9,26 @@ import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.IntrinsicSize
|
import androidx.compose.foundation.layout.IntrinsicSize
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.CardDefaults
|
||||||
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
|
import androidx.compose.material3.OutlinedCard
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.draw.scale
|
import androidx.compose.ui.draw.scale
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.unit.*
|
import androidx.compose.ui.unit.*
|
||||||
import androidx.compose.ui.window.Popup
|
import androidx.compose.ui.window.Popup
|
||||||
import androidx.compose.ui.window.PopupPositionProvider
|
import androidx.compose.ui.window.PopupPositionProvider
|
||||||
import androidx.compose.ui.window.PopupProperties
|
import androidx.compose.ui.window.PopupProperties
|
||||||
import com.vanced.manager.ui.component.card.ManagerCard
|
import com.vanced.manager.ui.theme.SmallShape
|
||||||
|
|
||||||
private const val TransitionDuration = 200
|
private const val TransitionDuration = 200
|
||||||
|
|
||||||
@ExperimentalAnimationApi
|
@ExperimentalAnimationApi
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerDropdownMenu(
|
fun ManagerDropdownMenu(
|
||||||
expanded: Boolean,
|
expanded: Boolean,
|
||||||
|
@ -47,21 +49,19 @@ fun ManagerDropdownMenu(
|
||||||
|
|
||||||
if (expandedStates.currentState || expandedStates.targetState) {
|
if (expandedStates.currentState || expandedStates.targetState) {
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
val popupPositionProvider =
|
val popupPositionProvider = ManagerDropdownMenuPopupPositionProvider(density)
|
||||||
ManagerDropdownMenuPopupPositionProvider(density)
|
|
||||||
|
|
||||||
Popup(
|
Popup(
|
||||||
popupPositionProvider = popupPositionProvider,
|
popupPositionProvider = popupPositionProvider,
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
properties = PopupProperties(focusable = true)
|
properties = PopupProperties(focusable = true)
|
||||||
) {
|
) {
|
||||||
ManagerCard(
|
OutlinedCard(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(IntrinsicSize.Max)
|
.width(IntrinsicSize.Max)
|
||||||
.alpha(alphaAndScale)
|
.alpha(alphaAndScale)
|
||||||
.scale(alphaAndScale),
|
.scale(alphaAndScale),
|
||||||
tonalElevation = 2.dp,
|
elevation = CardDefaults.elevatedCardElevation()
|
||||||
shadowElevation = 2.dp
|
|
||||||
) {
|
) {
|
||||||
Column(content = content)
|
Column(content = content)
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,22 @@ fun ManagerDropdownMenu(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerDropdownMenuItem(
|
||||||
|
title: String,
|
||||||
|
onClick: () -> Unit
|
||||||
|
) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
onClick = onClick,
|
||||||
|
modifier = Modifier.clip(SmallShape),
|
||||||
|
text = {
|
||||||
|
ManagerText(text = title)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
//Kanged from Menu.kt
|
//Kanged from Menu.kt
|
||||||
data class ManagerDropdownMenuPopupPositionProvider(
|
private data class ManagerDropdownMenuPopupPositionProvider(
|
||||||
val density: Density
|
val density: Density
|
||||||
) : PopupPositionProvider {
|
) : PopupPositionProvider {
|
||||||
|
|
||||||
|
@ -101,8 +115,7 @@ data class ManagerDropdownMenuPopupPositionProvider(
|
||||||
val toCenter = anchorBounds.top - popupContentSize.height / 2
|
val toCenter = anchorBounds.top - popupContentSize.height / 2
|
||||||
val toDisplayBottom = windowSize.height - popupContentSize.height - verticalMargin
|
val toDisplayBottom = windowSize.height - popupContentSize.height - verticalMargin
|
||||||
val y = sequenceOf(toBottom, toTop, toCenter, toDisplayBottom).firstOrNull {
|
val y = sequenceOf(toBottom, toTop, toCenter, toDisplayBottom).firstOrNull {
|
||||||
it >= verticalMargin &&
|
it >= verticalMargin && it + popupContentSize.height <= windowSize.height - verticalMargin
|
||||||
it + popupContentSize.height <= windowSize.height - verticalMargin
|
|
||||||
} ?: toTop
|
} ?: toTop
|
||||||
|
|
||||||
return IntOffset(x, y)
|
return IntOffset(x, y)
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.gestures.FlingBehavior
|
||||||
|
import androidx.compose.foundation.gestures.ScrollableDefaults
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.LazyListScope
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
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.ui.util.EdgeToEdgeContentPadding
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerLazyColumn(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
state: LazyListState = rememberLazyListState(),
|
||||||
|
contentPadding: PaddingValues = PaddingValues(
|
||||||
|
start = EdgeToEdgeContentPadding,
|
||||||
|
end = EdgeToEdgeContentPadding,
|
||||||
|
bottom = 8.dp
|
||||||
|
),
|
||||||
|
reverseLayout: Boolean = false,
|
||||||
|
verticalArrangement: Arrangement.Vertical =
|
||||||
|
Arrangement.spacedBy(8.dp, if (!reverseLayout) Alignment.Top else Alignment.Bottom),
|
||||||
|
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
|
||||||
|
flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
|
||||||
|
content: LazyListScope.() -> Unit
|
||||||
|
) {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = modifier,
|
||||||
|
state = state,
|
||||||
|
contentPadding = contentPadding,
|
||||||
|
reverseLayout = reverseLayout,
|
||||||
|
verticalArrangement = verticalArrangement,
|
||||||
|
horizontalAlignment = horizontalAlignment,
|
||||||
|
flingBehavior = flingBehavior,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun LazyListScope.managerCategory(
|
||||||
|
noinline categoryName: @Composable () -> String,
|
||||||
|
content: LazyListScope.() -> Unit,
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
ManagerText(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(
|
||||||
|
start = 8.dp,
|
||||||
|
top = 4.dp
|
||||||
|
),
|
||||||
|
text = categoryName(),
|
||||||
|
textStyle = MaterialTheme.typography.headlineSmall,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
content()
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.gestures.FlingBehavior
|
||||||
|
import androidx.compose.foundation.gestures.ScrollableDefaults
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.lazy.LazyListScope
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
|
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.ui.util.EdgeToEdgeContentPadding
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerLazyRow(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
state: LazyListState = rememberLazyListState(),
|
||||||
|
contentPadding: PaddingValues = PaddingValues(
|
||||||
|
start = EdgeToEdgeContentPadding,
|
||||||
|
end = EdgeToEdgeContentPadding,
|
||||||
|
),
|
||||||
|
reverseLayout: Boolean = false,
|
||||||
|
horizontalArrangement: Arrangement.Horizontal =
|
||||||
|
Arrangement.spacedBy(8.dp, if (!reverseLayout) Alignment.Start else Alignment.End),
|
||||||
|
verticalAlignment: Alignment.Vertical = Alignment.Top,
|
||||||
|
flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
|
||||||
|
content: LazyListScope.() -> Unit
|
||||||
|
) {
|
||||||
|
LazyRow(
|
||||||
|
modifier = modifier,
|
||||||
|
state = state,
|
||||||
|
contentPadding = contentPadding,
|
||||||
|
reverseLayout = reverseLayout,
|
||||||
|
horizontalArrangement = horizontalArrangement,
|
||||||
|
verticalAlignment = verticalAlignment,
|
||||||
|
flingBehavior = flingBehavior,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,13 +1,17 @@
|
||||||
package com.vanced.manager.ui.component.list
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.ContentAlpha
|
import androidx.compose.material.ContentAlpha
|
||||||
import androidx.compose.material.LocalContentAlpha
|
import androidx.compose.material.LocalContentAlpha
|
||||||
|
import androidx.compose.material3.LocalTextStyle
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
||||||
|
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerListItem(
|
fun ManagerListItem(
|
||||||
|
@ -17,7 +21,10 @@ fun ManagerListItem(
|
||||||
icon: @Composable (() -> Unit)? = null,
|
icon: @Composable (() -> Unit)? = null,
|
||||||
trailing: @Composable (() -> Unit)? = null
|
trailing: @Composable (() -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
Row(modifier = modifier) {
|
Row(
|
||||||
|
modifier = modifier,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(DefaultContentPaddingHorizontal)
|
||||||
|
) {
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.align(Alignment.CenterVertically)
|
modifier = Modifier.align(Alignment.CenterVertically)
|
||||||
|
@ -29,25 +36,28 @@ fun ManagerListItem(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.padding(
|
.padding(
|
||||||
start = if (icon != null) 12.dp else 0.dp,
|
vertical =
|
||||||
top = if (description != null) 6.dp else 12.dp,
|
if (description != null) DefaultContentPaddingVertical - 4.dp else DefaultContentPaddingVertical,
|
||||||
bottom = if (description != null) 6.dp else 12.dp,
|
|
||||||
end = if (trailing != null) 12.dp else 0.dp,
|
|
||||||
)
|
)
|
||||||
.align(Alignment.CenterVertically)
|
.align(Alignment.CenterVertically)
|
||||||
) {
|
) {
|
||||||
title()
|
CompositionLocalProvider(
|
||||||
|
LocalTextStyle provides MaterialTheme.typography.titleSmall
|
||||||
|
) {
|
||||||
|
title()
|
||||||
|
}
|
||||||
if (description != null) {
|
if (description != null) {
|
||||||
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
|
CompositionLocalProvider(
|
||||||
|
LocalContentAlpha provides ContentAlpha.medium,
|
||||||
|
LocalTextStyle provides MaterialTheme.typography.bodySmall
|
||||||
|
) {
|
||||||
description()
|
description()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (trailing != null) {
|
if (trailing != null) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier.align(Alignment.CenterVertically),
|
||||||
.size(48.dp)
|
|
||||||
.align(Alignment.CenterVertically),
|
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
trailing()
|
trailing()
|
|
@ -2,17 +2,54 @@ package com.vanced.manager.ui.navigation
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.animation.AnimatedContent
|
||||||
import androidx.compose.animation.AnimatedContentScope
|
import androidx.compose.animation.AnimatedContentScope
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
|
||||||
import androidx.compose.animation.with
|
import androidx.compose.animation.with
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
||||||
|
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||||
import com.vanced.manager.ui.util.Screen
|
import com.vanced.manager.ui.util.Screen
|
||||||
|
|
||||||
@OptIn(ExperimentalAnimationApi::class)
|
@Composable
|
||||||
|
fun <T> rememberManagerNavigationController(
|
||||||
|
initialScreen: T
|
||||||
|
) = remember {
|
||||||
|
ManagerNavigationControllerImpl(initialScreen)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ManagerNavigationController<T> {
|
||||||
|
|
||||||
|
val screens: SnapshotStateList<T>
|
||||||
|
|
||||||
|
fun push(item: T)
|
||||||
|
|
||||||
|
fun pop(): Boolean
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ManagerNavigationControllerImpl<T>(
|
||||||
|
initialScreen: T
|
||||||
|
) : ManagerNavigationController<T> {
|
||||||
|
|
||||||
|
override val screens: SnapshotStateList<T> =
|
||||||
|
mutableStateListOf(initialScreen)
|
||||||
|
|
||||||
|
override fun push(item: T) {
|
||||||
|
screens.add(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pop(): Boolean {
|
||||||
|
if (screens.size > 1) {
|
||||||
|
screens.removeLast()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun <T : Screen> ManagerNavigator(
|
fun <T : Screen> ManagerNavigator(
|
||||||
navigationController: NavigationController<T>,
|
navigationController: ManagerNavigationController<T>,
|
||||||
content: @Composable (targetContent: T) -> Unit
|
content: @Composable (targetContent: T) -> Unit
|
||||||
) {
|
) {
|
||||||
val saveableStateHolder = rememberSaveableStateHolder()
|
val saveableStateHolder = rememberSaveableStateHolder()
|
|
@ -0,0 +1,263 @@
|
||||||
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.Checkbox
|
||||||
|
import androidx.compose.material.Switch
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.RadioButton
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.vanced.manager.R
|
||||||
|
import com.vanced.manager.core.preferences.RadioButtonPreference
|
||||||
|
import com.vanced.manager.ui.resource.managerString
|
||||||
|
import com.vanced.manager.ui.theme.LargeShape
|
||||||
|
import com.vanced.manager.ui.theme.SmallShape
|
||||||
|
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerPreference(
|
||||||
|
preferenceTitle: String,
|
||||||
|
preferenceDescription: String? = null,
|
||||||
|
trailing: @Composable () -> Unit = {},
|
||||||
|
onClick: () -> Unit
|
||||||
|
) {
|
||||||
|
ManagerElevatedCard(
|
||||||
|
shape = LargeShape,
|
||||||
|
onClick = onClick
|
||||||
|
) {
|
||||||
|
ManagerListItem(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = DefaultContentPaddingHorizontal),
|
||||||
|
title = {
|
||||||
|
ManagerText(text = preferenceTitle)
|
||||||
|
},
|
||||||
|
description = if (preferenceDescription != null) {
|
||||||
|
{
|
||||||
|
ManagerText(text = preferenceDescription)
|
||||||
|
}
|
||||||
|
} else null,
|
||||||
|
trailing = trailing,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerSwitchPreference(
|
||||||
|
preferenceTitle: String,
|
||||||
|
preferenceDescription: String? = null,
|
||||||
|
isChecked: Boolean,
|
||||||
|
onCheckedChange: (isChecked: Boolean) -> Unit
|
||||||
|
) {
|
||||||
|
ManagerPreference(
|
||||||
|
preferenceTitle = preferenceTitle,
|
||||||
|
preferenceDescription = preferenceDescription,
|
||||||
|
onClick = {
|
||||||
|
onCheckedChange(!isChecked)
|
||||||
|
},
|
||||||
|
trailing = {
|
||||||
|
Switch(
|
||||||
|
checked = isChecked,
|
||||||
|
onCheckedChange = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerDialogPreference(
|
||||||
|
preferenceTitle: String,
|
||||||
|
preferenceDescription: String? = null,
|
||||||
|
trailing: @Composable () -> Unit = {},
|
||||||
|
onPreferenceClick: () -> Unit,
|
||||||
|
isDialogVisible: Boolean,
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
confirmButton: @Composable () -> Unit,
|
||||||
|
dismissButton: @Composable () -> Unit = {},
|
||||||
|
content: @Composable () -> Unit
|
||||||
|
) {
|
||||||
|
ManagerPreference(
|
||||||
|
preferenceTitle = preferenceTitle,
|
||||||
|
preferenceDescription = preferenceDescription,
|
||||||
|
trailing = trailing,
|
||||||
|
onClick = onPreferenceClick
|
||||||
|
)
|
||||||
|
if (isDialogVisible) {
|
||||||
|
ManagerDialog(
|
||||||
|
title = preferenceTitle,
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
confirmButton = confirmButton,
|
||||||
|
dismissButton = dismissButton,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerSingleSelectDialogPreference(
|
||||||
|
preferenceTitle: String,
|
||||||
|
preferenceDescription: String,
|
||||||
|
isDialogVisible: Boolean,
|
||||||
|
currentSelectedKey: String,
|
||||||
|
buttons: List<RadioButtonPreference>,
|
||||||
|
trailing: @Composable () -> Unit = {},
|
||||||
|
onPreferenceClick: () -> Unit,
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
onItemClick: (itemKey: String) -> Unit,
|
||||||
|
onSave: () -> Unit,
|
||||||
|
) {
|
||||||
|
ManagerDialogPreference(
|
||||||
|
preferenceTitle = preferenceTitle,
|
||||||
|
preferenceDescription = preferenceDescription,
|
||||||
|
trailing = trailing,
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(onClick = onSave) {
|
||||||
|
ManagerText(managerString(R.string.dialog_button_save))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton(onClick = onDismissRequest) {
|
||||||
|
ManagerText(managerString(R.string.dialog_button_cancel))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
isDialogVisible = isDialogVisible,
|
||||||
|
onPreferenceClick = onPreferenceClick
|
||||||
|
) {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.heightIn(max = 400.dp)
|
||||||
|
) {
|
||||||
|
items(buttons) { button ->
|
||||||
|
val (title, key) = button
|
||||||
|
ListDialogRadiobuttonItem(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
text = title,
|
||||||
|
selected = currentSelectedKey == key,
|
||||||
|
onClick = {
|
||||||
|
onItemClick(key)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerMultiSelectDialogPreference(
|
||||||
|
preferenceTitle: String,
|
||||||
|
preferenceDescription: String,
|
||||||
|
isDialogVisible: Boolean,
|
||||||
|
currentSelectedKeys: List<String>,
|
||||||
|
buttons: List<RadioButtonPreference>,
|
||||||
|
trailing: @Composable () -> Unit = {},
|
||||||
|
onPreferenceClick: () -> Unit,
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
onItemCheckChange: (isChecked: Boolean, itemKey: String) -> Unit,
|
||||||
|
onSave: () -> Unit,
|
||||||
|
) {
|
||||||
|
ManagerDialogPreference(
|
||||||
|
preferenceTitle = preferenceTitle,
|
||||||
|
preferenceDescription = preferenceDescription,
|
||||||
|
trailing = trailing,
|
||||||
|
confirmButton = {
|
||||||
|
androidx.compose.material.TextButton(onClick = onSave) {
|
||||||
|
ManagerText(managerString(R.string.dialog_button_save))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
androidx.compose.material.TextButton(onClick = onDismissRequest) {
|
||||||
|
ManagerText(managerString(R.string.dialog_button_cancel))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
isDialogVisible = isDialogVisible,
|
||||||
|
onPreferenceClick = onPreferenceClick
|
||||||
|
) {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.heightIn(max = 400.dp)
|
||||||
|
) {
|
||||||
|
items(buttons) { button ->
|
||||||
|
val (title, key) = button
|
||||||
|
ListDialogCheckboxItem(
|
||||||
|
text = title,
|
||||||
|
checked = currentSelectedKeys.contains(key),
|
||||||
|
onCheckedChange = { isChecked ->
|
||||||
|
onItemCheckChange(isChecked, key)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ListDialogRadiobuttonItem(
|
||||||
|
text: String,
|
||||||
|
selected: Boolean,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
ListDialogItem(
|
||||||
|
modifier = modifier,
|
||||||
|
text = text,
|
||||||
|
onClick = onClick,
|
||||||
|
trailing = {
|
||||||
|
RadioButton(
|
||||||
|
selected = selected,
|
||||||
|
onClick = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ListDialogCheckboxItem(
|
||||||
|
text: String,
|
||||||
|
checked: Boolean,
|
||||||
|
onCheckedChange: (Boolean) -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
ListDialogItem(
|
||||||
|
modifier = modifier,
|
||||||
|
text = text,
|
||||||
|
onClick = {
|
||||||
|
onCheckedChange(!checked)
|
||||||
|
},
|
||||||
|
trailing = {
|
||||||
|
Checkbox(
|
||||||
|
checked = checked,
|
||||||
|
onCheckedChange = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ListDialogItem(
|
||||||
|
text: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
trailing: @Composable () -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = modifier
|
||||||
|
.clip(SmallShape)
|
||||||
|
.clickable(onClick = onClick)
|
||||||
|
.padding(8.dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
ManagerText(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
text = text,
|
||||||
|
textStyle = MaterialTheme.typography.titleSmall
|
||||||
|
)
|
||||||
|
trailing()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
|
import androidx.compose.material.ProgressIndicatorDefaults
|
||||||
|
import androidx.compose.material3.LinearProgressIndicator
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import com.vanced.manager.ui.util.animated
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerProgressIndicator(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
color: Color = MaterialTheme.colorScheme.primary,
|
||||||
|
trackColor: Color = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
) {
|
||||||
|
LinearProgressIndicator(
|
||||||
|
modifier = modifier,
|
||||||
|
color = color.animated,
|
||||||
|
trackColor = trackColor.animated
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerProgressIndicator(
|
||||||
|
progress: Float,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
color: Color = MaterialTheme.colorScheme.primary,
|
||||||
|
trackColor: Color = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
) {
|
||||||
|
val animatedProgress by animateFloatAsState(
|
||||||
|
targetValue = progress,
|
||||||
|
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
|
||||||
|
)
|
||||||
|
LinearProgressIndicator(
|
||||||
|
progress = animatedProgress,
|
||||||
|
modifier = modifier,
|
||||||
|
color = color.animated,
|
||||||
|
trackColor = trackColor.animated
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,17 +1,25 @@
|
||||||
package com.vanced.manager.ui.component.layout
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.FabPosition
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.contentColorFor
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import com.vanced.manager.ui.util.animated
|
||||||
|
|
||||||
@ExperimentalMaterial3Api
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerScaffold(
|
fun ManagerScaffold(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
topBar: @Composable () -> Unit = {},
|
topBar: @Composable () -> Unit = {},
|
||||||
|
bottomBar: @Composable () -> Unit = {},
|
||||||
|
snackbarHost: @Composable () -> Unit = {},
|
||||||
floatingActionButton: @Composable () -> Unit = {},
|
floatingActionButton: @Composable () -> Unit = {},
|
||||||
floatingActionButtonPosition: FabPosition = FabPosition.End,
|
floatingActionButtonPosition: FabPosition = FabPosition.End,
|
||||||
|
containerColor: Color = MaterialTheme.colorScheme.background,
|
||||||
|
contentColor: Color = contentColorFor(containerColor),
|
||||||
content: @Composable (PaddingValues) -> Unit
|
content: @Composable (PaddingValues) -> Unit
|
||||||
) {
|
) {
|
||||||
// //M3 Scaffold doesn't support tonal elevation for Surface
|
// //M3 Scaffold doesn't support tonal elevation for Surface
|
||||||
|
@ -22,8 +30,12 @@ fun ManagerScaffold(
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
topBar = topBar,
|
topBar = topBar,
|
||||||
|
bottomBar = bottomBar,
|
||||||
|
snackbarHost = snackbarHost,
|
||||||
floatingActionButton = floatingActionButton,
|
floatingActionButton = floatingActionButton,
|
||||||
floatingActionButtonPosition = floatingActionButtonPosition,
|
floatingActionButtonPosition = floatingActionButtonPosition,
|
||||||
|
containerColor = containerColor.animated,
|
||||||
|
contentColor = contentColor.animated,
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
// }
|
// }
|
|
@ -1,4 +1,4 @@
|
||||||
package com.vanced.manager.ui.component.list
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
|
@ -1,22 +1,31 @@
|
||||||
package com.vanced.manager.ui.component.layout
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import com.google.accompanist.swiperefresh.SwipeRefresh
|
import com.google.accompanist.swiperefresh.SwipeRefresh
|
||||||
import com.google.accompanist.swiperefresh.SwipeRefreshIndicator
|
import com.google.accompanist.swiperefresh.SwipeRefreshIndicator
|
||||||
import com.google.accompanist.swiperefresh.SwipeRefreshState
|
import com.google.accompanist.swiperefresh.SwipeRefreshState
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerSwipeRefresh(
|
fun ManagerSwipeRefresh(
|
||||||
refreshState: SwipeRefreshState,
|
swipeRefreshState: SwipeRefreshState,
|
||||||
onRefresh: () -> Unit,
|
onRefresh: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
content: @Composable () -> Unit
|
swipeEnabled: Boolean = true,
|
||||||
|
refreshTriggerDistance: Dp = 80.dp,
|
||||||
|
indicatorAlignment: Alignment = Alignment.TopCenter,
|
||||||
|
indicatorPadding: PaddingValues = PaddingValues(0.dp),
|
||||||
|
clipIndicatorToPadding: Boolean = true,
|
||||||
|
content: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
SwipeRefresh(
|
SwipeRefresh(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
state = refreshState,
|
state = swipeRefreshState,
|
||||||
onRefresh = onRefresh,
|
onRefresh = onRefresh,
|
||||||
indicator = { state, trigger ->
|
indicator = { state, trigger ->
|
||||||
SwipeRefreshIndicator(
|
SwipeRefreshIndicator(
|
||||||
|
@ -27,6 +36,11 @@ fun ManagerSwipeRefresh(
|
||||||
backgroundColor = MaterialTheme.colorScheme.surface
|
backgroundColor = MaterialTheme.colorScheme.surface
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
swipeEnabled = swipeEnabled,
|
||||||
|
refreshTriggerDistance = refreshTriggerDistance,
|
||||||
|
indicatorAlignment = indicatorAlignment,
|
||||||
|
indicatorPadding = indicatorPadding,
|
||||||
|
clipIndicatorToPadding = clipIndicatorToPadding,
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.vanced.manager.ui.component.text
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.vanced.manager.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.RowScope
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerSmallTopAppBar(
|
||||||
|
title: @Composable () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
navigationIcon: @Composable () -> Unit = {},
|
||||||
|
actions: @Composable RowScope.() -> Unit = {},
|
||||||
|
colors: TopAppBarColors = TopAppBarDefaults.smallTopAppBarColors(),
|
||||||
|
scrollBehavior: TopAppBarScrollBehavior? = null
|
||||||
|
) {
|
||||||
|
SmallTopAppBar(
|
||||||
|
modifier = modifier,
|
||||||
|
title = title,
|
||||||
|
actions = actions,
|
||||||
|
navigationIcon = navigationIcon,
|
||||||
|
colors = colors,
|
||||||
|
scrollBehavior = scrollBehavior
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ManagerCenterAlignedTopAppBar(
|
||||||
|
title: @Composable () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
navigationIcon: @Composable () -> Unit = {},
|
||||||
|
actions: @Composable RowScope.() -> Unit = {},
|
||||||
|
colors: TopAppBarColors = TopAppBarDefaults.smallTopAppBarColors(),
|
||||||
|
scrollBehavior: TopAppBarScrollBehavior? = null
|
||||||
|
) {
|
||||||
|
CenterAlignedTopAppBar(
|
||||||
|
modifier = modifier,
|
||||||
|
title = title,
|
||||||
|
actions = actions,
|
||||||
|
navigationIcon = navigationIcon,
|
||||||
|
colors = colors,
|
||||||
|
scrollBehavior = scrollBehavior
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,26 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.animation
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import androidx.compose.animation.core.Transition
|
|
||||||
import androidx.compose.animation.core.animateDp
|
|
||||||
import androidx.compose.animation.core.keyframes
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.unit.Dp
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
@SuppressLint("UnusedTransitionTargetStateParameter")
|
|
||||||
@Composable
|
|
||||||
fun <T> Transition<T>.jumpAnimation(
|
|
||||||
initialValue: Dp,
|
|
||||||
label: String
|
|
||||||
) = animateDp(
|
|
||||||
transitionSpec = {
|
|
||||||
keyframes {
|
|
||||||
durationMillis = 250
|
|
||||||
initialValue - 8.dp at 50
|
|
||||||
initialValue + 8.dp at 150
|
|
||||||
initialValue at 250
|
|
||||||
}
|
|
||||||
},
|
|
||||||
label = label
|
|
||||||
) { initialValue }
|
|
|
@ -1,41 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.button
|
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
|
||||||
import androidx.compose.ui.semantics.Role
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerIconButton(
|
|
||||||
icon: ImageVector,
|
|
||||||
contentDescription: String,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
val interactionSource = remember { MutableInteractionSource() }
|
|
||||||
val buttonSize = 36.dp
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.clickable(
|
|
||||||
onClick = onClick,
|
|
||||||
role = Role.Button,
|
|
||||||
interactionSource = interactionSource,
|
|
||||||
indication = rememberRipple(radius = buttonSize / 2)
|
|
||||||
)
|
|
||||||
.size(buttonSize),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = icon,
|
|
||||||
contentDescription = contentDescription
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.button
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.RowScope
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.ButtonDefaults
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.luminance
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerThemedButton(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
backgroundColor: Color = managerAccentColor(),
|
|
||||||
onClick: () -> Unit,
|
|
||||||
content: @Composable RowScope.() -> Unit
|
|
||||||
) {
|
|
||||||
Button(
|
|
||||||
modifier = modifier.fillMaxWidth(),
|
|
||||||
onClick = onClick,
|
|
||||||
shape = MediumShape,
|
|
||||||
colors = ButtonDefaults.buttonColors(
|
|
||||||
containerColor = backgroundColor,
|
|
||||||
contentColor =
|
|
||||||
if (backgroundColor.luminance() > 0.7)
|
|
||||||
Color.Black
|
|
||||||
else
|
|
||||||
Color.White
|
|
||||||
),
|
|
||||||
elevation = ButtonDefaults.elevatedButtonElevation(0.dp, 0.dp, 0.dp, 0.dp)
|
|
||||||
) {
|
|
||||||
content()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.button
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerThemedTextButton(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
backgroundColor: Color = managerAccentColor(),
|
|
||||||
text: String,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
ManagerThemedButton(
|
|
||||||
modifier = modifier,
|
|
||||||
backgroundColor = backgroundColor,
|
|
||||||
onClick = onClick
|
|
||||||
) {
|
|
||||||
ManagerText(text = text)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.card
|
|
||||||
|
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.Shape
|
|
||||||
import androidx.compose.ui.unit.Dp
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerCard(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
shape: Shape = MediumShape,
|
|
||||||
backgroundColor: Color = MaterialTheme.colorScheme.surface,
|
|
||||||
tonalElevation: Dp = 0.dp,
|
|
||||||
shadowElevation: Dp = 0.dp,
|
|
||||||
content: @Composable () -> Unit,
|
|
||||||
) {
|
|
||||||
Surface(
|
|
||||||
modifier = modifier,
|
|
||||||
shape = shape,
|
|
||||||
color = backgroundColor,
|
|
||||||
shadowElevation = shadowElevation,
|
|
||||||
tonalElevation = tonalElevation,
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
|
||||||
@Composable
|
|
||||||
fun ManagerCard(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
shape: Shape = MediumShape,
|
|
||||||
backgroundColor: Color = MaterialTheme.colorScheme.surface,
|
|
||||||
tonalElevation: Dp = 0.dp,
|
|
||||||
shadowElevation: Dp = 0.dp,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
content: @Composable () -> Unit,
|
|
||||||
) {
|
|
||||||
Surface(
|
|
||||||
modifier = modifier,
|
|
||||||
shape = shape,
|
|
||||||
color = backgroundColor,
|
|
||||||
shadowElevation = shadowElevation,
|
|
||||||
tonalElevation = tonalElevation,
|
|
||||||
onClick = onClick,
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.card
|
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.github.zsoltk.compose.backpress.LocalBackPressHandler
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
|
||||||
|
|
||||||
private val cardModifier = Modifier.sizeIn(
|
|
||||||
minHeight = 100.dp,
|
|
||||||
minWidth = 100.dp
|
|
||||||
)
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerItemCard(
|
|
||||||
title: String,
|
|
||||||
@DrawableRes icon: Int? = null
|
|
||||||
) {
|
|
||||||
LocalBackPressHandler.current.handle()
|
|
||||||
ManagerCard(
|
|
||||||
modifier = cardModifier,
|
|
||||||
) {
|
|
||||||
ManagerItemCardContent(title, icon)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerItemCard(
|
|
||||||
title: String,
|
|
||||||
@DrawableRes icon: Int? = null,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
ManagerTonalCard(
|
|
||||||
modifier = cardModifier,
|
|
||||||
onClick = onClick
|
|
||||||
) {
|
|
||||||
ManagerItemCardContent(title, icon)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun ManagerItemCardContent(
|
|
||||||
title: String,
|
|
||||||
@DrawableRes icon: Int? = null,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.padding(
|
|
||||||
horizontal = DefaultContentPaddingHorizontal,
|
|
||||||
vertical = DefaultContentPaddingVertical
|
|
||||||
),
|
|
||||||
horizontalAlignment = Alignment.Start,
|
|
||||||
verticalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
|
||||||
if (icon != null) {
|
|
||||||
Icon(
|
|
||||||
modifier = Modifier
|
|
||||||
.size(32.dp),
|
|
||||||
painter = painterResource(id = icon),
|
|
||||||
contentDescription = title,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
ManagerText(
|
|
||||||
text = title,
|
|
||||||
textStyle = MaterialTheme.typography.labelLarge
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.card
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.annotation.DrawableRes
|
|
||||||
import androidx.browser.customtabs.CustomTabsIntent
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import com.vanced.manager.core.preferences.holder.useCustomTabsPref
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerLinkCard(
|
|
||||||
title: String,
|
|
||||||
@DrawableRes icon: Int,
|
|
||||||
link: String
|
|
||||||
) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val customTabs = remember { CustomTabsIntent.Builder().build() }
|
|
||||||
val uri = remember { Uri.parse(link) }
|
|
||||||
val intent = remember { Intent(Intent.ACTION_VIEW, uri) }
|
|
||||||
ManagerItemCard(
|
|
||||||
title = title,
|
|
||||||
icon = icon
|
|
||||||
) {
|
|
||||||
if (useCustomTabsPref) {
|
|
||||||
customTabs.launchUrl(context, uri)
|
|
||||||
} else {
|
|
||||||
context.startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.card
|
|
||||||
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Shape
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerContainerCard(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
shape: Shape = MediumShape,
|
|
||||||
content: @Composable () -> Unit,
|
|
||||||
) {
|
|
||||||
ManagerCard(
|
|
||||||
modifier = modifier,
|
|
||||||
shape = shape,
|
|
||||||
backgroundColor = MaterialTheme.colorScheme.primaryContainer,
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerContainerCard(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
shape: Shape = MediumShape,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
content: @Composable () -> Unit,
|
|
||||||
) {
|
|
||||||
ManagerCard(
|
|
||||||
modifier = modifier,
|
|
||||||
shape = shape,
|
|
||||||
backgroundColor = MaterialTheme.colorScheme.primaryContainer,
|
|
||||||
onClick = onClick,
|
|
||||||
content = content,
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.card
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Shape
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerTonalCard(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
shape: Shape = MediumShape,
|
|
||||||
content: @Composable () -> Unit,
|
|
||||||
) {
|
|
||||||
ManagerCard(
|
|
||||||
modifier = modifier,
|
|
||||||
shape = shape,
|
|
||||||
tonalElevation = 4.dp,
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerTonalCard(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
shape: Shape = MediumShape,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
content: @Composable () -> Unit,
|
|
||||||
) {
|
|
||||||
ManagerCard(
|
|
||||||
modifier = modifier,
|
|
||||||
shape = shape,
|
|
||||||
tonalElevation = 4.dp,
|
|
||||||
onClick = onClick,
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.checkbox
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
||||||
import androidx.compose.foundation.layout.requiredSizeIn
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.rounded.Close
|
|
||||||
import androidx.compose.material.icons.rounded.Done
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.contentColorFor
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Shape
|
|
||||||
import com.vanced.manager.ui.component.card.ManagerCard
|
|
||||||
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
|
|
||||||
@SuppressLint("UnusedTransitionTargetStateParameter")
|
|
||||||
@Composable
|
|
||||||
fun ManagerCheckbox(
|
|
||||||
modifier: Modifier,
|
|
||||||
isChecked: Boolean,
|
|
||||||
shape: Shape = MediumShape,
|
|
||||||
onCheckedChange: (isChecked: Boolean) -> Unit
|
|
||||||
) {
|
|
||||||
val cardColor =
|
|
||||||
managerAnimatedColor(if (isChecked) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.primaryContainer)
|
|
||||||
val iconTint =
|
|
||||||
managerAnimatedColor(
|
|
||||||
if (isChecked)
|
|
||||||
contentColorFor(MaterialTheme.colorScheme.primary)
|
|
||||||
else
|
|
||||||
contentColorFor(MaterialTheme.colorScheme.primaryContainer)
|
|
||||||
)
|
|
||||||
|
|
||||||
ManagerCard(
|
|
||||||
modifier = modifier,
|
|
||||||
shape = shape,
|
|
||||||
onClick = { onCheckedChange(!isChecked) },
|
|
||||||
backgroundColor = cardColor
|
|
||||||
) {
|
|
||||||
BoxWithConstraints {
|
|
||||||
Icon(
|
|
||||||
modifier = Modifier
|
|
||||||
.requiredSizeIn(
|
|
||||||
minWidth = minWidth / 1.6f,
|
|
||||||
minHeight = minHeight / 1.6f,
|
|
||||||
maxWidth = maxWidth / 1.6f,
|
|
||||||
maxHeight = maxHeight / 1.6f,
|
|
||||||
)
|
|
||||||
.align(Alignment.Center),
|
|
||||||
imageVector = if (isChecked) Icons.Rounded.Done else Icons.Rounded.Close,
|
|
||||||
tint = iconTint,
|
|
||||||
contentDescription = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.color
|
|
||||||
|
|
||||||
import androidx.compose.material3.LocalContentColor
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ThemedItemContentColorProvider(
|
|
||||||
content: @Composable () -> Unit
|
|
||||||
) {
|
|
||||||
CompositionLocalProvider(
|
|
||||||
LocalContentColor provides contentColorForColor(managerAccentColor()),
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ThemedCardContentColorProvider(
|
|
||||||
content: @Composable () -> Unit
|
|
||||||
) {
|
|
||||||
CompositionLocalProvider(
|
|
||||||
LocalContentColor provides contentColorForColor(managerAccentColor()),
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ThemedContentColorProvider(
|
|
||||||
content: @Composable () -> Unit
|
|
||||||
) {
|
|
||||||
CompositionLocalProvider(
|
|
||||||
LocalContentColor provides managerAccentColor(),
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.color
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.skydoves.colorpickerview.ColorEnvelope
|
|
||||||
import com.skydoves.orchestra.colorpicker.ColorPicker
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerColorPicker(
|
|
||||||
onColorSelected: (color: Long) -> Unit
|
|
||||||
) {
|
|
||||||
val (selectedColor, setColor) = remember { mutableStateOf(ColorEnvelope(0)) }
|
|
||||||
ColorPicker(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(300.dp),
|
|
||||||
onColorListener = { envelope, _ -> setColor(envelope) },
|
|
||||||
children = {},
|
|
||||||
initialColor = managerAccentColor()
|
|
||||||
)
|
|
||||||
onColorSelected(selectedColor.color.toLong())
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.color
|
|
||||||
|
|
||||||
import androidx.compose.animation.animateColorAsState
|
|
||||||
import androidx.compose.animation.core.tween
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.luminance
|
|
||||||
import com.vanced.manager.core.preferences.holder.managerAccentColorPref
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun contentColorForColor(color: Color) =
|
|
||||||
if (color.luminance() > 0.7)
|
|
||||||
Color.Black
|
|
||||||
else
|
|
||||||
Color.White
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun managerAccentColor(): Color {
|
|
||||||
return Color(managerAccentColorPref)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun managerThemedCardColor() = managerAccentColor().copy(alpha = 0.27f)
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun managerTextColor(): Color = managerAnimatedColor(color = MaterialTheme.colorScheme.onSurface)
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun managerSurfaceColor(): Color = managerAnimatedColor(color = MaterialTheme.colorScheme.surface)
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun managerAnimatedColor(
|
|
||||||
color: Color
|
|
||||||
): Color = animateColorAsState(
|
|
||||||
targetValue = color,
|
|
||||||
animationSpec = tween(500)
|
|
||||||
).value
|
|
|
@ -1,20 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.layout
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerButtonColumn(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
content: @Composable ColumnScope.() -> Unit
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier,
|
|
||||||
verticalArrangement = Arrangement.spacedBy(DefaultContentPaddingVertical),
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.layout
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.LazyListScope
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerLazyColumn(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
contentPadding: PaddingValues = PaddingValues(),
|
|
||||||
content: LazyListScope.() -> Unit
|
|
||||||
) {
|
|
||||||
LazyColumn(
|
|
||||||
modifier = modifier,
|
|
||||||
contentPadding = contentPadding,
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.layout
|
|
||||||
|
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
|
||||||
import androidx.compose.animation.core.tween
|
|
||||||
import androidx.compose.foundation.Canvas
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.SideEffect
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
|
||||||
import com.vanced.manager.ui.theme.isDark
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerScrim(
|
|
||||||
show: Boolean
|
|
||||||
) {
|
|
||||||
val systemUiController = rememberSystemUiController()
|
|
||||||
|
|
||||||
val scrimColor = Color.Black.copy(alpha = 0.5f)
|
|
||||||
val surfaceColor = MaterialTheme.colorScheme.surface
|
|
||||||
|
|
||||||
val isDark = isDark()
|
|
||||||
|
|
||||||
val scrimAlpha by animateFloatAsState(
|
|
||||||
targetValue = if (show) 1f else 0f,
|
|
||||||
animationSpec = tween()
|
|
||||||
)
|
|
||||||
|
|
||||||
SideEffect {
|
|
||||||
//TODO fix colors in navigation bars
|
|
||||||
if (show) {
|
|
||||||
systemUiController.setSystemBarsColor(scrimColor, false)
|
|
||||||
} else {
|
|
||||||
systemUiController.setSystemBarsColor(surfaceColor, !isDark)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Canvas(
|
|
||||||
Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
) {
|
|
||||||
drawRect(
|
|
||||||
color = scrimColor,
|
|
||||||
alpha = scrimAlpha
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.layout
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.Dp
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerScrollableColumn(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
contentPaddingVertical: Dp = DefaultContentPaddingVertical,
|
|
||||||
itemSpacing: Dp = 0.dp,
|
|
||||||
content: @Composable ColumnScope.() -> Unit
|
|
||||||
) {
|
|
||||||
val scrollState = rememberScrollState()
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.verticalScroll(scrollState)
|
|
||||||
.padding(vertical = contentPaddingVertical),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
verticalArrangement = Arrangement.spacedBy(itemSpacing),
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.layout
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.vanced.manager.ui.component.color.managerSurfaceColor
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerSurface(
|
|
||||||
content: @Composable () -> Unit
|
|
||||||
) {
|
|
||||||
Surface(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
color = managerSurfaceColor(),
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.layout
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.lazy.LazyRow
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun <T> ScrollableItemRow(
|
|
||||||
items: List<T>,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
content: @Composable (T) -> Unit
|
|
||||||
) {
|
|
||||||
val state = rememberLazyListState()
|
|
||||||
LazyRow(
|
|
||||||
modifier = modifier,
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
|
||||||
state = state
|
|
||||||
) {
|
|
||||||
item {
|
|
||||||
Spacer(Modifier.width(8.dp))
|
|
||||||
}
|
|
||||||
items(items) { item ->
|
|
||||||
content(item)
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
Spacer(Modifier.width(8.dp))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.menu
|
|
||||||
|
|
||||||
import androidx.compose.material.DropdownMenuItem
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
import com.vanced.manager.ui.theme.SmallShape
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerDropdownMenuItem(
|
|
||||||
title: String,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
DropdownMenuItem(
|
|
||||||
onClick = onClick,
|
|
||||||
modifier = Modifier.clip(SmallShape),
|
|
||||||
) {
|
|
||||||
ManagerText(
|
|
||||||
text = title,
|
|
||||||
textStyle = MaterialTheme.typography.labelLarge
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.modifier
|
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.composed
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
|
|
||||||
fun Modifier.managerClickable(
|
|
||||||
onClick: () -> Unit
|
|
||||||
) = composed {
|
|
||||||
val ripple = rememberRipple()
|
|
||||||
val interactionSource = remember { MutableInteractionSource() }
|
|
||||||
|
|
||||||
then(clip(MediumShape)).then(
|
|
||||||
clickable(
|
|
||||||
interactionSource = interactionSource,
|
|
||||||
onClick = onClick,
|
|
||||||
indication = ripple
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.modifier
|
|
||||||
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.composed
|
|
||||||
import com.google.accompanist.placeholder.PlaceholderHighlight
|
|
||||||
import com.google.accompanist.placeholder.material.placeholder
|
|
||||||
import com.google.accompanist.placeholder.material.shimmer
|
|
||||||
|
|
||||||
fun Modifier.managerPlaceholder(
|
|
||||||
visible: Boolean
|
|
||||||
) = composed {
|
|
||||||
then(
|
|
||||||
placeholder(
|
|
||||||
visible = visible,
|
|
||||||
highlight = PlaceholderHighlight.shimmer()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.modifier
|
|
||||||
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
|
|
||||||
fun modifierBuilder(
|
|
||||||
block: Modifier.() -> Unit
|
|
||||||
) = Modifier.block()
|
|
|
@ -1,30 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.preference
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.ui.widget.checkbox.ManagerAnimatedCheckbox
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun CheckboxPreference(
|
|
||||||
preferenceTitle: String,
|
|
||||||
preferenceDescription: String? = null,
|
|
||||||
isChecked: Boolean,
|
|
||||||
onCheckedChange: (isChecked: Boolean) -> Unit = {}
|
|
||||||
) {
|
|
||||||
val onClick: () -> Unit = {
|
|
||||||
onCheckedChange(!isChecked)
|
|
||||||
}
|
|
||||||
|
|
||||||
Preference(
|
|
||||||
preferenceTitle = preferenceTitle,
|
|
||||||
preferenceDescription = preferenceDescription,
|
|
||||||
onClick = onClick,
|
|
||||||
trailing = {
|
|
||||||
ManagerAnimatedCheckbox(
|
|
||||||
isChecked = isChecked,
|
|
||||||
onCheckedChange = { onClick() },
|
|
||||||
size = 40.dp
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.preference
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import com.vanced.manager.ui.component.dialog.ManagerDialog
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun DialogPreference(
|
|
||||||
preferenceTitle: String,
|
|
||||||
preferenceDescription: String? = null,
|
|
||||||
trailing: @Composable () -> Unit = {},
|
|
||||||
onPreferenceClick: () -> Unit,
|
|
||||||
isDialogVisible: Boolean,
|
|
||||||
onDismissRequest: () -> Unit,
|
|
||||||
confirmButton: @Composable () -> Unit,
|
|
||||||
dismissButton: @Composable () -> Unit = {},
|
|
||||||
content: @Composable () -> Unit
|
|
||||||
) {
|
|
||||||
Preference(
|
|
||||||
preferenceTitle = preferenceTitle,
|
|
||||||
preferenceDescription = preferenceDescription,
|
|
||||||
trailing = trailing,
|
|
||||||
onClick = onPreferenceClick
|
|
||||||
)
|
|
||||||
if (isDialogVisible) {
|
|
||||||
ManagerDialog(
|
|
||||||
title = preferenceTitle,
|
|
||||||
onDismissRequest = onDismissRequest,
|
|
||||||
confirmButton = confirmButton,
|
|
||||||
dismissButton = dismissButton,
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.preference
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.heightIn
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.material.TextButton
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.core.preferences.RadioButtonPreference
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
import com.vanced.manager.ui.widget.list.CheckboxItem
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun MultiSelectDialogPreference(
|
|
||||||
preferenceTitle: String,
|
|
||||||
preferenceDescription: String,
|
|
||||||
isDialogVisible: Boolean,
|
|
||||||
currentSelectedKeys: List<String>,
|
|
||||||
buttons: List<RadioButtonPreference>,
|
|
||||||
trailing: @Composable () -> Unit = {},
|
|
||||||
onPreferenceClick: () -> Unit,
|
|
||||||
onDismissRequest: () -> Unit,
|
|
||||||
onItemCheckChange: (isChecked: Boolean, itemKey: String) -> Unit,
|
|
||||||
onSave: () -> Unit,
|
|
||||||
) {
|
|
||||||
DialogPreference(
|
|
||||||
preferenceTitle = preferenceTitle,
|
|
||||||
preferenceDescription = preferenceDescription,
|
|
||||||
trailing = trailing,
|
|
||||||
confirmButton = {
|
|
||||||
TextButton(onClick = onSave) {
|
|
||||||
ManagerText(managerString(R.string.dialog_button_save))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dismissButton = {
|
|
||||||
TextButton(onClick = onDismissRequest) {
|
|
||||||
ManagerText(managerString(R.string.dialog_button_cancel))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onDismissRequest = onDismissRequest,
|
|
||||||
isDialogVisible = isDialogVisible,
|
|
||||||
onPreferenceClick = onPreferenceClick
|
|
||||||
) {
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier.heightIn(max = 400.dp)
|
|
||||||
) {
|
|
||||||
items(buttons) { button ->
|
|
||||||
val (title, key) = button
|
|
||||||
CheckboxItem(
|
|
||||||
text = title,
|
|
||||||
checked = currentSelectedKeys.contains(key),
|
|
||||||
onCheckedChange = { isChecked ->
|
|
||||||
onItemCheckChange(isChecked, key)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.preference
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.LocalContentColor
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.ui.component.card.ManagerTonalCard
|
|
||||||
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
|
||||||
import com.vanced.manager.ui.component.list.ManagerListItem
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
import com.vanced.manager.ui.theme.LargeShape
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun Preference(
|
|
||||||
preferenceTitle: String,
|
|
||||||
preferenceDescription: String? = null,
|
|
||||||
trailing: @Composable () -> Unit = {},
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
val color = managerAnimatedColor(color = MaterialTheme.colorScheme.onSurface)
|
|
||||||
ManagerTonalCard(
|
|
||||||
shape = LargeShape,
|
|
||||||
onClick = onClick
|
|
||||||
) {
|
|
||||||
ManagerListItem(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(
|
|
||||||
horizontal = DefaultContentPaddingHorizontal,
|
|
||||||
vertical = 8.dp
|
|
||||||
),
|
|
||||||
title = {
|
|
||||||
CompositionLocalProvider(
|
|
||||||
LocalContentColor provides color,
|
|
||||||
LocalTextStyle provides MaterialTheme.typography.titleSmall
|
|
||||||
) {
|
|
||||||
ManagerText(text = preferenceTitle)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
description = if (preferenceDescription != null) {
|
|
||||||
{
|
|
||||||
CompositionLocalProvider(
|
|
||||||
LocalContentColor provides color,
|
|
||||||
LocalTextStyle provides MaterialTheme.typography.bodySmall
|
|
||||||
) {
|
|
||||||
ManagerText(text = preferenceDescription)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else null,
|
|
||||||
trailing = trailing,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.preference
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.heightIn
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.material3.TextButton
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.core.preferences.RadioButtonPreference
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
import com.vanced.manager.ui.widget.list.RadiobuttonItem
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SingleSelectDialogPreference(
|
|
||||||
preferenceTitle: String,
|
|
||||||
preferenceDescription: String,
|
|
||||||
isDialogVisible: Boolean,
|
|
||||||
currentSelectedKey: String,
|
|
||||||
buttons: List<RadioButtonPreference>,
|
|
||||||
trailing: @Composable () -> Unit = {},
|
|
||||||
onPreferenceClick: () -> Unit,
|
|
||||||
onDismissRequest: () -> Unit,
|
|
||||||
onItemClick: (itemKey: String) -> Unit,
|
|
||||||
onSave: () -> Unit,
|
|
||||||
) {
|
|
||||||
DialogPreference(
|
|
||||||
preferenceTitle = preferenceTitle,
|
|
||||||
preferenceDescription = preferenceDescription,
|
|
||||||
trailing = trailing,
|
|
||||||
confirmButton = {
|
|
||||||
TextButton(onClick = onSave) {
|
|
||||||
ManagerText(managerString(R.string.dialog_button_save))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dismissButton = {
|
|
||||||
TextButton(onClick = onDismissRequest) {
|
|
||||||
ManagerText(managerString(R.string.dialog_button_cancel))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onDismissRequest = onDismissRequest,
|
|
||||||
isDialogVisible = isDialogVisible,
|
|
||||||
onPreferenceClick = onPreferenceClick
|
|
||||||
) {
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier.heightIn(max = 400.dp)
|
|
||||||
) {
|
|
||||||
items(buttons) { button ->
|
|
||||||
val (title, key) = button
|
|
||||||
RadiobuttonItem(
|
|
||||||
text = title,
|
|
||||||
selected = currentSelectedKey == key,
|
|
||||||
onClick = {
|
|
||||||
onItemClick(key)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.progressindicator
|
|
||||||
|
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.material.LinearProgressIndicator
|
|
||||||
import androidx.compose.material.ProgressIndicatorDefaults
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.composed
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
|
|
||||||
private val progressBarModifier = Modifier.composed {
|
|
||||||
then(height(5.dp))
|
|
||||||
.then(fillMaxWidth())
|
|
||||||
.then(clip(MediumShape))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerProgressIndicator() {
|
|
||||||
LinearProgressIndicator(
|
|
||||||
modifier = progressBarModifier,
|
|
||||||
color = managerAccentColor()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerProgressIndicator(
|
|
||||||
progress: Float
|
|
||||||
) {
|
|
||||||
val animatedProgress by animateFloatAsState(
|
|
||||||
targetValue = progress,
|
|
||||||
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
|
|
||||||
)
|
|
||||||
LinearProgressIndicator(
|
|
||||||
modifier = progressBarModifier,
|
|
||||||
color = managerAccentColor(),
|
|
||||||
progress = animatedProgress
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.radiobutton
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Shape
|
|
||||||
import com.vanced.manager.ui.component.card.ManagerCard
|
|
||||||
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
|
|
||||||
@SuppressLint("UnusedTransitionTargetStateParameter")
|
|
||||||
@Composable
|
|
||||||
fun ManagerRadiobutton(
|
|
||||||
modifier: Modifier,
|
|
||||||
isSelected: Boolean,
|
|
||||||
shape: Shape = MediumShape,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
val cardColor =
|
|
||||||
managerAnimatedColor(if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.primaryContainer)
|
|
||||||
ManagerCard(
|
|
||||||
modifier = modifier,
|
|
||||||
onClick = onClick,
|
|
||||||
shape = shape,
|
|
||||||
backgroundColor = cardColor,
|
|
||||||
content = {}
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.text
|
|
||||||
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun AppVersionText(
|
|
||||||
text: String,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
ManagerText(
|
|
||||||
modifier = modifier,
|
|
||||||
text = text,
|
|
||||||
textStyle = MaterialTheme.typography.bodySmall,
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.text
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun CategoryTitleText(
|
|
||||||
text: String
|
|
||||||
) {
|
|
||||||
ManagerText(
|
|
||||||
modifier = Modifier.padding(start = DefaultContentPaddingHorizontal),
|
|
||||||
text = text,
|
|
||||||
textStyle = MaterialTheme.typography.headlineSmall,
|
|
||||||
color = managerAnimatedColor(MaterialTheme.colorScheme.onSurface)
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.text
|
|
||||||
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ToolbarTitleText(
|
|
||||||
text: String
|
|
||||||
) {
|
|
||||||
ManagerText(
|
|
||||||
text = text,
|
|
||||||
textStyle = MaterialTheme.typography.headlineMedium,
|
|
||||||
color = managerAnimatedColor(MaterialTheme.colorScheme.onSurface)
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package com.vanced.manager.ui.component.topappbar
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.RowScope
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.SmallTopAppBar
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerTopAppBar(
|
|
||||||
title: String,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
actions: @Composable RowScope.() -> Unit = {},
|
|
||||||
navigationIcon: @Composable () -> Unit = {},
|
|
||||||
) {
|
|
||||||
SmallTopAppBar(
|
|
||||||
modifier = modifier,
|
|
||||||
title = {
|
|
||||||
ManagerText(
|
|
||||||
text = title,
|
|
||||||
textStyle = MaterialTheme.typography.headlineMedium,
|
|
||||||
color = managerAnimatedColor(MaterialTheme.colorScheme.onSurface)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
actions = actions,
|
|
||||||
navigationIcon = navigationIcon,
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package com.vanced.manager.ui.navigation
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun <T> rememberNavigationController(
|
|
||||||
initialScreen: T
|
|
||||||
) = remember {
|
|
||||||
NavigationControllerImpl(initialScreen)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface NavigationController<T> {
|
|
||||||
|
|
||||||
val screens: SnapshotStateList<T>
|
|
||||||
|
|
||||||
fun push(item: T)
|
|
||||||
|
|
||||||
fun pop(): Boolean
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class NavigationControllerImpl<T>(
|
|
||||||
initialScreen: T
|
|
||||||
) : NavigationController<T> {
|
|
||||||
|
|
||||||
override val screens: SnapshotStateList<T> =
|
|
||||||
mutableStateListOf(initialScreen)
|
|
||||||
|
|
||||||
override fun push(item: T) {
|
|
||||||
screens.add(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pop(): Boolean {
|
|
||||||
if (screens.size > 1) {
|
|
||||||
screens.removeLast()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.vanced.manager.ui.resources
|
package com.vanced.manager.ui.resource
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
|
@ -1,8 +1,9 @@
|
||||||
package com.vanced.manager.ui.screens
|
package com.vanced.manager.ui.screen
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.ArrowBackIosNew
|
import androidx.compose.material.icons.rounded.ArrowBackIosNew
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
@ -13,25 +14,19 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.SpanStyle
|
import androidx.compose.ui.text.SpanStyle
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.vanced.manager.BuildConfig
|
import com.vanced.manager.BuildConfig
|
||||||
import com.vanced.manager.R
|
import com.vanced.manager.R
|
||||||
import com.vanced.manager.ui.component.card.ManagerLinkCard
|
import com.vanced.manager.ui.component.*
|
||||||
import com.vanced.manager.ui.component.card.ManagerTonalCard
|
import com.vanced.manager.ui.resource.managerString
|
||||||
import com.vanced.manager.ui.component.layout.ManagerLazyColumn
|
|
||||||
import com.vanced.manager.ui.component.layout.ManagerScaffold
|
|
||||||
import com.vanced.manager.ui.component.layout.ScrollableItemRow
|
|
||||||
import com.vanced.manager.ui.component.list.ManagerListItem
|
|
||||||
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.theme.LargeShape
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
||||||
import com.vanced.manager.ui.util.Screen
|
import com.vanced.manager.ui.util.Screen
|
||||||
import com.vanced.manager.ui.widget.layout.managerCategory
|
import com.vanced.manager.ui.widget.LinkCard
|
||||||
|
|
||||||
data class Person(
|
data class Person(
|
||||||
val name: String,
|
val name: String,
|
||||||
|
@ -109,17 +104,15 @@ private val sources = listOf(
|
||||||
|
|
||||||
@ExperimentalMaterial3Api
|
@ExperimentalMaterial3Api
|
||||||
@Composable
|
@Composable
|
||||||
fun AboutLayout(
|
fun AboutScreen(
|
||||||
onToolbarBackButtonClick: () -> Unit
|
onToolbarBackButtonClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
val aboutCategoryVancedTeam = managerString(R.string.about_category_credits_vanced_team)
|
|
||||||
val aboutCategoryOtherContributors = managerString(R.string.about_category_credits_other)
|
|
||||||
val aboutCategorySources = managerString(R.string.about_category_sources)
|
|
||||||
|
|
||||||
ManagerScaffold(
|
ManagerScaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
ManagerTopAppBar(
|
ManagerSmallTopAppBar(
|
||||||
title = managerString(Screen.About.displayName),
|
title = {
|
||||||
|
ManagerText(managerString(Screen.About.displayName))
|
||||||
|
},
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = onToolbarBackButtonClick) {
|
IconButton(onClick = onToolbarBackButtonClick) {
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -137,12 +130,17 @@ fun AboutLayout(
|
||||||
.padding(paddingValues),
|
.padding(paddingValues),
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
ManagerTonalCard(
|
ManagerElevatedCard(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
shape = LargeShape
|
shape = LargeShape
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.padding(vertical = DefaultContentPaddingVertical),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(
|
||||||
|
vertical = DefaultContentPaddingVertical,
|
||||||
|
horizontal = DefaultContentPaddingHorizontal
|
||||||
|
),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
) {
|
) {
|
||||||
|
@ -168,62 +166,73 @@ fun AboutLayout(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
managerCategory(
|
managerCategory(categoryName = {
|
||||||
categoryName = aboutCategoryVancedTeam,
|
managerString(R.string.about_category_credits_vanced_team)
|
||||||
items = vancedTeam
|
}) {
|
||||||
) { person ->
|
items(vancedTeam) { person ->
|
||||||
CreditPersonItem(
|
CreditCard(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
personName = person.name,
|
personName = person.name,
|
||||||
personContribution = person.contribution
|
personContribution = person.contribution
|
||||||
)
|
|
||||||
}
|
|
||||||
managerCategory(
|
|
||||||
categoryName = aboutCategoryOtherContributors,
|
|
||||||
items = otherContributors
|
|
||||||
) { person ->
|
|
||||||
CreditPersonItem(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
personName = person.name,
|
|
||||||
personContribution = person.contribution
|
|
||||||
)
|
|
||||||
}
|
|
||||||
managerCategory(aboutCategorySources) {
|
|
||||||
ScrollableItemRow(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth(),
|
|
||||||
items = sources
|
|
||||||
) { source ->
|
|
||||||
ManagerLinkCard(
|
|
||||||
title = managerString(source.nameId),
|
|
||||||
icon = source.iconId,
|
|
||||||
link = source.link
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
managerCategory(categoryName = {
|
||||||
|
managerString(R.string.about_category_credits_other)
|
||||||
|
}) {
|
||||||
|
items(otherContributors) { person ->
|
||||||
|
CreditCard(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
personName = person.name,
|
||||||
|
personContribution = person.contribution
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
managerCategory(categoryName = {
|
||||||
|
managerString(R.string.about_category_sources)
|
||||||
|
}) {
|
||||||
|
item {
|
||||||
|
ManagerLazyRow(modifier = Modifier.fillMaxWidth()) {
|
||||||
|
items(sources) { source ->
|
||||||
|
LinkCard(
|
||||||
|
text = managerString(source.nameId),
|
||||||
|
icon = painterResource(source.iconId),
|
||||||
|
url = source.link
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun CreditPersonItem(
|
private fun CreditCard(
|
||||||
personName: String,
|
personName: String,
|
||||||
personContribution: String,
|
personContribution: String,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
ManagerListItem(
|
ManagerElevatedCard(
|
||||||
modifier = modifier.padding(horizontal = DefaultContentPaddingHorizontal),
|
modifier = modifier,
|
||||||
title = {
|
shape = LargeShape
|
||||||
ManagerText(
|
) {
|
||||||
text = personName,
|
ManagerListItem(
|
||||||
textStyle = MaterialTheme.typography.titleSmall
|
modifier = Modifier
|
||||||
)
|
.fillMaxWidth()
|
||||||
},
|
.padding(horizontal = DefaultContentPaddingHorizontal),
|
||||||
description = {
|
title = {
|
||||||
ManagerText(
|
ManagerText(
|
||||||
text = personContribution,
|
text = personName,
|
||||||
textStyle = MaterialTheme.typography.bodySmall
|
textStyle = MaterialTheme.typography.titleSmall
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
description = {
|
||||||
|
ManagerText(
|
||||||
|
text = personContribution,
|
||||||
|
textStyle = MaterialTheme.typography.bodySmall
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,38 +1,28 @@
|
||||||
package com.vanced.manager.ui.screens
|
package com.vanced.manager.ui.screen
|
||||||
|
|
||||||
import androidx.compose.animation.*
|
import androidx.compose.animation.*
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
|
||||||
import androidx.compose.material.ListItem
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.ArrowBackIosNew
|
import androidx.compose.material.icons.rounded.ArrowBackIosNew
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.R
|
import com.vanced.manager.R
|
||||||
import com.vanced.manager.domain.model.InstallationOption
|
import com.vanced.manager.domain.model.InstallationOption
|
||||||
import com.vanced.manager.ui.component.card.ManagerTonalCard
|
import com.vanced.manager.ui.component.*
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
import com.vanced.manager.ui.resource.managerString
|
||||||
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.theme.LargeShape
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
||||||
import com.vanced.manager.ui.viewmodel.ConfigurationViewModel
|
import com.vanced.manager.ui.viewmodel.ConfigurationViewModel
|
||||||
import com.vanced.manager.ui.widget.layout.managerCategory
|
|
||||||
import org.koin.androidx.compose.getViewModel
|
import org.koin.androidx.compose.getViewModel
|
||||||
|
|
||||||
private const val enterDuration = 300
|
private const val enterDuration = 300
|
||||||
private const val exitDuration = 250
|
private const val exitDuration = 250
|
||||||
|
|
||||||
@ExperimentalFoundationApi
|
|
||||||
@ExperimentalAnimationApi
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ConfigurationScreen(
|
fun ConfigurationScreen(
|
||||||
installationOptions: List<InstallationOption>,
|
installationOptions: List<InstallationOption>,
|
||||||
|
@ -42,8 +32,10 @@ fun ConfigurationScreen(
|
||||||
val viewModel: ConfigurationViewModel = getViewModel()
|
val viewModel: ConfigurationViewModel = getViewModel()
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
ManagerTopAppBar(
|
ManagerSmallTopAppBar(
|
||||||
title = managerString(R.string.toolbar_installation_preferences),
|
title = {
|
||||||
|
ManagerText(managerString(R.string.toolbar_installation_preferences))
|
||||||
|
},
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
|
@ -60,7 +52,7 @@ fun ConfigurationScreen(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
ConfigurationButtons(
|
ConfigurationBottomBar(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(
|
.padding(
|
||||||
horizontal = DefaultContentPaddingHorizontal,
|
horizontal = DefaultContentPaddingHorizontal,
|
||||||
|
@ -91,7 +83,6 @@ fun ConfigurationScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalAnimationApi::class, ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ConfigurationBody(
|
private fun ConfigurationBody(
|
||||||
currentIndex: Int,
|
currentIndex: Int,
|
||||||
|
@ -112,55 +103,52 @@ private fun ConfigurationBody(
|
||||||
}
|
}
|
||||||
) { optionIndex ->
|
) { optionIndex ->
|
||||||
val installationOption = installationOptions[optionIndex]
|
val installationOption = installationOptions[optionIndex]
|
||||||
val categoryName = managerString(installationOption.titleId)
|
ManagerLazyColumn {
|
||||||
LazyColumn {
|
managerCategory(categoryName = {
|
||||||
when (installationOption) {
|
managerString(installationOption.titleId)
|
||||||
is InstallationOption.SingleSelect -> {
|
}) {
|
||||||
managerCategory(
|
when (installationOption) {
|
||||||
categoryName = categoryName,
|
is InstallationOption.SingleSelect -> {
|
||||||
items = installationOption.items
|
items(installationOption.items) { item ->
|
||||||
) { item ->
|
val preference = installationOption.getOption()
|
||||||
val preference = installationOption.getOption()
|
ConfigurationItem(
|
||||||
ConfigurationItem(
|
modifier = Modifier
|
||||||
modifier = Modifier
|
.fillMaxWidth(),
|
||||||
.fillMaxWidth(),
|
text = item.displayText(item.key),
|
||||||
text = item.displayText(item.key),
|
onClick = {
|
||||||
onClick = {
|
installationOption.setOption(item.key)
|
||||||
installationOption.setOption(item.key)
|
},
|
||||||
},
|
trailing = {
|
||||||
trailing = {
|
RadioButton(
|
||||||
RadioButton(
|
selected = preference == item.key,
|
||||||
selected = preference == item.key,
|
onClick = null
|
||||||
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),
|
is InstallationOption.MultiSelect -> {
|
||||||
onCheckedChange = null
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,9 +156,8 @@ private fun ConfigurationBody(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalAnimationApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ConfigurationButtons(
|
private fun ConfigurationBottomBar(
|
||||||
currentIndex: Int,
|
currentIndex: Int,
|
||||||
lastIndex: Int,
|
lastIndex: Int,
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
|
@ -224,7 +211,6 @@ private fun ConfigurationButtons(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ConfigurationItem(
|
private fun ConfigurationItem(
|
||||||
text: String,
|
text: String,
|
||||||
|
@ -232,18 +218,16 @@ private fun ConfigurationItem(
|
||||||
trailing: @Composable () -> Unit,
|
trailing: @Composable () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
ManagerTonalCard(
|
ManagerElevatedCard(
|
||||||
modifier = modifier
|
modifier = modifier,
|
||||||
.padding(
|
|
||||||
start = 6.dp,
|
|
||||||
end = 6.dp,
|
|
||||||
bottom = 8.dp
|
|
||||||
),
|
|
||||||
shape = LargeShape,
|
shape = LargeShape,
|
||||||
onClick = onClick
|
onClick = onClick
|
||||||
) {
|
) {
|
||||||
ListItem(
|
ManagerListItem(
|
||||||
text = {
|
modifier = Modifier.padding(
|
||||||
|
horizontal = DefaultContentPaddingHorizontal
|
||||||
|
),
|
||||||
|
title = {
|
||||||
ManagerText(
|
ManagerText(
|
||||||
text = text,
|
text = text,
|
||||||
textStyle = MaterialTheme.typography.titleSmall
|
textStyle = MaterialTheme.typography.titleSmall
|
|
@ -0,0 +1,284 @@
|
||||||
|
package com.vanced.manager.ui.screen
|
||||||
|
|
||||||
|
import androidx.compose.animation.*
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyListScope
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.rounded.MoreVert
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import coil.compose.rememberImagePainter
|
||||||
|
import coil.request.CachePolicy
|
||||||
|
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
|
||||||
|
import com.vanced.manager.R
|
||||||
|
import com.vanced.manager.core.util.socialMedia
|
||||||
|
import com.vanced.manager.core.util.sponsors
|
||||||
|
import com.vanced.manager.domain.model.App
|
||||||
|
import com.vanced.manager.domain.model.InstallationOption
|
||||||
|
import com.vanced.manager.ui.component.*
|
||||||
|
import com.vanced.manager.ui.resource.managerString
|
||||||
|
import com.vanced.manager.ui.util.Screen
|
||||||
|
import com.vanced.manager.ui.viewmodel.MainViewModel
|
||||||
|
import com.vanced.manager.ui.widget.AppCard
|
||||||
|
import com.vanced.manager.ui.widget.AppCardPlaceholder
|
||||||
|
import com.vanced.manager.ui.widget.LinkCard
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun HomeScreen(
|
||||||
|
viewModel: MainViewModel,
|
||||||
|
onToolbarScreenSelected: (Screen) -> Unit,
|
||||||
|
onAppDownloadClick: (
|
||||||
|
appName: String,
|
||||||
|
appVersions: List<String>?,
|
||||||
|
installationOptions: List<InstallationOption>?
|
||||||
|
) -> Unit,
|
||||||
|
onAppUninstallClick: (appPackage: String) -> Unit,
|
||||||
|
onAppLaunchClick: (appName: String, appPackage: String) -> Unit,
|
||||||
|
) {
|
||||||
|
val refreshState =
|
||||||
|
rememberSwipeRefreshState(isRefreshing = viewModel.appState.isFetching)
|
||||||
|
var menuExpanded by remember { mutableStateOf(false) }
|
||||||
|
val dropdownScreens = remember { listOf(Screen.Settings, Screen.About) }
|
||||||
|
|
||||||
|
ManagerScaffold(
|
||||||
|
topBar = {
|
||||||
|
HomeScreenTopBar(
|
||||||
|
modifier = Modifier,
|
||||||
|
menuExpanded = menuExpanded,
|
||||||
|
dropdownScreens = dropdownScreens,
|
||||||
|
onActionClick = {
|
||||||
|
menuExpanded = true
|
||||||
|
},
|
||||||
|
onDropdownItemClick = onToolbarScreenSelected,
|
||||||
|
onDropdownDismissRequest = {
|
||||||
|
menuExpanded = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
ManagerSwipeRefresh(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues),
|
||||||
|
swipeRefreshState = refreshState,
|
||||||
|
onRefresh = { viewModel.fetch() }
|
||||||
|
) {
|
||||||
|
AnimatedContent(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
targetState = viewModel.appState,
|
||||||
|
transitionSpec = {
|
||||||
|
scaleIn(initialScale = 0.9f) + fadeIn() with
|
||||||
|
scaleOut(targetScale = 0.9f) + fadeOut()
|
||||||
|
}
|
||||||
|
) { animatedAppState ->
|
||||||
|
when (animatedAppState) {
|
||||||
|
is StateFetching -> {
|
||||||
|
HomeScreenLoading(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
appsCount = animatedAppState.placeholderAppsCount
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is StateSuccess -> {
|
||||||
|
HomeScreenLoaded(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
apps = animatedAppState.apps,
|
||||||
|
onAppDownloadClick = onAppDownloadClick,
|
||||||
|
onAppUninstallClick = onAppUninstallClick,
|
||||||
|
onAppLaunchClick = onAppLaunchClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is StateError -> {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typealias StateFetching = MainViewModel.AppState.Fetching
|
||||||
|
typealias StateSuccess = MainViewModel.AppState.Success
|
||||||
|
typealias StateError = MainViewModel.AppState.Error
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun HomeScreenTopBar(
|
||||||
|
menuExpanded: Boolean,
|
||||||
|
dropdownScreens: List<Screen>,
|
||||||
|
onActionClick: () -> Unit,
|
||||||
|
onDropdownItemClick: (Screen) -> Unit,
|
||||||
|
onDropdownDismissRequest: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
ManagerCenterAlignedTopAppBar(
|
||||||
|
modifier = modifier,
|
||||||
|
title = {
|
||||||
|
ManagerText(managerString(Screen.Home.displayName))
|
||||||
|
},
|
||||||
|
actions = {
|
||||||
|
IconButton(onClick = onActionClick) {
|
||||||
|
Icon(
|
||||||
|
Icons.Rounded.MoreVert,
|
||||||
|
contentDescription = "Navigation"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ManagerDropdownMenu(
|
||||||
|
expanded = menuExpanded,
|
||||||
|
onDismissRequest = onDropdownDismissRequest
|
||||||
|
) {
|
||||||
|
for (dropdownScreen in dropdownScreens) {
|
||||||
|
ManagerDropdownMenuItem(
|
||||||
|
title = managerString(dropdownScreen.displayName),
|
||||||
|
onClick = {
|
||||||
|
onDropdownItemClick(dropdownScreen)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun HomeScreenLoaded(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
apps: List<App>,
|
||||||
|
onAppDownloadClick: (
|
||||||
|
appName: String,
|
||||||
|
appVersions: List<String>?,
|
||||||
|
installationOptions: List<InstallationOption>?
|
||||||
|
) -> Unit,
|
||||||
|
onAppUninstallClick: (appPackage: String) -> Unit,
|
||||||
|
onAppLaunchClick: (appName: String, appPackage: String) -> Unit,
|
||||||
|
) {
|
||||||
|
HomeScreenBody(modifier = modifier) {
|
||||||
|
managerCategory(categoryName = {
|
||||||
|
managerString(R.string.home_category_apps)
|
||||||
|
}) {
|
||||||
|
items(apps) { app ->
|
||||||
|
val appIcon = rememberImagePainter(app.iconUrl) {
|
||||||
|
diskCachePolicy(CachePolicy.ENABLED)
|
||||||
|
}
|
||||||
|
|
||||||
|
var showAppInfoDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
AppCard(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(),
|
||||||
|
appName = app.name,
|
||||||
|
appIcon = appIcon,
|
||||||
|
appInstalledVersion = app.installedVersion,
|
||||||
|
appRemoteVersion = app.remoteVersion,
|
||||||
|
onAppDownloadClick = {
|
||||||
|
onAppDownloadClick(
|
||||||
|
app.name,
|
||||||
|
app.versions,
|
||||||
|
app.installationOptions
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onAppUninstallClick = {
|
||||||
|
onAppUninstallClick(
|
||||||
|
app.packageName
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onAppLaunchClick = {
|
||||||
|
onAppLaunchClick(
|
||||||
|
app.name,
|
||||||
|
app.packageName,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onAppInfoClick = {
|
||||||
|
showAppInfoDialog = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (showAppInfoDialog) {
|
||||||
|
ManagerDialog(
|
||||||
|
title = managerString(
|
||||||
|
R.string.app_info_title,
|
||||||
|
app.name
|
||||||
|
),
|
||||||
|
onDismissRequest = { showAppInfoDialog = false },
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(onClick = {
|
||||||
|
showAppInfoDialog = false
|
||||||
|
}) {
|
||||||
|
ManagerText(text = managerString(R.string.dialog_button_close))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
ManagerText(
|
||||||
|
modifier = Modifier.padding(top = 4.dp),
|
||||||
|
text = app.changelog,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun HomeScreenLoading(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
appsCount: Int,
|
||||||
|
) {
|
||||||
|
HomeScreenBody(modifier = modifier) {
|
||||||
|
managerCategory(categoryName = {
|
||||||
|
managerString(R.string.home_category_apps)
|
||||||
|
}) {
|
||||||
|
items(appsCount) {
|
||||||
|
AppCardPlaceholder(
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private inline fun HomeScreenBody(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
crossinline appsCategory: LazyListScope.() -> Unit,
|
||||||
|
) {
|
||||||
|
ManagerLazyColumn(modifier = modifier) {
|
||||||
|
appsCategory()
|
||||||
|
managerCategory(categoryName = {
|
||||||
|
managerString(R.string.home_category_support_us)
|
||||||
|
}) {
|
||||||
|
item {
|
||||||
|
ManagerLazyRow(modifier = Modifier.fillMaxWidth()) {
|
||||||
|
items(sponsors) { sponsor ->
|
||||||
|
LinkCard(
|
||||||
|
text = sponsor.title,
|
||||||
|
icon = painterResource(sponsor.icon),
|
||||||
|
url = sponsor.link
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
managerCategory(categoryName = {
|
||||||
|
managerString(R.string.home_category_social_media)
|
||||||
|
}) {
|
||||||
|
item {
|
||||||
|
ManagerLazyRow(modifier = Modifier.fillMaxWidth()) {
|
||||||
|
items(socialMedia) { socialMedia ->
|
||||||
|
LinkCard(
|
||||||
|
text = socialMedia.title,
|
||||||
|
icon = painterResource(socialMedia.icon),
|
||||||
|
url = socialMedia.link
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,13 @@
|
||||||
package com.vanced.manager.ui.screens
|
package com.vanced.manager.ui.screen
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.ArrowDropDown
|
import androidx.compose.material.icons.rounded.ArrowDropDown
|
||||||
import androidx.compose.material.icons.rounded.Done
|
import androidx.compose.material.icons.rounded.Done
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.ExtendedFloatingActionButton
|
import androidx.compose.material3.ExtendedFloatingActionButton
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
@ -24,20 +23,11 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.withStyle
|
import androidx.compose.ui.text.withStyle
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.vanced.manager.R
|
import com.vanced.manager.R
|
||||||
import com.vanced.manager.ui.component.layout.ManagerLazyColumn
|
import com.vanced.manager.ui.component.*
|
||||||
import com.vanced.manager.ui.component.layout.ManagerScaffold
|
import com.vanced.manager.ui.resource.managerString
|
||||||
import com.vanced.manager.ui.component.modifier.managerClickable
|
|
||||||
import com.vanced.manager.ui.component.progressindicator.ManagerProgressIndicator
|
|
||||||
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.util.DefaultContentPaddingHorizontal
|
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
||||||
import com.vanced.manager.ui.viewmodel.InstallViewModel
|
import com.vanced.manager.ui.viewmodel.InstallViewModel
|
||||||
|
|
||||||
@OptIn(
|
|
||||||
ExperimentalFoundationApi::class,
|
|
||||||
ExperimentalMaterial3Api::class
|
|
||||||
)
|
|
||||||
@Composable
|
@Composable
|
||||||
fun InstallScreen(
|
fun InstallScreen(
|
||||||
appName: String,
|
appName: String,
|
||||||
|
@ -62,8 +52,10 @@ fun InstallScreen(
|
||||||
ManagerScaffold(
|
ManagerScaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
Column {
|
Column {
|
||||||
ManagerTopAppBar(
|
ManagerSmallTopAppBar(
|
||||||
title = managerString(R.string.toolbar_install),
|
title = {
|
||||||
|
ManagerText(managerString(R.string.toolbar_install))
|
||||||
|
},
|
||||||
)
|
)
|
||||||
when (status) {
|
when (status) {
|
||||||
is InstallViewModel.Status.Progress -> {
|
is InstallViewModel.Status.Progress -> {
|
||||||
|
@ -127,7 +119,7 @@ fun InstallScreen(
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.managerClickable {
|
.clickable {
|
||||||
visible = !visible
|
visible = !visible
|
||||||
}
|
}
|
||||||
.padding(horizontal = DefaultContentPaddingHorizontal),
|
.padding(horizontal = DefaultContentPaddingHorizontal),
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.vanced.manager.ui.screen
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.rounded.ArrowBackIosNew
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import com.vanced.manager.R
|
||||||
|
import com.vanced.manager.core.util.notificationApps
|
||||||
|
import com.vanced.manager.ui.component.*
|
||||||
|
import com.vanced.manager.ui.resource.managerString
|
||||||
|
import com.vanced.manager.ui.util.Screen
|
||||||
|
import com.vanced.manager.ui.widget.SettingsCustomTabsItem
|
||||||
|
import com.vanced.manager.ui.widget.SettingsManagerVariantItem
|
||||||
|
import com.vanced.manager.ui.widget.SettingsNotificationsItem
|
||||||
|
import com.vanced.manager.ui.widget.ThemeSettingsItem
|
||||||
|
|
||||||
|
@ExperimentalMaterial3Api
|
||||||
|
@Composable
|
||||||
|
fun SettingsScreen(
|
||||||
|
onToolbarBackButtonClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
ManagerScaffold(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
topBar = {
|
||||||
|
ManagerSmallTopAppBar(
|
||||||
|
title = {
|
||||||
|
ManagerText(managerString(Screen.Settings.displayName))
|
||||||
|
},
|
||||||
|
navigationIcon = {
|
||||||
|
IconButton(onClick = onToolbarBackButtonClick) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.ArrowBackIosNew,
|
||||||
|
contentDescription = "Back"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
ManagerLazyColumn(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues),
|
||||||
|
) {
|
||||||
|
managerCategory(categoryName = {
|
||||||
|
managerString(R.string.settings_category_behaviour)
|
||||||
|
}) {
|
||||||
|
item {
|
||||||
|
SettingsCustomTabsItem()
|
||||||
|
}
|
||||||
|
items(notificationApps) { notificationApp ->
|
||||||
|
SettingsNotificationsItem(notificationApp)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
SettingsManagerVariantItem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
managerCategory(categoryName = {
|
||||||
|
managerString(R.string.settings_category_appearance)
|
||||||
|
}) {
|
||||||
|
item {
|
||||||
|
ThemeSettingsItem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,217 +0,0 @@
|
||||||
package com.vanced.manager.ui.screens
|
|
||||||
|
|
||||||
import androidx.compose.animation.*
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.rounded.MoreVert
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.TextButton
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import coil.compose.rememberImagePainter
|
|
||||||
import coil.request.CachePolicy
|
|
||||||
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.core.util.socialMedia
|
|
||||||
import com.vanced.manager.core.util.sponsors
|
|
||||||
import com.vanced.manager.domain.model.InstallationOption
|
|
||||||
import com.vanced.manager.ui.component.card.ManagerLinkCard
|
|
||||||
import com.vanced.manager.ui.component.dialog.ManagerDialog
|
|
||||||
import com.vanced.manager.ui.component.layout.ManagerLazyColumn
|
|
||||||
import com.vanced.manager.ui.component.layout.ManagerScaffold
|
|
||||||
import com.vanced.manager.ui.component.layout.ManagerSwipeRefresh
|
|
||||||
import com.vanced.manager.ui.component.layout.ScrollableItemRow
|
|
||||||
import com.vanced.manager.ui.component.menu.ManagerDropdownMenu
|
|
||||||
import com.vanced.manager.ui.component.menu.ManagerDropdownMenuItem
|
|
||||||
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.util.Screen
|
|
||||||
import com.vanced.manager.ui.viewmodel.MainViewModel
|
|
||||||
import com.vanced.manager.ui.widget.app.AppCard
|
|
||||||
import com.vanced.manager.ui.widget.app.AppCardPlaceholder
|
|
||||||
import com.vanced.manager.ui.widget.layout.managerCategory
|
|
||||||
|
|
||||||
@ExperimentalMaterial3Api
|
|
||||||
@ExperimentalAnimationApi
|
|
||||||
@Composable
|
|
||||||
fun HomeLayout(
|
|
||||||
viewModel: MainViewModel,
|
|
||||||
onToolbarScreenSelected: (Screen) -> Unit,
|
|
||||||
onAppInstallPress: (
|
|
||||||
appName: String,
|
|
||||||
appVersions: List<String>?,
|
|
||||||
installationOptions: List<InstallationOption>?
|
|
||||||
) -> Unit
|
|
||||||
) {
|
|
||||||
val appState = viewModel.appState
|
|
||||||
|
|
||||||
val refreshState =
|
|
||||||
rememberSwipeRefreshState(isRefreshing = appState is MainViewModel.AppState.Fetching)
|
|
||||||
var isMenuExpanded by remember { mutableStateOf(false) }
|
|
||||||
val dropdownScreens = remember { listOf(Screen.Settings, Screen.About) }
|
|
||||||
|
|
||||||
val homeCategoryApps = managerString(R.string.home_category_apps)
|
|
||||||
val homeCategorySupportUs = managerString(R.string.home_category_support_us)
|
|
||||||
val homeCategorySocialMedia = managerString(R.string.home_category_social_media)
|
|
||||||
|
|
||||||
ManagerScaffold(
|
|
||||||
topBar = {
|
|
||||||
ManagerTopAppBar(
|
|
||||||
title = managerString(Screen.Home.displayName),
|
|
||||||
actions = {
|
|
||||||
IconButton(onClick = { isMenuExpanded = true }) {
|
|
||||||
Icon(
|
|
||||||
Icons.Rounded.MoreVert,
|
|
||||||
contentDescription = "Navigation"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
ManagerDropdownMenu(
|
|
||||||
expanded = isMenuExpanded,
|
|
||||||
onDismissRequest = {
|
|
||||||
isMenuExpanded = false
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
for (dropdownScreen in dropdownScreens) {
|
|
||||||
ManagerDropdownMenuItem(
|
|
||||||
title = managerString(dropdownScreen.displayName),
|
|
||||||
onClick = {
|
|
||||||
onToolbarScreenSelected(dropdownScreen)
|
|
||||||
isMenuExpanded = false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { paddingValues ->
|
|
||||||
ManagerSwipeRefresh(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(paddingValues),
|
|
||||||
refreshState = refreshState,
|
|
||||||
onRefresh = { viewModel.fetch() }
|
|
||||||
) {
|
|
||||||
ManagerLazyColumn {
|
|
||||||
managerCategory(homeCategoryApps) {
|
|
||||||
AnimatedContent(
|
|
||||||
targetState = appState,
|
|
||||||
transitionSpec = {
|
|
||||||
scaleIn(initialScale = 0.9f) + fadeIn() with
|
|
||||||
scaleOut(targetScale = 0.9f) + fadeOut()
|
|
||||||
}
|
|
||||||
) { animatedAppState ->
|
|
||||||
Column(
|
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
when (animatedAppState) {
|
|
||||||
is MainViewModel.AppState.Success -> {
|
|
||||||
for (app in animatedAppState.apps) {
|
|
||||||
val appIcon = rememberImagePainter(app.iconUrl) {
|
|
||||||
diskCachePolicy(CachePolicy.ENABLED)
|
|
||||||
}
|
|
||||||
|
|
||||||
var showAppInfoDialog by rememberSaveable {
|
|
||||||
mutableStateOf(
|
|
||||||
false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
AppCard(
|
|
||||||
appName = app.name,
|
|
||||||
appIcon = appIcon,
|
|
||||||
appInstalledVersion = app.installedVersion,
|
|
||||||
appRemoteVersion = app.remoteVersion,
|
|
||||||
onAppDownloadClick = {
|
|
||||||
onAppInstallPress(
|
|
||||||
app.name,
|
|
||||||
app.versions,
|
|
||||||
app.installationOptions
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onAppUninstallClick = {
|
|
||||||
viewModel.uninstallApp(
|
|
||||||
appPackage = app.packageName
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onAppLaunchClick = {
|
|
||||||
viewModel.launchApp(
|
|
||||||
appName = app.name,
|
|
||||||
appPackage = app.packageName,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onAppInfoClick = {
|
|
||||||
showAppInfoDialog = true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (showAppInfoDialog) {
|
|
||||||
ManagerDialog(
|
|
||||||
title = managerString(
|
|
||||||
R.string.app_info_title,
|
|
||||||
app.name
|
|
||||||
),
|
|
||||||
onDismissRequest = { showAppInfoDialog = false },
|
|
||||||
confirmButton = {
|
|
||||||
TextButton(onClick = {
|
|
||||||
showAppInfoDialog = false
|
|
||||||
}) {
|
|
||||||
ManagerText(text = managerString(R.string.dialog_button_close))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
ManagerText(
|
|
||||||
modifier = Modifier.padding(top = 4.dp),
|
|
||||||
text = app.changelog,
|
|
||||||
//textStyle = MaterialTheme.typography.bodyMedium
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is MainViewModel.AppState.Fetching -> {
|
|
||||||
for (i in 0 until animatedAppState.placeholderAppsCount) {
|
|
||||||
AppCardPlaceholder()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is MainViewModel.AppState.Error -> {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
managerCategory(homeCategorySupportUs) {
|
|
||||||
ScrollableItemRow(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
items = sponsors
|
|
||||||
) { sponsor ->
|
|
||||||
ManagerLinkCard(
|
|
||||||
icon = sponsor.icon,
|
|
||||||
title = sponsor.title,
|
|
||||||
link = sponsor.link
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
managerCategory(homeCategorySocialMedia) {
|
|
||||||
ScrollableItemRow(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
items = socialMedia
|
|
||||||
) { socialMedia ->
|
|
||||||
ManagerLinkCard(
|
|
||||||
icon = socialMedia.icon,
|
|
||||||
title = socialMedia.title,
|
|
||||||
link = socialMedia.link
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
package com.vanced.manager.ui.screens
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.rounded.ArrowBackIosNew
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.ui.component.layout.ManagerLazyColumn
|
|
||||||
import com.vanced.manager.ui.component.topappbar.ManagerTopAppBar
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
import com.vanced.manager.ui.util.Screen
|
|
||||||
import com.vanced.manager.ui.widget.layout.managerCategory
|
|
||||||
import com.vanced.manager.ui.widget.settings.*
|
|
||||||
|
|
||||||
@ExperimentalMaterial3Api
|
|
||||||
@Composable
|
|
||||||
fun SettingsLayout(
|
|
||||||
onToolbarBackButtonClick: () -> Unit,
|
|
||||||
) {
|
|
||||||
val settingsCategoryBehaviour = managerString(R.string.settings_category_behaviour)
|
|
||||||
val settingsCategoryApperance = managerString(R.string.settings_category_appearance)
|
|
||||||
|
|
||||||
Scaffold(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
topBar = {
|
|
||||||
ManagerTopAppBar(
|
|
||||||
title = managerString(Screen.Settings.displayName),
|
|
||||||
navigationIcon = {
|
|
||||||
IconButton(onClick = onToolbarBackButtonClick) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.ArrowBackIosNew,
|
|
||||||
contentDescription = "Back"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { paddingValues ->
|
|
||||||
ManagerLazyColumn(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(paddingValues),
|
|
||||||
) {
|
|
||||||
managerCategory(settingsCategoryBehaviour) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
SettingsCustomTabsItem()
|
|
||||||
SettingsNotificationsItem()
|
|
||||||
SettingsManagerVariantItem()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
managerCategory(settingsCategoryApperance) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
SettingsAccentColorItem()
|
|
||||||
ThemeSettingsItem()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +1,9 @@
|
||||||
package com.vanced.manager.ui.theme
|
package com.vanced.manager.ui.theme
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import androidx.compose.foundation.LocalIndication
|
|
||||||
import androidx.compose.foundation.gestures.LocalOverScrollConfiguration
|
import androidx.compose.foundation.gestures.LocalOverScrollConfiguration
|
||||||
import androidx.compose.foundation.gestures.OverScrollConfiguration
|
import androidx.compose.foundation.gestures.OverScrollConfiguration
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
@ -79,38 +75,42 @@ fun isDark(): Boolean = when (managerThemePref) {
|
||||||
else -> throw IllegalArgumentException("Unknown theme")
|
else -> throw IllegalArgumentException("Unknown theme")
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@Composable
|
||||||
@ExperimentalFoundationApi
|
inline fun apiDependantColorScheme(
|
||||||
|
dynamic: () -> ColorScheme,
|
||||||
|
static: () -> ColorScheme
|
||||||
|
): ColorScheme {
|
||||||
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
dynamic()
|
||||||
|
} else {
|
||||||
|
static()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerTheme(
|
fun ManagerTheme(
|
||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val isAndroid12OrHigher = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
val context = LocalContext.current
|
||||||
val colorScheme =
|
val colorScheme =
|
||||||
if (isAndroid12OrHigher) {
|
if (isDark()) {
|
||||||
val context = LocalContext.current
|
apiDependantColorScheme(
|
||||||
if (isDark()) {
|
dynamic = { dynamicDarkColorScheme(context) },
|
||||||
dynamicDarkColorScheme(context)
|
static = { DarkThemeColors }
|
||||||
} else {
|
)
|
||||||
dynamicLightColorScheme(context)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (isDark()) {
|
apiDependantColorScheme(
|
||||||
DarkThemeColors
|
dynamic = { dynamicLightColorScheme(context)},
|
||||||
} else {
|
static = { LightThemeColors }
|
||||||
LightThemeColors
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colorScheme = colorScheme,
|
colorScheme = colorScheme,
|
||||||
typography = ManagerTypography,
|
typography = ManagerTypography,
|
||||||
) {
|
) {
|
||||||
val rippleIndication = rememberRipple()
|
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalIndication provides rippleIndication,
|
|
||||||
LocalOverScrollConfiguration provides OverScrollConfiguration(
|
LocalOverScrollConfiguration provides OverScrollConfiguration(
|
||||||
forceShowAlways = isAndroid12OrHigher
|
forceShowAlways = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
content()
|
content()
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.vanced.manager.ui.util
|
||||||
|
|
||||||
|
import androidx.compose.animation.animateColorAsState
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
val Color.animated
|
||||||
|
@Composable
|
||||||
|
get() = animateColorAsState(this, animationSpec = tween(400)).value
|
|
@ -3,4 +3,6 @@ package com.vanced.manager.ui.util
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
val DefaultContentPaddingHorizontal = 16.dp
|
val DefaultContentPaddingHorizontal = 16.dp
|
||||||
val DefaultContentPaddingVertical = 12.dp
|
val DefaultContentPaddingVertical = 12.dp
|
||||||
|
|
||||||
|
val EdgeToEdgeContentPadding = 8.dp
|
|
@ -36,6 +36,10 @@ class MainViewModel(
|
||||||
data class Fetching(val placeholderAppsCount: Int) : AppState()
|
data class Fetching(val placeholderAppsCount: Int) : AppState()
|
||||||
data class Success(val apps: List<App>) : AppState()
|
data class Success(val apps: List<App>) : AppState()
|
||||||
data class Error(val error: String) : AppState()
|
data class Error(val error: String) : AppState()
|
||||||
|
|
||||||
|
val isFetching get() = this is Fetching
|
||||||
|
val isSuccess get() = this is Success
|
||||||
|
val isError get() = this is Error
|
||||||
}
|
}
|
||||||
|
|
||||||
var appState by mutableStateOf<AppState>(AppState.Fetching(appCount))
|
var appState by mutableStateOf<AppState>(AppState.Fetching(appCount))
|
||||||
|
|
|
@ -0,0 +1,257 @@
|
||||||
|
package com.vanced.manager.ui.widget
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.Info
|
||||||
|
import androidx.compose.material.icons.rounded.DeleteForever
|
||||||
|
import androidx.compose.material.icons.rounded.Download
|
||||||
|
import androidx.compose.material.icons.rounded.Launch
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.composed
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.Shape
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import coil.compose.ImagePainter
|
||||||
|
import com.google.accompanist.placeholder.PlaceholderHighlight
|
||||||
|
import com.google.accompanist.placeholder.placeholder
|
||||||
|
import com.google.accompanist.placeholder.shimmer
|
||||||
|
import com.vanced.manager.R
|
||||||
|
import com.vanced.manager.ui.component.ManagerElevatedCard
|
||||||
|
import com.vanced.manager.ui.component.ManagerListItem
|
||||||
|
import com.vanced.manager.ui.component.ManagerText
|
||||||
|
import com.vanced.manager.ui.theme.LargeShape
|
||||||
|
import com.vanced.manager.ui.theme.MediumShape
|
||||||
|
import com.vanced.manager.ui.theme.SmallShape
|
||||||
|
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
||||||
|
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AppCard(
|
||||||
|
appName: String,
|
||||||
|
appIcon: ImagePainter,
|
||||||
|
appInstalledVersion: String?,
|
||||||
|
appRemoteVersion: String?,
|
||||||
|
onAppDownloadClick: () -> Unit,
|
||||||
|
onAppUninstallClick: () -> Unit,
|
||||||
|
onAppLaunchClick: () -> Unit,
|
||||||
|
onAppInfoClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
BaseAppCard(
|
||||||
|
modifier = modifier,
|
||||||
|
appTitle = {
|
||||||
|
ManagerText(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
text = appName,
|
||||||
|
textStyle = MaterialTheme.typography.titleMedium
|
||||||
|
)
|
||||||
|
},
|
||||||
|
appIcon = {
|
||||||
|
Image(
|
||||||
|
modifier = Modifier.size(48.dp),
|
||||||
|
painter = appIcon,
|
||||||
|
contentDescription = "App Icon",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
appTrailing = {
|
||||||
|
IconButton(onClick = onAppInfoClick) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Info,
|
||||||
|
contentDescription = "App Info"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
appVersionsColumn = {
|
||||||
|
ManagerText(
|
||||||
|
text = stringResource(
|
||||||
|
id = R.string.app_version_latest,
|
||||||
|
appRemoteVersion ?: stringResource(
|
||||||
|
id = R.string.app_content_unavailable
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
ManagerText(
|
||||||
|
text = stringResource(
|
||||||
|
id = R.string.app_version_installed,
|
||||||
|
appInstalledVersion ?: stringResource(
|
||||||
|
id = R.string.app_content_unavailable
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
appActionsRow = {
|
||||||
|
if (appInstalledVersion != null) {
|
||||||
|
IconButton(onClick = onAppUninstallClick) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.DeleteForever,
|
||||||
|
contentDescription = "Uninstall"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
IconButton(onClick = onAppLaunchClick) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.Launch,
|
||||||
|
contentDescription = "Launch",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconButton(onClick = onAppDownloadClick) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.Download,
|
||||||
|
contentDescription = "Install",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AppCardPlaceholder(
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
BaseAppCard(
|
||||||
|
modifier = modifier,
|
||||||
|
appTitle = {
|
||||||
|
ManagerText(
|
||||||
|
modifier = Modifier
|
||||||
|
.managerPlaceholder(
|
||||||
|
visible = true,
|
||||||
|
shape = MediumShape
|
||||||
|
),
|
||||||
|
text = " ".repeat(40),
|
||||||
|
textStyle = MaterialTheme.typography.titleMedium
|
||||||
|
)
|
||||||
|
},
|
||||||
|
appIcon = {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.managerPlaceholder(
|
||||||
|
visible = true,
|
||||||
|
shape = RoundedCornerShape(24.dp)
|
||||||
|
)
|
||||||
|
.size(48.dp)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
appTrailing = {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.managerPlaceholder(
|
||||||
|
visible = true,
|
||||||
|
shape = MediumShape
|
||||||
|
)
|
||||||
|
.size(24.dp)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
appVersionsColumn = {
|
||||||
|
ManagerText(
|
||||||
|
modifier = Modifier
|
||||||
|
.managerPlaceholder(
|
||||||
|
visible = true,
|
||||||
|
shape = SmallShape
|
||||||
|
),
|
||||||
|
text = " ".repeat(30)
|
||||||
|
)
|
||||||
|
ManagerText(
|
||||||
|
modifier = Modifier
|
||||||
|
.managerPlaceholder(
|
||||||
|
visible = true,
|
||||||
|
shape = SmallShape
|
||||||
|
),
|
||||||
|
text = " ".repeat(30)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
appActionsRow = {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(0.8f)
|
||||||
|
.height(36.dp)
|
||||||
|
.managerPlaceholder(
|
||||||
|
visible = true,
|
||||||
|
shape = MediumShape
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun BaseAppCard(
|
||||||
|
appTitle: @Composable () -> Unit,
|
||||||
|
appIcon: @Composable () -> Unit,
|
||||||
|
appTrailing: @Composable () -> Unit,
|
||||||
|
appVersionsColumn: @Composable ColumnScope.() -> Unit,
|
||||||
|
appActionsRow: @Composable RowScope.() -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
ManagerElevatedCard(
|
||||||
|
modifier = modifier,
|
||||||
|
shape = LargeShape,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(
|
||||||
|
horizontal = DefaultContentPaddingHorizontal,
|
||||||
|
vertical = DefaultContentPaddingVertical
|
||||||
|
),
|
||||||
|
verticalArrangement = Arrangement
|
||||||
|
.spacedBy(DefaultContentPaddingVertical)
|
||||||
|
) {
|
||||||
|
ManagerListItem(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
title = appTitle,
|
||||||
|
icon = appIcon,
|
||||||
|
trailing = appTrailing
|
||||||
|
)
|
||||||
|
Divider(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(LargeShape),
|
||||||
|
thickness = 2.dp,
|
||||||
|
)
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
|
horizontalAlignment = Alignment.Start
|
||||||
|
) {
|
||||||
|
ManagerText(
|
||||||
|
text = stringResource(id = R.string.app_versions),
|
||||||
|
textStyle = MaterialTheme.typography.bodyMedium
|
||||||
|
)
|
||||||
|
ProvideTextStyle(value = MaterialTheme.typography.bodySmall) {
|
||||||
|
appVersionsColumn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.wrapContentWidth(),
|
||||||
|
content = appActionsRow,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.End
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Modifier.managerPlaceholder(
|
||||||
|
visible: Boolean,
|
||||||
|
shape: Shape
|
||||||
|
) = composed {
|
||||||
|
placeholder(
|
||||||
|
visible = visible,
|
||||||
|
shape = shape,
|
||||||
|
color = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
highlight = PlaceholderHighlight.shimmer(
|
||||||
|
highlightColor = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.vanced.manager.ui.widget
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.browser.customtabs.CustomTabsIntent
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.vanced.manager.core.preferences.holder.useCustomTabsPref
|
||||||
|
import com.vanced.manager.ui.component.ManagerElevatedCard
|
||||||
|
import com.vanced.manager.ui.component.ManagerText
|
||||||
|
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
||||||
|
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
||||||
|
|
||||||
|
//TODO this composable should not handle opening links
|
||||||
|
@Composable
|
||||||
|
fun LinkCard(
|
||||||
|
text: String,
|
||||||
|
icon: Painter,
|
||||||
|
url: String,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val customTabs = remember { CustomTabsIntent.Builder().build() }
|
||||||
|
val uri = remember { Uri.parse(url) }
|
||||||
|
val intent = remember { Intent(Intent.ACTION_VIEW, uri) }
|
||||||
|
ManagerElevatedCard(
|
||||||
|
modifier = modifier
|
||||||
|
.height(100.dp)
|
||||||
|
.widthIn(min = 100.dp),
|
||||||
|
onClick = {
|
||||||
|
if (useCustomTabsPref) {
|
||||||
|
customTabs.launchUrl(context, uri)
|
||||||
|
} else {
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(
|
||||||
|
horizontal = DefaultContentPaddingHorizontal,
|
||||||
|
vertical = DefaultContentPaddingVertical
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(32.dp)
|
||||||
|
.align(Alignment.TopStart),
|
||||||
|
painter = icon,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
ManagerText(
|
||||||
|
modifier = Modifier.align(Alignment.BottomStart),
|
||||||
|
text = text,
|
||||||
|
textStyle = MaterialTheme.typography.labelLarge
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,138 @@
|
||||||
|
package com.vanced.manager.ui.widget
|
||||||
|
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import com.vanced.manager.R
|
||||||
|
import com.vanced.manager.core.preferences.RadioButtonPreference
|
||||||
|
import com.vanced.manager.core.preferences.holder.managerThemePref
|
||||||
|
import com.vanced.manager.core.preferences.holder.managerVariantPref
|
||||||
|
import com.vanced.manager.core.preferences.holder.useCustomTabsPref
|
||||||
|
import com.vanced.manager.core.preferences.managerBooleanPreference
|
||||||
|
import com.vanced.manager.core.util.isMagiskInstalled
|
||||||
|
import com.vanced.manager.domain.model.NotificationPrefModel
|
||||||
|
import com.vanced.manager.ui.component.ManagerPreference
|
||||||
|
import com.vanced.manager.ui.component.ManagerSingleSelectDialogPreference
|
||||||
|
import com.vanced.manager.ui.component.ManagerSwitchPreference
|
||||||
|
import com.vanced.manager.ui.resource.managerString
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SettingsClearFilesItem() {
|
||||||
|
ManagerPreference(
|
||||||
|
preferenceTitle = managerString(
|
||||||
|
stringId = R.string.settings_preference_clear_files_title
|
||||||
|
),
|
||||||
|
preferenceDescription = null,
|
||||||
|
onClick = {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SettingsCustomTabsItem() {
|
||||||
|
ManagerSwitchPreference(
|
||||||
|
preferenceTitle = stringResource(id = R.string.settings_preference_use_custom_tabs_title),
|
||||||
|
preferenceDescription = stringResource(id = R.string.settings_preference_use_custom_tabs_summary),
|
||||||
|
isChecked = useCustomTabsPref,
|
||||||
|
onCheckedChange = {
|
||||||
|
useCustomTabsPref = it
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SettingsManagerVariantItem() {
|
||||||
|
var showDialog by remember { mutableStateOf(false) }
|
||||||
|
var selectedKey by remember { mutableStateOf(managerVariantPref) }
|
||||||
|
ManagerSingleSelectDialogPreference(
|
||||||
|
preferenceTitle = managerString(
|
||||||
|
stringId = R.string.settings_preference_variant_title
|
||||||
|
),
|
||||||
|
preferenceDescription = managerVariantPref,
|
||||||
|
isDialogVisible = showDialog,
|
||||||
|
currentSelectedKey = selectedKey,
|
||||||
|
buttons = listOf(
|
||||||
|
RadioButtonPreference(
|
||||||
|
title = "nonroot",
|
||||||
|
key = "nonroot"
|
||||||
|
),
|
||||||
|
RadioButtonPreference(
|
||||||
|
title = "root",
|
||||||
|
key = "root"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPreferenceClick = {
|
||||||
|
showDialog = true
|
||||||
|
},
|
||||||
|
onDismissRequest = {
|
||||||
|
showDialog = false
|
||||||
|
selectedKey = managerVariantPref
|
||||||
|
},
|
||||||
|
onItemClick = {
|
||||||
|
if (it == "root" && !isMagiskInstalled)
|
||||||
|
return@ManagerSingleSelectDialogPreference
|
||||||
|
|
||||||
|
selectedKey = it
|
||||||
|
},
|
||||||
|
onSave = {
|
||||||
|
managerVariantPref = selectedKey
|
||||||
|
showDialog = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SettingsNotificationsItem(notificationApp: NotificationPrefModel) {
|
||||||
|
with(notificationApp) {
|
||||||
|
var appNotificationsPref by managerBooleanPreference(
|
||||||
|
key = "${prefKey}_notifications",
|
||||||
|
defaultValue = true
|
||||||
|
)
|
||||||
|
ManagerSwitchPreference(
|
||||||
|
preferenceTitle = "$app Push Notifications",
|
||||||
|
preferenceDescription = "Receive push notifications when an update for $app is released",
|
||||||
|
isChecked = appNotificationsPref,
|
||||||
|
onCheckedChange = {
|
||||||
|
appNotificationsPref = it
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ThemeSettingsItem() {
|
||||||
|
var showDialog by remember { mutableStateOf(false) }
|
||||||
|
var selectedKey by remember { mutableStateOf(managerThemePref) }
|
||||||
|
ManagerSingleSelectDialogPreference(
|
||||||
|
preferenceTitle = managerString(stringId = R.string.settings_preference_theme_title),
|
||||||
|
preferenceDescription = managerThemePref,
|
||||||
|
isDialogVisible = showDialog,
|
||||||
|
currentSelectedKey = selectedKey,
|
||||||
|
buttons = listOf(
|
||||||
|
RadioButtonPreference(
|
||||||
|
title = managerString(R.string.settings_preference_theme_light),
|
||||||
|
key = "Light"
|
||||||
|
),
|
||||||
|
RadioButtonPreference(
|
||||||
|
title = managerString(R.string.settings_preference_theme_dark),
|
||||||
|
key = "Dark"
|
||||||
|
),
|
||||||
|
RadioButtonPreference(
|
||||||
|
title = managerString(R.string.settings_option_system_default),
|
||||||
|
key = "System Default"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
onPreferenceClick = {
|
||||||
|
showDialog = true
|
||||||
|
},
|
||||||
|
onDismissRequest = {
|
||||||
|
showDialog = false
|
||||||
|
selectedKey = managerThemePref
|
||||||
|
},
|
||||||
|
onItemClick = {
|
||||||
|
selectedKey = it
|
||||||
|
},
|
||||||
|
onSave = {
|
||||||
|
managerThemePref = selectedKey
|
||||||
|
showDialog = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,100 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.app
|
|
||||||
|
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.outlined.Info
|
|
||||||
import androidx.compose.material.icons.rounded.DeleteForever
|
|
||||||
import androidx.compose.material.icons.rounded.Download
|
|
||||||
import androidx.compose.material.icons.rounded.Launch
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import coil.compose.ImagePainter
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.ui.component.text.AppVersionText
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
|
|
||||||
@OptIn(ExperimentalAnimationApi::class)
|
|
||||||
@Composable
|
|
||||||
fun AppCard(
|
|
||||||
appName: String,
|
|
||||||
appIcon: ImagePainter,
|
|
||||||
appInstalledVersion: String?,
|
|
||||||
appRemoteVersion: String?,
|
|
||||||
onAppDownloadClick: () -> Unit,
|
|
||||||
onAppUninstallClick: () -> Unit,
|
|
||||||
onAppLaunchClick: () -> Unit,
|
|
||||||
onAppInfoClick: () -> Unit,
|
|
||||||
) {
|
|
||||||
BaseAppCard(
|
|
||||||
appTitle = {
|
|
||||||
ManagerText(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
text = appName,
|
|
||||||
textStyle = MaterialTheme.typography.titleMedium
|
|
||||||
)
|
|
||||||
},
|
|
||||||
appIcon = {
|
|
||||||
Image(
|
|
||||||
modifier = Modifier.size(48.dp),
|
|
||||||
painter = appIcon,
|
|
||||||
contentDescription = "App Icon",
|
|
||||||
)
|
|
||||||
},
|
|
||||||
appTrailing = {
|
|
||||||
IconButton(onClick = onAppInfoClick) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Outlined.Info,
|
|
||||||
contentDescription = "App Info"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
appVersionsColumn = {
|
|
||||||
AppVersionText(
|
|
||||||
text = stringResource(
|
|
||||||
id = R.string.app_version_latest,
|
|
||||||
appRemoteVersion ?: stringResource(
|
|
||||||
id = R.string.app_content_unavailable
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
AppVersionText(
|
|
||||||
text = stringResource(
|
|
||||||
id = R.string.app_version_installed,
|
|
||||||
appInstalledVersion ?: stringResource(
|
|
||||||
id = R.string.app_content_unavailable
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
appActionsRow = {
|
|
||||||
if (appInstalledVersion != null) {
|
|
||||||
IconButton(onClick = onAppUninstallClick) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.DeleteForever,
|
|
||||||
contentDescription = "Uninstall"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
IconButton(onClick = onAppLaunchClick) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.Launch,
|
|
||||||
contentDescription = "Launch",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IconButton(onClick = onAppDownloadClick) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.Download,
|
|
||||||
contentDescription = "Install",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.app
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.ui.component.modifier.managerPlaceholder
|
|
||||||
import com.vanced.manager.ui.component.text.AppVersionText
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
import com.vanced.manager.ui.theme.SmallShape
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun AppCardPlaceholder() {
|
|
||||||
BaseAppCard(
|
|
||||||
appTitle = {
|
|
||||||
ManagerText(
|
|
||||||
modifier = Modifier
|
|
||||||
.clip(MediumShape)
|
|
||||||
.managerPlaceholder(true),
|
|
||||||
text = " ".repeat(40),
|
|
||||||
textStyle = MaterialTheme.typography.titleMedium
|
|
||||||
)
|
|
||||||
},
|
|
||||||
appIcon = {
|
|
||||||
Box(
|
|
||||||
Modifier
|
|
||||||
.clip(MediumShape)
|
|
||||||
.managerPlaceholder(true)
|
|
||||||
.size(48.dp)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
appTrailing = {
|
|
||||||
Box(
|
|
||||||
Modifier
|
|
||||||
.clip(CircleShape)
|
|
||||||
.managerPlaceholder(true)
|
|
||||||
.size(24.dp)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
appVersionsColumn = {
|
|
||||||
AppVersionText(
|
|
||||||
modifier = Modifier
|
|
||||||
.managerPlaceholder(true)
|
|
||||||
.clip(SmallShape),
|
|
||||||
text = " ".repeat(30)
|
|
||||||
)
|
|
||||||
AppVersionText(
|
|
||||||
modifier = Modifier
|
|
||||||
.managerPlaceholder(true)
|
|
||||||
.clip(SmallShape),
|
|
||||||
text = " ".repeat(30)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
appActionsRow = {
|
|
||||||
Box(
|
|
||||||
Modifier
|
|
||||||
.clip(MediumShape)
|
|
||||||
.fillMaxWidth(0.8f)
|
|
||||||
.height(36.dp)
|
|
||||||
.managerPlaceholder(true)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.app
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.material.Divider
|
|
||||||
import androidx.compose.material3.LocalContentColor
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.ui.component.card.ManagerTonalCard
|
|
||||||
import com.vanced.manager.ui.component.list.ManagerListItem
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
import com.vanced.manager.ui.theme.LargeShape
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun BaseAppCard(
|
|
||||||
appTitle: @Composable () -> Unit,
|
|
||||||
appIcon: @Composable () -> Unit,
|
|
||||||
appTrailing: @Composable () -> Unit,
|
|
||||||
appVersionsColumn: @Composable ColumnScope.() -> Unit,
|
|
||||||
appActionsRow: @Composable RowScope.() -> Unit,
|
|
||||||
) {
|
|
||||||
ManagerTonalCard(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
shape = LargeShape,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(
|
|
||||||
horizontal = DefaultContentPaddingHorizontal,
|
|
||||||
vertical = DefaultContentPaddingVertical
|
|
||||||
),
|
|
||||||
verticalArrangement = Arrangement
|
|
||||||
.spacedBy(DefaultContentPaddingVertical)
|
|
||||||
) {
|
|
||||||
ManagerListItem(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
title = appTitle,
|
|
||||||
icon = appIcon,
|
|
||||||
trailing = appTrailing
|
|
||||||
)
|
|
||||||
Divider(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.clip(MediumShape),
|
|
||||||
thickness = 2.dp,
|
|
||||||
color = LocalContentColor.current.copy(alpha = 0.12f)
|
|
||||||
)
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.wrapContentWidth(),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
|
||||||
horizontalAlignment = Alignment.Start
|
|
||||||
) {
|
|
||||||
ManagerText(
|
|
||||||
text = stringResource(id = R.string.app_versions),
|
|
||||||
textStyle = MaterialTheme.typography.bodyMedium
|
|
||||||
)
|
|
||||||
appVersionsColumn()
|
|
||||||
}
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.wrapContentWidth(),
|
|
||||||
content = appActionsRow,
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.End
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.button
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.ui.component.button.ManagerThemedTextButton
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerCancelButton(
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
ManagerThemedTextButton(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = managerString(
|
|
||||||
stringId = R.string.dialog_button_cancel
|
|
||||||
),
|
|
||||||
onClick = onClick
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.button
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.ui.component.button.ManagerThemedTextButton
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerCloseButton(
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
ManagerThemedTextButton(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = managerString(
|
|
||||||
stringId = R.string.dialog_button_close
|
|
||||||
),
|
|
||||||
onClick = onClick
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.button
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.ui.component.button.ManagerThemedTextButton
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerDownloadButton(
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
ManagerThemedTextButton(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = managerString(
|
|
||||||
stringId = R.string.app_download_dialog_confirm
|
|
||||||
),
|
|
||||||
onClick = onClick
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.button
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.ui.component.button.ManagerThemedTextButton
|
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerResetButton(
|
|
||||||
backgroundColor: Color = managerAccentColor(),
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
ManagerThemedTextButton(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = managerString(
|
|
||||||
stringId = R.string.dialog_button_reset
|
|
||||||
),
|
|
||||||
backgroundColor = backgroundColor,
|
|
||||||
onClick = onClick
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.button
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.ui.component.button.ManagerThemedTextButton
|
|
||||||
import com.vanced.manager.ui.component.color.managerAccentColor
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerSaveButton(
|
|
||||||
backgroundColor: Color = managerAccentColor(),
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
ManagerThemedTextButton(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = managerString(
|
|
||||||
stringId = R.string.dialog_button_save
|
|
||||||
),
|
|
||||||
backgroundColor = backgroundColor,
|
|
||||||
onClick = onClick
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.checkbox
|
|
||||||
|
|
||||||
import androidx.compose.animation.core.updateTransition
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Shape
|
|
||||||
import androidx.compose.ui.unit.Dp
|
|
||||||
import com.vanced.manager.ui.component.animation.jumpAnimation
|
|
||||||
import com.vanced.manager.ui.component.checkbox.ManagerCheckbox
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerAnimatedCheckbox(
|
|
||||||
size: Dp,
|
|
||||||
isChecked: Boolean,
|
|
||||||
shape: Shape = MediumShape,
|
|
||||||
onCheckedChange: (isChecked: Boolean) -> Unit,
|
|
||||||
) {
|
|
||||||
val transition = updateTransition(
|
|
||||||
targetState = isChecked,
|
|
||||||
label = "Checkbox Animation"
|
|
||||||
)
|
|
||||||
val animatedSize by transition.jumpAnimation(
|
|
||||||
initialValue = size,
|
|
||||||
label = "Checkbox Size"
|
|
||||||
)
|
|
||||||
ManagerCheckbox(
|
|
||||||
modifier = Modifier.size(animatedSize),
|
|
||||||
isChecked = isChecked,
|
|
||||||
shape = shape,
|
|
||||||
onCheckedChange = onCheckedChange
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.layout
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.LazyItemScope
|
|
||||||
import androidx.compose.foundation.lazy.LazyListScope
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.vanced.manager.ui.component.color.managerAnimatedColor
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
|
|
||||||
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun CategoryLayout(
|
|
||||||
categoryName: String,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
content: @Composable ColumnScope.() -> Unit,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier,
|
|
||||||
verticalArrangement = Arrangement.spacedBy(DefaultContentPaddingVertical)
|
|
||||||
) {
|
|
||||||
ManagerText(
|
|
||||||
modifier = Modifier.padding(start = DefaultContentPaddingHorizontal),
|
|
||||||
text = categoryName,
|
|
||||||
textStyle = MaterialTheme.typography.headlineSmall,
|
|
||||||
color = managerAnimatedColor(MaterialTheme.colorScheme.onSurface)
|
|
||||||
)
|
|
||||||
content()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> LazyListScope.managerCategory(
|
|
||||||
categoryName: String,
|
|
||||||
items: List<T>,
|
|
||||||
itemContent: @Composable (T) -> Unit
|
|
||||||
) {
|
|
||||||
item {
|
|
||||||
ManagerText(
|
|
||||||
modifier = Modifier.padding(
|
|
||||||
horizontal = DefaultContentPaddingHorizontal,
|
|
||||||
vertical = DefaultContentPaddingVertical
|
|
||||||
),
|
|
||||||
text = categoryName,
|
|
||||||
textStyle = MaterialTheme.typography.headlineSmall,
|
|
||||||
color = managerAnimatedColor(MaterialTheme.colorScheme.onSurface)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
items(items) { item ->
|
|
||||||
itemContent(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun LazyListScope.managerCategory(
|
|
||||||
categoryName: String,
|
|
||||||
content: @Composable LazyItemScope.() -> Unit,
|
|
||||||
) {
|
|
||||||
item {
|
|
||||||
ManagerText(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(
|
|
||||||
horizontal = DefaultContentPaddingHorizontal,
|
|
||||||
vertical = DefaultContentPaddingVertical
|
|
||||||
),
|
|
||||||
text = categoryName,
|
|
||||||
textStyle = MaterialTheme.typography.headlineSmall,
|
|
||||||
color = managerAnimatedColor(MaterialTheme.colorScheme.onSurface)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
item(content = content)
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.layout
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SettingsCategoryLayout(
|
|
||||||
categoryName: String,
|
|
||||||
content: @Composable () -> Unit
|
|
||||||
) {
|
|
||||||
CategoryLayout(
|
|
||||||
categoryName = categoryName,
|
|
||||||
) {
|
|
||||||
Column {
|
|
||||||
content()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.list
|
|
||||||
|
|
||||||
import androidx.compose.material3.Checkbox
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.vanced.manager.ui.component.color.managerTextColor
|
|
||||||
import com.vanced.manager.ui.component.list.ManagerSelectableListItem
|
|
||||||
import com.vanced.manager.ui.component.modifier.managerClickable
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun CheckboxItem(
|
|
||||||
text: String,
|
|
||||||
checked: Boolean,
|
|
||||||
onCheckedChange: (Boolean) -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
ManagerSelectableListItem(
|
|
||||||
modifier = modifier
|
|
||||||
.managerClickable(onClick = {
|
|
||||||
onCheckedChange(!checked)
|
|
||||||
}),
|
|
||||||
title = {
|
|
||||||
ManagerText(
|
|
||||||
text = text,
|
|
||||||
color = managerTextColor(),
|
|
||||||
textStyle = MaterialTheme.typography.titleSmall
|
|
||||||
)
|
|
||||||
},
|
|
||||||
trailing = {
|
|
||||||
Checkbox(
|
|
||||||
checked = checked,
|
|
||||||
onCheckedChange = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.list
|
|
||||||
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.RadioButton
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.vanced.manager.ui.component.color.managerTextColor
|
|
||||||
import com.vanced.manager.ui.component.list.ManagerSelectableListItem
|
|
||||||
import com.vanced.manager.ui.component.modifier.managerClickable
|
|
||||||
import com.vanced.manager.ui.component.text.ManagerText
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun RadiobuttonItem(
|
|
||||||
text: String,
|
|
||||||
selected: Boolean,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier
|
|
||||||
) {
|
|
||||||
ManagerSelectableListItem(
|
|
||||||
modifier = modifier
|
|
||||||
.managerClickable(onClick = onClick),
|
|
||||||
title = {
|
|
||||||
ManagerText(
|
|
||||||
text = text,
|
|
||||||
color = managerTextColor(),
|
|
||||||
textStyle = MaterialTheme.typography.titleSmall
|
|
||||||
)
|
|
||||||
},
|
|
||||||
trailing = {
|
|
||||||
RadioButton(
|
|
||||||
selected = selected,
|
|
||||||
onClick = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.radiobutton
|
|
||||||
|
|
||||||
import androidx.compose.animation.core.updateTransition
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Shape
|
|
||||||
import androidx.compose.ui.unit.Dp
|
|
||||||
import com.vanced.manager.ui.component.animation.jumpAnimation
|
|
||||||
import com.vanced.manager.ui.component.radiobutton.ManagerRadiobutton
|
|
||||||
import com.vanced.manager.ui.theme.MediumShape
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ManagerAnimatedRadiobutton(
|
|
||||||
size: Dp,
|
|
||||||
isSelected: Boolean,
|
|
||||||
shape: Shape = MediumShape,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
val transition = updateTransition(
|
|
||||||
targetState = isSelected,
|
|
||||||
label = "Radiobutton Animation"
|
|
||||||
)
|
|
||||||
val animatedSize by transition.jumpAnimation(
|
|
||||||
initialValue = size,
|
|
||||||
label = "Checkbox Size"
|
|
||||||
)
|
|
||||||
ManagerRadiobutton(
|
|
||||||
modifier = Modifier.size(animatedSize),
|
|
||||||
isSelected = isSelected,
|
|
||||||
shape = shape,
|
|
||||||
onClick = onClick
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.settings
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SettingsAccentColorItem() {
|
|
||||||
// var localAccentColor by remember { mutableStateOf(managerAccentColorPref.value.value) }
|
|
||||||
// DialogPreference(
|
|
||||||
// preferenceTitle = managerString(
|
|
||||||
// stringId = R.string.settings_preference_accent_color_title
|
|
||||||
// ),
|
|
||||||
// preferenceDescription = "#" + Integer.toHexString(localAccentColor.toInt()),
|
|
||||||
// buttons = { isShown ->
|
|
||||||
// ManagerResetButton(
|
|
||||||
// backgroundColor = Color(localAccentColor)
|
|
||||||
// ) {
|
|
||||||
// isShown.value = false
|
|
||||||
// managerAccentColorPref.save(defAccentColor)
|
|
||||||
// }
|
|
||||||
// ManagerSaveButton(
|
|
||||||
// backgroundColor = Color(localAccentColor)
|
|
||||||
// ) {
|
|
||||||
// isShown.value = false
|
|
||||||
// managerAccentColorPref.save(localAccentColor)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ) {
|
|
||||||
// ManagerColorPicker {
|
|
||||||
// localAccentColor = it
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.settings
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.ui.component.preference.Preference
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SettingsClearFilesItem() {
|
|
||||||
Preference(
|
|
||||||
preferenceTitle = managerString(
|
|
||||||
stringId = R.string.settings_preference_clear_files_title
|
|
||||||
),
|
|
||||||
preferenceDescription = null,
|
|
||||||
onClick = {}
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.settings
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.core.preferences.holder.useCustomTabsPref
|
|
||||||
import com.vanced.manager.ui.component.preference.CheckboxPreference
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SettingsCustomTabsItem() {
|
|
||||||
CheckboxPreference(
|
|
||||||
preferenceTitle = stringResource(id = R.string.settings_preference_use_custom_tabs_title),
|
|
||||||
preferenceDescription = stringResource(id = R.string.settings_preference_use_custom_tabs_summary),
|
|
||||||
isChecked = useCustomTabsPref,
|
|
||||||
onCheckedChange = {
|
|
||||||
useCustomTabsPref = it
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.settings
|
|
||||||
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.core.preferences.RadioButtonPreference
|
|
||||||
import com.vanced.manager.core.preferences.holder.managerVariantPref
|
|
||||||
import com.vanced.manager.core.util.isMagiskInstalled
|
|
||||||
import com.vanced.manager.ui.component.preference.SingleSelectDialogPreference
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SettingsManagerVariantItem() {
|
|
||||||
var showDialog by remember { mutableStateOf(false) }
|
|
||||||
var selectedKey by remember { mutableStateOf(managerVariantPref) }
|
|
||||||
SingleSelectDialogPreference(
|
|
||||||
preferenceTitle = managerString(
|
|
||||||
stringId = R.string.settings_preference_variant_title
|
|
||||||
),
|
|
||||||
preferenceDescription = managerVariantPref,
|
|
||||||
isDialogVisible = showDialog,
|
|
||||||
currentSelectedKey = selectedKey,
|
|
||||||
buttons = listOf(
|
|
||||||
RadioButtonPreference(
|
|
||||||
title = "nonroot",
|
|
||||||
key = "nonroot"
|
|
||||||
),
|
|
||||||
RadioButtonPreference(
|
|
||||||
title = "root",
|
|
||||||
key = "root"
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onPreferenceClick = {
|
|
||||||
showDialog = true
|
|
||||||
},
|
|
||||||
onDismissRequest = {
|
|
||||||
showDialog = false
|
|
||||||
selectedKey = managerVariantPref
|
|
||||||
},
|
|
||||||
onItemClick = {
|
|
||||||
if (it == "root" && !isMagiskInstalled)
|
|
||||||
return@SingleSelectDialogPreference
|
|
||||||
|
|
||||||
selectedKey = it
|
|
||||||
},
|
|
||||||
onSave = {
|
|
||||||
managerVariantPref = selectedKey
|
|
||||||
showDialog = false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.settings
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import com.vanced.manager.core.preferences.managerBooleanPreference
|
|
||||||
import com.vanced.manager.core.util.notificationApps
|
|
||||||
import com.vanced.manager.ui.component.preference.CheckboxPreference
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SettingsNotificationsItem() {
|
|
||||||
notificationApps.forEach { notificationApp ->
|
|
||||||
with(notificationApp) {
|
|
||||||
var appNotificationsPref by managerBooleanPreference(
|
|
||||||
key = "${prefKey}_notifications",
|
|
||||||
defaultValue = true
|
|
||||||
)
|
|
||||||
CheckboxPreference(
|
|
||||||
preferenceTitle = "$app Push Notifications",
|
|
||||||
preferenceDescription = "Receive push notifications when an update for $app is released",
|
|
||||||
isChecked = appNotificationsPref,
|
|
||||||
onCheckedChange = {
|
|
||||||
appNotificationsPref = it
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package com.vanced.manager.ui.widget.settings
|
|
||||||
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import com.vanced.manager.R
|
|
||||||
import com.vanced.manager.core.preferences.RadioButtonPreference
|
|
||||||
import com.vanced.manager.core.preferences.holder.managerThemePref
|
|
||||||
import com.vanced.manager.ui.component.preference.SingleSelectDialogPreference
|
|
||||||
import com.vanced.manager.ui.resources.managerString
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ThemeSettingsItem() {
|
|
||||||
var showDialog by remember { mutableStateOf(false) }
|
|
||||||
var selectedKey by remember { mutableStateOf(managerThemePref) }
|
|
||||||
SingleSelectDialogPreference(
|
|
||||||
preferenceTitle = managerString(stringId = R.string.settings_preference_theme_title),
|
|
||||||
preferenceDescription = managerThemePref,
|
|
||||||
isDialogVisible = showDialog,
|
|
||||||
currentSelectedKey = selectedKey,
|
|
||||||
buttons = listOf(
|
|
||||||
RadioButtonPreference(
|
|
||||||
title = managerString(R.string.settings_preference_theme_light),
|
|
||||||
key = "Light"
|
|
||||||
),
|
|
||||||
RadioButtonPreference(
|
|
||||||
title = managerString(R.string.settings_preference_theme_dark),
|
|
||||||
key = "Dark"
|
|
||||||
),
|
|
||||||
RadioButtonPreference(
|
|
||||||
title = managerString(R.string.settings_option_system_default),
|
|
||||||
key = "System Default"
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onPreferenceClick = {
|
|
||||||
showDialog = true
|
|
||||||
},
|
|
||||||
onDismissRequest = {
|
|
||||||
showDialog = false
|
|
||||||
selectedKey = managerThemePref
|
|
||||||
},
|
|
||||||
onItemClick = {
|
|
||||||
selectedKey = it
|
|
||||||
},
|
|
||||||
onSave = {
|
|
||||||
managerThemePref = selectedKey
|
|
||||||
showDialog = false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
Loading…
Reference in New Issue